From ffbd9d349e85acc1181a84526ae27e2bc877f6f5 Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 19:48:01 +0200 Subject: [PATCH 01/17] Create Original Repo Is Back https://github.com/Retera/WarsmashModEngine --- Original Repo Is Back | 1 + 1 file changed, 1 insertion(+) create mode 100644 Original Repo Is Back diff --git a/Original Repo Is Back b/Original Repo Is Back new file mode 100644 index 00000000..50fc7361 --- /dev/null +++ b/Original Repo Is Back @@ -0,0 +1 @@ +https://github.com/Retera/WarsmashModEngine From 6bd8782c62e4646bf51705e06781520384608807 Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:00:28 +0200 Subject: [PATCH 02/17] Update README.md --- README.md | 40 ++-------------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 756d20f6..2721c667 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,2 @@ -# Warsmash: Mod Engine -This is a Warcraft III modding project that aspires to eventually make Warcraft III modding easier by providing a replacement component for the game program that can be more easily modified while still requiring the Blizzard Warcraft III game and assets to be installed on the computer only from Blizzard. In short, buy Warcraft III from Blizzard, and then you can begin to use this mod engine with it. - -## Gameplay Example -https://www.youtube.com/watch?v=HD8HGQPm_nw - -## How to Install -1. Clone the repo -2. Open the repo as a Gradle Project with your Java IDE of choice (IntelliJ seems to be the easiest to get working) -3. Run the Gradle target called "run" - -## How to Build -1. Clone the repo -2. Run ./gradlew desktop:dist -3. Find "./desktop/build/libs/desktop-1.0.jar" -4. Open this JAR with 7zip -5. Remove the duplicate "META-INF/services/javax.imageio.spi.ImageReaderSpi" files that share the same name located in META-INF so that only the BLP related file is present -6. Save the JAR and exit 7zip -*(This process will hopefully become easier in the future)* - -## Background and History -My current codebase is running on Java 8 and the LibGDX game engine coupled with the port of the mdx-m3-viewer's engine. It contains: -- A transcription of only the relevant portions of this WebGL viewer necessary to load MDX models and W3X map data, and to display the models https://github.com/flowtsohg/mdx-m3-viewer - - I changed several things about the viewer as of the time of writing, such as a naive implementation of Light objects that will support the Day/Night cycle of the game as well as support point lights for torches and other game objects, however there is a memory leak in my Light system so that it will cause progressively increasing lag on slower computers - - After the development of this project began, there was code sharing between the MDLX parser in this repo and the one in the "conflictfixes" branch of ReteraModelStudio. Other users (tw1lac and flowtsohg) made contributions to the MDLX parser while it was sitting in that repo, and then I copied it back to this repo, so at this point this repo is including a few changes that were made by those users, but in an undocumented way. Hopefully I will clean this up and get the MDLX parser split from both of these projects off to its own repo. However, credits and thanks to them for their changes to that code (I think it was mostly flowtsohg)! My lack of the git history for those changes in this repo is not an attempt to remove citation/credits for their work, but is rather the result of laziness. -- A transcription of the HiveWE terrain rendering systems from this project, then modified to interface nicely with the ported viewers MDX rendering https://github.com/stijnherfst/HiveWE - - I changed the orientation of the cliff meshes. Mine are rotated 90 degrees from HiveWE in order to more accurately reproduce the likeness of what we observe in the Warcraft III World Editor. At times, I also tinkered with the Ramp logic and at this point mine is not 1:1 the same as HiveWE, but there are still many issues with mine. -- The shaders GLSL code from both of the above projects, originally copied in almost their exact form but with a few necessary changes. As a result, there are still bizarre disparities in the GL Shader Language version used for different things within this same project -- Graphical Enhancements to viewer from this fork of it: https://github.com/d07RiV/wc3data -(By copying the above repo, I was able to add support for water waves, shadow on the edge of the map, shadow under buildings, UberSplat under buildings, the little shadow picture under units, and some earlier drafts of the unit selection mouse intersect code that I mostly replaced at this point. I had to heavily modify the Splat logic to make them mobile as this repo at the time of copying was only able to create the shadow in a static location and upload the single location to the graphics card. Theoretically I have found cases for Ramps in map terrain that are handled properly by this repo and not by HiveWE terrain rendering nor by my copy of it, but I never prioritized investigating those ramp problems further) -- I use Java-based blp-iio-plugin so I didnt need to bother porting the BLP parser from the model viewer BUT this one I am using has some issue on campaign art textures where the alpha isnt loaded, so NightElfCampaign3D_exp for example has render artifacts around palm leaves https://github.com/DrSuperGood/blp-iio-plugin -- I use an MPQ parser by the same guy as the above, DrSuperGood, but he didnt put it on github so I just included the sourcecode in the repo for now -- For loading Unit Data, I have two SLK parsers and two INI parsers which is gross. One set is copied from ReteraModelStudio and the other is transcribed from viewer. I am mostly using the ReteraModelStudio one where possible because I wrote it not as a copy of anything else from my own intuition years ago and the API interfaces better with my high level unit data API that I copied from ReteraModelStudio (https://github.com/Retera/ReterasModelStudio) -- For loading map changeset unit data (Object Editor) I am using a transcription of the parsers written by PitzerMike for Grimoire/Widgetizer. Somebody linked me some ancient pastebin on the Hive at some point that included this C++ code so I wrote a Java port in my model editor repo and copied it to this repo and cleaned it up a bit -- For loading TGA image files such as building pathing, I use the same TGA parser included in ReteraModelStudio codebase. It was written by OgerLord long ago https://github.com/OgerLord/WcDataLibrary/blob/master/src/de/wc3data/image/TgaFile.java - -## Legal Stuff -I have tagged this repository with the MIT license. From my understanding this means that the users are free to take the contents of the repo and try to encrypt it all and sell it to each other. Some day, maybe a user will download this repo and reprogram a modified version that only plays the DotA map and use that as a DotA engine thing that they would sell to others and prevent me from modifying or using their upgrades. In my opinion, that is not very cool -- and I do not have experience playing the DotA map -- but I am setting up the repo here so that it does not stop them from doing that. Also, I am guessing that since MIT license probably allows selling modified versions of the code and stuff, this hopefully would leave the door open that Blizzard could download this repo and take stuff out of it and include it in their private Warcraft III game code if they ever needed to. At the time of writing I do not think my repo has anything in particular that Warcraft III Reforged does not have, however, so this is purely hypothetical that I am intending to leave as an open door for the future. +# Original Repo Is Back +https://github.com/Retera/WarsmashModEngine From 380028047718fa1091e66d78a182d0b9a02815d4 Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:01:39 +0200 Subject: [PATCH 03/17] Delete settings.gradle --- settings.gradle | 1 - 1 file changed, 1 deletion(-) delete mode 100644 settings.gradle diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 5d318b09..00000000 --- a/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include 'desktop', 'core', 'fdfparser', 'jassparser' \ No newline at end of file From 5b21db917fec1bb57aba4971cc731905dfaa2b31 Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:01:41 +0200 Subject: [PATCH 04/17] Delete gradlew.bat --- gradlew.bat | 84 ----------------------------------------------------- 1 file changed, 84 deletions(-) delete mode 100644 gradlew.bat diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index f9553162..00000000 --- a/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega From 99d01d75e9012849c2cdbbba9ba4f44bc489e950 Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:01:43 +0200 Subject: [PATCH 05/17] Delete gradlew --- gradlew | 172 -------------------------------------------------------- 1 file changed, 172 deletions(-) delete mode 100644 gradlew diff --git a/gradlew b/gradlew deleted file mode 100644 index 4453ccea..00000000 --- a/gradlew +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env sh - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save ( ) { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" From a07545466fe9924a696b7c81df3bd4f1eff1857f Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:01:46 +0200 Subject: [PATCH 06/17] Delete gradle.properties --- gradle.properties | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 gradle.properties diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index ff329ac3..00000000 --- a/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.gradle.daemon=true -org.gradle.jvmargs=-Xms128m -Xmx1500m -org.gradle.configureondemand=false From 9ff6f2921efaacc8c2dc5569f285274806dcc0a3 Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:01:47 +0200 Subject: [PATCH 07/17] Delete build.gradle --- build.gradle | 98 ---------------------------------------------------- 1 file changed, 98 deletions(-) delete mode 100644 build.gradle diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 9d2880bb..00000000 --- a/build.gradle +++ /dev/null @@ -1,98 +0,0 @@ -buildscript { - repositories { - mavenLocal() - flatDir { - dirs "$rootProject.projectDir/jars" - } - mavenCentral() - maven { url "https://plugins.gradle.org/m2/" } - maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } - maven { url "https://maven.nikr.net/" } - jcenter() - google() - } -} - -allprojects { - apply plugin: "eclipse" - apply plugin: "idea" - - version = '1.0' - ext { - appName = "warsmash" - gdxVersion = '1.9.8' - roboVMVersion = '2.3.5' - box2DLightsVersion = '1.4' - ashleyVersion = '1.7.0' - aiVersion = '1.8.0' - antlrVersion = '4.7' - } - - repositories { - mavenLocal() - mavenCentral() - google() - maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } - maven { url "https://oss.sonatype.org/content/repositories/releases/" } - maven { url "https://maven.nikr.net/" } - maven { url 'https://jitpack.io' } - } -} - -project(":desktop") { - apply plugin: "java" - - - dependencies { - compile project(":core") - compile "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion" - compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" - compile "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop" - compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop" - compile "com.google.guava:guava:23.5-jre" - compile "org.apache.commons:commons-compress:1.20" - compile "net.nikr:dds:1.0.0" - compile files(fileTree(dir:'../jars', includes: ['*.jar'])) - - } -} - -project(":core") { - apply plugin: "java" - - - dependencies { - compile project(":fdfparser") - compile project(":jassparser") - compile "com.badlogicgames.gdx:gdx:$gdxVersion" - compile "com.badlogicgames.gdx:gdx-box2d:$gdxVersion" - compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion" - compile "com.google.guava:guava:23.5-jre" - compile "org.apache.commons:commons-compress:1.20" - compile "net.nikr:dds:1.0.0" - compile files(fileTree(dir:'../jars', includes: ['*.jar'])) - - } -} - -project(":fdfparser") { - apply plugin: "antlr" - - - dependencies { - antlr "org.antlr:antlr4:$antlrVersion" // use antlr version 4 - } -} - -project(":jassparser") { - apply plugin: "antlr" - - - dependencies { - antlr "org.antlr:antlr4:$antlrVersion" // use antlr version 4 - } -} - -tasks.eclipse.doLast { - delete ".project" -} \ No newline at end of file From d03e812c02ae8718878db3c217c099e7d46acf49 Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:01:49 +0200 Subject: [PATCH 08/17] Delete .gitignore --- .gitignore | 128 ----------------------------------------------------- 1 file changed, 128 deletions(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 8d97c253..00000000 --- a/.gitignore +++ /dev/null @@ -1,128 +0,0 @@ -## Java - -*.class -*.war -*.ear -hs_err_pid* - -## Robovm -/ios/robovm-build/ - -## GWT -/html/war/ -/html/gwt-unitCache/ -.apt_generated/ -.gwt/ -gwt-unitCache/ -www-test/ -.gwt-tmp/ - -## Android Studio and Intellij and Android in general -/android/libs/armeabi/ -/android/libs/armeabi-v7a/ -/android/libs/arm64-v8a/ -/android/libs/x86/ -/android/libs/x86_64/ -/android/gen/ -.idea/ -*.ipr -*.iws -*.iml -/android/out/ -com_crashlytics_export_strings.xml - -## Eclipse - -.classpath -.project -.metadata/ -/android/bin/ -/core/bin/ -/desktop/bin/ -/html/bin/ -/ios/bin/ -/ios-moe/bin/ -*.tmp -*.bak -*.swp -*~.nib -.settings/ -.loadpath -.externalToolBuilders/ -*.launch - -## NetBeans - -/nbproject/private/ -/android/nbproject/private/ -/core/nbproject/private/ -/desktop/nbproject/private/ -/html/nbproject/private/ -/ios/nbproject/private/ -/ios-moe/nbproject/private/ - -/build/ -/android/build/ -/core/build/ -/desktop/build/ -/html/build/ -/ios/build/ -/ios-moe/build/ - -/nbbuild/ -/android/nbbuild/ -/core/nbbuild/ -/desktop/nbbuild/ -/html/nbbuild/ -/ios/nbbuild/ -/ios-moe/nbbuild/ - -/dist/ -/android/dist/ -/core/dist/ -/desktop/dist/ -/html/dist/ -/ios/dist/ -/ios-moe/dist/ - -/nbdist/ -/android/nbdist/ -/core/nbdist/ -/desktop/nbdist/ -/html/nbdist/ -/ios/nbdist/ -/ios-moe/nbdist/ - -nbactions.xml -nb-configuration.xml - -## Gradle - -/local.properties -.gradle/ -gradle-app.setting -/build/ -/android/build/ -/core/build/ -/desktop/build/ -/html/build/ -/ios/build/ -/ios-moe/build/ - -## OS Specific -.DS_Store -Thumbs.db - -## iOS -/ios/xcode/*.xcodeproj/* -!/ios/xcode/*.xcodeproj/xcshareddata -!/ios/xcode/*.xcodeproj/project.pbxproj -/ios/xcode/native/ - -/ios-moe/xcode/*.xcodeproj/* -!/ios-moe/xcode/*.xcodeproj/xcshareddata -!/ios-moe/xcode/*.xcodeproj/project.pbxproj -/ios-moe/xcode/native/ - -## data -/core/data From d176fe5dcec8c7d6949aaa0d82bc03f74b52cd89 Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:01:52 +0200 Subject: [PATCH 09/17] Delete resources directory --- resources/Scripts/common.jui | 162 ------------------ resources/Scripts/melee.jui | 73 -------- resources/UI/FrameDef/SmashFrameDef.toc | 4 - .../UI/FrameDef/SmashUI/InventoryCover.fdf | 15 -- .../UI/FrameDef/SmashUI/SmashConsoleUI.fdf | 81 --------- .../FrameDef/SmashUI/TimeOfDayIndicator.fdf | 6 - resources/UI/FrameDef/SmashUI/ToolTip.fdf | 67 -------- .../UI/FrameDef/SmashUI/UnitPortrait.fdf | 44 ----- 8 files changed, 452 deletions(-) delete mode 100644 resources/Scripts/common.jui delete mode 100644 resources/Scripts/melee.jui delete mode 100644 resources/UI/FrameDef/SmashFrameDef.toc delete mode 100644 resources/UI/FrameDef/SmashUI/InventoryCover.fdf delete mode 100644 resources/UI/FrameDef/SmashUI/SmashConsoleUI.fdf delete mode 100644 resources/UI/FrameDef/SmashUI/TimeOfDayIndicator.fdf delete mode 100644 resources/UI/FrameDef/SmashUI/ToolTip.fdf delete mode 100644 resources/UI/FrameDef/SmashUI/UnitPortrait.fdf diff --git a/resources/Scripts/common.jui b/resources/Scripts/common.jui deleted file mode 100644 index 34f4ec7b..00000000 --- a/resources/Scripts/common.jui +++ /dev/null @@ -1,162 +0,0 @@ -//============================================================================ -// User Interface scripts for the Warsmash mod engine. This is -// an attempt to get these defined in an external import that -// a map can override. Unfortunately, although I would like for -// this to be a JASS file, it is not very consistent with the -// notion of the JASS2 VM to define UI, because handles are -// mostly network synced. So, we will assume the contents -// of this file are run in a special client-only JASS VM -// once I implement networking, so that this script will not -// cause a desync as it would if it was in the standard game -// JASS files. For that reason, it will have '.jui' extension -// to signify it runs in this modified JASS VM, instead of -// standard '.j' as used for JASS2 script files. -// -// Right now there is some duplicated code from common.j -- -// maybe later on we will load that stuff first, then this -// one in the same variable space? -// - -type framehandle extends handle -type framepointtype extends handle -type trigger extends handle -type triggeraction extends handle -type triggercondition extends handle -type boolexpr extends handle -type conditionfunc extends boolexpr - -native LogError takes string message returns nothing -constant native ConvertFramePointType takes integer i returns framepointtype - -globals - -//=================================================== -// UI API constants -//=================================================== - - constant framepointtype FRAMEPOINT_TOPLEFT = ConvertFramePointType(0) - constant framepointtype FRAMEPOINT_TOP = ConvertFramePointType(1) - constant framepointtype FRAMEPOINT_TOPRIGHT = ConvertFramePointType(2) - constant framepointtype FRAMEPOINT_LEFT = ConvertFramePointType(3) - constant framepointtype FRAMEPOINT_CENTER = ConvertFramePointType(4) - constant framepointtype FRAMEPOINT_RIGHT = ConvertFramePointType(5) - constant framepointtype FRAMEPOINT_BOTTOMLEFT = ConvertFramePointType(6) - constant framepointtype FRAMEPOINT_BOTTOM = ConvertFramePointType(7) - constant framepointtype FRAMEPOINT_BOTTOMRIGHT = ConvertFramePointType(8) -endglobals - -//=================================================== -// UI API -//=================================================== - -// Loads an entry from the file "UI\war3skins.txt" and returns -// it as the current GAMEUI. The default possible -// strings are "Human", "Orc", "NightElf", and "Undead". -// Some UI FDF templates will use this information as -// the source for lookup strings as a means to change -// their style. -// Calling this more than once will probably crash the game, -// or something, so only call it once on startup. -native CreateRootFrame takes string skinName returns framehandle - -// Loads the (T)able (O)f (C)ontents file. -// This must be a simple text document with each line -// having only a filepath of a .FDF frame template -// definition file to load. Unlike War3 engine, -// I do not require the file to include one extra -// blank line at the end. -// -// We typically call this first during UI setup, and -// only once for a given mod. -native LoadTOCFile takes string TOCFile returns framehandle - -// Spawn a SIMPLEFRAME element that was defined in a FDF -// template onto the screen. The "name" field must match -// the name of a template to spawn, loaded with LoadTOCFile. -// The create context is pretty pointless, but I think -// they use it so that they have an integer tag on the -// "Attack 1" and "Attack 2" ui components. I was trying -// to keep parity with the FDF UI APIs from 1.31, imagine -// that. -native CreateSimpleFrame takes string name, framehandle owner, integer createContext returns framehandle - -// Spawn a FRAME element that was defined in an FDF -// template onto the screen. The "name" field must -// match the name of a template to spawn, loaded with LoadTOCFile. -// As noted on CreateSimpleFrame, for now createContext is pointless. -// Likewise for priority -- until it fixed. -native CreateFrame takes string name, framehandle owner, integer priority, integer createContext returns framehandle - - -// Set the absolute point (often called Anchor) for the frame handle. -// See FDF template files for examples -native FrameSetAnchor takes framehandle frame, framepointtype point, real x, real y returns nothing - -// Tasyen said: "takes one point of a Frame unbound that point and places it to a specific coordinates on the screen." -native FrameSetAbsPoint takes framehandle frame, framepointtype point, real x, real y returns nothing - -// Set the relative point (called SetPoint in FDF templates) for the frame handle. -// See FDF template files for examples -// Tasyen said: places a point of FrameA relative to a point of FrameB. When FrameB moves FrameA's point will keep this rule and moves with it. -// Note for Project Warsmash: "When FrameB moves..." might not be true... call FramePositionBounds() for now -native FrameSetPoint takes framehandle frame, framepointtype point, framehandle relative, framepointtype relativePoint, real x, real y returns nothing - - -// Created for Warsmash engine, not a part of 1.31 UI apis, -// and at some point it might be removed. Basically -// this function will apply Anchors and SetPoints assigned -// to the frame handle and all its children and resolve where -// they should go onscreen. Generally in my experience, -// War3 will do this automatically in their FDF system. -native FramePositionBounds takes framehandle frame returns nothing - -// Used to lookup fields in the Skin data, for example -// SkinGetField("TimeOfDayIndicator") will return the -// string "UI\\Console\\Human\\HumanUI-TimeIndicator.mdl" -// when the "Human" skin was loaded with CreateRootFrame -native SkinGetField takes string field returns string - -// Sets the text value on a String Frame, currently it crashes otherwise -native FrameSetText takes framehandle frame, string text returns nothing - -// Sets the text color on a String Frame, currently it crashes otherwise -native FrameSetTextColor takes framehandle frame, integer color returns nothing - -native ConvertColor takes integer a, integer r, integer g, integer b returns integer - - -// Gets a previously created Frame using its name ( from an FDF template file that was -// previously spawned ). See previous notes about createContext. Mostly pointless? -native GetFrameByName takes string name, integer createContext returns framehandle - -//============================================================================ -// Native trigger interface -// -native CreateTrigger takes nothing returns trigger -native DestroyTrigger takes trigger whichTrigger returns nothing -native EnableTrigger takes trigger whichTrigger returns nothing -native DisableTrigger takes trigger whichTrigger returns nothing -native IsTriggerEnabled takes trigger whichTrigger returns boolean - -native TriggerAddCondition takes trigger whichTrigger, boolexpr condition returns triggercondition -native TriggerRemoveCondition takes trigger whichTrigger, triggercondition whichCondition returns nothing -native TriggerClearConditions takes trigger whichTrigger returns nothing - -native TriggerAddAction takes trigger whichTrigger, code actionFunc returns triggeraction -native TriggerRemoveAction takes trigger whichTrigger, triggeraction whichAction returns nothing -native TriggerClearActions takes trigger whichTrigger returns nothing -native TriggerEvaluate takes trigger whichTrigger returns boolean -native TriggerExecute takes trigger whichTrigger returns nothing - - -//============================================================================ -// Boolean Expr API ( for compositing trigger conditions and unit filter funcs...) -//============================================================================ -native And takes boolexpr operandA, boolexpr operandB returns boolexpr -native Or takes boolexpr operandA, boolexpr operandB returns boolexpr -native Not takes boolexpr operand returns boolexpr -native Condition takes code func returns conditionfunc -native DestroyCondition takes conditionfunc c returns nothing -native Filter takes code func returns filterfunc -native DestroyFilter takes filterfunc f returns nothing -native DestroyBoolExpr takes boolexpr e returns nothing \ No newline at end of file diff --git a/resources/Scripts/melee.jui b/resources/Scripts/melee.jui deleted file mode 100644 index 9d3c9a4b..00000000 --- a/resources/Scripts/melee.jui +++ /dev/null @@ -1,73 +0,0 @@ - -globals -// Defaults for testing: - constant string SKIN = "NightElf" -// Major UI components - framehandle ROOT_FRAME - framehandle CONSOLE_UI - framehandle RESOURCE_BAR - framehandle RESOURCE_BAR_GOLD_TEXT - framehandle RESOURCE_BAR_LUMBER_TEXT - framehandle RESOURCE_BAR_SUPPLY_TEXT - framehandle RESOURCE_BAR_UPKEEP_TEXT - framehandle TIME_INDICATOR - framehandle SIMPLE_INFO_PANEL_UNIT_DETAIL - framehandle UNIT_PORTRAIT - framehandle UNIT_LIFE_TEXT - framehandle UNIT_MANA_TEXT -endglobals - - -function main takes nothing returns nothing - // ================================= - // Load skins and templates - // ================================= - set ROOT_FRAME = CreateRootFrame(SKIN) - if not LoadTOCFile("UI\\FrameDef\\FrameDef.toc") then - call LogError("Unable to load FrameDef.toc") - endif - if not LoadTOCFile("UI\\FrameDef\\SmashFrameDef.toc") then - call LogError("Unable to load SmashFrameDef.toc") - endif - // ================================= - // Load major UI components - // ================================= - // Console UI is the background with the racial theme - set CONSOLE_UI = CreateSimpleFrame("ConsoleUI", ROOT_FRAME, 0) - // Resource bar is a 3 part bar with Gold, Lumber, and Food. - // Its template does not specify where to put it, so we must - // put it in the "TOPRIGHT" corner. - set RESOURCE_BAR = CreateSimpleFrame("ResourceBarFrame", CONSOLE_UI, 0) - call FrameSetPoint(RESOURCE_BAR, FRAMEPOINT_TOPRIGHT, CONSOLE_UI, FRAMEPOINT_TOPRIGHT, 0, 0) - - // Create the Time Indicator (clock) - set TIME_INDICATOR = CreateFrame("TimeOfDayIndicator", ROOT_FRAME, 0, 0) - - // Create the unit portrait stuff (for now this doesn't actually create the 3D, only HP/mana) - set UNIT_PORTRAIT = CreateSimpleFrame("UnitPortrait", CONSOLE_UI, 0) - set UNIT_LIFE_TEXT = GetFrameByName("UnitPortraitHitPointText", 0) - set UNIT_MANA_TEXT = GetFrameByName("UnitPortraitManaPointText", 0) - - // Set default values - call FrameSetText(UNIT_LIFE_TEXT, "706 / 725") - call FrameSetText(UNIT_MANA_TEXT, "405 / 405") - - - // Retrieve inflated sub-frames and store references - set RESOURCE_BAR_GOLD_TEXT = GetFrameByName("ResourceBarGoldText", 0) - set RESOURCE_BAR_LUMBER_TEXT = GetFrameByName("ResourceBarLumberText", 0) - set RESOURCE_BAR_SUPPLY_TEXT = GetFrameByName("ResourceBarSupplyText", 0) - set RESOURCE_BAR_UPKEEP_TEXT = GetFrameByName("ResourceBarUpkeepText", 0) - - // Set default values - call FrameSetText(RESOURCE_BAR_GOLD_TEXT, "500") - call FrameSetText(RESOURCE_BAR_LUMBER_TEXT, "150") - call FrameSetText(RESOURCE_BAR_SUPPLY_TEXT, "5/10") - call FrameSetText(RESOURCE_BAR_UPKEEP_TEXT, "No Upkeep") - call FrameSetTextColor(RESOURCE_BAR_UPKEEP_TEXT, ConvertColor(255, 0, 255, 0)) - - // Assemble the UI and resolve the location of every component that - // has Anchors and SetPoints (maybe in future version this call - // wont be necessary!) - call FramePositionBounds(ROOT_FRAME) -endfunction \ No newline at end of file diff --git a/resources/UI/FrameDef/SmashFrameDef.toc b/resources/UI/FrameDef/SmashFrameDef.toc deleted file mode 100644 index 26aa1336..00000000 --- a/resources/UI/FrameDef/SmashFrameDef.toc +++ /dev/null @@ -1,4 +0,0 @@ -UI\FrameDef\SmashUI\TimeOfDayIndicator.fdf -UI\FrameDef\SmashUI\UnitPortrait.fdf -UI\FrameDef\SmashUI\InventoryCover.fdf -UI\FrameDef\SmashUI\ToolTip.fdf diff --git a/resources/UI/FrameDef/SmashUI/InventoryCover.fdf b/resources/UI/FrameDef/SmashUI/InventoryCover.fdf deleted file mode 100644 index 378e7078..00000000 --- a/resources/UI/FrameDef/SmashUI/InventoryCover.fdf +++ /dev/null @@ -1,15 +0,0 @@ -Frame "SIMPLEFRAME" "SmashConsoleInventoryCover" { - DecorateFileNames, - SetAllPoints, - - // The top of the UI console - Texture "SmashConsoleInventoryCoverTexture" { - File "ConsoleInventoryCoverTexture", - Width 0.128, - Height 0.176, - AlphaMode "ALPHAKEY", - TexCoord 0, 1, 0.3125, 1, - Anchor BOTTOMLEFT,0.472,0.0, - } - -} diff --git a/resources/UI/FrameDef/SmashUI/SmashConsoleUI.fdf b/resources/UI/FrameDef/SmashUI/SmashConsoleUI.fdf deleted file mode 100644 index 9ba99492..00000000 --- a/resources/UI/FrameDef/SmashUI/SmashConsoleUI.fdf +++ /dev/null @@ -1,81 +0,0 @@ -// I had to override this because the Blizzard version is missing the "ConsoleTexture01Top" names. -Frame "SIMPLEFRAME" "ConsoleUI" { - DecorateFileNames, - - // The top of the UI console - Texture "ConsoleTexture01Top" { - File "ConsoleTexture01", - Width 0.256, - Height 0.032, - TexCoord 0, 1, 0, 0.125, - AlphaMode "ALPHAKEY", - Anchor TOPLEFT,0,0, - } - Texture "ConsoleTexture02Top" { - File "ConsoleTexture02", - Width 0.087, - Height 0.032, - TexCoord 0, 0.33984375, 0, 0.125, - AlphaMode "ALPHAKEY", - Anchor TOPLEFT,0.256, 0, - } - Texture "ConsoleTexture02Top" { - File "ConsoleTexture02", - Width 0.053, - Height 0.032, - TexCoord 0.79296875, 1, 0, 0.125, - AlphaMode "ALPHAKEY", - Anchor TOPRIGHT,-0.288, 0, - } - Texture "ConsoleTexture03Top" { - File "ConsoleTexture03", - Width 0.256, - Height 0.032, - TexCoord 0, 1, 0, 0.125, - AlphaMode "ALPHAKEY", - Anchor TOPRIGHT,-0.032, 0, - } - Texture "ConsoleTexture04Top" { - File "ConsoleTexture04", - Width 0.032, - Height 0.032, - TexCoord 0, 1, 0, 0.125, - AlphaMode "ALPHAKEY", - Anchor TOPRIGHT,0,0, - } - - // The bottom of the UI console - Texture "ConsoleTexture01Bottom" { - File "ConsoleTexture01", - Width 0.256, - Height 0.176, - TexCoord 0, 1, 0.3125, 1, - AlphaMode "ALPHAKEY", - Anchor BOTTOMLEFT,0,0, - } - Texture "ConsoleTexture02Bottom" { - File "ConsoleTexture02", - Width 0.256, - Height 0.15, - TexCoord 0, 1, 0.4140625, 1, - AlphaMode "ALPHAKEY", - Anchor BOTTOMLEFT,0.256,0, - } - Texture "ConsoleTexture03Bottom" { - File "ConsoleTexture03", - Width 0.256, - Height 0.176, - TexCoord 0, 1, 0.3125, 1, - AlphaMode "ALPHAKEY", - Anchor BOTTOMRIGHT,-0.032,0.0, - } - Texture "ConsoleTexture04Bottom" { - File "ConsoleTexture04", - Width 0.032, - Height 0.176, - TexCoord 0, 1, 0.3125, 1, - AlphaMode "ALPHAKEY", - Anchor BOTTOMRIGHT,0,0, - } - -} diff --git a/resources/UI/FrameDef/SmashUI/TimeOfDayIndicator.fdf b/resources/UI/FrameDef/SmashUI/TimeOfDayIndicator.fdf deleted file mode 100644 index 9480e6ea..00000000 --- a/resources/UI/FrameDef/SmashUI/TimeOfDayIndicator.fdf +++ /dev/null @@ -1,6 +0,0 @@ - -Frame "SPRITE" "TimeOfDayIndicator" { - DecorateFileNames, - BackgroundArt "TimeOfDayIndicator", - SetPoint BOTTOMLEFT,"ConsoleUI",BOTTOMLEFT,0,0, -} \ No newline at end of file diff --git a/resources/UI/FrameDef/SmashUI/ToolTip.fdf b/resources/UI/FrameDef/SmashUI/ToolTip.fdf deleted file mode 100644 index bb309202..00000000 --- a/resources/UI/FrameDef/SmashUI/ToolTip.fdf +++ /dev/null @@ -1,67 +0,0 @@ -/* - * ToolTip.fdf - * --------------------- - * These are some definitions to help us externalize the art of the tooltip. - * We want to use the following: - - ToolTipBackground=UI\Widgets\ToolTips\Human\human-tooltip-background.blp - ToolTipBorder=UI\Widgets\ToolTips\Human\human-tooltip-border.blp - ToolTipGoldIcon=UI\Widgets\ToolTips\Human\ToolTipGoldIcon.blp - ToolTipLumberIcon=UI\Widgets\ToolTips\Human\ToolTipLumberIcon.blp - ToolTipStonesIcon=UI\Widgets\ToolTips\Human\ToolTipStonesIcon.blp - ToolTipManaIcon=UI\Widgets\ToolTips\Human\ToolTipManaIcon.blp - ToolTipSupplyIcon=UI\Widgets\ToolTips\Human\ToolTipSupplyIcon.blp - */ - -Frame "FRAME" "SmashToolTip" { - Frame "BACKDROP" "SmashToolTipBackdrop" { - SetAllPoints, - DecorateFileNames, - BackdropTileBackground, - BackdropBackground "ToolTipBackground", - BackdropCornerFlags "UL|UR|BL|BR|T|L|B|R", - BackdropCornerSize 0.008, - BackdropBackgroundSize 0.036, - BackdropBackgroundInsets 0.0025 0.0025 0.0025 0.0025, - BackdropEdgeFile "ToolTipBorder", - BackdropBlendAll, - } - Frame "TEXT" "SmashToolTipText" { - DecorateFileNames, - FrameFont "MasterFont", 0.010, "", - FontJustificationH JUSTIFYLEFT, - FontJustificationV JUSTIFYTOP, - FontFlags "FIXEDSIZE", - FontColor 1.0 1.0 1.0 1.0, - } - Frame "TEXT" "SmashUberTipText" { - DecorateFileNames, - FrameFont "MasterFont", 0.010, "", - FontJustificationH JUSTIFYLEFT, - FontJustificationV JUSTIFYTOP, - FontFlags "FIXEDSIZE", - FontColor 1.0 1.0 1.0 1.0, - } -} -Frame "SIMPLEFRAME" "SmashToolTipIconResource" { - DecorateFileNames, - Height 0.010, - - // --- icon ------------------------------------------------------------- - Texture "SmashToolTipIconResourceBackdrop" { - Anchor LEFT, 0.0, 0.0 - Width 0.008, - Height 0.008, - File "ToolTipStonesIcon", - } - - // --- label ------------------------------------------------------------ - String "SmashToolTipIconResourceLabel" { - SetPoint LEFT, "SmashToolTipIconResourceBackdrop", RIGHT, 0.001, 0.000, - FontJustificationH JUSTIFYLEFT, - FontJustificationV JUSTIFYMIDDLE, - FontColor 0.99 0.827 0.0705 1.0, - Font "InfoPanelTextFont",0.0085, - Text "275", - } -} \ No newline at end of file diff --git a/resources/UI/FrameDef/SmashUI/UnitPortrait.fdf b/resources/UI/FrameDef/SmashUI/UnitPortrait.fdf deleted file mode 100644 index eb3aa550..00000000 --- a/resources/UI/FrameDef/SmashUI/UnitPortrait.fdf +++ /dev/null @@ -1,44 +0,0 @@ -/* - * UnitPortrait.fdf - * --------------------- - * Right now the actual 3d portrait is hardcoded like the - * original game, eventually that should be a config file - * like this so that a map can override it. - */ - -String "UnitPortraitTextTemplate" { - Font "MasterFont",0.011, - Height 0.01640625, - TextLength 20, -} - -Frame "SIMPLEFRAME" "UnitPortrait" { - DecorateFileNames, - SetPoint BOTTOMLEFT,"ConsoleUI",BOTTOMLEFT,0.211,0, - Width 0.0835, - Height 0.114, - - Frame "SIMPLEFRAME" "UnitPortraitModel" { - DecorateFileNames, - SetPoint BOTTOM,"UnitPortrait",BOTTOM,0,0.0285, - Width 0.0835, - Height 0.085, - - //Texture { - //File "IdlePeon", - // AlphaMode "ALPHAKEY", - //} - } - - String "UnitPortraitHitPointText" INHERITS "UnitPortraitTextTemplate" { - Anchor BOTTOM, 0, 0.014, - FontJustificationH JUSTIFYCENTER, - FontColor 0.0 1.0 0.0 1.0, - } - - String "UnitPortraitManaPointText" INHERITS "UnitPortraitTextTemplate" { - Anchor BOTTOM, 0, -0.0005, - FontJustificationH JUSTIFYCENTER, - FontColor 1.0 1.0 1.0 1.0, - } -} \ No newline at end of file From f0650416f3448c730616d1a2df6d030499672caa Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:01:56 +0200 Subject: [PATCH 10/17] Delete jassparser directory --- jassparser/.gitignore | 1 - jassparser/antlr-src/Jass.g4 | 200 ------------------ jassparser/build.gradle | 49 ----- .../etheller/interpreter/ast/Assignable.java | 30 --- .../etheller/interpreter/ast/JassRunner.java | 50 ----- .../expression/ArrayRefJassExpression.java | 41 ---- .../FunctionCallJassExpression.java | 36 ---- .../FunctionReferenceJassExpression.java | 27 --- .../ast/expression/JassExpression.java | 10 - .../ast/expression/LiteralJassExpression.java | 21 -- .../ast/expression/NotJassExpression.java | 21 -- .../expression/ReferenceJassExpression.java | 26 --- .../ast/function/AbstractJassFunction.java | 51 ----- .../ast/function/JassFunction.java | 11 - .../ast/function/JassNativeManager.java | 37 ---- .../ast/function/JassParameter.java | 28 --- .../ast/function/NativeJassFunction.java | 27 --- .../ast/function/UserJassFunction.java | 45 ---- .../interpreter/ast/scope/GlobalScope.java | 162 -------------- .../ast/scope/GlobalScopeAssignable.java | 45 ---- .../interpreter/ast/scope/LocalScope.java | 42 ---- .../ast/scope/TriggerExecutionScope.java | 18 -- .../interpreter/ast/scope/TypeDefinition.java | 11 - .../scope/trigger/RemovableTriggerEvent.java | 11 - .../ast/scope/trigger/Trigger.java | 93 -------- .../trigger/TriggerBooleanExpression.java | 8 - .../ast/scope/variableevent/CLimitOp.java | 12 -- .../scope/variableevent/VariableEvent.java | 55 ----- .../JassArrayedAssignmentStatement.java | 50 ----- .../ast/statement/JassCallStatement.java | 42 ---- .../ast/statement/JassIfElseIfStatement.java | 45 ---- .../ast/statement/JassIfElseStatement.java | 50 ----- .../ast/statement/JassIfStatement.java | 47 ---- .../ast/statement/JassReturnStatement.java | 25 --- .../ast/statement/JassSetStatement.java | 35 --- .../ast/statement/JassStatement.java | 12 -- .../interpreter/ast/value/ArrayJassType.java | 30 --- .../interpreter/ast/value/ArrayJassValue.java | 34 --- .../ast/value/BooleanJassValue.java | 39 ---- .../interpreter/ast/value/CodeJassValue.java | 21 -- .../interpreter/ast/value/HandleJassType.java | 43 ---- .../ast/value/HandleJassValue.java | 25 --- .../ast/value/IntegerJassValue.java | 18 -- .../interpreter/ast/value/JassType.java | 16 -- .../ast/value/JassTypeVisitor.java | 9 - .../interpreter/ast/value/JassValue.java | 5 - .../ast/value/JassValueVisitor.java | 17 -- .../ast/value/PrimitiveJassType.java | 25 --- .../interpreter/ast/value/RealJassType.java | 16 -- .../interpreter/ast/value/RealJassValue.java | 18 -- .../ast/value/StringJassValue.java | 24 --- .../value/visitor/ArrayJassValueVisitor.java | 54 ----- .../visitor/ArrayPrimitiveTypeVisitor.java | 31 --- .../visitor/BooleanJassValueVisitor.java | 54 ----- .../value/visitor/HandleJassTypeVisitor.java | 30 --- .../HandleTypeSuperTypeLoadingVisitor.java | 32 --- .../visitor/IntegerJassValueVisitor.java | 54 ----- .../visitor/JassFunctionJassValueVisitor.java | 55 ----- .../visitor/JassTypeGettingValueVisitor.java | 55 ----- .../value/visitor/NotJassValueVisitor.java | 56 ----- .../value/visitor/ObjectJassValueVisitor.java | 54 ----- .../value/visitor/RealJassValueVisitor.java | 54 ----- .../value/visitor/StringJassValueVisitor.java | 54 ----- .../ast/value/visitor/SuperTypeVisitor.java | 30 --- .../visitors/ArgumentExpressionHandler.java | 15 -- .../ast/visitors/JassArgumentsVisitor.java | 31 --- .../ast/visitors/JassExpressionVisitor.java | 91 -------- .../ast/visitors/JassGlobalsVisitor.java | 51 ----- .../ast/visitors/JassParametersVisitor.java | 38 ---- .../ast/visitors/JassProgramVisitor.java | 106 ---------- .../ast/visitors/JassStatementVisitor.java | 91 -------- .../ast/visitors/JassTypeVisitor.java | 31 --- 72 files changed, 2881 deletions(-) delete mode 100644 jassparser/.gitignore delete mode 100644 jassparser/antlr-src/Jass.g4 delete mode 100644 jassparser/build.gradle delete mode 100644 jassparser/src/com/etheller/interpreter/ast/Assignable.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/JassRunner.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/expression/ArrayRefJassExpression.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/expression/FunctionCallJassExpression.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/expression/FunctionReferenceJassExpression.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/expression/JassExpression.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/expression/LiteralJassExpression.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/expression/NotJassExpression.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/expression/ReferenceJassExpression.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/function/AbstractJassFunction.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/function/JassFunction.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/function/JassNativeManager.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/function/JassParameter.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/function/NativeJassFunction.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/function/UserJassFunction.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/scope/GlobalScope.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/scope/GlobalScopeAssignable.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/scope/LocalScope.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/scope/TriggerExecutionScope.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/scope/TypeDefinition.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/scope/trigger/RemovableTriggerEvent.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/scope/trigger/Trigger.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/scope/trigger/TriggerBooleanExpression.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/scope/variableevent/CLimitOp.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/scope/variableevent/VariableEvent.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/statement/JassArrayedAssignmentStatement.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/statement/JassCallStatement.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/statement/JassIfElseIfStatement.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/statement/JassIfElseStatement.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/statement/JassIfStatement.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/statement/JassReturnStatement.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/statement/JassSetStatement.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/statement/JassStatement.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/ArrayJassType.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/ArrayJassValue.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/BooleanJassValue.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/CodeJassValue.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/HandleJassType.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/HandleJassValue.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/IntegerJassValue.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/JassType.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/JassTypeVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/JassValue.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/JassValueVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/PrimitiveJassType.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/RealJassType.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/RealJassValue.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/StringJassValue.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/visitor/ArrayJassValueVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/visitor/ArrayPrimitiveTypeVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/visitor/BooleanJassValueVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/visitor/HandleJassTypeVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/visitor/HandleTypeSuperTypeLoadingVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/visitor/IntegerJassValueVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/visitor/JassFunctionJassValueVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/visitor/JassTypeGettingValueVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/visitor/NotJassValueVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/visitor/ObjectJassValueVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/visitor/RealJassValueVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/visitor/StringJassValueVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/value/visitor/SuperTypeVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/visitors/ArgumentExpressionHandler.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/visitors/JassArgumentsVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/visitors/JassExpressionVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/visitors/JassGlobalsVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/visitors/JassParametersVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/visitors/JassProgramVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/visitors/JassStatementVisitor.java delete mode 100644 jassparser/src/com/etheller/interpreter/ast/visitors/JassTypeVisitor.java diff --git a/jassparser/.gitignore b/jassparser/.gitignore deleted file mode 100644 index 84c048a7..00000000 --- a/jassparser/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build/ diff --git a/jassparser/antlr-src/Jass.g4 b/jassparser/antlr-src/Jass.g4 deleted file mode 100644 index cab4935b..00000000 --- a/jassparser/antlr-src/Jass.g4 +++ /dev/null @@ -1,200 +0,0 @@ -/** - * Define a grammar called Hello - */ -grammar Jass; - -@header { - package com.etheller.interpreter; -} - - -program : - newlines - | - newlines_opt - typeDefinitionBlock - (block)* - (functionBlock)* - ; - -typeDefinition : - TYPE ID EXTENDS ID newlines - ; - -type : - ID # BasicType - | - ID ARRAY # ArrayType - | - NOTHING # NothingType - ; - -global : - CONSTANT? type ID newlines # BasicGlobal - | - CONSTANT? type ID assignTail newlines # DefinitionGlobal - ; - -assignTail: - EQUALS expression; - -expression: - ID # ReferenceExpression - | - STRING_LITERAL #StringLiteralExpression - | - INTEGER #IntegerLiteralExpression - | - FUNCTION ID #FunctionReferenceExpression - | - NULL # NullExpression - | - TRUE # TrueExpression - | - FALSE # FalseExpression - | - ID '[' expression ']' # ArrayReferenceExpression - | - functionExpression # FunctionCallExpression - | - '(' expression ')' # ParentheticalExpression - | - NOT expression # NotExpression - ; - -functionExpression: - ID '(' argsList ')' - | - ID '(' ')' - ; - -argsList: - expression # SingleArgument - | - expression ',' argsList # ListArgument - ; - -//#booleanExpression: -// simpleArithmeticExpression # PassBooleanThroughExpression -// | - -statement: - CALL functionExpression newlines #CallStatement - | - SET ID EQUALS expression newlines #SetStatement - | - SET ID '[' expression ']' EQUALS expression newlines # ArrayedAssignmentStatement - | - RETURN expression newlines # ReturnStatement - | - IF ifStatementPartial # IfStatement - ; - -ifStatementPartial: - expression THEN newlines statements ENDIF newlines # SimpleIfStatement - | - expression THEN newlines statements ELSE newlines statements ENDIF newlines # IfElseStatement - | - expression THEN newlines statements ELSEIF ifStatementPartial # IfElseIfStatement - ; - -param: - type ID; - -paramList: - param # SingleParameter - | - param ',' paramList # ListParameter - | - NOTHING # NothingParameter - ; - -globalsBlock : - GLOBALS newlines (global)* ENDGLOBALS newlines ; - -typeDefinitionBlock : - (typeDefinition)* - ; - -nativeBlock: - CONSTANT? NATIVE ID TAKES paramList RETURNS type newlines - ; - -block: - globalsBlock - | - nativeBlock - ; - -functionBlock: - FUNCTION ID TAKES paramList RETURNS type newlines statements ENDFUNCTION newlines - ; - -statements: - (statement)* - ; - -newlines: - pnewlines - | - EOF; - -newlines_opt: - pnewlines - | - EOF - | - ; - -pnewlines: - NEWLINE - | - NEWLINE newlines - ; - -EQUALS : '='; - - -GLOBALS : 'globals' ; // globals -ENDGLOBALS : 'endglobals' ; // end globals block - -NATIVE : 'native' ; - -FUNCTION : 'function' ; // function -TAKES : 'takes' ; // takes -RETURNS : 'returns' ; -ENDFUNCTION : 'endfunction' ; // endfunction -NOTHING : 'nothing' ; - -CALL : 'call' ; -SET : 'set' ; -RETURN : 'return' ; - -ARRAY : 'array' ; - -TYPE : 'type'; - -EXTENDS : 'extends'; - -IF : 'if'; -THEN : 'then'; -ELSE : 'else'; -ENDIF : 'endif'; -ELSEIF : 'elseif'; -CONSTANT : 'constant'; - -STRING_LITERAL : ('"'.*?'"'); - -INTEGER : [0]|([1-9][0-9]*) ; - -NULL : 'null' ; -TRUE : 'true' ; -FALSE : 'false' ; - -NOT : 'not'; - -ID : ([a-zA-Z_][a-zA-Z_0-9]*) ; // match identifiers - -WS : [ \t]+ -> skip ; // skip spaces, tabs - -NEWLINE : '//'.*?'\r\n' | '//'.*?'\n' | '//'.*?'\r' | '\r' '\n' | '\n' | '\r'; diff --git a/jassparser/build.gradle b/jassparser/build.gradle deleted file mode 100644 index e12bfa45..00000000 --- a/jassparser/build.gradle +++ /dev/null @@ -1,49 +0,0 @@ -apply plugin: "antlr" - -sourceCompatibility = 1.8 -[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' - -sourceSets.main.java.srcDirs = [ "src/", "build/generated-src" ] -sourceSets.main.antlr.srcDirs = [ "antlr-src/" ] - -project.ext.mainClassName = "com.etheller.warsmash.jassparser.Main" - -task run(dependsOn: classes, type: JavaExec) { - main = project.mainClassName - classpath = sourceSets.main.runtimeClasspath - standardInput = System.in - ignoreExitValue = true -} - -task dist(type: Jar) { - from files(sourceSets.main.output.classesDir) - from files(sourceSets.main.output.resourcesDir) - from {configurations.compile.collect {zipTree(it)}} - - manifest { - attributes 'Main-Class': project.mainClassName - } -} - -dist.dependsOn classes - -eclipse.project { - name = appName + "-jassparser" -} - -task afterEclipseImport(description: "Post processing after project generation", group: "IDE") { - doLast { - def classpath = new XmlParser().parse(file(".classpath")) - def writer = new FileWriter(file(".classpath")) - def printer = new XmlNodePrinter(new PrintWriter(writer)) - printer.setPreserveWhitespace(true) - printer.print(classpath) - } -} - - -generateGrammarSource { - maxHeapSize = "64m" - arguments += ["-visitor", "-no-listener"] - outputDirectory = file("build/generated-src/com/etheller/warsmash/jassparser") -} \ No newline at end of file diff --git a/jassparser/src/com/etheller/interpreter/ast/Assignable.java b/jassparser/src/com/etheller/interpreter/ast/Assignable.java deleted file mode 100644 index 0bc72622..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/Assignable.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.etheller.interpreter.ast; - -import com.etheller.interpreter.ast.value.JassType; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.visitor.JassTypeGettingValueVisitor; - -public class Assignable { - private JassValue value; - private final JassType type; - - public Assignable(final JassType type) { - this.type = type; - } - - public void setValue(final JassValue value) { - final JassType valueType = value.visit(JassTypeGettingValueVisitor.getInstance()); - if (!this.type.isAssignableFrom(valueType)) { - throw new RuntimeException("Incompatible types " + valueType.getName() + " != " + this.type.getName()); - } - this.value = value; - } - - public JassValue getValue() { - return this.value; - } - - public JassType getType() { - return this.type; - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/JassRunner.java b/jassparser/src/com/etheller/interpreter/ast/JassRunner.java deleted file mode 100644 index 5470c69e..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/JassRunner.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.etheller.interpreter.ast; - -import org.antlr.v4.runtime.BaseErrorListener; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; - -import com.etheller.interpreter.JassLexer; -import com.etheller.interpreter.JassParser; -import com.etheller.interpreter.ast.visitors.JassProgramVisitor; - -public class JassRunner { - public static final boolean REPORT_SYNTAX_ERRORS = true; - - public static void main(final String[] args) { - if (args.length < 1) { - System.err.println("Usage: [...]"); - return; - } - final JassProgramVisitor jassProgramVisitor = new JassProgramVisitor(); - for (final String arg : args) { - try { - final JassLexer lexer = new JassLexer(CharStreams.fromFileName(arg)); - final JassParser parser = new JassParser(new CommonTokenStream(lexer)); - parser.addErrorListener(new BaseErrorListener() { - @Override - public void syntaxError(final Recognizer recognizer, final Object offendingSymbol, - final int line, final int charPositionInLine, final String msg, - final RecognitionException e) { - if (!REPORT_SYNTAX_ERRORS) { - return; - } - - String sourceName = recognizer.getInputStream().getSourceName(); - if (!sourceName.isEmpty()) { - sourceName = String.format("%s:%d:%d: ", sourceName, line, charPositionInLine); - } - - System.err.println(sourceName + "line " + line + ":" + charPositionInLine + " " + msg); - } - }); - jassProgramVisitor.visit(parser.program()); - } catch (final Exception e) { - e.printStackTrace(); - } - } - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/expression/ArrayRefJassExpression.java b/jassparser/src/com/etheller/interpreter/ast/expression/ArrayRefJassExpression.java deleted file mode 100644 index 175cc196..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/expression/ArrayRefJassExpression.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.etheller.interpreter.ast.expression; - -import com.etheller.interpreter.ast.Assignable; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.ArrayJassValue; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.visitor.ArrayJassValueVisitor; -import com.etheller.interpreter.ast.value.visitor.IntegerJassValueVisitor; - -public class ArrayRefJassExpression implements JassExpression { - private final String identifier; - private final JassExpression indexExpression; - - public ArrayRefJassExpression(final String identifier, final JassExpression indexExpression) { - this.identifier = identifier; - this.indexExpression = indexExpression; - } - - @Override - public JassValue evaluate(final GlobalScope globalScope, final LocalScope localScope, - final TriggerExecutionScope triggerScope) { - Assignable variable = localScope.getAssignableLocal(this.identifier); - final JassValue index = this.indexExpression.evaluate(globalScope, localScope, triggerScope); - if (variable == null) { - variable = globalScope.getAssignableGlobal(this.identifier); - } - if (variable.getValue() == null) { - throw new RuntimeException("Unable to use subscript on uninitialized variable"); - } - final ArrayJassValue arrayValue = variable.getValue().visit(ArrayJassValueVisitor.getInstance()); - if (arrayValue != null) { - return arrayValue.get(index.visit(IntegerJassValueVisitor.getInstance())); - } - else { - throw new RuntimeException("Not an array"); - } - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/expression/FunctionCallJassExpression.java b/jassparser/src/com/etheller/interpreter/ast/expression/FunctionCallJassExpression.java deleted file mode 100644 index 7d87b6a0..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/expression/FunctionCallJassExpression.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.etheller.interpreter.ast.expression; - -import java.util.ArrayList; -import java.util.List; - -import com.etheller.interpreter.ast.function.JassFunction; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassValue; - -public class FunctionCallJassExpression implements JassExpression { - private final String functionName; - private final List arguments; - - public FunctionCallJassExpression(final String functionName, final List arguments) { - this.functionName = functionName; - this.arguments = arguments; - } - - @Override - public JassValue evaluate(final GlobalScope globalScope, final LocalScope localScope, - final TriggerExecutionScope triggerScope) { - final JassFunction functionByName = globalScope.getFunctionByName(this.functionName); - if (functionByName == null) { - throw new RuntimeException("Undefined function: " + this.functionName); - } - final List evaluatedExpressions = new ArrayList<>(); - for (final JassExpression expr : this.arguments) { - final JassValue evaluatedExpression = expr.evaluate(globalScope, localScope, triggerScope); - evaluatedExpressions.add(evaluatedExpression); - } - return functionByName.call(evaluatedExpressions, globalScope, triggerScope); - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/expression/FunctionReferenceJassExpression.java b/jassparser/src/com/etheller/interpreter/ast/expression/FunctionReferenceJassExpression.java deleted file mode 100644 index 3fac3ffa..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/expression/FunctionReferenceJassExpression.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.etheller.interpreter.ast.expression; - -import com.etheller.interpreter.ast.function.JassFunction; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.CodeJassValue; -import com.etheller.interpreter.ast.value.JassValue; - -public class FunctionReferenceJassExpression implements JassExpression { - private final String identifier; - - public FunctionReferenceJassExpression(final String identifier) { - this.identifier = identifier; - } - - @Override - public JassValue evaluate(final GlobalScope globalScope, final LocalScope localScope, - final TriggerExecutionScope triggerScope) { - final JassFunction functionByName = globalScope.getFunctionByName(this.identifier); - if (functionByName == null) { - throw new RuntimeException("Unable to find function: " + this.identifier); - } - return new CodeJassValue(functionByName); - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/expression/JassExpression.java b/jassparser/src/com/etheller/interpreter/ast/expression/JassExpression.java deleted file mode 100644 index d9e16ea3..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/expression/JassExpression.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.etheller.interpreter.ast.expression; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassValue; - -public interface JassExpression { - JassValue evaluate(GlobalScope globalScope, LocalScope localScope, TriggerExecutionScope triggerScope); -} diff --git a/jassparser/src/com/etheller/interpreter/ast/expression/LiteralJassExpression.java b/jassparser/src/com/etheller/interpreter/ast/expression/LiteralJassExpression.java deleted file mode 100644 index 426c3d35..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/expression/LiteralJassExpression.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.etheller.interpreter.ast.expression; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassValue; - -public class LiteralJassExpression implements JassExpression { - private final JassValue value; - - public LiteralJassExpression(final JassValue value) { - this.value = value; - } - - @Override - public JassValue evaluate(final GlobalScope globalScope, final LocalScope localScope, - final TriggerExecutionScope triggerScope) { - return this.value; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/expression/NotJassExpression.java b/jassparser/src/com/etheller/interpreter/ast/expression/NotJassExpression.java deleted file mode 100644 index eff46dfc..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/expression/NotJassExpression.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.etheller.interpreter.ast.expression; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.visitor.NotJassValueVisitor; - -public class NotJassExpression implements JassExpression { - private final JassExpression expression; - - public NotJassExpression(final JassExpression expression) { - this.expression = expression; - } - - @Override - public JassValue evaluate(final GlobalScope globalScope, final LocalScope localScope, - final TriggerExecutionScope triggerScope) { - return this.expression.evaluate(globalScope, localScope, triggerScope).visit(NotJassValueVisitor.getInstance()); - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/expression/ReferenceJassExpression.java b/jassparser/src/com/etheller/interpreter/ast/expression/ReferenceJassExpression.java deleted file mode 100644 index 2df08316..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/expression/ReferenceJassExpression.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.etheller.interpreter.ast.expression; - -import com.etheller.interpreter.ast.Assignable; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassValue; - -public class ReferenceJassExpression implements JassExpression { - private final String identifier; - - public ReferenceJassExpression(final String identifier) { - this.identifier = identifier; - } - - @Override - public JassValue evaluate(final GlobalScope globalScope, final LocalScope localScope, - final TriggerExecutionScope triggerScope) { - final Assignable local = localScope.getAssignableLocal(this.identifier); - if (local == null) { - return globalScope.getGlobal(this.identifier); - } - return local.getValue(); - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/function/AbstractJassFunction.java b/jassparser/src/com/etheller/interpreter/ast/function/AbstractJassFunction.java deleted file mode 100644 index af9107f5..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/function/AbstractJassFunction.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.etheller.interpreter.ast.function; - -import java.util.List; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassType; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.visitor.JassTypeGettingValueVisitor; - -/** - * Not a native - * - * @author Eric - * - */ -public abstract class AbstractJassFunction implements JassFunction { - protected final List parameters; - protected final JassType returnType; - - public AbstractJassFunction(final List parameters, final JassType returnType) { - this.parameters = parameters; - this.returnType = returnType; - } - - @Override - public final JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - if (arguments.size() != this.parameters.size()) { - throw new RuntimeException("Invalid number of arguments passed to function"); - } - final LocalScope localScope = new LocalScope(); - for (int i = 0; i < this.parameters.size(); i++) { - final JassParameter parameter = this.parameters.get(i); - final JassValue argument = arguments.get(i); - if (!parameter.matchesType(argument)) { - System.err.println( - parameter.getType() + " != " + argument.visit(JassTypeGettingValueVisitor.getInstance())); - throw new RuntimeException( - "Invalid type " + argument.visit(JassTypeGettingValueVisitor.getInstance()).getName() - + " for specified argument " + parameter.getType().getName()); - } - localScope.createLocal(parameter.getIdentifier(), parameter.getType(), argument); - } - return innerCall(arguments, globalScope, triggerScope, localScope); - } - - protected abstract JassValue innerCall(final List arguments, final GlobalScope globalScope, - TriggerExecutionScope triggerScope, final LocalScope localScope); -} diff --git a/jassparser/src/com/etheller/interpreter/ast/function/JassFunction.java b/jassparser/src/com/etheller/interpreter/ast/function/JassFunction.java deleted file mode 100644 index b4878ae5..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/function/JassFunction.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.etheller.interpreter.ast.function; - -import java.util.List; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassValue; - -public interface JassFunction { - JassValue call(List arguments, GlobalScope globalScope, TriggerExecutionScope triggerScope); -} diff --git a/jassparser/src/com/etheller/interpreter/ast/function/JassNativeManager.java b/jassparser/src/com/etheller/interpreter/ast/function/JassNativeManager.java deleted file mode 100644 index 931c9189..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/function/JassNativeManager.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.etheller.interpreter.ast.function; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.value.JassType; - -public class JassNativeManager { - private final Map nameToNativeCode; - private final Set registeredNativeNames = new HashSet<>(); - - public JassNativeManager() { - this.nameToNativeCode = new HashMap<>(); - } - - public void createNative(final String name, final JassFunction nativeCode) { - this.nameToNativeCode.put(name, nativeCode); - } - - public void registerNativeCode(final String name, final List parameters, final JassType returnType, - final GlobalScope globals) { - if (this.registeredNativeNames.contains(name)) { - throw new RuntimeException("Native already registered: " + name); - } - final JassFunction nativeCode = this.nameToNativeCode.remove(name); - globals.defineFunction(name, new NativeJassFunction(parameters, returnType, name, nativeCode)); - this.registeredNativeNames.add(name); - } - - public void checkUnregisteredNatives() { - // TODO maybe do this later - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/function/JassParameter.java b/jassparser/src/com/etheller/interpreter/ast/function/JassParameter.java deleted file mode 100644 index f9c460c7..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/function/JassParameter.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.etheller.interpreter.ast.function; - -import com.etheller.interpreter.ast.value.JassType; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.visitor.JassTypeGettingValueVisitor; - -public class JassParameter { - private final JassType type; - private final String identifier; - - public JassParameter(final JassType type, final String identifier) { - this.type = type; - this.identifier = identifier; - } - - public String getIdentifier() { - return this.identifier; - } - - public JassType getType() { - return this.type; - } - - public boolean matchesType(final JassValue value) { - final JassType valueType = value.visit(JassTypeGettingValueVisitor.getInstance()); - return this.type.isAssignableFrom(valueType); - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/function/NativeJassFunction.java b/jassparser/src/com/etheller/interpreter/ast/function/NativeJassFunction.java deleted file mode 100644 index 1cfbf0d8..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/function/NativeJassFunction.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.etheller.interpreter.ast.function; - -import java.util.List; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassType; -import com.etheller.interpreter.ast.value.JassValue; - -public class NativeJassFunction extends AbstractJassFunction { - private final String name; - private final JassFunction implementation; - - public NativeJassFunction(final List parameters, final JassType returnType, final String name, - final JassFunction impl) { - super(parameters, returnType); - this.name = name; - this.implementation = impl; - } - - @Override - protected JassValue innerCall(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope, final LocalScope localScope) { - return this.implementation.call(arguments, globalScope, triggerScope); - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/function/UserJassFunction.java b/jassparser/src/com/etheller/interpreter/ast/function/UserJassFunction.java deleted file mode 100644 index 92dff1f2..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/function/UserJassFunction.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.etheller.interpreter.ast.function; - -import java.util.List; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.statement.JassStatement; -import com.etheller.interpreter.ast.value.JassType; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.visitor.JassTypeGettingValueVisitor; - -/** - * Not a native - * - * @author Eric - * - */ -public final class UserJassFunction extends AbstractJassFunction { - private final List statements; - - public UserJassFunction(final List statements, final List parameters, - final JassType returnType) { - super(parameters, returnType); - this.statements = statements; - } - - @Override - public JassValue innerCall(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope, final LocalScope localScope) { - for (final JassStatement statement : this.statements) { - final JassValue returnValue = statement.execute(globalScope, localScope, triggerScope); - if (returnValue != null) { - if (returnValue.visit(JassTypeGettingValueVisitor.getInstance()) != this.returnType) { - throw new RuntimeException("Invalid return type"); - } - return returnValue; - } - } - if (JassType.NOTHING != this.returnType) { - throw new RuntimeException("Invalid return type"); - } - return null; - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/scope/GlobalScope.java b/jassparser/src/com/etheller/interpreter/ast/scope/GlobalScope.java deleted file mode 100644 index fa7cf072..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/scope/GlobalScope.java +++ /dev/null @@ -1,162 +0,0 @@ -package com.etheller.interpreter.ast.scope; - -import java.util.HashMap; -import java.util.Map; - -import com.etheller.interpreter.ast.Assignable; -import com.etheller.interpreter.ast.function.JassFunction; -import com.etheller.interpreter.ast.scope.trigger.RemovableTriggerEvent; -import com.etheller.interpreter.ast.scope.trigger.Trigger; -import com.etheller.interpreter.ast.scope.variableevent.CLimitOp; -import com.etheller.interpreter.ast.scope.variableevent.VariableEvent; -import com.etheller.interpreter.ast.value.ArrayJassType; -import com.etheller.interpreter.ast.value.ArrayJassValue; -import com.etheller.interpreter.ast.value.HandleJassType; -import com.etheller.interpreter.ast.value.JassType; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.PrimitiveJassType; -import com.etheller.interpreter.ast.value.visitor.ArrayPrimitiveTypeVisitor; -import com.etheller.interpreter.ast.value.visitor.HandleJassTypeVisitor; -import com.etheller.interpreter.ast.value.visitor.HandleTypeSuperTypeLoadingVisitor; - -public final class GlobalScope { - private final Map globals = new HashMap<>(); - private final Map functions = new HashMap<>(); - private final Map types = new HashMap<>(); - private final HandleTypeSuperTypeLoadingVisitor handleTypeSuperTypeLoadingVisitor = new HandleTypeSuperTypeLoadingVisitor(); - - public final HandleJassType handleType; - - private static int lineNumber; - - public GlobalScope() { - this.handleType = registerHandleType("handle");// the handle type - registerPrimitiveType(JassType.BOOLEAN); - registerPrimitiveType(JassType.INTEGER); - registerPrimitiveType(JassType.CODE); - registerPrimitiveType(JassType.NOTHING); - registerPrimitiveType(JassType.REAL); - registerPrimitiveType(JassType.STRING); - } - - public static void setLineNumber(final int lineNo) { - lineNumber = lineNo; - } - - public static int getLineNumber() { - return lineNumber; - } - - public HandleJassType registerHandleType(final String name) { - final HandleJassType handleJassType = new HandleJassType(null, name); - this.types.put(name, handleJassType); - return handleJassType; - } - - private void registerPrimitiveType(final PrimitiveJassType type) { - this.types.put(type.getName(), type); - } - - public void createGlobalArray(final String name, final JassType type) { - final GlobalScopeAssignable assignable = new GlobalScopeAssignable(type, this); - assignable.setValue(new ArrayJassValue((ArrayJassType) type)); // TODO less bad code - this.globals.put(name, assignable); - } - - public void createGlobal(final String name, final JassType type) { - this.globals.put(name, new GlobalScopeAssignable(type, this)); - } - - public void createGlobal(final String name, final JassType type, final JassValue value) { - final GlobalScopeAssignable assignable = new GlobalScopeAssignable(type, this); - assignable.setValue(value); - this.globals.put(name, assignable); - } - - public void setGlobal(final String name, final JassValue value) { - final GlobalScopeAssignable assignable = this.globals.get(name); - if (assignable == null) { - throw new RuntimeException("Undefined global: " + name); - } - if (assignable.getType().visit(ArrayPrimitiveTypeVisitor.getInstance()) != null) { - throw new RuntimeException("Unable to assign array variable: " + name); - } - assignable.setValue(value); - } - - public JassValue getGlobal(final String name) { - final Assignable global = this.globals.get(name); - if (global == null) { - throw new RuntimeException("Undefined global: " + name); - } - return global.getValue(); - } - - public GlobalScopeAssignable getAssignableGlobal(final String name) { - return this.globals.get(name); - } - - public void defineFunction(final String name, final JassFunction function) { - this.functions.put(name, function); - } - - public JassFunction getFunctionByName(final String name) { - return this.functions.get(name); - } - - public JassType parseType(final String text) { - final JassType type = this.types.get(text); - if (type != null) { - return type; - } - else { - throw new RuntimeException("Unknown type: " + text); - } - } - - public JassType parseArrayType(final String primitiveTypeName) { - final String arrayTypeName = primitiveTypeName + " array"; - JassType arrayType = this.types.get(arrayTypeName); - if (arrayType == null) { - arrayType = new ArrayJassType(parseType(primitiveTypeName)); - this.types.put(arrayTypeName, arrayType); - } - return arrayType; - } - - public void loadTypeDefinition(final String type, final String supertype) { - final JassType superType = this.types.get(supertype); - if (superType != null) { - final HandleJassType handleSuperType = superType.visit(HandleJassTypeVisitor.getInstance()); - if (handleSuperType != null) { - final JassType jassType = this.types.get(type); - if (jassType != null) { - jassType.visit(this.handleTypeSuperTypeLoadingVisitor.reset(handleSuperType)); - } - else { - throw new RuntimeException( - "unable to declare type " + type + " because it does not exist natively"); - } - } - else { - throw new RuntimeException("type " + type + " cannot extend primitive type " + supertype); - } - } - else { - throw new RuntimeException("type " + type + " cannot extend unknown type " + supertype); - } - } - - public RemovableTriggerEvent registerVariableEvent(final Trigger trigger, final String varName, - final CLimitOp limitOp, final double doubleValue) { - final VariableEvent variableEvent = new VariableEvent(trigger, limitOp, doubleValue); - final GlobalScopeAssignable assignableGlobal = getAssignableGlobal(varName); - assignableGlobal.add(variableEvent); - return new RemovableTriggerEvent() { - @Override - public void remove() { - assignableGlobal.remove(variableEvent); - } - }; - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/scope/GlobalScopeAssignable.java b/jassparser/src/com/etheller/interpreter/ast/scope/GlobalScopeAssignable.java deleted file mode 100644 index 029b44e2..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/scope/GlobalScopeAssignable.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.etheller.interpreter.ast.scope; - -import java.util.ArrayList; -import java.util.List; - -import com.etheller.interpreter.ast.Assignable; -import com.etheller.interpreter.ast.scope.variableevent.VariableEvent; -import com.etheller.interpreter.ast.value.JassType; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.visitor.RealJassValueVisitor; - -public class GlobalScopeAssignable extends Assignable { - private final List variableEvents = new ArrayList<>(); - private final GlobalScope globalScope; - - public GlobalScopeAssignable(final JassType type, final GlobalScope globalScope) { - super(type); - this.globalScope = globalScope; - } - - @Override - public void setValue(final JassValue value) { - final JassValue prevValue = getValue(); - super.setValue(value); - if (!this.variableEvents.isEmpty()) { - final Double prevReal = prevValue.visit(RealJassValueVisitor.getInstance()); - final Double newReal = value.visit(RealJassValueVisitor.getInstance()); - for (final VariableEvent variableEvent : this.variableEvents) { - if (!variableEvent.isMatching(prevReal.doubleValue()) - && variableEvent.isMatching(newReal.doubleValue())) { - variableEvent.fire(this.globalScope); - } - } - } - } - - public void add(final VariableEvent variableEvent) { - this.variableEvents.add(variableEvent); - } - - public void remove(final VariableEvent variableEvent) { - this.variableEvents.remove(variableEvent); - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/scope/LocalScope.java b/jassparser/src/com/etheller/interpreter/ast/scope/LocalScope.java deleted file mode 100644 index 1aea3d74..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/scope/LocalScope.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.etheller.interpreter.ast.scope; - -import java.util.HashMap; -import java.util.Map; - -import com.etheller.interpreter.ast.Assignable; -import com.etheller.interpreter.ast.value.JassType; -import com.etheller.interpreter.ast.value.JassValue; - -public final class LocalScope { - private final Map locals = new HashMap<>(); - - public void createLocal(final String name, final JassType type) { - this.locals.put(name, new Assignable(type)); - } - - public void createLocal(final String name, final JassType type, final JassValue value) { - final Assignable assignable = new Assignable(type); - assignable.setValue(value); - this.locals.put(name, assignable); - } - - public void setLocal(final String name, final JassValue value) { - final Assignable assignable = this.locals.get(name); - if (assignable == null) { - throw new RuntimeException("Undefined local variable: " + name); - } - assignable.setValue(value); - } - - public JassValue getLocal(final String name) { - final Assignable local = this.locals.get(name); - if (local == null) { - throw new RuntimeException("Undefined local variable: " + name); - } - return local.getValue(); - } - - public Assignable getAssignableLocal(final String name) { - return this.locals.get(name); - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/scope/TriggerExecutionScope.java b/jassparser/src/com/etheller/interpreter/ast/scope/TriggerExecutionScope.java deleted file mode 100644 index e9799edf..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/scope/TriggerExecutionScope.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.etheller.interpreter.ast.scope; - -import com.etheller.interpreter.ast.scope.trigger.Trigger; - -public class TriggerExecutionScope { - public static final TriggerExecutionScope EMPTY = new TriggerExecutionScope(null); - - private final Trigger triggeringTrigger; - - public TriggerExecutionScope(final Trigger triggeringTrigger) { - this.triggeringTrigger = triggeringTrigger; - } - - public Trigger getTriggeringTrigger() { - return this.triggeringTrigger; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/scope/TypeDefinition.java b/jassparser/src/com/etheller/interpreter/ast/scope/TypeDefinition.java deleted file mode 100644 index 1331a96d..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/scope/TypeDefinition.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.etheller.interpreter.ast.scope; - -public class TypeDefinition { - private final String name; - private final String supertype; - - public TypeDefinition(final String name, final String supertype) { - this.name = name; - this.supertype = supertype; - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/scope/trigger/RemovableTriggerEvent.java b/jassparser/src/com/etheller/interpreter/ast/scope/trigger/RemovableTriggerEvent.java deleted file mode 100644 index 9606e3a3..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/scope/trigger/RemovableTriggerEvent.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.etheller.interpreter.ast.scope.trigger; - -public interface RemovableTriggerEvent { - void remove(); - - RemovableTriggerEvent DO_NOTHING = new RemovableTriggerEvent() { - @Override - public void remove() { - } - }; -} diff --git a/jassparser/src/com/etheller/interpreter/ast/scope/trigger/Trigger.java b/jassparser/src/com/etheller/interpreter/ast/scope/trigger/Trigger.java deleted file mode 100644 index aca40c4d..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/scope/trigger/Trigger.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.etheller.interpreter.ast.scope.trigger; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.etheller.interpreter.ast.function.JassFunction; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; - -public class Trigger { - private final List conditions = new ArrayList<>(); - private final List actions = new ArrayList<>(); - private int evalCount; - private int execCount; - private boolean enabled = true; - // used for eval - private transient final TriggerExecutionScope triggerExecutionScope = new TriggerExecutionScope(this); - private boolean waitOnSleeps = true; - - public int addAction(final JassFunction function) { - final int index = this.actions.size(); - this.actions.add(function); - return index; - } - - public int addCondition(final TriggerBooleanExpression boolexpr) { - final int index = this.conditions.size(); - this.conditions.add(boolexpr); - return index; - } - - public void removeCondition(final TriggerBooleanExpression boolexpr) { - this.conditions.remove(boolexpr); - } - - public void removeConditionAtIndex(final int conditionIndex) { - this.conditions.remove(conditionIndex); - } - - public int getEvalCount() { - return this.evalCount; - } - - public int getExecCount() { - return this.execCount; - } - - public boolean evaluate(final GlobalScope globalScope, final TriggerExecutionScope triggerScope) { - for (final TriggerBooleanExpression condition : this.conditions) { - if (!condition.evaluate(globalScope, triggerScope)) { - return false; - } - } - return true; - } - - public void execute(final GlobalScope globalScope, final TriggerExecutionScope triggerScope) { - for (final JassFunction action : this.actions) { - action.call(Collections.emptyList(), globalScope, triggerScope); - } - } - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(final boolean enabled) { - this.enabled = enabled; - } - - public void destroy() { - - } - - public void reset() { - this.actions.clear(); - this.conditions.clear(); - this.evalCount = 0; - this.execCount = 0; - this.enabled = true; - this.waitOnSleeps = true; - } - - public void setWaitOnSleeps(final boolean waitOnSleeps) { - this.waitOnSleeps = waitOnSleeps; - } - - public boolean isWaitOnSleeps() { - return this.waitOnSleeps; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/scope/trigger/TriggerBooleanExpression.java b/jassparser/src/com/etheller/interpreter/ast/scope/trigger/TriggerBooleanExpression.java deleted file mode 100644 index 84633175..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/scope/trigger/TriggerBooleanExpression.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.etheller.interpreter.ast.scope.trigger; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; - -public interface TriggerBooleanExpression { - boolean evaluate(GlobalScope globalScope, TriggerExecutionScope triggerScope); -} diff --git a/jassparser/src/com/etheller/interpreter/ast/scope/variableevent/CLimitOp.java b/jassparser/src/com/etheller/interpreter/ast/scope/variableevent/CLimitOp.java deleted file mode 100644 index ca34cbcd..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/scope/variableevent/CLimitOp.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.etheller.interpreter.ast.scope.variableevent; - -public enum CLimitOp { - LESS_THAN, - LESS_THAN_OR_EQUAL, - EQUAL, - GREATER_THAN_OR_EQUAL, - GREATER_THAN, - NOT_EQUAL; - - public static CLimitOp[] VALUES = values(); -} diff --git a/jassparser/src/com/etheller/interpreter/ast/scope/variableevent/VariableEvent.java b/jassparser/src/com/etheller/interpreter/ast/scope/variableevent/VariableEvent.java deleted file mode 100644 index 19496d0f..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/scope/variableevent/VariableEvent.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.etheller.interpreter.ast.scope.variableevent; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.scope.trigger.Trigger; - -public class VariableEvent { - private final Trigger trigger; - private final CLimitOp limitOp; - private final double doubleValue; - - public VariableEvent(final Trigger trigger, final CLimitOp limitOp, final double doubleValue) { - this.trigger = trigger; - this.limitOp = limitOp; - this.doubleValue = doubleValue; - } - - public Trigger getTrigger() { - return this.trigger; - } - - public CLimitOp getLimitOp() { - return this.limitOp; - } - - public double getDoubleValue() { - return this.doubleValue; - } - - public boolean isMatching(final double realValue) { - switch (this.limitOp) { - case EQUAL: - return this.doubleValue == realValue; // TODO probably bad, probably needs epsilon comparison, but what's - // our default epsilon for this case? - case GREATER_THAN: - return realValue > this.doubleValue; - case GREATER_THAN_OR_EQUAL: - return realValue >= this.doubleValue; - case LESS_THAN: - return realValue < this.doubleValue; - case LESS_THAN_OR_EQUAL: - return realValue <= this.doubleValue; - case NOT_EQUAL: - return realValue != this.doubleValue; - } - throw new IllegalStateException(); - } - - public void fire(final GlobalScope globalScope) { - final TriggerExecutionScope triggerScope = new TriggerExecutionScope(this.trigger); - if (this.trigger.evaluate(globalScope, triggerScope)) { - this.trigger.execute(globalScope, triggerScope); - } - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/statement/JassArrayedAssignmentStatement.java b/jassparser/src/com/etheller/interpreter/ast/statement/JassArrayedAssignmentStatement.java deleted file mode 100644 index 5b80156a..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/statement/JassArrayedAssignmentStatement.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.etheller.interpreter.ast.statement; - -import com.etheller.interpreter.ast.Assignable; -import com.etheller.interpreter.ast.expression.JassExpression; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.ArrayJassValue; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.visitor.ArrayJassValueVisitor; -import com.etheller.interpreter.ast.value.visitor.IntegerJassValueVisitor; - -public class JassArrayedAssignmentStatement implements JassStatement { - private final String identifier; - private final JassExpression indexExpression; - private final JassExpression expression; - private final int lineNo; - - public JassArrayedAssignmentStatement(final int lineNo, final String identifier, - final JassExpression indexExpression, final JassExpression expression) { - this.lineNo = lineNo; - this.identifier = identifier; - this.indexExpression = indexExpression; - this.expression = expression; - } - - @Override - public JassValue execute(final GlobalScope globalScope, final LocalScope localScope, - final TriggerExecutionScope triggerScope) { - globalScope.setLineNumber(this.lineNo); - Assignable variable = localScope.getAssignableLocal(this.identifier); - final JassValue index = this.indexExpression.evaluate(globalScope, localScope, triggerScope); - if (variable == null) { - variable = globalScope.getAssignableGlobal(this.identifier); - } - if (variable.getValue() == null) { - throw new RuntimeException("Unable to assign uninitialized array"); - } - final ArrayJassValue arrayValue = variable.getValue().visit(ArrayJassValueVisitor.getInstance()); - if (arrayValue != null) { - arrayValue.set(index.visit(IntegerJassValueVisitor.getInstance()), - this.expression.evaluate(globalScope, localScope, triggerScope)); - } - else { - throw new RuntimeException("Not an array"); - } - return null; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/statement/JassCallStatement.java b/jassparser/src/com/etheller/interpreter/ast/statement/JassCallStatement.java deleted file mode 100644 index a5e96357..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/statement/JassCallStatement.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.etheller.interpreter.ast.statement; - -import java.util.ArrayList; -import java.util.List; - -import com.etheller.interpreter.ast.expression.JassExpression; -import com.etheller.interpreter.ast.function.JassFunction; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassValue; - -public class JassCallStatement implements JassStatement { - private final int lineNo; - private final String functionName; - private final List arguments; - - public JassCallStatement(final int lineNo, final String functionName, final List arguments) { - this.lineNo = lineNo; - this.functionName = functionName; - this.arguments = arguments; - } - - @Override - public JassValue execute(final GlobalScope globalScope, final LocalScope localScope, - final TriggerExecutionScope triggerScope) { - globalScope.setLineNumber(this.lineNo); - final JassFunction functionByName = globalScope.getFunctionByName(this.functionName); - if (functionByName == null) { - throw new RuntimeException("Undefined function: " + this.functionName); - } - final List evaluatedExpressions = new ArrayList<>(); - for (final JassExpression expr : this.arguments) { - final JassValue evaluatedExpression = expr.evaluate(globalScope, localScope, triggerScope); - evaluatedExpressions.add(evaluatedExpression); - } - functionByName.call(evaluatedExpressions, globalScope, triggerScope); - // throw away return value - return null; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/statement/JassIfElseIfStatement.java b/jassparser/src/com/etheller/interpreter/ast/statement/JassIfElseIfStatement.java deleted file mode 100644 index 5f1f2082..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/statement/JassIfElseIfStatement.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.etheller.interpreter.ast.statement; - -import java.util.List; - -import com.etheller.interpreter.ast.expression.JassExpression; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.visitor.BooleanJassValueVisitor; - -public class JassIfElseIfStatement implements JassStatement { - private final int lineNo; - private final JassExpression condition; - private final List thenStatements; - private final JassStatement elseifTail; - - public JassIfElseIfStatement(final int lineNo, final JassExpression condition, - final List thenStatements, final JassStatement elseifTail) { - this.lineNo = lineNo; - this.condition = condition; - this.thenStatements = thenStatements; - this.elseifTail = elseifTail; - } - - @Override - public JassValue execute(final GlobalScope globalScope, final LocalScope localScope, - final TriggerExecutionScope triggerScope) { - globalScope.setLineNumber(this.lineNo); - if (this.condition.evaluate(globalScope, localScope, triggerScope) - .visit(BooleanJassValueVisitor.getInstance())) { - for (final JassStatement statement : this.thenStatements) { - final JassValue returnValue = statement.execute(globalScope, localScope, triggerScope); - if (returnValue != null) { - return returnValue; - } - } - } - else { - return this.elseifTail.execute(globalScope, localScope, triggerScope); - } - return null; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/statement/JassIfElseStatement.java b/jassparser/src/com/etheller/interpreter/ast/statement/JassIfElseStatement.java deleted file mode 100644 index 20b97199..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/statement/JassIfElseStatement.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.etheller.interpreter.ast.statement; - -import java.util.List; - -import com.etheller.interpreter.ast.expression.JassExpression; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.visitor.BooleanJassValueVisitor; - -public class JassIfElseStatement implements JassStatement { - private final int lineNo; - private final JassExpression condition; - private final List thenStatements; - private final List elseStatements; - - public JassIfElseStatement(final int lineNo, final JassExpression condition, - final List thenStatements, final List elseStatements) { - this.lineNo = lineNo; - this.condition = condition; - this.thenStatements = thenStatements; - this.elseStatements = elseStatements; - } - - @Override - public JassValue execute(final GlobalScope globalScope, final LocalScope localScope, - final TriggerExecutionScope triggerScope) { - globalScope.setLineNumber(this.lineNo); - if (this.condition.evaluate(globalScope, localScope, triggerScope) - .visit(BooleanJassValueVisitor.getInstance())) { - for (final JassStatement statement : this.thenStatements) { - final JassValue returnValue = statement.execute(globalScope, localScope, triggerScope); - if (returnValue != null) { - return returnValue; - } - } - } - else { - for (final JassStatement statement : this.elseStatements) { - final JassValue returnValue = statement.execute(globalScope, localScope, triggerScope); - if (returnValue != null) { - return returnValue; - } - } - } - return null; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/statement/JassIfStatement.java b/jassparser/src/com/etheller/interpreter/ast/statement/JassIfStatement.java deleted file mode 100644 index abe42a03..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/statement/JassIfStatement.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.etheller.interpreter.ast.statement; - -import java.util.List; - -import com.etheller.interpreter.ast.expression.JassExpression; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.visitor.BooleanJassValueVisitor; - -public class JassIfStatement implements JassStatement { - private final int lineNo; - private final JassExpression condition; - private final List thenStatements; - - public JassIfStatement(final int lineNo, final JassExpression condition, final List thenStatements) { - this.lineNo = lineNo; - this.condition = condition; - this.thenStatements = thenStatements; - } - - public JassExpression getCondition() { - return this.condition; - } - - public List getThenStatements() { - return this.thenStatements; - } - - @Override - public JassValue execute(final GlobalScope globalScope, final LocalScope localScope, - final TriggerExecutionScope triggerScope) { - globalScope.setLineNumber(this.lineNo); - if (this.condition.evaluate(globalScope, localScope, triggerScope) - .visit(BooleanJassValueVisitor.getInstance())) { - for (final JassStatement statement : this.thenStatements) { - final JassValue returnValue = statement.execute(globalScope, localScope, triggerScope); - if (returnValue != null) { - return returnValue; - } - } - } - return null; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/statement/JassReturnStatement.java b/jassparser/src/com/etheller/interpreter/ast/statement/JassReturnStatement.java deleted file mode 100644 index adb1b4e6..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/statement/JassReturnStatement.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.etheller.interpreter.ast.statement; - -import com.etheller.interpreter.ast.expression.JassExpression; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassValue; - -public class JassReturnStatement implements JassStatement { - private final int lineNo; - private final JassExpression expression; - - public JassReturnStatement(final int lineNo, final JassExpression expression) { - this.lineNo = lineNo; - this.expression = expression; - } - - @Override - public JassValue execute(final GlobalScope globalScope, final LocalScope localScope, - final TriggerExecutionScope triggerScope) { - globalScope.setLineNumber(this.lineNo); - return this.expression.evaluate(globalScope, localScope, triggerScope); - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/statement/JassSetStatement.java b/jassparser/src/com/etheller/interpreter/ast/statement/JassSetStatement.java deleted file mode 100644 index e8249d4c..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/statement/JassSetStatement.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.etheller.interpreter.ast.statement; - -import com.etheller.interpreter.ast.Assignable; -import com.etheller.interpreter.ast.expression.JassExpression; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassValue; - -public class JassSetStatement implements JassStatement { - private final int lineNo; - private final String identifier; - private final JassExpression expression; - - public JassSetStatement(final int lineNo, final String identifier, final JassExpression expression) { - this.lineNo = lineNo; - this.identifier = identifier; - this.expression = expression; - } - - @Override - public JassValue execute(final GlobalScope globalScope, final LocalScope localScope, - final TriggerExecutionScope triggerScope) { - globalScope.setLineNumber(this.lineNo); - final Assignable local = localScope.getAssignableLocal(this.identifier); - if (local != null) { - local.setValue(this.expression.evaluate(globalScope, localScope, triggerScope)); - } - else { - globalScope.setGlobal(this.identifier, this.expression.evaluate(globalScope, localScope, triggerScope)); - } - return null; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/statement/JassStatement.java b/jassparser/src/com/etheller/interpreter/ast/statement/JassStatement.java deleted file mode 100644 index 5c2099da..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/statement/JassStatement.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.etheller.interpreter.ast.statement; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.value.JassValue; - -public interface JassStatement { - // When a value is returned, this indicates a RETURN statement, - // and will end outer execution - JassValue execute(GlobalScope globalScope, LocalScope localScope, TriggerExecutionScope triggerScope); -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/ArrayJassType.java b/jassparser/src/com/etheller/interpreter/ast/value/ArrayJassType.java deleted file mode 100644 index 109a5591..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/ArrayJassType.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.etheller.interpreter.ast.value; - -public class ArrayJassType implements JassType { - private final JassType primitiveType; - private final String name; - - public ArrayJassType(final JassType primitiveType) { - this.primitiveType = primitiveType; - this.name = primitiveType.getName() + " array"; - } - - @Override - public boolean isAssignableFrom(final JassType value) { - return value == this; - } - - public JassType getPrimitiveType() { - return this.primitiveType; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public TYPE visit(final JassTypeVisitor visitor) { - return visitor.accept(this); - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/ArrayJassValue.java b/jassparser/src/com/etheller/interpreter/ast/value/ArrayJassValue.java deleted file mode 100644 index 158d8d3d..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/ArrayJassValue.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.etheller.interpreter.ast.value; - -import com.etheller.interpreter.ast.value.visitor.JassTypeGettingValueVisitor; - -public class ArrayJassValue implements JassValue { - private final JassValue[] data = new JassValue[8192]; // that's the array size in JASS - private final ArrayJassType type; - - public ArrayJassValue(final ArrayJassType type) { - this.type = type; - } - - @Override - public TYPE visit(final JassValueVisitor visitor) { - return visitor.accept(this); - } - - public void set(final int index, final JassValue value) { - if (value.visit(JassTypeGettingValueVisitor.getInstance()) != type.getPrimitiveType()) { - throw new IllegalStateException( - "Illegal type for assignment to " + type.getPrimitiveType().getName() + " array"); - } - data[index] = value; - } - - public JassValue get(final int index) { - return data[index]; - } - - public ArrayJassType getType() { - return type; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/BooleanJassValue.java b/jassparser/src/com/etheller/interpreter/ast/value/BooleanJassValue.java deleted file mode 100644 index 602a8f56..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/BooleanJassValue.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.etheller.interpreter.ast.value; - -public class BooleanJassValue implements JassValue { - public static final BooleanJassValue TRUE = new BooleanJassValue(true); - public static final BooleanJassValue FALSE = new BooleanJassValue(false); - - private final boolean value; - - public BooleanJassValue(final boolean value) { - this.value = value; - } - - public boolean getValue() { - return this.value; - } - - @Override - public TYPE visit(final JassValueVisitor visitor) { - return visitor.accept(this); - } - - public static BooleanJassValue inverse(final BooleanJassValue value) { - if (value.value) { - return FALSE; - } - else { - return TRUE; - } - } - - public static BooleanJassValue of(final boolean flag) { - if (flag) { - return TRUE; - } - else { - return FALSE; - } - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/CodeJassValue.java b/jassparser/src/com/etheller/interpreter/ast/value/CodeJassValue.java deleted file mode 100644 index 2858184d..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/CodeJassValue.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.etheller.interpreter.ast.value; - -import com.etheller.interpreter.ast.function.JassFunction; - -public class CodeJassValue implements JassValue { - private final JassFunction value; - - public CodeJassValue(final JassFunction value) { - this.value = value; - } - - public JassFunction getValue() { - return value; - } - - @Override - public TYPE visit(final JassValueVisitor visitor) { - return visitor.accept(this); - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/HandleJassType.java b/jassparser/src/com/etheller/interpreter/ast/value/HandleJassType.java deleted file mode 100644 index bd025fbb..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/HandleJassType.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.etheller.interpreter.ast.value; - -import com.etheller.interpreter.ast.value.visitor.SuperTypeVisitor; - -public class HandleJassType implements JassType { - private HandleJassType superType; - private final String name; - - public HandleJassType(final HandleJassType superType, final String name) { - this.superType = superType; - this.name = name; - } - - @Override - public boolean isAssignableFrom(JassType valueType) { - while (valueType != null) { - if (this == valueType) { - return true; - } - valueType = valueType.visit(SuperTypeVisitor.getInstance()); - } - return false; - } - - @Override - public String getName() { - return this.name; - } - - public HandleJassType getSuperType() { - return this.superType; - } - - public void setSuperType(final HandleJassType superType) { - this.superType = superType; - } - - @Override - public TYPE visit(final JassTypeVisitor visitor) { - return visitor.accept(this); - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/HandleJassValue.java b/jassparser/src/com/etheller/interpreter/ast/value/HandleJassValue.java deleted file mode 100644 index 78032fdd..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/HandleJassValue.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.etheller.interpreter.ast.value; - -public class HandleJassValue implements JassValue { - private final HandleJassType type; - private final Object javaValue; - - public HandleJassValue(final HandleJassType type, final Object javaValue) { - this.type = type; - this.javaValue = javaValue; - } - - public HandleJassType getType() { - return this.type; - } - - public Object getJavaValue() { - return this.javaValue; - } - - @Override - public TYPE visit(final JassValueVisitor visitor) { - return visitor.accept(this); - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/IntegerJassValue.java b/jassparser/src/com/etheller/interpreter/ast/value/IntegerJassValue.java deleted file mode 100644 index bec6cfe9..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/IntegerJassValue.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.etheller.interpreter.ast.value; - -public class IntegerJassValue implements JassValue { - private final int value; - - public IntegerJassValue(final int value) { - this.value = value; - } - - public int getValue() { - return value; - } - - @Override - public TYPE visit(final JassValueVisitor visitor) { - return visitor.accept(this); - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/JassType.java b/jassparser/src/com/etheller/interpreter/ast/value/JassType.java deleted file mode 100644 index c72141e9..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/JassType.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.etheller.interpreter.ast.value; - -public interface JassType { - TYPE visit(JassTypeVisitor visitor); - - String getName(); // used for error messages - - boolean isAssignableFrom(JassType value); - - public static final PrimitiveJassType INTEGER = new PrimitiveJassType("integer"); - public static final PrimitiveJassType STRING = new PrimitiveJassType("string"); - public static final PrimitiveJassType CODE = new PrimitiveJassType("code"); - public static final PrimitiveJassType REAL = new RealJassType("real"); - public static final PrimitiveJassType BOOLEAN = new PrimitiveJassType("boolean"); - public static final PrimitiveJassType NOTHING = new PrimitiveJassType("nothing"); -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/JassTypeVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/JassTypeVisitor.java deleted file mode 100644 index 4d25c5a2..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/JassTypeVisitor.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.interpreter.ast.value; - -public interface JassTypeVisitor { - TYPE accept(PrimitiveJassType primitiveType); - - TYPE accept(ArrayJassType arrayType); - - TYPE accept(HandleJassType type); -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/JassValue.java b/jassparser/src/com/etheller/interpreter/ast/value/JassValue.java deleted file mode 100644 index c1c0c431..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/JassValue.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.interpreter.ast.value; - -public interface JassValue { - TYPE visit(JassValueVisitor visitor); -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/JassValueVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/JassValueVisitor.java deleted file mode 100644 index db03052a..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/JassValueVisitor.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.etheller.interpreter.ast.value; - -public interface JassValueVisitor { - TYPE accept(IntegerJassValue value); - - TYPE accept(RealJassValue value); - - TYPE accept(BooleanJassValue value); - - TYPE accept(StringJassValue value); - - TYPE accept(CodeJassValue value); - - TYPE accept(ArrayJassValue value); - - TYPE accept(HandleJassValue value); -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/PrimitiveJassType.java b/jassparser/src/com/etheller/interpreter/ast/value/PrimitiveJassType.java deleted file mode 100644 index 38bd2507..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/PrimitiveJassType.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.etheller.interpreter.ast.value; - -public class PrimitiveJassType implements JassType { - private final String name; - - public PrimitiveJassType(final String name) { - this.name = name; - } - - @Override - public boolean isAssignableFrom(final JassType value) { - return value == this; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public TYPE visit(final JassTypeVisitor visitor) { - return visitor.accept(this); - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/RealJassType.java b/jassparser/src/com/etheller/interpreter/ast/value/RealJassType.java deleted file mode 100644 index 3e2d66d9..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/RealJassType.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.etheller.interpreter.ast.value; - -public class RealJassType extends PrimitiveJassType { - - public RealJassType(final String name) { - super(name); - } - - @Override - public boolean isAssignableFrom(final JassType value) { - if (value == JassType.INTEGER) { - return true; - } - return super.isAssignableFrom(value); - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/RealJassValue.java b/jassparser/src/com/etheller/interpreter/ast/value/RealJassValue.java deleted file mode 100644 index 49636dc9..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/RealJassValue.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.etheller.interpreter.ast.value; - -public class RealJassValue implements JassValue { - private final double value; - - public RealJassValue(final double value) { - this.value = value; - } - - public double getValue() { - return value; - } - - @Override - public TYPE visit(final JassValueVisitor visitor) { - return visitor.accept(this); - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/StringJassValue.java b/jassparser/src/com/etheller/interpreter/ast/value/StringJassValue.java deleted file mode 100644 index 9cbcbb8c..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/StringJassValue.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.interpreter.ast.value; - -public class StringJassValue implements JassValue { - private final String value; - - public static StringJassValue of(final String value) { - // later this could do that dumb thing jass does with making sure we dont create - // duplicate instances, maybe - return new StringJassValue(value); - } - - public StringJassValue(final String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } - - @Override - public TYPE visit(final JassValueVisitor visitor) { - return visitor.accept(this); - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/visitor/ArrayJassValueVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/visitor/ArrayJassValueVisitor.java deleted file mode 100644 index 68a75b50..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/visitor/ArrayJassValueVisitor.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.etheller.interpreter.ast.value.visitor; - -import com.etheller.interpreter.ast.value.ArrayJassValue; -import com.etheller.interpreter.ast.value.BooleanJassValue; -import com.etheller.interpreter.ast.value.CodeJassValue; -import com.etheller.interpreter.ast.value.HandleJassValue; -import com.etheller.interpreter.ast.value.IntegerJassValue; -import com.etheller.interpreter.ast.value.JassValueVisitor; -import com.etheller.interpreter.ast.value.RealJassValue; -import com.etheller.interpreter.ast.value.StringJassValue; - -public class ArrayJassValueVisitor implements JassValueVisitor { - private static final ArrayJassValueVisitor INSTANCE = new ArrayJassValueVisitor(); - - public static ArrayJassValueVisitor getInstance() { - return INSTANCE; - } - - @Override - public ArrayJassValue accept(final IntegerJassValue value) { - return null; - } - - @Override - public ArrayJassValue accept(final RealJassValue value) { - return null; - } - - @Override - public ArrayJassValue accept(final BooleanJassValue value) { - return null; - } - - @Override - public ArrayJassValue accept(final StringJassValue value) { - return null; - } - - @Override - public ArrayJassValue accept(final CodeJassValue value) { - return null; - } - - @Override - public ArrayJassValue accept(final ArrayJassValue value) { - return value; - } - - @Override - public ArrayJassValue accept(final HandleJassValue value) { - return null; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/visitor/ArrayPrimitiveTypeVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/visitor/ArrayPrimitiveTypeVisitor.java deleted file mode 100644 index 11bb06ea..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/visitor/ArrayPrimitiveTypeVisitor.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.etheller.interpreter.ast.value.visitor; - -import com.etheller.interpreter.ast.value.ArrayJassType; -import com.etheller.interpreter.ast.value.HandleJassType; -import com.etheller.interpreter.ast.value.JassType; -import com.etheller.interpreter.ast.value.JassTypeVisitor; -import com.etheller.interpreter.ast.value.PrimitiveJassType; - -public class ArrayPrimitiveTypeVisitor implements JassTypeVisitor { - private static final ArrayPrimitiveTypeVisitor INSTANCE = new ArrayPrimitiveTypeVisitor(); - - public static ArrayPrimitiveTypeVisitor getInstance() { - return INSTANCE; - } - - @Override - public JassType accept(final PrimitiveJassType primitiveType) { - return null; - } - - @Override - public JassType accept(final ArrayJassType arrayType) { - return arrayType.getPrimitiveType(); - } - - @Override - public JassType accept(final HandleJassType type) { - return null; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/visitor/BooleanJassValueVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/visitor/BooleanJassValueVisitor.java deleted file mode 100644 index 2b7f995c..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/visitor/BooleanJassValueVisitor.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.etheller.interpreter.ast.value.visitor; - -import com.etheller.interpreter.ast.value.ArrayJassValue; -import com.etheller.interpreter.ast.value.BooleanJassValue; -import com.etheller.interpreter.ast.value.CodeJassValue; -import com.etheller.interpreter.ast.value.HandleJassValue; -import com.etheller.interpreter.ast.value.IntegerJassValue; -import com.etheller.interpreter.ast.value.JassValueVisitor; -import com.etheller.interpreter.ast.value.RealJassValue; -import com.etheller.interpreter.ast.value.StringJassValue; - -public class BooleanJassValueVisitor implements JassValueVisitor { - private static final BooleanJassValueVisitor INSTANCE = new BooleanJassValueVisitor(); - - public static BooleanJassValueVisitor getInstance() { - return INSTANCE; - } - - @Override - public Boolean accept(final IntegerJassValue value) { - throw new IllegalStateException("Unable to convert " + value + " to boolean"); - } - - @Override - public Boolean accept(final RealJassValue value) { - throw new IllegalStateException("Unable to convert " + value + " to boolean"); - } - - @Override - public Boolean accept(final BooleanJassValue value) { - return value.getValue(); - } - - @Override - public Boolean accept(final StringJassValue value) { - throw new IllegalStateException("Unable to convert " + value + " to boolean"); - } - - @Override - public Boolean accept(final CodeJassValue value) { - throw new IllegalStateException("Unable to convert " + value + " to boolean"); - } - - @Override - public Boolean accept(final ArrayJassValue value) { - throw new IllegalStateException("Unable to convert " + value + " to boolean"); - } - - @Override - public Boolean accept(final HandleJassValue value) { - throw new IllegalStateException("Unable to convert " + value + " to boolean"); - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/visitor/HandleJassTypeVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/visitor/HandleJassTypeVisitor.java deleted file mode 100644 index 3f4e75a7..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/visitor/HandleJassTypeVisitor.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.etheller.interpreter.ast.value.visitor; - -import com.etheller.interpreter.ast.value.ArrayJassType; -import com.etheller.interpreter.ast.value.HandleJassType; -import com.etheller.interpreter.ast.value.JassTypeVisitor; -import com.etheller.interpreter.ast.value.PrimitiveJassType; - -public class HandleJassTypeVisitor implements JassTypeVisitor { - private static final HandleJassTypeVisitor INSTANCE = new HandleJassTypeVisitor(); - - public static HandleJassTypeVisitor getInstance() { - return INSTANCE; - } - - @Override - public HandleJassType accept(final PrimitiveJassType primitiveType) { - return null; - } - - @Override - public HandleJassType accept(final ArrayJassType arrayType) { - return null; - } - - @Override - public HandleJassType accept(final HandleJassType type) { - return type; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/visitor/HandleTypeSuperTypeLoadingVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/visitor/HandleTypeSuperTypeLoadingVisitor.java deleted file mode 100644 index a2a4de74..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/visitor/HandleTypeSuperTypeLoadingVisitor.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.etheller.interpreter.ast.value.visitor; - -import com.etheller.interpreter.ast.value.ArrayJassType; -import com.etheller.interpreter.ast.value.HandleJassType; -import com.etheller.interpreter.ast.value.JassTypeVisitor; -import com.etheller.interpreter.ast.value.PrimitiveJassType; - -public class HandleTypeSuperTypeLoadingVisitor implements JassTypeVisitor { - private HandleJassType superType; - - public HandleTypeSuperTypeLoadingVisitor reset(final HandleJassType superType) { - this.superType = superType; - return this; - } - - @Override - public Void accept(final PrimitiveJassType primitiveType) { - return null; - } - - @Override - public Void accept(final ArrayJassType arrayType) { - return null; - } - - @Override - public Void accept(final HandleJassType type) { - type.setSuperType(this.superType); - return null; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/visitor/IntegerJassValueVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/visitor/IntegerJassValueVisitor.java deleted file mode 100644 index 2edae0e8..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/visitor/IntegerJassValueVisitor.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.etheller.interpreter.ast.value.visitor; - -import com.etheller.interpreter.ast.value.ArrayJassValue; -import com.etheller.interpreter.ast.value.BooleanJassValue; -import com.etheller.interpreter.ast.value.CodeJassValue; -import com.etheller.interpreter.ast.value.HandleJassValue; -import com.etheller.interpreter.ast.value.IntegerJassValue; -import com.etheller.interpreter.ast.value.JassValueVisitor; -import com.etheller.interpreter.ast.value.RealJassValue; -import com.etheller.interpreter.ast.value.StringJassValue; - -public class IntegerJassValueVisitor implements JassValueVisitor { - private static final IntegerJassValueVisitor INSTANCE = new IntegerJassValueVisitor(); - - public static IntegerJassValueVisitor getInstance() { - return INSTANCE; - } - - @Override - public Integer accept(final IntegerJassValue value) { - return value.getValue(); - } - - @Override - public Integer accept(final RealJassValue value) { - return (int) value.getValue(); - } - - @Override - public Integer accept(final BooleanJassValue value) { - return 0; - } - - @Override - public Integer accept(final StringJassValue value) { - return 0; - } - - @Override - public Integer accept(final CodeJassValue value) { - return 0; - } - - @Override - public Integer accept(final ArrayJassValue value) { - return 0; - } - - @Override - public Integer accept(final HandleJassValue value) { - return 0; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/visitor/JassFunctionJassValueVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/visitor/JassFunctionJassValueVisitor.java deleted file mode 100644 index ee5f6baa..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/visitor/JassFunctionJassValueVisitor.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.etheller.interpreter.ast.value.visitor; - -import com.etheller.interpreter.ast.function.JassFunction; -import com.etheller.interpreter.ast.value.ArrayJassValue; -import com.etheller.interpreter.ast.value.BooleanJassValue; -import com.etheller.interpreter.ast.value.CodeJassValue; -import com.etheller.interpreter.ast.value.HandleJassValue; -import com.etheller.interpreter.ast.value.IntegerJassValue; -import com.etheller.interpreter.ast.value.JassValueVisitor; -import com.etheller.interpreter.ast.value.RealJassValue; -import com.etheller.interpreter.ast.value.StringJassValue; - -public class JassFunctionJassValueVisitor implements JassValueVisitor { - private static final JassFunctionJassValueVisitor INSTANCE = new JassFunctionJassValueVisitor(); - - public static JassFunctionJassValueVisitor getInstance() { - return INSTANCE; - } - - @Override - public JassFunction accept(final IntegerJassValue value) { - return null; - } - - @Override - public JassFunction accept(final RealJassValue value) { - return null; - } - - @Override - public JassFunction accept(final BooleanJassValue value) { - return null; - } - - @Override - public JassFunction accept(final StringJassValue value) { - return null; - } - - @Override - public JassFunction accept(final CodeJassValue value) { - return value.getValue(); - } - - @Override - public JassFunction accept(final ArrayJassValue value) { - return null; - } - - @Override - public JassFunction accept(final HandleJassValue value) { - return null; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/visitor/JassTypeGettingValueVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/visitor/JassTypeGettingValueVisitor.java deleted file mode 100644 index 95a5c956..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/visitor/JassTypeGettingValueVisitor.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.etheller.interpreter.ast.value.visitor; - -import com.etheller.interpreter.ast.value.ArrayJassValue; -import com.etheller.interpreter.ast.value.BooleanJassValue; -import com.etheller.interpreter.ast.value.CodeJassValue; -import com.etheller.interpreter.ast.value.HandleJassValue; -import com.etheller.interpreter.ast.value.IntegerJassValue; -import com.etheller.interpreter.ast.value.JassType; -import com.etheller.interpreter.ast.value.JassValueVisitor; -import com.etheller.interpreter.ast.value.RealJassValue; -import com.etheller.interpreter.ast.value.StringJassValue; - -public class JassTypeGettingValueVisitor implements JassValueVisitor { - public static JassTypeGettingValueVisitor INSTANCE = new JassTypeGettingValueVisitor(); - - public static JassTypeGettingValueVisitor getInstance() { - return INSTANCE; - } - - @Override - public JassType accept(final IntegerJassValue value) { - return JassType.INTEGER; - } - - @Override - public JassType accept(final RealJassValue value) { - return JassType.REAL; - } - - @Override - public JassType accept(final BooleanJassValue value) { - return JassType.BOOLEAN; - } - - @Override - public JassType accept(final StringJassValue value) { - return JassType.STRING; - } - - @Override - public JassType accept(final CodeJassValue value) { - return JassType.CODE; - } - - @Override - public JassType accept(final ArrayJassValue value) { - return value.getType(); - } - - @Override - public JassType accept(final HandleJassValue value) { - return value.getType(); - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/visitor/NotJassValueVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/visitor/NotJassValueVisitor.java deleted file mode 100644 index f0d9f477..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/visitor/NotJassValueVisitor.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.etheller.interpreter.ast.value.visitor; - -import com.etheller.interpreter.ast.value.ArrayJassValue; -import com.etheller.interpreter.ast.value.BooleanJassValue; -import com.etheller.interpreter.ast.value.CodeJassValue; -import com.etheller.interpreter.ast.value.HandleJassValue; -import com.etheller.interpreter.ast.value.IntegerJassValue; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.JassValueVisitor; -import com.etheller.interpreter.ast.value.RealJassValue; -import com.etheller.interpreter.ast.value.StringJassValue; - -public class NotJassValueVisitor implements JassValueVisitor { - private static final NotJassValueVisitor INSTANCE = new NotJassValueVisitor(); - - public static NotJassValueVisitor getInstance() { - return INSTANCE; - } - - @Override - public JassValue accept(final IntegerJassValue value) { - throw new IllegalStateException("Unable to apply not keyword to a variable of type integer"); - } - - @Override - public JassValue accept(final RealJassValue value) { - throw new IllegalStateException("Unable to apply not keyword to a variable of type real"); - } - - @Override - public JassValue accept(final BooleanJassValue value) { - return BooleanJassValue.inverse(value); - } - - @Override - public JassValue accept(final StringJassValue value) { - throw new IllegalStateException("Unable to apply not keyword to a variable of type string"); - } - - @Override - public JassValue accept(final CodeJassValue value) { - throw new IllegalStateException("Unable to apply not keyword to a variable of type code"); - } - - @Override - public JassValue accept(final ArrayJassValue value) { - throw new IllegalStateException("Unable to apply not keyword to a variable of an array type"); - } - - @Override - public JassValue accept(final HandleJassValue value) { - throw new IllegalStateException( - "Unable to apply not keyword to a variable of type " + value.getType().getName()); - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/visitor/ObjectJassValueVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/visitor/ObjectJassValueVisitor.java deleted file mode 100644 index d8da3106..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/visitor/ObjectJassValueVisitor.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.etheller.interpreter.ast.value.visitor; - -import com.etheller.interpreter.ast.value.ArrayJassValue; -import com.etheller.interpreter.ast.value.BooleanJassValue; -import com.etheller.interpreter.ast.value.CodeJassValue; -import com.etheller.interpreter.ast.value.HandleJassValue; -import com.etheller.interpreter.ast.value.IntegerJassValue; -import com.etheller.interpreter.ast.value.JassValueVisitor; -import com.etheller.interpreter.ast.value.RealJassValue; -import com.etheller.interpreter.ast.value.StringJassValue; - -public class ObjectJassValueVisitor implements JassValueVisitor { - private static final ObjectJassValueVisitor INSTANCE = new ObjectJassValueVisitor(); - - public static ObjectJassValueVisitor getInstance() { - return (ObjectJassValueVisitor) INSTANCE; - } - - @Override - public T accept(final IntegerJassValue value) { - return null; - } - - @Override - public T accept(final RealJassValue value) { - return null; - } - - @Override - public T accept(final BooleanJassValue value) { - return null; - } - - @Override - public T accept(final StringJassValue value) { - return null; - } - - @Override - public T accept(final CodeJassValue value) { - return null; - } - - @Override - public T accept(final ArrayJassValue value) { - return null; - } - - @Override - public T accept(final HandleJassValue value) { - return (T) value.getJavaValue(); - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/visitor/RealJassValueVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/visitor/RealJassValueVisitor.java deleted file mode 100644 index f4045810..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/visitor/RealJassValueVisitor.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.etheller.interpreter.ast.value.visitor; - -import com.etheller.interpreter.ast.value.ArrayJassValue; -import com.etheller.interpreter.ast.value.BooleanJassValue; -import com.etheller.interpreter.ast.value.CodeJassValue; -import com.etheller.interpreter.ast.value.HandleJassValue; -import com.etheller.interpreter.ast.value.IntegerJassValue; -import com.etheller.interpreter.ast.value.JassValueVisitor; -import com.etheller.interpreter.ast.value.RealJassValue; -import com.etheller.interpreter.ast.value.StringJassValue; - -public class RealJassValueVisitor implements JassValueVisitor { - private static final RealJassValueVisitor INSTANCE = new RealJassValueVisitor(); - - public static RealJassValueVisitor getInstance() { - return INSTANCE; - } - - @Override - public Double accept(final IntegerJassValue value) { - return Double.valueOf(value.getValue()); - } - - @Override - public Double accept(final RealJassValue value) { - return value.getValue(); - } - - @Override - public Double accept(final BooleanJassValue value) { - return 0.0; - } - - @Override - public Double accept(final StringJassValue value) { - return 0.0; - } - - @Override - public Double accept(final CodeJassValue value) { - return 0.0; - } - - @Override - public Double accept(final ArrayJassValue value) { - return 0.0; - } - - @Override - public Double accept(final HandleJassValue value) { - return 0.0; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/visitor/StringJassValueVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/visitor/StringJassValueVisitor.java deleted file mode 100644 index f9ef72f3..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/visitor/StringJassValueVisitor.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.etheller.interpreter.ast.value.visitor; - -import com.etheller.interpreter.ast.value.ArrayJassValue; -import com.etheller.interpreter.ast.value.BooleanJassValue; -import com.etheller.interpreter.ast.value.CodeJassValue; -import com.etheller.interpreter.ast.value.HandleJassValue; -import com.etheller.interpreter.ast.value.IntegerJassValue; -import com.etheller.interpreter.ast.value.JassValueVisitor; -import com.etheller.interpreter.ast.value.RealJassValue; -import com.etheller.interpreter.ast.value.StringJassValue; - -public class StringJassValueVisitor implements JassValueVisitor { - private static final StringJassValueVisitor INSTANCE = new StringJassValueVisitor(); - - public static StringJassValueVisitor getInstance() { - return INSTANCE; - } - - @Override - public String accept(final IntegerJassValue value) { - return null; - } - - @Override - public String accept(final RealJassValue value) { - return null; - } - - @Override - public String accept(final BooleanJassValue value) { - return null; - } - - @Override - public String accept(final StringJassValue value) { - return value.getValue(); - } - - @Override - public String accept(final CodeJassValue value) { - return null; - } - - @Override - public String accept(final ArrayJassValue value) { - return null; - } - - @Override - public String accept(final HandleJassValue value) { - return null; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/value/visitor/SuperTypeVisitor.java b/jassparser/src/com/etheller/interpreter/ast/value/visitor/SuperTypeVisitor.java deleted file mode 100644 index 2a9e3365..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/value/visitor/SuperTypeVisitor.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.etheller.interpreter.ast.value.visitor; - -import com.etheller.interpreter.ast.value.ArrayJassType; -import com.etheller.interpreter.ast.value.HandleJassType; -import com.etheller.interpreter.ast.value.JassTypeVisitor; -import com.etheller.interpreter.ast.value.PrimitiveJassType; - -public class SuperTypeVisitor implements JassTypeVisitor { - private static final SuperTypeVisitor INSTANCE = new SuperTypeVisitor(); - - public static SuperTypeVisitor getInstance() { - return INSTANCE; - } - - @Override - public HandleJassType accept(final PrimitiveJassType primitiveType) { - return null; - } - - @Override - public HandleJassType accept(final ArrayJassType arrayType) { - return null; - } - - @Override - public HandleJassType accept(final HandleJassType type) { - return type.getSuperType(); - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/visitors/ArgumentExpressionHandler.java b/jassparser/src/com/etheller/interpreter/ast/visitors/ArgumentExpressionHandler.java deleted file mode 100644 index 8ec596e1..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/visitors/ArgumentExpressionHandler.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.etheller.interpreter.ast.visitors; - -public class ArgumentExpressionHandler { - protected JassArgumentsVisitor argumentsVisitor; - protected JassExpressionVisitor expressionVisitor; - - public void setJassArgumentsVisitor(final JassArgumentsVisitor jassArgumentsVisitor) { - this.argumentsVisitor = jassArgumentsVisitor; - } - - public void setJassExpressionVisitor(final JassExpressionVisitor jassExpressionVisitor) { - this.expressionVisitor = jassExpressionVisitor; - } - -} diff --git a/jassparser/src/com/etheller/interpreter/ast/visitors/JassArgumentsVisitor.java b/jassparser/src/com/etheller/interpreter/ast/visitors/JassArgumentsVisitor.java deleted file mode 100644 index cd44e487..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/visitors/JassArgumentsVisitor.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.etheller.interpreter.ast.visitors; - -import java.util.LinkedList; -import java.util.List; - -import com.etheller.interpreter.JassBaseVisitor; -import com.etheller.interpreter.JassParser.ListArgumentContext; -import com.etheller.interpreter.JassParser.SingleArgumentContext; -import com.etheller.interpreter.ast.expression.JassExpression; - -public class JassArgumentsVisitor extends JassBaseVisitor> { - private final ArgumentExpressionHandler argumentExpressionHandler; - - public JassArgumentsVisitor(final ArgumentExpressionHandler argumentExpressionHandler) { - this.argumentExpressionHandler = argumentExpressionHandler; - } - - @Override - public List visitSingleArgument(final SingleArgumentContext ctx) { - final List list = new LinkedList<>(); - list.add(this.argumentExpressionHandler.expressionVisitor.visit(ctx.expression())); - return list; - } - - @Override - public List visitListArgument(final ListArgumentContext ctx) { - final List list = visit(ctx.argsList()); - list.add(0, this.argumentExpressionHandler.expressionVisitor.visit(ctx.expression())); - return list; - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/visitors/JassExpressionVisitor.java b/jassparser/src/com/etheller/interpreter/ast/visitors/JassExpressionVisitor.java deleted file mode 100644 index cb5e077b..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/visitors/JassExpressionVisitor.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.etheller.interpreter.ast.visitors; - -import java.util.Collections; -import java.util.List; - -import com.etheller.interpreter.JassBaseVisitor; -import com.etheller.interpreter.JassParser.ArgsListContext; -import com.etheller.interpreter.JassParser.ArrayReferenceExpressionContext; -import com.etheller.interpreter.JassParser.FalseExpressionContext; -import com.etheller.interpreter.JassParser.FunctionCallExpressionContext; -import com.etheller.interpreter.JassParser.FunctionReferenceExpressionContext; -import com.etheller.interpreter.JassParser.IntegerLiteralExpressionContext; -import com.etheller.interpreter.JassParser.NotExpressionContext; -import com.etheller.interpreter.JassParser.ParentheticalExpressionContext; -import com.etheller.interpreter.JassParser.ReferenceExpressionContext; -import com.etheller.interpreter.JassParser.StringLiteralExpressionContext; -import com.etheller.interpreter.JassParser.TrueExpressionContext; -import com.etheller.interpreter.ast.expression.ArrayRefJassExpression; -import com.etheller.interpreter.ast.expression.FunctionCallJassExpression; -import com.etheller.interpreter.ast.expression.FunctionReferenceJassExpression; -import com.etheller.interpreter.ast.expression.JassExpression; -import com.etheller.interpreter.ast.expression.LiteralJassExpression; -import com.etheller.interpreter.ast.expression.NotJassExpression; -import com.etheller.interpreter.ast.expression.ReferenceJassExpression; -import com.etheller.interpreter.ast.value.BooleanJassValue; -import com.etheller.interpreter.ast.value.IntegerJassValue; -import com.etheller.interpreter.ast.value.StringJassValue; - -public class JassExpressionVisitor extends JassBaseVisitor { - private final ArgumentExpressionHandler argumentExpressionHandler; - - public JassExpressionVisitor(final ArgumentExpressionHandler argumentExpressionHandler) { - this.argumentExpressionHandler = argumentExpressionHandler; - } - - @Override - public JassExpression visitReferenceExpression(final ReferenceExpressionContext ctx) { - return new ReferenceJassExpression(ctx.ID().getText()); - } - - @Override - public JassExpression visitParentheticalExpression(final ParentheticalExpressionContext ctx) { - return visit(ctx.expression()); - } - - @Override - public JassExpression visitStringLiteralExpression(final StringLiteralExpressionContext ctx) { - final String stringLiteralText = ctx.STRING_LITERAL().getText(); - final String parsedString = stringLiteralText.substring(1, stringLiteralText.length() - 1).replace("\\\\", - "\\"); - return new LiteralJassExpression(new StringJassValue(parsedString)); - } - - @Override - public JassExpression visitIntegerLiteralExpression(final IntegerLiteralExpressionContext ctx) { - return new LiteralJassExpression(new IntegerJassValue(Integer.parseInt(ctx.INTEGER().getText()))); - } - - @Override - public JassExpression visitFunctionReferenceExpression(final FunctionReferenceExpressionContext ctx) { - return new FunctionReferenceJassExpression(ctx.ID().getText()); - } - - @Override - public JassExpression visitArrayReferenceExpression(final ArrayReferenceExpressionContext ctx) { - return new ArrayRefJassExpression(ctx.ID().getText(), visit(ctx.expression())); - } - - @Override - public JassExpression visitFalseExpression(final FalseExpressionContext ctx) { - return new LiteralJassExpression(BooleanJassValue.FALSE); - } - - @Override - public JassExpression visitTrueExpression(final TrueExpressionContext ctx) { - return new LiteralJassExpression(BooleanJassValue.TRUE); - } - - @Override - public JassExpression visitNotExpression(final NotExpressionContext ctx) { - return new NotJassExpression(visit(ctx.expression())); - } - - @Override - public JassExpression visitFunctionCallExpression(final FunctionCallExpressionContext ctx) { - final ArgsListContext argsList = ctx.functionExpression().argsList(); - final List arguments = argsList == null ? Collections.emptyList() - : this.argumentExpressionHandler.argumentsVisitor.visit(argsList); - return new FunctionCallJassExpression(ctx.functionExpression().ID().getText(), arguments); - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/visitors/JassGlobalsVisitor.java b/jassparser/src/com/etheller/interpreter/ast/visitors/JassGlobalsVisitor.java deleted file mode 100644 index f5fcfc23..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/visitors/JassGlobalsVisitor.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.etheller.interpreter.ast.visitors; - -import com.etheller.interpreter.JassBaseVisitor; -import com.etheller.interpreter.JassParser.BasicGlobalContext; -import com.etheller.interpreter.JassParser.DefinitionGlobalContext; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.LocalScope; -import com.etheller.interpreter.ast.value.JassType; -import com.etheller.interpreter.ast.value.visitor.ArrayPrimitiveTypeVisitor; - -public class JassGlobalsVisitor extends JassBaseVisitor { - private static final LocalScope EMPTY_LOCAL_SCOPE = new LocalScope(); - private final GlobalScope globals; - private final JassTypeVisitor jassTypeVisitor; - private final JassExpressionVisitor jassExpressionVisitor; - - public JassGlobalsVisitor(final GlobalScope globals, final JassTypeVisitor jassTypeVisitor, - final JassExpressionVisitor jassExpressionVisitor) { - this.globals = globals; - this.jassTypeVisitor = jassTypeVisitor; - this.jassExpressionVisitor = jassExpressionVisitor; - } - - @Override - public Void visitBasicGlobal(final BasicGlobalContext ctx) { - final JassType type = this.jassTypeVisitor.visit(ctx.type()); - final JassType arrayPrimType = type.visit(ArrayPrimitiveTypeVisitor.getInstance()); - if (arrayPrimType != null) { - this.globals.createGlobalArray(ctx.ID().getText(), type); - } - else { - this.globals.createGlobal(ctx.ID().getText(), type); - } - return null; - } - - @Override - public Void visitDefinitionGlobal(final DefinitionGlobalContext ctx) { - final JassType type = this.jassTypeVisitor.visit(ctx.type()); - final JassType arrayPrimType = type.visit(ArrayPrimitiveTypeVisitor.getInstance()); - if (arrayPrimType != null) { - this.globals.createGlobalArray(ctx.ID().getText(), type); - } - else { - this.globals.createGlobal(ctx.ID().getText(), type, - this.jassExpressionVisitor.visit(ctx.assignTail().expression()).evaluate(this.globals, - EMPTY_LOCAL_SCOPE, JassProgramVisitor.EMPTY_TRIGGER_SCOPE)); - } - return null; - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/visitors/JassParametersVisitor.java b/jassparser/src/com/etheller/interpreter/ast/visitors/JassParametersVisitor.java deleted file mode 100644 index 89cde26c..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/visitors/JassParametersVisitor.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.etheller.interpreter.ast.visitors; - -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -import com.etheller.interpreter.JassBaseVisitor; -import com.etheller.interpreter.JassParser.ListParameterContext; -import com.etheller.interpreter.JassParser.NothingParameterContext; -import com.etheller.interpreter.JassParser.SingleParameterContext; -import com.etheller.interpreter.ast.function.JassParameter; - -public class JassParametersVisitor extends JassBaseVisitor> { - private final JassTypeVisitor typeVisitor; - - public JassParametersVisitor(final JassTypeVisitor typeVisitor) { - this.typeVisitor = typeVisitor; - } - - @Override - public List visitSingleParameter(final SingleParameterContext ctx) { - final List list = new LinkedList<>(); - list.add(new JassParameter(typeVisitor.visit(ctx.param().type()), ctx.param().ID().getText())); - return list; - } - - @Override - public List visitListParameter(final ListParameterContext ctx) { - final List list = visit(ctx.paramList()); - list.add(0, new JassParameter(typeVisitor.visit(ctx.param().type()), ctx.param().ID().getText())); - return list; - } - - @Override - public List visitNothingParameter(final NothingParameterContext ctx) { - return Collections.EMPTY_LIST; - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/visitors/JassProgramVisitor.java b/jassparser/src/com/etheller/interpreter/ast/visitors/JassProgramVisitor.java deleted file mode 100644 index 2c5e0d2c..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/visitors/JassProgramVisitor.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.etheller.interpreter.ast.visitors; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.etheller.interpreter.JassBaseVisitor; -import com.etheller.interpreter.JassParser.BlockContext; -import com.etheller.interpreter.JassParser.FunctionBlockContext; -import com.etheller.interpreter.JassParser.GlobalContext; -import com.etheller.interpreter.JassParser.ProgramContext; -import com.etheller.interpreter.JassParser.StatementContext; -import com.etheller.interpreter.JassParser.TypeDefinitionContext; -import com.etheller.interpreter.ast.function.JassFunction; -import com.etheller.interpreter.ast.function.JassNativeManager; -import com.etheller.interpreter.ast.function.UserJassFunction; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.statement.JassStatement; - -public class JassProgramVisitor extends JassBaseVisitor { - public static final TriggerExecutionScope EMPTY_TRIGGER_SCOPE = new TriggerExecutionScope(null); - private final GlobalScope globals = new GlobalScope(); - private final JassNativeManager jassNativeManager = new JassNativeManager(); - private final JassTypeVisitor jassTypeVisitor = new JassTypeVisitor(this.globals); - private final ArgumentExpressionHandler argumentExpressionHandler = new ArgumentExpressionHandler(); - private final JassExpressionVisitor jassExpressionVisitor = new JassExpressionVisitor( - this.argumentExpressionHandler); - private final JassArgumentsVisitor jassArgumentsVisitor = new JassArgumentsVisitor(this.argumentExpressionHandler); - { - this.argumentExpressionHandler.setJassArgumentsVisitor(this.jassArgumentsVisitor); - this.argumentExpressionHandler.setJassExpressionVisitor(this.jassExpressionVisitor); - } - private final JassGlobalsVisitor jassGlobalsVisitor = new JassGlobalsVisitor(this.globals, this.jassTypeVisitor, - this.jassExpressionVisitor); - private final JassParametersVisitor jassParametersVisitor = new JassParametersVisitor(this.jassTypeVisitor); - private final JassStatementVisitor jassStatementVisitor = new JassStatementVisitor(this.argumentExpressionHandler); - - @Override - public Void visitBlock(final BlockContext ctx) { - if (ctx.globalsBlock() != null) { - for (final GlobalContext globalContext : ctx.globalsBlock().global()) { - this.jassGlobalsVisitor.visit(globalContext); - } - } - else if (ctx.nativeBlock() != null) { - final String text = ctx.nativeBlock().ID().getText(); - System.out.println("Registering native: " + text); - this.jassNativeManager.registerNativeCode(text, - this.jassParametersVisitor.visit(ctx.nativeBlock().paramList()), - this.jassTypeVisitor.visit(ctx.nativeBlock().type()), this.globals); - } - return null; - } - - @Override - public Void visitFunctionBlock(final FunctionBlockContext ctx) { - final List statements = new ArrayList<>(); - for (final StatementContext statementContext : ctx.statements().statement()) { - statements.add(this.jassStatementVisitor.visit(statementContext)); - } - final UserJassFunction userJassFunction = new UserJassFunction(statements, - this.jassParametersVisitor.visit(ctx.paramList()), this.jassTypeVisitor.visit(ctx.type())); - this.globals.defineFunction(ctx.ID().getText(), userJassFunction); - return null; - } - - @Override - public Void visitProgram(final ProgramContext ctx) { - for (final TypeDefinitionContext typeDefinitionContext : ctx.typeDefinitionBlock().typeDefinition()) { - this.globals.loadTypeDefinition(typeDefinitionContext.ID(0).getText(), - typeDefinitionContext.ID(1).getText()); - } - for (final BlockContext blockContext : ctx.block()) { - visit(blockContext); - } - for (final FunctionBlockContext functionBlockContext : ctx.functionBlock()) { - final List statements = new ArrayList<>(); - for (final StatementContext statementContext : functionBlockContext.statements().statement()) { - statements.add(this.jassStatementVisitor.visit(statementContext)); - } - final UserJassFunction userJassFunction = new UserJassFunction(statements, - this.jassParametersVisitor.visit(functionBlockContext.paramList()), - this.jassTypeVisitor.visit(functionBlockContext.type())); - this.globals.defineFunction(functionBlockContext.ID().getText(), userJassFunction); - } - final JassFunction mainFunction = this.globals.getFunctionByName("main"); - if (mainFunction != null) { - try { - mainFunction.call(Collections.EMPTY_LIST, this.globals, EMPTY_TRIGGER_SCOPE); - } - catch (final Exception exc) { - throw new RuntimeException("Exception on Line " + GlobalScope.getLineNumber(), exc); - } - } - return null; - } - - public GlobalScope getGlobals() { - return this.globals; - } - - public JassNativeManager getJassNativeManager() { - return this.jassNativeManager; - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/visitors/JassStatementVisitor.java b/jassparser/src/com/etheller/interpreter/ast/visitors/JassStatementVisitor.java deleted file mode 100644 index 14ac8290..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/visitors/JassStatementVisitor.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.etheller.interpreter.ast.visitors; - -import java.util.ArrayList; -import java.util.List; - -import com.etheller.interpreter.JassBaseVisitor; -import com.etheller.interpreter.JassParser.ArrayedAssignmentStatementContext; -import com.etheller.interpreter.JassParser.CallStatementContext; -import com.etheller.interpreter.JassParser.IfElseIfStatementContext; -import com.etheller.interpreter.JassParser.IfElseStatementContext; -import com.etheller.interpreter.JassParser.ReturnStatementContext; -import com.etheller.interpreter.JassParser.SetStatementContext; -import com.etheller.interpreter.JassParser.SimpleIfStatementContext; -import com.etheller.interpreter.JassParser.StatementContext; -import com.etheller.interpreter.ast.statement.JassArrayedAssignmentStatement; -import com.etheller.interpreter.ast.statement.JassCallStatement; -import com.etheller.interpreter.ast.statement.JassIfElseIfStatement; -import com.etheller.interpreter.ast.statement.JassIfElseStatement; -import com.etheller.interpreter.ast.statement.JassIfStatement; -import com.etheller.interpreter.ast.statement.JassReturnStatement; -import com.etheller.interpreter.ast.statement.JassSetStatement; -import com.etheller.interpreter.ast.statement.JassStatement; - -public class JassStatementVisitor extends JassBaseVisitor { - private final ArgumentExpressionHandler argumentExpressionHandler; - - public JassStatementVisitor(final ArgumentExpressionHandler argumentExpressionHandler) { - this.argumentExpressionHandler = argumentExpressionHandler; - } - - @Override - public JassStatement visitCallStatement(final CallStatementContext ctx) { - return new JassCallStatement(ctx.getStart().getLine(), ctx.functionExpression().ID().getText(), - this.argumentExpressionHandler.argumentsVisitor.visit(ctx.functionExpression().argsList())); - } - - @Override - public JassStatement visitSetStatement(final SetStatementContext ctx) { - return new JassSetStatement(ctx.getStart().getLine(), ctx.ID().getText(), - this.argumentExpressionHandler.expressionVisitor.visit(ctx.expression())); - } - - @Override - public JassStatement visitReturnStatement(final ReturnStatementContext ctx) { - return new JassReturnStatement(ctx.getStart().getLine(), - this.argumentExpressionHandler.expressionVisitor.visit(ctx.expression())); - } - - @Override - public JassStatement visitIfElseIfStatement(final IfElseIfStatementContext ctx) { - final List thenStatements = new ArrayList<>(); - for (final StatementContext statementCtx : ctx.statements().statement()) { - thenStatements.add(visit(statementCtx)); - } - final JassStatement elseIfTail = visit(ctx.ifStatementPartial()); - return new JassIfElseIfStatement(ctx.getStart().getLine(), - this.argumentExpressionHandler.expressionVisitor.visit(ctx.expression()), thenStatements, elseIfTail); - } - - @Override - public JassStatement visitIfElseStatement(final IfElseStatementContext ctx) { - final List thenStatements = new ArrayList<>(); - for (final StatementContext statementCtx : ctx.statements(0).statement()) { - thenStatements.add(visit(statementCtx)); - } - final List elseStatements = new ArrayList<>(); - for (final StatementContext statementCtx : ctx.statements(1).statement()) { - elseStatements.add(visit(statementCtx)); - } - return new JassIfElseStatement(ctx.getStart().getLine(), - this.argumentExpressionHandler.expressionVisitor.visit(ctx.expression()), thenStatements, - elseStatements); - } - - @Override - public JassStatement visitSimpleIfStatement(final SimpleIfStatementContext ctx) { - final List thenStatements = new ArrayList<>(); - for (final StatementContext statementCtx : ctx.statements().statement()) { - thenStatements.add(visit(statementCtx)); - } - return new JassIfStatement(ctx.getStart().getLine(), - this.argumentExpressionHandler.expressionVisitor.visit(ctx.expression()), thenStatements); - } - - @Override - public JassStatement visitArrayedAssignmentStatement(final ArrayedAssignmentStatementContext ctx) { - return new JassArrayedAssignmentStatement(ctx.getStart().getLine(), ctx.ID().getText(), - this.argumentExpressionHandler.expressionVisitor.visit(ctx.expression(0)), - this.argumentExpressionHandler.expressionVisitor.visit(ctx.expression(1))); - } -} diff --git a/jassparser/src/com/etheller/interpreter/ast/visitors/JassTypeVisitor.java b/jassparser/src/com/etheller/interpreter/ast/visitors/JassTypeVisitor.java deleted file mode 100644 index d4530b03..00000000 --- a/jassparser/src/com/etheller/interpreter/ast/visitors/JassTypeVisitor.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.etheller.interpreter.ast.visitors; - -import com.etheller.interpreter.JassBaseVisitor; -import com.etheller.interpreter.JassParser.ArrayTypeContext; -import com.etheller.interpreter.JassParser.BasicTypeContext; -import com.etheller.interpreter.JassParser.NothingTypeContext; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.value.JassType; - -public class JassTypeVisitor extends JassBaseVisitor { - private final GlobalScope globals; - - public JassTypeVisitor(final GlobalScope globals) { - this.globals = globals; - } - - @Override - public JassType visitArrayType(final ArrayTypeContext ctx) { - return globals.parseArrayType(ctx.ID().getText()); - } - - @Override - public JassType visitBasicType(final BasicTypeContext ctx) { - return globals.parseType(ctx.ID().getText()); - } - - @Override - public JassType visitNothingType(final NothingTypeContext ctx) { - return JassType.NOTHING; - } -} From 04a10eb93711f44786f510a9ea11d7d9dea8e221 Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:01:58 +0200 Subject: [PATCH 11/17] Delete jars directory --- jars/blp-iio-plugin.jar | Bin 64414 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 jars/blp-iio-plugin.jar diff --git a/jars/blp-iio-plugin.jar b/jars/blp-iio-plugin.jar deleted file mode 100644 index f72f214c7d4d46a1f14b89c52c656ad61d8a4068..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64414 zcmcG#V~{6d)a6;-W!vhqUDajVwr$(CtNvx%wr$(CZEe5v&dyBChnd-p-HgbHjL3+5 zKHU7}ee#@htN|Yy@4}8w+*;q%Skca0(AL`8)`r&5O5f2j zN%2euSsvw^md3g)rD{}#?;H*SmtQVkIK(A_MO)0YGM9I>QR-B0gPos)9^iF0OUa7)TbL$g5*>puO|oR$YV|1) zHRL)-k=G{u$z-mwxe}p$^f82SczXf>)0eL@yYQw3k=e(JudBCP=0#9}<;l)caRvj7 zzk$0&#sA)+MA=1T=i6Uz&PrX3Z9!Xxmf+bgKf8FTqr$XUXi;6`r z&Us_hOfv@trYgC@Wy_{|Ay`Tp9rF{?bO&nxItljHhA`;EXbTXDywN-{r4nfKPB1i& z<~(PI@90z@Dz<>rbqcu$shv!-ELoO0OkxpJFe6BT(}IXF&oz=u#(jWs-zkYRko_27 zxcETpD8y|ZY&iK)Z68$-`b=!NQl(X)QjZm)Uan!Fm{qS%lMbtSI**~|%n3ITDjfs6 znOB{G`jJYI{g&e@kb$|JrBYy3WMzNdtL&;ZIfGyDK6w0O0Fng}helilOfWy-d)6XW zG8fN92zGMMGxmYl)(aaaL*#fBm;f)nS$jyda$A6ep5!I9Kden_k=BbFkxG2U^tqq4 zYklH6=;9sk`CiR?&&NAL)MJWp4*-~oWgDM_A#;;x{Lvuxka z20{{Rr_*tiFWdPK99nm0Kx=*j0U?9_uW(@h-{K%4CoC#$ZfC7;C+A>mXzb`{>p;x# zpHyTiS<5cSq4>~dP+2WZQAEU0oG&uy8ULm<`26#WNioO>Oh8QPdL6oBwW;9>Y)>~$ zEDY=G*Ea%hZcm?^O$&%~SRZ`X$>Vb;*9q6j<3ucc&MzrL6+!#~z}er&cB@F-70;`c ztzw;qqiwtwYK8RohooRr$@;b3DbyL3;F}Je?n;93xb0)>>W$5{`4r2Iei-IKjN!$r zYFcbBNikJ)>pc*UqWaF`F}_OsnfU2sf-gR{e#0&FlEHdk5pG) zNWftuh<(AtNUfs?6yys40^Ga&rBcWnlA5&u0>f6)7S%SgCC?Ye^7a9GM~}ug#-)t) zvqsM~X3cCe>JW#%*R1S_1Ok?AtsyqTMl82OF=KNKlho5Oe5~NOqwHEV?V3Jdedo@1 z`{+HWHh_;a1*iclIpU^I6oNgJqbt__=zg)q3{8k=uns~OEB0{CKW30yqdTy!>5XLd zD8qk?n4`3sN0{`|tFh6dVZPc-Fog$RLgE^Rg|48EAa%f0_UAf#R%2ZCNk1>qU*;=4 z!r=;PiL)a*L&unR@UYW_=U!`I6^C~z#_}V*-1!ku;3S$fJjCxQx0rMzJB`ohH2-A< zl@?Rm+|;Gg*~7E_G(`NHt6GZhoKRK*ANLuVqSK?F-&}6_`s4)Dk}-Z=GC?+>Cjm%5+)99T4K!jO^OS|(QBCh{GAj0_H5V1w#NAN*I zAkPdivrfuamahRgc-LW7-33Zp(l7osut@izpV&fc#&bQq&XxX23YRVr@%7^!XYmI)6+#mm(`p(&$Dm_X z#k~`k_4mfgy_&*n=P4o*auB2bqjLl{gHzhDp^k3yk3XBB_!S;j{ZxiPd&nsy8GZTE zlxl#cZR?3xiF%^XADlgg!NBCl$OoZ(7ZWrpm@~YVNSc3u{H9tI5ZK~dAJ$p<4?u>? zFJ8Br<+kt0{sE#G(*BLVCK51X#Wbj*Eg9ucP(a{cSWjz#AxIfaPHQf9z$mDsTAh~e zG&o_?LD0Fkh)^&Tdt^F zp&;@}O%G_mb3+kTCZQjqX9e&$L19i1=~s2=WPtadi;~!9?NJ6R`M{Tf?9-PbY!DZV zvkJS@!%!UBOFEzY9WeAx9lV{kxw`2iDmLHj>jJrEJQRf};va#L{>>^q2Z=HKv`{97VuzT03tWMk-j2mtQGKa(qa^sH}tl*>s%Re4#iS0-;fz)Jr(fpC-I= zDnZ9&mP~Js^brbU`?O{HLunA{+1aH~6_b7SO~DKC4m8|wy`7!w4y9izRdqgVtkcwX z1C77H{37o$O^`5E9tmXRc#btoMJ0DJ6<*&XSiQ7Z!#Ts67hd-f&3Js%t>MT#-6HZNTm0i^PZ~apbey}tVt>| z1~UGF7Qk9HCS^9cU4I7eH7DzB?3-D7lcQNir`ti3!tzwDp!9_WADvW|tIKs8U1uso zA1BYGbr>lxZJxhLqC*ra#Bq19AVq=`-5vEEKgU7SuYiJpXa_5S_Tn()CtpQ~pp1p` zcNOt=WJ8LXL28AHOorZU5YK?@lY>sXwZAL3BUakluIE6}#?sotK{`}zS_aQZ0WZ+^ zmUZzkAzo{Rrix7d*cIsQr$3~qh)1iBPYj=9n;uLpIFHgy$1bzAh7iR{v9W?yC+}6e zS0;gwDE}@PTkzI$&J4a|M=fs6wQR02xRYHn_63u9|Zz&HIyTz`7QSEMLi)O@526;>=JH zE=n=+n14h{TB361!$o6Vg-AQ^EW;z!r-V!f{o8!s1J`-FzL-W$HcM)NBA{|uu5-RQ z#RIPoS{j4S-|^$HP9%Tz_2 zuBkZ7{#)ZiLc>#=t{}Uda->3>C^nF)KQTbLUNY@2^hC z>^w?&>-~h(Xhw^y3z;AzD9?fw7u0offkj;N7)K3Hnr8zJnT7_!7Ve(o{d%2a0yL%G zs*-F1)4`2U5^rtapRTpqp7wasX^Nz-IgIRh>j*hg6?gle#QjT+AQ>5!=>c7SuGg*+}SwiyBu;z&AS14>~H3WID%BqPmyK>{;^CY^)HQXzbteWjGX;0?Bv9Z7qGD7w&&Ehnv zV!2V%6Ka(6#0)b-)6Xgg{s^r?DB@0YV#DG37fL1wU!j<&%^(c%#R;VvzCZBtKmAmt zID!+v3J`!-f}Ef}$4sDJSuO{Wdlq%GtF-iCLbW8XW>MwuxtZD1V_C67m7C+d6a^|x z4lV;w$t#4<5c`^bd=0#y$SW)8@1*(fAb2(dY}H#~H`xU zmeH=8e}y#Dd;hp>n(xE$_syBncwz74wJnMYqO6}?M>H0ER4!XTJJEGZdMznUgm&21 zgnOO}e8s8K*57h_%p6fxQQ(e+!oVuVSWg zpyAEF?#3XvNOPr1(Y|l_!FSB*>%)&jPJ*C!xQf#k=bvHmHrC3HoNm`yWNZlr7<$%S zn7Hb2QL~k`H~m@0i>bgyJFP=?(yaSaS#G?%)XQbT8`0$^MBfCDY8>7;4844z$-jtJ zTB)Z^K0k{^ld5hPK&szyX9&$J|9~Mm!;Jpgl~gxL`4ya%?mdF3|Qf8Z8S%Aaub z>?FFt9cZGk#Pf+Fo8eY2%H=Rj{RzWM231uj8+oR{OSYu@cxoGOdP{}egA#=`$xp)- zc@h>1*kFh6TkX%^=BZj&VBsV_{NmDKzWY7pA}0V%w`Y6|WTb;^Wo`*aA{oKpt$O-b z=DB8{1vxa4be1e>?jx_1f6>Yo!#=Jk~M43Jy z2umS@JBeM)*f@nbQga}_kq2D9x8k)Rn0IexI-b*EY4t6(qqekKVdbkLxM%N%`5eP} zLUG^a-Oo57N95A=79RP=MRv|JMH9^=UyJ=`qW@=?+w@_2o*8pXEWYa&9F1qNhaKkv z>+hAf#n`R<`QoV}D)s>ZXCc#IQ`3k!N1k3Jv;(deTR@~VqDozt-&8S$I);ULv`r>% zr7hH&%VO3qNiKT^Rs^&L|HEYV2F~!VgRT9#!9^z#66cU6)&-;-qdE81F7`Z@zUN~% zbRE~VlV15Dvb6+D2^ohHU?hzMGC{MP@{;9evo33F25G5_#(m0)k#VFfG|i=1g~wi>gxkErsJ z?7zYFG9R&2O?PA;g=(Y~Bmf8tC|==Ox0aiRb-h!Hi6(E36xlZ<}q+d-eM zp4bUZM$r??Dhy~uPNU}U$rdAj9e(2>%>}UoAY%58ewt_)(7=*dqqSqVFMH87v3tt# z@QX6dith#rs6}C{i?qHHMSQ~ZcjB5TwML(z1ONoEC}?QC34!3X-d^VP ziFnXd#Z92G;0HhBaEK2xt0BVFOu7w}rA!6EVi!Pth@-AYTvDxrJv1X?HgKmO#!6`A zD}~DITrdzu~YNb<}kedL0Jw zF6y@9?fz8B%vHh#8>!W5nb!p>)Nq(gg&ju%lHIcf81};+C`83to4$Lyv+sw5ZG#DP zXWb2$uuUs>e`~Zj^dNU9uT*}!9Wi2A;s+Q#&s?!Q=6pInQKf!LMrjNf^0aAm8;rAX zKRicgihh2Sdr8xgE}=dl1(j^fpo$vvYNrFnoXeQIIwVy^+KZG{#-FepY-$@4p|Tu_ z2G+^Or#x=g2zTUoSfNFnicGf1nF;MSHmKW#yURukU;3;)fEhb;V5_vs61*-HjlmVY z9V%8iw)MxZ`ms26gY3Aocn~{{dLg#q-5rp3nh!ba7sO{0!j0Ao%zl8e?I@!=B^O3J z5>1&9vM64P&kdbjrJu_3Oo}02MqiXyc*S&_X;njB)E#=bdKuZWoM<6g)>SD6I*O3Y zNyoCd%)|vaFb?v~!4Wc5)YxCa-u>hl<&4L4U~hO)GU@HSPW4&P$Eb6-f>@>4<2v0> z2b4#27w!*WzvhxZM-%WTWJ`alIpLoc*QEE3!T95~6O>ezmGQbZJw)&nrFm>h;(>i* zIiPZqw&;EM>6eXS*RXuVvKtRe?g5VAheDQw7ApD@{p}JppHUb}{97TcLFrera6F4+ zbV}8x5W+d9$1P@Usy@Q7<-C)SEkT4X`*<;kuovo;-9$6$_m=M2?(qeTQxk!A^h1|z zsC{frr3L3#xbAZaDUE8Q2i>VEg*|XXUSVTYXvz9C0KMEhJ+f>pl-HMpoj-wqs@jE^~*(8G*=V zEQ<5+Qr|udG7m(!+~#qgrDWcuOpSo^Q25ecIiyY$j1%7yNzEiosntVC&S^`8)3ATXIaP77<#3;>;P?P%~GCD(oB?-0-kUo zU4fKNl9z+x;Qv=^W3|z_jSUO+HNRHjC znR0BmOB$*KDZy_cGmP~xk#h{0O36MrSbRNyjW{Pk9>6C?J2W@tp>`fihJIoeN=7YH zOtA!`@`~egBHZJR#_P!?pqru$VR-fH%N@?<%iAiBRc6YlYh+Z_xW!nYFb8N1gAiwD znDX2_3aL<@Gvyk!N}?L01=$5+OucoH36Y-ldoVteZP{e+< z5N@g^ezqUvb0!*fCH|cSOHafPVMGylove@SS*%0#-4~EBre+PfkgYS8TI?XInHo=S z+)S+;;!b2!4b;e-83Q^FMnw~OOeB_GHZIE^hiFJ&o9a`eMiKnQhVO?xLI{l4o#ypV zHuog;vO2jCb?KnPX7@62phkBu#OZG_&n)|aWqJ9q(8i3k*t!;O!kftlkMqspKEwE? z)Xc^5=>Ye_4%rh2yGhJ~qW2X57mXd&>#m#LhhyX*}L6+L!u8F0D@ z+F)_)=aDMM-G86J14KDQuR|>i*tAptm+*uwILW7Uof?h9Ru+4m$Q^sY2m^}{1rb*6 zsS(KtBbyLJt$F2yHZ|LU#*mW_IC-i*Fbtq|Lm1L0E`m+#-Dnv(B_!zwU<6Gv6(uHW zzYhu{r+Mgy3%N|sg58}yI~E1I-Rba5g=r25=6 zihp*%^7OO-(x?;6M{ms~Cb$&|uovqzmR_?NV2jb^)?TyRQm~D$q4~NYF znjsefU6x08t41e4vSZ2SLQ8v;XIsoeCkT_`cnI~a6Jq&#BjN?RVMk*#;JoTzbD*OY z`(Y1^H;ncfR1o{{2J@jaJoRjDRgb%Gw=M;jxRUe?i94*^nr_MnBAaLnH#HVZHo7HP zCVGI-J+1;aWkuROoE$nIbI{K2)NX#+6~nDl&6C8aHTDc|hAv^Mkl>XuElHtZQeLqg zr{fH*>TI&zi)m3zHn1Z8Y~f0JoS~;yqtG!RI=W)gefNuNIFxPZ2k~Bvz;NtRWK-yP zr*?^Yv)a&LV{vek)!~gxV~4kJlKT$9W-US<8Gb(*#Ks%tZA|4i=eQY{;)CmTpSCe3 zCj)6*9eSk(oPlc^*{=AXI@E4I(eQd_vl>0klRdu=2IrTrrZ;d7yW2g#45tmd%q_=J z2AZo6`QNe2mwky6ikZE1Gs+ge>ycB;LU&5QvRL$4Wh8g6szx77&0pYBX+e_}CX~~=kpK1i%&gQS%Bihz zd4DP27~YK>>`}XH$WJE!7uJ&q-j$rDf(Pjy;lFV4rVt#?)S|D)TXXJaj?H!vZ3PeA z-fRjPKlb1p6ZOxK7QpJb1_1S6uDudsU@cVJ^_P5qjm5)IN2kTaeEx6}eAj34!J*=f zvft9w^2Qycr^odUiZYlO2!w?Wys^<5aykI7S>fiyA-fV%#c?Z<)?(V-B<`<6CUO`l z2o!^C*2~J2!5Tq9_bVLvv{!R7>0Ko;sSBEt7*&5yN`7Ryg{kM3wAN4Se<_lj+b z`*jAoyjf#yy2^)TrTTTyL%JR~Z4O|*AQg3of?jG0%xL(7BMjOE+yt8O2k312N3M0l ze4Mg;m>y?3=SA@+O+Q37G8Lr^T8YLuMyB-dURWMmqe`Nx;xaj&>8K?W=Hrg_}V86tNk& zs7JOPrR}7E-)*Ufw;e-%&FJj!d~oih^6lk4tkIgX{n(;+4n={RWtdKwDHp9*CV^&I zwpT*z15N3qS*j1y$n+CXr#3|fml3U|*3SW75ldVgRe08><5wr0SZh&M8Hd{VXmPy6 z!N&Ia<5-yNly(}2S)bs|V?jviY-KDDe=>T4QB2(#X}nn$O7P)5ne?za-Zz3lR=Aj49(C0PQ7WNmoc>SrD*_ROaN5nl zLOA6i9OKR)qT;x-Sh^nrmexRhGo6{eC`eUQMrpKHw~jD4Cc|AEv#s#+VBmaa+-Nf( z)U$BXDMW-_FsJ3$lnn{7jtPe!X~uXbl$j3r>>;6mq=`Uxsb6xL&>9B-g!zHtklYJ4 ziEbmzB*6|FDzkb@T+Hy~2(pb4)I2EH@acx{&i?_Eb)s{q+K+XuPPBTRY-Jg&6Zih9 ze$u->SZ9NPHRly$Kmoiq<<7#8x6rm(p#3Xx<55GU-!j}6^RLg*>xH2 zm8Mb-z;c{UTJ%byz+IvWwh4Y?Dr)X|V1X%6JiOXhNmC%ZsU=sy;*|jDWiw#H*u`4s zLC>@1z8}w>ogfs`@%NgxTzh(2nMYs-B74g9nW-nruS+%tyZqKv5|dpfkWEG&)7k48 z1pH$$(qnNn%Ax#7(*vzBemRG^-tI6Q!Ih^21I&;K$N<#|h|NF0yb`ZCjhL^K7??Nb zR%u4|2q=07ym$x?AOHt<0hxTeRD&A|0WU^S97jg>6U>;DCF5r7(!&#H3PPh4Nofut zlL->vw8>Bci&pHhxs58v5}X?uM%`L8IY~4iy&1-NoBXpKiB}y)@i@CtqDNNl5xFna zIdn+NI{H7FL5=XEWs2u8IbPGLgjCUr#!2?=nYNRFTn1eg>?E(6WDmo%N(PIfIW-Dt zk*uKT2jeQl1n4N1c`Ig#$T}IqVPP*Ff%b`_sgN@=<&9xwic}LxMT$8z5>LTjF;%RP z(X<^;nw;8-9KqKxQH&agu0hK1F-*$}>pRE^Cx{R~d?5haz2&6MN)latI2x1`DbxyrtV$cGjcmpO+VoFxHPZ(rQB1L)*OHgAzDDJ z3a}QAa$v~Uh8Z&r7Muf(G}~za)A5J8TFM0OWcOdRpeuI<NCd1RKIsV;|0n4a&R?IXA55B~lUX^vlDjlgJYHo}*yhv890+p#^oVhO<{ z-?qe|N@elrX_?fHqRs)G&mxyt78Z=I!~A>9cDk=5y9HI~$El37l~Qe0 zY~kETo=KrAknM%((+2qU;DGmlno6vS1Xi8@q3dt)29-RnDo>@`@ZuIhr0)?+6>ZPV zRi}AyRZa|Vib=L=ay_DTAe5fC@t2%Rx`{-6-z0!ksp>>*DANd~zC)6sJZ@sGfRbkU z_L1D{eHAj+vd1;AAfK?@j8K`8KgTm#9IRd9L7%crYi6N6p3E6p_6$4q534I@+5RJK zL^RSdSw99|Es4t^lm4MnsZ$8U5KnPpblJ0ZFu~9>^JvxdgYU2Zur+9a(smp$fPlo9 z{zogE^nXf*(EV?14FM@R1!H|9g6z@v$K7zA-la4srGD5;daNhcNy<|IP zpR}E1JKm4z*60AYMw4L;V^GSVq~hAjej*HYh?AYCTkmY_oYYB1R<{}OdQi7g?a$YT z;0#< zr(TzR!}B%q_?6ZY6fkc^+)TMesQa-hgqYQq=@F!M`4xCpEp zjv~146+)XZEwak}NwkXAcVmK#)h2YXfd_TY-;Q1AoC?VsWD-1osXJ?pz`~LaR4FdT z`A4dm)Q)3Xj&aCGj+^tyfxt}W+pIr(ikmX!j}!n}3Rh!cyrMc_g8j?b?R3X0`IDo% z5uXf1D?RGzi$liRX$eYmvGNW?!_lvqh1bKiU>9Q|F_CR{9liKrdP5n=S%dEap7yr^ZM-EAJ27K(XXHuj`=r^4o6$s5=HJDfpra{Lxkx$3|{arJAX{J=fYjdO=VKlRNH z@WZdm{d4H?%k}{GJwc&UQYWPlWWB4Tw*|sO%D;zrH6=AEvW+a%&G!P8vX`Lx>n})- z!nhA%6Yl|+H_2F=&#RwMwaq?S-@*+0HBNygLck*(%o*I>o>*6PR8QQ!Zmb`A$Zqg2 zH@KYARIF=?*N;~isz7W_p*t45J#4PxMCeAt)1TUD4Vwi%1nz}G21rsC3V>uA3IuaXM6Lo}D-SaWi^6XRIbFAP;tHd( zt7t1Sr7uk4ZXjYPBzP|%{NU6rA=KLdWl5c!G~65}&*AU4iw}4p%~iWvzS3vsS&XtW zubP4`x5AO=>>4;YA!a>#8!K0x?gWEB1^2~))cRD`?yAwi4B4PTT8s+zZ*UXN3P@bU zY>Im+#s~=4Unf<|K7<8wuS|2*5JR(!hj?XjB(f0s2^ueI3QO7o&1K+>@ck6%k)xQ6 zhy8uwzZu!C2xF1}RQ)ki{= zSMFLetfu+qr$yYYT8HLErFVxJj*+(e!u_)3nuqz}gw8f4g>fTc(oNjsjQxF+WAx}} zsCcq;9%^Ta9ZJ4@irqQW?2xvCqxu`)E<|<30N%8&UzSnEZV7Z)J%(0ecqFq9tBH=h z+GnUp_D9aUQHkn7#6$_KYA@aTy}hc(zrLs|+<6friA^+B8*_TOA^5*!uFwW~!5)7B z0pWxEuU;sQ{|AlcKa*Gg*>(PFqC{R=c7qSW`+$uh6#zp1_0542Z&ym^7gWkd3`(J( zQI2*rzp$>pFO5@U%!zVW;~}s=i$9AW%%LM{uKeVuW`1%oHJ!n_uG_-O`|EPQ2{^JA z`?L(b9QsYWB$0YC{6zHpT%u4A4yk70=TkT$Pin_UX-tXOc)ypFd1PO}Ej~~QKt>U$FX zkC=njmmB|QY&=zddn>gee7kGA<2thEr7TP8uif5&iDr{t;L6&n6!=wMzPqgoGx~XE zr687WY`0Nw-?#v`8M|MPbZ7Ad-b!ea3dq)sB2xyl2W`zX&&ygHi9ePNlin7WOkAcn z>A^a?Nmt)s|FOsDETfD_{8#$DfANX`o<9Ab_ZT$)=cWJ8YFDX4dMQ0+{d|w!ktT{l zu=f(kfg`2`@u3iy<;x*ei$RDXKqy^F9+S8;rln1H+N}vvaa&o!d%8DjSS8^#M+|{P zJ)Kssw{PKXTs>EJwQRY#dg52pe0^_cV3LB1ug`?sZvTA!^!(g(fB$g(tc+v>)hh5< z>V@cu%Npe7?Xc_NOBFtsd?1g7T&Fr7h9yNf#95h{?{p6|=evya<^6FAbnfL?+=Wr| zZca2aTWIN_hA7?wSi@R1X-nFPe*nxl9e3p?n$kgsWHzs)p5lt0=Zw4td77Ht9A=+d z93t6wiNPz4l7olK%HDI)ZKgIvxf;Bttnapi zaw!!q#ODwi_Pt?^R>NNq$y@j2VzZpGgt)Brnses^<&|wFsvw{=k>xod3>f62**DQ7 z)#j!!DWD0PIwV@%vcm~cz!~5lU>D<#dK8aH(Q>5_?2vgpl>|GGTR6eM+piX7DmYD` zDc6y?Rjg8y93DBD)K8x|&H1mKnyQ++`olS|vHJE$)ecCrym-&0IHsC90?2y}kkR$x zq1p$7{QY7qqyhbf>qrzOGvS)FYsIi|Y}p31saQ>f>Lv#4SRleN?+N2>%W@m-wzZy{ zCcr5W)4ZHpXpw8)DwPXOTAZdOK(wfnv1I*t*>)TZspoYAUn(4%)*E+r>n?$<7!^uU zBK*!qoxF?JjCPoqw`lu^tt;Vcup2ZjJABApoEJFQ?6`wRt^I>Zxk!;)LBAo7jk>HB zP3nIfEIc&$jdFu6vJjNYVnFGJEGk*+eqnRdq6o=l9}x~%I3irssvp@PPsT*)RBWO4 zq9s^0?cW7qUlXXTz{M6JUrUpK^@~F_aQRg|PTEkVFEwE0p;*>U4Z3JayGm_5`*ahk zmK{tAmMCN^_Tjijhik7&%T(btrRg~ut@C6cn$J2Lz;*@R;WfDlQXRP1`Bg}iObqH= z76dgu+EAgE2(xP5nMr9g;G{Wq%$zonRu4Qy*+}3#am&iF((+Bme|h0V?c30sf_+%I zresNYz6E0DPXW<5o*m9N4{39vwix&@ZdeS76QT;CWWBd8`w0q4vli(f3GqHxTpI=; zFQ`7E_#xk~a!KP#@2p1+z5?FY?aTzcVgHmF^hnUNGRm`2-aqc-jiK@v(wCCMLsb5- zO3RFPjcgM1buuJz*WiKL1r;S3(ZYF7?BP-2$qX8Xrk(U_q+XWdS5sQC#Y0(Ue)P3- zg$1e=`MhHx*9=`?j6N>F-en5`=IS5p5_mksjj)1=eW4Ryr&@=4FVe<;s-sC`_F<(^ zRIPVv&Cj8Dlgs^Cm5xNp|al(0bcS{N1xU*S?K6lZkUbAgtvss_`O~c=b+X8mW(`>Us|3aJ?4v=(w zBF0d*XT4OQUq6N0G~S)2SYi)pG^yzT%_z>OEglWiNar=%$J>;on*($+#B+$vZ=9O{ zUc(+_@LKKlR;0Apr=1xTT?7%awW8nZVai*?qn8i(GnMcdVZJ0(C&^OWL`Gu=1_n~` zoo6ImzRpl|sk2{K5@@RK(BScYmHmY&y}-SQjmL0jUIk(N2gW12b|7>_Uwry?R!wV)+r5=#tSNSug>c zX|jjE!3N3@FoWTiDa??QVEIz^E4w#QY3LW#Uo+c_rQ;%+9?@yPx<;O8U&h-t`O~kE zu|eJg%;bk{A&Xvvs!p$fY>S;&8=C+buCPS4BA#1z=UnSo_i9+9L(ny+9Q$Pq`%s%i2UH5X9mq@?DlxN1_Aw^^TPrhaQ9d$k&8s zCS8`hoAnFyr$Hq1jb2|Vlvq5d8Zy_I)w$?wyvtHLC7>O>RL6E_L%g^YsRoL#LO^}&VG`f7zvTChlPna5%JZy2MF8Z3- zVaDB{Pge`7^?1gH*}ZL!hTTXYBua-S8)p};Uk*FNY;kR*c*B~hnIuLMNlFVCAP$;gz{z zoQW>63m0<7EFPQj!Npp+mEdCDEy&IvYpkQe#nj1>7<-wQlg;RFomuGSoam10)lM*Q zZnNe~%i9{+=#o`x)b_Ot%?jL=V-2V`rJB%B-R9?Iax=;SP4Uf+?&~g8MPw8?ycf9_ zg3OID&(G^+QGcc=O#>;=CrFgYJ$Ih|b_i@-)I5V7D)haj8Kh0Rh^!M>wncfwO)P<` zq|KLpi5i2A3Qk#6zZ;kmrKCBu-A?MpSFB%92wDE@bKGmpWfV+WQrF&`n=3^0npSh#kur-j_pdF#aZ*nW-aqEn%EZQ zyBB(^8{vF+Ivez8aKNs`vr9~%aH%j3O<|EBm%zSEV9z#%XHcwrRW^0C|1Uv05Q!*w*6P$9_SQy#e+O;4jUuL zS#~ke{%Z4vVy?q5C;4U)N*C>>U^gaH3(3Xd>)zH81v3Dj;8L6`u5N`kpFoNa<+UYt z7*7uHjs*)CN+kj@A|9-KOO!!0@$`F2@i%qv&>^JWyZ$?$TF#@^^|+5eQzY{w)f9p2 zs^bJ-9A@JLHy5=&xC}=kUz8lB=1QhIhU1pb#jQJ3xcqJ6I<})z0icNrj7Mnf60ol+ zW@}B$K4im|Eo`u{>TwXlOdf>nDn@yqZ~3G%ZG%(v)(q z=$zv0jpk=^HDLZ1lh}}U4{h#NejBS}$x3!`P}cT zvd*RJxXG-ZU=jy>ANVKR#o{BkJ?xtO7*`bbs;2_&F~zVO;xnm-)0&V%&7W~^H&6w# z9`K#W>c>!r!?a@J7KsL?K3iQ}J&9`LVBXsZUaL@KIwf><{Y;v49Wy50C z>`YL|+0u-tEHhA==!lZNJroS}e9=r~wWM6=JpZK$56W;+0xc0~yJ^^r#QRbAk8>Oip#<+0yfTjqbKdAUtjqQoUvf52XNip2^^{ zz=Cuu8M!4;y_MJ^##`c(xB{p8wmTEAF!!*H$Uaols^s`+`U+qp=z54b5hamvP@38; zP8jIRV+E-dv5}96?D2wZp;o_DAKEfU=}4HYOZ(yA-*E8x!P;WZYXPUGr@Ax4j5>TI zrMdg$3p4q*AUjVp`o|Eo*X3#qQAx5A9Wva}ORo7+qO$tVANH9ivO3uron8=An4?W? zV@;Z|1@31JYAUP&&f1c)12GzRqg>%TqO# z7Yvu*f~yUcJ`go(e}h!F14)R&9GY6n*p&Vaq_vY8f_!N^fBwrWwC0tavYn6iej>s+ z$rpte?;{pEd1F-5CT#arM+^+K-iaG{JrT8@{lc;XvAv{(hdG#9e79eGr?U0-Gr{cJ z=y-jb*6$qAe0b?meNhY$^G+UndAI;}%_mk;q7Q;!qEQqKiNG8BvKah56E88UN#`wDhF4E_4YC&tqqsV67&=D-aS|49F> zb+R|mU_TM5zvPgRi&*lmwsO}KRc6%KO-RE|q1jN)aGb%#WG{m>FiAnC@hg#PI`erI^||`ANy^#!zQHLVJu)QTkyJZ->#h|2FQc2#D0?4j zV|Nyx2&%heYN0s_fS<=fwX=pKWW&Voxi!gvjK`P_WC!GzO-YUiOd#H)ZUNa*AgE_7 z@*LgK8~nYI?p%d`2HJvr#B;+*YE!aD+hK|}>JL+tt~v4dC9@ArYrWo-y;fchw9ElK z)2R@h!Y{Hrh35w;MfuWGb`Y6xJ0-OiW+i4~;Sv%#zXH&Dz3)1vnM@WPB1PU?ONk%s z`zOuweOKn$8;T`-j9TA9fUf}6chr4|tPF@r+d-QFQ|Po#Oi0Bg%&uRikd1qg-W}qQ=%C5qt7+3?#Cr zF-VhwmWQ)g?2TOC3DGzjb6ZS@UhrK9Nk)45-3akffA%W*1nWgk0;ak!MtR-l)HSAXy5@UwC zI2M=yM)t8wI;mmk$1E@;Ya#qM*~PZEw`zg9LY8Yc60SNAHgp4;HTAsp#CZjD zMIRG$Qn{oL~(P z>h(s^VJghY8Fr$(IN|coDIx@@07>31g}d-qTxWe5U}l>%QMSaMG^cKuQ8)=ADHG7h z19y5*%cG+$hd_y&u);E>Ko~A3M-Tvos1%k9uTLq|#ymx9R>>B_0veq(QrGBV;%w|| zsO+rnEbMFOY^LI@?99UX#mYPdm!ztyq8elZKUO75Rn$H|;Cwl$8lwVHf_hTNB)bSZ zW}VkN&^GxF z((%_Fb$(6KieFsNt5e*U0$9yE!e}g#zUhu4O|K+HBu25y=cG1)auG#QOO)>OG@K#)6e4~rH6<*< zG5i$yUJq;_0w$z4tkT%d``(I?>KW##z4Oa|^85E2AmtMO9twQLDAlp#u#tc`LhYh-C(RDd=1dy@ zjvS8g;WVX1MRR=X^;%ccT$lt!y7!;ERgzjkb5fkbM!JOA)?ANh#-eA`kYIK27ubd% z*Q!=y7_F1D<3f>)3JxqE--UZ1@^4I*234A1t}oLMxiW0C>YJ}$ZcNr$&az{`AtC*? zApLeG{TJOwC571loGvc85%O@N?!P)J!wt`C6F6IrUEV_J20n}dC*+3=^-X6T#ZHV46l3^=RTOKDF4kcx~R zCXy*pkT@tb_qi~oG0X)n33UV#NtUD)K#Q3z=RiZc7&U68`+Y*RpHQ-HlO@{Rf164T zAPMigbuqf=k%1!ot@m(ZXR67tx8|vOh&W2n@X%m_?WU#55Ec5J$tJPXA*IvFWXvk_ zD6bLnNv4I-%K#Y&6PU3>84r=qkUU}JppNM?Ets7eB^+=k#Eb!1hI8H;MZjO%nWvML zDp#HKEHmyDSOF&txX&vw%H(GfbY;d+Ef$1ik!fK_2n*WpyVK($pKaS>$2@7<+8$XA zhwg(FHPYJ6ZWmbDuiG`e%TB(7VZE@iQt`)5Vi^8%N&2FU-z}OIX^o2tKc_#Rq_j&h zCf}?oIeca?n;C~t9h!xx1pO;yj5ADZIP!1eq*p{bFtna!=~$!)eRFs9iA?kyQXt$! zj|L00{c*4AMd6%+GeN^eOI86Nk;eaB$$6dZ#P&?wvh{{TP|}R0?1UzeqZq_trFokH zFg8B@xA7o7O1%*&E6Rk{eke2QCDEyY5k3v2g}YSGRTEfbv}*9ch-hQ*FzS zvV-wBzAzMDW&h5O95Et>s*il&T7+-2iS~e0;jmrqz$3P1&cE9nl9~0{RxD>!NJtV> zoW#<8l?2n=2!q%n2f7gXO3l2F(Bbp?7?Zq@v8VKZ+zpgb(lOf*aLYRCZ<&PpIaXWXLObWin z=}-jt7XYP#J^mpQUQ(o?X+xR2&o7d6>o7?Gq>8z@euY3Oi!;hJ^vi+gMIj{9eYJQ5!Zdk zZ<3Za1s(^^%xhm8K{TtGS+1XXe+c)@dd z1joJm^sL6`+2GdtoMfK2)g0CQ(cj61;OP~Z#9~3@_Q{NW0MR9t(#yMMvb~~|) z06los-W9Xd+v@?JXT+A8urDHD;Ve7O$P?Q95tYGHqG>b+twCW8&`1oreFa3-E8@G{ z79Ap(3*xu;u?3*JqoN+XyVXdadNy&SXWCRRedrk|JciOB1oAbRii#{mY@)Vw=5&AF z*)LoLke&i=#+P4Ai}v__Z-!2_Vc77svq7P1S)^Mu;PacJPn}za-3Q0&HFQqDqeu)sVH4s7tE?3ghO?{EqU-br1)GtWs4lBNI z7ZLHqvHjPmQ#{2}|2=f~5-BaHg``o^DQM7D;~Pob8~%EQJi%*Ss7)K*-nIFghvy?t zp~gf$RGz=Qz(|SksGmFlWuWAx(o1rBmae6~jkgA(O$p4P!f*A4v>S;)_xHQ)7ubKx z9iC3n4%ikv7ZSpcxuM{jHqv zQ7H9_dYoRQo>Y)#N{*=8N3QZEWz9`6C-Nnw}fOFc#HKygOe2-Fe!1vBW z%E(2CqVte|X5`s;)j=3VoQLxKIZ-71S~|mbRw?gq4Wb;ynPef;$Fbhshq{O?`?7Pe z#wUhKm3@>~bobvIhBB=^+Y~DPYkU8?A_nNzFiEb2D^^u)SjW zm#FieR;el(kV7#tuOjuMEZG7i8*(hNt6iJ@s;tWH(D(3hta3AYfI|$u=X{oT9D^_L ze~Up>1N9N|pD|?O|6>aMzt%7Re`4_e#2S>W9g%-3SM-=*9qG3%|}q+N68~ zDglYPDyUPbv^#%H6PuP)lgta7)h!h8$G|Ue-dBi^$tdByK;B;bq8!f#Mf39$xb(Fj zrS`;qmgiO5zgS+~Z#X?DZ1qA&IU-MH-5T{HxS2)Yc5~f0BbaGlY+Ke0y`qi zB=m++gp`E#mMniN@B&!Ef3}wroa;A&z*We@1=YwYHT2$0gu9G{9prDuBhFAO-{j+W zZ2ice@<=p$;keQC-TQ7bPKgA7aQB^v@^lN>h z9t_7Rr$CPSMEyp&$?|82Vp3kXJ?zTsAPsyssQ5u2iftpmiXm~DVv{kIeFV4}o{7+F z9+bvHr^gVIkE>UaXQW1qgAX$GQN;E#Qr4S8=kzd~8%0t{dY&dz0!MGV=p&z@m;lR% z6cyfjl)HjjllfAuNib`@q*}-8SEFiu+Q$?m0__Ugs&2|4EQ_z3c}d(lfb*p(E}nq& zA>h4r&CObWDmGDylZ-}ZN2ct8H%@zD$i!^1)vgqb!DmKf5uz{=A>3CZ3U1AEE?(9f zC?3*I^zl^>Q6YmS&Iga^ZrkVeSp0@yxpz972~ID}q657T0l@M=2w)o8#^jcL&!HcU z;RehGku1o1f}UEJ)G48-&SE~H%zznY^XI=Kw9k8tf3d3Op^+t!wAOOA5;)Tj#BMl% z2hrSiUZj!2C29T(`J!Cq?vk51zF|IAdTxttmM@I4kSgou#EhsaVvyM#e;Qks0 zpXro8@?f!aflU-E?*E3(Wh?4FABaU;+MXC?D%jXUbx&zGO%b zFw9e?(U^hk5wB*&wP87HPpm<-k8qg_Qppp;dw?`$=fJn(c(jXsfCt;uIp#7Y0^E># z=LFRslIglpYKKin{5YvA9Av2UzKVSY?$%yYTfLKZJyA{}r0w)k?D*)T zIn@?|vxl|4#3y&wkJS~C?sCuWpW6i;BiE4pp+EccI&Mb zCYqks%jeB!J!eqig1*0ap&2@wiGmOSO^4a(EgiPo*zY4V*XX}I)NK0(uV6p{$CI^Bl0_~W&QR?)~y5l7> zT418Dj)VH}joyj)Kq9TF|Blt7h?DZ9oGP8ncx6C_BvVAXGwx}uw}X2#C4vo9oB-C} zggguypf`^q@FAye^0C$XO7f(j;?&hJXxy;itl0t5IvI6>Zz>))U(9H2@#z2!HGMT_ zlhb88<{iRJM&j&LGO~<*J8OWk;cXKNpjnVYD7xz)1m2{GBVXMmRM(|4X=SToO5YL5 zPd~mhszG67Kd`Z(i=Fp#zTCtNJ{id)?j|4M@R4C)m~>-qYX|%7e6bqnow~OHKkE!l znNZkd?%$5xWfl@VP?a>qlU??*i?iQ8Y(ycFq*J+Io9t43!J5M#^Jm!zYtcFt>tz&H z%^{kV*Qf8e$8TW~-%qS7ITrGBwIx@}f*A^rra4dFKWA;v-J1BjghRdNUP0tOH^2W| zCV=uWQy>0;QZj!c=KqFL{?|}0NOStSI6Zuq`jdOg2yd+u=dVCL|CoFMNQ0-D(W#^fVo3WuQKT^aHrMKjH?nP@& z1H4RF2rdXTb!t5;Ad|{;D3m70d!j?*ouWios^glvvWB`<=wOF1yx1So>I`a{22{en zYr7D@&+A`~0jeap0|rVwb_vhw9NOM42r2yNt*$?7VKV{o#3ka65V&|qzvZ931-C8DBro!JD zLElDyBES8W$s%fv~EZ@w+2_j>wFPXVez~UUdsq^e%I(qp` z7*^!;S9t`get6~Bwapv%e#IH__^!+*my;P)|KiuSbK8M%SKcWMwh%WJ_T{As=8xLJ0%hTnoEKpk1Cyl@Nrn z%_RYPfG~Ph_4>&?dTTpbL$BMhD71E}^cfi)jRVBSMwFvSt|U`UlS_%PFmUVvViVVf zgL@xjY~G?Ja_A+fkKKMvRZRHIU3p&KDxwW2=UWD)WFD>BUK=HojIB^C9VZ2L48p4I96`sSq#2O1SK zUm|cciCo~6avtV1pIBa($&YrA4`i$mf{?dfI@nQqR84!1Q!2`ua1ASoyuIo|I|cN& zUOX_#t8pN0v?>iMnjlqx!U|i1iT%`MAB|?u<6umYT`@3k)ar8(b6G7+3h`5y#?Rgqv`~dHsJP_I zOVpk=LGhndQOeByo!M9oC?{&lve4`D;iH%~ck5E~g?A{*GcCvEsl2E;Yt; zBOb7lq5=c+=oR0=r~0N?!BPrK$In&Ez#x-Z9lWei`k!<+bqP$ZYQc)T5Qn9k-RW;n z!GZ-OQ~}<+Dmu4a@!#Kit}55@Ba;0mgU5_;Jer$|h#{_+{iHz%vBY3xL!YSbrNvevo2=w~%E{Wg@!bIvJED$0HrVQENps1}WNrI_v zxH8!z1r){<#Wr%YUL2^qDgMP>Mm`7iucE!rG84lQ#bhV)ohWq^V}+*9DA@t_fyV zQa#r#1me|e9PQ+F=hH5%0h?n+B_d-cwB|w&TZ0j7SwBG1CfJ7ZDiG%w`V$^Ow#nk> zpmcF!JN%XEu4(wkNS%yOaP9zz(X4<^fwaHU9N)5=qVUtGofQ8&-9+rt#)AO4a|48<(bv(}Bsx_M#5UJX?F>7>w+p3M)p z@gJ5>aP5WXsk?UKbPRt}W|~2CI9K?XB8tM<=*?mAY8Yyczb?fMHKoOVv=Un{99=lh zHkYZ~%s(ITG2LrQ>Km|*j`j~A153qJv{}J&Hf_(GM!k@QfA^u#%uoFq{Cp6C63;lB zqY0l0&^;kL2rD1)jby~};~yzp7r(a1;L+yySv`}(Y#z`t{LDgA_e8*aV&jg4jok7u(u80?|1|}goKIy zma}2J#+fa1dM|FsbfHd7%b7C%pw4AC+&md>=1fEX87N~zXMdlN?dsWfhm;K8(i_r`g|O9Qa}>__ zyE9G&J1+XsOD4hR4Baw2Osm7NH{QvNnza%fPgK#{^F2*exIWjxI=ui2AHImRUOL8+ zSRwXl&naRk;=DVvu`n|QIf6sn--xKB&97)gUhx~k5W*8isHj&``O_LxTXUH8{rXZw ziq{Pl_S7Lq=@LkOTUFVto#EA>g_FYq&=9`$jnKa6G)38H{G- zPQl^`b+dz@uxsc5=HeO(N{Pl@3b|#&<_O|hJm)8d9M+~5h_z_r!Rs30s+w_S20E+_ zY)CqrQyokvj}9&)c=us3RME%mxpmuNGgR4LhQXxOD2tMrB2()j$#b`1HB{NCz7y@v zRlXQglrps}J&_6q;_z0b@_o0svFe&5m9_{}4@=w@vQoBq&0`j?luah}p~N=Pt3~*P z*k=?}Uq8hYf^>e5Bo$VSP~w0B><$2x%APs20+*2_8~;$56n}j@=_z&X?rEXNl8h?9 z+&{@ai7OgYu_eGX-}p+xh8UgTdX!Ad$k3T$$u~_ECl;D`T2#@;Y~EtITBsuhd<0)! zWu#2D0+0)F77|8hS@SQsHlq7usd`P zqPR#*du{{`TdoWA(+(x)t<3LJ3`*A#VUXmG_Kq&@;?1NZ{fY?5)l=iPXp$QCzwVS? z4vA{!v{bZ%`1Lxu;j@gr21CYbfj5@oT2^xBFfM0?RtJ#X;rNW|;)R_rz^(L98*++q zaIcLAqZkm|BW0^GDCFs;i?X(6B55vMumAYWaP|u{hZ^jX^*N9>zoqH0&Wcv#|M1hj zp*{%1miUyz9^xxs^f$0SI98J;oGdhMJ7-;Xex)P=fagU}4R48i=Y^76Y*d(Ch znb}o4dvin~j<;J& z)J6lbl|B&RH3ASJ^!uVAT?_=>xv<9t*VpCP>v{ut$+VZ#>17Xu1p257_`S1WG;b|B zRr)MP0fS%yMo*k-*wupL7D-DovMtMt)3gP$$B5~}c{~oqfk~%qNJbnWo+)JWq$aCV zfDepnJ^ro2eUr|i8*lkc1`j<*`d%I818b`Q3Qa6UW|a4Ogljo_DjQ;Pda30LzlMs1 ztzs(g%{#N_!E|NlZQ(%skc=(1cx6c*>a-x&eQtow2=3r~8%x#1Io7|GNlTmZT%Mll z@JcnGPkA)7>7`}m+cQt)&RD^f{@{gk^u-75p3XXxx6X`|SEc2t>MENI(;~2Erfc6A z`nr>}TI4$%{J|~gtBB!SZ%XA`La($@NRhxg3a+PZ`;_9oHPku=eN<07c$#oPb;UF~ z$)DxoQ+LZ;kZ>XEpuPgY)xgL}r8dyN46#;M2l?;x3%WP_62$0g7z_U;oFE!~GuhG? zk{t*tTG!eMe3FBAGM=LSg_kJ2I|mdT^v{RzmZsRbu##n3`xz3wzsZV z!$BUU+t?Sxp?^VXc#=vT#4FoNDqirsCbZi51V?trF9Y0aS+i)g&viui$T$n+ksR zq?ga~i0{2mrsaoj|ER2rfE^*&Y@3#12;gaFuc3Z7e1%)ir`arKj0%&N4)(;ij2A+R zmdSa0nj1M3L;!)(1_ui|X_aEoE^}41C6cMVH5$MD*8>Ost8_~RA9-spYBXFxOu$;w zU5s;blrySR+loaF0T5@$2JUQtx5q?PKT&0b*x5l7ajFqfIxAS4c8`ZZT0-wR*>`71bSQ5dPi; zLU79G4U>X&V9KBnAQBF&AXqZ7bUprO{F@Z!08}|@&bDW?ZE`W~*Vz!A*x68cImSqR zCZ^F9wo_A_9YQu%EP6%0P!iS($}mLtd=Y4u2i#!AS!2QQFnP5jA+o~@Tnek!t zKZ6*ioBtq8YEs<_A$1Qw7wT#rP%-pLV&-Ptkk;`T;m8n`gj3lzh}ust&NNJF_op1% zxm8x_mP-w))JzN8V2vQ1w4=JV!=JIy?BUwRIr69J0XR^KcofqGtAbgv^fqGd1U+(m zG%k1EJ47ellxae-k`&P)h)E)mu;nlDtx;;l{|ZT%mV}2Szb88UNCG_D06vqc7z&1p zhOn+$Wf2t*n$hlAu9W*3quxFKJ_S8R9aWAgn)j_1z(8L<6aC!`7}QyRcXn`cU2z2D z2DMuK`$hMGsS$YfX*UOh>`{7b&%v1TS~%i^###edbXW?9!{|)s$6!?6KMC_Q8%2IQziIPVv?^{^g>}4j zx;Ve9ysMg{K61#Vyt;&e)Rb+zp4fW zc5e*kxb9y0TX$5qf(DP1z4zdz5hkrXU{psVoi){NmkVHx)C{5A-)6R#EWGAd-YkCR zp51s31K6y*;}!GN^E>n4V|v9hVHib=%i84?50A`5{8i$5#`pte)N)c5MvgcP7d{u^ z26!``lrKq;!A{g?9$F{+B?jKNvm!5jv*PTL4yw{61+Gk|NT5s?%AcWAEIJM|dKji% zvvKk#>wTfpO5|aFn)H#-cS3ZA%R*c59yB>oLc)`vXYc_s3eYF2$ILr?V@Sj9*7Uaf|ry&zIMZ$b$HXwolMMDpcCWx2?Wn7CyCcydW7q`$- z*>INe$k6pr0(vUnX2D z0-3c+?U%cz-y)N9_^?T{Em6Tp3DO^O*0-|`z2#bMgHmvxEp%Ng^FW)qvjLXO zFy<5^%i;XuUtcR+_!Fx3+YSwP1du-^*ys+$i=Xw&2LnP|=yom0^OsC8!J?e{Z^Ha` z?38{BHE_$YvnFOk*vFiT1)in90Fif#0DIOsE5bA&59oD$us-OyFY;clfW{0qdAJ71 zVU7Je4vhwwNl`u8QD`~5W*vV@Xes5t{CU!Z2awqg`G|QfXgGO~;UUt)^k1P*!u^k( zVR2b_h%)~0!_!*DJbsbR9?(&97~H_qZUv=X8acukguN+%9AsCLfV%C_2vsqN8s0+>HqiqZq%m%#BEo@hhQIOrO7W&o zKD@sBnzfzHs~FCLbPB(AAim2KG%b?L?KsqLycFDD1L}^!uzG(l35mR(q!nwMxwenZRoewKz`bROrA7@qF$NMA8D}NssS% z9F}P_#8;6}0og%V_aw`0fPYL)*tJGtc>c+Pe4c&z=|AI=@N?#2UIiX4?m#`CgDzo- zjjSGpgzh0`i~R`-cjA{j`x|OOrf`Y1D##K}fHt7xmL!%V9MJ=hSD=HYgq=o1xzk5K zc>Pz+p9XsKktLlvXk-rx__1)Bi3B>_a3IU*LIj9{Q=BXVqdmhBC$_+O;XqIt4$&G;cKw++=f? z37|Bya;Y7-V3$amu1>~*6#L(5*5=JooP^23oX910R=OE6%}yOh;Z>sBjqrwcq#qOw zMXL(oW|9~soFVdpI)rUj^(6`I*3c`c@YbA@IS=&9H-;%R!ZkIuMQ2l}`dOD^qM{*X zjE}tZfS^=87DbnEF}gqqQZ9s$_pMXr~0qORTu>mW$HG92Hvd-2K~s~1H_9wiT)x`|q&X^!4Xt-&lOC>WeaydgR8 zDUOO~02*8mBu2s*w`j_Y4^#SAPcifx)(;E< zUHjBM?W(+mFji7`DlDp=G zjFZIvchPt679r2@Cf!+O?S?_ONYzZQGfrU}qGi+YJQ4NmbNFGkmbuG1AN_v9MK>`x zkvwu6p^`YA!R@9jSy9*^T9aYT+Le@kT%qA{1AeTIVH@!SV0m|kH`$4sXx9N0I7P~#QP{Bt}(*zp4BjzIqyrQxLAW@ zf4?zS=u*XLW4;4K&o-{G5zIe-1`@l%cTb^oVsp2sKMahv)x8>DGej>I#|!i*lb zI_{wHv_#pAhisjDbBC57{--zh8jc>ro4(55H zgbYqpY_aCYb{;oq+1N)l#u{OI`9)CYAfw8aV*zs{fGU}a@h}w{AcP#kMURfQ;ia1> zUHMfQ{PHG6M7wh#zjZ-|31`F7lujOu^15m|x@FYNLDUUPgbI|rpG_Iz^u~z&J+)3H z!=Ex@;1YCk6BM|fg*-?Ew@|YuS z>j#+TZcS?z&NJWzyV`%|#_I*=PcOO~%?F5Wi0@w24XRC`?}5wzMNu6;TB?rCa z%N$vInO5w;kZ>9et3gaF`2C=C8lBC6{Jsqr|3xpuz7I7D{DImnTMh->F54{!TDWVO z7k=arKQ)88-H%PxgcP}cn>o@v&;jTIbCy~8ka%$$+uCB7qEzIpzJ|YYF&x*D6Hty# zJ4#6=t6tNoLzey<)HE}95KA%lqEFQLC-W1`G-H=vgEXCC)hQ}Kx8RQE%oG1y3c^0- z6gkWC4dq-~SMHO_irzakIsr42Bv^tf`BZ7WR(-sWsW85k4=_A5Phyo^ZXd1`D_Jz; zR{S8SMMhIn51T5Q--iY}}qD8(9j4m~2h^kO`FL}N~=?kwW zVY}C|(Dhd1bVkW1U`0H4KYD)UMX>?uPr9Og!&*#BhUmWaF%dx0zQUc+hAB71HN)~2 z?;d#5MkkzeQoD5lr~iHO-`>n*%Wl{4Mp+juKK)K4e1_{Dts{JL?B2jJ$V=EODom#C z0N(vb>&OS#6$^g9sPW*)p^}$Y^FiVr#wK0tfaxKUmr9ObPaN(Gl{*#>-Apg~q54a{ zmgu91mpBiIFLBHMgahZ73fw-`9s5gpCy+0>F8`zDEz7IPN0%38H| zOBo{&ucA!e9rK4)*$`b4+DB+TMvqd;9&fS@fUdVD3ICuc8T&@lmyEt+F_hiuB_Oe&$sG+A%-^vFSAtfuhj<2eJurI1M6 zeWbdu`g1G$9yVR-VK@vzI7sQn`BLppSvHzHjhIvKG(ZYclGXx0oA8HR7Ll_@qfGR$ z*Zf2a;z_C@t34AKF@tZ~X{6*h!Fo4;HQ}`5@#veZZrdC$nk*`=Amwf^CZ}_?Xr&Z^ zyy+&c>E#>m7k&>74RLuFg>Ax7WrSF{r`$Oi(CND$3(q4TJ$esXZ2aH`v<2lTc ztiXp7Jyc9fHc-qLShb-)e{n)cp;@Wi!0>>X(7ZszMJci;@sLOi^MEB$wMO-N0_7K1 zTp%ylB70E{)t?X(evEg3qV^C*TPG5}fh8VfguQ;Z#Ma>gR{-OCfwT?4^J6-j8mq^~ z#dz~3!1LoBEgm3{;{=39u(dJ2BcLE$4xo14bGF8tP`>Crt;F5Is=@KotoQh5QSdJ6N~+nq3g^WluL2|M~lL~>fU_fo4i#ozrGGFS0ts+Vx|1Vn@Y zIb66!t{+>owOcf+Vuq)CLKqa)%82|))P{LF0B1a!gnpr|lqkG$UIHr-hFu^yo(N1r z2#}=cO_ZEi+M{69FBK1V9|VgQzPDRAPwLQ1UxfknFI?WPj>2zZ&}_aA zd6%OezDreZWyFTR`ro%^Um3??y6<^Cm(0EFtha0{ZrxlkP?D*0jCH2DI&;SC`Y$)P}0O)J1A- zIN{W;VSvw{Fe=L-sf!AgNPa!2;}DR7i!uC)uUYHAAHp@LAlx&6_;iWLjsJ77J~KpH zr&+^I(w{GSF-OO5Y(;F_{OrUz)bobljYat_ynHA>2B6qNij@@KhpN-%f_?h_?@l(l z;*O;;_`iPb3jFT|{r_cTT~6OY-}*l=NOb&|3@|@J$ae@3im3e%*s~dMfjzB`)_xyL zMmQlY4x1U)2_F?(BBs_pll!cY;eH>)O92c?Si(U) zl*+>NC!@Xqp`ZK=x~Fc(X~W5EaI{ zvk-!@nA)AxMa~LzKlg5Mx!y_h1yRj$E7ek${NfqvDZ`}3x30gy6L8SNX%7$+JGi#T zxqoWNLV73g)e55EZ~sKon~s#}it3YkuEa-F-P}mxC`4RAF~osx?<=&SVx^fAXy9o| z9H}_hG#>}ZjCIItW|lCApzcN@nYw5jGUMX%VeSXbp1eSVMLLtXzok9DXTxd78^s@( zGgQTJ6)X&of!?$mIImREOHJoo#kwo7;LcEP$>|^RuOZ?Nr_ke?eq@96FR&z!eut`Y zf@fo&!1*ru;0p@aI@pEsj!47AA+RFwO#Qi19p=fsh(jne4gnS;K%GL!wu{#op8q{8 z=n%aK+J5*CoBu8U@&8Q=iQ5<%yBQn(2Nn9i)`0ydK$_HkyWyxhe_iu1zhiJ`JJ+XJ zO~hnZl4v?0iQ1Elgp*8+1z54C)OD$dF|Ol^8(v3lscX6bTlZpMfj}iS+W&2W70)g% zj8-ICQ^^N4GfzYkFqh1$nN^@@!_-O}lr02|#Xn`GyE)Z>!iVAenWW!t-d02HJ&Yqp;WGXAo znJQ+4)&f4CaGW+kY@Mt%c7DFR5Fb)Zzbs3`LvL-a>BOOJNus!Of_4jSG_vYtD>nth z3DozGm=c+%Z-HzT*emAtdbBHomr*Le$(Q)Cvt2(3=8J~@1L!OrFosT{wg7XzmKITD zAZD+B7t>Hh>{S3F?KHH!?%u8fwvM#a9p5=U7*;KXG{975sMo%IC|$NrTjSQ)3|m{j zR-GlNee-h>vy8MHi*L5$s*W|gt)3L4%_E=Mt}D%9jaHfuLq2Z z*Q$VjG)pS3L4pi=i|7ZRgmFG?>}ypB296DA0><{yp?j$XSDnBW5aMOVXx6K_VoG?6 z(J~O5xmXU_Z|Bq21(Xjxn_&w2{3F*sF6EzTq66Ok=p*0aH7xb}`%DEPMdM-DkP#~89yuX(0sLdQ=2nqsQnMD}C`}NLZZI3L)US`7W71 zZtK;UZt?1?47ZjvM#3T{!-v%@gyq=`lL5m8hCO;vsKfj-mw>pnS!67oo!$jlWZpn2 zD}4y=DpVZrRv)4{$!{1{*Z7q(b3{AljPEg9;aAq&d4UFK-c#`hK;zFMownwrb{kYb zAaM+Z-l~AvBC0jt08qVGZ8E(wZK9$wRM?>;w|!7KNv8zYb%;%3#v9j*41RTtAuJ_m zI%9^wEPOKRKb5XVdPkwr?vxEVFC?uYSYW|Wt;!mkp3;*a5w!{qZ5)Lt0E6f(^RauU zMs(!WF^acru1|H^F_C9Jy&!-g2NaRE5)1=Ee)|wwO5ra%*e`_208CGBQ+=HGv(rDlk?emQ*~jBTF`;*61Dg zro%$*%*?i*OXy5gjuqF6Qo_F)U{FumnK=0!Y#xmZs^2L)^nPn;#ldzX`zO7iw*EWhTkx^qKm7B3B5lQRq}$tCui3rp-Qj%<7>Qt})C7MK z!)f!SIh~HBz;sRS@uS2WuvTph?=V38!7Bo8S&bkox#NYg?@#Ybuzovnc?|tUji3BG zBqAUciZ5LowUe>MJShd1r8qUG_6i!-Wd=RF!->WO!jw(x3!_O5iR;C8a}S*jHCa_$ zWur&wR<#~ytX@yicuoFhis4(@NE6HPKqV<3; zT;9KaW&m%Yvr2l<{$=$?W*>^=kNBmSjw-BAUADa4p0)|3JpOOd`VS#JJ(&Rj zC39rbz$Yo;umZis9LLd72~m8lWrv{36Y7y*^5b1C7hQrivv0AJk^0^rTA#eEg-6QC zg4iDg`*dIqF{@Bsx|gjEphJ5v!0eP@0#0%t^}<@3v^l6vi>d0z83s%&^Bn1uUoy>{I}`WkObMG(7nNyJK&L+9Bf@ zAJ)6E*c({+7G8}S85WBCjAaKY`&iczVlgkWArRuk5HwnQ_s!LocbDtq)hgE2dLNVi z&Snv4i+rWZAb{f_fm(hj*#K4(dPavyz>ODjiafI^c)mtqXo+YrfkL~M20a$Pu3T{S z3%7rahsN%w`y@6!pg|^%!X|-UZTvM*ua4Hap)gJU$=*OAeb&OS;TzqnoH|U5S*F~|mr@Lha@jn%pJ zWpjQHu6=lJOCGTjW5oJ0!t2uP8NqJ@zb`fLYDRBL+zPT?w>JZ>CRkyXGp2`Gz?3t% z5>f@cJkVkm{{gIAGf;WjKJ9~d*|$<7Za0&I>C;&=bDXh!_WN1nY@5Yj*SmY|5ymEW z&^z9b{O@S80q}KQGN(-i+4R8|oG*XIenP3sMq1DmfKMGI<@d8vibjm90lP zUwQp<$Hf|h>SRWxOY=%r(br{@DdO)pkS2dD(^=!6MHRDbG7`lbg|pZf=FmQ+U9@t} zNU0Fzu@Gl5__co=hhoTO8&}qdwEQ{hbA+Au8ZvT6EWmiVOpAG4Dn&pofXCBMk>~q* z9)V?I50GWm_50Y+ctj{`6Wbg)l`ag_VCW}Zn9iSwf*@J-cmqx1ZoMGdZ(OF~9FAp9 zTCwfTM)e_|@6LH(?!S2Z-ybRP0{lZ?zu4e*k=epV+U_t(=%;Umr#~6yxn8>hL#LR# z!(qCksbgKqx@Vr@?IC%G<@W};`-fW4pChn3CAIurBaB;RnSb^!nRJR;4KXnEKKpd4 z7TReY-tgGNZ`0xJe!ds9>Shf>-D2<%R--ss;l@(^{4 zblb*#doHH2k9VCJ8=yEO73}n>lf~h1$Lu6yPR=2}aFeM9zaa7ilZO{deC>?j*YeOH z?({3NiE^cetKKr-YxV(dl|KkY@rc|>d89K^!*B@64sedb`a#X_iV+6fC2o<&AZhJL zd}~&PC%H;VGW4Y!l!6sop=T6ySms`Vat>^C&OULa_S|2><}2L%HD1G)s9s>a%aH0K zU#LZs2hUM>M&wcDJMevt#K(5=-U?A!45IMfxI~)!1V(phGP?>=;A(bv<<|nlX^2f25wcS%q&FRF-0XTe0ZR!?lM#wZC4r`YfV+IO+M3n zTp52oFfcwdsD@xP*&mB0TvIy=JdHG3&q?`m1+CmDV!Ho)-(2;rdjuU*C61~&Y@D{r z_({<}&&v!`N2rUtG6Hmtw)iTL5cmB9xO9ff?g_2NV{{Gcs!`UG!;wjZo(y%qxZcne zu(nkopiyot!XEDz+sU?G15>hxyCx5J8H^cO-lPo@yTqK#B8@Xr#&<7^R$NKrFSDJYiA@whak0NFOLQq9m@mJY*??5?T3KuZx5VN7>J zm}aU9t}VSfhO%EMK{Lop{-X)kbMznA@873TqRDW-e&zl2MgHH#5C7ji5j%ZD%b$(# zH0CxYw*R^Eaz5Iw@PLDZBZIrRfRl-UR~>$6eMU{zFW!CRU+hPH0Dl%{O_rAr=A#f4 z@bwTduyZnSEB|4lqsh(o502+2psJ&m=Ot&L)865wq+)3civLk^^)ynjFVQfOC&%+6 zsE6W-)nR~u5Q8v*fYLM80*jM@v;LgnXJawd2b9Z?@j&R$^Z$M(*8hq%!GFKg3)))Q zI!N0Z8C(75WXb<+KkHHUw>Q&Ip{|F7=^#zumkGG~OueO!S-cH{3!tP;M=&qN~Hs4p?RQKX!POLsN z@Jm>_N^{`$>LlJdyj#e@F`sk&pMRcQC$9rrJ%xjzh5UtHA$dDRN2Oe?v$dt8sOWu; z-NxJT`4e+6=Q^sAn*MsbkQV`JcuBM98+d^X^xo0clx59EBG26VW^n3~-O%vQvy?N>6-D!e*q^zfJAys>)g#>1lGtLX5P##2s0}V?~%#Y=$;&F~yxnb$g z>Q1VPe!L{WdY@w}nz3B}>kuA?W>ZR-ul0Drx%6N4&Jj~NGc|w_) zYa5v^4?)s|Vxj6kQK;iIiV-ca=Lj{f6pbQ;M%0DD4aG6FPE+?K7x-hUNz9U^H#Nrf zEWCpYs6wccC#Ayk-ea*IZ>Q#?Da!*;M+buWKf_h=J{e63^HN7ETl#dg z$^ZWRx=hxB9LqTN0(8wV9ORUJ3CkXNRWwkQk z`~TLsn1Xc&={LY^I8lzFtIE8@N-@i}G1h3!KfjAvr_5Wzr_7M4b_lq5NfF?$b0Yp# zYv4B*PswC+SsN%vO7JhiL=Kh7AMiHBZEmrzr#sdc;?)&kif}d2N|G(|@;BJ z#oA~hu4~#$z8S`D%%lWoMJhhIU8>)$E2bKX@1JkfzZKZ84CLNHp!5(WkX-Nf{Zg*EP)0;d=$~ln?4~7|)lS^>{u(du_7Ng4U zG&!CdV(41(PcR7|QHYt*(9gwCb7~jLsWLp*uPn({y|cP#W2#MWvmpMJz9wNybLHAZ zu#W7njMbq_f0$2i%A~(DA^Xxg8WiK!T`AQ_bsOv}r$5*`7&0#}WG1ZjFyCTzPdTul z$)9@|dQXNcC%22n`?XULZHjMTInuT(Z*HN4yK2J1r%$*#5oEVIZ6UgP?F_=-2p;!* z34QD3;tsTV0~$tL##(q8Z_#`v`^}A)t)0+SyA-Yl+9@IT$;o^GZ6oN|YAfBM&>fRs z(cwMGJpIWMt4zF1x2^`od>n{Hj&b()Qw0S+oq@i0yZBH6)by;P3YApfQNH?!m~2T> z;xy|22W#&XU3t814OWs$D%h#mwr$(0*yfIH+o{;LZQHhOn^pO8&iQ)u?H+y4x!t2* z_y1)-tlz?1bIqwc2+g9+d9m@gmkvqu=@Ki{UeVjd(YI38<< zaPSvRUIBS_k%8kmxUTBkw?utcC|7VqnF@78uusE1urNPh>#Cxe)MFARak{thp3kjM z+vLQREt#e4V0@s=TSXrkX&04D^5PUEN1^oLFIgSpfdr&$Oar)8YM#^$Hj_xJWr*+I zTIs|pWU}(0hYYt6;XGqx&&i|+_|pZD^W+>9x>(rnb^PHsmKb(HmA?Zb0#Ag!ZJ4REd{wA7ljeYzCXb^&ve2q@%P(&S>^c}XSO%jxE8rpMIE>LV2yubu42lK$RuvBG~L7@8TQC+TZGog{C zNF)6xXGHD;6|++@JlgDX`U|u59a9CH`$8~-dSMtov$C4@ zDbo29Yv#2*83g1R!|YNPy0o*1rhz>PO@`}m2@--W$9>ob$Uu+*ueG<^%b{=bc2|ZC zA9R7hQ44>XDbFw##CEbhUUm3}8&vm`5F_$0d7jABt#^h?^@Iy*$SA!hm}!HpsWX20 z-a_!?L&Jqr#~8g{j1ieHs(bwiuA1D?Bykgn@k;2cr>etJgLobU%xl%6sS?O*om=xu znLO_Fe&4eN*$s`I*XCa>>g>YQX_7mPF;CjXbSV#^&R1x-)%Zuo(QAjlqWxY|n>epORjf1pACtT|0(=T#{0=45P57~gzR0E zX1UhLcS)>h?=|0e)FO4L_q{AwaBNwA=78B*S< zY7R*En$ZB2m;|mJ?z=?pd)~n0&s$`=aaPE6iue(>`~%*WNHM9%A3OFuXWow3E7tib zy7>L;r8_vt?^D<{lRc=FRiOqwyQo3qwJiNTGxAK8ZKMg;AA{;zO#T+xGXew$#pi<| zukRtmE*kMP%|CZIFBViXiY^Nt%p#id=vVanUunXPY%dSbeAyb<9Pz?8jz73EL9UZB zgFjkc9MVu+`wnDX%%rSNbX+6n=`*Hg)GzF#cizk&0Z-gv;%4YP&#N=M_%m7Pv@F$n z-jnwn1h&6S$}QL(P{T~=T`@r1S+aOw^g#vmT)e8LtYpvJ6>dgM?pwPy2$i#jSgs z_|zVF@oWnR@&zId7``CvzM+|hnr2dCd4 zCd{r*koIOk6{lCrf|=VPBFc38s464r;tPZ=qv z#pyK_WL~)yV}h>(y~xBqIWT4(>$mgZiSe@(2x&G>zsROfF#6mxwKFgUhPu5Rbdoz8 z|5lhxorc?Y-Xoi?F)}{gI0S2iA3ae`OJe5JU6~}_ zshTBFEZgS4mh#EA9JzE{BQaY~{Wyu$5)GJ@}{n_PG5*2ED<=ciy(TKrT z%8IS3Y3px#rEs}sBu1lYq-Dou$dWVZ%0{Gq!w1{Um<5(#!8?9G&0$KP=Yg?qo#w)j z9{zlDjjh`&ZH01{==m8!yI`Sq@flyvoAfF9kxaY5_0loj%6*w5*)pAXtS?Q z|AR4|(6LfA)6pF5?q!NJ4+Eo*$&$nPfk2M^;e=?4gQfmHo)Kx4%y>!4gn{wA6Tdzd zhEX#<8plK+Vioj>p6JCjQJZ`$&;?fUs*HbD9`)W37>1`1WQp89VpqT!6J)931aR14 zpkgfai?&CU-RHxiGW%%(87dV$CVa%d-xpFV#5M8uggpOpO7d!SCl)(giX5vf8~NF;f`jxEQ!hwmAxr_Y zBE=zT%yQz6cZjm=LY_q9{CDM}LtxY|ZH7{+;avJkOJCW_*s1e-k6}&+kSLf(^u`a; zMs6Wf-Y|nlN@JLoFMt&`Qu-N=aFbh)lnkjp|Ri!YMN!)CV z>~zlAxDDhmXTsLxBH4yAt;xnwntIIu?$Vro^R0*#<|;Tvn*(NuQ|lFiPr516+BDs0 z=CHXosRe(-{liy@Xl^7da}poZ^gfNm{n1V@1Pf(pU?tSSR%>WuS#d&@3HR4E0HO9{ z!ki5L^Oi_Kxw2C#rwK=1L7Ryh4W^1JJu!Qm!rn1RYb;m2+bSjSnhBe?hq|ktTauAm z@}|vv;weGIs40>sVekU@j@hVDQcawGnESqK&pS37?(yim+se7K7_Z_9VF8dWq!V-} zDAq2I?{+ECtySLQQ9xNV?$EKZ`FY-x_-BTJQ>|DOEZ0~xivnoX>yOs3PP_sxmGLr3@vj*`&kzv7K)gU(}PHbG2aK{H)Mc#AJ>t!Nhz7r|3hqGqo_3Xl1p1 zwE)y%4a)YyTIA~7EHTgQtUmh!TM%)RtpCm8=!SMlW)P< zj1Fy|_vVn)z?IUndEmnBSxu$~Kr6bkE!U;imDxRwsRB68@4c0d_s1Evr{8rGE~aO#x6f=?{3+C_f!@1?T><@E{J3s7 zrg(@6d5E*k{pmsi7PpCUbm2s8YE5}Wjf0QbuP{VGOaZ4fzcBj3%zWjn#FY+Sy7(^D z=&3~+`R3vpwImLvQ%Fdpe1Ig|b5DCaVbWAevxRSNvoqVr>JR7|>ltKkggKZ1H~!A? zxOLZEzKUKeW4hE~2v?f}hXs4$IwvnTgZZHp7wM16T7{!b1bCE^TZ4Z`wIUWa-V$a*;)qw_Qq{Vv9~ZLA^> zd6XqDN7Uz_$s};#WwFPabgE1r$+{batukM>gGM2KSArR7xUe)7$NsI0Vfp~tlh}SQ>;D} zF+lg6Q>qAxDZ_|pbBqS~UMZAcA({N`;JvI?5@vC*J#nGMeY{lZvg$$-1y0Ia4(ntH zt>7WjZ}TK^4g^ehAX$(-6ofAe$?QY82twh+IG7Xua904#<4_-DoWEPi6}}%rvZe1w3)YNyPR+eB4zOgul8%xP2Ln2wBn{-J^ zJfoK`E?cna%5|nmc;S9;s8dSn3)R+9{mTqP<}gN?IWZrC)VSplfr^V;!5-SnW_E0( z&Mi2QNu{}S|r%PmV1BK-)sFcIV_IUc z+5?-Jiev(1_n#8j6!#Y3z(dT!+YfWFRzDrp_$b!4K5A zmS}+uVF;hyQlFdGZt5+#--D7GTv6tyPM#3i;0X=T2t&e>RtemaaR?8T5<{~4HPLr; zeUGSPmkEv+`yo-CCi)mE<&FKWzd9fHsiluES*lj%WESGHH_(c&z)Cv%ufJ#02I9ef zgow&-e2E9KP>hM}-3TQlhdr})^H>v{0Ie(_w**gE&4t}gQ7>T}^`bH@5&{iQ3_(4w zWT0^my|rngDVx!sAcko^2>FX0UT`Sy@3%18{eCOivea-n!-m1~+6ZO~dgV_qAjY)r8U%f()Phk&t~wLk`VsB4A_9Tsash zLQ2nEaWsIzRjxf9Fq}Y)N>j;;;Mh0BHj) zqrZkcVw`zUo9{o^eT>+YCF-ll?Guda5p?Pi{Jl#Bgm=$Bre%kS_9YaCch7gZb^`>j zAmXSeWakw=c%UnkjAIA;Lhh!48xMfA5idgocHjS620CwGW8eE-n_l2Yq}Y_C*eU8& z(#?u-2@7`g@sWj>Hn6hUrBy>{CBMP_pux$Jq*N+?D|xbr1J`2mHDDZOMKV<)rgaK~k#Cj%5%RCG5%- z{2k1kJZt|*SwT_N($NcQ(JCNI@+EJQX(d^2Qg~I@iT5IVsNR^vORH-tBZaA5Ycd>9 zevzXolFjUmdr}8~_+C00rXuJ5SzdtkxD~o=_p0FR*JDKvZ(^XJH_IBaFv~Xi^0tg% zv&2h&k@Xu%kZ=xl5t4ui0fK=9_<@MK$p}E!T{e@Rg~`!>Zxjg7wx_5v76IWS@XJP= znT9-+Sz4Z+9q^#CaAxtANJC4lNJcMQ25*$wSXM!+01A!`gadu-|U(1H#*=;NSaX7!3>JP3WEN zbf%fC8m^tCQoHe<(c#D&1|_c z`ikwPgGkuRrnSPIEM92v8dh&he{$^c9R$uJQW@JdIhsA>EczDKII^pye%4jqa1y2t zU}J8Df733c+UhfqZKU^>|RVr+z{N8Jnh?`(v_H$=A;nujN8*@5TH&9)_`h*%Vc?JsPe0`=x8Pbl>t| z*l5Xpm$t}w`x^8<9Imf=`Li9#byPmiHUVAL)?U{Uv)IJe{p)Z>E4Sa)$urTgXUQ%& z#rU^ssXoTpt#wvkoHH9s+MZ*p81riXA>XCL&!*yW-Bh1z`P=soV)vM{Pn}q{a%=~0 z-go2-{BxqRyCQpY=1>jr(v3M>2aPm&2!v=l+etnu_q1Jz@t$R4?a}mRGo_pm=bNrT zd;+dp=`&O^EARw3^kA+7IjrOFAu&eMdU5`VfcmoETg@KC6MsxU2r%@8$uktn?K(&3 zH(`91mufqlLrWro1L)jIv#bhmf$jz8!+Q#$fp>HwQk z^&J)|mWQ_QXCYEec&#K%I1zBNp0t>ze!Upbra_Dmj8}$Xx!G6#E#T!(P8dHQ52$|% z^St*?^M{x5D_7W*?Lj|U4q8E#1M>T3BFmKt$!an|k9#qNxGT-_dR-aF z>mV!=9%XF@Yy1_F9!v3UmP(38*ijH(iw$@S7zlq^jkuDVxrPm;8Q5^iA)5Y7weEyqW88CsXIUf=BQf8CRLG{D)R{0h}CC7KR`m7=&PN?c2CbHR;!4=Jy_A5C}%&#bX~sl(aFQk5w7bNtX8;!%x?upf%IjD;+EaRy|d@&M5^o}$fTrX8m$+nF9|4To)d1Y6oY9^k6K*VAq#>a7}nX8 zBh0EFA`_$z6plqWt|=c;)?RS@Q)wLES)Q!WVe5O6FF_-pItUpM;05AVC4A_AejnJE zF86iy0y@v)mdZVOzm3gT1stgza2%+jujH+63+_Owf?c=h^tT>jTkLK|q4IJMED%(6 z3UByjUyiT=9TlB%r?7r`y|%Mxnb zA0e^KFR5{iFl)GxV=i)Sn+GB8Psh|WfXE&fXgLIqvEkr zd|(a8mB^nzx&nEJ@y?Usm9t{}@%c|N=)RAa^q?;x=&}Ec$MyeR0+i`L<~l*?Un16q zHby{eQzbWBLs;1#;=0;cAZNhL0g`q5U_R>@2ru8jG3sd=jkLpfG?yOWUL zgzau?SH2icXB&cya{4;pF8^>rD7eI#wgNpMZi==js|Xd?n4~>+l=XEA-KM;~5MN|y z>gW;SSBTNEZqlg7Y+0{T_>k!2CB!Xm0N2(}3}~Q@@(34fUs&P%scmk0UWjtb&J+J`x)ddH z*X_;ZJ0-X6{h~1n+K%asg~{RwYqON7p)#F1giyB%)wzm*O^PR7hK~5lZ^f1&dRLVr zm95|5)~>IVd3ir{=&bje{51icd*bs9l_l_#DhPw$OI4~CT^y!WAR`z(1kWYP^m#@J zij+!jVgXY{K)mK2XJMF+Ja7_ofkE5IIw3Jln0!H4rqkT$m%C`4t+5j)d4K;EhA5;7 zl&sw42Bcvcnv*06bbE4~zmd6Lc6h;Eu>BGlXC2stbvgsJIR*$65UQ(X%B69Bzg_|* zTjw11hVGF>5%xI5h9gLfkj<`>nk~47n!>5=I{>oDQZkuP zf0EVS0IF#*IfQ11Sq#(}vyV5eVUi=|YD1L$4-y^VQq7ku>QGyqrv*7|x)!WsLtyc8 zXFa8WW;gc4bT+oKwt356;(N%#9~l|P2KVvIk%(Tk39tIzmEYWak6tw96NV-Hg>qap3%-QG-{*6$;Gn}IWbPW8qjU4g1Fc@c`#1=@tKwM{d z#%oA^Vo0DHdq}ClZ0SIZ6`1S)1 z7|S;)>{T;-LEHuh@87{O&&d2QGk#0;XEs@;!D}Lxw>QK=S*88;T*yF>)(`fy7L4A* z9HuCvBGd{HK$`<-Vw_+E?QG`)`%5h5jdr z>z~@i|Ga4=Ry5SNG?ue<1X=;z^&NpW*8fUmg^E^+i1NtZRWQ^$M=+?t8czn`W^skA zNCi1UOwy1`l(6%~FxKu?tHw!#5I)MgKQhxYc%SprrZ)BONZx0902%iiUQ-;?4jk|I z%gc)2BGgnEdT#2h*%UnXdR~mU@H9P~nUt9ZcL`ja$$>>n;px}dyO`-4yHOaOQ!@D* zjv_+X_NpsM(0KhbynH(p@tW;e*NFXKYa|uFyCyJN@;Z4wKp~uM^u~_<7_gLojLXoWyRd=I* zuW$i`dLd8ko`oZbv2E+Ee$}DMJ)Cn!VsIZrc`f!tq)Yg?sx`06 zZn~0mSaj3d>BNn8&^psxHQ^9;v@YP!7YCpyMlPvvO zs9H{D=r=nnsx~&{{m+X{ z2dKH8pfB$RgD($}|DNE<@c%CA|96ZlY0DuAAoGCH1l9R2_#22IgRF~?Q+oUBl`bq$ zt67%DrljOr>e;SuURcY!&5M2d{)NO_fF$L80gL=gvY*)~NI@d$y3)$za>emHvC)42 zXL;G?+Ykc^KUlwQFZIy!K=9v7?-IASx9q^nuC_E)y+D=X}jTRpG-(^ zb56BBN$+I&sg5(L#Gr}7#6NeH!dA#fuN5%AMqmVIM8z(ToW6l#5;o%BagpZGM`<5{ zOv}J56CP(SgYKq)Us68W7+4kopAQzO*%}Ao&Y_)Cwgi2tIw_5L8K*Qz9)izFE7SXAr zzZqvzvOF5HFapsZk9^dz4frc5jFdRCs~KU5Y&x`LC$8aSSOZ8PY3Y=M=7`hasl#$$ zKfQel^vJu;;^uqms)tVNkG$GX3fGy^K7i;aZ0s zO$6DzGNMwbQnGb&{l;Z9?YP?B3iT!!cS%=~wSHd8>(G_C!Z>R(SlLX$!LyCz__gr3 z8Lk~6xDT^DWnUFov!a-`jdVpW_oTE~OJ9Q%xt!W~6^K`iRf0ztLCSSOwLgJZG{Q>T zsP2a|#c$2C)xl}a3=gyW^1zE?0DtgZw0sux?PNX-%mWj*FkT(H@Xvna+zk;vc1 z=pr3)>Kd)bs(eHr`XMc&4!otH?=C%tElMDA@{R$KDj^bgRTVkMERc#1=xv|E%IF8u zI^oiu7^-KGVGGa{%P5S|<&S~F=0P2V6X#%o4ek|yW!ui^-&@Ztf?EqH_F!z!P+`Az zzrK@9w1WkXH0d359_o|QpXQ=>#yqfYoxZ~UW2|>5IX~I_dOJXffA@C&GvWKI)%};+ z{eSUov(j8sLGL0W-<9bwy4UtG2Z!9t@%FM0*b5+p0RSbQ8r9~h*IlE- zx}mG_BdVxFvpyyU)+Gj2=2fDqPX0utN$Dg!brZ8#miTjvYIv%(Mw)3QEKI^7uQK2s{VZqdXOHSZ{sA?K+VIPvxWAod zkDGSpr+t%QW%GG^QaM&TOGKu6KeKsyumuy>7n|<>=KzD$@pGhFoF;(`_WeTg`|03! z-d;h#^Y;y|KdpP2_!z08om;lT1*t#nDu0bpxf^SbmSYCIDGhkh(gVz}EG$+p@t^n$ zOk2vyvtc7}!(9UrK;qBCvo@8e(qxA-st=U4)s-EC^6NY3L_7!YieyLj<-SX4q28u2 z$ds(ROK>1uTOe%LG>rBFaaza-86#Z?4Flzq>5ZBR%uv;t=rusGIJnOg+EVOydIl%aKonwz>T|jcU7EAg~{F&oLfS zCDCaA429+lM>DUPh8Kv2j5t%`ZlobIUDS&M7KZM@)l?TGOB{^nFW{X-8fox@ul7e3 zqu%i!I@GO`K&JzB*@%)YpV~mKoGcX@n?>`~s!8x!;-745PZwzu!)Yki51opU0cnh~ zYjKtbq^*$$Qd5~lv#R?+I8)a2XOT;0?L~t_&Aw8bAsHsCDMjj7xh~eI{rv z31nGe9qUA_vx(9n7%M|4oDq`A31gM{kuMxf4`7GJ5KhBYq9s)u?`j;i-;v^H*;)j) zG#j%127qnm+JvD+A$@!ar(U!B`Ap>FucZEbVGsd-3c)AYOg!=|@EqYqEo_OAz?(Z52%d*K?{G$ zIwu!^apEq}EwUni)BNESXgYm2c8iaxQkNJF8xFHFfU3TJ5D}+*WENApO3inR<~&xa z`f~e>I}=1ZBm9HeFI(SsMmr_9Ml81`v|$;hZUr3i)K|DBhVlo;&g+xUKe7_=kTZ?_ ztB-Z~0v!MQivB0O9P@$?sB=((=#$1`A=e#A_UlmqaRm|VQ(2UbRQu+kd=P1!TSEe1kj046bC!4Ux zea7%f6pe%RmNpss(T&7E_|$vpMHE*ZzcXxv8z373?j(O$v8VD~`(1e?)wgF*QiV3h zqoQnBYo^j7I+BIsJ}^EU(hO_aER`3jGL|)s!jHGJ^wVNx4SLz3`vn4ZVjO?`;VJL^ z-B$MSwoEYEnYC(rnWWCz8GOhIm>*4lOPFgJQbMjzA&NRWFVbhD1zL9B+ncASX&i?o z303pD-6PRQkn%rAtqJt9Uz9{Uvxn19{c0E8HO4PBc4x+FTYoS=a){V}$b!<{kq%H? zu;677IMab-bkn~B{Y4*K1>+s~aRuXzy#L`RT;$LDFhBXtEgiYP+wJv-f##fxhJg?n z`fRg*A1<1+_zKd-U;hCzKXwU=$QfVY+BJd1JNBjGUQ*2Ki8_ihfCoN}r+4$-Q61Yk zBEgKy_uJJxZ}5+lQ(_O|6fjvyDm;4TcZ@LCBdWM-_;9>#V`|wS#n+#Ip|KSsiEYIo ze~8bwi9=!l;xc=X8z>6T?y$ z^=K>ON>ZqEcwr@l{|tOuW`n}4uX61F75x8w;Qwdj>Hk@EL`BmEO9c7vkn`S<-F#e8 z5x<6XD~Ck-p?AFm0gcFdn?#^IyfCQD5|Zg!C(yYG%55L5$7Uz>$8UZVC4U!h89bHq(8d7NxR9b($mvrh-@+9*q{n{pX8-F>n|CdsAZoFIJj88=RQq^Pg?Aw*>?+$@bEZ$>pHRfG+ZR&&HZb%j#QiL3QG4oLrR{f z#(uHAVA&HK?Iv$^Az6H`LoFh1o~d0I3N*iRRCcmnx8{x%uD$CQ;5cR>E%!;!!V~Md zX?Q^Zlb)JKr?Aw5E6u~j`j&lK6D1e;R^f-doaa zI#N4Cm#|;Os@iVwtJnt9BH~Bv zi}a24P_NVHxP^lr6irx{amGXXgncGldN<$%l#9$QH`w}?c;?82a_U?FHm4=WjF}%&MO~L74+D+~ zlDO*efb1jmh?a&zFVKy|YM(}U-r$T`Y^E})vd^4VR}#-2Po$mavrmQWb4C=YF>V1C z8{~a}JT+HgVkM^;cuk%?s+Rtaa~ygT!|sNM)|FAQ-9OlU*iO`uQ zbZ}&H$EaS3Wa$WpI83SC7raWpd_Nj-4jU4wp?E`WiF9LRXT=~o!{}v$bS}^>i%;fc ze5WewUn~M!j5hLwe3E(NU4?sRb=&G~HyS;h~or1p04F+kf7pNm&24d$dXwOUf^A@RH<35H&q+-{DJ*v48Z&zpHJwv@_ zuZ?nc)gt5Z&iE5NE%qDDxQeA;KUS}DAi zrSgtwygWrFIv!ME!4)K2tVo_nR?-P%7fFehHLa9*%{v%Y@q<14?o{M~whg)Pux||ksM8X!&ofbKMqn?}reV|^#XFR#h_sG3VJjWT#<4|OriQs)pcOo?< zevk~wYgC~$0e7yBEmdO34UdfStL*19MuiDf&^z~n2_42>bodTRVlP~zF*Hh%IFh@b zQKVPE%}LoF_dsP+o53swo#*l#kvbZbHG6-G8qMFb%~D_7HYs7;6GOJ5Ci!eeUHMFP zxmDL*(G;R6696(oP8l}@jTlw6&m6sCSSeuH+j3CZ=`X6>O#DMu0`m|YS0i2CEk~~h zWd0zNa*a0kZm57rm|4{Tb?Jf^&V-7#dlttM9XvXvH>_l)t>nwp=b)=COW4qKrX6~7jrhXQqZ;$-c+qA zS|B8csZi)-dHG5Ea?5>R&8U#mxe#gbi0V-H)*XR%qDRU@|C{4&VfG6iiN@7&OvAZ8UPR~x`d`R!i@0j~?fe%kkE+bf1ReG_#ur8?%w;iQ5*Y1{aV(l_PyE#|| zL{D}ym(&`B09g;f3E?!sJ+;#o15|4PZ#^2&ASibJ?W zvlG^X4JyAKWQ33C$~J=<`MnAsIp*x1y?_8wJh-8NA*A=ENN*rC@W@U{j1e2kW2vxmv zuj0{Hf|u)=uy3u$!}@=lPvcNqgy60ap`mT^w_;-DUMeZA>*YSM^jp~?u!YnJ6Ns<7 z#l`uC4QZO=Q2q)(Y=wG*3(&Go2vo0LN4bxZ*O7Z7X$GHFo}+u{&eEQB<}|Sm9B#Q~ zEWq2O4hR026han$xHn1sNRtFofkBv<{Q<7=3dv>ln%+_$PV4hc?SJD^Ld!Bm)WvtD zD@(vu3UaYzAQ`@q@h4rdBp@07MOcCP_>)r2$(*+!ZeMvOD0h1ZY>z%0_Kg+Sc{DPS zU%c5ddVT+%on~gXh4W~rJ+Cz3jwH_oOj@Xdkr9rn;E-yDA(t#eCckRQtL^l)~rPz-^+b zyUhT;-()^UtAE1~y!o#_z=>Xd<<_biv$cncqVg%34cvzI^$1l$1^LP1z(RvvBSLsM z)(RQeBJgPh^-4^USfx{;f4G7}R9E)wu;55Ni*@duh%w(W2)$AXy{6lV0EzdMRZQsi`_Bm;)kS()5 z@$lH#BF&F?*H|lIZ`!%6vwdN8ab>niji%3>^cE|*p`W<8(avIQS(Qea&`IyTx6i-v z-<1afjsOAA>bEik-J|r%YU`9@<#LjmLD2nY>kMvQtHHVHZS`Y01AEGI>CH_+aPc7Y z6XuY60FvpS1iNadExdb+lO{#z)o)N9D*ePAyd`r`7Qc2Am)u}^U&6`?(hVw?t6)6h zmtlM1Db-=Em0ByMwzUELz0?x68t%z;SN8d2BO`-*`-vDm##+jDK?LlC-P=yWn*A)o z7#|x=Zr%D$Z-B5_!sTwG;_gSS61mkMlofdExnQH}O&UiluY z&>0^^>7|&s1JIm0NT)I`Jz3_*OvM;S3x0c)GdJ@OdJ*=h4wr**x>uA6)HIc!^z|{n z&ok~@rZx`P?h-%*6Vpt6TgP|_vndQf?;qe4QFjO!Oz5Mi30)(>xpN2*>}QxTjwIt5 zOJ!uJ>2UOJQwF5I0RotpRceVv;&)(L*a6*grADr`jxuAx#?*|IgY z+lU_vq-??1P#UrAe(+M*dq*xcKEo7&NlT0>8?UHwjB)UeQsT!)|57Wt*|HBc{+gBv z{_Wz2|Nlcw{{p&N>D&I7kXEu#MAS$2-a=JVV`Gu*FiB1DB?YdD{1zSz1|?Qab$*-a z*a^1SFad%2R0_g#G`D}-h%x89{uyubl)HiPlySW2;5Jon`ucbOp23%6z(~tLja+Gb z7sp}RRkd+z$)&8(w#(@1+QA|{L&KFLaS=1AcO01C+w2zbUVrq?SZ&p09t`*)^h~?G zzl&In+#e=cKe01XVTuTtUHC+crXLxdFyAvaNaUu;nkouBR`YH{FtvrccTdWtid~g_ zceq_p5j0fubgGTMGRrkmnGlT>fd1~VU|rZ|)v~M9v!iT>vRvZQfV2lwAPZ4kXHtkR z0pWlf{#a_;cNk3FlLM{(t@#@f)F^(m|+ z(&=Qt-tRJ0SBha8MZNc5e&6XBtS(ZV2%CqcWCAkC{C0u{e$fX3F8}`ETa0g2ay2X%0%fIYv$k2Fqr~qr@(bXVn>ebv^+&Su^==F*NG3{Cdb#^QPWPxt zbgIRs&Y#||<`Bs>8i6R0EQ*j<@A;bz;yI@*^=i9OMIr*JOd_-m&kT7vq*N&VbsSh< zN9e&fd@2PDvgWjtGYS$9z3oX5gF2u_htWFm>`AjQ-MO%54 zyiD>s`utD&zhN5MeO7I9NH}^?BP3x{Ob?+N4M%Otx3LXPis4@d@$t%pJxFeNBM7`ow@LOe#VzT+_n*g7lB+ z(=J-SV&Ln=4F3QAV*Yhu^Iu*}f|bL(DE#ne2)0xbU07OD0o2S~oZy%DtPnOis~hnz zwrHeZ1~Wa>_u~8|B9@+~2Q~qjvNynrA00U$^qb2vg9Eo;FZUAEcIZ)(@CUb4|Q4w^awT^I;~tP z1&3BGR)ykIgV6Z2^wC(W`VIx1cEzbD130y!JYR~#WGz~os%TYI$@Fp7{zeZms(ErH zuj;Fydcc}+nV@&qFSg{Fqvd^kqEH!O|~ngjCkbvyBOXcgd^0o z-3cN93eOfD5fO2S0})Xg>X=;`N&*TPUGSZD*YGE8u5O=5v^NwOBCQ=j96f=)pCPnm zp~_axHA27UU~$vFz3C7F%V69EBUm!3?1qZ)hL|cJ3YKWWyyd*Hq}^+`SzFQ|FKT=1TD#MXOZ#TeJB0b#R7)@luqlq>YW6<7U@~#zg?)*K<>|BAPxI ze({}!MD#=BqykijT6Mc$*{ap4n(4^LbYxvrGRJYfV+r%yB=ND>VK0RESu8VQYG?t* zs1dOn@jDR*{HOp$C4-v+g+t^WVAo3H7{_-KVf=i0yEh|ue+>!1HQ;+E<2ExpnQ*(%s$NARs9qvFKRR(jbU*r%HDt4bt6RBHi8HjYv0m zmhb+~E4ux*?sF#Bx_Exw_ndQ#IiF|7xJSqQI!lR>0gJTcu&NzJZv=Ian;CN1sq(xV z`1z7GzM%3fyp&Y2(i$d!7}2cuvCuX5w^6+_?oMC=+EY6D$3xu5|NcGrKbIgh;M{;` z$zSj9T$H~z^7-UV`pVNseUt1+P*MrPFHvQR#652k!3^99s#5KXFy};RA zU+h2#iTm;qD>E5lid~3--nj1^g@?y$N%=y3QL8~@Z^)x3-j(UA#-16}t5frmZSnN* zZ1i45`h|grJRGdVFX`f*#+_EN*JLOvdh7c(7^;6JuRbeLjk`NyO>LmT zZ!O8wu#GAF9EV%lqW8HWg~T9r0WSTOz8bwv$P5t6*-EN#?0J$Go;O)=Rfod4zRons zcsi8)$Xlsc8$vA{ShKT*G%lvubu)zW$_jfiuA6l5IxcRaqd~B_*>&YAgUKe*1kyBi zA3~VQ#8qSN%?xpHf?M5Wq&pYcVVs~mwYM782gpp?Ul7>bMS}wOA{}L5Ef_sjTl8BG zGjTm5LPOt%R%eI?<*Rwx&RpV!mkHA{@S-VMFZ6)1MrN5PD5Ul-!mP@7u=jW}5VK82 zPH)irrbUD&212Q*XwXhZjB-7~q+DqP|GYd-RA2if@uU?Vt7v(7?X;@K>;<8nI1Uzy ziRGwOGle?gVE&#AuBo<;s{szHxrKtk{M1JWItieGKrO|Ns<>`kKdk&f9VOgn`uXnu zx4y{GW;{IZL78M3;@MF63TgTZFq7n&q>^#Y*FB0As7y8(p&^?y!HwVVSi7zHI=HlG~Ak^NYNKiWyv04I#ZqOxa0b<}5?=OQ?ovA|Rfb*W3>KYNWODE9w zM@}48eANuKYn+_%G7Izv?YiPsx?*F7bYB{PNo3r>qAzG5E3I&c&s-1`x*(V*g6Ohg))$@Tq344`x}M4B|s{W zJQR61Ss$Hp0vD#Kyh1D?CB&OQzfjQ3DRa}3u?$kQl7whdD!c*mlj_vzZ^qB_e@K@I z^ z&~XiLtJI>L1ZA$$FPQ)6GN;V%L{v@Q8p&*zGZphziV0tjtxnzg-nTla%0XON|5=Y= z8UEOrMsd&(!NG1QLExll*_=&Koaf7UF(MA3V=grsyh|)?g+u-=;2mdw*95_uhUhp8 z+zoeQw{Y>`+&ECRp}yMVoudcn4xD@=F9Qb4+7!ID9^Y4S%zP)TuY<;&HWhD6OM{eJ zm@QNe@%4bagr(zCXeKWerQkhsR_zxQGlv_M_M2N0M<*2|)==OV^|-%k z2!Wl#LF%eVQXgK%n#lWGJ7FIs- zU3CoDS1IA%ikqFTwX*|c7tO%NFchBk;;0vo2zvQLv6u4etX3#G`%!!MQF~Xla$=9n za0K-d^UtpaxZ&^pGK@zPkO*RY@0;lb+jNXjC;?{6w=rFUYL1>OLy>NT&yTp(jd)tM zsCuL}z9{K@?Gk1Z^RZqX%&))4EEVTCqWY+GC@<0i)}uWM({=rv9UB%f%f&s3UX~P~ z*;kiCp{?1_u?awq8MVffAT>=Hg?f?68X_*e70@@&?(w<Ll4p*^D7B4z4ydf-e zU^f`Jdb_KY5i978N4Fj$#hVv6JZD;J$g#&cQ)%zX+-n>f+<8n%h?K?eV{_APM~A?L zkKd`7pF1m;&L2^Puu)J8D~N+-bTkz@;N zJy(_3*;80<2slE=vEF)2hBj$WA_H>~_p-6suyLu4cf_-d{iD1fxDk>WK*( zI)iGhDS8Y8aMCZe-oG$KCH-WjZZ>USRu0WYg+@?KDj;NjvJWjgZ zc8f{K^I;MqK9b^i0`NRzHy_U*m74Ec9ey%iv8C}kiUudwE{(ruSbm*v$9isB`;HCf zI>hMH6$Pp$D2&_6Dns$K~gW%y7Xx6huN=H@-v#}H;$3cV#tcz0R|q}zl_((*u!jW(kBDr3@#4maMr245x=CYWZl z;>(uOxSowVxIT{)@@)0`WypQ4x^1BoQ*k&@`;C4<1Ela|YS1Jae{7Fb3u-0J3O zn;UUHLyIP951ni3x~icrFrNdq0x>V|Ye@q~*R9sK*r!wC84k5G z5ko0|D%!);8svZ#&w{kvdC@doTQ6y7?x-4A|Je}5zF2;5`010wxm65#Gq)C93W+Lp zujJDxM#8A7P75qs)>v-ho>r}D6ic2$v9l5vc2T4Ao}dGxYLw#xLwY5X<{1R{A}7q< zl>_7Dg8kx7Bbm+Om_(V}ZVBF`V@ss)H?~$s&4}84bp-L(x%%OPHqs?w>bU7)Gu59_s2;7*SrdMWi*(10o%BMl zqm2^6I?gGl>~jWFmdbrJcD{@H^7so>HrD(l?;+yQz0c0IYNv;{H9rDM%G!xe8s?C} z`@y`>M-_@48JfGDnR;pWHQ1yKiD^T79j%eX<7dl_lqs(}!5X_qodZ@HyKS6iU^ozD zc~T`JNpi1zTC6LOU73cw8q=%+HJ=c$xJE8K&oN9}Rc5bvzpGX)}LRYJlT= z!l=J55p_dFfucL6EzQfI4p2IPHzJSHY!v24P806V;ZTtDVoT^Mi}qp1_mt}G#3UX{ z(<=P1q9%K#CQ5;t4q>NAHaSN7I(uYV#K0OdWUOPAO|3>om*GIXOzvJ~0nUfn8YfBA z7m-NdHErs=m!`6$yNpoYSbMb6S2j>Gyc!ODy0lwQBC9N%eNJeXR7?{9IG?E!O#PJ- z7P|?ujR~{w7=Pl`re@{Vo}LdnS0tGbhVdE=T`tp}{O8r^@x`#zgs`nR!OiH*7^}{e^)9;*b$IRi?aL< zH6bjC+6kJRG^s5&)#e$fZne$M-w?N_rm`OZ&sJH^C};$FT5+9mvTgd4ca|FpkPS@D z&i!Uca)jP}wU8y436dw!B)SSEc3X5p)gf#Z;z>N-b$Z^D84<%y$Z>m`%u~<~=E~u> z7OCyoZ{$`mO59QtOPtQRO6%-)!ue<^J|2`fRsPMfAg0u+P4~{Q^(HUnsJ0D2U;6ke z61l^vf7x6ismZQWhH5Ilgf&_bCYp>Ib8Da}+Th(vP~D(ZJZtdQTpEws6VvkaowOB> zcrk(G0hwM>KXD#=1sImp3PMBegS3c{qR}9SQ-w5HYWCROE6Z22m3Dm5iaT($iIieR zp`1NBt9pQh=r}Tdb#*G^n9;{}Pq8$8Bew!~L!Twc^xE@r$=dGCT@Zckmm4=! z?ud72SLy$-p>_98dl~8y-FLJPwkc_++kSk6z$BeJZA26H zgkRj!fTGEZVdsUG{1-ifJ2<|bAt(QP&xKP#mmNrcVUkr?ckitogT|J%hEq6h&(u|p zYlhH~t=HNTbW!)>UONc*18Y#%e9wntfwEmDY(zOmguyDX>BwZ;^eH+tqb7+~!{+44 z2WWCGGPHJaTg{lvyyQR^F~oFkG3+J=-(f%U#Lz&(2x{LznFtz~AU%Daud1zUl-lyx z6zxDoQe%Hb{WM%A{Em427+i{0{le+qlf-r?Yd>0aKC!%MmfnuBbdkp15^ao_ReS4d zCute9H|tk7`U#gn8F^cOQ&T*BU*dEZ9(>z&K>Iu=ce1Q95BUIU$tW=NBgFGnss!;d zbrk!!XIoY^t4~>Q0}-%%s7`{lWy%N@291KE z3cMZjqJwar+=TOUrsiLDDE4OIr_{9r3)7+bZ8_YTfPEa#`H@(d)^RM3@UutBQ;c?7 z>=10|oAu3f`J&C3A(Ya zVZ-yW-KRj_`_q=2aU+h79%95E3GHe}9dJr0&X&z^y}ikWH75%qYm~vo6tBcJcLy~w z=p&VA{zuki^q*M;>?ILBTp87(wEn3Z*8Q=FG7qn^DUPQ4fHK?=dO%fYnEk>|xrr2#+O0jL_&DCmp% z?7he8qk*E7Db(*@v|**r`hr^K$zHm&p^>O!folmTLvmEhes$SyIeimI=3`07T!mAW zBpbJ4);)YuT68-N=}BdtAD6V~2+q=D?3nA-R|X@KqMA0_E(RlcEEcTTe5V~Do%&Jt zn~yrv3;is5)66^d13hdQSX{Qx1+aHqh8UPTSgr8}(Gp9wv_d~j2QxUa^bAhG@ToIj zy-|&}5rg{VW>YW!(XuG}uOHyb08C$&p z3S`f!gDK_00Q4*r=82kT1zSiLr{riu{maR2mIY-?Q0XKXd%Znt-VL4b|sCn z7b9|B(8X3`+j`e{cS*z>$!xFb@V^|y$A(q$A8Z^s5MK=R<#cU>5k0&AD`jFns`nub zCKwns!#^D&|MGh3YdwpXEHaj$P(o7|BSUdZ8*@E7kS>><4JbJJe*&X{X8(z`5=GFQ zEYiiogev+VNuof)4~3cfHmq7OU)I0m^;}uu>xRq)@>jRZB}WC+h5H0+L1&_m+pFO-?OE2Js+QGp>{*4$ai%YbT~l6f z%D+~pUH}|6Pm!LX%7{~4HZplr$g(Fld)9A|QibP+*VG^7@{R*)m0)f#jSgmr{7vt0 ze(Z4!1k0?E?}Fpnn^pyF&?%kC^cZ54*BR>>0}`uXh&D{v zUrYALC9qUcg~M;4R^(?~9N5xW0EW;KHCiTT34ocAH}#$h8du|ueU*oTDH)}nqo87O}A`GD2;qLaZS?)Q^uEDL##TZaArcpKw2hv zZ0-Kuvtr^r=8Tf?;FWsSITgFIijFG=Hy=5EKuLJ```|spi*sT&Rw*9BuY7b_2Y9cY z>Qt>{TP9uwnMbCRg+h5rE$Xa>od%j(woWsuS5Da@DIzL5NF5L2i#QK)$qF%&TKR`M zZ@(Gzdh2vW3-7NgA9}hvvfUv)QW>2yvd?7XV#<%L?Im=Kb&q0_iUKuRx@B9*JI7$W z(oJ9AI`VuU1*ItcB4nLMatJ(tSA^D}omGxMXE*>3iYOddLm z+!+m}>u^s&+0Cnc!PsQD<`?r{DjCKHeU{Q0%0pMyQN?bS^eB(u?|MGvy$?I=cWt+L zwa8GdbTYtsnmx%DkJ^G`qR1BLd|E{b{{eDLGq^!|$hFcVHPHR3m{7YlzC;AsTzQgrTu3`r*;0)m16*YjyU^)(>7a)mQxf$N{TtdB3p|h z8pF@6ZT4Coe(QS)exX9Xm}zy|PsnjCx(gGV!M~j_@DyvY$AL~5H2yKLnDSRA4F4JU zvU)E~4M0~`{~GBbDl@7WFA1BXeBgM{u%2Pk8d&#;1ZY+TlB33U!sL3^>YCB$Ny4vBCkyJ*So-J#&hQ{lGc*6jMl5~;cQ z^5`WP4J%6<%}Q0_$SwvGGsao{Zw7kv6GrKw)TT0G;c=9&mjV;N1EyYm%$i6QNAq*Md1Y?~A! zGtafZK;B%_$Pvtbi#A>ndIFal38TF1PPM1INfhcRJoG4EJp!ie6weI9TVBjYU%6`w zI6Jr_N!d}R&le0%L@$C>%k~v&yqhA%vF*-y{M*=(+1Oc>Y5hs*)AU&FuMRp^5c1yX zW#_%e6vkH_4&jze7-PsJ2goF_7yza}J1=+Ij+Y^EY{AI3DnfTzX^GUXAB3t~RMwPA z20(qRTzDJhB;A>Z6!ZKldzo`kL0OpFR&J3gJUX}nJv~uAyC2~0k+~l%gQQ_(TW)79 zSb#&+#xAPcLWM%YNTd=H`AQ=+Kd%sApk$97Sg#RLByQYGB{8s_FIZxf-0JBfGO(%M zrY=z<{i=oCR*|eirv(g#&ZM{eB}j(U4vCv)G?BpY@f1PRK?k(r1su2=pv97GjU74U3?KTR0%HB{P^;<9sn(#g0G>=7b~#?Fz4g zp8i>i(&LWLE%wlBwZg!G>MH0oT3$BV%0={i%M(#Ua=KX_TF!<_0G{JCwR2H4PLZtR z>5Wm5!YmNEK)8;{MJR(b2%u4R5D8t>-X=o zkzfI+%~{45H(gV+i2stekiE1GH5RyU+D?JIJ=7c;*d>W(Gzd)P~K+wyp zk2{9fsE-{!u+;RtCPMa~qH5=2tx_Nh|FD2oPAJBgnoP*%saT}@9PfFUV&fU96jV#{ zVXbnCkX|g`M^B2!TD&8F%; z$saBqcZsWlbh~qr zft=?(Hws-1gJ81O$r{9eNqjwG#CvW7S|9)=6*+MB6>tkXyUX zVAxbvR*uF~f#4C$D!cTE5!2#qD$++W&85l??tL64San_eI-(*&@Y$&rHWyL$2fq0S z*!Mbxf<<@*5XSs#1mn!T&9dX(Q^^p19cUN4_DJQU0w{PXEV%xDd-XX*yKaed(IRMF zDH5ZqMC{K(PZH)CPYRfPr6VjyL&5bIE=tphRorFPt>Dg$X?uK*>tfdy`}$Lz2JaBQ z&G%!x&uCIWcSJ7WAAaZ|hS@8DruhGsU(WY-MoxAtpm1PjD;rBIBO5zYBik627K=F^ z)Fzy5Aw<;6@@u5YA{|x+BS~UUesgm@v8Sqf=s$Q!gSal>z{#?t zhS3cLn-lTWnUxEy6};-z`j=;Kv)?sW*N_-F%0s+cl!tsAY!xzqSn3-B=-TDzh8JXC z-c2oV)EQ%Y(mdM~Gp>VpaE08$Zf<$@PPu1hR*{rcc~0DuqHJ;oTtt324>JBq8v*Xb z*jt0lZEIZUkT!RH2R_llCllNTVVmex8qCeJObW*wqDBc{&Za5$pT8YZENUz_#-?9T zl|i)#<@v-xOz;6_Qq2JdF=Da7|1H{{5t(udIfdX*;>2siiPW8VZ1TB85B8-GEpPL9 zbQLn@8PHbyy^gh!k2Z75jEh}))s3BQtZ?F)_dOG3l6!kv%eI2X9Y)cIR6AxodTOc! z(MyV8yAHBmM~E?jW5uSzaZD+bq7eB6`E+|=41Lb2rn+Fc6}!khzW_X;-kLzEryOKH z)X2PJWH0+Dhc{^zrXiz2$d|)!Mzj+;I2j$?pqs=?k@9(@Ej4{lmxxXNq=D#&&k;2i z+jI!sW`_%ChRIGizb1SbEUQiPN)s-{Y^6eUO(JxQe1Nw1sc(ongOgC~J48>yb{ZQX zrE@B0@CACjXO$M)3t+8Nr_UbZu2L6n=A@X0*(qEj5pGpTf_QRhActUyZ!&KApfJ7}UmwJnIb=v+#y4*Gwm4Q?`kDIN1)ze1>jLsO#YUA;b5FLb| zhtFXXkTY#frKIiMQOSTWr(H%?(cC{cjBZg1VG^n+>e`q~aO#`_p!zxYdjPW1w90N| zNKpgDWkQhnf>Yh|G=v`}y^Zl_m?b0}(6;lk6&W|Y5*I?MQw|h%rt4;|H)y}aT*9jW z;x9KPA&&=mRz~tZokWei9}Gjo$#|NQ{a%&fvfrMfd5}3${DmoH9;MA2Sk{^?HUafU zro8M-mV+YTvGyT0-eKd)k(R!d#^brnpKbmti^nE zR1o|wJ6T;lx>gVQ!`Bw^GWpy|G@HX}WZWFe%cS?rYI|O4!Jh;dZ!vG_AB# z-eq_y$tWz?dDTPCP2lZ{9uzkNz zJPGF0TZ9W-OeiUEb00CM6iwnjD%rUpi~EU)w&^qiPY%|QZyrk2dMR;J8= zZ_i3bdWJ?eAQ=Ja!J&!1ZboUQA(md|!ETme>E52gd?`jLaCZ39BsU08B@AVyAWsB# ztZ1yaT98E0qCV}7n9vkH3k${wnq|x1KpYT&YK;f_VS<5zL4PR!?Mqo=%xDC;P_QXeFMjC7lJtj2LmGkIn0mXQPh79{)_JU z2Hu!Q9~cD!UjbQy_lKIV)BZX5Unc*n8Nco!z;*?;6$Ths3mq8Pw+R35Wr_ZedHxRl zZ9KTzh1e{DoX8Im4D6ev$@h{E8i@aF;s192e+5o{c2g{U^)4Dv=S2Oj_cx#Y0s3Dv z%dbrPt?D)!q<}XdzZn88z<)IDD~Ue`|AlG4fx~&2sCR-)n+PKK(X`^ye-8eaY5!`* zulrvIV4E8X$}GAp^0R5}WdE4w*U&6zZlrafCRl))@S|y8nEwIvH;4R>*x9eqAErh9 zv4iX^e~12`oS{aBKh1T&=6RT^^v70Md;E^a>TfAme|FG^SrxveJN;h7-uw<7@* ze)==VLz&=j`5C^K%g8_A_+PR${LJ!Dp!3HUPf*hDSpGqP_-C4ja(dr3wZ9j~wBONy zI_&S-pFa~kR4x-MFA9=}*6-0eS52BKv-(dl*jg^anbUwtr9ebI{e#Y!9!w|H!7;`S00& z4p{k_?crJ1x2yBt3k~Q~`?ntpKX&D>9s1#}`j1{0zW57@-yfm<+=hqSIF#QT0D1~o z{oe?F+^TzXBvMumunb7});-?m70V From c0515fc8592e7cad69602744b86670de8cd52bc6 Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:01:59 +0200 Subject: [PATCH 12/17] Delete gradle/wrapper directory --- gradle/wrapper/gradle-wrapper.jar | Bin 54208 -> 0 bytes gradle/wrapper/gradle-wrapper.properties | 6 ------ 2 files changed, 6 deletions(-) delete mode 100644 gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle/wrapper/gradle-wrapper.properties diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index bafc550b87fe65a78f9b11ebb03e513ae6e0a2dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54208 zcmaI7W3XjgkTrT(b!^+VZQHhOvyN@swr$(CZTqW^?*97Se)qi=aD0)rp{0Dyr3KzI>K0Q|jx{^R!d0{?5$!b<$q;xZz%zyNapa9sZMd*c1;p!C=N zhX0SFG{20vh_Ip(jkL&v^yGw;BsI+(v?Mjf^yEx~0^K6x?$P}u^{Dui^c1By6(GcU zuu<}1p$2&?Dsk~)p}}Z>6UGJlgTtKz;Q!-+U!MPbGmyUzv~@83$4mWhAISgmF?G;4 zvNHbvbw&KAtE+>)ot?46|0`tuI|Oh93;-bUuRqzphp7H%sIZ%{p|g{%1C61TzN2H3 zYM3YD3j9x19F@B|)F@gleHZ|+Ks>!`YdjLB;^w;?HKxVFu)3tBXILe21@bPFxqwIE znf7`kewVDrNTc3dD>!$a^vws)PpnUtdq<^;LEhuT$;)?hVxq?Fxhdi{Y)ru*}G{?0XIuDTgbgDhU{TZBc@$+^ay*JK-Y1#a7SpO zHyWJnsR7T|T~Bv6T*n>U;oojNGn}}GOCkMk$tSQ6w{djY2X8sv z`d;xTvUj&RwNbF9%Uq2O~P)32M5LhEvu)YifH{1z#~{bWNWb@jLMh zVUJV2#fMpMrGIr%9Y7o#C)zVd+KQX8Z)V`&oL^y}Ut?pT;i8{o%0fdIdjtoI5(~Y{ zl$R_`XQt0k0VLP&_!>>&wg55P~iFB}0=c!p}&pO(~&fo}p9!sAW37Mf!kAsUZ4@ zwYFm>c`ib_KqQ|-f1mK47)b3M%)Z2KT)vjM>^`gn=~VsD%Iyl77GI{(9#eGF0Ao6S(TAGLd+S<_FpyMWx={C_7^bT$Bbrg{4Bex-6CxC+|3- zq-eUnX4He-g``+N04TM@rr|3$bFmDJz_Oxtgj-HMLL}x?xt0LJZOW+8cgLnDeSviP z+~H_$+_wl(UWUCKktl{p{0p7l8GOP((+bpm>KqIG{0Nc^gP2jVEgeGC1)41Qmf$GA ztV|uyJTjG?BbIT|YCPeWKDTUGMHyo??xB-yw_N?@6)--PTy6=|ge97~FsHIA6+Zlj z?>&AY_|8}uVjW^javZJ#ZHh9@$;1T%RK%qs3oX3Q{|U=4C0pAP;TvE&B?eaxJ+_g}vtIrE=zaCbk^9am`Fyhw!*X zf(5y2gXmQUWg)$8X>C~+g}k_F8P+fni0nq}RN_pq`P0P^!I*Mp(gK0|RlKIWBA6z+ zZvXp_Hp8KRiwNMwLun?;)l})q>G{HkK^3t@znN?AGnI5!^ogl;>Cq#F|Orith$uD5^dob0h8vyOzOu2MKJUyq{(MIx-^e>y#K0oqJug- znT^aGBM&`u6gvDu6;_!pIhv`i?^JJ3pDprdv}(_9;+=Ub<&Vj_z7nL#{lzISdygW$ zS;Mm_eAx{{ZeO`u(NFR~UdmTUQehNB{7>b+o!b|<@4Vfd*OWj(U=bxEug6FmX;Iuc zldB0@l*UM&GRw8n>=)-VlXN+q$~%nY>?zH2by=_U&1$aGwXNL`A>|})<{n{soC{$f z6i{}Rq~K;U@!0~l0*!C)-VOGv&L>;)DIe{~MOx}*9-Ilor5hAU<|QurOl76NzoN3V zFz=oQ*mRGk@zvH6bG=PAVuhP#vQ)|NqkokQjR$y!VE`vqM(9pk6O3%eF#5L)yu2A+ zs*{Pv!F6}w4%j=vsHRJRBQFSruEA8b+xm116n3s9l*X^2CIqvWhj3h>YKD7;Vodb*~~wfg>xvIfk;u|-e5I|v(RV` zfVcu;xAAxGfjJ}RpiGe>hrN<&TjLbp$?XY{pD8hDB;3DtAmV zOU8|p1xwqShBr-NT}{v1+|S!xNU5h>%WD}IS5wdewOiX8W;fOdo*A_H&U|h?L(e>Y z+pdZ5JuYFFG5hLVA*lzhsL6A!QJrgiynro+pe}MwuJMaD?c>~oZ86oJv^p`~seL|~ z1ArVq0QgvgpqnwMr|XIY4uJWp1|TCsL??Ec(|na|KJjYy28(mJ+-pqtRmNvp*i%Bn>YoSNj+$8+o{rJE{3LOmHi-8jE|VJk_ot%f8pC+4sRyV(3# zW3O2ekaOSg_hUNR7YtwtYU4(m-K}~6*>ToXhNBN4SJ^3&JH}VFGf2J)odBc@>*Gl- zu!@kC8GN(Z%CmDFt?t)BFVTrrZ!TnsPU=#=U$g_cdL4gn$zU5h5vGgRrg@pWEHx`Y z|LMgbYmX`<5rDTUZj18LN6hc9Y_ch?Mvg14mUt;M@RzemPs;Q4n8`|C<7dRgZGJHI zwVvX>w5PjdBjX<^bnISW$31*#3Mt_V3Ao-Pm*S)!i<{%`o-C~T>iy;u%@3-6-z`da z;}xiz)MqEgBfPGcZ39Q~i%t-b3?ye+s zkV{&6m%A-gUR^>9Cg;E*M8+;83~U?~k$A^f&yHwE4pT*`ItMWs>*JDDl0*7UOs3rb z{N%7rt%axd2NKO377KmHN-?%orIejNHen&@RYXd9e{|0?3Z@QR&K_88nhI*wn zl_95|n6VThK4AIQu(kAlGG#LYNFwEsi~vd_%0*~WeMfzssz;mj4JG${`-^wNa@^*u z?1Se|Y4gsSwq$N7$s7O8lxI5YL)Oh?M$6Cl%*79o9n4SU9#^DbV)ckzuSjG(`2aL} zwyJ#Mm9)AVg#`Ve-l&XvA!>fDv5SG+-nff!a0Z3VkR6sLz14*8$!#4O56%GT?HC$Q z5UTKdWBAPI=Ng*Kfg^*L&X6^-Zs>jlJ<+WKk}kp#?ZhoI{iAYRH_Fh8@wW)lPUOBO zy%**V{0Xh--4K$N^hncGQ@CX^6{yB?J(OpDDQEN^8Jn}a zkClUmg|oT7h0oKtm5qh7zC918qdLFWd$5n<43cw2ta>hB1zq{>t``4oEHts?wEyHs=F{&{>VYY$DN|T5^;50-h$n*X8tDV$ zVr~9Nk&!g~n6K}EH8Uk&F@*5|$fEErn^6)H8!_VPoN7$moX&?~o% z!6kGR_z~thhh53cpJ1*`T)(qa+tG*IhNzCAH3wpZPe@O&rOclYvKv_ z$Hytrd^BA-$jHy+Y|Qan157h8Y#;?EzO(dW?&*I);tr@ysC4#JwcOXX^jUhA$=kjE zJfioI8g;!`WvNYLW4-xBl{dVBfX8L;w$#Wu$YH1zDokI{a0e!=41*dG;R1vbHGEHp z88sW%D^$I^8JgM;&}_x0%tdqs#BdypVQMz43>ih(iH+fx)VuUpW=ol9ek9@GA_dT18;t9-Mb&B2VurL628tpA$#ZPxIjlxWVD(7rsfn(hajk_}%sP9xNhl zrJ{)y=?ZENjKlW>@fHaLx`TaX7bSGN=!p~g5#y22p|5_@a+hV=mdqo3 zCuyRIO;)UZ1<=N0Ml8GsSAZ+d8gPqO2u%0N1Y#K13SxsT46W@7M`X^-G#AdceVFsls%T{Z^LV&`j4|WDsRZ{7y557 z5BiXpTcO`?X(K>&nMIwU#I)&g9PjW{o~Ij!#IUhElGfxc)lQ#Q$iOjA+x%=@2{t!X z`&-aD`#Mar42lblnS=)o**}54&DVL5xKCWAi)ww!HKT85aIf`c)Gi*QBZ6)C;(fhE zJRDf-=;x5!szU?NF{J3|Xp*V+W|4&ns|StSqY|=Pmay6SSXTCIe#$ilOgaR2wCa1V z;=4b@*@z+}3wK7y0X2B(?GepcPFzP-97U%GXP$aA!LCHq{9S{hYNR@IM%Stzp4(;u z?@Sj@=pNq5>}tl&r=HbUM%ZUW%l=T6o+l5Jxk}i&A}ZJ&<3In4q%mB*PPhMCE8(C3 z02u$hRtmcrS~)wKyBLd@TN(2k8X7w~O6%L`oBmJX)O5r&Mfc%RpI^Ut!nfI1VXsc$ zBPMN*M-hvYE-e`556f(=GdOQ%(w5Y{j8g3|Xp%6%LxM18Pga!NfJ@yA)}fo6MK33E z3$_Dg)Ec;jY`uhLowVb3>(*YoBfnl`{EoiabKiM++g{rFei`8fWDD0lbHgfv@j^gd zq^sJC;MjMQ8HkJ~lCXH_)aaUxMqT&*6*^pP62#?kg%POWZPqiHB zjK-Gm`fY`sQkQFkg{|Crb(`3w!P&hDj_ZsKh`~|4YXNj#b27M))fy}etvh$C46TcJ zN}WBC)5fMlmfgwbtnbx%o5`npSMNMD&XLTSk_F+lk%b9=I__!1UAw8b?tr0?OITYm zZwZ3v3@8tGTJ0XKXa{_zTZiSGiq)je$wm_^h6<5p?&r2$Ay-#o)^TrDz(M&H&wL?v zG()L5-FUQNvBMGh`+=p(C?cCTCF`LooUlRFyFw+w=lQUyexY`Lp-*=GxT%AC59vYJ&WHijkfN>?*}Xx%{_#wN<6Q3-=x z#yg8RzNweQR4j?ybGpetSoSMyPQk`7KgPFGL0E0 zg|d`R9ScEK^)03o*8-GQ-qY{-RbB`#JXlx*w?%|i?OFj27IiqI6cxuB)g`4fznbzQ z=t66!^#15RjJ#FZ2tt?};n9t1Lvg$-&Fr?zHbGC@Z$lGK+=00=CYmemy!LIt1$6N6 zS=qh(HuL0F;=w2%Vu!KYjDf-8V};oV&rXfQ$Q~@o#|6*Bgs)C4KwHTfHYF2gt%E=~ z1sYV844uKUAgBvGoU}I6YG$3AD{(Z-e_)Ah5bT^9QoJK+x7jaE@7NJ8N%yod&;##c zq~7YbR?2tUslO(C5u(9&5D%{RzJ(3ls*N@$ScyA-r5s*V?|D9^#?tJMPRr~5-f&|| z5hG4_qe_t?&JYXofBA`%*zTKF@&}e~+-eQbzS;U|V4!bYf3kU3qDfy}Xi2#cwA91u zj_?Lz=NH$77i>?Pf1aOj}Wer%O5^pQg2XI&tg@}X|aQ9xmEwfVE_C@_)0A@ zSGbHYe0oR3Gf4i43Hljw_0hu?@Ie-iHVqD)AY?D`Sb*oU*SI=y?DNMJeH**aXfzIW zEEVH=en4^dv`L(oJv;9AMCYDGAdYbBJ63c8>xcQn1DBAQA>FTxCXeW`yB zVT|dk=M&LV6!Mh4MYhG<2jZ*1=nl}&+nl-lSJ*9#SxOy z?b$iv;=He)Bb670FaOG}HWrc_?A`tcSF~bngbktNmslVzr3`Y`*o^@}`<;VXcMii= z=FGm2$Z2w-t{?Y9bN!c3eTM3yvIysmd zI6Il!+WZ&kub?T3$&d6sZL+oGRAJxLysp{k9%^~9zOO0Cj{t(-7=(iBMJ5%GFVnsT zogf|YBhe>!o5$OWtIWk1JYNduwVLMmLF2eO(Szy>&^c7WKB-p)1}iK5IEgjm-T5d_ z@@maI8l#j$w{sevL!hGGS%dKAvsq3leS2@nTzUz|f{}JTh)um77U^p~cO!}I3;%Yv zt%v71C1f$|j;mCD9~0Ph{&*)oH)iz^ySrT9Ohm<`M8ON~DP7hB{tKaBWEo*BZ+86f zAm1_)0mZsz`nkyh#xbcVa2HRysG8Wn$lb`bylI>o!AEm7?(K)TBU{1w;rKe7YebV7 zom96W&t~j`C=+gtr4>M!3k*(=yBEs@_%-#Zj^EAIH|BC!LtJP*jF+{eJ_!**xncaC ziKX%(XYY!$@Wo1Avwzn^ zPfE}$xxI4jvV^r|P&w5rGW2kuo|IImxq`L9 zyCnpoTEiCp0N#LriHe0Nio6-=zo=rPncSuGj1@+m5CtzTfZ9zJI4YTL!-s_C|powj7a%txF*KQ(sgv@^^Fq6{h218-K34C$?^mfUa*|L-w z?9l+DEk8JVrcj#Pj>?DOyTZivZ6|Rr!O?m%`kW(CV35Nos1;(Ij2fs}S#FWLOpe-i z2&lK72Yv1-iGGA`i6|fz7<$NsAX}|3worY-PRsm!L(~& zF%V64k%>!j>#dHjkdkS<=~pPQVH&tG1iZ$Sot>eD&DJj;mzN`v!q<7}_YB8o%^CEV zRJ$5ar>Yh74Ew$1ho)*4iZ%#w#!z+PQCZ;<-UnrZ%{LB*^u@G_RWK6t4k6dm8^vOi zs*+pOUb+hHwACR}wc4+6@b6R7U=4h8DPJ!LwOy8C`H^d3rg%!QFf8|*SdK-48Bz~x z_C4vZpU3(Fr;N2963h1zueM5{oDJIkGr^2JCU@fhCKvZ#p_T666HL+F(aG5QZ+89F zBc05R9mVu*{)(CZMKMLGXew$dBYm@ov*BZncQJ`+7B&THD$t4%H&P%GAp;SE73rMg zXOe^jJMNE(1KK{lYv^K`o(I^%OtVcdrqGQ>dcTO4?Z^-uE{_}4Kd)PQdtNp5G_A;d zzkkH=0(OSldY=vz`jg|H)13`COHroY^$|wdzUAtv$Pg%W%Cpmm z)sYQJ<0?^!yH&zZxRt}qerk7WQqzHlUubrT5*JxYd21*th(^py+7g5K zbrD{*0kGDNd<3{(b%~OONM{9sUm=9xuuYA;gWvVRU`lB}I20DBI`T_i#p*B& zt;lg`Zmz#JGVTE)a?U;@a?XKYIPGnbe~pq?lr6|F*=+?N>ZBAkKI)<&wlT8D8H{m*1(^qX#M5Zs~^uY9_HY(sgHR5yrRiBe_-U6uCrAQc64e zU@d95dqi)+O9UxR6|!e00zhixU>_U_+A~NiuD=MF)g6cr z!)U%>KSa}*le&IsOYJ&Fg#|t$))2q~6`k4T z8N6{9<2Cl)J{A3=Kn+0mhd&w`t)EU_i>f;yLu|K2aIxxYfSENl;6v0c7zejsQ1I&$ zKapAFStLZ%!EAS><+t-DHFD3#7>-9lh};UyoX}%g^D&kNT0V0~bDVc0FZy)e0YDbe zTpVyFid*1?Qai}-mX9lp>G~(T6L0_R++iD*$1t}KY*WrG`{B!>w&@vnFFUHr%Qrik z2Ndetsc3B2Z+mv$cluy^rg=hGTw%^5bvJvMsl&P?sP{2lT=k0+)6hl`_Go!bQfhsK zhH&`RMjpHZSoEjg-}-N$HM^>j$KqNBjXX{W$cHrgk8rMO>w->*YoZ?3o#83B4CG68 z0hFR=#7&LS_K*9fT78yOLAX1PD|C`{@>DW?u1V`nUVyqK&muaW54!){-?A#uUKjt8 z0W7fp-x7h1qm#as6%qY^f~Ks$)B}<#x{vHL!-UBnI1M{ZvpJDfDrm?&IdDG+aBIO7 zK1=}+L+5%3#c_47lN5t(D z72Y$f_o_$49UxP>fnm>nhbChvPEC(QJu?vbQv>ei8-c~VLV#=Y`{ zyiB$E@}}T@gQ+3)3)RM`Mvv2u#x|MAM14TDE$H1Qpb|Hm!}yqZzMj6~6wPO-V8uHE zIekC2?=Ac!EjkC=;2T7&qt?)7Xd**j;!$I{B@_eFvv+L6ChdsF=zW1kb7;khE2icG zt=A^&t4Mdm1^s#e2Ak8qC;CM%C7RzWpgUdg?3DyZNo_--;0t+zCN(=c!i|5V<83q^$>9^jYxY_Y&AT@s7w(?6IR>jTJ}ovoqtf{CONXPfB(nIXG?*K zv_iwOtk!4D0KsU$D4Pqyb(0OI@0fex7C4;p(qcnoo#l_Pt_~43wx0XkV+$o%oBK$WL#QLM z{dERKhszLa4B9snqT%6#Nt(7B<%ivM@`q)HHIsw0DW+*ucY*i}`U@3H|6~92=7tBu z5M;kZgP%)AuC?wk$9glV>NGV<8%mZj~TT znW@zaG*6L;2x8FNNQb6Edo7bcCI54Lov1d>C-or0_@ch;&rYpoBx()nqXl>;zJpHs26q$+#~UgR2JePYBZWD2A;z** zDuXm7FO<7UWwRQ&24Gmb$OW9pADw8A+fMioI;ggQJF$F}E?2IgR5w*xUD18FV+f9N zH5cr$1Jyb7>PL!X*P30qq4A2&FFA}dgC*h09WCJ(;mSO|FgmX~511Bh80rq)KPX*+ zW=60pbL^Wu?bie{wCJW&UYUMo6dFV8;CDPBu8T??ib|&y`!E#B_NK26S*^0dHTvEl zWoD;W)nOc!?3>(hokwq6aFRpSds*SA(cJfsG(oJfXrV12Z6W*$_SeKhijaxnGkK=_ z^S(MY?$OG3*Ax}~Zl8BY#VD-i=^~Naqd{5p!SB2tCLzg zoN?jWFst}W-dL9G&xF!4R|Gi@M)O4ON_Zi~WBDhCI3h6G`bj&5Lpyc2KfQ3@LHbQN zzZXe#BpBS(p!agicj27@Llz&CJ-}mrRi+Ixyt@Oy(#s?!XWY@{?7xz#Gx-M? z!MH0PC~0tqiN31nD_|3)3m&TSUyYEZ;piW>*riHEGYnIB+>~4yGV28245RIl5z9*q zcRa`CjR*w)(v7QSO)ks7xkq@6Udo;9*kgk~?SUN$cmvtS?aUbboeFX5t2{Kr^!h>j z&zgASp^dSPfDuA+VKzL(TuAN5~HWY?N7u* z;U*hv^(l9EA`U{76b7`C?6n7yqi?At*$EDJjEc3k{r*x*u%irpX>Hr^a?hc4^_MfQ zB&5Vg1vwb$j1(jjTZMyTD?m@@ChbLys)B$^Fo^~~l`;RNNrSqQ<}9tf5{4j=rmn23 zOdYjjDKxh|D*g(+)_n30#e; zrlB&+&Yg&THMR9hn%4bm%49}r(thGWQ@z>TvRFPoSDySnJx;RBn6RUd>i48wBf0F< z=uqdel4w(9fstNSPz_@MT7Ui@m?#*Bb*jHnyJkTf$TZW`WNiNOpp1BkA3CudfD+uI zecGD|xs+u6v3eA%gTEoDy0HKO8<7+3b^Cy=;ORU>>{~4CyMoz#`r01UkgN^_!?R1W z^_Y!i`$S*W_-1I{#^1He0|RA|yuxQnqjfOi+tm#^!60}>N>LrCc^ARko2Lgp1o~25 zCHe%tr2lNS7I(E4A0W1nQ6>l4B6&sJoFZR(=#XPJs~B-6A<^Y9O?c24q`C-|yy!KA zcJ&d^G>4ipI-G4v2r+Uw$P_S`T^QToGw`Tj#8AHC@ZQe)AklsEdPb+4veveTem1*% z2kG$1GO6tRj%bJ?)~XaQ)*wapnxEG1D@G6%kNRS{&(GNf%2e^dC zBi=B5tzIw{_&#f(iO_+9o>LLEi0m8^`Xjt?LkxQXgkEe3!Az?dg0O=}O%WnX($gPh zfhp_kK}#a%@?^-A7mmAayl}C^1*4#Dyrx8zF~dL46SDNFX;4=c2EL$sMP;Ur-HQ8v z+)hm+rJzGe-F{J^L135e?h=CZf9v9g_tXA-KOluL4Sa$;P^+&Gh7H7^I?c!K@CXa)ja&8#UC-etu4?M+p4Do7U+ zo1ps5jBU-`Oy^`771U@XfkDpUl%x>U?iWJZk|Vyp6_Ee}4s;^zQ7GGzvSOSVEB$0X z?Me)`U=O^pPUvvlUM0AJvjk8AB51#GL!t(tovE?C|CfAPBlWB&dQU!$}YoI8d9Rx zK5L8CKckM5!?+(4TIzzLgi*@*qYfNAY~b~wNM4)bJ!!EGIEG?UGN!OJkXs_<r2(QEvMBbQX}G>ErdB+ZtJRo;yuUZJpc_U$E!yQ21mXP!KAU^ChICNq zE0XyLwJdHj#vu^s!>8~KPLkq-cb`-V#v)ctC~?nVuu38U&pvbC8J7H;OIpr6YgGVW zuNx{={f(0#C+;)Y%sY6Mp%nz&c)o__PlKafvP?6#9Xu!Ct1`g!+ioIkbWchTRUTzv zw+#LV)&R1^b-@InMgfiC*NGsmo*^M2H7{BmQ;HXw>SBJr{DGye$_G{x}_3CIE#f~E!)cd{c zssrB)IXbxM%zqYPeUI~zerpUsVr-l0F;}CR^?gA9rQ8!oaN`F;oV^BnMepd@y*7JE zZ^eOg`b&;((?~4dDx+u6U%9$-|IP<=8{vi1{?7Y`5_R?(>Q%jC{q>EayAT&2(UTz1 zP2<{Ky@xp;Xgj_q%>LPh)lD2?JF&;<@LJ7ufa~;G;D_%eJM!ZE$u|HCeL1Aa@h#5t zqaObmk@-~taP{ zmP;ehKFgGMkw4aJuYYO~L?bnhOlclwwmd|k-FRxyMAP4{RuIwDu0{&lXkpMr!eT~1 z0079CJ+*G5JABWzfe04UK0Wj%=ZOFfHg&TVY5ae+H_dUafCDm~r7 zI;K6tQatQE@#^i&O5DYfnzrtuC$--3K6a8ig5yAa$E86fc=&K@5}_=>$a31V+0$&8 z#yz!G_PC^^h!j)iWj@==$7V9Qxn{g=I+CesW=t|KGR83R{LtHPxt^ZToj2trtiyUr z-s2Cz+$uD)2D*YeCowg#uweSh#rWr)6?4b2`oeQ-2FhwDNE^1~+}_iC`l^^_s9w!c zk)mW*T>;JOgmt_Pox%|_HW_}nX$ki6T;b7Lht1hcu@ckP>fiGu=b$bVkyof`oA?_! z&Y>s66dWtr({h@wcae|9RiUWnP5bjz(iw4Mjz;l3iJmRdtzXF*;*#ag%1TGIYDAmb z!f5gI1f&-gY)WZpO1}@)r!K{g7?W*dQuJG^yIC!6D)lDHjaD2J-TLg^lkB3{kllbR zH_j#K4z~ldvf_`-h3(}jU@9m@ll=GGhSui~-Ig*!HW#Uah%-Ag>W!OgE2&BBrN-&) zX^*9i=u8P9M}%ZxQ0Zj{O}u$gC&n(5pDhd$$gBGZf$A!hf-#d*RLkL3EDRdRn?p-U zn$!0=?7PTq;5MYV{(MM(lK4y@v4&q!QAD)ORv^q}mrs))D>!ef;))|%JFMn~xhOh? z${^N^*k-s<;+#Acy=g<(N;{z=Wk}18i(R!pef{euv#k7*BBOcCZ`R&NL(G8mF0`?WHAR3J4z*$uD&Vs zF-TS@;A<#rO)I-FjYJ?{6!fW2H5W-N7hCJRu+XkIPi>TZUzMh(8z>ZtIV3R*Dkz*V z>9BV{TQFOZ2C0%78}M9cqE=|hWB-20wryak(i5wHmXGGG*+x)R&fRXTGRBr%mmg^O z8hCC@nz;q7D?1NT6f7}HT_TQqBdw~{nnzlpj<8LUXh2HuFr~QiC>Q1&dVR)z22f5+ z`ZjakxF?~WSLxX)TUFRMO@@!O(p6@xvkwbTHz{rU1}BWyi(Gp-UISFQ-O?%fDBbyF zL5wS(4ks>yh+j{(l+Ln#wy!=146rWobRD$R@-=97Ym5(466kKN_AWwoCHFC2k5Ju) zUdq}jtpu5vDqS!3QKlJHuDOYieoNZ{cWTozDZ4MWIPO-TkQUQxAnz!SVlON`S^=n1 z*PPj6I`PkVM%Tm84;v{0jQWJy_n|m&tB1wE3|p+ER@6H9EIoJ|S|hWJf#`NKw|<*+ z&1yJs*F@n@69=wlW-NIx*qk{!JL0_i!OiFt56x9Ww*_A=N>)6UTA5k;NY-(#$9|l! z#c-E>O3u%*>=&}WrX03ZMx|i1L050%*H(S`b2>qxsL*irL+2u2_qb}X;O&W>y)fZc zUPNVi!1`IqxSuhd?Ru@RcUcv1bH)+7V);oN+x5`>S!i43D)-~CjO{vopQ4oqqu^XEm*20FDU1b#;=dYdK554TnG0xMJ)>N8!>{IY zni*o8P@T>GWJNI5WykKJ^;QUd+m`1InBR4P&eZ726EOT-Z3?%maw|?eb=^3|&l^%AT_0=4K-|c&-N^h`O?jJE(yQk;m zms4(!1sg(y$Wu@&scQ=hH$)K{eMP_(E`Mj)z4hB;pk^%*CiLz0KNs1S%*)K&MprBv zQBAEr)n`w(g_k9BaN8=qQKU=7T^pz2r%@N_5Uby-vN)n3xCLJw`@fh(ZfUSa8qf-c z@x3xVbN04T+g_Bfy%TU!XeRYRpSl5iB7dV-u`X2W>UWwiy8eRQLw0%r5xJ|FOdvVu z71plt$JbVMd5+jKK?k$WB#R&z2a9_P|ko=t69ab}>GjRiRC) zHQ)*xvemft;tPxmy}K!(9b)x~EZk;On$;!vMQeEb5Xhtd17dY&yXgY^zJK9r<27@M!LsJkn7P0(H@pS`nap9Cz7WhG^0OLk3L5nK`knIwlcb60>(; ziXm@jV{}|pcMsf(m9Nv|Bu}?9dXbPqF46VhN}b$)&psq%@9>3--g$!LWi;KrutVCJ z0)O+dUt#G}UvrCz_JI42s{6a&iDr%gJ=&pfhae|<+0q;QpxLU_jo!Q}Y@Jgw46e&C^DaRD``Hf$5s}}NgM^4bG(WOwnL8F zcZ>c87Ib4Vm*k078x>~sCx(weoR%~`PmC^Zkswb<;YN%|Qy>egv3ihr^J_4^)|-0D z1N+c-H!uwk{+D6ms_a8doA))K{EfNjPY!#PsdT##$5K~&o#3wq$%;Q5Pz|3)Me+j4=#tiuF8JDVu zL?OH2o;zUr)B&*8xG`Y)fx}y6Y_URmxmWcuM$pNJyI((~@o+xC)WOhv&)|&YQJd5t zx8m?LgdF|KyL%g#>fzm5CqwVaZ5v?c5_u;D-$XB@;nO^m*a8`n3S`j3XQzlqIueiW z-pp&;+KgpU0WsgnJ%{=7?^mGhTszA@%eQX4wuvVs=H)=0X)R=4dHvQ5=6}DwYX)e# z6^5{dm8-b5-i!F^6y%|aE0)lw=Cj_cwiEr+Y~PVH;IsU-Nq+BgWY3D3zf|P2O+FI} zhN#Sjk}IQzAkCHI`O07}6@&=5J{C2v#z0?oOB3V?yh!MHut^H}E<85@{Hfk8z*7_3 zLODdLO6G-(NM9yhmuj;t+9)I-O9zUHp}JyivE5pbSLS>WT&$eI!ct|qR@ZHFfKl9k zEZL;3AuSZ)yws>s41b|9%~Z{UBdMk_xn3z8KYL_BqD!>BRFomLka1w5DxFdmMCc)1 zQ}*WV&B-+q^foIUjO^|rfO0AZ|{X3%g%o{t- zsDHJnhK0aGTQnqFta8a9omw*rGidmL27rABg3v^bGL44j3#5xjJpnO7yE$!46BqVE z3Nbw@bvr(?`QlgvI$+<=Ed*t)GA-DvgriHP1#o7{?ue>8ObE|AcVLlO(v}VZWkJ0f z!^%F}&a7lEiHUh4bR;>2U50g^*#OaASoE1qaZNnIUqru_HR`$0%a(yq>Hzzmeye<~ zF%MiZyuPH-#S$`w%34|^jYLG~DY%k9sD|J5;nb#hh_vy3lfI%?9ex@*I1S!H&2-76 zd+9XJb`^nb&eKR;U~i_68tqa{L~onQ?<6t0P~jMbJKLr!CJg$Mxi2A$x!|1kDW zQJQthzIRsIwr$(4v~AmVR%WGb+qNog+qP}<#?^q47}~AMXi&C`()sm#Ybsc~_IhTYnNR+VvBI)uvlWik#~q%MF$hQK>jbXkDKys1)#IMY8yRh{!JQ%TNuy2b6()&oc!C-Zr}GhI zLuPX3_nc*2>V|{LT{k*+01BIOi7d1d-9Kd*JD+;)ZDLAV#3y4J4I!prCyWOowwo1R zG=6}xOfO`s7?a5X*A{a5+@&6ktTj@aGO|9nb=sxE9peF+fxx-R`mDh2SJFOBOJ6T^ zr~$Qfw_z^WQHnGXCJrtUE{EYGgqPY)Fve# zPud^{Udiq(xbjmrZ7~mNj#J-8d`^S9p-d)ladBrr(&z?+toB*y&O&A@PoGvYaO_sm z#nq*uK%9ol*xJ~>JaZDKzr56afl<2f=-54RvskyBnctuCBjQ)ptl~FkU}=`G#0kb* zrZD&fA@T9LQO`>PrHC3Za%%2@@}lSrd9(7?`Q1IS`iKY8M}W7pI+Z_$%*65#7 zFRt%~gIygaa*fFSIMg7n@GeG*9JDS>|Tl1F&Q3bHKiEHe$mhgaxLRw3E0y zt3bh(KtVGdaRVK4>?NdJwROnc_XcJn)LDa%6cdB`NJ+qQSe7D}%@`CoXTtE{dtR&A z*w1Od@%B%PdGx;brAFN_n?$_*4}%&YN}up225Y`5c#2JknvmeUY#G2ryj|P!hUiO` z7knSlgR5T3b?anxk>E^6p_|E=bm&Y>Y-HX_ViiP7AQ9~&;l@w7KTVQwjb|RzM&>iP zD>XtLK?~a2i1knoOqg}8EKrfSX-671Q&0~n_S6lpLN!iZ*A6i%iGmu=7T6ZS1!gc9 z5a>h5I6Emd)DY&R!ji^Jdi^HJ8n~y-dowYpb>l{Y=Lg7g3wdhfZL`q1MP)FF#1aN4 z4d`(WazPoF5d&NbjoOtLWKN9g!nR)YW34ST<3@QE6!uCl4t5Jq4p5UCD ze2XC(=!;?Rn(lB)Uf~$UT-s zE&pP^Nu-n||3c1Je*L8M+38#BW>ry09;D$61unVdkejt*Ks%4YW+{Z|%_sNFk(hl1 zbW(z&IIuH*RVT}3NZHj*7p6ofes>EFWn9LcsJp{MPTr4)C|O-p99glb^h>&E;&tCI zvb3EyDbBXA#?ngODiXg5Lz%fCZoJkCtYAZnWqg&{pH20Xzn zk27dh<^b>Z4Dw6t0PhZq@+)AgU#(gZwCo-AOX=Xx3(kB_Rb#Y7*HJdbyJO-OiqpH_ zmZYYKRAkXD-HzdBqMqrXnP~-V?x207`kfNd1+1QMyFsgY!#>dvF&p+plr^L!L8yqelQe-7F zjZd}UNLlM@(OigQZwytWzxABpIQBz3R#kF#uVh+A+uhI))*l8q(>}k)dfLx{*$Cpb zX3=I5aP@oko0N^Er^#247O5$GrgysM(PTomX=viH;zEg-;=LtPYzLO0b(4@2SzC4| zg7+kn7p#YVUn6pjoj7=ye=NVGz9o+Cot?67*bdA&MBu4!3Q-WvpkLJ5@!mVHny>Ko zN91-|S9oeYP&mX(U6LRT9?<84(P9}!M6`Lo8jJOW$}7#D?~7ez6l5M(TgvtmiAyHC zVYY}r<}>=@@hlV8O?{maOkAtG#7VM^&k*S%w5ZO$L9g{i4c!+;Tjv# zYTZT(3$^O`gKMBqa)0zcY3s=YWS%yvaR({T?vk?<&L4nwPbTwsm}@ew#q^=!Aq_c= z4i;dbHtD>nIVxO>>(&5Ads-#lxoGJb2OFqBqnH|($3BHCZooa|EfnnJ&a=eczmj05 zU$o_*6bFnmut~(xF`==>@hlcgC>Jrwj1rH{u{#2aDg0TNv$mLc4<@qIYsmyk+v^a^ zAZHG8H=43P$j$Maep__LCCf-VZ>tU1`?W-sr)S;-A)+&a+yaYV(AwC)+FZ&ea!=04 z1Q3rm_f|1~bPU6UR1Z0RtmXKU$CX*Wyj_Dev_3y?w5HcjGk zRl9huBzrW3JlW3)L|a@+b%!drsz{JSbFV`VcJ&cS)aWhrjxj5q-WAUK#|7GrGYq-g zO@=0~nEQbcvKiHQwiq2uoJY!FqAE6NVf!up%V;_5+_MmCFxIpT5#B0?8b;oT6Q@y% zWPJ&+t?6_mI)$s*Z1VA#@MHRL|6{sXqG4C47ViD8z|Jt-*h6p-u^va`0RU;W@S>c; zcYDm}?uenWYm_If!Y4R*c67J!_5)!9POvC)0PZtw{BU z)6lP=n_lDf0wbw!(cWqt{Ph;O2j@)!kPDPqg`b2z(@*0a%szxT zP_JR{;Z>Z1#S4cZcc5lbPd1})lpuFt$M-Y>KU)uNRxXY{hIHU4fs`1nk`|Z|E&}1( zB1xxJ_zkhN+z=*;E|{ZfgK}M_Q|DnF15UVS&4HX}N#=ioI?ow9QREZ@naQsOWXfG5 zR&;`ijOO2&Lu^Ps#p)(ZraW-A;)w|M>n#A?;}@jxx0&(b_^Lxu2yFF2(wPY#6TGsH zw<2o6eQ(wyiC0)}G@DV@>%Mz2NP1a);haSU*tWwaB_07&dM{?@ki$llB#-Q(I#yZZ zGX%g^swjg7#8M+&i)M@anj?s^$y{V#Zgl|08B+Xukm*Z6FOO1OR&-DgNs&2JEOe_b z9KW9qH4ZR564Adm_l}jVsl=xA?~TsBg93`otRRp8OTz^yC0!j3F_y+nN`a4eE;9sx zT0O}f!2#5cyvB*}sGpVAEy|VFojIyXr4!x>s8Cr+Zqd`TJ1LolTn7^L?P<3N(eVhe z0>XQ#@Sj>CTL9-AbUq0Zw^fb(I6yxMJB&uFxjI6%nmrmh zQ>*0L=lwqyf2`Jlxc@}#4WxN959@QG(z(lA3fBN=tFt;>6J<*7=?%Ye0B=Pj z$b-X=9=>DPM*y=zQ)F0e)Bo_)t9`3ES&znmnxpo*gx_h)FLfo< z&+SXj4!{Z5vl+ep!Jzg^Z(s;+#|??!3AX(KTZ6du2$0bcGKhBkQ|$xOijQt)Y`Zzw zWR}V|4{u${BT>gc+0vZsBSt4U8LxL8Zzg)ib@`WPU(ll{#*~jRUo8(`=w|;_W>b*u zv?gnV<31x*qrJ^Qa`!KdohTxwk^BM}IZwx*`a=MLj+ez+R{~Q#QpYH(+);phQ?tl9 z)|7HYm{RuS1#accS(~+el%h6cie9+B34RmCC@$Ped%4vQ6&dQG(%TIVSUQPJXn?x@ z`-w37u%i#y>ld+VJ@X)ag6ub6gwXehY8?@JZXl$dC=}-`#P7-G1juN)sQ%gzCLNMp zzRPp#u$z?`MN8Iqp{_m^Hr_{?Bej}IC(NFSFPAa&XOLi#5`DT zEeZM&nXv0be-vxY6e#fIj~V$Ha_%Px!hm*ptceCePwE61@W)s0*K}Qgq$)4ue z!JbEQ9Gt#t(*sUuPwv-j1-@p4rp>rm>E~ollRlvF@g%gJcr5bHM6F}5^zOAOeK!Tn zc+ogj1jp)6fQ-iB1Wt&iUx5Zr@B~iaO8P#*HSqGQUYN+eBfMT^Q;C_;)-J&Av6fx9 znpU<98VjB~Ft{#3Dl#Jt=}I8aA!E{g;L31^YrwES!B^&58e#T)0Kv%qZ2I#478?S8efz>410xbZ0KN^Pf-W8+Erzq^+XK`dLIAkFxWNu_B9(sWbk#B2@$}r)R!=P%d{fQ0eX{w~`Qd%_);Sda<^Ie7 zklv4q!e#d-Y{D&6ONTN!nSwn(Ps}g;+5x2cdN1);yTqkV^TuI3Qn6eQ)K^N)4EkO(S`A`C0bjkIee2b4%4+l#0 zULPf|Uv$|sI&al3lAB-;8H$(004sOt?%Z<(UUnjL_TAncWG6mf7dc#ZT(E9jMAq%z zSlo>2`*WFJwYcVG(%8~Rv(V?SzG&OBXVlKhZLVKls)#%QwxT|Hj8a4}T+N{LHX_~v11vu^ z5jA|20abDCXUD7_7pk6$J|I+0*TP721~Kz%S7GlC&<_NA<9w4PqyA7*(cgVGl+t|3 zl*T|)Zk0n(*Aee-bsl- zw)G2NRZh^>&J*URFCXP|d=TFrom5#WRHLSBr1RMx=4V)!`7_sNEH_izf3h?^c$@GzkoQ zmHC4HH#)RdfJWS5)%v1BY8xZ3SDFo074TZ$(xh};=A~S#G>Y)J3&Eey%<{xxEV=Y~ zy|N3!5H_Y5ElE2vRVd^WBnV~XiB6bf16~&Ggrm&zw3Nv5rJ+9wb3!PkmBI(Y)bc_x zYZGMB_c~{{m|kX+Wz=SxV|fxRfKh6tkkG`vy+zH7NRz@*0J&E0g?k$Wi9k0HObG)B z8F&&gi%o?@Cya)b+4?6DIMbN-a>3Kr5qOLPES3r_(oG7@uVM{F`e*wkY9%C~%?%on z(V*AZ+zn@2M(e#AM6|}IA5#dhNcQsripqhN#mGd+3s=hvEDb8vibEgrRJIv!?JT9q z_0iJhEY?GWqeUWP<(TbpKc&M;=7f2w4Ba2e=_0h!Q%N_h;H2OB6PJi1t>uLCNm)Z8 z+oSxf`qG+#|4pm}ij=C1{Uis!QxqnnnpKS^q<$0|HX!DU7Ru|E0Kl8|%F1Ts>8Z4_! z-wWxy>`?TcaAle5c=seZ)*hK9UHO5+CB1mNuql#|4rNmwZU>rn_d?e>s>9EnQYQJLge*V(hP&T@uV`l94)IBn8c z7TIcs)k=y~&h2<%hiP-L1?_>oj5-9-@lHcFPiDkz&E93!CdDeMx^zy+49hrPSfpk_ ztn*058P}bl>W!+qnOD_=4#pjdzx393#E%usL1_9Ijn{194&F52=69hU#c|Oz6n^3( zxE<_q?zshu(!;t>yMZ{=f>nA4p99woX4pNTKp#BlI2~ckdrwX`HB8=VNl;}{bQHhr z^YC4*jH4vyAp;cw$k!I^S zrMzXM>ExeRsb4MA&b2e}OtR18RN(bmSPjAg@B%Xg0AUAJ@7Vm1XvUjdDPPAMUrDz2 zAve{Pfh54A*QzEXhUQQM`U!&s54TDl+=9B+o!I=l{1Bgi2;nmc-w(kcRxKm9S)ms< zyWg*BP@MYwaQ7@#aON5~EZti`7j*P@PW7?;b1)jH#A~qkk48TKS?C4~yHwz0$?M+~ zN-=eHE#zv%=4c?^Fc`pT;big)6~HKh;l*;&2?H3^BRQnQ@r4tgIX-*Deh&2&Ek=FB zv=%D<7JbM`aA1-}HGYpeWmDs#P z+r3(1P*xYprI()mA#k2f*V=2L*u z?8P`xfL7%LVOx!gt>+PgQEc)MYr3LVL`rW-&LP|9C(0G-ES)~HCdR5JGtMa+KLG2R zNyhRP2FhzuCiQ^6tf84fdNH&Ze@nldw>mB_7_HnSUe>imSH*i=mG&M&HyPEi_)9W1 zTU~vSpQZIS?F>R_*+(&^0nuPsb)iX;(AyPW$)BU^EKl==mXlsbI94%MA~nBO(3Hn@ zwyZB0kr)Gf1i&D0`dUCUI>XY3R_$Eyq&(=b2)STo{d|=mov6RT?)|t`K0keB7EkyASRR?*SXdB~cKN<+VOpN+(8n~a?*G2a$ghetO+SD+g?yd7 zXq@tJoA8{9eWPrc?wK92ex$QQiSJ6^@;uia%9^+*d;ac^A5#OcND(Vf3A0R{jJ&r_ z(dqP)x7A<0)bG7Cu9LvRBF~LY+7wtbjS?!pT z(SEHZkc;c-^pv|Greb?zI*#Yf7XFgj&pdA+Cx|qb`bvdXGuOo$+33}#eX^!~x}|`Q zF~=a0(xc~#wi(?~xO6~hw?I4_`1&_8C2*<7hSqnxxcs-E=zkFt{T=BlI~qHP*;*S* z+1gq<+x;EvMk;E`VtxZkL}IlU9~3Ic8=EXNfi+h&E|ll`$I3#L!0{nujRGO6Xxog` zt=?5Th%GE;hj{NrS$O&ssD}O9Mp`CZI~@{ zh-f{B!i&`4@3i>E0Cd26$creLN%u-ZNJ7VJzCOMRQ0lIZRM{5Z&kD#)CArLHI|bRD zF0->RkJXfGOgc)pwT{wnL{fcww}`9>G)Yg7Sbej(TC6O6Pmn$fhuyBgr6(v}=4O-C zqNmtgzASQjVAf1Xl86GS^eZ;Y;PnZtU{o}3cH=%u^eT#X7y50SRG1*)QTuX@1r|!w zCEhlXj!A9n;sadf=C-qWw^4hUG-nI%=2Zk!^hmOInzX1UYmE&0Ta6V9*TVgbBF#gC z-vq1SOcZg-!t?@KyzX`4A^Qjd#O(^T5h$P!CNMvIq^~b)OWgcXP@dpTQjW9UMCKYO z*Nwro=gQr}UFWNl?xD)vqT!(LT(QBNue-!vuTzpcqU0_sc5X2H^b$QWmIyGfA_!2s zyh#u{Y)0JZ@H6dWj+?zDg3KnW=&3hD>v#a{`Lp(d(JzNQ=Le}bUgbS-K0?CG<4^|B z&3ofFM17FIo2&2%QrU&#;*n>>m}Y^X(DZaQW5`GJsMw>xh?VhtDY%JodYN$><7G9B z?wR|%laJ{xKm0rb`D05!I|KZaV>pF+pF!1AmI4Wdp$Sz&T%e=HC-H+?&Uz71$w?nc z=1#k+k|{L36ji}d=yC$UNAA4=iNdz5=lwBVGP4hMmqazagZKf~Z zTJZnHO#hjR3EA41n43B~=>IoICoPjn+XC=nL!yE zMa)a6$}WlMAZlHkVszf-JkwgOKS_{V zW79;8n)6d>mhE!XLzCxxUHg+sInw6EWooANT>XnWF;dU(3#NI@swLLdtd_0Xh^Z`h zFDv&!nSE95qx_9a4^mTtb+0wZMcVduxyljSsW%73T94Y``lLennK{bhJ=&_$^YXOd zvaiQ75z)3dQ{fea(m$ptAAp` zpg_;)=-SX$vz)eRPP`somPfKV!}t#~L1+9T_@ugFL5^9H+btT84Eh1{bCdlcTQ{+a zQ+HS7YNu9fI`SkDDuGbMJ^qpJ7Sb-sY1EC4_bYI!V}e#nCjP{PU9a6d3F);M)YhmS4jVGQJ%*721f#$n z%J;7V5zG!a@GtuJT}_FY0%*p3;Fd~I@lkxog48P@1$g{;iI@uLx*Xt^e9)0m{AlsJ z0yr^wUnvR!1;$}V5;0|%xHy3%@%mY?0%Cp(iI@gx1y#S}Zx|GGolM%2H~%Q05$F8+ z2h{&8HtYpX>*9VF8L+>fzf?(oPn)3m=LiX!f6RZd`=$fa+WmhF7b^16DG6y>iY93~ z38@kB1?kC=eM-s+s*!Q&Mv#9I1U>xQ(2H-1!as&y{Bxj%p_Tdnm{9T8>!LFz=W*XV zE#q51^l$jZzg`!zwYL5S$Vi#n7|ZE9e4h!#vUY#%G{tXrm5u4&$3mjwg$&X+v1ksi zDWOq&G?_fjPkEKbm|~YKWDpaH=m!!s=oid|T9TD(`o_R<{xk4rqA>nUKiG9{gliF% z;2Q9=pcB)z0 zvv#_DKtb$J>Ci2WJfE?eu&(KgCdX?wj;Z?HmcdO&arFjmF3qF#n&&)A=@ixs#1=Y2 z^hQfosufp%Tmrt5uGj@#Zco=&b~|bI$Wy^xFMI{In;nd?PM>xhrdRkN`3?s30Ch}x(x#a zEuqc2^JbT&{XC!ZV^%gt#ehWXVSv8z&;}OBZEfJc*0_l~eS?&?^?3WG-QI98J>*F_ zE*TP~kIw0U9(x!YMGbABQ)=c`VTeHmjkHmieYGYd^vs#1r#u8B#ZVI#b(S)FosjE5 zaSA>7^@_#inTN|bp25fDG4_+gCO;kL1Xl1exQB~t-5CAMv8C|oe$>56VQV1Le9*qXNlU5%lOC{_|ze;cakm*5(& zh(wTof@uRb!3RqG7i-X@l^53zGrnc5{(#Wce54!w3vyl-YNZ36Ij+DJXmmCp8JC_= z*o5ddOq^(MZt6jcVLxo^cA8&$CJ`CaG(FA)e_uq}?|YkE-{#m}>-7_Tk=@o*bJG;* z@>zy)O3nU));RQyOCGJCm~7^Ov9JHK;r=plT{zy^{BIMd0Q-M5aRHNW{q)~saCbQ=VTJ>&GDNF~#w;zQu90>A05N)%gJ+Hy8$rGKX20azZAq%1}-a=?+7R zs+6Ei&A5O1tA2#1eAkV&&ust=rksqRfG zk)Y#L6PQk{@71N=B)qu&FwVGncd145pf}dTND53-CY-?M$XG9Y$QE$usi5`Hy-Cg4 zz1%q70yhFX9D|gAboY$n%pkt2dIjqTn!wsHJ)^e!z?Q?@fll8#c)%WuiU})*f)=xp zgLXVLP$!yDNpmm#eA1e{Ib#kct7nX7zXWYwIL*^m^zGEkX6w~QDe03csH^8f5;h&K z_<%AfeZ_Y-MEuA>4N5{L$O|Qt6t*#hf76a_c@*#Qz>wI80@6dgydIB@l2$WbKlC7Z_dwaqO5QG#0#7IR9Qj z0gtN!dY@!Hj3EJ5h+wQVh9RgPVGp4)=a}3}^tC0|M?}J8`RN3p1_MyidI`1${zsux z6mj7GT{C*_l?aPvoQ2mMvAdJos zbDN>-w5>o=GOnV^M6*eRWu#{q6H+NkJbJ}gzn$L#rHKtT1N#; zD3AmH!!PDrATE^ivsPJDDOOAUaQ3a^1FHSL@}Ll|L9w@B-08Jn$n=%$RcQ5>sEW}_ zon%pb=w#MH)`qQX7tbx8&$qMkO}??l=AtJt?x`SBn zr@3*H99)A~527>_5aErQJT3K$VJ7GxD#&xA9?TiC6D8k@?13*Mv0p@nlN1pj^h7i& z-#<=LPnu@=CE8JbNEv0bU&L&xCODL!!>n9vV2Sv+*o9MS1G7MVScI*~7T!nZE+~It zU@Xp*c>+d)y9!@}$ujSdN}7)8OoU<2C_g>wuIbt%CKj}zs6H*xl%yIsQelxkFA;KP z(pkr!xh%#8-fE_qI9qW^Ey2DHzFHUFl2?feO_R)azh2VVP>>dAzcEj`F>Hf4gRn85 z8IP!N0uaF4D$aP-ipo5J&V0s*GN82>TmX4P zwfqvHm4Q4>_G2@VJ~w4Q4upr$jjZVh&M=FJ*l3zXMRCfLs=uQl5HZdao9zz z=riLcu7$ic$VdGyKiTV2KOn(Z=}^%5JZDkSM%Cw=MFe6laZRF zY|L9v!M3RqggNcg;6ljI;H4#bU-SjP979ekDsUWSNs@_z9=$npa~>OcA*OJ@o{FB7 zfQyrvuevA>6=f1aR7h+BSjU*k{3Lz&_?!Z$vBji{HcXehyEgx=SMoSNW4-)l%luAh z_=&BjyX*|R1E9^(Do1HZ+E*9#UxOrw?lHFn7QaNf2({>pvjj)Eh1S*;8~6l>@0b>O z1R9EB>#0J-n;q;xa1e0~umYR=??OYz=|Z5Z_|5yy^S|kip_{9*dya4hUY7-5$gR`i zxQBJ=YC)j~+=UDp?ZV;EG(oZ3SE(P|sfX#Rb}7#xkfQX!&9gGtB)5hMC{@Z6_I%Z< z6qz~67AhQ<0TY}*E@~}f9K*>I-qv%J$2=p9SiEmmY;EUS1vn^tMmWfH24lMih`mL_2&Y5Nx2;t_6(0Ut{)4CSoN9e~zL<` zA`U^;-rRI+foNa?vPQmGRU%W>jYx+VzfcRPEb+3eusNWKWtuzky62TR%c9!)`7del zUtXQjO0`MiJCXtZ_Ut168QcG7ur8$UX#6b-Ft%|tclze1{~fh|zh4Yie=aNT<5VQ6_CnoCppyOO$BCV**PnGbv_ zS;rj4IKBrxfU9*-r^Sx)M_Gj;y|oWh~rW{N2@sZO&yRr3a+$17c&xF?FjPi z?Xwgcc;X<$2;-st^$DO-$f03XLOV{8u#5|~*EJ1|9Rn}o3ek|t;tL;L#{gRVg~TYpVs z8Bx&2g9U??Nc7?IMFh@Ld@FC?V;EQgSei}_M%dZ0IHEr<+h`sfJ#3Y8UZyx#I5iAj z=&9;8-M*cXx%4T%>@MfaA+|5fer`5|I66r*I1X8Q^#UC{*Xm0||D@F0&59pIH3D}a zu`E#^6MYLtoyt)vLiuBpJUG>XeLS~}E4@9`AB3@vyfoLmG+TsxyqLWhFA(s$sq&(>_O^xDWNe36o0Uz<@OCmRMcv<E&}=w2K4{^TmKHb{{HZ9Vw02cKXYjX?Y|h%JoW1JF4EEsX}hiw6e1Kh z$hyRYX8g#0kg?p)tl~iz!zL;wWF%ktT?Mj%yw5Ut%J@>m1Z*-jLJN%LH{5;0Sk3fBsOE*a|v$U$q1(on5-Yj zr(2p|?G;#djs)oMJdO;jZP;gmZ!oS;SFblJ2(l4o5&Mx3O{fJ6l(^F&3b4g}!&#qN zPFHyITSvKKIs3dS$mb75peI^jc@i)VH}6Z8pGYOUP#z3_YWR1`1?}XmdhKty!`q{P z(&QIHo+(mI2KQ>+>?GmA1D$>T-Wpg1Z|ueUG%kX1Ta-FD18P?M{3;gyABjK zNK$m}VJ|~CrU)zw1@4%=D$^tDXt!Q)hta~kIAbQGkH(AYlS>n}ka+aco+k$yni8t= zw1NZ}F_=91^t_1w_FqXb^8We_hkPUg{QL~w+`vj*&>SL5L95R(kT-!w?PyH>OYk^i zV5MsyoTyifJ5r@KDXFsf9mWD~)cDv+fAS%gj2iwIsj&XzzbLc*GW2i(7Avps#fSP{ ze9r%L%ikoui=X~3U%GsAdjAX8l^G`~+sls}I0XVM?8PV7mv`O`jEUsD zMyt%1o0)IN=p0w6vrfTULAf?!v@eN}p=)winuCh^IVw=>EDJ^-hf?yXc>xD6nZB7fbS9+$yq z*b=6<#|Jjjj@>`g6-=Xci(QG{^pXz~L+)O`Xfi$3Iw4~6g2z8=TnG|Gu^!102dW6Q z_(y&?k{84ngI4s;y~e3MD2=z!obIs%U|QDCvCv}+z_iq#R1hUEu4JVTaR1YJkpYWA zV|=fv>0gC||6J4meF-Dwr6v3L;l1Y;2j{EH$fgLHAw{aCDa7QF0U;qa|D3d1iL=#h zBz&^MeFFF-G)w0K#|xq*WxCg2eWSyUp3bnkc_wk3a54}xh!vr#U~;#himiIy6DW4N z(5qJ14+J1Qab(>M0IMMpIHSh`d@xf>Tl|^)u*7pyMp($!7a-sy)QlRG2+=|9vE3dK zvpn^S0_m933)W>7PP!O)j^gE6(-~MG3Rhd|&u|J@JF7AWgOPu(siGK!DwrL2dy?IQ z+ILxSS7a(A9B}T)GB&=Vk+jTsKxl1MsRfK(Or}={T>3!uPPpv)qrOB?)vqX}^PA~8 zr_l%^(WGCjR2bi|Vq>w?=qjzJNerpL+Nt$h?t>2vc;5aCo9VAT<3_rxr1yOZh50>n zm+L?OUjc)^cy|A9o2F7l(-rd@Y7Gl5#h7~Nm&-z0DGrSS2vgZ)PQxrQH?KGHvozG4 z%EcEV71_kjBt-bj|ElW1Q}+zYT1!$j`vd0_);aq(zEMq~dhf2*%eP%?o@de-hgh*mWT= zToY&wPk_DG02x=iJN_=g)|XiS5}^b1XF-wWBceYW_KE>~Qe@sJecX(bbBD@E`Jp$7 zE~z-aA#%cPl7WTSCL-ixmI;H_6uJq84r8K$dL-JY26y5gD@BUs^dfm>X-&mS<9r4A zdqTE0t79-?r3v6ZHE|vl&h?Vjv|Of$V4_s-1OCutln&&n)uN(gG3VYw579=H$_iAB zB997n5JgLMY-;q^DwVQSU=Cznh$f)bA_I+paHO4TPQ##;rL*{^8HaCm5GmsaplC^0nUPk=!qzhg~-|5Xx%VK4kQ=gM$Qgc_Lhk!L9 z@(qkJTX~|>fJ@!m9@gDT@!Bv&Pt_yL@JdVUmMWAB;V!ED=xMUMVX3BVRaFZR&XH^l&w+vp6YHI3|0&17<=CrvWM=KX=aG z#gv-Jk682uV@4-=_`wA`7WH>y0@dYO>T_>l^rFF0Gj^-&IoFC4j%I0Kk~oRkdl>?4{3X{BHZ{ zsDi;+VA)Pm7$NywT=+iP`rwZB7c#}46qh?s^NP?GUI%G~YS2*3KZ)nf-Xd!}U9$&F zrps=Gq#xbLPn@R6IM6Ri&`gfM1~{&x!3S-58n33QWq3BEpAWPBKLml`NJ}5Mdhv_8 zuPXC>@0tO?0qJ05_~uSc-DNqi^s9^;Bvy4!=|sG{dg}KwZM)Mq5K55hV4fEZV4jx@ zm{G9Mmp_**0RS80ft|uSj}Qo>v3s26G?0EXLC!?SZh|Z4&|jFeyTzbBeUiC9DQ1T| zbiqKg;^XLt=zq*27zJh52>LTY)9tiSNP+*}0Tn^@7TB6X51(~L>;2Ne8(t==YaqiuQgTM|{=A#)H=+-937xGO!M;x;h{ z;Ycr$+97?`i}?|84+c2Czyi1iuy!QpQL zL&!(q!FO^ALkJ5Cm60_9>-3h0759#fg3_cCbgy-_#89Fs(SG@UZ4WN>Mq;tG*0l4a zLLvx~*zX)}Uamc5bb4P-?0;PSxdPa?*A#%>gXE;25h%}~kMG?d=t=N19~ZV~3A2QD zSlP?M9l#cPM{pf$Z6gJQJ_TA^+%OJL9`i`mHyE&w%-FfjD?EZsO4W3cAhAJHmC~%< z6*=9$gC@AdgdRyWeFvFRUuSi&%(7es#TkGKRtwt6ALo^=jmpN41({>*_zBA6ol(mn z;5lHrh|xPH6B~AhN>QFTTXe~Ln4Uzdvya@|IH|38?ytA(X%Qy|Bzu0;bT|8}`5-mw zBRPX6!45GcYs>g}(_2T!AyPv8503&{=1NYDp<>Wk<>}gHT#P4UruiS)FhjiAP4gU^ zwFm~CJtBwE%{nIr12**T>r+1F8h4jX+qwoG3Mriw3jHDs5se>nV~ZJKn$uUQc^{>Q z97wy7lpZr=aok5mF5KOzSke=O8eF$m-J!oI2n#UR7vDl0S$Kh2Ze zB8cUAGuM7JP|eUvb?O>|#Wd9N1T>uE_O3qT?&EOA#1N+YNilsQFunl?dW*2V`SCuY z6dy~KBkBQ|0{D>78huJ=QM^#eONHc_+S4|3O6nMi?<_TX5)$@yzO-9BFmD^PNB01v zLdDcIMGvPFZC^R-wSac=k1F*z?ia>)^Lg2orOA25MudNcr=VZ?n#4Nvqd-_E&#(S8 z!;^QoCCDdKTbAu#scwx!R8~0^qoW1W!YaT&2~S~7!r=p0<4{-t!{bw&C{;%3OXNR7 z7XivN6noxVR z*iB3(?)QjPN-BVSN!~o=gM4|Op0{dgrOHq75c!JAD+B9t?+sq7tBZ$C%{5P3&ovKA z&6BRj)YNe)SklM6y>lMV>W;U-FkPUhO280U*CeLAU&%#Y?7=|h}HCraHxGB4bMd$F7-HznMY zM}FM2`%L>x8heD9u-E8#(F^9>(R0hybHun;drSvUz%NqBVd9+HeevE})I_EureP6M z4>!zaBXizfO@mBMko4jEh>?=cWd@J-sSO9W5W``RFG`U9lsjCCy!FDejW#a0*?o@t zia9r0nW&D9gLh6EqjxMiIrfnXvbaz)iIktF?BOU&)f>5&sc0?E-4XOR);KwuOz+J$-9;; zyh>$M!S|fC@H-xM!+h@nF?A33NLQ9XGd0}v?^$2m>eY@MGXGqoaHh8}3{B)gywBv- z4^;Bn#E-Z{`b+g2Re%RqnrRP53{;@cr6_0K=n=1@M}ziRJI6-JFj))|$w&TSkgj4f zTnw`thaB>|*_NS7524u7$?UY@nroKqTkDI}*7tO1#E4X%8EnS*!wf61J5Zc@rblUq z4$FkH0A|P#(qw9xZ*2kTS!x}rDeuW#WFKJOfXTs!9yx&3)+AUB%d`#%I##hLHb08F z)XZe;yQ*z6KN=IxJv@fq{VUSRk|DF!;$an~9J7geevxjguGQsY^&pv<{zcV>$u&(` z`$n&X(xOqltz0GD-V8-&n3>Xms;z=+#83&-xnl()ZGBKrb2-BGXKmj>YJK>5HUZPR ziZPQ~Gb5sPxkY#y4MBMs2XckPxwSF9)ygQX7GM^L2|4nLGTyp%Bk}k^KUNJ8OV$qE zIC7I(rhNH|Ql~F6IULq%oqsGPO9L-vKfPKugR~$;SyC2SM5?9`D)pr{GBntpWQrC^ z;aSSMb1bSPD^w$9D`%6&Ors#UJQdM|iCHEF%;;5r4%a4b0Hz|ZzHO7Ku$Q<*b$|pR z9iL~+$Q*@a%3-1vw$;F_m3)|wWE#KSuqEy@L=UVLK<1b$o92jbKki|2fqbPeXs4-l#TcsToBj}~h@98k&Jyq(foKD{W6QqgWRWZS)F=SYd9`oUv zh7hGUfkiqg7*iW0`=!(l2CzSz);g+CNbWiu_lrzyJfuuztz7Z32m3I=1#t=L99FCP z?vA(opn$&-W0A{Y;P&?#;shcx0CiL&R0ujWgR#bCtkzAKAzfRARM4db99gZr99~Is zNKmK&G5yv08D}bI!VG&jQi;NYf^|KL^(G4$>S1K=i#>~)>X8s^Oi>WGLX7b5kHs1W z!bszXaZwrpY%51mMq=NY8&yCJ^GYq-7GRc_&4XI;=M4k*bLbnq$~& z_PCrLir?dWY7&D-XeuGL_SPmwu1iZC$`oAvQNhhl+COq4)?{(UN{_Iv7+;$}RcG9d z!a$`w?Dof{u_;V;5C*Y9Y9gdrg#wRp>gh*N_^6SgWTq=|eBb(f@#L`*<*A8dJxaKA zI+r8q+^9SI z&0{%z?MQeYa=cFf@L;TNxfqs1r1ra9$K+71=Iv|SHl4FM!6ytwySY*R0_U-Vn7YQ- zxSLead_>vhsb#_3kJx7#>fVuqZ_u4d)pKrLJ=q6mFrV0402yOZH2${xKq3BNkp6sA zY~RgW6wDo`sOoHc=p`k~ZZEqN2cTQMV9=e3U3%Bn??3%*kGKHLNF)slA;Ja{jX}3Y zzygnH{jUy%0IXT)<`^Y|`_0`$Yr`fIjm5^8*`-y|$MR>y=C}Lu?w5Piv7j5p1eqS4 z;e1B6JzseJuh4|JyIs-W@%fCd`@Dv?>E?JqzlSSYc=c~rga5GtgB@k{$J?tW1tLW1 zBKg&sxwG9UKj!D3Y64U5`+q9?3aG5Mt!=uM?nXMK8>G8LI;Fe2yE~-2yO9RzkZzz( z^TnHpq)ZrezAlLnrC9@)tyIpR&4kwVM-O9up8*P_ZjS*J)Yyc^q7M;)*=P9>G}_># zFUH69#MmZ#Lso1^v@B|>A#aRLrAl9si6omRD=&uihB|_89P}_!8pvbW!7de_3_^VA ztT4Gx*6Y5I#10&&VncdukIpL6Y0Zcckezm5fUyt^krJA+uvTT@rwn&OQ7vDiFT65BKz^Ppi@l}-HpogVwp?onP0FD7E00*j7P){h67|<3xG_fk+rHoe z)oe==omT5hH)-C+mjz!$UO|S)oC(uAI$3e-4Cpl6q&`@6pj*G?C#=z zpnYiBjp!+h;Dd+0v~ID=EFI-2R8Zk@8Kd#^ZQ3%-Li@^Hfr-2y17ozY+Ei(0mBd2? z+SJaAdcVq4o_lVWm-EErU$VnAbJH7{bkIfa7tkgSh}%ui%SC-X19BlxXRQxeYhXru zK>3l)38i7tq8F=l$@(JGw`m+#kw-Y;69?+b4X(kJVq>ew#=wG}Y_NbzGv6|qgI!XV zG8*5627xktzsXaJ6jSQ>@WJ}xqVnvFGEsJ@xFTEp`Wxb%$-2r8ZP=%wgN2hc13msk z43*Z|A)H=Y-kF*}G`M=@=1qcQ;0h}iQ04lOn9c%9t<+jH`~j}R=+LZ!onnw% zRA0Zd#D{v6vlI=DID~K)v`d4+Doiw5rN2p>&yFr1x!{XdOMLz6^gE$7tM1N_jGz%( zHSwr8^R|EG{QDi`Rmk0JU4f!NU!O3XdVDQm1ENgxv9nTTTc$*}gCC#B!fsx(VCKiQ zERXvUgRtHy#a>)ay?}ll6}H=&v6&t6Izb@?viSt9hT1p3J&OrEL1d(P}P>g6SS3wKDoY=ePnB-TE8M6Tc3|ON;o#9 zZyfJ3QsHqF2h(1t%!&>q6p8m-Fc?eh2jXKaf~_n>ryMzI>rgm2EQn&YQPalWl0XST{;q7uR#m~L2L64VbGii{A2>X zp=nx9q0Qje$jN>@tPA;&GNs*m%5VjX5QVqg{E<43P`A|w6{}BO=NOHCML!76M?tY2 zc{W)u&mK1Qt5AT`oJ8--jXUi9G`{3e{Z#j02 zCF8#`DPV}VPIjN(3C+!Pg0OitnM2vRotIIJa zgni%+JE8ZxSKnz5vua9OS@aRf4WP=lX78^z+xW|9Im@OO~`oe0_2+dd2SOp%zvns0l z8291AaYmIr=y;cq&BcI+Mz`-%gCa&0b^~Hctn{9K`S5uO2)keP&#)rgxN5Qkw;+kr z)hW{>J^-zRGexkB%Xd4`Xh@@vqp3 zuqI+m%M-EEXN1oqGka1}o3WCQeGS?a?J2{0hQF)$NVU|9KY73&^N4iEEm~=z*QK;; zdc7V#*oj)*p=@8mL(0sSZ?RXIq@!zzzB~&YU7wmN%94sg+;cKc*W#o z=47UC>r7zU1MrLs(ihVkb{7b4__#C9%5HkG3miuV_;FXT+qIeYFG3c$BJt9jA7$~m zAycl%=!IpuGos5_x?8;-p`Ic({PFe~C33G>Z>pv+dAu*Gr2LEqAVt3#%#e23Gq zrd3|tZr8z&c_2vvZ_a8AsFL!*ZmrF1Ysp#{{JfxWKyixFh|e#M=4>$Q1Uj%-Jka5Q zzBP9HfY*IQ3*ufIRFu^TfsCaV-5%59L+6dBYV&>SP9Kz>9ejqAAPK%M39NZYQ0*0M zsW<*i*C_TX>$oHGJu|emmaC8mu_tngdiyETEt=7yJn!UM23chnbEZ?0X2+ZkZ~665 z9vg9$Eplsd2&yKf7vmB>w}fVz+_*(h55_*z&}VEu<-DrH53!oH9XeAl5< z2_Bj;d)xT92$oUSXhK8eEfMdM)J}$Q`N&N78JmBG zTqBfti`$aR_*pMaIV*CeWK;Y)$-8rKk@me@EQrxmQ#f}mBDN}m=%FEU-3PF-1$C#! zRtgyi=UC2;aZRT^QoptM0y#n_5)cVqQgrBj5ts!2=5L~_(@?O;#@NEihy2On@k{V! z(gf#^;J}x*e&csg2`hwt@A${uB*|0?>Vbk+*4$iDw#OWA)Nk=-$FCa0m)A7T->!)B zd{^4(yXScDlkt&2T7I3a!$zScGz*kSqGwBZNACjL!YukFtxdr44cAJ6F;FuZ{T-*@ z<<(Tk^w!_>Q~?%STY}st>MPzAR3N7DX7iR(ixmNz3JKD z&dqyEI~aVsonVv&sWBy^)ShI}>MC|)`kh9-rn)q;E+3tgiCZ>t%83*&e-UWpe(M65 zeP1IRkD*ZD=d)|i$#dB{`B3t5Iw6O|cyr3&N18AjSVlnL9sQip=tiL!|DDk% z43TO26kj+5qftK33LgjbeYZRx2iDhqh?M0^Y_AIPG9LtC=4FU8AJDFqY>3EK0wr&b zx_6cR6}jG^Iq;+_7%CN{h2q`fYX|i_Nqlis-v9b`A`ShiL)K>GnD`0*VO*OYUVvf$ zqF}15P<0p~oX6MU{5^{D;X8hdSw?w93{L42L-O<5VnT=zKa=nMT<4Fa#O^_*Xkj=) z8Vwb}I_TL;;hbu$^8n+TfGg@ex6zePpW&Eh*?oiWWutu)+JQYrhMxn^{AhM7-kFdQ zPv9j)Eo+nQ4$%Cl?;~j~tFHy_*g3A{A!p=pRP^Wn|5tb(ym@|{Y&S9E3unGuZtUZn5({7mpen7x8>jswuE7Y-8?t6rO0WuP za7Tu~ARPO!I798iVy`ZddmSI=9{Ab1jCm6)c;;P~^{!cu7rl;&#aGe}X4nYF+dDsl zh+2rNLmlhG!nLVdjmNDvaLLw5x>xlQtNiZPr~1NK4cnodF3uxn7${H|%GRedsFD*I zSe&^FkhKEPor1TeiSZayX1-Uz4Bg8}%8s$dQi*K}?Bk1?i(Z|j-_^b`G#^AyC0aCr zH1C~tO;;|;Lz`kcN4r^rl+0ZvA6)(rQU5?QrufASw?x>^F>-52O;dHns>Bg~;WXPrVLbXecIH#W z8z81lgqw1tck0^oZfMu8kRCHvBlmrI*7zfi9!_PC8JZtPorF4sS|}?$2z$yuMF;(0 zxtIgZX)0c2zV}a<1!u{f#*Dz4jjh9blhHkGK;!~iA?hU8p+3SOmLo$PV4U7wBE{K#56T;OjBTnF0ry!Bx}=4>@8VDwD-pvG&W$$d z48zf)-Kh0@3b&3I1t3zE4b9yJJU&?WubQIBzi z#+&HJWSv)}WY@FmDIYm`@)}uIOY$W^Q^T+6Wvr@bO%<6aVugzHh;f*ZS+)^$$|WH0 zl=HvJ>*&0jFk5psKFqv1a`BOaBQDCQn+sTlD}?d{gC!)kK|Gbe%n2ua z9r_$mitMZMyGtGXRX#JvV92V?JiP9@K(3%N+BZKgH{>v}Ng~^LIKo2$D~(@&wbIky zaW2Jr8=mgZWc6BUDD$+Z*SJ&~U*t3r`mJSZPcjl*bmr#*#`?K_JOmj&B$?QYf-03% zz62+<*7Z_HU;DPpp;xyj#&A*QAdptJS{n!|G8-%=ViHbR3bBO-?lsC}bir}9$~;3O zOI9387nE&nTE%DYdu-D=deBh{k-119#5uU~GL5dq(}(&g3|pKiLU~fxzL1#bI(gxU zNu%lS_lr&GtL(UzHD%5!9zWu++^Vu(+?e5KkK1G6UwV!DOXpg8=yQN5p+>Y*FCn|8 z7@Qy~stL7E`xsQ1-eRW|$lC5bc;4uk&}RB(#@Nnr1#*b@-HLWGWmB7Dg-4U(8}R$& z^R>`Cw%MbZtH7}2qSjuWNd=W}Ox-;ZzfXtnv`2vmf>nN_nP1u}TIGpaA394%sM%+I z0zul7;-uW-AG>a@j+Ahm?gaUSc=Un#@sPbGbkQ@_#v!pf8|6w1*`kLp<^d0UjZrh; z$(ORHFZ#^4-EJJ?T4fPJ7P?r32C7P`n)tO&ZBuKBK}G3;mIz8O3^C9 zbp3Ir@_TKVbv}QJF<%%tt3V}fxNxnhACLhBYjp4SNL1MC)-cNb!y+fIkO?2L_c8R{ zp)Cq%DZ7+qRw}%oj5!1P_)ni+tPo;>IFo+*ecc0&gW3POLU@^p{gatO{RqwnfZ|gyZzCl(9l27zTfpo#+!^LMkbx)Ulv#LfyHkRL?SarDB|l@ zNo716eHu<}Z1HSq18xU4OCW#`Co)6HQt=xGF+_RO#E~k;|YeqO7)$qo29eD1nY&0kVW~iuI`$|Z=ep`T4`o+!3R^2lEmr-v zm0%Kz)UU4Pm7NB%LoU92G7top&jb3-j*gyOvcEN)(I_C}eC`C?lM$$qgaI|vdylD%Gyl|+dg zXM0D>3s`1Ci&JjtR=w6orLy(?N=4rWGYxh~Y?a@3UhBp3B`b;6js|>~I-9e|2=M3I zY*m=zcc%NQPhkJ;_9a{gb;S*Eb*k9sI5;I&9o!eGL zXj(#{Acv-xlZjznji2xuG>_Oo>U=6%b-p%BnoaKET2M{ffgMGMkSo>7K80|;QF}% zJWZsSlru4$R8u^?ewU;l*#VT6rv5Qu#RJN0L-i9P9FBm8j;ALlmHe9vSM@Gp`#2PRf@Z$*ja0H`i`RBfx zeDSCEf)ykq2OU0N-y0QNNLK_F{Q*wHu^QH4XsLpKP{=UV?I zE&NZPo7l7#)E2-bO8|&_p#JMb`>&y>_siJ)HKy&SXa&H*=CQ7x=71SLZqV5d;eZmlF)}A{+2Eydov&;MT|N($}7E>hMLq`&Eu%Bf$GcE_v+mB zwh%}dB-bG`YbCz?>cPvzxqZ(^Z-UNG z8yvL2LT1BC&6Fd8T1hD9DRRslG9##*DVU>(VJg z<&OP{fx4exjuOwr2`q*St5eLme4K%MoXOeC4qCNSw~1>>n)%a-V3!<)(dARGbAZ0C zYr_Ob+u55k`uc=Mg0@|?o@X9%-DBHr!iRE$xs5R$(UW`9#V3Bpyb zGqsK1^*O2p(}o813!#VCvMzC5^&VjiPv}PkPJVbycl-c3vb7z=3B-G!%OVZyL?$1T zBKe$*>%Jm>JY?MIg!$<{3cQn&A9gWM>oFIfsMjD1IAb=nZN{Q-dPwO}Rh@(pjg?}F z&qQ{@SM43CwxUSc-?Y8Q$37icVlr^Uv@;aw{XkBIeZCsw16o)GuXnGT(0lVb{99cI zJAT~Li#TRACyT^S0E0vy;%|Lt{xS;wj3`k0=83I@`Y626KOtD9&=;{psxZkGug@Mp zJmypsxlB93PvrY(jLsg6>HVX9vVPy0=+-1TcUa4+mgCdoFsPK zB)HmW@GJ+eBm52wz5y~Q*yuUW)Y;|qrxk_n#c(KpzL;38RmF=QV<=zsU zQDjM9j5);jZF~PGV^qk{cvW&^-!l^TW9#W+BY$XHYguL(xu&c%8|sKKM0SO`+7N@e zL&d!D>rw-`&5qtQAm7(fc{IrqsvVHx#!6-qxb-2^LhH6UpI;k_S3vEwV%M>BM1=1J zSVW5L49!raRx(R)f1D7$9T5$ZOazy58a*~B4&7${0evFH@A5TONy1QG0^QWIre`yi z)Q>+_3YyTp!tavf2uHWh_$1|n!?hh~T+|ZfQdrmd$o@AcQc+GF+MPI{B~rJ&uLj|l zmjnUCc1#nM>gBT5Y`mW5hljznVPN{Y5{5#(>vbwr*Oz7=-y?mJPyjfmhj-={!Djo$ z;@dGOo)C2Ov>2j|p|7oTtGs%L9$)k7<&B`N!UWhhcv z?WevPC{SyecZeLzVk)7w_&VylDRo>O zyMyzz!;|P8Zm}}fF)O0nL-E9)AhUD}AL`%BcZ?p}LPNG%v!(79eP;|uk8YlIQVVW{ zXqVfjt&Tz+TK(jMdheq&N-F2;DD*C8HQ^dHP`JW}LXs*G=;nc0QU6}JgN(jlwf-7c z#Ca)9s{m#C!*EHC(iU@MU|P9M(sH`EWiQ=klzY6A z;qNT;WQ3`x_R$vUvZ-B7j-RXKv6Ax-ze=zk*(lrG4n?U!rj_B+rwVP*IR+C8`lS6B zO|OFxI2;W#e}(y-UPR4_-|8_V#elS^98Q(43 z*X*o>9lo@<-E?f)w&K$ZOIr)(M#@vRpH1(QO7M&)gtd#^l{IQY= znWvyg6dEo(w6D7VF=6?)oyS{(*+7=kpBIG0H}Ap-zjk>sdC}<|w!}1pQ#fL0HL5|a z@cQX|(%FajZci^=<*&025%XaBo>+2wwo*4vgP%@5@&Bieh<& z9T~p6(g)wsg=$n*VbiXAwD`ekl8WVUS*HSj6J65|BMc}Q4;4A4f9y*nS!attu#CAz zcKYOi*V&g=LC6Ojv5v7S8i^>>3H=pj8o!beHyZM*xSN zctD6ar(DL+WUg`)=Jvp( zB!AFO-wBv8>?|U6?Z`D)MqW4HKBAisClQ}{<6}yHD(XJNEhNA4g|Q?XOlO)1P9Mi2 zXdANm&=tlSaq1n=oDfZ-6$E-bM4P!&kLpI6a(uADf6Sex=1+BaLD(PQcI=J0$?uJr1*36(SB()a<6 zMAJd@9yQy~Kf*|WqnTB3TeaZKvuk8wCrRQclx=#E7UmMo%VerADm?n`enviCA`tpxN1CEOmlK z(fSwaD^cwX5_caoKu}lsz=itw=zx|4m|DONEmrk~KWQu{8M!mjR~}k^g;teJr7W0; z$)F*+c5vXF6t&5P?%PID#TD=V7J6N3c=u}b^1Y|I!|g?ESqXj#-cNgIe^^$W$efwGJ9qsku!8*D797R5u>lZ~yfwn<`h#VpT5=h$<&;Q z54}u+HU{)htpvJ3US6a=wDi(U9a=t0@TE!2OL7xvE3_>qz1R-~nxffnPCDUN0~yi_ zXl$`1dgDnC*kwj<(q?P_mF7Fs4;7XEyF#~YP%IP4bO|L=V!WXc#jqefb`LW|&%FIB z2|@Zky7Rf%46B9lgI5X79KM&lP)nMOjT<|!yVSo`m-G}5Q{`(e(uc1nE0kEvQeg96 zJ&;E5##4L^A%wd^>*BA&=e39>tTs>}&)_p|Xj594IVf;j$c%VpjG$twpsNjzOPj~v|q+XjJR)?*F11Z{(A zZrZTD&pH+PunB}q!&#Z#NdSNgdCVe2k(ptT}V&&fwJ7z$U5(G1Nw3F z@JL4;F|>}ds^Qth40GDprK7=QVw8nvjl;ml@_>rJ!`chBF+0J0|KMr1PW~#whmq}v zwUGqKh(L%8CPC7Zw-qj^e-X#0Bl89sytfC~ELH`7ZkT`1DZ4(t4nhl7oy+}n+# z>8_WL7e|(~K)Kc*dsT+gvJEtaF>G-#F_F;psaI8jBpOCef)lB2OQGgoVKOMP&p=d; zSj+W7yo;j`l8Q(TL#Sgr#i_@u?x_qHdKw1@A=?ZqFSszEvHhWC>OqzYGG8b zP*Sdf$xjPdFw)YO%D8lW6k*$1Vo^6RN#XmN+>F(QsXb>hC7x_ALZdK%^fgKUb5ogW zQzC14Oy(eh=J;Vsd|kepee)POvpWMhc0iWOw_?=_Q?QgXV$6fRAZaXeeBS1uNoTYG zzDe@AV*PFWZ%xKlZX{RnxiX5*=Uwcd! zL+x_hkJmHeas_{Xy$GJX1urGn3Sq&HXA(=f5@xN=(wGP*;tdQ3zamcQTqDi7yXDI8 zCb`zg05iLFUpETYpo>y2IS2>muw4?i5jC|d$VaOkOauQ65-qNa0GWQWd9?K$TN%ELe>BiI$)xeb0+_FObhv?k$-^L(}|Uh0lP@ZPJi zYK5>WX5u*x1~cE~Q1-w_{RHLEwg6~JBy;-Y>}Yu4eS!cmT=!4k#dNSfAP}oGIX7^X ziB8#y&^Tl&ezEF8OQWMlpMdG2m)K)8v>OJ~snJLREA|j=+jc%D%Kcg8QQs8`CKmiUmECrm z&5Cw*Z2*VS4|D8{4CLY`WT{Hm z4u7nMBktDg@TA0e3vzf^6(0ppWR^=cDOgwM{T!n#p*gjD?!&_suZY|2Ljs}}Wsg(8 zvYz23@^~{}SBy|2t9)83eMBFXwJ%hl56X1sP)^W}b2iGS!cof)z#G_95N3}CwXt9O ztI}mal*>U#8TsfTD61rS=Tr5Kb_^&kaJOdF=u+s1gpp#}yXUbEy)mqC;dNF6$pt<} zh|KOMR}CMT8*s`Ek$Y1c^$&}!OT_o)mL+{ZMaej4&R|NA1r(8r{BSESuj z%bpW(M~z=2NO*_--`%REREpuJ5~(l1^!SgwK>k>j{a$G$O@8!Wwn&2}eQoos(;ThO zKB`&o^(Y8L#e;H#p{o#);ewa*5Axwu90m^KuPfRIQXpMVK!QnoYdk-l3_FzZo0_oM zEvH}(yjoZoD8)iY`wxT8L!IJ9rp?#`JBiRuaIme+ZPg{5a3O-+pm>E z7@xtTHTKnFNe81yw9jRlt6X&%TlO;rgQ~S@=R1US`8)DL@W2T}(W5l53HwV>8IJI3 zS2rRq#0ES8omp$@3NzT1dZ>C8>(+p8$AU|BL&-E!op`VX<;ksR>6Xro%W>jxE;Ng> zlZ|ehqNy;GXwqF~ZzPtYZ!|bI0;WSk+|e^*H3<>#1!iHP`j#J-OVv$lmAI=-_=-5Q zu}-cAm0Shc;|TL+F%aT^+}-rVH2Ez)0bvGQ>USaX$pu$m&=wE#&Trw9)HnIh<$vgH zTR1nFfi1FNUYfQL!xbm+)&r5LD%bU0bN(2izoyn4VaeVG_q}ME8*kDbp?D()j5NwX zRAYO%(z?sI=|d?ET9*^;XAHc{FVM*t3pQ9C+SdU_SO&Lg9Sq$3zQXHh+$yisp(UEN z=ack|RS`ZmfIUgR?t>}=rRq8wBvkY)bl9-;NIw1-gDWF2W^B4-fj1D;Z{HlXZ-HOZ4!T zZf@`9g3(;7KqZD;I&e7VQ;H%TGqdcPR5e#j>_t4|5`-O0Z;@8SDLvQglbS?Wb39!= zMihL0;GFN=1ff#|OIpA(Q8zDiEb7`TZ4&`~y%?|&`Tywae2&^Sf2xE2GMknu08~L` z5xDCC8XXQ*s97GXkUEG>C@{?Z1u#hT#IKU4m^wV`4^+|Xo3{>UB1KN1?>FG31jC8n zc>%O|)#6nrl7-eYMn;B`Z1Wwr4j=C?9w5D(OUa_TU%ld}J~igg$wrOzXT6zHji zKm|l5FcZ@i=x7Q>6ROyzNF7c|#OpGIC8&>+Gl5ks7-Si!`S+f1pC&ZXb(9(Fo8-!11WI;dqESg4#j zF>vpw6lK2guZ^ft9-|Lpj{O2CIkto6^TEn7sJWveME+tOR70soFP25)w)Mm4o5YDZS ztKqax{tGl`w1e`yd3&-2NoT6V=Pmo4I2wz=$m&9kxwMaiaooG#%&rR4(oMN=3c|** zKNL6`f_2&Sc-yJIPYW-WM)q5OUN8f7m? zIyYRctk4EywjeWayt}|YE(7Fy$2>B|Dd&6c50Ik!5apLuIYnX+bwO-udlNJccA?%D zV6zL%8x6cO1e?U}A4jMVIRh0u1dE&qFZ-+A-uR0ME@F9GQG z^nbf*0PM5v&Gjwpgq(Es|0RL@r+GbkSR9ld#b4%@G3RrgsyWqO=V7e^cPCFIk`lUs;YxM3uiIR@T zcJ^(b0&bt%EKeEyB6L|qmj`)kM2E-#FnY{#SH`7 zI)rJ*eyiOHl;`|HeTZj1L9Pi55k(l-{r)gDiNWW4>{{>?3E2{>z0_hxMnzxL5o!~h z?(*SC#or~}%vjN9s$`2@_pV@4(SQmv&nWKA{rP+HeeQOGM(>q&>%cQ2xZaZJ&wh5;?I0GNna z|F%{Bw21ui(FIsatbP?Xi&OZQYO9CE?6@okhNavwxF8(1rM?#d9Ac^t8aiDP;fXHh zF!iqLghO}68vI)5$97Sj>-|Wg^aU2%O7S%TSHRwneYEkarPj0D;{oD*dqf!1mfrcP z68shkbw5HCxi0h|lBT$FboBZiil&(I#<4xL5HvQDCZnA>M*NyN1F_AGJ4BTp{vMn= zYS)BgN;v4!O(||-E@t5z^YG#`2qX}zTa+~gP zUB820#`Y8p!;aE1gc?#ErsB~Y5?}m63Kh2b>b)G&G9~#MuKngPKfPH`0JU+sW}W(y z&8tziaZcUH9s-oGRqie)^%*vcPgzz+jSUV}nKp0&vUxdZk(RKO8X8wV1Wbj1Pz^O~ zdHdy<`b82gZ48S@%VfKJueW@@e8!^++56+Kl!ipYdp?iDY?sT$(&~D*S++89xu4sk z5FW?pECC(Js~VR_rM?S1_5}m>JwIF*ckm~Si39S|<^s#$rIg*dPwS7VEgwoHv<5zb zHKfvE2Dl@8{Z5W@INZg6@4Y~jB+IZ;t2Q}Up2cNT~97Xk~Z|Jo|u|(nGJk_$d zd_~GVJ1!TUyL}>4LFpWHP=dj6Ug!GT*;iFzMjd#(*Q`g1*MwB1@> z;_>u+gs=*F0}8#rGsle35dn-l8h6F-%#Q1f3yv!k;M8-WuA(2bby@(Yx^!d}FdgvY zBv!j(SZL715n7DZZDB86wNv2^x^Q6h&?{@|*k6~UbI-2P*ioZq22WJ`TlL|UOZ=>? zp8X2vHouLm!Cb@8#pkDtqa9MgIK>im5|$;rH*kH8y-D^KNg9K;L-i=x%7ct^&6k+< z`t0}tqM;->6V-J=KILK)rf;XYsr$nL{w=FM+NPTALmexS^eC-6pW-k}Dg1x1d)JX0 z>(ObtS2=%dYGWO%>a!}@` zzeef8{NuD(XS;d8ko|0&AoQJBBAe(s-fPSd)2ITI)><4)Y)opoMQ-T7zKnJA4%mYaXwF-o2uMW5%coztRNCf z3}-QmHDjp=vnVzI-SJ7II2wgRYGF~;lJ)^B3x(`2Nr)y>=Zuuerf1&?E52#IfsKwt z4@yT7e`DnT!P;+b8S3O{5{62T&l$RO(&J5`JjS*(C52_$a%Fq7jErBloRe4Jr;?Fq zXf_tIZHzvi&d z;xyIFGmH=b|2#;jjm4?}fXhA*;FKKjcVG|{AVBQ^&@gUq{sj#fHUBCA53d(RN=TlM zMod~5pt||rx6RypU;Na1kq7*KKI(J%DGm0Y+obrU#e{|A6Q$G?dI z28v%wGT{2BhRomH0WgdHQriB!<4@I@zq|40dw4FpfXiRxYW~bP@E7L!$3WmdC?KFu zfV+R{Ha-^|z)I;i07^F6R#y5pLQeX+_Ww~8eOayTeP!EX0Mr8DNAwH{xT1jhEvlFx zKsCqAQd{qjh1N?vooi#N9l-hk>-8Vr5YLdvfY8M`?uWQOHAFl z!(?j!CIZ|aO7YK_Jb>Q)8%)4r(9GTzpsXrvY^KkrtE+EoE2V9rZTP-QFo@{>i@^-{w+t_RVMPH+CH`kK zq?KS?PXU^N1(3huzq^Vg;IF@F27tt^owk`7@t*>sFKc_`qMC37sO>bMwm-AUJQpp% z`27tYzon(!PyIQopNT#Jd)jA##+T4WK6(Z@0K93y@69tV;41m;Z=wJ5s{cn_^PK6L z6aj4q1o*K3oK2sL2kmbGB`ppAXLnn=U7^4LD8MfRIv3$H65t9EU?Tm^ga5mBzaMfC z=J?6DfJtE=@YV?a3(g2IJN^dl&vyAe+RLP?&wyPYev2mZ`xLA%o8)DRt7qIYjlaSD zUBauE&@a;xJwwZD{TBMqnejJCie5s$%nI`iO{e>xZ|a{j_HVzdzXJaBnfwXxvmgB| zfN}Ioi39-t(pW$BX~PNCcl?;f2oW6%mQNn7nc7ImE4y+FSS~qd1f5`!t+aK zda)&X3Hwr_^cj}L=`XPV-f{gCmEV^{FC_(^iH_X#O|CgitOXQdC!q3RYIsZ5E?;HB1tI{(jU&&uE z|N2_~#&PLo?O(ctJTnQD{{yDKaS(aQ^zz{NnJKXPA29u&v*61U#Ap2F+JAumcjt*O zALZo%&NJ25`hQII`{SIKR4)zZ&s42Ve@FE{%;+!SUs`~l;pJNX4*t*a_j`NrOOlsH zv}Y3gFMlEV_XPh-ul_&gke7y$XLz8_|19bLmzm_>b^W(dZgeiU?c<>M2Z3b7YOM80USuVL;wH) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 9f7b58ba..00000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Jun 09 23:06:52 EDT 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip From 5e2a7bedea4e8a1ff2b74b50b67a66a1e4504200 Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:02:02 +0200 Subject: [PATCH 13/17] Delete fdfparser directory --- fdfparser/.gitignore | 1 - fdfparser/antlr-src/FDF.g4 | 151 ------------ fdfparser/build.gradle | 49 ---- .../warsmash/fdfparser/FDFParserBuilder.java | 5 - .../FrameDefinitionFieldVisitor.java | 159 ------------- .../fdfparser/FrameDefinitionVisitor.java | 224 ------------------ .../com/etheller/warsmash/fdfparser/Main.java | 48 ---- .../fdfparser/TestFDFParserBuilder.java | 27 --- .../fdf/datamodel/AnchorDefinition.java | 30 --- .../fdf/datamodel/BackdropCornerFlags.java | 24 -- .../parsers/fdf/datamodel/ControlStyle.java | 19 -- .../parsers/fdf/datamodel/FontDefinition.java | 25 -- .../parsers/fdf/datamodel/FontFlags.java | 5 - .../parsers/fdf/datamodel/FrameClass.java | 8 - .../fdf/datamodel/FrameDefinition.java | 163 ------------- .../parsers/fdf/datamodel/FrameEvent.java | 20 -- .../parsers/fdf/datamodel/FramePoint.java | 13 - .../datamodel/FrameTemplateEnvironment.java | 29 --- .../fdf/datamodel/HighlightAlphaMode.java | 5 - .../parsers/fdf/datamodel/HighlightType.java | 5 - .../fdf/datamodel/SetPointDefinition.java | 38 --- .../parsers/fdf/datamodel/TextJustify.java | 10 - .../fdf/datamodel/Vector2Definition.java | 28 --- .../fdf/datamodel/Vector3Definition.java | 23 -- .../fdf/datamodel/Vector4Definition.java | 52 ---- .../fields/FloatFrameDefinitionField.java | 19 -- .../fields/FontFrameDefinitionField.java | 21 -- .../fields/FrameDefinitionField.java | 5 - .../fields/FrameDefinitionFieldVisitor.java | 19 -- .../fields/StringFrameDefinitionField.java | 18 -- .../StringPairFrameDefinitionField.java | 24 -- .../TextJustifyFrameDefinitionField.java | 21 -- .../fields/Vector2FrameDefinitionField.java | 20 -- .../fields/Vector3FrameDefinitionField.java | 21 -- .../fields/Vector4FrameDefinitionField.java | 20 -- .../fields/visitor/GetFloatFieldVisitor.java | 56 ----- .../fields/visitor/GetFontFieldVisitor.java | 57 ----- .../fields/visitor/GetStringFieldVisitor.java | 56 ----- .../visitor/GetStringPairFieldVisitor.java | 56 ----- .../visitor/GetTextJustifyFieldVisitor.java | 57 ----- .../visitor/GetVector2FieldVisitor.java | 57 ----- .../visitor/GetVector4FieldVisitor.java | 57 ----- 42 files changed, 1745 deletions(-) delete mode 100644 fdfparser/.gitignore delete mode 100644 fdfparser/antlr-src/FDF.g4 delete mode 100644 fdfparser/build.gradle delete mode 100644 fdfparser/src/com/etheller/warsmash/fdfparser/FDFParserBuilder.java delete mode 100644 fdfparser/src/com/etheller/warsmash/fdfparser/FrameDefinitionFieldVisitor.java delete mode 100644 fdfparser/src/com/etheller/warsmash/fdfparser/FrameDefinitionVisitor.java delete mode 100644 fdfparser/src/com/etheller/warsmash/fdfparser/Main.java delete mode 100644 fdfparser/src/com/etheller/warsmash/fdfparser/TestFDFParserBuilder.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/AnchorDefinition.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/BackdropCornerFlags.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/ControlStyle.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FontDefinition.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FontFlags.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameClass.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameDefinition.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameEvent.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FramePoint.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameTemplateEnvironment.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/HighlightAlphaMode.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/HighlightType.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/SetPointDefinition.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/TextJustify.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/Vector2Definition.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/Vector3Definition.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/Vector4Definition.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FloatFrameDefinitionField.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FontFrameDefinitionField.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FrameDefinitionField.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FrameDefinitionFieldVisitor.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/StringFrameDefinitionField.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/StringPairFrameDefinitionField.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/TextJustifyFrameDefinitionField.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/Vector2FrameDefinitionField.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/Vector3FrameDefinitionField.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/Vector4FrameDefinitionField.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetFloatFieldVisitor.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetFontFieldVisitor.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetStringFieldVisitor.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetStringPairFieldVisitor.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetTextJustifyFieldVisitor.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetVector2FieldVisitor.java delete mode 100644 fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetVector4FieldVisitor.java diff --git a/fdfparser/.gitignore b/fdfparser/.gitignore deleted file mode 100644 index 84c048a7..00000000 --- a/fdfparser/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build/ diff --git a/fdfparser/antlr-src/FDF.g4 b/fdfparser/antlr-src/FDF.g4 deleted file mode 100644 index 7728f25e..00000000 --- a/fdfparser/antlr-src/FDF.g4 +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Define a grammar called FDF - */ -grammar FDF; - -@header { - package com.etheller.warsmash.fdfparser; -} - -program : - (statement)* - ; - -statement: - STRING_LIST OPEN_CURLY (ID STRING_LITERAL COMMA)*? CLOSE_CURLY # StringListStatement - | - INCLUDE_FILE STRING_LITERAL COMMA # IncludeStatement - | - frame # FrameStatement - ; - -frame: - frame_type_qualifier OPEN_CURLY frame_element* CLOSE_CURLY # AnonymousCompDefinition - | - frame_type_qualifier INHERITS STRING_LITERAL OPEN_CURLY frame_element* CLOSE_CURLY # AnonymousCompSubTypeDefinition - | - frame_type_qualifier INHERITS WITHCHILDREN STRING_LITERAL OPEN_CURLY frame_element* CLOSE_CURLY # AnonymousCompSubTypeDefinitionWithChildren - | - frame_type_qualifier STRING_LITERAL OPEN_CURLY frame_element* CLOSE_CURLY # CompDefinition - | - frame_type_qualifier STRING_LITERAL INHERITS STRING_LITERAL OPEN_CURLY frame_element* CLOSE_CURLY # CompSubTypeDefinition - | - frame_type_qualifier STRING_LITERAL INHERITS WITHCHILDREN STRING_LITERAL OPEN_CURLY frame_element* CLOSE_CURLY # CompSubTypeDefinitionWithChildren - | - FRAME STRING_LITERAL STRING_LITERAL OPEN_CURLY frame_element* CLOSE_CURLY # FrameDefinition - | - FRAME STRING_LITERAL STRING_LITERAL INHERITS STRING_LITERAL OPEN_CURLY frame_element* CLOSE_CURLY # FrameSubTypeDefinition - | - FRAME STRING_LITERAL STRING_LITERAL INHERITS WITHCHILDREN STRING_LITERAL OPEN_CURLY frame_element* CLOSE_CURLY # FrameSubTypeDefinitionWithChildren - ; - -frame_element: - frame # FrameFrameElement - | - ID FLOAT COMMA # FloatElement - | - ID STRING_LITERAL COMMA # StringElement - | - ID STRING_LITERAL STRING_LITERAL COMMA # StringPairElement - | - ID FLOAT FLOAT COMMA # Vector2Element - | - ID COMMA # FlagElement - | - ID FLOAT FLOAT FLOAT FLOAT COMMA # Vector4Element - | - ID FLOAT COMMA FLOAT COMMA FLOAT COMMA FLOAT COMMA # Vector4CommaElement - | - SETPOINT frame_point COMMA STRING_LITERAL COMMA frame_point COMMA FLOAT COMMA FLOAT COMMA # SetPointElement - | - ANCHOR frame_point COMMA FLOAT COMMA FLOAT COMMA # AnchorElement - | - ID STRING_LITERAL COMMA FLOAT COMMA STRING_LITERAL COMMA # FontElement - | - ID FLOAT FLOAT FLOAT COMMA # Vector3Element - | - ID text_justify COMMA # TextJustifyElement - | - ID STRING_LITERAL COMMA FLOAT COMMA # SimpleFontElement - ; - -text_justify: - JUSTIFYTOP | JUSTIFYMIDDLE | JUSTIFYBOTTOM | JUSTIFYLEFT | JUSTIFYCENTER | JUSTIFYRIGHT; - -frame_point: - FRAMEPOINT_TOPLEFT - | FRAMEPOINT_TOP - | FRAMEPOINT_TOPRIGHT - | FRAMEPOINT_LEFT - | FRAMEPOINT_CENTER - | FRAMEPOINT_RIGHT - | FRAMEPOINT_BOTTOMLEFT - | FRAMEPOINT_BOTTOM - | FRAMEPOINT_BOTTOMRIGHT; - -color: - FLOAT FLOAT FLOAT - | - FLOAT FLOAT FLOAT FLOAT - ; - -frame_type_qualifier: - STRING - | - TEXTURE - | - LAYER - ; - -OPEN_CURLY : '{'; - -CLOSE_CURLY : '}'; - -STRING_LIST : 'StringList' ; - -INCLUDE_FILE : 'IncludeFile' ; - -FRAME : 'Frame' ; - -STRING : 'String' ; - -TEXTURE : 'Texture' ; - -LAYER : 'Layer' ; - -INHERITS : 'INHERITS' ; - -WITHCHILDREN : 'WITHCHILDREN' ; - -SETPOINT : 'SetPoint'; -ANCHOR : 'Anchor'; - -JUSTIFYTOP : 'JUSTIFYTOP'; -JUSTIFYMIDDLE : 'JUSTIFYMIDDLE'; -JUSTIFYBOTTOM : 'JUSTIFYBOTTOM'; -JUSTIFYLEFT : 'JUSTIFYLEFT'; -JUSTIFYCENTER : 'JUSTIFYCENTER'; -JUSTIFYRIGHT : 'JUSTIFYRIGHT'; - -FRAMEPOINT_TOPLEFT : 'TOPLEFT'; -FRAMEPOINT_TOP : 'TOP'; -FRAMEPOINT_TOPRIGHT : 'TOPRIGHT'; -FRAMEPOINT_LEFT : 'LEFT'; -FRAMEPOINT_CENTER : 'CENTER'; -FRAMEPOINT_RIGHT : 'RIGHT'; -FRAMEPOINT_BOTTOMLEFT : 'BOTTOMLEFT'; -FRAMEPOINT_BOTTOM : 'BOTTOM'; -FRAMEPOINT_BOTTOMRIGHT : 'BOTTOMRIGHT'; - -ID : ([a-zA-Z_][a-zA-Z_0-9]*) ; - -COMMA : ','; - -STRING_LITERAL : ('"'.*?'"'); - -WS : [ \t\r\n]+ -> skip ; - -FLOAT : '-'?([0]|([1-9][0-9]*))('.'([0-9]*)?)?'f'? ; - -MULTI_LINE_COMMENT : '/*'.*?'*/' -> skip ; -COMMENT : '//'.*?'\n' -> skip ; diff --git a/fdfparser/build.gradle b/fdfparser/build.gradle deleted file mode 100644 index 679dff91..00000000 --- a/fdfparser/build.gradle +++ /dev/null @@ -1,49 +0,0 @@ -apply plugin: "antlr" - -sourceCompatibility = 1.8 -[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' - -sourceSets.main.java.srcDirs = [ "src/", "build/generated-src" ] -sourceSets.main.antlr.srcDirs = [ "antlr-src/" ] - -project.ext.mainClassName = "com.etheller.warsmash.fdfparser.Main" - -task run(dependsOn: classes, type: JavaExec) { - main = project.mainClassName - classpath = sourceSets.main.runtimeClasspath - standardInput = System.in - ignoreExitValue = true -} - -task dist(type: Jar) { - from files(sourceSets.main.output.classesDir) - from files(sourceSets.main.output.resourcesDir) - from {configurations.compile.collect {zipTree(it)}} - - manifest { - attributes 'Main-Class': project.mainClassName - } -} - -dist.dependsOn classes - -eclipse.project { - name = appName + "-fdfparser" -} - -task afterEclipseImport(description: "Post processing after project generation", group: "IDE") { - doLast { - def classpath = new XmlParser().parse(file(".classpath")) - def writer = new FileWriter(file(".classpath")) - def printer = new XmlNodePrinter(new PrintWriter(writer)) - printer.setPreserveWhitespace(true) - printer.print(classpath) - } -} - - -generateGrammarSource { - maxHeapSize = "64m" - arguments += ["-visitor", "-no-listener"] - outputDirectory = file("build/generated-src/com/etheller/warsmash/fdfparser") -} \ No newline at end of file diff --git a/fdfparser/src/com/etheller/warsmash/fdfparser/FDFParserBuilder.java b/fdfparser/src/com/etheller/warsmash/fdfparser/FDFParserBuilder.java deleted file mode 100644 index 66c2df4b..00000000 --- a/fdfparser/src/com/etheller/warsmash/fdfparser/FDFParserBuilder.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.fdfparser; - -public interface FDFParserBuilder { - FDFParser build(String path); -} diff --git a/fdfparser/src/com/etheller/warsmash/fdfparser/FrameDefinitionFieldVisitor.java b/fdfparser/src/com/etheller/warsmash/fdfparser/FrameDefinitionFieldVisitor.java deleted file mode 100644 index 00a8d42c..00000000 --- a/fdfparser/src/com/etheller/warsmash/fdfparser/FrameDefinitionFieldVisitor.java +++ /dev/null @@ -1,159 +0,0 @@ -package com.etheller.warsmash.fdfparser; - -import com.etheller.warsmash.fdfparser.FDFParser.AnchorElementContext; -import com.etheller.warsmash.fdfparser.FDFParser.FlagElementContext; -import com.etheller.warsmash.fdfparser.FDFParser.FloatElementContext; -import com.etheller.warsmash.fdfparser.FDFParser.FontElementContext; -import com.etheller.warsmash.fdfparser.FDFParser.FrameFrameElementContext; -import com.etheller.warsmash.fdfparser.FDFParser.SetPointElementContext; -import com.etheller.warsmash.fdfparser.FDFParser.SimpleFontElementContext; -import com.etheller.warsmash.fdfparser.FDFParser.StringElementContext; -import com.etheller.warsmash.fdfparser.FDFParser.StringPairElementContext; -import com.etheller.warsmash.fdfparser.FDFParser.TextJustifyElementContext; -import com.etheller.warsmash.fdfparser.FDFParser.Vector2ElementContext; -import com.etheller.warsmash.fdfparser.FDFParser.Vector3ElementContext; -import com.etheller.warsmash.fdfparser.FDFParser.Vector4CommaElementContext; -import com.etheller.warsmash.fdfparser.FDFParser.Vector4ElementContext; -import com.etheller.warsmash.parsers.fdf.datamodel.AnchorDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.FontDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.FrameDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; -import com.etheller.warsmash.parsers.fdf.datamodel.SetPointDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.TextJustify; -import com.etheller.warsmash.parsers.fdf.datamodel.Vector2Definition; -import com.etheller.warsmash.parsers.fdf.datamodel.Vector4Definition; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FloatFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FontFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringPairFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.TextJustifyFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector2FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector4FrameDefinitionField; - -public class FrameDefinitionFieldVisitor extends FDFBaseVisitor { - private static final int JUSTIFY_OFFSET = "JUSTIFY".length(); - private final FrameDefinition frameDefinition; - private final FrameDefinitionVisitor frameDefinitionVisitor; - - public FrameDefinitionFieldVisitor(final FrameDefinition frameDefinition, - final FrameDefinitionVisitor frameDefinitionVisitor) { - this.frameDefinition = frameDefinition; - this.frameDefinitionVisitor = frameDefinitionVisitor; - } - - @Override - public Void visitStringElement(final StringElementContext ctx) { - String text = ctx.STRING_LITERAL().getText(); - text = text.substring(1, text.length() - 1); - this.frameDefinition.set(ctx.ID().getText(), new StringFrameDefinitionField(text)); - return null; - } - - @Override - public Void visitStringPairElement(final StringPairElementContext ctx) { - String first = ctx.STRING_LITERAL(0).getText(); - first = first.substring(1, first.length() - 1); - String second = ctx.STRING_LITERAL(1).getText(); - second = second.substring(1, second.length() - 1); - this.frameDefinition.set(ctx.ID().getText(), new StringPairFrameDefinitionField(first, second)); - return super.visitStringPairElement(ctx); - } - - @Override - public Void visitFloatElement(final FloatElementContext ctx) { - this.frameDefinition.set(ctx.ID().getText(), - new FloatFrameDefinitionField(Float.parseFloat(ctx.FLOAT().getText()))); - return null; - } - - @Override - public Void visitFlagElement(final FlagElementContext ctx) { - this.frameDefinition.add(ctx.ID().getText()); - return null; - } - - @Override - public Void visitVector2Element(final Vector2ElementContext ctx) { - this.frameDefinition.set(ctx.ID().getText(), - new Vector2FrameDefinitionField(new Vector2Definition(Float.parseFloat(ctx.FLOAT(0).getText()), - Float.parseFloat(ctx.FLOAT(1).getText())))); - return null; - } - - @Override - public Void visitVector3Element(final Vector3ElementContext ctx) { - this.frameDefinition.set(ctx.ID().getText(), - new Vector4FrameDefinitionField(new Vector4Definition(Float.parseFloat(ctx.FLOAT(0).getText()), - Float.parseFloat(ctx.FLOAT(1).getText()), Float.parseFloat(ctx.FLOAT(2).getText()), 1.0f))); - return null; - } - - @Override - public Void visitVector4Element(final Vector4ElementContext ctx) { - this.frameDefinition.set(ctx.ID().getText(), - new Vector4FrameDefinitionField(new Vector4Definition(Float.parseFloat(ctx.FLOAT(0).getText()), - Float.parseFloat(ctx.FLOAT(1).getText()), Float.parseFloat(ctx.FLOAT(2).getText()), - Float.parseFloat(ctx.FLOAT(3).getText())))); - return null; - } - - @Override - public Void visitVector4CommaElement(final Vector4CommaElementContext ctx) { - this.frameDefinition.set(ctx.ID().getText(), - new Vector4FrameDefinitionField(new Vector4Definition(Float.parseFloat(ctx.FLOAT(0).getText()), - Float.parseFloat(ctx.FLOAT(1).getText()), Float.parseFloat(ctx.FLOAT(2).getText()), - Float.parseFloat(ctx.FLOAT(3).getText())))); - return null; - } - - @Override - public Void visitSetPointElement(final SetPointElementContext ctx) { - String other = ctx.STRING_LITERAL().getText(); - other = other.substring(1, other.length() - 1); - final SetPointDefinition setPointDefinition = new SetPointDefinition( - FramePoint.valueOf(ctx.frame_point(0).getText()), other, - FramePoint.valueOf(ctx.frame_point(1).getText()), Float.parseFloat(ctx.FLOAT(0).getText()), - Float.parseFloat(ctx.FLOAT(1).getText())); - this.frameDefinition.add(setPointDefinition); - return null; - } - - @Override - public Void visitAnchorElement(final AnchorElementContext ctx) { - final AnchorDefinition anchorDefinition = new AnchorDefinition(FramePoint.valueOf(ctx.frame_point().getText()), - Float.parseFloat(ctx.FLOAT(0).getText()), Float.parseFloat(ctx.FLOAT(1).getText())); - this.frameDefinition.add(anchorDefinition); - return null; - } - - @Override - public Void visitTextJustifyElement(final TextJustifyElementContext ctx) { - final TextJustify justify = TextJustify.valueOf(ctx.text_justify().getText().substring(JUSTIFY_OFFSET)); - this.frameDefinition.set(ctx.ID().getText(), new TextJustifyFrameDefinitionField(justify)); - return null; - } - - @Override - public Void visitFontElement(final FontElementContext ctx) { - String text = ctx.STRING_LITERAL(0).getText(); - text = text.substring(1, text.length() - 1); - this.frameDefinition.set(ctx.ID().getText(), new FontFrameDefinitionField( - new FontDefinition(text, Float.parseFloat(ctx.FLOAT().getText()), ctx.STRING_LITERAL(1).getText()))); - return null; - } - - @Override - public Void visitSimpleFontElement(final SimpleFontElementContext ctx) { - String text = ctx.STRING_LITERAL().getText(); - text = text.substring(1, text.length() - 1); - this.frameDefinition.set(ctx.ID().getText(), - new FontFrameDefinitionField(new FontDefinition(text, Float.parseFloat(ctx.FLOAT().getText()), null))); - return null; - } - - @Override - public Void visitFrameFrameElement(final FrameFrameElementContext ctx) { - this.frameDefinition.add(this.frameDefinitionVisitor.visit(ctx)); - return null; - } -} diff --git a/fdfparser/src/com/etheller/warsmash/fdfparser/FrameDefinitionVisitor.java b/fdfparser/src/com/etheller/warsmash/fdfparser/FrameDefinitionVisitor.java deleted file mode 100644 index f9f0f451..00000000 --- a/fdfparser/src/com/etheller/warsmash/fdfparser/FrameDefinitionVisitor.java +++ /dev/null @@ -1,224 +0,0 @@ -package com.etheller.warsmash.fdfparser; - -import java.util.List; - -import org.antlr.v4.runtime.tree.TerminalNode; - -import com.etheller.warsmash.fdfparser.FDFParser.AnonymousCompDefinitionContext; -import com.etheller.warsmash.fdfparser.FDFParser.AnonymousCompSubTypeDefinitionContext; -import com.etheller.warsmash.fdfparser.FDFParser.AnonymousCompSubTypeDefinitionWithChildrenContext; -import com.etheller.warsmash.fdfparser.FDFParser.CompDefinitionContext; -import com.etheller.warsmash.fdfparser.FDFParser.CompSubTypeDefinitionContext; -import com.etheller.warsmash.fdfparser.FDFParser.CompSubTypeDefinitionWithChildrenContext; -import com.etheller.warsmash.fdfparser.FDFParser.FrameDefinitionContext; -import com.etheller.warsmash.fdfparser.FDFParser.FrameSubTypeDefinitionContext; -import com.etheller.warsmash.fdfparser.FDFParser.FrameSubTypeDefinitionWithChildrenContext; -import com.etheller.warsmash.fdfparser.FDFParser.Frame_elementContext; -import com.etheller.warsmash.fdfparser.FDFParser.IncludeStatementContext; -import com.etheller.warsmash.fdfparser.FDFParser.StringListStatementContext; -import com.etheller.warsmash.parsers.fdf.datamodel.FrameClass; -import com.etheller.warsmash.parsers.fdf.datamodel.FrameDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.FrameTemplateEnvironment; - -public class FrameDefinitionVisitor extends FDFBaseVisitor { - private final FrameTemplateEnvironment templates; - private final FDFParserBuilder fdfParserBuilder; - - public FrameDefinitionVisitor(final FrameTemplateEnvironment templates, final FDFParserBuilder fdfParserBuilder) { - this.templates = templates; - this.fdfParserBuilder = fdfParserBuilder; - } - - @Override - public FrameDefinition visitStringListStatement(final StringListStatementContext ctx) { - final List ids = ctx.ID(); - final List strings = ctx.STRING_LITERAL(); - for (int i = 0; i < ids.size(); i++) { - final String id = ids.get(i).getText(); - String value = strings.get(i).getText(); - value = unquote(value); - this.templates.addDecoratedString(id, value); - } - return null; - } - - @Override - public FrameDefinition visitIncludeStatement(final IncludeStatementContext ctx) { - final String includeFilePath = unquote(ctx.STRING_LITERAL().getText()); - final FDFParser parser = this.fdfParserBuilder.build(includeFilePath); - visit(parser.program()); - return null; - } - - private String unquote(String includeFilePath) { - includeFilePath = includeFilePath.substring(1, includeFilePath.length() - 1); - return includeFilePath; - } - - @Override - public FrameDefinition visitFrameDefinition(final FrameDefinitionContext ctx) { - final String type = unquote(ctx.STRING_LITERAL(0).getText()); - final String name = unquote(ctx.STRING_LITERAL(1).getText()); - final FrameDefinition frameDefinition = new FrameDefinition(FrameClass.Frame, type, name); - final FrameDefinitionFieldVisitor fieldVisitor = new FrameDefinitionFieldVisitor(frameDefinition, this); - for (final Frame_elementContext element : ctx.frame_element()) { - fieldVisitor.visit(element); - } - this.templates.put(name, frameDefinition); - return frameDefinition; - } - - @Override - public FrameDefinition visitFrameSubTypeDefinition(final FrameSubTypeDefinitionContext ctx) { - final String type = unquote(ctx.STRING_LITERAL(0).getText()); - final String name = unquote(ctx.STRING_LITERAL(1).getText()); - final String parent = unquote(ctx.STRING_LITERAL(2).getText()); - final FrameDefinition frameDefinition = new FrameDefinition(FrameClass.Frame, type, name); - // INHERITS - final FrameDefinition inheritParent = this.templates.getFrame(parent); - if (inheritParent == null) { - throw new IllegalStateException( - "\"" + name + "\" cannot inherit from \"" + parent + "\" because it does not exist!"); - } - frameDefinition.inheritFrom(inheritParent, false); - - final FrameDefinitionFieldVisitor fieldVisitor = new FrameDefinitionFieldVisitor(frameDefinition, this); - for (final Frame_elementContext element : ctx.frame_element()) { - fieldVisitor.visit(element); - } - this.templates.put(name, frameDefinition); - return frameDefinition; - } - - @Override - public FrameDefinition visitFrameSubTypeDefinitionWithChildren( - final FrameSubTypeDefinitionWithChildrenContext ctx) { - final String type = unquote(ctx.STRING_LITERAL(0).getText()); - final String name = unquote(ctx.STRING_LITERAL(1).getText()); - final String parent = unquote(ctx.STRING_LITERAL(2).getText()); - final FrameDefinition frameDefinition = new FrameDefinition(FrameClass.Frame, type, name); - // INHERITS - final FrameDefinition inheritParent = this.templates.getFrame(parent); - if (inheritParent == null) { - throw new IllegalStateException( - "\"" + name + "\" cannot inherit from \"" + parent + "\" because it does not exist!"); - } - frameDefinition.inheritFrom(inheritParent, true); - - final FrameDefinitionFieldVisitor fieldVisitor = new FrameDefinitionFieldVisitor(frameDefinition, this); - for (final Frame_elementContext element : ctx.frame_element()) { - fieldVisitor.visit(element); - } - this.templates.put(name, frameDefinition); - return frameDefinition; - } - - @Override - public FrameDefinition visitAnonymousCompDefinition(final AnonymousCompDefinitionContext ctx) { - final FrameDefinition frameDefinition = new FrameDefinition( - FrameClass.valueOf(ctx.frame_type_qualifier().getText()), null, null); - final FrameDefinitionFieldVisitor fieldVisitor = new FrameDefinitionFieldVisitor(frameDefinition, this); - for (final Frame_elementContext element : ctx.frame_element()) { - fieldVisitor.visit(element); - } - return frameDefinition; - } - - @Override - public FrameDefinition visitAnonymousCompSubTypeDefinition(final AnonymousCompSubTypeDefinitionContext ctx) { - final String parent = unquote(ctx.STRING_LITERAL().getText()); - final FrameClass frameClass = FrameClass.valueOf(ctx.frame_type_qualifier().getText()); - final FrameDefinition frameDefinition = new FrameDefinition(frameClass, null, null); - // INHERITS - final FrameDefinition inheritParent = this.templates.getFrame(parent); - if (inheritParent == null) { - throw new IllegalStateException( - "" + frameClass + " cannot inherit from \"" + parent + "\" because it does not exist!"); - } - frameDefinition.inheritFrom(inheritParent, false); - - final FrameDefinitionFieldVisitor fieldVisitor = new FrameDefinitionFieldVisitor(frameDefinition, this); - for (final Frame_elementContext element : ctx.frame_element()) { - fieldVisitor.visit(element); - } - return frameDefinition; - } - - @Override - public FrameDefinition visitAnonymousCompSubTypeDefinitionWithChildren( - final AnonymousCompSubTypeDefinitionWithChildrenContext ctx) { - final String parent = unquote(ctx.STRING_LITERAL().getText()); - final FrameClass frameClass = FrameClass.valueOf(ctx.frame_type_qualifier().getText()); - final FrameDefinition frameDefinition = new FrameDefinition(frameClass, null, null); - // INHERITS - final FrameDefinition inheritParent = this.templates.getFrame(parent); - if (inheritParent == null) { - throw new IllegalStateException( - "" + frameClass + " cannot inherit from \"" + parent + "\" because it does not exist!"); - } - frameDefinition.inheritFrom(inheritParent, true); - - final FrameDefinitionFieldVisitor fieldVisitor = new FrameDefinitionFieldVisitor(frameDefinition, this); - for (final Frame_elementContext element : ctx.frame_element()) { - fieldVisitor.visit(element); - } - return frameDefinition; - } - - @Override - public FrameDefinition visitCompDefinition(final CompDefinitionContext ctx) { - final String name = unquote(ctx.STRING_LITERAL().getText()); - final FrameDefinition frameDefinition = new FrameDefinition( - FrameClass.valueOf(ctx.frame_type_qualifier().getText()), null, name); - final FrameDefinitionFieldVisitor fieldVisitor = new FrameDefinitionFieldVisitor(frameDefinition, this); - for (final Frame_elementContext element : ctx.frame_element()) { - fieldVisitor.visit(element); - } - this.templates.put(name, frameDefinition); - return frameDefinition; - } - - @Override - public FrameDefinition visitCompSubTypeDefinition(final CompSubTypeDefinitionContext ctx) { - final String name = unquote(ctx.STRING_LITERAL(0).getText()); - final String parent = unquote(ctx.STRING_LITERAL(1).getText()); - final FrameDefinition frameDefinition = new FrameDefinition( - FrameClass.valueOf(ctx.frame_type_qualifier().getText()), null, name); - // INHERITS - final FrameDefinition inheritParent = this.templates.getFrame(parent); - if (inheritParent == null) { - throw new IllegalStateException( - "\"" + name + "\" cannot inherit from \"" + parent + "\" because it does not exist!"); - } - frameDefinition.inheritFrom(inheritParent, false); - - final FrameDefinitionFieldVisitor fieldVisitor = new FrameDefinitionFieldVisitor(frameDefinition, this); - for (final Frame_elementContext element : ctx.frame_element()) { - fieldVisitor.visit(element); - } - this.templates.put(name, frameDefinition); - return frameDefinition; - } - - @Override - public FrameDefinition visitCompSubTypeDefinitionWithChildren(final CompSubTypeDefinitionWithChildrenContext ctx) { - final String name = unquote(ctx.STRING_LITERAL(0).getText()); - final String parent = unquote(ctx.STRING_LITERAL(1).getText()); - final FrameDefinition frameDefinition = new FrameDefinition( - FrameClass.valueOf(ctx.frame_type_qualifier().getText()), null, name); - // INHERITS - final FrameDefinition inheritParent = this.templates.getFrame(parent); - if (inheritParent == null) { - throw new IllegalStateException( - "\"" + name + "\" cannot inherit from \"" + parent + "\" because it does not exist!"); - } - frameDefinition.inheritFrom(inheritParent, true); - - final FrameDefinitionFieldVisitor fieldVisitor = new FrameDefinitionFieldVisitor(frameDefinition, this); - for (final Frame_elementContext element : ctx.frame_element()) { - fieldVisitor.visit(element); - } - this.templates.put(name, frameDefinition); - return frameDefinition; - } -} diff --git a/fdfparser/src/com/etheller/warsmash/fdfparser/Main.java b/fdfparser/src/com/etheller/warsmash/fdfparser/Main.java deleted file mode 100644 index c2c4f81e..00000000 --- a/fdfparser/src/com/etheller/warsmash/fdfparser/Main.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.etheller.warsmash.fdfparser; - -import org.antlr.v4.runtime.BaseErrorListener; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; - -import com.etheller.warsmash.parsers.fdf.datamodel.FrameDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.FrameTemplateEnvironment; - -public class Main { - public static final boolean REPORT_SYNTAX_ERRORS = true; - - public static void main(final String[] args) { - if (args.length < 1) { - System.err.println("Usage: "); - return; - } - try { - final BaseErrorListener errorListener = new BaseErrorListener() { - @Override - public void syntaxError(final Recognizer recognizer, final Object offendingSymbol, final int line, - final int charPositionInLine, final String msg, final RecognitionException e) { - if (!REPORT_SYNTAX_ERRORS) { - return; - } - - String sourceName = recognizer.getInputStream().getSourceName(); - if (!sourceName.isEmpty()) { - sourceName = String.format("%s:%d:%d: ", sourceName, line, charPositionInLine); - } - - System.err.println(sourceName + "line " + line + ":" + charPositionInLine + " " + msg); - } - }; - final FrameTemplateEnvironment templates = new FrameTemplateEnvironment(); - final TestFDFParserBuilder testFDFParserBuilder = new TestFDFParserBuilder(errorListener); - final FrameDefinitionVisitor fdfVisitor = new FrameDefinitionVisitor(templates, testFDFParserBuilder); - final FDFParser firstFileParser = testFDFParserBuilder.build(args[0]); - fdfVisitor.visit(firstFileParser.program()); - final FrameDefinition bnetChat = templates.getFrame("BattleNetTextAreaTemplate"); - System.out.println("Value of BattleNetTextAreaTemplate: " + bnetChat); - } - catch (final Exception exc) { - System.err.println(exc.getMessage()); - } - } - -} diff --git a/fdfparser/src/com/etheller/warsmash/fdfparser/TestFDFParserBuilder.java b/fdfparser/src/com/etheller/warsmash/fdfparser/TestFDFParserBuilder.java deleted file mode 100644 index df363f1d..00000000 --- a/fdfparser/src/com/etheller/warsmash/fdfparser/TestFDFParserBuilder.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.etheller.warsmash.fdfparser; - -import java.io.IOException; - -import org.antlr.v4.runtime.BaseErrorListener; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; - -public class TestFDFParserBuilder implements FDFParserBuilder { - private final BaseErrorListener errorListener; - - public TestFDFParserBuilder(final BaseErrorListener errorListener) { - this.errorListener = errorListener; - } - - @Override - public FDFParser build(final String path) { - FDFLexer lexer; - try { - lexer = new FDFLexer(CharStreams.fromFileName(path)); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return new FDFParser(new CommonTokenStream(lexer)); - } -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/AnchorDefinition.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/AnchorDefinition.java deleted file mode 100644 index 13852236..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/AnchorDefinition.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -public class AnchorDefinition { - private final FramePoint myPoint; - private final float x; - private final float y; - - public AnchorDefinition(final FramePoint myPoint, final float x, final float y) { - this.myPoint = myPoint; - this.x = x; - this.y = y; - } - - public FramePoint getMyPoint() { - return this.myPoint; - } - - public float getX() { - return this.x; - } - - public float getY() { - return this.y; - } - - @Override - public String toString() { - return "AnchorDefinition [myPoint=" + this.myPoint + ", x=" + this.x + ", y=" + this.y + "]"; - } -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/BackdropCornerFlags.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/BackdropCornerFlags.java deleted file mode 100644 index 116f9397..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/BackdropCornerFlags.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -import java.util.EnumSet; - -public enum BackdropCornerFlags { - UL, - UR, - BL, - BR, - T, - L, - B, - R; - - public static EnumSet parseCornerFlags(final String cornerFlags) { - final EnumSet set = EnumSet.noneOf(BackdropCornerFlags.class); - for (final String flag : cornerFlags.split("\\|")) { - if (!"".equals(flag)) { - set.add(BackdropCornerFlags.valueOf(flag)); - } - } - return set; - } -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/ControlStyle.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/ControlStyle.java deleted file mode 100644 index 8762a24d..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/ControlStyle.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -import java.util.EnumSet; - -public enum ControlStyle { - AUTOTRACK, - HIGHLIGHTONFOCUS, - HIGHLIGHTONMOUSEOVER; - - public static EnumSet parseControlStyle(final String controlStyles) { - final EnumSet set = EnumSet.noneOf(ControlStyle.class); - for (final String flag : controlStyles.split("\\|")) { - if (!"".equals(flag)) { - set.add(ControlStyle.valueOf(flag)); - } - } - return set; - } -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FontDefinition.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FontDefinition.java deleted file mode 100644 index 4f0b0f8b..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FontDefinition.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -public class FontDefinition { - private final String fontName; - private final float fontSize; - private final String extra; - - public FontDefinition(final String fontName, final float fontSize, final String extra) { - this.fontName = fontName; - this.fontSize = fontSize; - this.extra = extra; - } - - public String getFontName() { - return this.fontName; - } - - public float getFontSize() { - return this.fontSize; - } - - public String getExtra() { - return this.extra; - } -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FontFlags.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FontFlags.java deleted file mode 100644 index 99fef405..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FontFlags.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -public enum FontFlags { - FIXEDSIZE; -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameClass.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameClass.java deleted file mode 100644 index ad624083..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameClass.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -public enum FrameClass { - Frame, - String, - Texture, - Layer; -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameDefinition.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameDefinition.java deleted file mode 100644 index 14ecf1de..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameDefinition.java +++ /dev/null @@ -1,163 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringPairFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.visitor.GetFloatFieldVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.visitor.GetFontFieldVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.visitor.GetStringFieldVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.visitor.GetStringPairFieldVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.visitor.GetTextJustifyFieldVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.visitor.GetVector2FieldVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.visitor.GetVector4FieldVisitor; - -/** - * Pretty sure this is probably not how it works in-game but this silly - * everything class might help get a prototype running fast until I have a - * better understanding of how I want these classes designed. - */ -public class FrameDefinition { - private final FrameClass frameClass; - private final String frameType; - private final String name; - private final List innerFrames = new ArrayList<>(); - private final Set flags = new HashSet<>(); - private final Map nameToField = new HashMap<>(); - private final List setPoints = new ArrayList<>(); - private final List anchors = new ArrayList<>(); - - public FrameDefinition(final FrameClass frameClass, final String frameType, final String name) { - this.frameClass = frameClass; - this.frameType = frameType; - this.name = name; - } - - public void inheritFrom(final FrameDefinition other, final boolean withChildren) { - this.flags.addAll(other.flags); - this.nameToField.putAll(other.nameToField); - if (withChildren) { - this.innerFrames.addAll(other.innerFrames); - } - } - - public void set(final String fieldName, final FrameDefinitionField value) { - this.nameToField.put(fieldName, value); - } - - public void add(final FrameDefinition childDefition) { - this.innerFrames.add(childDefition); - } - - public void add(final SetPointDefinition setPointDefinition) { - this.setPoints.add(setPointDefinition); - } - - public void add(final AnchorDefinition anchorDefinition) { - this.anchors.add(anchorDefinition); - } - - public void add(final String flag) { - this.flags.add(flag); - } - - public boolean has(final String flag) { - return this.flags.contains(flag); - } - - public FrameDefinitionField get(final String fieldName) { - return this.nameToField.get(fieldName); - } - - @Override - public String toString() { - return "FrameDefinition [frameClass=" + this.frameClass + ", frameType=" + this.frameType + ", name=" - + this.name + ", innerFrames=" + this.innerFrames + ", flags=" + this.flags + ", nameToField=" - + this.nameToField + ", setPoints=" + this.setPoints + ", anchors=" + this.anchors + "]"; - } - - public String getFrameType() { - return this.frameType; - } - - public String getName() { - return this.name; - } - - public FrameClass getFrameClass() { - return this.frameClass; - } - - public List getInnerFrames() { - return this.innerFrames; - } - - public List getAnchors() { - return this.anchors; - } - - public List getSetPoints() { - return this.setPoints; - } - - public String getString(final String id) { - final FrameDefinitionField frameDefinitionField = this.nameToField.get(id); - if (frameDefinitionField != null) { - return frameDefinitionField.visit(GetStringFieldVisitor.INSTANCE); - } - return null; - } - - public StringPairFrameDefinitionField getStringPair(final String id) { - final FrameDefinitionField frameDefinitionField = this.nameToField.get(id); - if (frameDefinitionField != null) { - return frameDefinitionField.visit(GetStringPairFieldVisitor.INSTANCE); - } - return null; - } - - public Float getFloat(final String id) { - final FrameDefinitionField frameDefinitionField = this.nameToField.get(id); - if (frameDefinitionField != null) { - return frameDefinitionField.visit(GetFloatFieldVisitor.INSTANCE); - } - return null; - } - - public Vector4Definition getVector4(final String id) { - final FrameDefinitionField frameDefinitionField = this.nameToField.get(id); - if (frameDefinitionField != null) { - return frameDefinitionField.visit(GetVector4FieldVisitor.INSTANCE); - } - return null; - } - - public Vector2Definition getVector2(final String id) { - final FrameDefinitionField frameDefinitionField = this.nameToField.get(id); - if (frameDefinitionField != null) { - return frameDefinitionField.visit(GetVector2FieldVisitor.INSTANCE); - } - return null; - } - - public FontDefinition getFont(final String id) { - final FrameDefinitionField frameDefinitionField = this.nameToField.get(id); - if (frameDefinitionField != null) { - return frameDefinitionField.visit(GetFontFieldVisitor.INSTANCE); - } - return null; - } - - public TextJustify getTextJustify(final String id) { - final FrameDefinitionField frameDefinitionField = this.nameToField.get(id); - if (frameDefinitionField != null) { - return frameDefinitionField.visit(GetTextJustifyFieldVisitor.INSTANCE); - } - return null; - } -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameEvent.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameEvent.java deleted file mode 100644 index 3e4472bd..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameEvent.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -public enum FrameEvent { - CONTROL_CLICK, - MOUSE_ENTER, - MOUSE_LEAVE, - MOUSE_UP, - MOUSE_DOWN, - MOUSE_WHEEL, - CHECKBOX_CHECKED, - CHECKBOX_UNCHECKED, - EDITBOX_TEXT_CHANGED, - POPUPMENU_ITEM_CHANGED, - MOUSE_DOUBLECLICK, - SPRITE_ANIM_UPDATE, - SLIDER_VALUE_CHANGED, - DIALOG_CANCEL, - DIALOG_ACCEPT, - EDITBOX_ENTER -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FramePoint.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FramePoint.java deleted file mode 100644 index 2a9229ac..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FramePoint.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -public enum FramePoint { - TOPLEFT, - TOP, - TOPRIGHT, - LEFT, - CENTER, - RIGHT, - BOTTOMLEFT, - BOTTOM, - BOTTOMRIGHT; -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameTemplateEnvironment.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameTemplateEnvironment.java deleted file mode 100644 index ba9da1b3..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/FrameTemplateEnvironment.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -import java.util.HashMap; -import java.util.Map; - -public class FrameTemplateEnvironment { - private final Map idToDecoratedString = new HashMap<>(); - private final Map idToFrame = new HashMap<>(); - - public void addDecoratedString(final String id, final String value) { - this.idToDecoratedString.put(id, value); - } - - public String getDecoratedString(final String id) { - final String decoratedString = this.idToDecoratedString.get(id); - if (decoratedString != null) { - return decoratedString; - } - return id; - } - - public void put(final String id, final FrameDefinition frame) { - this.idToFrame.put(id, frame); - } - - public FrameDefinition getFrame(final String id) { - return this.idToFrame.get(id); - } -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/HighlightAlphaMode.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/HighlightAlphaMode.java deleted file mode 100644 index 4766c429..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/HighlightAlphaMode.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -public enum HighlightAlphaMode { - ADD; -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/HighlightType.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/HighlightType.java deleted file mode 100644 index f03ce4a3..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/HighlightType.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -public enum HighlightType { - FILETEXTURE; -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/SetPointDefinition.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/SetPointDefinition.java deleted file mode 100644 index bbfbe0bb..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/SetPointDefinition.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -public class SetPointDefinition { - private final FramePoint myPoint; - private final String other; - private final FramePoint otherPoint; - private final float x; - private final float y; - - public SetPointDefinition(final FramePoint myPoint, final String other, final FramePoint otherPoint, final float x, - final float y) { - this.myPoint = myPoint; - this.other = other; - this.otherPoint = otherPoint; - this.x = x; - this.y = y; - } - - public FramePoint getMyPoint() { - return this.myPoint; - } - - public String getOther() { - return this.other; - } - - public FramePoint getOtherPoint() { - return this.otherPoint; - } - - public float getX() { - return this.x; - } - - public float getY() { - return this.y; - } -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/TextJustify.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/TextJustify.java deleted file mode 100644 index ae305911..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/TextJustify.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -public enum TextJustify { - TOP, - MIDDLE, - BOTTOM, - LEFT, - CENTER, - RIGHT; -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/Vector2Definition.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/Vector2Definition.java deleted file mode 100644 index 209ce72e..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/Vector2Definition.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -public class Vector2Definition { - private float x; - private float y; - - public Vector2Definition(final float x, final float y) { - this.x = x; - this.y = y; - } - - public float getX() { - return this.x; - } - - public float getY() { - return this.y; - } - - public void setX(final float x) { - this.x = x; - } - - public void setY(final float y) { - this.y = y; - } - -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/Vector3Definition.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/Vector3Definition.java deleted file mode 100644 index 22aa15df..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/Vector3Definition.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -public class Vector3Definition { - private final float x, y, z; - - public Vector3Definition(final float x, final float y, final float z) { - this.x = x; - this.y = y; - this.z = z; - } - - public float getX() { - return this.x; - } - - public float getY() { - return this.y; - } - - public float getZ() { - return this.z; - } -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/Vector4Definition.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/Vector4Definition.java deleted file mode 100644 index 1ea78faf..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/Vector4Definition.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel; - -public class Vector4Definition { - private float x, y, z, w; - - public Vector4Definition(final float x, final float y, final float z, final float w) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - } - - public float getX() { - return this.x; - } - - public float getY() { - return this.y; - } - - public float getZ() { - return this.z; - } - - public float getW() { - return this.w; - } - - public void setX(final float x) { - this.x = x; - } - - public void setY(final float y) { - this.y = y; - } - - public void setZ(final float z) { - this.z = z; - } - - public void setW(final float w) { - this.w = w; - } - - public void set(final float x2, final float y2, final float z2, final float w2) { - this.x = x2; - this.y = y2; - this.z = z2; - this.w = w2; - - } -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FloatFrameDefinitionField.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FloatFrameDefinitionField.java deleted file mode 100644 index 52188333..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FloatFrameDefinitionField.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields; - -public class FloatFrameDefinitionField implements FrameDefinitionField { - private final float value; - - public FloatFrameDefinitionField(final float value) { - this.value = value; - } - - public float getValue() { - return this.value; - } - - @Override - public TYPE visit(final FrameDefinitionFieldVisitor visitor) { - return visitor.accept(this); - } - -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FontFrameDefinitionField.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FontFrameDefinitionField.java deleted file mode 100644 index d6ca65cd..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FontFrameDefinitionField.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields; - -import com.etheller.warsmash.parsers.fdf.datamodel.FontDefinition; - -public class FontFrameDefinitionField implements FrameDefinitionField { - private final FontDefinition value; - - public FontFrameDefinitionField(final FontDefinition value) { - this.value = value; - } - - public FontDefinition getValue() { - return this.value; - } - - @Override - public TYPE visit(final FrameDefinitionFieldVisitor visitor) { - return visitor.accept(this); - } - -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FrameDefinitionField.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FrameDefinitionField.java deleted file mode 100644 index f0b84ee7..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FrameDefinitionField.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields; - -public interface FrameDefinitionField { - TYPE visit(FrameDefinitionFieldVisitor visitor); -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FrameDefinitionFieldVisitor.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FrameDefinitionFieldVisitor.java deleted file mode 100644 index 10495106..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/FrameDefinitionFieldVisitor.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields; - -public interface FrameDefinitionFieldVisitor { - TYPE accept(StringFrameDefinitionField field); - - TYPE accept(StringPairFrameDefinitionField field); - - TYPE accept(FloatFrameDefinitionField field); - - TYPE accept(Vector3FrameDefinitionField field); - - TYPE accept(Vector4FrameDefinitionField field); - - TYPE accept(Vector2FrameDefinitionField field); - - TYPE accept(FontFrameDefinitionField field); - - TYPE accept(TextJustifyFrameDefinitionField field); -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/StringFrameDefinitionField.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/StringFrameDefinitionField.java deleted file mode 100644 index c2c903e0..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/StringFrameDefinitionField.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields; - -public class StringFrameDefinitionField implements FrameDefinitionField { - private final String value; - - public StringFrameDefinitionField(final String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } - - @Override - public TYPE visit(final FrameDefinitionFieldVisitor visitor) { - return visitor.accept(this); - } -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/StringPairFrameDefinitionField.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/StringPairFrameDefinitionField.java deleted file mode 100644 index 9cf192b0..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/StringPairFrameDefinitionField.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields; - -public class StringPairFrameDefinitionField implements FrameDefinitionField { - private final String first; - private final String second; - - public StringPairFrameDefinitionField(final String first, final String second) { - this.first = first; - this.second = second; - } - - public String getFirst() { - return this.first; - } - - public String getSecond() { - return this.second; - } - - @Override - public TYPE visit(final FrameDefinitionFieldVisitor visitor) { - return visitor.accept(this); - } -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/TextJustifyFrameDefinitionField.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/TextJustifyFrameDefinitionField.java deleted file mode 100644 index c0aa2951..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/TextJustifyFrameDefinitionField.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields; - -import com.etheller.warsmash.parsers.fdf.datamodel.TextJustify; - -public class TextJustifyFrameDefinitionField implements FrameDefinitionField { - private final TextJustify value; - - public TextJustifyFrameDefinitionField(final TextJustify value) { - this.value = value; - } - - public TextJustify getValue() { - return this.value; - } - - @Override - public TYPE visit(final FrameDefinitionFieldVisitor visitor) { - return visitor.accept(this); - } - -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/Vector2FrameDefinitionField.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/Vector2FrameDefinitionField.java deleted file mode 100644 index e07f7987..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/Vector2FrameDefinitionField.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields; - -import com.etheller.warsmash.parsers.fdf.datamodel.Vector2Definition; - -public class Vector2FrameDefinitionField implements FrameDefinitionField { - private final Vector2Definition value; - - public Vector2FrameDefinitionField(final Vector2Definition value) { - this.value = value; - } - - public Vector2Definition getValue() { - return this.value; - } - - @Override - public TYPE visit(final FrameDefinitionFieldVisitor visitor) { - return visitor.accept(this); - } -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/Vector3FrameDefinitionField.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/Vector3FrameDefinitionField.java deleted file mode 100644 index da09089a..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/Vector3FrameDefinitionField.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields; - -import com.etheller.warsmash.parsers.fdf.datamodel.Vector3Definition; - -public class Vector3FrameDefinitionField implements FrameDefinitionField { - private final Vector3Definition value; - - public Vector3FrameDefinitionField(final Vector3Definition value) { - this.value = value; - } - - public Vector3Definition getValue() { - return this.value; - } - - @Override - public TYPE visit(final FrameDefinitionFieldVisitor visitor) { - return visitor.accept(this); - } - -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/Vector4FrameDefinitionField.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/Vector4FrameDefinitionField.java deleted file mode 100644 index 94bc3b6d..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/Vector4FrameDefinitionField.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields; - -import com.etheller.warsmash.parsers.fdf.datamodel.Vector4Definition; - -public class Vector4FrameDefinitionField implements FrameDefinitionField { - private final Vector4Definition value; - - public Vector4FrameDefinitionField(final Vector4Definition value) { - this.value = value; - } - - public Vector4Definition getValue() { - return this.value; - } - - @Override - public TYPE visit(final FrameDefinitionFieldVisitor visitor) { - return visitor.accept(this); - } -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetFloatFieldVisitor.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetFloatFieldVisitor.java deleted file mode 100644 index 38a30843..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetFloatFieldVisitor.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields.visitor; - -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FloatFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FontFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FrameDefinitionFieldVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringPairFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.TextJustifyFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector2FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector3FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector4FrameDefinitionField; - -public class GetFloatFieldVisitor implements FrameDefinitionFieldVisitor { - public static GetFloatFieldVisitor INSTANCE = new GetFloatFieldVisitor(); - - @Override - public Float accept(final StringFrameDefinitionField field) { - return null; - } - - @Override - public Float accept(final StringPairFrameDefinitionField field) { - return null; - } - - @Override - public Float accept(final FloatFrameDefinitionField field) { - return field.getValue(); - } - - @Override - public Float accept(final Vector3FrameDefinitionField field) { - return null; - } - - @Override - public Float accept(final Vector4FrameDefinitionField field) { - return null; - } - - @Override - public Float accept(final Vector2FrameDefinitionField field) { - return null; - } - - @Override - public Float accept(final FontFrameDefinitionField field) { - return null; - } - - @Override - public Float accept(final TextJustifyFrameDefinitionField field) { - return null; - } - -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetFontFieldVisitor.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetFontFieldVisitor.java deleted file mode 100644 index 44f9ece0..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetFontFieldVisitor.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields.visitor; - -import com.etheller.warsmash.parsers.fdf.datamodel.FontDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FloatFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FontFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FrameDefinitionFieldVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringPairFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.TextJustifyFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector2FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector3FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector4FrameDefinitionField; - -public class GetFontFieldVisitor implements FrameDefinitionFieldVisitor { - public static GetFontFieldVisitor INSTANCE = new GetFontFieldVisitor(); - - @Override - public FontDefinition accept(final StringFrameDefinitionField field) { - return null; - } - - @Override - public FontDefinition accept(final StringPairFrameDefinitionField field) { - return null; - } - - @Override - public FontDefinition accept(final FloatFrameDefinitionField field) { - return null; - } - - @Override - public FontDefinition accept(final Vector3FrameDefinitionField field) { - return null; - } - - @Override - public FontDefinition accept(final Vector4FrameDefinitionField field) { - return null; - } - - @Override - public FontDefinition accept(final Vector2FrameDefinitionField field) { - return null; - } - - @Override - public FontDefinition accept(final FontFrameDefinitionField field) { - return field.getValue(); - } - - @Override - public FontDefinition accept(final TextJustifyFrameDefinitionField field) { - return null; - } - -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetStringFieldVisitor.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetStringFieldVisitor.java deleted file mode 100644 index b90b83d8..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetStringFieldVisitor.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields.visitor; - -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FloatFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FontFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FrameDefinitionFieldVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringPairFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.TextJustifyFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector2FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector3FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector4FrameDefinitionField; - -public class GetStringFieldVisitor implements FrameDefinitionFieldVisitor { - public static GetStringFieldVisitor INSTANCE = new GetStringFieldVisitor(); - - @Override - public String accept(final StringFrameDefinitionField field) { - return field.getValue(); - } - - @Override - public String accept(final StringPairFrameDefinitionField field) { - return null; - } - - @Override - public String accept(final FloatFrameDefinitionField field) { - return null; - } - - @Override - public String accept(final Vector3FrameDefinitionField field) { - return null; - } - - @Override - public String accept(final Vector4FrameDefinitionField field) { - return null; - } - - @Override - public String accept(final Vector2FrameDefinitionField field) { - return null; - } - - @Override - public String accept(final FontFrameDefinitionField field) { - return null; - } - - @Override - public String accept(final TextJustifyFrameDefinitionField field) { - return null; - } - -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetStringPairFieldVisitor.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetStringPairFieldVisitor.java deleted file mode 100644 index 0b9f34c7..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetStringPairFieldVisitor.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields.visitor; - -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FloatFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FontFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FrameDefinitionFieldVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringPairFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.TextJustifyFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector2FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector3FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector4FrameDefinitionField; - -public class GetStringPairFieldVisitor implements FrameDefinitionFieldVisitor { - public static GetStringPairFieldVisitor INSTANCE = new GetStringPairFieldVisitor(); - - @Override - public StringPairFrameDefinitionField accept(final StringFrameDefinitionField field) { - return null; - } - - @Override - public StringPairFrameDefinitionField accept(final StringPairFrameDefinitionField field) { - return field; - } - - @Override - public StringPairFrameDefinitionField accept(final FloatFrameDefinitionField field) { - return null; - } - - @Override - public StringPairFrameDefinitionField accept(final Vector3FrameDefinitionField field) { - return null; - } - - @Override - public StringPairFrameDefinitionField accept(final Vector4FrameDefinitionField field) { - return null; - } - - @Override - public StringPairFrameDefinitionField accept(final Vector2FrameDefinitionField field) { - return null; - } - - @Override - public StringPairFrameDefinitionField accept(final FontFrameDefinitionField field) { - return null; - } - - @Override - public StringPairFrameDefinitionField accept(final TextJustifyFrameDefinitionField field) { - return null; - } - -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetTextJustifyFieldVisitor.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetTextJustifyFieldVisitor.java deleted file mode 100644 index bb45533d..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetTextJustifyFieldVisitor.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields.visitor; - -import com.etheller.warsmash.parsers.fdf.datamodel.TextJustify; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FloatFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FontFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FrameDefinitionFieldVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringPairFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.TextJustifyFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector2FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector3FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector4FrameDefinitionField; - -public class GetTextJustifyFieldVisitor implements FrameDefinitionFieldVisitor { - public static GetTextJustifyFieldVisitor INSTANCE = new GetTextJustifyFieldVisitor(); - - @Override - public TextJustify accept(final StringFrameDefinitionField field) { - return null; - } - - @Override - public TextJustify accept(final StringPairFrameDefinitionField field) { - return null; - } - - @Override - public TextJustify accept(final FloatFrameDefinitionField field) { - return null; - } - - @Override - public TextJustify accept(final Vector3FrameDefinitionField field) { - return null; - } - - @Override - public TextJustify accept(final Vector4FrameDefinitionField field) { - return null; - } - - @Override - public TextJustify accept(final Vector2FrameDefinitionField field) { - return null; - } - - @Override - public TextJustify accept(final FontFrameDefinitionField field) { - return null; - } - - @Override - public TextJustify accept(final TextJustifyFrameDefinitionField field) { - return field.getValue(); - } - -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetVector2FieldVisitor.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetVector2FieldVisitor.java deleted file mode 100644 index e49490d6..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetVector2FieldVisitor.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields.visitor; - -import com.etheller.warsmash.parsers.fdf.datamodel.Vector2Definition; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FloatFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FontFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FrameDefinitionFieldVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringPairFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.TextJustifyFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector2FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector3FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector4FrameDefinitionField; - -public class GetVector2FieldVisitor implements FrameDefinitionFieldVisitor { - public static GetVector2FieldVisitor INSTANCE = new GetVector2FieldVisitor(); - - @Override - public Vector2Definition accept(final StringFrameDefinitionField field) { - return null; - } - - @Override - public Vector2Definition accept(final StringPairFrameDefinitionField field) { - return null; - } - - @Override - public Vector2Definition accept(final FloatFrameDefinitionField field) { - return null; - } - - @Override - public Vector2Definition accept(final Vector3FrameDefinitionField field) { - return null; - } - - @Override - public Vector2Definition accept(final Vector2FrameDefinitionField field) { - return field.getValue(); - } - - @Override - public Vector2Definition accept(final Vector4FrameDefinitionField field) { - return null; - } - - @Override - public Vector2Definition accept(final FontFrameDefinitionField field) { - return null; - } - - @Override - public Vector2Definition accept(final TextJustifyFrameDefinitionField field) { - return null; - } - -} diff --git a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetVector4FieldVisitor.java b/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetVector4FieldVisitor.java deleted file mode 100644 index 7bc33c76..00000000 --- a/fdfparser/src/com/etheller/warsmash/parsers/fdf/datamodel/fields/visitor/GetVector4FieldVisitor.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.datamodel.fields.visitor; - -import com.etheller.warsmash.parsers.fdf.datamodel.Vector4Definition; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FloatFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FontFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.FrameDefinitionFieldVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringPairFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.TextJustifyFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector2FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector3FrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.Vector4FrameDefinitionField; - -public class GetVector4FieldVisitor implements FrameDefinitionFieldVisitor { - public static GetVector4FieldVisitor INSTANCE = new GetVector4FieldVisitor(); - - @Override - public Vector4Definition accept(final StringFrameDefinitionField field) { - return null; - } - - @Override - public Vector4Definition accept(final StringPairFrameDefinitionField field) { - return null; - } - - @Override - public Vector4Definition accept(final FloatFrameDefinitionField field) { - return null; - } - - @Override - public Vector4Definition accept(final Vector3FrameDefinitionField field) { - return null; - } - - @Override - public Vector4Definition accept(final Vector4FrameDefinitionField field) { - return field.getValue(); - } - - @Override - public Vector4Definition accept(final Vector2FrameDefinitionField field) { - return null; - } - - @Override - public Vector4Definition accept(final FontFrameDefinitionField field) { - return null; - } - - @Override - public Vector4Definition accept(final TextJustifyFrameDefinitionField field) { - return null; - } - -} From d6cfabeb2825e56cafc1cef485c7043ae185f8ae Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:02:05 +0200 Subject: [PATCH 14/17] Delete desktop directory --- desktop/build.gradle | 62 --- .../gdx/backends/lwjgl/LwjglApplication.java | 487 ---------------- .../gdx/backends/lwjgl/LwjglCanvas.java | 501 ----------------- .../src/com/etheller/warsmash/audio/Flac.java | 195 ------- .../audio/JavaSoundAudioRecorder.java | 66 --- .../src/com/etheller/warsmash/audio/Mp3.java | 163 ------ .../src/com/etheller/warsmash/audio/Ogg.java | 89 --- .../warsmash/audio/OggInputStream.java | 520 ------------------ .../etheller/warsmash/audio/OpenALAudio.java | 479 ---------------- .../warsmash/audio/OpenALAudioDevice.java | 265 --------- .../etheller/warsmash/audio/OpenALMusic.java | 396 ------------- .../etheller/warsmash/audio/OpenALSound.java | 249 --------- .../src/com/etheller/warsmash/audio/Wav.java | 201 ------- .../warsmash/desktop/DesktopLauncher.java | 248 --------- .../desktop/editor/mdx/MdxEditorMain.java | 33 -- .../mdx/listeners/YseraGUIListener.java | 29 - .../mdx/ui/AnimationControllerFrame.java | 30 - .../mdx/ui/AnimationControllerPanel.java | 210 ------- .../desktop/editor/mdx/ui/YseraFrame.java | 64 --- .../desktop/editor/mdx/ui/YseraPanel.java | 193 ------- .../desktop/editor/util/ExceptionPopup.java | 84 --- .../warsmash/desktop/util/TerrainView.java | 36 -- .../desktop/util/TerrainViewPanel.java | 93 ---- .../io/nayuki/flac/app/DecodeFlacToWav.java | 141 ----- .../io/nayuki/flac/app/EncodeWavToFlac.java | 176 ------ .../flac/app/SeekableFlacPlayerGui.java | 236 -------- .../io/nayuki/flac/app/ShowFlacFileStats.java | 277 ---------- .../src/io/nayuki/flac/common/FrameInfo.java | 456 --------------- .../src/io/nayuki/flac/common/SeekTable.java | 204 ------- .../src/io/nayuki/flac/common/StreamInfo.java | 310 ----------- .../decode/AbstractFlacLowLevelInput.java | 354 ------------ .../flac/decode/ByteArrayFlacInput.java | 86 --- .../flac/decode/DataFormatException.java | 47 -- .../io/nayuki/flac/decode/FlacDecoder.java | 337 ------------ .../nayuki/flac/decode/FlacLowLevelInput.java | 129 ----- .../io/nayuki/flac/decode/FrameDecoder.java | 387 ------------- .../flac/decode/SeekableFileFlacInput.java | 83 --- .../flac/encode/AdvancedFlacEncoder.java | 115 ---- .../nayuki/flac/encode/BitOutputStream.java | 174 ------ .../nayuki/flac/encode/ConstantEncoder.java | 79 --- .../io/nayuki/flac/encode/FastDotProduct.java | 97 ---- .../flac/encode/FixedPredictionEncoder.java | 85 --- .../io/nayuki/flac/encode/FlacEncoder.java | 67 --- .../io/nayuki/flac/encode/FrameEncoder.java | 174 ------ .../flac/encode/LinearPredictiveEncoder.java | 277 ---------- .../encode/RandomAccessFileOutputStream.java | 81 --- .../io/nayuki/flac/encode/RiceEncoder.java | 216 -------- .../io/nayuki/flac/encode/SizeEstimate.java | 61 -- .../nayuki/flac/encode/SubframeEncoder.java | 247 --------- .../nayuki/flac/encode/VerbatimEncoder.java | 58 -- 50 files changed, 9647 deletions(-) delete mode 100644 desktop/build.gradle delete mode 100644 desktop/src/com/badlogic/gdx/backends/lwjgl/LwjglApplication.java delete mode 100644 desktop/src/com/badlogic/gdx/backends/lwjgl/LwjglCanvas.java delete mode 100644 desktop/src/com/etheller/warsmash/audio/Flac.java delete mode 100644 desktop/src/com/etheller/warsmash/audio/JavaSoundAudioRecorder.java delete mode 100644 desktop/src/com/etheller/warsmash/audio/Mp3.java delete mode 100644 desktop/src/com/etheller/warsmash/audio/Ogg.java delete mode 100644 desktop/src/com/etheller/warsmash/audio/OggInputStream.java delete mode 100644 desktop/src/com/etheller/warsmash/audio/OpenALAudio.java delete mode 100644 desktop/src/com/etheller/warsmash/audio/OpenALAudioDevice.java delete mode 100644 desktop/src/com/etheller/warsmash/audio/OpenALMusic.java delete mode 100644 desktop/src/com/etheller/warsmash/audio/OpenALSound.java delete mode 100644 desktop/src/com/etheller/warsmash/audio/Wav.java delete mode 100644 desktop/src/com/etheller/warsmash/desktop/DesktopLauncher.java delete mode 100644 desktop/src/com/etheller/warsmash/desktop/editor/mdx/MdxEditorMain.java delete mode 100644 desktop/src/com/etheller/warsmash/desktop/editor/mdx/listeners/YseraGUIListener.java delete mode 100644 desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/AnimationControllerFrame.java delete mode 100644 desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/AnimationControllerPanel.java delete mode 100644 desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/YseraFrame.java delete mode 100644 desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/YseraPanel.java delete mode 100644 desktop/src/com/etheller/warsmash/desktop/editor/util/ExceptionPopup.java delete mode 100644 desktop/src/com/etheller/warsmash/desktop/util/TerrainView.java delete mode 100644 desktop/src/com/etheller/warsmash/desktop/util/TerrainViewPanel.java delete mode 100644 desktop/src/io/nayuki/flac/app/DecodeFlacToWav.java delete mode 100644 desktop/src/io/nayuki/flac/app/EncodeWavToFlac.java delete mode 100644 desktop/src/io/nayuki/flac/app/SeekableFlacPlayerGui.java delete mode 100644 desktop/src/io/nayuki/flac/app/ShowFlacFileStats.java delete mode 100644 desktop/src/io/nayuki/flac/common/FrameInfo.java delete mode 100644 desktop/src/io/nayuki/flac/common/SeekTable.java delete mode 100644 desktop/src/io/nayuki/flac/common/StreamInfo.java delete mode 100644 desktop/src/io/nayuki/flac/decode/AbstractFlacLowLevelInput.java delete mode 100644 desktop/src/io/nayuki/flac/decode/ByteArrayFlacInput.java delete mode 100644 desktop/src/io/nayuki/flac/decode/DataFormatException.java delete mode 100644 desktop/src/io/nayuki/flac/decode/FlacDecoder.java delete mode 100644 desktop/src/io/nayuki/flac/decode/FlacLowLevelInput.java delete mode 100644 desktop/src/io/nayuki/flac/decode/FrameDecoder.java delete mode 100644 desktop/src/io/nayuki/flac/decode/SeekableFileFlacInput.java delete mode 100644 desktop/src/io/nayuki/flac/encode/AdvancedFlacEncoder.java delete mode 100644 desktop/src/io/nayuki/flac/encode/BitOutputStream.java delete mode 100644 desktop/src/io/nayuki/flac/encode/ConstantEncoder.java delete mode 100644 desktop/src/io/nayuki/flac/encode/FastDotProduct.java delete mode 100644 desktop/src/io/nayuki/flac/encode/FixedPredictionEncoder.java delete mode 100644 desktop/src/io/nayuki/flac/encode/FlacEncoder.java delete mode 100644 desktop/src/io/nayuki/flac/encode/FrameEncoder.java delete mode 100644 desktop/src/io/nayuki/flac/encode/LinearPredictiveEncoder.java delete mode 100644 desktop/src/io/nayuki/flac/encode/RandomAccessFileOutputStream.java delete mode 100644 desktop/src/io/nayuki/flac/encode/RiceEncoder.java delete mode 100644 desktop/src/io/nayuki/flac/encode/SizeEstimate.java delete mode 100644 desktop/src/io/nayuki/flac/encode/SubframeEncoder.java delete mode 100644 desktop/src/io/nayuki/flac/encode/VerbatimEncoder.java diff --git a/desktop/build.gradle b/desktop/build.gradle deleted file mode 100644 index 7e7b0392..00000000 --- a/desktop/build.gradle +++ /dev/null @@ -1,62 +0,0 @@ -apply plugin: "java" - -sourceCompatibility = 1.7 -sourceSets.main.java.srcDirs = [ "src/" ] - -project.ext.mainClassName = "com.etheller.warsmash.desktop.DesktopLauncher" -project.ext.assetsDir = new File("../core/assets"); - -if(project.hasProperty("args")) { - ext.cmdargs = project.getProperty("args") -} else { - ext.cmdargs = "" -} - -task run(dependsOn: classes, type: JavaExec) { - main = project.mainClassName - classpath = sourceSets.main.runtimeClasspath - standardInput = System.in - workingDir = project.assetsDir - ignoreExitValue = true - args cmdargs.split() -} - -task debug(dependsOn: classes, type: JavaExec) { - main = project.mainClassName - classpath = sourceSets.main.runtimeClasspath - standardInput = System.in - workingDir = project.assetsDir - ignoreExitValue = true - debug = true -} - -task dist(type: Jar) { - from files(sourceSets.main.output.classesDir) - from files(sourceSets.main.output.resourcesDir) - from {configurations.compile.collect {zipTree(it)}} - from files(project.assetsDir); - - manifest { - attributes 'Main-Class': project.mainClassName - } -} - -dist.dependsOn classes - -eclipse { - project { - name = appName + "-desktop" - linkedResource name: 'assets', type: '2', location: 'PARENT-1-PROJECT_LOC/core/assets' - } -} - -task afterEclipseImport(description: "Post processing after project generation", group: "IDE") { - doLast { - def classpath = new XmlParser().parse(file(".classpath")) - new Node(classpath, "classpathentry", [ kind: 'src', path: 'assets' ]); - def writer = new FileWriter(file(".classpath")) - def printer = new XmlNodePrinter(new PrintWriter(writer)) - printer.setPreserveWhitespace(true) - printer.print(classpath) - } -} diff --git a/desktop/src/com/badlogic/gdx/backends/lwjgl/LwjglApplication.java b/desktop/src/com/badlogic/gdx/backends/lwjgl/LwjglApplication.java deleted file mode 100644 index 2123195d..00000000 --- a/desktop/src/com/badlogic/gdx/backends/lwjgl/LwjglApplication.java +++ /dev/null @@ -1,487 +0,0 @@ -/******************************************************************************* - * Copyright 2011 See AUTHORS file. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package com.badlogic.gdx.backends.lwjgl; - -import java.awt.Canvas; -import java.io.File; - -import org.lwjgl.LWJGLException; -import org.lwjgl.opengl.Display; - -import com.badlogic.gdx.Application; -import com.badlogic.gdx.ApplicationListener; -import com.badlogic.gdx.ApplicationLogger; -import com.badlogic.gdx.Audio; -import com.badlogic.gdx.Files; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Input; -import com.badlogic.gdx.LifecycleListener; -import com.badlogic.gdx.Net; -import com.badlogic.gdx.Preferences; -import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.Clipboard; -import com.badlogic.gdx.utils.GdxRuntimeException; -import com.badlogic.gdx.utils.ObjectMap; -import com.badlogic.gdx.utils.SnapshotArray; -import com.etheller.warsmash.audio.OpenALAudio; - -/** - * An OpenGL surface fullscreen or in a lightweight window. This was modified by - * Retera in accordance with the permission to do so from the Apache 2.0 license - * listed at the top of the file. The ONLY reason for this modified file - * override currently is to use a replacement for the OpenALAudio class that - * will now support the 3D sound! - */ -public class LwjglApplication implements Application { - protected final LwjglGraphics graphics; - protected OpenALAudio audio; - protected final LwjglFiles files; - protected final LwjglInput input; - protected final LwjglNet net; - protected final ApplicationListener listener; - protected Thread mainLoopThread; - protected boolean running = true; - protected final Array runnables = new Array(); - protected final Array executedRunnables = new Array(); - protected final SnapshotArray lifecycleListeners = new SnapshotArray( - LifecycleListener.class); - protected int logLevel = LOG_INFO; - protected ApplicationLogger applicationLogger; - protected String preferencesdir; - protected Files.FileType preferencesFileType; - - public LwjglApplication(final ApplicationListener listener, final String title, final int width, final int height) { - this(listener, createConfig(title, width, height)); - } - - public LwjglApplication(final ApplicationListener listener) { - this(listener, null, 640, 480); - } - - public LwjglApplication(final ApplicationListener listener, final LwjglApplicationConfiguration config) { - this(listener, config, new LwjglGraphics(config)); - } - - public LwjglApplication(final ApplicationListener listener, final Canvas canvas) { - this(listener, new LwjglApplicationConfiguration(), new LwjglGraphics(canvas)); - } - - public LwjglApplication(final ApplicationListener listener, final LwjglApplicationConfiguration config, - final Canvas canvas) { - this(listener, config, new LwjglGraphics(canvas, config)); - } - - public LwjglApplication(final ApplicationListener listener, final LwjglApplicationConfiguration config, - final LwjglGraphics graphics) { - LwjglNativesLoader.load(); - setApplicationLogger(new LwjglApplicationLogger()); - - if (config.title == null) { - config.title = listener.getClass().getSimpleName(); - } - this.graphics = graphics; - if (!LwjglApplicationConfiguration.disableAudio) { - try { - this.audio = new OpenALAudio(config.audioDeviceSimultaneousSources, config.audioDeviceBufferCount, - config.audioDeviceBufferSize); - } - catch (final Throwable t) { - log("LwjglApplication", "Couldn't initialize audio, disabling audio", t); - LwjglApplicationConfiguration.disableAudio = true; - } - } - this.files = new LwjglFiles(); - this.input = new LwjglInput(); - this.net = new LwjglNet(); - this.listener = listener; - this.preferencesdir = config.preferencesDirectory; - this.preferencesFileType = config.preferencesFileType; - - Gdx.app = this; - Gdx.graphics = graphics; - Gdx.audio = this.audio; - Gdx.files = this.files; - Gdx.input = this.input; - Gdx.net = this.net; - initialize(); - } - - private static LwjglApplicationConfiguration createConfig(final String title, final int width, final int height) { - final LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); - config.title = title; - config.width = width; - config.height = height; - config.vSyncEnabled = true; - return config; - } - - private void initialize() { - this.mainLoopThread = new Thread("LWJGL Application") { - @Override - public void run() { - LwjglApplication.this.graphics.setVSync(LwjglApplication.this.graphics.config.vSyncEnabled); - try { - LwjglApplication.this.mainLoop(); - } - catch (final Throwable t) { - if (LwjglApplication.this.audio != null) { - LwjglApplication.this.audio.dispose(); - } - Gdx.input.setCursorCatched(false); - if (t instanceof RuntimeException) { - throw (RuntimeException) t; - } - else { - throw new GdxRuntimeException(t); - } - } - } - }; - this.mainLoopThread.start(); - } - - void mainLoop() { - final SnapshotArray lifecycleListeners = this.lifecycleListeners; - - try { - this.graphics.setupDisplay(); - } - catch (final LWJGLException e) { - throw new GdxRuntimeException(e); - } - - this.listener.create(); - this.graphics.resize = true; - - int lastWidth = this.graphics.getWidth(); - int lastHeight = this.graphics.getHeight(); - - this.graphics.lastTime = System.nanoTime(); - boolean wasActive = true; - while (this.running) { - Display.processMessages(); - if (Display.isCloseRequested()) { - exit(); - } - - final boolean isActive = Display.isActive(); - if (wasActive && !isActive) { // if it's just recently minimized from active state - wasActive = false; - synchronized (lifecycleListeners) { - final LifecycleListener[] listeners = lifecycleListeners.begin(); - for (int i = 0, n = lifecycleListeners.size; i < n; ++i) { - listeners[i].pause(); - } - lifecycleListeners.end(); - } - this.listener.pause(); - } - if (!wasActive && isActive) { // if it's just recently focused from minimized state - wasActive = true; - synchronized (lifecycleListeners) { - final LifecycleListener[] listeners = lifecycleListeners.begin(); - for (int i = 0, n = lifecycleListeners.size; i < n; ++i) { - listeners[i].resume(); - } - lifecycleListeners.end(); - } - this.listener.resume(); - } - - boolean shouldRender = false; - - if (this.graphics.canvas != null) { - final int width = this.graphics.canvas.getWidth(); - final int height = this.graphics.canvas.getHeight(); - if ((lastWidth != width) || (lastHeight != height)) { - lastWidth = width; - lastHeight = height; - Gdx.gl.glViewport(0, 0, lastWidth, lastHeight); - this.listener.resize(lastWidth, lastHeight); - shouldRender = true; - } - } - else { - this.graphics.config.x = Display.getX(); - this.graphics.config.y = Display.getY(); - if (this.graphics.resize || Display.wasResized() - || ((int) (Display.getWidth() * Display.getPixelScaleFactor()) != this.graphics.config.width) - || ((int) (Display.getHeight() - * Display.getPixelScaleFactor()) != this.graphics.config.height)) { - this.graphics.resize = false; - this.graphics.config.width = (int) (Display.getWidth() * Display.getPixelScaleFactor()); - this.graphics.config.height = (int) (Display.getHeight() * Display.getPixelScaleFactor()); - Gdx.gl.glViewport(0, 0, this.graphics.config.width, this.graphics.config.height); - if (this.listener != null) { - this.listener.resize(this.graphics.config.width, this.graphics.config.height); - } - this.graphics.requestRendering(); - } - } - - if (executeRunnables()) { - shouldRender = true; - } - - // If one of the runnables set running to false, for example after an exit(). - if (!this.running) { - break; - } - - this.input.update(); - shouldRender |= this.graphics.shouldRender(); - this.input.processEvents(); - if (this.audio != null) { - this.audio.update(); - } - - if (!isActive && (this.graphics.config.backgroundFPS == -1)) { - shouldRender = false; - } - int frameRate = isActive ? this.graphics.config.foregroundFPS : this.graphics.config.backgroundFPS; - if (shouldRender) { - this.graphics.updateTime(); - this.graphics.frameId++; - this.listener.render(); - Display.update(false); - } - else { - // Sleeps to avoid wasting CPU in an empty loop. - if (frameRate == -1) { - frameRate = 10; - } - if (frameRate == 0) { - frameRate = this.graphics.config.backgroundFPS; - } - if (frameRate == 0) { - frameRate = 30; - } - } - if (frameRate > 0) { - Display.sync(frameRate); - } - } - - synchronized (lifecycleListeners) { - final LifecycleListener[] listeners = lifecycleListeners.begin(); - for (int i = 0, n = lifecycleListeners.size; i < n; ++i) { - listeners[i].pause(); - listeners[i].dispose(); - } - lifecycleListeners.end(); - } - this.listener.pause(); - this.listener.dispose(); - Display.destroy(); - if (this.audio != null) { - this.audio.dispose(); - } - if (this.graphics.config.forceExit) { - System.exit(-1); - } - } - - public boolean executeRunnables() { - synchronized (this.runnables) { - for (int i = this.runnables.size - 1; i >= 0; i--) { - this.executedRunnables.add(this.runnables.get(i)); - } - this.runnables.clear(); - } - if (this.executedRunnables.size == 0) { - return false; - } - do { - this.executedRunnables.pop().run(); - } - while (this.executedRunnables.size > 0); - return true; - } - - @Override - public ApplicationListener getApplicationListener() { - return this.listener; - } - - @Override - public Audio getAudio() { - return this.audio; - } - - @Override - public Files getFiles() { - return this.files; - } - - @Override - public LwjglGraphics getGraphics() { - return this.graphics; - } - - @Override - public Input getInput() { - return this.input; - } - - @Override - public Net getNet() { - return this.net; - } - - @Override - public ApplicationType getType() { - return ApplicationType.Desktop; - } - - @Override - public int getVersion() { - return 0; - } - - public void stop() { - this.running = false; - try { - this.mainLoopThread.join(); - } - catch (final Exception ex) { - } - } - - @Override - public long getJavaHeap() { - return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); - } - - @Override - public long getNativeHeap() { - return getJavaHeap(); - } - - ObjectMap preferences = new ObjectMap(); - - @Override - public Preferences getPreferences(final String name) { - if (this.preferences.containsKey(name)) { - return this.preferences.get(name); - } - else { - final Preferences prefs = new LwjglPreferences( - new LwjglFileHandle(new File(this.preferencesdir, name), this.preferencesFileType)); - this.preferences.put(name, prefs); - return prefs; - } - } - - @Override - public Clipboard getClipboard() { - return new LwjglClipboard(); - } - - @Override - public void postRunnable(final Runnable runnable) { - synchronized (this.runnables) { - this.runnables.add(runnable); - Gdx.graphics.requestRendering(); - } - } - - @Override - public void debug(final String tag, final String message) { - if (this.logLevel >= LOG_DEBUG) { - getApplicationLogger().debug(tag, message); - } - } - - @Override - public void debug(final String tag, final String message, final Throwable exception) { - if (this.logLevel >= LOG_DEBUG) { - getApplicationLogger().debug(tag, message, exception); - } - } - - @Override - public void log(final String tag, final String message) { - if (this.logLevel >= LOG_INFO) { - getApplicationLogger().log(tag, message); - } - } - - @Override - public void log(final String tag, final String message, final Throwable exception) { - if (this.logLevel >= LOG_INFO) { - getApplicationLogger().log(tag, message, exception); - } - } - - @Override - public void error(final String tag, final String message) { - if (this.logLevel >= LOG_ERROR) { - getApplicationLogger().error(tag, message); - } - } - - @Override - public void error(final String tag, final String message, final Throwable exception) { - if (this.logLevel >= LOG_ERROR) { - getApplicationLogger().error(tag, message, exception); - } - } - - @Override - public void setLogLevel(final int logLevel) { - this.logLevel = logLevel; - } - - @Override - public int getLogLevel() { - return this.logLevel; - } - - @Override - public void setApplicationLogger(final ApplicationLogger applicationLogger) { - this.applicationLogger = applicationLogger; - } - - @Override - public ApplicationLogger getApplicationLogger() { - return this.applicationLogger; - } - - @Override - public void exit() { - postRunnable(new Runnable() { - @Override - public void run() { - LwjglApplication.this.running = false; - } - }); - } - - @Override - public void addLifecycleListener(final LifecycleListener listener) { - synchronized (this.lifecycleListeners) { - this.lifecycleListeners.add(listener); - } - } - - @Override - public void removeLifecycleListener(final LifecycleListener listener) { - synchronized (this.lifecycleListeners) { - this.lifecycleListeners.removeValue(listener, true); - } - } -} diff --git a/desktop/src/com/badlogic/gdx/backends/lwjgl/LwjglCanvas.java b/desktop/src/com/badlogic/gdx/backends/lwjgl/LwjglCanvas.java deleted file mode 100644 index a1c915e6..00000000 --- a/desktop/src/com/badlogic/gdx/backends/lwjgl/LwjglCanvas.java +++ /dev/null @@ -1,501 +0,0 @@ -/******************************************************************************* - * Copyright 2011 See AUTHORS file. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package com.badlogic.gdx.backends.lwjgl; - -import java.awt.Canvas; -import java.awt.Cursor; -import java.awt.Dimension; -import java.awt.EventQueue; -import java.util.HashMap; -import java.util.Map; - -import org.lwjgl.opengl.AWTGLCanvas; -import org.lwjgl.opengl.Display; - -import com.badlogic.gdx.Application; -import com.badlogic.gdx.ApplicationListener; -import com.badlogic.gdx.ApplicationLogger; -import com.badlogic.gdx.Audio; -import com.badlogic.gdx.Files; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Graphics; -import com.badlogic.gdx.Input; -import com.badlogic.gdx.LifecycleListener; -import com.badlogic.gdx.Net; -import com.badlogic.gdx.Preferences; -import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.Clipboard; -import com.badlogic.gdx.utils.SharedLibraryLoader; -import com.etheller.warsmash.audio.OpenALAudio; - -/** - * An OpenGL surface on an AWT Canvas, allowing OpenGL to be embedded in a Swing - * application. This uses {@link Display#setParent(Canvas)}, which is preferred - * over {@link AWTGLCanvas} but is limited to a single LwjglCanvas in an - * application. All OpenGL calls are done on the EDT. Note that you may need to - * call {@link #stop()} or a Swing application may deadlock on System.exit due - * to how LWJGL and/or Swing deal with shutdown hooks. - * - * @author Nathan Sweet - */ -public class LwjglCanvas implements Application { - static boolean isWindows = System.getProperty("os.name").contains("Windows"); - - LwjglGraphics graphics; - OpenALAudio audio; - LwjglFiles files; - LwjglInput input; - LwjglNet net; - ApplicationListener listener; - Canvas canvas; - final Array runnables = new Array(); - final Array executedRunnables = new Array(); - final Array lifecycleListeners = new Array(); - boolean running = true; - int logLevel = LOG_INFO; - ApplicationLogger applicationLogger; - Cursor cursor; - - public LwjglCanvas(final ApplicationListener listener) { - final LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); - initialize(listener, config); - } - - public LwjglCanvas(final ApplicationListener listener, final LwjglApplicationConfiguration config) { - initialize(listener, config); - } - - private void initialize(final ApplicationListener listener, final LwjglApplicationConfiguration config) { - LwjglNativesLoader.load(); - setApplicationLogger(new LwjglApplicationLogger()); - this.canvas = new Canvas() { - private final Dimension minSize = new Dimension(1, 1); - - @Override - public final void addNotify() { - super.addNotify(); - if (SharedLibraryLoader.isMac) { - EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - create(); - } - }); - } - else { - create(); - } - } - - @Override - public final void removeNotify() { - stop(); - super.removeNotify(); - } - - @Override - public Dimension getMinimumSize() { - return this.minSize; - } - }; - this.canvas.setSize(1, 1); - this.canvas.setIgnoreRepaint(true); - - this.graphics = new LwjglGraphics(this.canvas, config) { - @Override - public void setTitle(final String title) { - super.setTitle(title); - LwjglCanvas.this.setTitle(title); - } - - public boolean setWindowedMode(final int width, final int height, final boolean fullscreen) { - if (!super.setWindowedMode(width, height)) { - return false; - } - if (!fullscreen) { - LwjglCanvas.this.setDisplayMode(width, height); - } - return true; - } - - @Override - public boolean setFullscreenMode(final DisplayMode displayMode) { - if (!super.setFullscreenMode(displayMode)) { - return false; - } - LwjglCanvas.this.setDisplayMode(displayMode.width, displayMode.height); - return true; - } - }; - this.graphics.setVSync(config.vSyncEnabled); - if (!LwjglApplicationConfiguration.disableAudio) { - this.audio = new OpenALAudio(); - } - this.files = new LwjglFiles(); - this.input = new LwjglInput(); - this.net = new LwjglNet(); - this.listener = listener; - - Gdx.app = this; - Gdx.graphics = this.graphics; - Gdx.audio = this.audio; - Gdx.files = this.files; - Gdx.input = this.input; - Gdx.net = this.net; - } - - protected void setDisplayMode(final int width, final int height) { - } - - protected void setTitle(final String title) { - } - - @Override - public ApplicationListener getApplicationListener() { - return this.listener; - } - - public Canvas getCanvas() { - return this.canvas; - } - - @Override - public Audio getAudio() { - return this.audio; - } - - @Override - public Files getFiles() { - return this.files; - } - - @Override - public Graphics getGraphics() { - return this.graphics; - } - - @Override - public Input getInput() { - return this.input; - } - - @Override - public Net getNet() { - return this.net; - } - - @Override - public ApplicationType getType() { - return ApplicationType.Desktop; - } - - @Override - public int getVersion() { - return 0; - } - - void create() { - try { - this.graphics.setupDisplay(); - - this.listener.create(); - this.listener.resize(Math.max(1, this.graphics.getWidth()), Math.max(1, this.graphics.getHeight())); - - start(); - } - catch (final Exception ex) { - stopped(); - exception(ex); - return; - } - - EventQueue.invokeLater(new Runnable() { - int lastWidth = Math.max(1, LwjglCanvas.this.graphics.getWidth()); - int lastHeight = Math.max(1, LwjglCanvas.this.graphics.getHeight()); - - @Override - public void run() { - if (!LwjglCanvas.this.running || Display.isCloseRequested()) { - LwjglCanvas.this.running = false; - stopped(); - return; - } - try { - Display.processMessages(); - if ((LwjglCanvas.this.cursor != null) || !isWindows) { - LwjglCanvas.this.canvas.setCursor(LwjglCanvas.this.cursor); - } - - boolean shouldRender = false; - - final int width = Math.max(1, LwjglCanvas.this.graphics.getWidth()); - final int height = Math.max(1, LwjglCanvas.this.graphics.getHeight()); - if ((this.lastWidth != width) || (this.lastHeight != height)) { - this.lastWidth = width; - this.lastHeight = height; - Gdx.gl.glViewport(0, 0, this.lastWidth, this.lastHeight); - resize(width, height); - LwjglCanvas.this.listener.resize(width, height); - shouldRender = true; - } - - if (executeRunnables()) { - shouldRender = true; - } - - // If one of the runnables set running to false, for example after an exit(). - if (!LwjglCanvas.this.running) { - return; - } - - LwjglCanvas.this.input.update(); - shouldRender |= LwjglCanvas.this.graphics.shouldRender(); - LwjglCanvas.this.input.processEvents(); - if (LwjglCanvas.this.audio != null) { - LwjglCanvas.this.audio.update(); - } - - if (shouldRender) { - LwjglCanvas.this.graphics.updateTime(); - LwjglCanvas.this.graphics.frameId++; - LwjglCanvas.this.listener.render(); - Display.update(false); - } - - Display.sync(getFrameRate()); - } - catch (final Throwable ex) { - exception(ex); - } - EventQueue.invokeLater(this); - } - }); - } - - public boolean executeRunnables() { - synchronized (this.runnables) { - for (int i = this.runnables.size - 1; i >= 0; i--) { - this.executedRunnables.addAll(this.runnables.get(i)); - } - this.runnables.clear(); - } - if (this.executedRunnables.size == 0) { - return false; - } - do { - this.executedRunnables.pop().run(); - } - while (this.executedRunnables.size > 0); - return true; - } - - protected int getFrameRate() { - int frameRate = Display.isActive() ? this.graphics.config.foregroundFPS : this.graphics.config.backgroundFPS; - if (frameRate == -1) { - frameRate = 10; - } - if (frameRate == 0) { - frameRate = this.graphics.config.backgroundFPS; - } - if (frameRate == 0) { - frameRate = 30; - } - return frameRate; - } - - protected void exception(final Throwable ex) { - ex.printStackTrace(); - stop(); - } - - /** - * Called after {@link ApplicationListener} create and resize, but before the - * game loop iteration. - */ - protected void start() { - } - - /** Called when the canvas size changes. */ - protected void resize(final int width, final int height) { - } - - /** Called when the game loop has stopped. */ - protected void stopped() { - } - - public void stop() { - EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - if (!LwjglCanvas.this.running) { - return; - } - LwjglCanvas.this.running = false; - final Array listeners = LwjglCanvas.this.lifecycleListeners; - synchronized (listeners) { - for (final LifecycleListener listener : listeners) { - listener.pause(); - listener.dispose(); - } - } - LwjglCanvas.this.listener.pause(); - LwjglCanvas.this.listener.dispose(); - try { - Display.destroy(); - if (LwjglCanvas.this.audio != null) { - LwjglCanvas.this.audio.dispose(); - } - } - catch (final Throwable ignored) { - } - } - }); - } - - @Override - public long getJavaHeap() { - return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); - } - - @Override - public long getNativeHeap() { - return getJavaHeap(); - } - - Map preferences = new HashMap(); - - @Override - public Preferences getPreferences(final String name) { - if (this.preferences.containsKey(name)) { - return this.preferences.get(name); - } - else { - final Preferences prefs = new LwjglPreferences(name, ".prefs/"); - this.preferences.put(name, prefs); - return prefs; - } - } - - @Override - public Clipboard getClipboard() { - return new LwjglClipboard(); - } - - @Override - public void postRunnable(final Runnable runnable) { - synchronized (this.runnables) { - this.runnables.add(runnable); - Gdx.graphics.requestRendering(); - } - } - - @Override - public void debug(final String tag, final String message) { - if (this.logLevel >= LOG_DEBUG) { - getApplicationLogger().debug(tag, message); - } - } - - @Override - public void debug(final String tag, final String message, final Throwable exception) { - if (this.logLevel >= LOG_DEBUG) { - getApplicationLogger().debug(tag, message, exception); - } - } - - @Override - public void log(final String tag, final String message) { - if (this.logLevel >= LOG_INFO) { - getApplicationLogger().log(tag, message); - } - } - - @Override - public void log(final String tag, final String message, final Throwable exception) { - if (this.logLevel >= LOG_INFO) { - getApplicationLogger().log(tag, message, exception); - } - } - - @Override - public void error(final String tag, final String message) { - if (this.logLevel >= LOG_ERROR) { - getApplicationLogger().error(tag, message); - } - } - - @Override - public void error(final String tag, final String message, final Throwable exception) { - if (this.logLevel >= LOG_ERROR) { - getApplicationLogger().error(tag, message, exception); - } - } - - @Override - public void setLogLevel(final int logLevel) { - this.logLevel = logLevel; - } - - @Override - public int getLogLevel() { - return this.logLevel; - } - - @Override - public void setApplicationLogger(final ApplicationLogger applicationLogger) { - this.applicationLogger = applicationLogger; - } - - @Override - public ApplicationLogger getApplicationLogger() { - return this.applicationLogger; - } - - @Override - public void exit() { - postRunnable(new Runnable() { - @Override - public void run() { - LwjglCanvas.this.listener.pause(); - LwjglCanvas.this.listener.dispose(); - if (LwjglCanvas.this.audio != null) { - LwjglCanvas.this.audio.dispose(); - } - System.exit(-1); - } - }); - } - - /** @param cursor May be null. */ - public void setCursor(final Cursor cursor) { - this.cursor = cursor; - } - - @Override - public void addLifecycleListener(final LifecycleListener listener) { - synchronized (this.lifecycleListeners) { - this.lifecycleListeners.add(listener); - } - } - - @Override - public void removeLifecycleListener(final LifecycleListener listener) { - synchronized (this.lifecycleListeners) { - this.lifecycleListeners.removeValue(listener, true); - } - } -} diff --git a/desktop/src/com/etheller/warsmash/audio/Flac.java b/desktop/src/com/etheller/warsmash/audio/Flac.java deleted file mode 100644 index 3a99bf92..00000000 --- a/desktop/src/com/etheller/warsmash/audio/Flac.java +++ /dev/null @@ -1,195 +0,0 @@ -/******************************************************************************* - * Copyright 2011 See AUTHORS file. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package com.etheller.warsmash.audio; - -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.Arrays; - -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.utils.GdxRuntimeException; -import com.badlogic.gdx.utils.StreamUtils; -import com.etheller.warsmash.audio.Wav.WavInputStream; - -import io.nayuki.flac.common.StreamInfo; -import io.nayuki.flac.decode.DataFormatException; -import io.nayuki.flac.decode.FlacDecoder; - -public class Flac { - static public class Music extends OpenALMusic { - private WavInputStream input; - - public Music(final OpenALAudio audio, final FileHandle file) { - super(audio, file); - try { - this.input = new WavInputStream(new ByteArrayInputStream(makeItWav(file)), file); - } - catch (final IOException ex) { - throw new GdxRuntimeException("Error reading FLAC file: " + this.file, ex); - } - if (audio.noDevice) { - return; - } - setup(this.input.channels, this.input.sampleRate); - } - - @Override - public int read(final byte[] buffer) { - if (this.input == null) { - try { - this.input = new WavInputStream(new ByteArrayInputStream(makeItWav(this.file)), this.file); - } - catch (final IOException ex) { - throw new GdxRuntimeException("Error reading FLAC file: " + this.file, ex); - } - setup(this.input.channels, this.input.sampleRate); - } - try { - return this.input.read(buffer); - } - catch (final IOException ex) { - throw new GdxRuntimeException("Error reading FLAC file: " + this.file, ex); - } - } - - @Override - public void reset() { - StreamUtils.closeQuietly(this.input); - this.input = null; - } - } - - static public class Sound extends OpenALSound { - public Sound(final OpenALAudio audio, final FileHandle file) { - super(audio); - if (audio.noDevice) { - return; - } - - WavInputStream input = null; - try { - input = new WavInputStream(new ByteArrayInputStream(makeItWav(file)), file); - setup(StreamUtils.copyStreamToByteArray(input, input.dataRemaining), input.channels, input.sampleRate); - } - catch (final IOException ex) { - throw new GdxRuntimeException("Error reading FLAC file: " + file, ex); - } - finally { - StreamUtils.closeQuietly(input); - } - } - } - - private static byte[] makeItWav(final FileHandle file) throws IOException { - // Decode input FLAC file - StreamInfo streamInfo; - int[][] samples; - try (FlacDecoder dec = new FlacDecoder(file.readBytes())) { - - // Handle metadata header blocks - while (dec.readAndHandleMetadataBlock() != null) { - ; - } - streamInfo = dec.streamInfo; - if ((streamInfo.sampleDepth % 8) != 0) { - throw new UnsupportedOperationException("Only whole-byte sample depth supported"); - } - - // Decode every block - samples = new int[streamInfo.numChannels][(int) streamInfo.numSamples]; - for (int off = 0;;) { - final int len = dec.readAudioBlock(samples, off); - if (len == 0) { - break; - } - off += len; - } - } - - // Check audio MD5 hash - final byte[] expectHash = streamInfo.md5Hash; - if (Arrays.equals(expectHash, new byte[16])) { - System.err.println("Warning: MD5 hash field was blank"); - } - else if (!Arrays.equals(StreamInfo.getMd5Hash(samples, streamInfo.sampleDepth), expectHash)) { - throw new DataFormatException("MD5 hash check failed"); - // Else the hash check passed - } - - // Start writing WAV output file - int bytesPerSample = streamInfo.sampleDepth / 8; - final boolean needsDownscaleForLibgdx = bytesPerSample >= 3; - int downsampleBytes = 0; - if (needsDownscaleForLibgdx) { - downsampleBytes = bytesPerSample - 2; - bytesPerSample = 2; - } - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (DataOutputStream out = new DataOutputStream(new BufferedOutputStream(baos))) { - // Header chunk - final int sampleDataLen = samples[0].length * streamInfo.numChannels * bytesPerSample; - out.writeInt(0x52494646); // "RIFF" - writeLittleInt32(out, sampleDataLen + 36); - out.writeInt(0x57415645); // "WAVE" - - // Metadata chunk - out.writeInt(0x666D7420); // "fmt " - writeLittleInt32(out, 16); - writeLittleInt16(out, 0x0001); - writeLittleInt16(out, streamInfo.numChannels); - writeLittleInt32(out, streamInfo.sampleRate); - writeLittleInt32(out, streamInfo.sampleRate * streamInfo.numChannels * bytesPerSample); - writeLittleInt16(out, streamInfo.numChannels * bytesPerSample); - writeLittleInt16(out, needsDownscaleForLibgdx ? 16 : streamInfo.sampleDepth); - - // Audio data chunk ("data") - out.writeInt(0x64617461); // "data" - writeLittleInt32(out, sampleDataLen); - for (int i = 0; i < samples[0].length; i++) { - for (int j = 0; j < samples.length; j++) { - int val = samples[j][i]; - for (int k = 0; k < downsampleBytes; k++) { - val = val >>> 8; - } - if (bytesPerSample == 1) { - out.write(val + 128); // Convert to unsigned, as per WAV PCM conventions - } - else { // 2 <= bytesPerSample <= 4 - for (int k = 0; k < bytesPerSample; k++) { - out.write(val >>> (k * 8)); // Little endian - } - } - } - } - return baos.toByteArray(); - } - } - - // Helper members for writing WAV files - - private static void writeLittleInt16(final DataOutputStream out, final int x) throws IOException { - out.writeShort(Integer.reverseBytes(x) >>> 16); - } - - private static void writeLittleInt32(final DataOutputStream out, final int x) throws IOException { - out.writeInt(Integer.reverseBytes(x)); - } - -} diff --git a/desktop/src/com/etheller/warsmash/audio/JavaSoundAudioRecorder.java b/desktop/src/com/etheller/warsmash/audio/JavaSoundAudioRecorder.java deleted file mode 100644 index a9f663f7..00000000 --- a/desktop/src/com/etheller/warsmash/audio/JavaSoundAudioRecorder.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * Copyright 2011 See AUTHORS file. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package com.etheller.warsmash.audio; - -import javax.sound.sampled.AudioFormat; -import javax.sound.sampled.AudioFormat.Encoding; -import javax.sound.sampled.AudioSystem; -import javax.sound.sampled.TargetDataLine; - -import com.badlogic.gdx.audio.AudioRecorder; -import com.badlogic.gdx.utils.GdxRuntimeException; - -/** @author mzechner */ -public class JavaSoundAudioRecorder implements AudioRecorder { - private TargetDataLine line; - private byte[] buffer = new byte[1024 * 4]; - - public JavaSoundAudioRecorder(final int samplingRate, final boolean isMono) { - try { - final AudioFormat format = new AudioFormat(Encoding.PCM_SIGNED, samplingRate, 16, isMono ? 1 : 2, - isMono ? 2 : 4, samplingRate, false); - this.line = AudioSystem.getTargetDataLine(format); - this.line.open(format, this.buffer.length); - this.line.start(); - } - catch (final Exception ex) { - throw new GdxRuntimeException("Error creating JavaSoundAudioRecorder.", ex); - } - } - - @Override - public void read(final short[] samples, final int offset, final int numSamples) { - if (this.buffer.length < (numSamples * 2)) { - this.buffer = new byte[numSamples * 2]; - } - - final int toRead = numSamples * 2; - int read = 0; - while (read != toRead) { - read += this.line.read(this.buffer, read, toRead - read); - } - - for (int i = 0, j = 0; i < (numSamples * 2); i += 2, j++) { - samples[offset + j] = (short) ((this.buffer[i + 1] << 8) | (this.buffer[i] & 0xff)); - } - } - - @Override - public void dispose() { - this.line.close(); - } -} diff --git a/desktop/src/com/etheller/warsmash/audio/Mp3.java b/desktop/src/com/etheller/warsmash/audio/Mp3.java deleted file mode 100644 index 02bc10c3..00000000 --- a/desktop/src/com/etheller/warsmash/audio/Mp3.java +++ /dev/null @@ -1,163 +0,0 @@ -/******************************************************************************* - * Copyright 2011 See AUTHORS file. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package com.etheller.warsmash.audio; - -import java.io.ByteArrayOutputStream; - -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.utils.GdxRuntimeException; - -import javazoom.jl.decoder.Bitstream; -import javazoom.jl.decoder.BitstreamException; -import javazoom.jl.decoder.Header; -import javazoom.jl.decoder.MP3Decoder; -import javazoom.jl.decoder.OutputBuffer; - -/** @author Nathan Sweet */ -public class Mp3 { - static public class Music extends OpenALMusic { - // Note: This uses a slightly modified version of JLayer. - - private Bitstream bitstream; - private OutputBuffer outputBuffer; - private MP3Decoder decoder; - - public Music(final OpenALAudio audio, final FileHandle file) { - super(audio, file); - if (audio.noDevice) { - return; - } - this.bitstream = new Bitstream(file.read()); - this.decoder = new MP3Decoder(); - this.bufferOverhead = 4096; - try { - final Header header = this.bitstream.readFrame(); - if (header == null) { - throw new GdxRuntimeException("Empty MP3"); - } - final int channels = header.mode() == Header.SINGLE_CHANNEL ? 1 : 2; - this.outputBuffer = new OutputBuffer(channels, false); - this.decoder.setOutputBuffer(this.outputBuffer); - setup(channels, header.getSampleRate()); - } - catch (final BitstreamException e) { - throw new GdxRuntimeException("error while preloading mp3", e); - } - } - - @Override - public int read(final byte[] buffer) { - try { - boolean setup = this.bitstream == null; - if (setup) { - this.bitstream = new Bitstream(this.file.read()); - this.decoder = new MP3Decoder(); - } - - int totalLength = 0; - final int minRequiredLength = buffer.length - (OutputBuffer.BUFFERSIZE * 2); - while (totalLength <= minRequiredLength) { - final Header header = this.bitstream.readFrame(); - if (header == null) { - break; - } - if (setup) { - final int channels = header.mode() == Header.SINGLE_CHANNEL ? 1 : 2; - this.outputBuffer = new OutputBuffer(channels, false); - this.decoder.setOutputBuffer(this.outputBuffer); - setup(channels, header.getSampleRate()); - setup = false; - } - try { - this.decoder.decodeFrame(header, this.bitstream); - } - catch (final Exception ignored) { - // JLayer's decoder throws ArrayIndexOutOfBoundsException sometimes!? - } - this.bitstream.closeFrame(); - - final int length = this.outputBuffer.reset(); - System.arraycopy(this.outputBuffer.getBuffer(), 0, buffer, totalLength, length); - totalLength += length; - } - return totalLength; - } - catch (final Throwable ex) { - reset(); - throw new GdxRuntimeException("Error reading audio data.", ex); - } - } - - @Override - public void reset() { - if (this.bitstream == null) { - return; - } - try { - this.bitstream.close(); - } - catch (final BitstreamException ignored) { - } - this.bitstream = null; - } - } - - static public class Sound extends OpenALSound { - // Note: This uses a slightly modified version of JLayer. - - public Sound(final OpenALAudio audio, final FileHandle file) { - super(audio); - if (audio.noDevice) { - return; - } - final ByteArrayOutputStream output = new ByteArrayOutputStream(4096); - - final Bitstream bitstream = new Bitstream(file.read()); - final MP3Decoder decoder = new MP3Decoder(); - - try { - OutputBuffer outputBuffer = null; - int sampleRate = -1, channels = -1; - while (true) { - final Header header = bitstream.readFrame(); - if (header == null) { - break; - } - if (outputBuffer == null) { - channels = header.mode() == Header.SINGLE_CHANNEL ? 1 : 2; - outputBuffer = new OutputBuffer(channels, false); - decoder.setOutputBuffer(outputBuffer); - sampleRate = header.getSampleRate(); - } - try { - decoder.decodeFrame(header, bitstream); - } - catch (final Exception ignored) { - // JLayer's decoder throws ArrayIndexOutOfBoundsException sometimes!? - } - bitstream.closeFrame(); - output.write(outputBuffer.getBuffer(), 0, outputBuffer.reset()); - } - bitstream.close(); - setup(output.toByteArray(), channels, sampleRate); - } - catch (final Throwable ex) { - throw new GdxRuntimeException("Error reading audio data.", ex); - } - } - } -} diff --git a/desktop/src/com/etheller/warsmash/audio/Ogg.java b/desktop/src/com/etheller/warsmash/audio/Ogg.java deleted file mode 100644 index f61fb19a..00000000 --- a/desktop/src/com/etheller/warsmash/audio/Ogg.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * Copyright 2011 See AUTHORS file. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package com.etheller.warsmash.audio; - -import java.io.ByteArrayOutputStream; - -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.utils.StreamUtils; - -/** @author Nathan Sweet */ -public class Ogg { - static public class Music extends OpenALMusic { - private OggInputStream input; - private OggInputStream previousInput; - - public Music(final OpenALAudio audio, final FileHandle file) { - super(audio, file); - if (audio.noDevice) { - return; - } - this.input = new OggInputStream(file.read()); - setup(this.input.getChannels(), this.input.getSampleRate()); - } - - @Override - public int read(final byte[] buffer) { - if (this.input == null) { - this.input = new OggInputStream(this.file.read(), this.previousInput); - setup(this.input.getChannels(), this.input.getSampleRate()); - this.previousInput = null; // release this reference - } - return this.input.read(buffer); - } - - @Override - public void reset() { - StreamUtils.closeQuietly(this.input); - this.previousInput = null; - this.input = null; - } - - @Override - protected void loop() { - StreamUtils.closeQuietly(this.input); - this.previousInput = this.input; - this.input = null; - } - } - - static public class Sound extends OpenALSound { - public Sound(final OpenALAudio audio, final FileHandle file) { - super(audio); - if (audio.noDevice) { - return; - } - OggInputStream input = null; - try { - input = new OggInputStream(file.read()); - final ByteArrayOutputStream output = new ByteArrayOutputStream(4096); - final byte[] buffer = new byte[2048]; - while (!input.atEnd()) { - final int length = input.read(buffer); - if (length == -1) { - break; - } - output.write(buffer, 0, length); - } - setup(output.toByteArray(), input.getChannels(), input.getSampleRate()); - } - finally { - StreamUtils.closeQuietly(input); - } - } - } -} diff --git a/desktop/src/com/etheller/warsmash/audio/OggInputStream.java b/desktop/src/com/etheller/warsmash/audio/OggInputStream.java deleted file mode 100644 index 9fed1cf8..00000000 --- a/desktop/src/com/etheller/warsmash/audio/OggInputStream.java +++ /dev/null @@ -1,520 +0,0 @@ -/** - * Copyright (c) 2007, Slick 2D - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following - * conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the distribution. Neither the name of the Slick 2D nor the names of - * its contributors may be used to endorse or promote products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.etheller.warsmash.audio; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteOrder; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.utils.GdxRuntimeException; -import com.badlogic.gdx.utils.StreamUtils; -import com.jcraft.jogg.Packet; -import com.jcraft.jogg.Page; -import com.jcraft.jogg.StreamState; -import com.jcraft.jogg.SyncState; -import com.jcraft.jorbis.Block; -import com.jcraft.jorbis.Comment; -import com.jcraft.jorbis.DspState; -import com.jcraft.jorbis.Info; - -/** - * An input stream to read Ogg Vorbis. - * - * @author kevin - */ -public class OggInputStream extends InputStream { - private final static int BUFFER_SIZE = 512; - - /** The conversion buffer size */ - private int convsize = BUFFER_SIZE * 4; - /** The buffer used to read OGG file */ - private byte[] convbuffer; - /** The stream we're reading the OGG file from */ - private final InputStream input; - /** The audio information from the OGG header */ - private final Info oggInfo = new Info(); // struct that stores all the static vorbis bitstream settings - /** True if we're at the end of the available data */ - private boolean endOfStream; - - /** The Vorbis SyncState used to decode the OGG */ - private final SyncState syncState = new SyncState(); // sync and verify incoming physical bitstream - /** The Vorbis Stream State used to decode the OGG */ - private final StreamState streamState = new StreamState(); // take physical pages, weld into a logical stream of - // packets - /** The current OGG page */ - private final Page page = new Page(); // one Ogg bitstream page. Vorbis packets are inside - /** The current packet page */ - private final Packet packet = new Packet(); // one raw packet of data for decode - - /** The comment read from the OGG file */ - private final Comment comment = new Comment(); // struct that stores all the bitstream user comments - /** The Vorbis DSP stat eused to decode the OGG */ - private final DspState dspState = new DspState(); // central working state for the packet->PCM decoder - /** The OGG block we're currently working with to convert PCM */ - private final Block vorbisBlock = new Block(this.dspState); // local working space for packet->PCM decode - - /** Temporary scratch buffer */ - byte[] buffer; - /** The number of bytes read */ - int bytes = 0; - /** The true if we should be reading big endian */ - boolean bigEndian = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN); - /** True if we're reached the end of the current bit stream */ - boolean endOfBitStream = true; - /** True if we're initialise the OGG info block */ - boolean inited = false; - - /** The index into the byte array we currently read from */ - private int readIndex; - /** The byte array store used to hold the data read from the ogg */ - private byte[] outBuffer; - private int outIndex; - /** The total number of bytes */ - private int total; - - /** - * Create a new stream to decode OGG data - * - * @param input The input stream from which to read the OGG file - */ - public OggInputStream(final InputStream input) { - this(input, null); - } - - /** - * Create a new stream to decode OGG data, reusing buffers from another stream. - * - * It's not a good idea to use the old stream instance afterwards. - * - * @param input The input stream from which to read the OGG file - * @param previousStream The stream instance to reuse buffers from, may be null - */ - public OggInputStream(final InputStream input, final OggInputStream previousStream) { - if (previousStream == null) { - this.convbuffer = new byte[this.convsize]; - this.outBuffer = new byte[4096 * 500]; - } - else { - this.convbuffer = previousStream.convbuffer; - this.outBuffer = previousStream.outBuffer; - } - - this.input = input; - try { - this.total = input.available(); - } - catch (final IOException ex) { - throw new GdxRuntimeException(ex); - } - - init(); - } - - /** - * Get the number of bytes on the stream - * - * @return The number of the bytes on the stream - */ - public int getLength() { - return this.total; - } - - public int getChannels() { - return this.oggInfo.channels; - } - - public int getSampleRate() { - return this.oggInfo.rate; - } - - /** Initialise the streams and thread involved in the streaming of OGG data */ - private void init() { - initVorbis(); - readPCM(); - } - - /** @see java.io.InputStream#available() */ - @Override - public int available() { - return this.endOfStream ? 0 : 1; - } - - /** Initialise the vorbis decoding */ - private void initVorbis() { - this.syncState.init(); - } - - /** - * Get a page and packet from that page - * - * @return True if there was a page available - */ - private boolean getPageAndPacket() { - // grab some data at the head of the stream. We want the first page - // (which is guaranteed to be small and only contain the Vorbis - // stream initial header) We need the first page to get the stream - // serialno. - - // submit a 4k block to libvorbis' Ogg layer - int index = this.syncState.buffer(BUFFER_SIZE); - if (index == -1) { - return false; - } - - this.buffer = this.syncState.data; - if (this.buffer == null) { - this.endOfStream = true; - return false; - } - - try { - this.bytes = this.input.read(this.buffer, index, BUFFER_SIZE); - } - catch (final Exception e) { - throw new GdxRuntimeException("Failure reading Vorbis.", e); - } - this.syncState.wrote(this.bytes); - - // Get the first page. - if (this.syncState.pageout(this.page) != 1) { - // have we simply run out of data? If so, we're done. - if (this.bytes < BUFFER_SIZE) { - return false; - } - - // error case. Must not be Vorbis data - throw new GdxRuntimeException("Input does not appear to be an Ogg bitstream."); - } - - // Get the serial number and set up the rest of decode. - // serialno first; use it to set up a logical stream - this.streamState.init(this.page.serialno()); - - // extract the initial header from the first page and verify that the - // Ogg bitstream is in fact Vorbis data - - // I handle the initial header first instead of just having the code - // read all three Vorbis headers at once because reading the initial - // header is an easy way to identify a Vorbis bitstream and it's - // useful to see that functionality seperated out. - - this.oggInfo.init(); - this.comment.init(); - if (this.streamState.pagein(this.page) < 0) { - // error; stream version mismatch perhaps - throw new GdxRuntimeException("Error reading first page of Ogg bitstream."); - } - - if (this.streamState.packetout(this.packet) != 1) { - // no page? must not be vorbis - throw new GdxRuntimeException("Error reading initial header packet."); - } - - if (this.oggInfo.synthesis_headerin(this.comment, this.packet) < 0) { - // error case; not a vorbis header - throw new GdxRuntimeException("Ogg bitstream does not contain Vorbis audio data."); - } - - // At this point, we're sure we're Vorbis. We've set up the logical - // (Ogg) bitstream decoder. Get the comment and codebook headers and - // set up the Vorbis decoder - - // The next two packets in order are the comment and codebook headers. - // They're likely large and may span multiple pages. Thus we reead - // and submit data until we get our two pacakets, watching that no - // pages are missing. If a page is missing, error out; losing a - // header page is the only place where missing data is fatal. */ - - int i = 0; - while (i < 2) { - while (i < 2) { - int result = this.syncState.pageout(this.page); - if (result == 0) { - break; // Need more data - // Don't complain about missing or corrupt data yet. We'll - // catch it at the packet output phase - } - - if (result == 1) { - this.streamState.pagein(this.page); // we can ignore any errors here - // as they'll also become apparent - // at packetout - while (i < 2) { - result = this.streamState.packetout(this.packet); - if (result == 0) { - break; - } - if (result == -1) { - // Uh oh; data at some point was corrupted or missing! - // We can't tolerate that in a header. Die. - throw new GdxRuntimeException("Corrupt secondary header."); - } - - this.oggInfo.synthesis_headerin(this.comment, this.packet); - i++; - } - } - } - // no harm in not checking before adding more - index = this.syncState.buffer(BUFFER_SIZE); - if (index == -1) { - return false; - } - this.buffer = this.syncState.data; - try { - this.bytes = this.input.read(this.buffer, index, BUFFER_SIZE); - } - catch (final Exception e) { - throw new GdxRuntimeException("Failed to read Vorbis.", e); - } - if ((this.bytes == 0) && (i < 2)) { - throw new GdxRuntimeException("End of file before finding all Vorbis headers."); - } - this.syncState.wrote(this.bytes); - } - - this.convsize = BUFFER_SIZE / this.oggInfo.channels; - - // OK, got and parsed all three headers. Initialize the Vorbis - // packet->PCM decoder. - this.dspState.synthesis_init(this.oggInfo); // central decode state - this.vorbisBlock.init(this.dspState); // local state for most of the decode - // so multiple block decodes can - // proceed in parallel. We could init - // multiple vorbis_block structures - // for vd here - - return true; - } - - /** Decode the OGG file as shown in the jogg/jorbis examples */ - private void readPCM() { - boolean wrote = false; - - while (true) { // we repeat if the bitstream is chained - if (this.endOfBitStream) { - if (!getPageAndPacket()) { - break; - } - this.endOfBitStream = false; - } - - if (!this.inited) { - this.inited = true; - return; - } - - final float[][][] _pcm = new float[1][][]; - final int[] _index = new int[this.oggInfo.channels]; - // The rest is just a straight decode loop until end of stream - while (!this.endOfBitStream) { - while (!this.endOfBitStream) { - int result = this.syncState.pageout(this.page); - - if (result == 0) { - break; // need more data - } - - if (result == -1) { // missing or corrupt data at this page position - // throw new GdxRuntimeException("Corrupt or missing data in bitstream."); - Gdx.app.log("gdx-audio", "Error reading OGG: Corrupt or missing data in bitstream."); - } - else { - this.streamState.pagein(this.page); // can safely ignore errors at - // this point - while (true) { - result = this.streamState.packetout(this.packet); - - if (result == 0) { - break; // need more data - } - if (result == -1) { // missing or corrupt data at this page position - // no reason to complain; already complained above - } - else { - // we have a packet. Decode it - int samples; - if (this.vorbisBlock.synthesis(this.packet) == 0) { // test for success! - this.dspState.synthesis_blockin(this.vorbisBlock); - } - - // **pcm is a multichannel float vector. In stereo, for - // example, pcm[0] is left, and pcm[1] is right. samples is - // the size of each channel. Convert the float values - // (-1.<=range<=1.) to whatever PCM format and write it out - - while ((samples = this.dspState.synthesis_pcmout(_pcm, _index)) > 0) { - final float[][] pcm = _pcm[0]; - // boolean clipflag = false; - final int bout = (samples < this.convsize ? samples : this.convsize); - - // convert floats to 16 bit signed ints (host order) and - // interleave - for (int i = 0; i < this.oggInfo.channels; i++) { - int ptr = i * 2; - // int ptr=i; - final int mono = _index[i]; - for (int j = 0; j < bout; j++) { - int val = (int) (pcm[i][mono + j] * 32767.); - // might as well guard against clipping - if (val > 32767) { - val = 32767; - } - if (val < -32768) { - val = -32768; - } - if (val < 0) { - val = val | 0x8000; - } - - if (this.bigEndian) { - this.convbuffer[ptr] = (byte) (val >>> 8); - this.convbuffer[ptr + 1] = (byte) (val); - } - else { - this.convbuffer[ptr] = (byte) (val); - this.convbuffer[ptr + 1] = (byte) (val >>> 8); - } - ptr += 2 * (this.oggInfo.channels); - } - } - - final int bytesToWrite = 2 * this.oggInfo.channels * bout; - if ((this.outIndex + bytesToWrite) > this.outBuffer.length) { - throw new GdxRuntimeException("Ogg block too big to be buffered: " - + bytesToWrite + ", " + (this.outBuffer.length - this.outIndex)); - } - else { - System.arraycopy(this.convbuffer, 0, this.outBuffer, this.outIndex, - bytesToWrite); - this.outIndex += bytesToWrite; - } - - wrote = true; - this.dspState.synthesis_read(bout); // tell libvorbis how - // many samples we - // actually consumed - } - } - } - if (this.page.eos() != 0) { - this.endOfBitStream = true; - } - - if ((!this.endOfBitStream) && (wrote)) { - return; - } - } - } - - if (!this.endOfBitStream) { - this.bytes = 0; - final int index = this.syncState.buffer(BUFFER_SIZE); - if (index >= 0) { - this.buffer = this.syncState.data; - try { - this.bytes = this.input.read(this.buffer, index, BUFFER_SIZE); - } - catch (final Exception e) { - throw new GdxRuntimeException("Error during Vorbis decoding.", e); - } - } - else { - this.bytes = 0; - } - this.syncState.wrote(this.bytes); - if (this.bytes == 0) { - this.endOfBitStream = true; - } - } - } - - // clean up this logical bitstream; before exit we see if we're - // followed by another [chained] - this.streamState.clear(); - - // ogg_page and ogg_packet structs always point to storage in - // libvorbis. They're never freed or manipulated directly - - this.vorbisBlock.clear(); - this.dspState.clear(); - this.oggInfo.clear(); // must be called last - } - - // OK, clean up the framer - this.syncState.clear(); - this.endOfStream = true; - } - - @Override - public int read() { - if (this.readIndex >= this.outIndex) { - this.outIndex = 0; - readPCM(); - this.readIndex = 0; - if (this.outIndex == 0) { - return -1; - } - } - - int value = this.outBuffer[this.readIndex]; - if (value < 0) { - value = 256 + value; - } - this.readIndex++; - - return value; - } - - public boolean atEnd() { - return this.endOfStream && (this.readIndex >= this.outIndex); - } - - @Override - public int read(final byte[] b, final int off, final int len) { - for (int i = 0; i < len; i++) { - final int value = read(); - if (value >= 0) { - b[i] = (byte) value; - } - else { - if (i == 0) { - return -1; - } - return i; - } - } - return len; - } - - @Override - public int read(final byte[] b) { - return read(b, 0, b.length); - } - - @Override - public void close() { - StreamUtils.closeQuietly(this.input); - } -} diff --git a/desktop/src/com/etheller/warsmash/audio/OpenALAudio.java b/desktop/src/com/etheller/warsmash/audio/OpenALAudio.java deleted file mode 100644 index ac162600..00000000 --- a/desktop/src/com/etheller/warsmash/audio/OpenALAudio.java +++ /dev/null @@ -1,479 +0,0 @@ -/******************************************************************************* - * Copyright 2011 See AUTHORS file. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package com.etheller.warsmash.audio; - -import static org.lwjgl.openal.AL10.AL_BUFFER; -import static org.lwjgl.openal.AL10.AL_NO_ERROR; -import static org.lwjgl.openal.AL10.AL_ORIENTATION; -import static org.lwjgl.openal.AL10.AL_PAUSED; -import static org.lwjgl.openal.AL10.AL_PLAYING; -import static org.lwjgl.openal.AL10.AL_POSITION; -import static org.lwjgl.openal.AL10.AL_SOURCE_STATE; -import static org.lwjgl.openal.AL10.AL_STOPPED; -import static org.lwjgl.openal.AL10.AL_VELOCITY; -import static org.lwjgl.openal.AL10.alDeleteSources; -import static org.lwjgl.openal.AL10.alGenSources; -import static org.lwjgl.openal.AL10.alGetError; -import static org.lwjgl.openal.AL10.alGetSourcei; -import static org.lwjgl.openal.AL10.alListener; -import static org.lwjgl.openal.AL10.alSourcePause; -import static org.lwjgl.openal.AL10.alSourcePlay; -import static org.lwjgl.openal.AL10.alSourceStop; -import static org.lwjgl.openal.AL10.alSourcei; - -import java.nio.FloatBuffer; - -import org.lwjgl.BufferUtils; -import org.lwjgl.LWJGLException; -import org.lwjgl.openal.AL; -import org.lwjgl.openal.AL10; - -import com.badlogic.gdx.Audio; -import com.badlogic.gdx.audio.AudioDevice; -import com.badlogic.gdx.audio.AudioRecorder; -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.utils.Array; -import com.badlogic.gdx.utils.GdxRuntimeException; -import com.badlogic.gdx.utils.IntArray; -import com.badlogic.gdx.utils.IntMap; -import com.badlogic.gdx.utils.LongMap; -import com.badlogic.gdx.utils.ObjectMap; - -/** @author Nathan Sweet */ -public class OpenALAudio implements Audio { - private final int deviceBufferSize; - private final int deviceBufferCount; - private IntArray idleSources, allSources; - private LongMap soundIdToSource; - private IntMap sourceToSoundId; - private long nextSoundId = 0; - private final ObjectMap> extensionToSoundClass = new ObjectMap(); - private final ObjectMap> extensionToMusicClass = new ObjectMap(); - private OpenALSound[] recentSounds; - private int mostRecetSound = -1; - - Array music = new Array(false, 1, OpenALMusic.class); - boolean noDevice = false; - - public OpenALAudio() { - this(16, 9, 512); - } - - public OpenALAudio(final int simultaneousSources, final int deviceBufferCount, final int deviceBufferSize) { - this.deviceBufferSize = deviceBufferSize; - this.deviceBufferCount = deviceBufferCount; - - registerSound("ogg", Ogg.Sound.class); - registerMusic("ogg", Ogg.Music.class); - registerSound("wav", Wav.Sound.class); - registerMusic("wav", Wav.Music.class); - registerSound("mp3", Mp3.Sound.class); - registerMusic("mp3", Mp3.Music.class); - registerSound("flac", Flac.Sound.class); - registerMusic("flac", Flac.Music.class); - - try { - AL.create(); - } - catch (final LWJGLException ex) { - this.noDevice = true; - ex.printStackTrace(); - return; - } - - this.allSources = new IntArray(false, simultaneousSources); - for (int i = 0; i < simultaneousSources; i++) { - final int sourceID = alGenSources(); - if (alGetError() != AL_NO_ERROR) { - break; - } - this.allSources.add(sourceID); - } - this.idleSources = new IntArray(this.allSources); - this.soundIdToSource = new LongMap(); - this.sourceToSoundId = new IntMap(); - - final FloatBuffer orientation = (FloatBuffer) BufferUtils.createFloatBuffer(6) - .put(new float[] { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f }).flip(); - alListener(AL_ORIENTATION, orientation); - final FloatBuffer velocity = (FloatBuffer) BufferUtils.createFloatBuffer(3) - .put(new float[] { 0.0f, 0.0f, 0.0f }).flip(); - alListener(AL_VELOCITY, velocity); - final FloatBuffer position = (FloatBuffer) BufferUtils.createFloatBuffer(3) - .put(new float[] { 0.0f, 0.0f, 0.0f }).flip(); - alListener(AL_POSITION, position); - - this.recentSounds = new OpenALSound[simultaneousSources]; - } - - public void registerSound(final String extension, final Class soundClass) { - if (extension == null) { - throw new IllegalArgumentException("extension cannot be null."); - } - if (soundClass == null) { - throw new IllegalArgumentException("soundClass cannot be null."); - } - this.extensionToSoundClass.put(extension, soundClass); - } - - public void registerMusic(final String extension, final Class musicClass) { - if (extension == null) { - throw new IllegalArgumentException("extension cannot be null."); - } - if (musicClass == null) { - throw new IllegalArgumentException("musicClass cannot be null."); - } - this.extensionToMusicClass.put(extension, musicClass); - } - - @Override - public OpenALSound newSound(final FileHandle file) { - if (file == null) { - throw new IllegalArgumentException("file cannot be null."); - } - final Class soundClass = this.extensionToSoundClass.get(file.extension().toLowerCase()); - if (soundClass == null) { - throw new GdxRuntimeException("Unknown file extension for sound: " + file); - } - try { - return soundClass.getConstructor(new Class[] { OpenALAudio.class, FileHandle.class }).newInstance(this, - file); - } - catch (final Exception ex) { - throw new GdxRuntimeException("Error creating sound " + soundClass.getName() + " for file: " + file, ex); - } - } - - @Override - public OpenALMusic newMusic(final FileHandle file) { - if (file == null) { - throw new IllegalArgumentException("file cannot be null."); - } - final Class musicClass = this.extensionToMusicClass.get(file.extension().toLowerCase()); - if (musicClass == null) { - throw new GdxRuntimeException("Unknown file extension for music: " + file); - } - try { - return musicClass.getConstructor(new Class[] { OpenALAudio.class, FileHandle.class }).newInstance(this, - file); - } - catch (final Exception ex) { - throw new GdxRuntimeException("Error creating music " + musicClass.getName() + " for file: " + file, ex); - } - } - - int obtainSource(final boolean isMusic) { - if (this.noDevice) { - return 0; - } - for (int i = 0, n = this.idleSources.size; i < n; i++) { - final int sourceId = this.idleSources.get(i); - final int state = alGetSourcei(sourceId, AL_SOURCE_STATE); - if ((state != AL_PLAYING) && (state != AL_PAUSED)) { - if (isMusic) { - this.idleSources.removeIndex(i); - } - else { - if (this.sourceToSoundId.containsKey(sourceId)) { - final long soundId = this.sourceToSoundId.get(sourceId); - this.sourceToSoundId.remove(sourceId); - this.soundIdToSource.remove(soundId); - } - - final long soundId = this.nextSoundId++; - this.sourceToSoundId.put(sourceId, soundId); - this.soundIdToSource.put(soundId, sourceId); - } - alSourceStop(sourceId); - alSourcei(sourceId, AL_BUFFER, 0); - AL10.alSourcef(sourceId, AL10.AL_GAIN, 1); - AL10.alSourcef(sourceId, AL10.AL_PITCH, 1); - AL10.alSource3f(sourceId, AL10.AL_POSITION, 0, 0, 1f); - return sourceId; - } - } - return -1; - } - - void freeSource(final int sourceID) { - if (this.noDevice) { - return; - } - alSourceStop(sourceID); - alSourcei(sourceID, AL_BUFFER, 0); - if (this.sourceToSoundId.containsKey(sourceID)) { - final long soundId = this.sourceToSoundId.remove(sourceID); - this.soundIdToSource.remove(soundId); - } - this.idleSources.add(sourceID); - } - - void freeBuffer(final int bufferID) { - if (this.noDevice) { - return; - } - for (int i = 0, n = this.idleSources.size; i < n; i++) { - final int sourceID = this.idleSources.get(i); - if (alGetSourcei(sourceID, AL_BUFFER) == bufferID) { - if (this.sourceToSoundId.containsKey(sourceID)) { - final long soundId = this.sourceToSoundId.remove(sourceID); - this.soundIdToSource.remove(soundId); - } - alSourceStop(sourceID); - alSourcei(sourceID, AL_BUFFER, 0); - } - } - } - - void stopSourcesWithBuffer(final int bufferID) { - if (this.noDevice) { - return; - } - for (int i = 0, n = this.idleSources.size; i < n; i++) { - final int sourceID = this.idleSources.get(i); - if (alGetSourcei(sourceID, AL_BUFFER) == bufferID) { - if (this.sourceToSoundId.containsKey(sourceID)) { - final long soundId = this.sourceToSoundId.remove(sourceID); - this.soundIdToSource.remove(soundId); - } - alSourceStop(sourceID); - } - } - } - - void pauseSourcesWithBuffer(final int bufferID) { - if (this.noDevice) { - return; - } - for (int i = 0, n = this.idleSources.size; i < n; i++) { - final int sourceID = this.idleSources.get(i); - if (alGetSourcei(sourceID, AL_BUFFER) == bufferID) { - alSourcePause(sourceID); - } - } - } - - void resumeSourcesWithBuffer(final int bufferID) { - if (this.noDevice) { - return; - } - for (int i = 0, n = this.idleSources.size; i < n; i++) { - final int sourceID = this.idleSources.get(i); - if (alGetSourcei(sourceID, AL_BUFFER) == bufferID) { - if (alGetSourcei(sourceID, AL_SOURCE_STATE) == AL_PAUSED) { - alSourcePlay(sourceID); - } - } - } - } - - public void update() { - if (this.noDevice) { - return; - } - for (int i = 0; i < this.music.size; i++) { - this.music.items[i].update(); - } - } - - public long getSoundId(final int sourceId) { - if (!this.sourceToSoundId.containsKey(sourceId)) { - return -1; - } - return this.sourceToSoundId.get(sourceId); - } - - public void stopSound(final long soundId) { - if (!this.soundIdToSource.containsKey(soundId)) { - return; - } - final int sourceId = this.soundIdToSource.get(soundId); - alSourceStop(sourceId); - } - - public void pauseSound(final long soundId) { - if (!this.soundIdToSource.containsKey(soundId)) { - return; - } - final int sourceId = this.soundIdToSource.get(soundId); - alSourcePause(sourceId); - } - - public void resumeSound(final long soundId) { - if (!this.soundIdToSource.containsKey(soundId)) { - return; - } - final int sourceId = this.soundIdToSource.get(soundId); - if (alGetSourcei(sourceId, AL_SOURCE_STATE) == AL_PAUSED) { - alSourcePlay(sourceId); - } - } - - public void setSoundGain(final long soundId, final float volume) { - if (!this.soundIdToSource.containsKey(soundId)) { - return; - } - final int sourceId = this.soundIdToSource.get(soundId); - AL10.alSourcef(sourceId, AL10.AL_GAIN, volume); - } - - public void setSoundLooping(final long soundId, final boolean looping) { - if (!this.soundIdToSource.containsKey(soundId)) { - return; - } - final int sourceId = this.soundIdToSource.get(soundId); - alSourcei(sourceId, AL10.AL_LOOPING, looping ? AL10.AL_TRUE : AL10.AL_FALSE); - } - - public void setSoundPitch(final long soundId, final float pitch) { - if (!this.soundIdToSource.containsKey(soundId)) { - return; - } - final int sourceId = this.soundIdToSource.get(soundId); - AL10.alSourcef(sourceId, AL10.AL_PITCH, pitch); - } - - public void setSoundPan(final long soundId, final float pan, final float volume) { - if (!this.soundIdToSource.containsKey(soundId)) { - return; - } - final int sourceId = this.soundIdToSource.get(soundId); - - AL10.alSource3f(sourceId, AL10.AL_POSITION, MathUtils.cos(((pan - 1) * MathUtils.PI) / 2), 0, - MathUtils.sin(((pan + 1) * MathUtils.PI) / 2)); - AL10.alSourcef(sourceId, AL10.AL_GAIN, volume); - } - - public void setSoundPosition(final long soundId, final float x, final float y, final float z, - final boolean is3DSound, final float maxDistance, final float refDistance) { - if (!this.soundIdToSource.containsKey(soundId)) { - return; - } - final int sourceId = this.soundIdToSource.get(soundId); - - AL10.alSource3f(sourceId, AL10.AL_POSITION, x, y, z); - AL10.alSourcef(sourceId, AL10.AL_MAX_DISTANCE, maxDistance); - AL10.alSourcef(sourceId, AL10.AL_REFERENCE_DISTANCE, refDistance); - AL10.alSourcef(sourceId, AL10.AL_ROLLOFF_FACTOR, 1.0f); - AL10.alSourcei(sourceId, AL10.AL_SOURCE_RELATIVE, is3DSound ? AL10.AL_FALSE : AL10.AL_TRUE); - } - - public void dispose() { - if (this.noDevice) { - return; - } - for (int i = 0, n = this.allSources.size; i < n; i++) { - final int sourceID = this.allSources.get(i); - final int state = alGetSourcei(sourceID, AL_SOURCE_STATE); - if (state != AL_STOPPED) { - alSourceStop(sourceID); - } - alDeleteSources(sourceID); - } - - this.sourceToSoundId.clear(); - this.soundIdToSource.clear(); - - AL.destroy(); - while (AL.isCreated()) { - try { - Thread.sleep(10); - } - catch (final InterruptedException e) { - } - } - } - - @Override - public AudioDevice newAudioDevice(final int sampleRate, final boolean isMono) { - if (this.noDevice) { - return new AudioDevice() { - @Override - public void writeSamples(final float[] samples, final int offset, final int numSamples) { - } - - @Override - public void writeSamples(final short[] samples, final int offset, final int numSamples) { - } - - @Override - public void setVolume(final float volume) { - } - - @Override - public boolean isMono() { - return isMono; - } - - @Override - public int getLatency() { - return 0; - } - - @Override - public void dispose() { - } - }; - } - return new OpenALAudioDevice(this, sampleRate, isMono, this.deviceBufferSize, this.deviceBufferCount); - } - - @Override - public AudioRecorder newAudioRecorder(final int samplingRate, final boolean isMono) { - if (this.noDevice) { - return new AudioRecorder() { - @Override - public void read(final short[] samples, final int offset, final int numSamples) { - } - - @Override - public void dispose() { - } - }; - } - return new JavaSoundAudioRecorder(samplingRate, isMono); - } - - /** - * Retains a list of the most recently played sounds and stops the sound played - * least recently if necessary for a new sound to play - */ - protected void retain(final OpenALSound sound, final boolean stop) { - // Move the pointer ahead and wrap - this.mostRecetSound++; - this.mostRecetSound %= this.recentSounds.length; - - if (stop) { - // Stop the least recent sound (the one we are about to bump off the buffer) - if (this.recentSounds[this.mostRecetSound] != null) { - this.recentSounds[this.mostRecetSound].stop(); - } - } - - this.recentSounds[this.mostRecetSound] = sound; - } - - /** Removes the disposed sound from the least recently played list */ - public void forget(final OpenALSound sound) { - for (int i = 0; i < this.recentSounds.length; i++) { - if (this.recentSounds[i] == sound) { - this.recentSounds[i] = null; - } - } - } -} diff --git a/desktop/src/com/etheller/warsmash/audio/OpenALAudioDevice.java b/desktop/src/com/etheller/warsmash/audio/OpenALAudioDevice.java deleted file mode 100644 index a251466b..00000000 --- a/desktop/src/com/etheller/warsmash/audio/OpenALAudioDevice.java +++ /dev/null @@ -1,265 +0,0 @@ -/******************************************************************************* - * Copyright 2011 See AUTHORS file. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package com.etheller.warsmash.audio; - -import static org.lwjgl.openal.AL10.AL_BUFFERS_PROCESSED; -import static org.lwjgl.openal.AL10.AL_FALSE; -import static org.lwjgl.openal.AL10.AL_FORMAT_MONO16; -import static org.lwjgl.openal.AL10.AL_FORMAT_STEREO16; -import static org.lwjgl.openal.AL10.AL_GAIN; -import static org.lwjgl.openal.AL10.AL_INVALID_VALUE; -import static org.lwjgl.openal.AL10.AL_LOOPING; -import static org.lwjgl.openal.AL10.AL_NO_ERROR; -import static org.lwjgl.openal.AL10.AL_PLAYING; -import static org.lwjgl.openal.AL10.AL_SOURCE_STATE; -import static org.lwjgl.openal.AL10.alBufferData; -import static org.lwjgl.openal.AL10.alDeleteBuffers; -import static org.lwjgl.openal.AL10.alGenBuffers; -import static org.lwjgl.openal.AL10.alGetError; -import static org.lwjgl.openal.AL10.alGetSourcef; -import static org.lwjgl.openal.AL10.alGetSourcei; -import static org.lwjgl.openal.AL10.alSourcePlay; -import static org.lwjgl.openal.AL10.alSourceQueueBuffers; -import static org.lwjgl.openal.AL10.alSourceUnqueueBuffers; -import static org.lwjgl.openal.AL10.alSourcef; -import static org.lwjgl.openal.AL10.alSourcei; - -import java.nio.ByteBuffer; -import java.nio.IntBuffer; - -import org.lwjgl.BufferUtils; -import org.lwjgl.openal.AL11; - -import com.badlogic.gdx.audio.AudioDevice; -import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.utils.GdxRuntimeException; - -/** @author Nathan Sweet */ -public class OpenALAudioDevice implements AudioDevice { - static private final int bytesPerSample = 2; - - private final OpenALAudio audio; - private final int channels; - private IntBuffer buffers; - private int sourceID = -1; - private final int format, sampleRate; - private boolean isPlaying; - private float volume = 1; - private float renderedSeconds; - - private final float secondsPerBuffer; - private byte[] bytes; - private final int bufferSize; - private final int bufferCount; - private final ByteBuffer tempBuffer; - - public OpenALAudioDevice(final OpenALAudio audio, final int sampleRate, final boolean isMono, final int bufferSize, - final int bufferCount) { - this.audio = audio; - this.channels = isMono ? 1 : 2; - this.bufferSize = bufferSize; - this.bufferCount = bufferCount; - this.format = this.channels > 1 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; - this.sampleRate = sampleRate; - this.secondsPerBuffer = (float) bufferSize / bytesPerSample / this.channels / sampleRate; - this.tempBuffer = BufferUtils.createByteBuffer(bufferSize); - } - - @Override - public void writeSamples(final short[] samples, final int offset, final int numSamples) { - if ((this.bytes == null) || (this.bytes.length < (numSamples * 2))) { - this.bytes = new byte[numSamples * 2]; - } - final int end = Math.min(offset + numSamples, samples.length); - for (int i = offset, ii = 0; i < end; i++) { - final short sample = samples[i]; - this.bytes[ii++] = (byte) (sample & 0xFF); - this.bytes[ii++] = (byte) ((sample >> 8) & 0xFF); - } - writeSamples(this.bytes, 0, numSamples * 2); - } - - @Override - public void writeSamples(final float[] samples, final int offset, final int numSamples) { - if ((this.bytes == null) || (this.bytes.length < (numSamples * 2))) { - this.bytes = new byte[numSamples * 2]; - } - final int end = Math.min(offset + numSamples, samples.length); - for (int i = offset, ii = 0; i < end; i++) { - float floatSample = samples[i]; - floatSample = MathUtils.clamp(floatSample, -1f, 1f); - final int intSample = (int) (floatSample * 32767); - this.bytes[ii++] = (byte) (intSample & 0xFF); - this.bytes[ii++] = (byte) ((intSample >> 8) & 0xFF); - } - writeSamples(this.bytes, 0, numSamples * 2); - } - - public void writeSamples(final byte[] data, int offset, int length) { - if (length < 0) { - throw new IllegalArgumentException("length cannot be < 0."); - } - - if (this.sourceID == -1) { - this.sourceID = this.audio.obtainSource(true); - if (this.sourceID == -1) { - return; - } - if (this.buffers == null) { - this.buffers = BufferUtils.createIntBuffer(this.bufferCount); - alGenBuffers(this.buffers); - if (alGetError() != AL_NO_ERROR) { - throw new GdxRuntimeException("Unabe to allocate audio buffers."); - } - } - alSourcei(this.sourceID, AL_LOOPING, AL_FALSE); - alSourcef(this.sourceID, AL_GAIN, this.volume); - // Fill initial buffers. - int queuedBuffers = 0; - for (int i = 0; i < this.bufferCount; i++) { - final int bufferID = this.buffers.get(i); - final int written = Math.min(this.bufferSize, length); - this.tempBuffer.clear(); - this.tempBuffer.put(data, offset, written).flip(); - alBufferData(bufferID, this.format, this.tempBuffer, this.sampleRate); - alSourceQueueBuffers(this.sourceID, bufferID); - length -= written; - offset += written; - queuedBuffers++; - } - // Queue rest of buffers, empty. - this.tempBuffer.clear().flip(); - for (int i = queuedBuffers; i < this.bufferCount; i++) { - final int bufferID = this.buffers.get(i); - alBufferData(bufferID, this.format, this.tempBuffer, this.sampleRate); - alSourceQueueBuffers(this.sourceID, bufferID); - } - alSourcePlay(this.sourceID); - this.isPlaying = true; - } - - while (length > 0) { - final int written = fillBuffer(data, offset, length); - length -= written; - offset += written; - } - } - - /** Blocks until some of the data could be buffered. */ - private int fillBuffer(final byte[] data, final int offset, final int length) { - final int written = Math.min(this.bufferSize, length); - - outer: while (true) { - int buffers = alGetSourcei(this.sourceID, AL_BUFFERS_PROCESSED); - while (buffers-- > 0) { - final int bufferID = alSourceUnqueueBuffers(this.sourceID); - if (bufferID == AL_INVALID_VALUE) { - break; - } - this.renderedSeconds += this.secondsPerBuffer; - - this.tempBuffer.clear(); - this.tempBuffer.put(data, offset, written).flip(); - alBufferData(bufferID, this.format, this.tempBuffer, this.sampleRate); - - alSourceQueueBuffers(this.sourceID, bufferID); - break outer; - } - // Wait for buffer to be free. - try { - Thread.sleep((long) (1000 * this.secondsPerBuffer)); - } - catch (final InterruptedException ignored) { - } - } - - // A buffer underflow will cause the source to stop. - if (!this.isPlaying || (alGetSourcei(this.sourceID, AL_SOURCE_STATE) != AL_PLAYING)) { - alSourcePlay(this.sourceID); - this.isPlaying = true; - } - - return written; - } - - public void stop() { - if (this.sourceID == -1) { - return; - } - this.audio.freeSource(this.sourceID); - this.sourceID = -1; - this.renderedSeconds = 0; - this.isPlaying = false; - } - - public boolean isPlaying() { - if (this.sourceID == -1) { - return false; - } - return this.isPlaying; - } - - @Override - public void setVolume(final float volume) { - this.volume = volume; - if (this.sourceID != -1) { - alSourcef(this.sourceID, AL_GAIN, volume); - } - } - - public float getPosition() { - if (this.sourceID == -1) { - return 0; - } - return this.renderedSeconds + alGetSourcef(this.sourceID, AL11.AL_SEC_OFFSET); - } - - public void setPosition(final float position) { - this.renderedSeconds = position; - } - - public int getChannels() { - return this.format == AL_FORMAT_STEREO16 ? 2 : 1; - } - - public int getRate() { - return this.sampleRate; - } - - @Override - public void dispose() { - if (this.buffers == null) { - return; - } - if (this.sourceID != -1) { - this.audio.freeSource(this.sourceID); - this.sourceID = -1; - } - alDeleteBuffers(this.buffers); - this.buffers = null; - } - - @Override - public boolean isMono() { - return this.channels == 1; - } - - @Override - public int getLatency() { - return (int) (this.secondsPerBuffer * this.bufferCount * 1000); - } -} diff --git a/desktop/src/com/etheller/warsmash/audio/OpenALMusic.java b/desktop/src/com/etheller/warsmash/audio/OpenALMusic.java deleted file mode 100644 index 279fea35..00000000 --- a/desktop/src/com/etheller/warsmash/audio/OpenALMusic.java +++ /dev/null @@ -1,396 +0,0 @@ -/******************************************************************************* - * Copyright 2011 See AUTHORS file. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package com.etheller.warsmash.audio; - -import static org.lwjgl.openal.AL10.AL_BUFFERS_PROCESSED; -import static org.lwjgl.openal.AL10.AL_BUFFERS_QUEUED; -import static org.lwjgl.openal.AL10.AL_FALSE; -import static org.lwjgl.openal.AL10.AL_FORMAT_MONO16; -import static org.lwjgl.openal.AL10.AL_FORMAT_STEREO16; -import static org.lwjgl.openal.AL10.AL_GAIN; -import static org.lwjgl.openal.AL10.AL_INVALID_VALUE; -import static org.lwjgl.openal.AL10.AL_LOOPING; -import static org.lwjgl.openal.AL10.AL_NO_ERROR; -import static org.lwjgl.openal.AL10.AL_PLAYING; -import static org.lwjgl.openal.AL10.AL_POSITION; -import static org.lwjgl.openal.AL10.AL_SOURCE_STATE; -import static org.lwjgl.openal.AL10.alBufferData; -import static org.lwjgl.openal.AL10.alDeleteBuffers; -import static org.lwjgl.openal.AL10.alGenBuffers; -import static org.lwjgl.openal.AL10.alGetError; -import static org.lwjgl.openal.AL10.alGetSourcef; -import static org.lwjgl.openal.AL10.alGetSourcei; -import static org.lwjgl.openal.AL10.alSource3f; -import static org.lwjgl.openal.AL10.alSourcePause; -import static org.lwjgl.openal.AL10.alSourcePlay; -import static org.lwjgl.openal.AL10.alSourceQueueBuffers; -import static org.lwjgl.openal.AL10.alSourceStop; -import static org.lwjgl.openal.AL10.alSourceUnqueueBuffers; -import static org.lwjgl.openal.AL10.alSourcef; -import static org.lwjgl.openal.AL10.alSourcei; - -import java.nio.ByteBuffer; -import java.nio.IntBuffer; - -import org.lwjgl.BufferUtils; -import org.lwjgl.openal.AL11; - -import com.badlogic.gdx.audio.Music; -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.utils.FloatArray; -import com.badlogic.gdx.utils.GdxRuntimeException; - -/** @author Nathan Sweet */ -public abstract class OpenALMusic implements Music { - static private final int bufferSize = 4096 * 10; - static private final int bufferCount = 3; - static private final int bytesPerSample = 2; - static private final byte[] tempBytes = new byte[bufferSize]; - static private final ByteBuffer tempBuffer = BufferUtils.createByteBuffer(bufferSize); - - private final FloatArray renderedSecondsQueue = new FloatArray(bufferCount); - - private final OpenALAudio audio; - private IntBuffer buffers; - private int sourceID = -1; - private int format, sampleRate; - private boolean isLooping, isPlaying; - private float volume = 1; - private float pan = 0; - private float renderedSeconds, maxSecondsPerBuffer; - - protected final FileHandle file; - protected int bufferOverhead = 0; - - private OnCompletionListener onCompletionListener; - - public OpenALMusic(final OpenALAudio audio, final FileHandle file) { - this.audio = audio; - this.file = file; - this.onCompletionListener = null; - } - - protected void setup(final int channels, final int sampleRate) { - this.format = channels > 1 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16; - this.sampleRate = sampleRate; - this.maxSecondsPerBuffer = (float) (bufferSize - this.bufferOverhead) - / (bytesPerSample * channels * sampleRate); - } - - @Override - public void play() { - if (this.audio.noDevice) { - return; - } - if (this.sourceID == -1) { - this.sourceID = this.audio.obtainSource(true); - if (this.sourceID == -1) { - return; - } - - this.audio.music.add(this); - - if (this.buffers == null) { - this.buffers = BufferUtils.createIntBuffer(bufferCount); - alGenBuffers(this.buffers); - final int errorCode = alGetError(); - if (errorCode != AL_NO_ERROR) { - throw new GdxRuntimeException("Unable to allocate audio buffers. AL Error: " + errorCode); - } - } - alSourcei(this.sourceID, AL_LOOPING, AL_FALSE); - setPan(this.pan, this.volume); - - boolean filled = false; // Check if there's anything to actually play. - for (int i = 0; i < bufferCount; i++) { - final int bufferID = this.buffers.get(i); - if (!fill(bufferID)) { - break; - } - filled = true; - alSourceQueueBuffers(this.sourceID, bufferID); - } - if (!filled && (this.onCompletionListener != null)) { - this.onCompletionListener.onCompletion(this); - } - - if (alGetError() != AL_NO_ERROR) { - stop(); - return; - } - } - if (!this.isPlaying) { - alSourcePlay(this.sourceID); - this.isPlaying = true; - } - } - - @Override - public void stop() { - if (this.audio.noDevice) { - return; - } - if (this.sourceID == -1) { - return; - } - this.audio.music.removeValue(this, true); - reset(); - this.audio.freeSource(this.sourceID); - this.sourceID = -1; - this.renderedSeconds = 0; - this.renderedSecondsQueue.clear(); - this.isPlaying = false; - } - - @Override - public void pause() { - if (this.audio.noDevice) { - return; - } - if (this.sourceID != -1) { - alSourcePause(this.sourceID); - } - this.isPlaying = false; - } - - @Override - public boolean isPlaying() { - if (this.audio.noDevice) { - return false; - } - if (this.sourceID == -1) { - return false; - } - return this.isPlaying; - } - - @Override - public void setLooping(final boolean isLooping) { - this.isLooping = isLooping; - } - - @Override - public boolean isLooping() { - return this.isLooping; - } - - @Override - public void setVolume(final float volume) { - this.volume = volume; - if (this.audio.noDevice) { - return; - } - if (this.sourceID != -1) { - alSourcef(this.sourceID, AL_GAIN, volume); - } - } - - @Override - public float getVolume() { - return this.volume; - } - - @Override - public void setPan(final float pan, final float volume) { - this.volume = volume; - this.pan = pan; - if (this.audio.noDevice) { - return; - } - if (this.sourceID == -1) { - return; - } - alSource3f(this.sourceID, AL_POSITION, MathUtils.cos(((pan - 1) * MathUtils.PI) / 2), 0, - MathUtils.sin(((pan + 1) * MathUtils.PI) / 2)); - alSourcef(this.sourceID, AL_GAIN, volume); - } - - @Override - public void setPosition(final float position) { - if (this.audio.noDevice) { - return; - } - if (this.sourceID == -1) { - return; - } - final boolean wasPlaying = this.isPlaying; - this.isPlaying = false; - alSourceStop(this.sourceID); - alSourceUnqueueBuffers(this.sourceID, this.buffers); - while (this.renderedSecondsQueue.size > 0) { - this.renderedSeconds = this.renderedSecondsQueue.pop(); - } - if (position <= this.renderedSeconds) { - reset(); - this.renderedSeconds = 0; - } - while (this.renderedSeconds < (position - this.maxSecondsPerBuffer)) { - if (read(tempBytes) <= 0) { - break; - } - this.renderedSeconds += this.maxSecondsPerBuffer; - } - this.renderedSecondsQueue.add(this.renderedSeconds); - boolean filled = false; - for (int i = 0; i < bufferCount; i++) { - final int bufferID = this.buffers.get(i); - if (!fill(bufferID)) { - break; - } - filled = true; - alSourceQueueBuffers(this.sourceID, bufferID); - } - this.renderedSecondsQueue.pop(); - if (!filled) { - stop(); - if (this.onCompletionListener != null) { - this.onCompletionListener.onCompletion(this); - } - } - alSourcef(this.sourceID, AL11.AL_SEC_OFFSET, position - this.renderedSeconds); - if (wasPlaying) { - alSourcePlay(this.sourceID); - this.isPlaying = true; - } - } - - @Override - public float getPosition() { - if (this.audio.noDevice) { - return 0; - } - if (this.sourceID == -1) { - return 0; - } - return this.renderedSeconds + alGetSourcef(this.sourceID, AL11.AL_SEC_OFFSET); - } - - /** - * Fills as much of the buffer as possible and returns the number of bytes - * filled. Returns <= 0 to indicate the end of the stream. - */ - abstract public int read(byte[] buffer); - - /** Resets the stream to the beginning. */ - abstract public void reset(); - - /** - * By default, does just the same as reset(). Used to add special behaviour in - * Ogg.Music. - */ - protected void loop() { - reset(); - } - - public int getChannels() { - return this.format == AL_FORMAT_STEREO16 ? 2 : 1; - } - - public int getRate() { - return this.sampleRate; - } - - public void update() { - if (this.audio.noDevice) { - return; - } - if (this.sourceID == -1) { - return; - } - - boolean end = false; - int buffers = alGetSourcei(this.sourceID, AL_BUFFERS_PROCESSED); - while (buffers-- > 0) { - final int bufferID = alSourceUnqueueBuffers(this.sourceID); - if (bufferID == AL_INVALID_VALUE) { - break; - } - this.renderedSeconds = this.renderedSecondsQueue.pop(); - if (end) { - continue; - } - if (fill(bufferID)) { - alSourceQueueBuffers(this.sourceID, bufferID); - } - else { - end = true; - } - } - if (end && (alGetSourcei(this.sourceID, AL_BUFFERS_QUEUED) == 0)) { - stop(); - if (this.onCompletionListener != null) { - this.onCompletionListener.onCompletion(this); - } - } - - // A buffer underflow will cause the source to stop. - if (this.isPlaying && (alGetSourcei(this.sourceID, AL_SOURCE_STATE) != AL_PLAYING)) { - alSourcePlay(this.sourceID); - } - } - - private boolean fill(final int bufferID) { - tempBuffer.clear(); - int length = read(tempBytes); - if (length <= 0) { - if (this.isLooping) { - loop(); - length = read(tempBytes); - if (length <= 0) { - return false; - } - if (this.renderedSecondsQueue.size > 0) { - this.renderedSecondsQueue.set(0, 0); - } - } - else { - return false; - } - } - final float previousLoadedSeconds = this.renderedSecondsQueue.size > 0 ? this.renderedSecondsQueue.first() : 0; - final float currentBufferSeconds = (this.maxSecondsPerBuffer * length) / bufferSize; - this.renderedSecondsQueue.insert(0, previousLoadedSeconds + currentBufferSeconds); - - tempBuffer.put(tempBytes, 0, length).flip(); - alBufferData(bufferID, this.format, tempBuffer, this.sampleRate); - return true; - } - - @Override - public void dispose() { - stop(); - if (this.audio.noDevice) { - return; - } - if (this.buffers == null) { - return; - } - alDeleteBuffers(this.buffers); - this.buffers = null; - this.onCompletionListener = null; - } - - @Override - public void setOnCompletionListener(final OnCompletionListener listener) { - this.onCompletionListener = listener; - } - - public int getSourceId() { - return this.sourceID; - } -} diff --git a/desktop/src/com/etheller/warsmash/audio/OpenALSound.java b/desktop/src/com/etheller/warsmash/audio/OpenALSound.java deleted file mode 100644 index 0a27681f..00000000 --- a/desktop/src/com/etheller/warsmash/audio/OpenALSound.java +++ /dev/null @@ -1,249 +0,0 @@ -/******************************************************************************* - * Copyright 2011 See AUTHORS file. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package com.etheller.warsmash.audio; - -import static org.lwjgl.openal.AL10.AL_BUFFER; -import static org.lwjgl.openal.AL10.AL_FALSE; -import static org.lwjgl.openal.AL10.AL_FORMAT_MONO16; -import static org.lwjgl.openal.AL10.AL_FORMAT_STEREO16; -import static org.lwjgl.openal.AL10.AL_GAIN; -import static org.lwjgl.openal.AL10.AL_LOOPING; -import static org.lwjgl.openal.AL10.AL_TRUE; -import static org.lwjgl.openal.AL10.alBufferData; -import static org.lwjgl.openal.AL10.alDeleteBuffers; -import static org.lwjgl.openal.AL10.alGenBuffers; -import static org.lwjgl.openal.AL10.alSourcePlay; -import static org.lwjgl.openal.AL10.alSourcef; -import static org.lwjgl.openal.AL10.alSourcei; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import com.badlogic.gdx.audio.Sound; - -/** @author Nathan Sweet */ -public class OpenALSound implements Sound { - private int bufferID = -1; - private final OpenALAudio audio; - private float duration; - - public OpenALSound(final OpenALAudio audio) { - this.audio = audio; - } - - void setup(final byte[] pcm, final int channels, final int sampleRate) { - final int bytes = pcm.length - (pcm.length % (channels > 1 ? 4 : 2)); - final int samples = bytes / (2 * channels); - this.duration = samples / (float) sampleRate; - - final ByteBuffer buffer = ByteBuffer.allocateDirect(bytes); - buffer.order(ByteOrder.nativeOrder()); - buffer.put(pcm, 0, bytes); - buffer.flip(); - - if (this.bufferID == -1) { - this.bufferID = alGenBuffers(); - alBufferData(this.bufferID, channels > 1 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16, buffer.asShortBuffer(), - sampleRate); - } - } - - @Override - public long play() { - return play(1); - } - - @Override - public long play(final float volume) { - if (this.audio.noDevice) { - return 0; - } - int sourceID = this.audio.obtainSource(false); - if (sourceID == -1) { - // Attempt to recover by stopping the least recently played sound - this.audio.retain(this, true); - sourceID = this.audio.obtainSource(false); - } - else { - this.audio.retain(this, false); - } - // In case it still didn't work - if (sourceID == -1) { - return -1; - } - final long soundId = this.audio.getSoundId(sourceID); - alSourcei(sourceID, AL_BUFFER, this.bufferID); - alSourcei(sourceID, AL_LOOPING, AL_FALSE); - alSourcef(sourceID, AL_GAIN, volume); - alSourcePlay(sourceID); - return soundId; - } - - @Override - public long loop() { - return loop(1); - } - - @Override - public long loop(final float volume) { - if (this.audio.noDevice) { - return 0; - } - final int sourceID = this.audio.obtainSource(false); - if (sourceID == -1) { - return -1; - } - final long soundId = this.audio.getSoundId(sourceID); - alSourcei(sourceID, AL_BUFFER, this.bufferID); - alSourcei(sourceID, AL_LOOPING, AL_TRUE); - alSourcef(sourceID, AL_GAIN, volume); - alSourcePlay(sourceID); - return soundId; - } - - @Override - public void stop() { - if (this.audio.noDevice) { - return; - } - this.audio.stopSourcesWithBuffer(this.bufferID); - } - - @Override - public void dispose() { - if (this.audio.noDevice) { - return; - } - if (this.bufferID == -1) { - return; - } - this.audio.freeBuffer(this.bufferID); - alDeleteBuffers(this.bufferID); - this.bufferID = -1; - this.audio.forget(this); - } - - @Override - public void stop(final long soundId) { - if (this.audio.noDevice) { - return; - } - this.audio.stopSound(soundId); - } - - @Override - public void pause() { - if (this.audio.noDevice) { - return; - } - this.audio.pauseSourcesWithBuffer(this.bufferID); - } - - @Override - public void pause(final long soundId) { - if (this.audio.noDevice) { - return; - } - this.audio.pauseSound(soundId); - } - - @Override - public void resume() { - if (this.audio.noDevice) { - return; - } - this.audio.resumeSourcesWithBuffer(this.bufferID); - } - - @Override - public void resume(final long soundId) { - if (this.audio.noDevice) { - return; - } - this.audio.resumeSound(soundId); - } - - @Override - public void setPitch(final long soundId, final float pitch) { - if (this.audio.noDevice) { - return; - } - this.audio.setSoundPitch(soundId, pitch); - } - - @Override - public void setVolume(final long soundId, final float volume) { - if (this.audio.noDevice) { - return; - } - this.audio.setSoundGain(soundId, volume); - } - - @Override - public void setLooping(final long soundId, final boolean looping) { - if (this.audio.noDevice) { - return; - } - this.audio.setSoundLooping(soundId, looping); - } - - @Override - public void setPan(final long soundId, final float pan, final float volume) { - if (this.audio.noDevice) { - return; - } - this.audio.setSoundPan(soundId, pan, volume); - } - - public void setPosition(final long soundId, final float x, final float y, final float z, final boolean is3DSound, - final float maxDistance, final float refDistance) { - if (this.audio.noDevice) { - return; - } - this.audio.setSoundPosition(soundId, x, y, z, is3DSound, maxDistance, refDistance); - } - - @Override - public long play(final float volume, final float pitch, final float pan) { - final long id = play(); - setPitch(id, pitch); - setPan(id, pan, volume); - return id; - } - - public long play(final float volume, final float pitch, final float x, final float y, final float z, - final boolean is3DSound, final float maxDistance, final float refDistance, final boolean looping) { - final long id = looping ? loop() : play(); - setPitch(id, pitch); - setVolume(id, volume); - setPosition(id, x, y, z, is3DSound, maxDistance, refDistance); - return id; - } - - @Override - public long loop(final float volume, final float pitch, final float pan) { - final long id = loop(); - setPitch(id, pitch); - setPan(id, pan, volume); - return id; - } - - /** Returns the length of the sound in seconds. */ - public float duration() { - return this.duration; - } -} diff --git a/desktop/src/com/etheller/warsmash/audio/Wav.java b/desktop/src/com/etheller/warsmash/audio/Wav.java deleted file mode 100644 index 7c8b6e3a..00000000 --- a/desktop/src/com/etheller/warsmash/audio/Wav.java +++ /dev/null @@ -1,201 +0,0 @@ -/******************************************************************************* - * Copyright 2011 See AUTHORS file. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package com.etheller.warsmash.audio; - -import java.io.EOFException; -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - -import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.utils.GdxRuntimeException; -import com.badlogic.gdx.utils.StreamUtils; - -public class Wav { - static public class Music extends OpenALMusic { - private WavInputStream input; - - public Music(final OpenALAudio audio, final FileHandle file) { - super(audio, file); - this.input = new WavInputStream(file); - if (audio.noDevice) { - return; - } - setup(this.input.channels, this.input.sampleRate); - } - - @Override - public int read(final byte[] buffer) { - if (this.input == null) { - this.input = new WavInputStream(this.file); - setup(this.input.channels, this.input.sampleRate); - } - try { - return this.input.read(buffer); - } - catch (final IOException ex) { - throw new GdxRuntimeException("Error reading WAV file: " + this.file, ex); - } - } - - @Override - public void reset() { - StreamUtils.closeQuietly(this.input); - this.input = null; - } - } - - static public class Sound extends OpenALSound { - public Sound(final OpenALAudio audio, final FileHandle file) { - super(audio); - if (audio.noDevice) { - return; - } - - WavInputStream input = null; - try { - input = new WavInputStream(file); - setup(StreamUtils.copyStreamToByteArray(input, input.dataRemaining), input.channels, input.sampleRate); - } - catch (final IOException ex) { - throw new GdxRuntimeException("Error reading WAV file: " + file, ex); - } - finally { - StreamUtils.closeQuietly(input); - } - } - } - - /** @author Nathan Sweet */ - static public class WavInputStream extends FilterInputStream { - - public int channels, sampleRate, dataRemaining; - - public WavInputStream(final FileHandle file) { - this(file.read(), file); - } - - public WavInputStream(final InputStream stream, final Object loggableFile) { - super(stream); - try { - if ((read() != 'R') || (read() != 'I') || (read() != 'F') || (read() != 'F')) { - throw new GdxRuntimeException("RIFF header not found: " + loggableFile); - } - - skipFully(4); - - if ((read() != 'W') || (read() != 'A') || (read() != 'V') || (read() != 'E')) { - throw new GdxRuntimeException("Invalid wave file header: " + loggableFile); - } - - final int fmtChunkLength = seekToChunk('f', 'm', 't', ' '); - - // http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html - // http://soundfile.sapp.org/doc/WaveFormat/ - final int type = (read() & 0xff) | ((read() & 0xff) << 8); - if (type != 1) { - String name; - switch (type) { - case 0x0002: - name = "ADPCM"; - break; - case 0x0003: - name = "IEEE float"; - break; - case 0x0006: - name = "8-bit ITU-T G.711 A-law"; - break; - case 0x0007: - name = "8-bit ITU-T G.711 u-law"; - break; - case 0xFFFE: - name = "Extensible"; - break; - default: - name = "Unknown"; - } - throw new GdxRuntimeException( - "WAV files must be PCM, unsupported format: " + name + " (" + type + ")"); - } - - this.channels = (read() & 0xff) | ((read() & 0xff) << 8); - if ((this.channels != 1) && (this.channels != 2)) { - throw new GdxRuntimeException("WAV files must have 1 or 2 channels: " + this.channels); - } - - this.sampleRate = (read() & 0xff) | ((read() & 0xff) << 8) | ((read() & 0xff) << 16) - | ((read() & 0xff) << 24); - - skipFully(6); - - final int bitsPerSample = (read() & 0xff) | ((read() & 0xff) << 8); - if (bitsPerSample != 16) { - throw new GdxRuntimeException("WAV files must have 16 bits per sample: " + bitsPerSample); - } - - skipFully(fmtChunkLength - 16); - - this.dataRemaining = seekToChunk('d', 'a', 't', 'a'); - } - catch (final Throwable ex) { - StreamUtils.closeQuietly(this); - throw new GdxRuntimeException("Error reading WAV file: " + loggableFile, ex); - } - } - - private int seekToChunk(final char c1, final char c2, final char c3, final char c4) throws IOException { - while (true) { - boolean found = read() == c1; - found &= read() == c2; - found &= read() == c3; - found &= read() == c4; - final int chunkLength = (read() & 0xff) | ((read() & 0xff) << 8) | ((read() & 0xff) << 16) - | ((read() & 0xff) << 24); - if (chunkLength == -1) { - throw new IOException("Chunk not found: " + c1 + c2 + c3 + c4); - } - if (found) { - return chunkLength; - } - skipFully(chunkLength); - } - } - - private void skipFully(int count) throws IOException { - while (count > 0) { - final long skipped = this.in.skip(count); - if (skipped <= 0) { - throw new EOFException("Unable to skip."); - } - count -= skipped; - } - } - - @Override - public int read(final byte[] buffer) throws IOException { - if (this.dataRemaining == 0) { - return -1; - } - final int length = Math.min(super.read(buffer), this.dataRemaining); - if (length == -1) { - return -1; - } - this.dataRemaining -= length; - return length; - } - } -} diff --git a/desktop/src/com/etheller/warsmash/desktop/DesktopLauncher.java b/desktop/src/com/etheller/warsmash/desktop/DesktopLauncher.java deleted file mode 100644 index 598d1e94..00000000 --- a/desktop/src/com/etheller/warsmash/desktop/DesktopLauncher.java +++ /dev/null @@ -1,248 +0,0 @@ -package com.etheller.warsmash.desktop; - -import static org.lwjgl.openal.AL10.AL_ORIENTATION; -import static org.lwjgl.openal.AL10.AL_POSITION; -import static org.lwjgl.openal.AL10.alListener; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.nio.FloatBuffer; - -import org.lwjgl.BufferUtils; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL31; -import org.lwjgl.opengl.GL32; -import org.lwjgl.opengl.GL33; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Graphics.DisplayMode; -import com.badlogic.gdx.audio.Sound; -import com.badlogic.gdx.backends.lwjgl.LwjglApplication; -import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; -import com.badlogic.gdx.backends.lwjgl.LwjglNativesLoader; -import com.etheller.warsmash.WarsmashGdxMenuScreen; -import com.etheller.warsmash.WarsmashGdxMultiScreenGame; -import com.etheller.warsmash.audio.OpenALSound; -import com.etheller.warsmash.networking.MultiplayerHack; -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.util.StringBundle; -import com.etheller.warsmash.viewer5.AudioContext; -import com.etheller.warsmash.viewer5.AudioContext.Listener; -import com.etheller.warsmash.viewer5.AudioDestination; -import com.etheller.warsmash.viewer5.gl.ANGLEInstancedArrays; -import com.etheller.warsmash.viewer5.gl.AudioExtension; -import com.etheller.warsmash.viewer5.gl.DynamicShadowExtension; -import com.etheller.warsmash.viewer5.gl.Extensions; -import com.etheller.warsmash.viewer5.gl.WireframeExtension; - -public class DesktopLauncher { - public static void main(final String[] arg) { - final LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); - config.useGL30 = true; - config.gles30ContextMajorVersion = 3; - config.gles30ContextMinorVersion = 3; - // config.samples = 16; -// config.vSyncEnabled = false; -// config.foregroundFPS = 0; -// config.backgroundFPS = 0; - final DisplayMode desktopDisplayMode = LwjglApplicationConfiguration.getDesktopDisplayMode(); - config.width = desktopDisplayMode.width; - config.height = desktopDisplayMode.height; - String fileToLoad = null; - config.fullscreen = true; - boolean noLogs = false; - for (int argIndex = 0; argIndex < arg.length; argIndex++) { - if ("-windowed".equals(arg[argIndex])) { - config.fullscreen = false; - } - else if ("-nolog".equals(arg[argIndex])) { - noLogs = true; - } - else if ((arg.length > (argIndex + 1)) && "-loadfile".equals(arg[argIndex])) { - argIndex++; - fileToLoad = arg[argIndex]; - } - else if ((arg.length > (argIndex + 1)) && "-client".equals(arg[argIndex])) { - argIndex++; - MultiplayerHack.MULTIPLAYER_HACK_SERVER_ADDR = arg[argIndex]; - } - else if ((arg.length > (argIndex + 1)) && "-lp".equals(arg[argIndex])) { - argIndex++; - MultiplayerHack.LP_VAL = Integer.parseInt(arg[argIndex]); - } - } - if (!noLogs) { - new File("Logs").mkdir(); - try { - System.setOut(new PrintStream( - new FileOutputStream(new File("Logs/" + System.currentTimeMillis() + ".out.log")))); - } - catch (final FileNotFoundException e) { - e.printStackTrace(); - } - try { - System.setErr(new PrintStream( - new FileOutputStream(new File("Logs/" + System.currentTimeMillis() + ".err.log")))); - } - catch (final FileNotFoundException e) { - e.printStackTrace(); - } - } - loadExtensions(); - final DataTable warsmashIni = loadWarsmashIni(); - final WarsmashGdxMultiScreenGame warsmashGdxMultiScreenGame = new WarsmashGdxMultiScreenGame(); - new LwjglApplication(warsmashGdxMultiScreenGame, config); - final String finalFileToLoad = fileToLoad; - Gdx.app.postRunnable(new Runnable() { - @Override - public void run() { - final WarsmashGdxMenuScreen menuScreen = new WarsmashGdxMenuScreen(warsmashIni, - warsmashGdxMultiScreenGame); - warsmashGdxMultiScreenGame.setScreen(menuScreen); - if (finalFileToLoad != null) { - menuScreen.startMap(finalFileToLoad); - } - } - }); - } - - public static DataTable loadWarsmashIni() { - final DataTable warsmashIni = new DataTable(StringBundle.EMPTY); - try (FileInputStream warsmashIniInputStream = new FileInputStream("warsmash.ini")) { - warsmashIni.readTXT(warsmashIniInputStream, true); - } - catch (final FileNotFoundException e) { - throw new RuntimeException(e); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return warsmashIni; - } - - public static void loadExtensions() { - LwjglNativesLoader.load(); - Extensions.angleInstancedArrays = new ANGLEInstancedArrays() { - @Override - public void glVertexAttribDivisorANGLE(final int index, final int divisor) { - GL33.glVertexAttribDivisor(index, divisor); - } - - @Override - public void glDrawElementsInstancedANGLE(final int mode, final int count, final int type, - final int indicesOffset, final int instanceCount) { - GL31.glDrawElementsInstanced(mode, count, type, indicesOffset, instanceCount); - } - - @Override - public void glDrawArraysInstancedANGLE(final int mode, final int first, final int count, - final int instanceCount) { - GL31.glDrawArraysInstanced(mode, first, count, instanceCount); - } - }; - Extensions.dynamicShadowExtension = new DynamicShadowExtension() { - @Override - public void glFramebufferTexture(final int target, final int attachment, final int texture, - final int level) { - GL32.glFramebufferTexture(target, attachment, texture, level); - } - - @Override - public void glDrawBuffer(final int mode) { - GL11.glDrawBuffer(mode); - } - }; - Extensions.wireframeExtension = new WireframeExtension() { - @Override - public void glPolygonMode(final int face, final int mode) { - GL11.glPolygonMode(face, mode); - } - }; - Extensions.audio = new AudioExtension() { - final FloatBuffer orientation = (FloatBuffer) BufferUtils.createFloatBuffer(6).clear(); - final FloatBuffer position = (FloatBuffer) BufferUtils.createFloatBuffer(3).clear(); - - @Override - public float getDuration(final Sound sound) { - if (sound == null) { - return 1; - } - return ((OpenALSound) sound).duration(); - } - - @Override - public void play(final Sound buffer, final float volume, final float pitch, final float x, final float y, - final float z, final boolean is3dSound, final float maxDistance, final float refDistance, - final boolean looping) { - ((OpenALSound) buffer).play(volume, pitch, x, y, z, is3dSound, maxDistance, refDistance, looping); - } - - @Override - public AudioContext createContext(final boolean world) { - Listener listener; - if (world) { - listener = new Listener() { - private float x; - private float y; - private float z; - - @Override - public void setPosition(final float x, final float y, final float z) { - this.x = x; - this.y = y; - this.z = z; - position.put(0, x); - position.put(1, y); - position.put(2, z); - alListener(AL_POSITION, position); - } - - @Override - public float getX() { - return this.x; - } - - @Override - public float getY() { - return this.y; - } - - @Override - public float getZ() { - return this.z; - } - - @Override - public void setOrientation(final float forwardX, final float forwardY, final float forwardZ, - final float upX, final float upY, final float upZ) { - orientation.put(0, forwardX); - orientation.put(1, forwardY); - orientation.put(2, forwardZ); - orientation.put(3, upX); - orientation.put(4, upY); - orientation.put(5, upZ); - alListener(AL_ORIENTATION, orientation); - } - - @Override - public boolean is3DSupported() { - return true; - } - }; - } - else { - listener = Listener.DO_NOTHING; - } - - return new AudioContext(listener, new AudioDestination() { - }); - } - }; - Extensions.GL_LINE = GL11.GL_LINE; - Extensions.GL_FILL = GL11.GL_FILL; - } -} diff --git a/desktop/src/com/etheller/warsmash/desktop/editor/mdx/MdxEditorMain.java b/desktop/src/com/etheller/warsmash/desktop/editor/mdx/MdxEditorMain.java deleted file mode 100644 index ae7430b6..00000000 --- a/desktop/src/com/etheller/warsmash/desktop/editor/mdx/MdxEditorMain.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.etheller.warsmash.desktop.editor.mdx; - -import javax.swing.SwingUtilities; -import javax.swing.UIManager; - -import com.etheller.warsmash.desktop.DesktopLauncher; -import com.etheller.warsmash.desktop.editor.mdx.ui.YseraFrame; -import com.etheller.warsmash.units.DataTable; - -public class MdxEditorMain { - - public static void main(final String[] args) { - DesktopLauncher.loadExtensions(); - - try { - // UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel"); - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } - catch (final Exception exc) { - } - - final DataTable warsmashIni = DesktopLauncher.loadWarsmashIni(); - - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - final YseraFrame frame = new YseraFrame(warsmashIni); - frame.setVisible(true); - } - }); - } - -} diff --git a/desktop/src/com/etheller/warsmash/desktop/editor/mdx/listeners/YseraGUIListener.java b/desktop/src/com/etheller/warsmash/desktop/editor/mdx/listeners/YseraGUIListener.java deleted file mode 100644 index 7255d288..00000000 --- a/desktop/src/com/etheller/warsmash/desktop/editor/mdx/listeners/YseraGUIListener.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.etheller.warsmash.desktop.editor.mdx.listeners; - -import com.etheller.warsmash.util.SubscriberSetNotifier; -import com.hiveworkshop.rms.parsers.mdlx.MdlxModel; - -public interface YseraGUIListener { - void openModel(MdlxModel model); - - // probably repaint - void stateChanged(); - - class YseraGUINotifier extends SubscriberSetNotifier implements YseraGUIListener { - - @Override - public void openModel(final MdlxModel model) { - for (final YseraGUIListener listener : set) { - listener.openModel(model); - } - } - - @Override - public void stateChanged() { - for (final YseraGUIListener listener : set) { - listener.stateChanged(); - } - } - - } -} diff --git a/desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/AnimationControllerFrame.java b/desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/AnimationControllerFrame.java deleted file mode 100644 index 87dba1ff..00000000 --- a/desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/AnimationControllerFrame.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.etheller.warsmash.desktop.editor.mdx.ui; - -import javax.swing.JFrame; -import javax.swing.WindowConstants; - -import com.etheller.warsmash.WarsmashPreviewApplication; -import com.etheller.warsmash.desktop.editor.mdx.listeners.YseraGUIListener; -import com.hiveworkshop.rms.parsers.mdlx.MdlxModel; - -public class AnimationControllerFrame extends JFrame implements YseraGUIListener { - private final AnimationControllerPanel animationControllerPanel; - - public AnimationControllerFrame(final WarsmashPreviewApplication warsmashPreviewApplication) { - super("Animation Controller"); - this.animationControllerPanel = new AnimationControllerPanel(warsmashPreviewApplication); - setContentPane(this.animationControllerPanel); - setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE); - pack(); - } - - @Override - public void openModel(final MdlxModel model) { - this.animationControllerPanel.openModel(model); - } - - @Override - public void stateChanged() { - this.animationControllerPanel.stateChanged(); - } -} diff --git a/desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/AnimationControllerPanel.java b/desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/AnimationControllerPanel.java deleted file mode 100644 index abdd0536..00000000 --- a/desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/AnimationControllerPanel.java +++ /dev/null @@ -1,210 +0,0 @@ -package com.etheller.warsmash.desktop.editor.mdx.ui; - -import java.awt.Component; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseWheelEvent; -import java.awt.event.MouseWheelListener; - -import javax.swing.ButtonGroup; -import javax.swing.DefaultComboBoxModel; -import javax.swing.GroupLayout; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JSlider; -import javax.swing.JSpinner; -import javax.swing.SpinnerNumberModel; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.plaf.basic.BasicComboBoxRenderer; - -import com.etheller.warsmash.WarsmashPreviewApplication; -import com.etheller.warsmash.desktop.editor.mdx.listeners.YseraGUIListener; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode; -import com.hiveworkshop.rms.parsers.mdlx.MdlxModel; -import com.hiveworkshop.rms.parsers.mdlx.MdlxSequence; - -public class AnimationControllerPanel extends JPanel implements YseraGUIListener { - private final WarsmashPreviewApplication previewApplication; - private final DefaultComboBoxModel animations; - private final JComboBox animationBox; - private MdlxModel model; - private JRadioButton defaultLoopButton; - private JRadioButton alwaysLoopButton; - private JRadioButton neverLoopButton; - private JSlider speedSlider; - private JLabel speedSliderLabel; - - public AnimationControllerPanel(final WarsmashPreviewApplication previewApplication) { - this.previewApplication = previewApplication; - - this.animations = new DefaultComboBoxModel<>(); - repopulateSequenceList(); - this.animationBox = new JComboBox<>(this.animations); - this.animationBox.setRenderer(new BasicComboBoxRenderer() { - @Override - public Component getListCellRendererComponent(final JList list, final Object value, final int index, - final boolean isSelected, final boolean cellHasFocus) { - Object display = value == null ? "(Unanimated)" : ((MdlxSequence) value).getName(); - if ((value != null) && (AnimationControllerPanel.this.model != null)) { - display = "(" + AnimationControllerPanel.this.model.getSequences().indexOf(value) + ") " + display; - } - return super.getListCellRendererComponent(list, display, index, isSelected, cellHasFocus); - } - }); - this.animationBox.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - update(true); - } - }); - this.animationBox.setMaximumSize(new Dimension(99999999, 35)); - this.animationBox.setFocusable(true); - this.animationBox.addMouseWheelListener(new MouseWheelListener() { - @Override - public void mouseWheelMoved(final MouseWheelEvent e) { - final int wheelRotation = e.getWheelRotation(); - int previousSelectedIndex = AnimationControllerPanel.this.animationBox.getSelectedIndex(); - if (previousSelectedIndex < 0) { - previousSelectedIndex = 0; - } - int newIndex = previousSelectedIndex + wheelRotation; - if (newIndex > (AnimationControllerPanel.this.animations.getSize() - 1)) { - newIndex = AnimationControllerPanel.this.animations.getSize() - 1; - } - else if (newIndex < 0) { - newIndex = 0; - } - if (newIndex != previousSelectedIndex) { - AnimationControllerPanel.this.animationBox.setSelectedIndex(newIndex); - // animationBox.setSelectedIndex( - // ((newIndex % animations.getSize()) + animations.getSize()) % - // animations.getSize()); - } - } - }); - this.speedSlider = new JSlider(0, 100, 50); - this.speedSliderLabel = new JLabel("Speed: 100%"); - this.speedSlider.addChangeListener(new ChangeListener() { - @Override - public void stateChanged(final ChangeEvent e) { - update(false); - } - }); - - final JButton playAnimationButton = new JButton("Play Animation"); - final ActionListener playAnimationActionListener = new ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - update(true); - } - }; - playAnimationButton.addActionListener(playAnimationActionListener); - - this.defaultLoopButton = new JRadioButton("Default Loop"); - this.alwaysLoopButton = new JRadioButton("Always Loop"); - this.neverLoopButton = new JRadioButton("Never Loop"); - - final ButtonGroup buttonGroup = new ButtonGroup(); - buttonGroup.add(this.defaultLoopButton); - buttonGroup.add(this.alwaysLoopButton); - buttonGroup.add(this.neverLoopButton); - final ActionListener setLoopTypeActionListener = new ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - update(true); - } - }; - this.defaultLoopButton.addActionListener(setLoopTypeActionListener); - this.alwaysLoopButton.addActionListener(setLoopTypeActionListener); - this.neverLoopButton.addActionListener(setLoopTypeActionListener); - - final JLabel levelOfDetailLabel = new JLabel("Level of Detail"); - final JSpinner levelOfDetailSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 5, 1)); - levelOfDetailSpinner.addChangeListener(new ChangeListener() { - @Override - public void stateChanged(final ChangeEvent e) { -// listener.setLevelOfDetail(((Number) levelOfDetailSpinner.getValue()).intValue()); - } - }); - levelOfDetailSpinner.setMaximumSize(new Dimension(99999, 25)); - levelOfDetailLabel.setVisible(false); - levelOfDetailSpinner.setVisible(false); - - final GroupLayout groupLayout = new GroupLayout(this); - - groupLayout.setHorizontalGroup(groupLayout.createParallelGroup().addComponent(this.animationBox) - .addGroup(groupLayout.createSequentialGroup().addGap(8) - .addGroup(groupLayout.createParallelGroup().addComponent(playAnimationButton) - .addComponent(this.defaultLoopButton).addComponent(this.alwaysLoopButton) - .addComponent(this.neverLoopButton).addComponent(this.speedSliderLabel) - .addComponent(this.speedSlider).addComponent(levelOfDetailLabel) - .addComponent(levelOfDetailSpinner)) - .addGap(8) - - )); - groupLayout.setVerticalGroup(groupLayout.createSequentialGroup().addComponent(this.animationBox).addGap(32) - .addComponent(playAnimationButton).addGap(16).addComponent(this.defaultLoopButton) - .addComponent(this.alwaysLoopButton).addComponent(this.neverLoopButton).addGap(16) - .addComponent(this.speedSliderLabel).addComponent(this.speedSlider).addGap(16) - .addComponent(levelOfDetailLabel).addComponent(levelOfDetailSpinner) - - ); - setLayout(groupLayout); - - this.defaultLoopButton.doClick(); - } - - private void update(final boolean playSequence) { - SequenceLoopMode loopType; - if (this.defaultLoopButton.isSelected()) { - loopType = SequenceLoopMode.MODEL_LOOP; - } - else if (this.alwaysLoopButton.isSelected()) { - loopType = SequenceLoopMode.ALWAYS_LOOP; - } - else if (this.neverLoopButton.isSelected()) { - loopType = SequenceLoopMode.NEVER_LOOP; - } - else { - throw new IllegalStateException(); - } - this.speedSliderLabel.setText("Speed: " + (this.speedSlider.getValue() * 2) + "%"); - final MdxComplexInstance mainInstance = this.previewApplication.getMainInstance(); - if (mainInstance != null) { - mainInstance.setAnimationSpeed(this.speedSlider.getValue() / 50f); - mainInstance.setSequenceLoopMode(loopType); - if (playSequence) { - mainInstance.setSequence(this.animationBox.getSelectedIndex() - 1); - } - } - } - - @Override - public void openModel(final MdlxModel model) { - this.model = model; - - repopulateSequenceList(); - } - - private void repopulateSequenceList() { - this.animations.removeAllElements(); - this.animations.addElement(null); - if (this.model != null) { - for (final MdlxSequence animation : this.model.getSequences()) { - this.animations.addElement(animation); - } - } - } - - @Override - public void stateChanged() { - - } -} diff --git a/desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/YseraFrame.java b/desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/YseraFrame.java deleted file mode 100644 index e75c53fa..00000000 --- a/desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/YseraFrame.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.etheller.warsmash.desktop.editor.mdx.ui; - -import java.awt.event.WindowEvent; -import java.awt.event.WindowListener; - -import javax.swing.JFrame; - -import com.badlogic.gdx.Gdx; -import com.etheller.warsmash.WarsmashPreviewApplication; -import com.etheller.warsmash.units.DataTable; - -public class YseraFrame extends JFrame { - public YseraFrame(final DataTable warsmashIni) { - super("Warsmash Model Editor"); - setDefaultCloseOperation(DISPOSE_ON_CLOSE); - final WarsmashPreviewApplication warsmashPreviewApplication = new WarsmashPreviewApplication(warsmashIni); - final YseraPanel contentPane = new YseraPanel(warsmashPreviewApplication); - setContentPane(contentPane); -// setIconImage(ImageUtils.getBLPImage(warsmashGdxGame.getCodebase(), -// "ReplaceableTextures\\CommandButtons\\BTNGreenDragon.blp")); - setJMenuBar(contentPane.createJMenuBar(this)); - pack(); - setLocationRelativeTo(null); - - addWindowListener(new WindowListener() { - - @Override - public void windowOpened(final WindowEvent e) { - - } - - @Override - public void windowIconified(final WindowEvent e) { - - } - - @Override - public void windowDeiconified(final WindowEvent e) { - - } - - @Override - public void windowDeactivated(final WindowEvent e) { - - } - - @Override - public void windowClosing(final WindowEvent e) { - Gdx.app.exit(); - } - - @Override - public void windowClosed(final WindowEvent e) { - - } - - @Override - public void windowActivated(final WindowEvent e) { - - } - }); - } - -} diff --git a/desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/YseraPanel.java b/desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/YseraPanel.java deleted file mode 100644 index 340bf02f..00000000 --- a/desktop/src/com/etheller/warsmash/desktop/editor/mdx/ui/YseraPanel.java +++ /dev/null @@ -1,193 +0,0 @@ -package com.etheller.warsmash.desktop.editor.mdx.ui; - -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; - -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JPanel; -import javax.swing.filechooser.FileNameExtensionFilter; - -import org.lwjgl.util.vector.Quaternion; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Input; -import com.badlogic.gdx.InputProcessor; -import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; -import com.badlogic.gdx.backends.lwjgl.LwjglCanvas; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.WarsmashPreviewApplication; -import com.etheller.warsmash.desktop.editor.mdx.listeners.YseraGUIListener; -import com.etheller.warsmash.desktop.editor.util.ExceptionPopup; -import com.etheller.warsmash.viewer5.handlers.w3x.camera.PortraitCameraManager; -import com.hiveworkshop.rms.parsers.mdlx.MdlxModel; - -public class YseraPanel extends JPanel { - private static final Quaternion IDENTITY = new Quaternion(); - private final WarsmashPreviewApplication warsmashPreviewApplication; - private final JFileChooser userFileChooser = new JFileChooser(); - private final YseraGUIListener.YseraGUINotifier notifier = new YseraGUIListener.YseraGUINotifier(); - - private MdlxModel model; - - private AnimationControllerFrame animationControllerFrame; - - public YseraPanel(final WarsmashPreviewApplication warsmashPreviewApplication) { - this.warsmashPreviewApplication = warsmashPreviewApplication; - setLayout(new BorderLayout()); - final LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); - config.useGL30 = true; - config.gles30ContextMajorVersion = 3; - config.gles30ContextMinorVersion = 3; - final LwjglCanvas lwjglCanvas = new LwjglCanvas(warsmashPreviewApplication, config); - add(BorderLayout.CENTER, lwjglCanvas.getCanvas()); - setPreferredSize(new Dimension(640, 480)); - this.userFileChooser - .setFileFilter(new FileNameExtensionFilter("Warcraft III Model or Texture", "mdx", "mdl", "blp")); - - final CameraMouseHandler cameraMouseHandler = new CameraMouseHandler(warsmashPreviewApplication); - Gdx.input.setInputProcessor(cameraMouseHandler); - - } - - public JMenuBar createJMenuBar(final JFrame frame) { - final JMenuBar jMenuBar = new JMenuBar(); - - final JMenu fileMenu = new JMenu("File"); - final JMenuItem openItem = new JMenuItem("Open"); - openItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - try { - final int userResult = YseraPanel.this.userFileChooser.showOpenDialog(frame); - if (userResult == JFileChooser.APPROVE_OPTION) { - final File selectedFile = YseraPanel.this.userFileChooser.getSelectedFile(); - if (selectedFile != null) { - YseraPanel.this.model = YseraPanel.this.warsmashPreviewApplication - .loadCustomModel(selectedFile.getPath()); - YseraPanel.this.notifier.openModel(YseraPanel.this.model); - } - } - } - catch (final Exception exc) { - ExceptionPopup.display(exc); - } - } - }); - fileMenu.add(openItem); - jMenuBar.add(fileMenu); - jMenuBar.add(new JMenu("Recent Files")); - jMenuBar.add(new JMenu("Edit")); - jMenuBar.add(new JMenu("View")); - jMenuBar.add(new JMenu("Team Color")); - final JMenu windowMenu = new JMenu("Windows"); - final JMenuItem modelEditorItem = new JMenuItem("Model Editor"); - windowMenu.add(modelEditorItem); - final JMenuItem animationControllerItem = new JMenuItem("Animation Controller"); - animationControllerItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - if (YseraPanel.this.animationControllerFrame == null) { - YseraPanel.this.animationControllerFrame = new AnimationControllerFrame( - YseraPanel.this.warsmashPreviewApplication); - YseraPanel.this.notifier.subscribe(YseraPanel.this.animationControllerFrame); - YseraPanel.this.animationControllerFrame.setLocationRelativeTo(frame); - } - YseraPanel.this.animationControllerFrame.setVisible(true); - YseraPanel.this.animationControllerFrame.toFront(); - } - }); - windowMenu.add(animationControllerItem); - jMenuBar.add(windowMenu); - jMenuBar.add(new JMenu("Extras")); - jMenuBar.add(new JMenu("Help")); - - return jMenuBar; - } - - private static final class CameraMouseHandler implements InputProcessor { - private int lastX, lastY; - private final Vector3 screenDimension = new Vector3(); - private int button; - private final WarsmashPreviewApplication warsmashPreviewApplication; - - public CameraMouseHandler(final WarsmashPreviewApplication warsmashPreviewApplication) { - this.warsmashPreviewApplication = warsmashPreviewApplication; - } - - @Override - public boolean keyDown(final int keycode) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean keyUp(final int keycode) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean keyTyped(final char character) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean touchDown(final int screenX, final int screenY, final int pointer, final int button) { - this.lastX = screenX; - this.lastY = screenY; - this.button = button; - return false; - } - - @Override - public boolean touchUp(final int screenX, final int screenY, final int pointer, final int button) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean touchDragged(final int screenX, final int screenY, final int pointer) { - final int newX = screenX; - final int newY = screenY; - final int dx = newX - this.lastX; - final int dy = newY - this.lastY; - final PortraitCameraManager cameraManager = this.warsmashPreviewApplication.getCameraManager(); - if (this.button == Input.Buttons.RIGHT) { - this.screenDimension.set(-1, 0, 0); - this.screenDimension.unrotate(cameraManager.camera.viewProjectionMatrix); - cameraManager.target.add(this.screenDimension.nor().scl(dx * 5)); - this.screenDimension.set(0, 1, 0); - this.screenDimension.unrotate(cameraManager.camera.viewProjectionMatrix); - cameraManager.target.add(this.screenDimension.nor().scl(dy * 5)); - } - else if (this.button == Input.Buttons.LEFT) { - cameraManager.horizontalAngle -= Math.toRadians(dx); - cameraManager.verticalAngle -= Math.toRadians(dy); - } - this.lastX = newX; - this.lastY = newY; - return false; - } - - @Override - public boolean mouseMoved(final int screenX, final int screenY) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean scrolled(final int amount) { - final PortraitCameraManager cameraManager = this.warsmashPreviewApplication.getCameraManager(); - cameraManager.distance += amount * 100; - return false; - } - } -} diff --git a/desktop/src/com/etheller/warsmash/desktop/editor/util/ExceptionPopup.java b/desktop/src/com/etheller/warsmash/desktop/editor/util/ExceptionPopup.java deleted file mode 100644 index 588414aa..00000000 --- a/desktop/src/com/etheller/warsmash/desktop/editor/util/ExceptionPopup.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.etheller.warsmash.desktop.editor.util; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; - -import javax.swing.JOptionPane; -import javax.swing.JTextPane; -import javax.swing.text.BadLocationException; -import javax.swing.text.Document; - -public class ExceptionPopup { - public static void display(final Throwable e) { - - final JTextPane pane = new JTextPane(); - final OutputStream stream = new OutputStream() { - public void updateStreamWith(final String s) { - final Document doc = pane.getDocument(); - try { - doc.insertString(doc.getLength(), s, null); - } - catch (final BadLocationException e) { - JOptionPane.showMessageDialog(null, "MDL open error popup failed to create info popup."); - e.printStackTrace(); - } - } - - @Override - public void write(final int b) throws IOException { - updateStreamWith(String.valueOf((char) b)); - } - - @Override - public void write(final byte[] b, final int off, final int len) throws IOException { - updateStreamWith(new String(b, off, len)); - } - - @Override - public void write(final byte[] b) throws IOException { - write(b, 0, b.length); - } - }; - final PrintStream ps = new PrintStream(stream); - ps.println("Unknown error occurred:"); - e.printStackTrace(ps); - JOptionPane.showMessageDialog(null, pane); - } - - public static void display(final String s, final Exception e) { - - final JTextPane pane = new JTextPane(); - final OutputStream stream = new OutputStream() { - public void updateStreamWith(final String s) { - final Document doc = pane.getDocument(); - try { - doc.insertString(doc.getLength(), s, null); - } - catch (final BadLocationException e) { - JOptionPane.showMessageDialog(null, "MDL open error popup failed to create info popup."); - e.printStackTrace(); - } - } - - @Override - public void write(final int b) throws IOException { - updateStreamWith(String.valueOf((char) b)); - } - - @Override - public void write(final byte[] b, final int off, final int len) throws IOException { - updateStreamWith(new String(b, off, len)); - } - - @Override - public void write(final byte[] b) throws IOException { - write(b, 0, b.length); - } - }; - final PrintStream ps = new PrintStream(stream); - ps.println(s + ":"); - e.printStackTrace(ps); - JOptionPane.showMessageDialog(null, pane); - } -} diff --git a/desktop/src/com/etheller/warsmash/desktop/util/TerrainView.java b/desktop/src/com/etheller/warsmash/desktop/util/TerrainView.java deleted file mode 100644 index 08f50e8c..00000000 --- a/desktop/src/com/etheller/warsmash/desktop/util/TerrainView.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.etheller.warsmash.desktop.util; - -import java.io.IOException; - -import javax.swing.JFrame; -import javax.swing.JScrollPane; -import javax.swing.WindowConstants; - -import com.etheller.warsmash.WarsmashGdxMapScreen; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.desktop.DesktopLauncher; -import com.etheller.warsmash.parsers.w3x.War3Map; -import com.etheller.warsmash.parsers.w3x.w3e.War3MapW3e; -import com.etheller.warsmash.units.DataTable; - -public class TerrainView { - public static void main(final String[] args) { - final DataTable warsmashIni = DesktopLauncher.loadWarsmashIni(); - final DataSource dataSources = WarsmashGdxMapScreen.parseDataSources(warsmashIni); - final War3Map war3Map = new War3Map(dataSources, warsmashIni.get("Map").getField("FilePath")); - try { - final War3MapW3e environmentFile = war3Map.readEnvironment(); - final TerrainViewPanel terrainViewPanel = new TerrainViewPanel(environmentFile); - - final JFrame frame = new JFrame("TerrainView"); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - frame.setContentPane(new JScrollPane(terrainViewPanel)); - frame.setBounds(0, 0, 800, 600); - frame.setLocationRelativeTo(null); - frame.setVisible(true); - } - catch (final IOException e) { - e.printStackTrace(); - } - } -} diff --git a/desktop/src/com/etheller/warsmash/desktop/util/TerrainViewPanel.java b/desktop/src/com/etheller/warsmash/desktop/util/TerrainViewPanel.java deleted file mode 100644 index d1055c71..00000000 --- a/desktop/src/com/etheller/warsmash/desktop/util/TerrainViewPanel.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.etheller.warsmash.desktop.util; - -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Graphics; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; - -import javax.swing.Box; -import javax.swing.JPanel; - -import com.etheller.warsmash.parsers.w3x.w3e.Corner; -import com.etheller.warsmash.parsers.w3x.w3e.War3MapW3e; - -public class TerrainViewPanel extends JPanel { - private final War3MapW3e environmentFile; - private final Font baseFont; - private final Font biggerFont; - private int cliffMode = 0; - - public TerrainViewPanel(final War3MapW3e environmentFile) { - this.environmentFile = environmentFile; - add(Box.createRigidArea(new Dimension(this.environmentFile.getCorners()[0].length * 32, - this.environmentFile.getCorners().length * 32))); - this.baseFont = getFont(); - this.biggerFont = this.baseFont.deriveFont(24f); - addMouseListener(new MouseListener() { - @Override - public void mouseReleased(final MouseEvent e) { - - } - - @Override - public void mousePressed(final MouseEvent e) { - TerrainViewPanel.this.cliffMode = (TerrainViewPanel.this.cliffMode + 1) % 4; - repaint(); - } - - @Override - public void mouseExited(final MouseEvent e) { - - } - - @Override - public void mouseEntered(final MouseEvent e) { - - } - - @Override - public void mouseClicked(final MouseEvent e) { - - } - }); - } - - @Override - protected void paintComponent(final Graphics g) { - super.paintComponent(g); - final Corner[][] corners = this.environmentFile.getCorners(); - for (int i = 0; i < corners.length; i++) { - final int length = corners[i].length; - for (int j = 0; j < length; j++) { - int base = 0; - final int value; - switch (this.cliffMode) { - case 0: - value = corners[i][j].getRamp(); - break; - case 1: - value = corners[i][j].getLayerHeight(); - base = 2; - break; - case 2: - value = corners[i][j].getGroundTexture(); - break; - case 3: - value = corners[i][j].getCliffTexture(); - break; - default: - value = 0; - break; - } - if (value != base) { - g.setFont(this.biggerFont); - } - else { - g.setFont(this.baseFont); - } - g.drawString(value + "", j * 32, (length - i - 1) * 32); - } - } - } -} diff --git a/desktop/src/io/nayuki/flac/app/DecodeFlacToWav.java b/desktop/src/io/nayuki/flac/app/DecodeFlacToWav.java deleted file mode 100644 index bf47e3fe..00000000 --- a/desktop/src/io/nayuki/flac/app/DecodeFlacToWav.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.app; - -import java.io.BufferedOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Arrays; -import io.nayuki.flac.common.StreamInfo; -import io.nayuki.flac.decode.DataFormatException; -import io.nayuki.flac.decode.FlacDecoder; - - -/** - * Decodes a FLAC file to an uncompressed PCM WAV file. Overwrites output file if already exists. - * Runs silently if successful, otherwise prints error messages to standard error. - *

Usage: java DecodeFlacToWav InFile.flac OutFile.wav

- *

Requirements on the FLAC file:

- *
    - *
  • Sample depth is 8, 16, 24, or 32 bits (not 4, 17, 23, etc.)
  • - *
  • Contains no ID3v1 or ID3v2 tags, or other data unrecognized by the FLAC format
  • - *
  • Correct total number of samples (not zero) is stored in stream info block
  • - *
  • Every frame has a correct header, subframes do not overflow the sample depth, - * and other strict checks enforced by this decoder library
  • - *
- */ -public final class DecodeFlacToWav { - - public static void main(String[] args) throws IOException { - // Handle command line arguments - if (args.length != 2) { - System.err.println("Usage: java DecodeFlacToWav InFile.flac OutFile.wav"); - System.exit(1); - return; - } - File inFile = new File(args[0]); - File outFile = new File(args[1]); - - // Decode input FLAC file - StreamInfo streamInfo; - int[][] samples; - try (FlacDecoder dec = new FlacDecoder(inFile)) { - - // Handle metadata header blocks - while (dec.readAndHandleMetadataBlock() != null); - streamInfo = dec.streamInfo; - if (streamInfo.sampleDepth % 8 != 0) - throw new UnsupportedOperationException("Only whole-byte sample depth supported"); - - // Decode every block - samples = new int[streamInfo.numChannels][(int)streamInfo.numSamples]; - for (int off = 0; ;) { - int len = dec.readAudioBlock(samples, off); - if (len == 0) - break; - off += len; - } - } - - // Check audio MD5 hash - byte[] expectHash = streamInfo.md5Hash; - if (Arrays.equals(expectHash, new byte[16])) - System.err.println("Warning: MD5 hash field was blank"); - else if (!Arrays.equals(StreamInfo.getMd5Hash(samples, streamInfo.sampleDepth), expectHash)) - throw new DataFormatException("MD5 hash check failed"); - // Else the hash check passed - - // Start writing WAV output file - int bytesPerSample = streamInfo.sampleDepth / 8; - try (DataOutputStream out = new DataOutputStream( - new BufferedOutputStream(new FileOutputStream(outFile)))) { - DecodeFlacToWav.out = out; - - // Header chunk - int sampleDataLen = samples[0].length * streamInfo.numChannels * bytesPerSample; - out.writeInt(0x52494646); // "RIFF" - writeLittleInt32(sampleDataLen + 36); - out.writeInt(0x57415645); // "WAVE" - - // Metadata chunk - out.writeInt(0x666D7420); // "fmt " - writeLittleInt32(16); - writeLittleInt16(0x0001); - writeLittleInt16(streamInfo.numChannels); - writeLittleInt32(streamInfo.sampleRate); - writeLittleInt32(streamInfo.sampleRate * streamInfo.numChannels * bytesPerSample); - writeLittleInt16(streamInfo.numChannels * bytesPerSample); - writeLittleInt16(streamInfo.sampleDepth); - - // Audio data chunk ("data") - out.writeInt(0x64617461); // "data" - writeLittleInt32(sampleDataLen); - for (int i = 0; i < samples[0].length; i++) { - for (int j = 0; j < samples.length; j++) { - int val = samples[j][i]; - if (bytesPerSample == 1) - out.write(val + 128); // Convert to unsigned, as per WAV PCM conventions - else { // 2 <= bytesPerSample <= 4 - for (int k = 0; k < bytesPerSample; k++) - out.write(val >>> (k * 8)); // Little endian - } - } - } - } - } - - - // Helper members for writing WAV files - - private static DataOutputStream out; - - private static void writeLittleInt16(int x) throws IOException { - out.writeShort(Integer.reverseBytes(x) >>> 16); - } - - private static void writeLittleInt32(int x) throws IOException { - out.writeInt(Integer.reverseBytes(x)); - } - -} diff --git a/desktop/src/io/nayuki/flac/app/EncodeWavToFlac.java b/desktop/src/io/nayuki/flac/app/EncodeWavToFlac.java deleted file mode 100644 index 64fbd958..00000000 --- a/desktop/src/io/nayuki/flac/app/EncodeWavToFlac.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.app; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.EOFException; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.RandomAccessFile; -import java.nio.charset.StandardCharsets; -import io.nayuki.flac.common.StreamInfo; -import io.nayuki.flac.decode.DataFormatException; -import io.nayuki.flac.encode.BitOutputStream; -import io.nayuki.flac.encode.FlacEncoder; -import io.nayuki.flac.encode.RandomAccessFileOutputStream; -import io.nayuki.flac.encode.SubframeEncoder; - - -/** - * Encodes an uncompressed PCM WAV file to a FLAC file. - * Overwrites the output file if it already exists. - *

Usage: java EncodeWavToFlac InFile.wav OutFile.flac

- *

Requirements on the WAV file:

- *
    - *
  • Sample depth is 8, 16, 24, or 32 bits (not 4, 17, 23, etc.)
  • - *
  • Number of channels is between 1 to 8 inclusive
  • - *
  • Sample rate is less than 220 hertz
  • - *
- */ -public final class EncodeWavToFlac { - - public static void main(String[] args) throws IOException { - // Handle command line arguments - if (args.length != 2) { - System.err.println("Usage: java EncodeWavToFlac InFile.wav OutFile.flac"); - System.exit(1); - return; - } - File inFile = new File(args[0]); - File outFile = new File(args[1]); - - // Read WAV file headers and audio sample data - int[][] samples; - int sampleRate; - int sampleDepth; - try (InputStream in = new BufferedInputStream(new FileInputStream(inFile))) { - // Parse and check WAV header - if (!readString(in, 4).equals("RIFF")) - throw new DataFormatException("Invalid RIFF file header"); - readLittleUint(in, 4); // Remaining data length - if (!readString(in, 4).equals("WAVE")) - throw new DataFormatException("Invalid WAV file header"); - - // Handle the format chunk - if (!readString(in, 4).equals("fmt ")) - throw new DataFormatException("Unrecognized WAV file chunk"); - if (readLittleUint(in, 4) != 16) - throw new DataFormatException("Unsupported WAV file type"); - if (readLittleUint(in, 2) != 0x0001) - throw new DataFormatException("Unsupported WAV file codec"); - int numChannels = readLittleUint(in, 2); - if (numChannels < 0 || numChannels > 8) - throw new RuntimeException("Too many (or few) audio channels"); - sampleRate = readLittleUint(in, 4); - if (sampleRate <= 0 || sampleRate >= (1 << 20)) - throw new RuntimeException("Sample rate too large or invalid"); - int byteRate = readLittleUint(in, 4); - int blockAlign = readLittleUint(in, 2); - sampleDepth = readLittleUint(in, 2); - if (sampleDepth == 0 || sampleDepth > 32 || sampleDepth % 8 != 0) - throw new RuntimeException("Unsupported sample depth"); - int bytesPerSample = sampleDepth / 8; - if (bytesPerSample * numChannels != blockAlign) - throw new RuntimeException("Invalid block align value"); - if (bytesPerSample * numChannels * sampleRate != byteRate) - throw new RuntimeException("Invalid byte rate value"); - - // Handle the data chunk - if (!readString(in, 4).equals("data")) - throw new DataFormatException("Unrecognized WAV file chunk"); - int sampleDataLen = readLittleUint(in, 4); - if (sampleDataLen <= 0 || sampleDataLen % (numChannels * bytesPerSample) != 0) - throw new DataFormatException("Invalid length of audio sample data"); - int numSamples = sampleDataLen / (numChannels * bytesPerSample); - samples = new int[numChannels][numSamples]; - for (int i = 0; i < numSamples; i++) { - for (int ch = 0; ch < numChannels; ch++) { - int val = readLittleUint(in, bytesPerSample); - if (sampleDepth == 8) - val -= 128; - else - val = (val << (32 - sampleDepth)) >> (32 - sampleDepth); - samples[ch][i] = val; - } - } - // Note: There might be chunks after "data", but they can be ignored - } - - // Open output file and encode samples to FLAC - try (RandomAccessFile raf = new RandomAccessFile(outFile, "rw")) { - raf.setLength(0); // Truncate an existing file - BitOutputStream out = new BitOutputStream( - new BufferedOutputStream(new RandomAccessFileOutputStream(raf))); - out.writeInt(32, 0x664C6143); - - // Populate and write the stream info structure - StreamInfo info = new StreamInfo(); - info.sampleRate = sampleRate; - info.numChannels = samples.length; - info.sampleDepth = sampleDepth; - info.numSamples = samples[0].length; - info.md5Hash = StreamInfo.getMd5Hash(samples, sampleDepth); - info.write(true, out); - - // Encode all frames - new FlacEncoder(info, samples, 4096, SubframeEncoder.SearchOptions.SUBSET_BEST, out); - out.flush(); - - // Rewrite the stream info metadata block, which is - // located at a fixed offset in the file by definition - raf.seek(4); - info.write(true, out); - out.flush(); - } - } - - - // Reads len bytes from the given stream and interprets them as a UTF-8 string. - private static String readString(InputStream in, int len) throws IOException { - byte[] temp = new byte[len]; - for (int i = 0; i < temp.length; i++) { - int b = in.read(); - if (b == -1) - throw new EOFException(); - temp[i] = (byte)b; - } - return new String(temp, StandardCharsets.UTF_8); - } - - - // Reads n bytes (0 <= n <= 4) from the given stream, interpreting - // them as an unsigned integer encoded in little endian. - private static int readLittleUint(InputStream in, int n) throws IOException { - int result = 0; - for (int i = 0; i < n; i++) { - int b = in.read(); - if (b == -1) - throw new EOFException(); - result |= b << (i * 8); - } - return result; - } - -} diff --git a/desktop/src/io/nayuki/flac/app/SeekableFlacPlayerGui.java b/desktop/src/io/nayuki/flac/app/SeekableFlacPlayerGui.java deleted file mode 100644 index 418b1f47..00000000 --- a/desktop/src/io/nayuki/flac/app/SeekableFlacPlayerGui.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.app; - -import java.awt.Dimension; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseMotionAdapter; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.File; -import java.io.IOException; -import javax.sound.sampled.AudioFormat; -import javax.sound.sampled.AudioSystem; -import javax.sound.sampled.DataLine; -import javax.sound.sampled.LineUnavailableException; -import javax.sound.sampled.SourceDataLine; -import javax.swing.JFrame; -import javax.swing.JSlider; -import javax.swing.SwingConstants; -import javax.swing.SwingUtilities; -import javax.swing.plaf.basic.BasicSliderUI; -import javax.swing.plaf.metal.MetalSliderUI; -import io.nayuki.flac.common.StreamInfo; -import io.nayuki.flac.decode.FlacDecoder; - - -/** - * Plays a single FLAC file to the system audio output, showing a GUI window with a seek bar. - * The file to play is specified as a command line argument. The seek bar is responsible for both - * displaying the current playback position, and allowing the user to click to seek to new positions. - *

Usage: java SeekableFlacPlayerGui InFile.flac

- */ -public final class SeekableFlacPlayerGui { - - public static void main(String[] args) throws - LineUnavailableException, IOException, InterruptedException { - - /*-- Initialization code --*/ - - // Handle command line arguments - if (args.length != 1) { - System.err.println("Usage: java SeekableFlacPlayerGui InFile.flac"); - System.exit(1); - return; - } - File inFile = new File(args[0]); - - // Process header metadata blocks - FlacDecoder decoder = new FlacDecoder(inFile); - while (decoder.readAndHandleMetadataBlock() != null); - StreamInfo streamInfo = decoder.streamInfo; - if (streamInfo.numSamples == 0) - throw new IllegalArgumentException("Unknown audio length"); - - // Start Java sound output API - AudioFormat format = new AudioFormat(streamInfo.sampleRate, - streamInfo.sampleDepth, streamInfo.numChannels, true, false); - DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); - SourceDataLine line = (SourceDataLine)AudioSystem.getLine(info); - line.open(format); - line.start(); - - // Create GUI object, event handler, communication object - final double[] seekRequest = {-1}; - AudioPlayerGui gui = new AudioPlayerGui("FLAC Player"); - gui.listener = new AudioPlayerGui.Listener() { - public void seekRequested(double t) { - synchronized(seekRequest) { - seekRequest[0] = t; - seekRequest.notify(); - } - } - public void windowClosing() { - System.exit(0); - } - }; - - /*-- Audio player loop --*/ - - // Decode and write audio data, handle seek requests, wait for seek when end of stream reached - int bytesPerSample = streamInfo.sampleDepth / 8; - long startTime = line.getMicrosecondPosition(); - - // Buffers for data created and discarded within each loop iteration, but allocated outside the loop - int[][] samples = new int[streamInfo.numChannels][65536]; - byte[] sampleBytes = new byte[65536 * streamInfo.numChannels * bytesPerSample]; - while (true) { - - // Get and clear seek request, if any - double seekReq; - synchronized(seekRequest) { - seekReq = seekRequest[0]; - seekRequest[0] = -1; - } - - // Decode next audio block, or seek and decode - int blockSamples; - if (seekReq == -1) - blockSamples = decoder.readAudioBlock(samples, 0); - else { - long samplePos = Math.round(seekReq * streamInfo.numSamples); - seekReq = -1; - blockSamples = decoder.seekAndReadAudioBlock(samplePos, samples, 0); - line.flush(); - startTime = line.getMicrosecondPosition() - Math.round(samplePos * 1e6 / streamInfo.sampleRate); - } - - // Set display position - double timePos = (line.getMicrosecondPosition() - startTime) / 1e6; - gui.setPosition(timePos * streamInfo.sampleRate / streamInfo.numSamples); - - // Wait when end of stream reached - if (blockSamples == 0) { - synchronized(seekRequest) { - while (seekRequest[0] == -1) - seekRequest.wait(); - } - continue; - } - - // Convert samples to channel-interleaved bytes in little endian - int sampleBytesLen = 0; - for (int i = 0; i < blockSamples; i++) { - for (int ch = 0; ch < streamInfo.numChannels; ch++) { - int val = samples[ch][i]; - for (int j = 0; j < bytesPerSample; j++, sampleBytesLen++) - sampleBytes[sampleBytesLen] = (byte)(val >>> (j << 3)); - } - } - line.write(sampleBytes, 0, sampleBytesLen); - } - } - - - - /*---- User interface classes ----*/ - - private static final class AudioPlayerGui { - - /*-- Fields --*/ - - public Listener listener; - private JSlider slider; - private BasicSliderUI sliderUi; - - - /*-- Constructor --*/ - - public AudioPlayerGui(String windowTitle) { - // Create and configure slider - slider = new JSlider(SwingConstants.HORIZONTAL, 0, 10000, 0); - sliderUi = new MetalSliderUI(); - slider.setUI(sliderUi); - slider.setPreferredSize(new Dimension(800, 50)); - slider.addMouseListener(new MouseAdapter() { - public void mousePressed(MouseEvent ev) { - moveSlider(ev); - } - public void mouseReleased(MouseEvent ev) { - moveSlider(ev); - listener.seekRequested((double)slider.getValue() / slider.getMaximum()); - } - }); - slider.addMouseMotionListener(new MouseMotionAdapter() { - public void mouseDragged(MouseEvent ev) { - moveSlider(ev); - } - }); - - // Create and configure frame (window) - JFrame frame = new JFrame(windowTitle); - frame.add(slider); - frame.pack(); - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent ev) { - listener.windowClosing(); - } - }); - frame.setResizable(false); - frame.setVisible(true); - } - - - /*-- Methods --*/ - - public void setPosition(double t) { - if (Double.isNaN(t)) - return; - final double val = Math.max(Math.min(t, 1), 0); - SwingUtilities.invokeLater(new Runnable() { - public void run() { - if (!slider.getValueIsAdjusting()) - slider.setValue((int)Math.round(val * slider.getMaximum())); - } - }); - } - - - private void moveSlider(MouseEvent ev) { - slider.setValue(sliderUi.valueForXPosition(ev.getX())); - } - - - /*-- Helper interface --*/ - - public interface Listener { - - public void seekRequested(double t); // 0.0 <= t <= 1.0 - - public void windowClosing(); - - } - - } - -} diff --git a/desktop/src/io/nayuki/flac/app/ShowFlacFileStats.java b/desktop/src/io/nayuki/flac/app/ShowFlacFileStats.java deleted file mode 100644 index 21f42162..00000000 --- a/desktop/src/io/nayuki/flac/app/ShowFlacFileStats.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.app; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.SortedMap; -import java.util.TreeMap; -import io.nayuki.flac.common.FrameInfo; -import io.nayuki.flac.common.StreamInfo; -import io.nayuki.flac.decode.DataFormatException; -import io.nayuki.flac.decode.FlacLowLevelInput; -import io.nayuki.flac.decode.FrameDecoder; -import io.nayuki.flac.decode.SeekableFileFlacInput; - - -/** - * Reads a FLAC file, collects various statistics, and - * prints human-formatted information to standard output. - *

Usage: java ShowFlacFileStats InFile.flac

- *

Example output from this program (abbreviated):

- *
===== Block sizes (samples) =====
- * 4096: * (11)
- * 5120: ***** (56)
- * 6144: *********** (116)
- * 7168: ************* (134)
- * 8192: ***************** (177)
- * 9216: ***************** (182)
- *10240: ***************** (179)
- *11264: ****************************** (318)
- *12288: ****************** (194)
- *
- *===== Frame sizes (bytes) =====
- *12000: ****** (20)
- *13000: ******* (24)
- *14000: ********** (34)
- *15000: **************** (51)
- *16000: ********************* (68)
- *17000: ******************* (63)
- *18000: ******************* (63)
- *19000: ************************ (77)
- *20000: ********************* (70)
- *21000: ****************** (60)
- *22000: ************************* (82)
- *23000: ********************* (69)
- *24000: *************************** (87)
- *25000: *************************** (88)
- *26000: ********************** (73)
- *27000: ************************** (84)
- *28000: ****************************** (98)
- *29000: ********************** (73)
- *30000: *********************** (75)
- *31000: ************ (39)
- *
- *===== Average compression ratio at block sizes =====
- * 4096: ********************** (0.7470)
- * 5120: ******************** (0.6815)
- * 6144: ******************** (0.6695)
- * 7168: ******************* (0.6438)
- * 8192: ******************* (0.6379)
- * 9216: ****************** (0.6107)
- *10240: ****************** (0.6022)
- *11264: ***************** (0.5628)
- *12288: ***************** (0.5724)
- *
- *===== Stereo coding modes =====
- *Independent: **** (83)
- *Left-side  :  (3)
- *Right-side : ************************ (574)
- *Mid-side   : ****************************** (708)
- */ -public final class ShowFlacFileStats { - - /*---- Main application function ----*/ - - public static void main(String[] args) throws IOException { - // Handle command line arguments - if (args.length != 1) { - System.err.println("Usage: java ShowFlacFileStats InFile.flac"); - System.exit(1); - return; - } - File inFile = new File(args[0]); - - // Data structures to hold statistics - List blockSizes = new ArrayList<>(); - List frameSizes = new ArrayList<>(); - List channelAssignments = new ArrayList<>(); - - // Read input file - StreamInfo streamInfo = null; - try (FlacLowLevelInput input = new SeekableFileFlacInput(inFile)) { - // Magic string "fLaC" - if (input.readUint(32) != 0x664C6143) - throw new DataFormatException("Invalid magic string"); - - // Handle metadata blocks - for (boolean last = false; !last; ) { - last = input.readUint(1) != 0; - int type = input.readUint(7); - int length = input.readUint(24); - byte[] data = new byte[length]; - input.readFully(data); - if (type == 0) - streamInfo = new StreamInfo(data); - } - - // Decode every frame - FrameDecoder dec = new FrameDecoder(input, streamInfo.sampleDepth); - int[][] blockSamples = new int[8][65536]; - while (true) { - FrameInfo meta = dec.readFrame(blockSamples, 0); - if (meta == null) - break; - blockSizes.add(meta.blockSize); - frameSizes.add(meta.frameSize); - channelAssignments.add(meta.channelAssignment); - } - } - - // Build and print graphs - printBlockSizeHistogram(blockSizes); - printFrameSizeHistogram(frameSizes); - printCompressionRatioGraph(streamInfo, blockSizes, frameSizes); - if (streamInfo.numChannels == 2) - printStereoModeGraph(channelAssignments); - } - - - - /*---- Statistics-processing functions ----*/ - - private static void printBlockSizeHistogram(List blockSizes) { - Map blockSizeCounts = new TreeMap<>(); - for (int bs : blockSizes) { - if (!blockSizeCounts.containsKey(bs)) - blockSizeCounts.put(bs, 0); - int count = blockSizeCounts.get(bs) + 1; - blockSizeCounts.put(bs, count); - } - List blockSizeLabels = new ArrayList<>(); - List blockSizeValues = new ArrayList<>(); - for (Map.Entry entry : blockSizeCounts.entrySet()) { - blockSizeLabels.add(String.format("%5d", entry.getKey())); - blockSizeValues.add((double)entry.getValue()); - } - printNormalizedBarGraph("Block sizes (samples)", blockSizeLabels, blockSizeValues); - } - - - private static void printFrameSizeHistogram(List frameSizes) { - final int step = 1000; - SortedMap frameSizeCounts = new TreeMap<>(); - int maxKeyLen = 0; - for (int fs : frameSizes) { - int key = (int)Math.round((double)fs / step); - maxKeyLen = Math.max(Integer.toString(key * step).length(), maxKeyLen); - if (!frameSizeCounts.containsKey(key)) - frameSizeCounts.put(key, 0); - frameSizeCounts.put(key, frameSizeCounts.get(key) + 1); - } - for (int i = frameSizeCounts.firstKey(); i < frameSizeCounts.lastKey(); i++) { - if (!frameSizeCounts.containsKey(i)) - frameSizeCounts.put(i, 0); - } - List frameSizeLabels = new ArrayList<>(); - List frameSizeValues = new ArrayList<>(); - for (Map.Entry entry : frameSizeCounts.entrySet()) { - frameSizeLabels.add(String.format("%" + maxKeyLen + "d", entry.getKey() * step)); - frameSizeValues.add((double)entry.getValue()); - } - printNormalizedBarGraph("Frame sizes (bytes)", frameSizeLabels, frameSizeValues); - } - - - private static void printCompressionRatioGraph(StreamInfo streamInfo, List blockSizes, List frameSizes) { - Map blockSizeCounts = new TreeMap<>(); - Map blockSizeBytes = new TreeMap<>(); - for (int i = 0; i < blockSizes.size(); i++) { - int bs = blockSizes.get(i); - if (!blockSizeCounts.containsKey(bs)) { - blockSizeCounts.put(bs, 0); - blockSizeBytes.put(bs, 0L); - } - blockSizeCounts.put(bs, blockSizeCounts.get(bs) + 1); - blockSizeBytes.put(bs, blockSizeBytes.get(bs) + frameSizes.get(i)); - } - List blockRatioLabels = new ArrayList<>(); - List blockRatioValues = new ArrayList<>(); - for (Map.Entry entry : blockSizeCounts.entrySet()) { - blockRatioLabels.add(String.format("%5d", entry.getKey())); - blockRatioValues.add(blockSizeBytes.get(entry.getKey()) / ((double)entry.getValue() * entry.getKey() * streamInfo.numChannels * streamInfo.sampleDepth / 8)); - } - printNormalizedBarGraph("Average compression ratio at block sizes", blockRatioLabels, blockRatioValues); - } - - - private static void printStereoModeGraph(List channelAssignments) { - List stereoModeLabels = Arrays.asList("Independent", "Left-side", "Right-side", "Mid-side"); - List stereoModeValues = new ArrayList<>(); - for (int i = 0; i < 4; i++) - stereoModeValues.add(0.0); - for (int mode : channelAssignments) { - int index; - switch (mode) { - case 1: index = 0; break; - case 8: index = 1; break; - case 9: index = 2; break; - case 10: index = 3; break; - default: throw new DataFormatException("Invalid mode in stereo stream"); - } - stereoModeValues.set(index, stereoModeValues.get(index) + 1); - } - printNormalizedBarGraph("Stereo coding modes", stereoModeLabels, stereoModeValues); - } - - - - /*---- Utility functions ----*/ - - private static void printNormalizedBarGraph(String heading, List labels, List values) { - Objects.requireNonNull(heading); - Objects.requireNonNull(labels); - Objects.requireNonNull(values); - if (labels.size() != values.size()) - throw new IllegalArgumentException(); - - final int maxBarWidth = 100; - System.out.printf("==================== %s ====================%n", heading); - System.out.println(); - - int maxLabelLen = 0; - for (String s : labels) - maxLabelLen = Math.max(s.length(), maxLabelLen); - String spaces = new String(new char[maxLabelLen]).replace((char)0, ' '); - - double maxValue = 1; // This avoids division by zero - for (double val : values) - maxValue = Math.max(val, maxValue); - - for (int i = 0; i < labels.size(); i++) { - String label = labels.get(i); - double value = values.get(i); - int barWidth = (int)Math.round(value / maxValue * maxBarWidth); - String bar = new String(new char[barWidth]).replace((char)0, '*'); - System.out.printf("%s%s: %s (%s)%n", label, spaces.substring(label.length()), - bar, (long)value == value ? Long.toString((long)value) : Double.toString(value)); - } - System.out.println(); - System.out.println(); - } - -} diff --git a/desktop/src/io/nayuki/flac/common/FrameInfo.java b/desktop/src/io/nayuki/flac/common/FrameInfo.java deleted file mode 100644 index a4c15623..00000000 --- a/desktop/src/io/nayuki/flac/common/FrameInfo.java +++ /dev/null @@ -1,456 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.common; - -import java.io.IOException; -import java.util.Objects; -import io.nayuki.flac.decode.DataFormatException; -import io.nayuki.flac.decode.FlacLowLevelInput; -import io.nayuki.flac.decode.FrameDecoder; -import io.nayuki.flac.encode.BitOutputStream; - - -/** - * Represents most fields in a frame header, in decoded (not raw) form. Mutable structure, - * not thread safe. Also has methods for parsing and serializing this structure to/from bytes. - * All fields can be modified freely when no method call is active. - * @see FrameDecoder - * @see StreamInfo#checkFrame(FrameInfo) - */ -public final class FrameInfo { - - /*---- Fields ----*/ - - // Exactly one of these following two fields equals -1. - - /** - * The index of this frame, where the foremost frame has index 0 and each subsequent frame - * increments it. This is either a uint31 value or −1 if unused. Exactly one of the fields - * frameIndex and sampleOffse is equal to −1 (not both nor neither). This value can only - * be used if the stream info's minBlockSize = maxBlockSize (constant block size encoding style). - */ - public int frameIndex; - - /** - * The offset of the first sample in this frame with respect to the beginning of the - * audio stream. This is either a uint36 value or −1 if unused. Exactly one of - * the fields frameIndex and sampleOffse is equal to −1 (not both nor neither). - */ - public long sampleOffset; - - - /** - * The number of audio channels in this frame, in the range 1 to 8 inclusive. - * This value is fully determined by the channelAssignment field. - */ - public int numChannels; - - /** - * The raw channel assignment value of this frame, which is a uint4 value. - * This indicates the number of channels, but also tells the stereo coding mode. - */ - public int channelAssignment; - - /** - * The number of samples per channel in this frame, in the range 1 to 65536 inclusive. - */ - public int blockSize; - - /** - * The sample rate of this frame in hertz (Hz), in the range 1 to 655360 inclusive, - * or −1 if unavailable (i.e. the stream info should be consulted). - */ - public int sampleRate; - - /** - * The sample depth of this frame in bits, in the range 8 to 24 inclusive, - * or −1 if unavailable (i.e. the stream info should be consulted). - */ - public int sampleDepth; - - /** - * The size of this frame in bytes, from the start of the sync sequence to the end - * of the trailing CRC-16 checksum. A valid value is at least 10, or −1 - * if unavailable (e.g. the frame header was parsed but not the entire frame). - */ - public int frameSize; - - - - /*---- Constructors ----*/ - - /** - * Constructs a blank frame metadata structure, setting all fields to unknown or invalid values. - */ - public FrameInfo() { - frameIndex = -1; - sampleOffset = -1; - numChannels = -1; - channelAssignment = -1; - blockSize = -1; - sampleRate = -1; - sampleDepth = -1; - frameSize = -1; - } - - - - /*---- Functions to read FrameInfo from stream ----*/ - - /** - * Reads the next FLAC frame header from the specified input stream, either returning - * a new frame info object or {@code null}. The stream must be aligned to a byte - * boundary and start at a sync sequence. If EOF is immediately encountered before - * any bytes were read, then this returns {@code null}. - *

Otherwise this reads between 6 to 16 bytes from the stream – starting - * from the sync code, and ending after the CRC-8 value is read (but before reading - * any subframes). It tries to parse the frame header data. After the values are - * successfully decoded, a new frame info object is created, almost all fields are - * set to the parsed values, and it is returned. (This doesn't read to the end - * of the frame, so the frameSize field is set to -1.)

- * @param in the input stream to read from (not {@code null}) - * @return a new frame info object or {@code null} - * @throws NullPointerException if the input stream is {@code null} - * @throws DataFormatException if the input data contains invalid values - * @throws IOException if an I/O exception occurred - */ - public static FrameInfo readFrame(FlacLowLevelInput in) throws IOException { - // Preliminaries - in.resetCrcs(); - int temp = in.readByte(); - if (temp == -1) - return null; - FrameInfo result = new FrameInfo(); - result.frameSize = -1; - - // Read sync bits - int sync = temp << 6 | in.readUint(6); // Uint14 - if (sync != 0x3FFE) - throw new DataFormatException("Sync code expected"); - - // Read various simple fields - if (in.readUint(1) != 0) - throw new DataFormatException("Reserved bit"); - int blockStrategy = in.readUint(1); - int blockSizeCode = in.readUint(4); - int sampleRateCode = in.readUint(4); - int chanAsgn = in.readUint(4); - result.channelAssignment = chanAsgn; - if (chanAsgn < 8) - result.numChannels = chanAsgn + 1; - else if (8 <= chanAsgn && chanAsgn <= 10) - result.numChannels = 2; - else - throw new DataFormatException("Reserved channel assignment"); - result.sampleDepth = decodeSampleDepth(in.readUint(3)); - if (in.readUint(1) != 0) - throw new DataFormatException("Reserved bit"); - - // Read and check the frame/sample position field - long position = readUtf8Integer(in); // Reads 1 to 7 bytes - if (blockStrategy == 0) { - if ((position >>> 31) != 0) - throw new DataFormatException("Frame index too large"); - result.frameIndex = (int)position; - result.sampleOffset = -1; - } else if (blockStrategy == 1) { - result.sampleOffset = position; - result.frameIndex = -1; - } else - throw new AssertionError(); - - // Read variable-length data for some fields - result.blockSize = decodeBlockSize(blockSizeCode, in); // Reads 0 to 2 bytes - result.sampleRate = decodeSampleRate(sampleRateCode, in); // Reads 0 to 2 bytes - int computedCrc8 = in.getCrc8(); - if (in.readUint(8) != computedCrc8) - throw new DataFormatException("CRC-8 mismatch"); - return result; - } - - - // Reads 1 to 7 whole bytes from the input stream. Return value is a uint36. - // See: https://hydrogenaud.io/index.php/topic,112831.msg929128.html#msg929128 - private static long readUtf8Integer(FlacLowLevelInput in) throws IOException { - int head = in.readUint(8); - int n = Integer.numberOfLeadingZeros(~(head << 24)); // Number of leading 1s in the byte - assert 0 <= n && n <= 8; - if (n == 0) - return head; - else if (n == 1 || n == 8) - throw new DataFormatException("Invalid UTF-8 coded number"); - else { - long result = head & (0x7F >>> n); - for (int i = 0; i < n - 1; i++) { - int temp = in.readUint(8); - if ((temp & 0xC0) != 0x80) - throw new DataFormatException("Invalid UTF-8 coded number"); - result = (result << 6) | (temp & 0x3F); - } - if ((result >>> 36) != 0) - throw new AssertionError(); - return result; - } - } - - - // Argument is a uint4 value. Reads 0 to 2 bytes from the input stream. - // Return value is in the range [1, 65536]. - private static int decodeBlockSize(int code, FlacLowLevelInput in) throws IOException { - if ((code >>> 4) != 0) - throw new IllegalArgumentException(); - switch (code) { - case 0: throw new DataFormatException("Reserved block size"); - case 6: return in.readUint(8) + 1; - case 7: return in.readUint(16) + 1; - default: - int result = searchSecond(BLOCK_SIZE_CODES, code); - if (result < 1 || result > 65536) - throw new AssertionError(); - return result; - } - } - - - // Argument is a uint4 value. Reads 0 to 2 bytes from the input stream. - // Return value is in the range [-1, 655350]. - private static int decodeSampleRate(int code, FlacLowLevelInput in) throws IOException { - if ((code >>> 4) != 0) - throw new IllegalArgumentException(); - switch (code) { - case 0: return -1; // Caller should obtain value from stream info metadata block - case 12: return in.readUint(8); - case 13: return in.readUint(16); - case 14: return in.readUint(16) * 10; - case 15: throw new DataFormatException("Invalid sample rate"); - default: - int result = searchSecond(SAMPLE_RATE_CODES, code); - if (result < 1 || result > 655350) - throw new AssertionError(); - return result; - } - } - - - // Argument is a uint3 value. Pure function and performs no I/O. Return value is in the range [-1, 24]. - private static int decodeSampleDepth(int code) { - if ((code >>> 3) != 0) - throw new IllegalArgumentException(); - else if (code == 0) - return -1; // Caller should obtain value from stream info metadata block - else { - int result = searchSecond(SAMPLE_DEPTH_CODES, code); - if (result == -1) - throw new DataFormatException("Reserved bit depth"); - if (result < 1 || result > 32) - throw new AssertionError(); - return result; - } - } - - - - /*---- Functions to write FrameInfo to stream ----*/ - - /** - * Writes the current state of this object as a frame header to the specified - * output stream, from the sync field through to the CRC-8 field (inclusive). - * This does not write the data of subframes, the bit padding, nor the CRC-16 field.

- *

The stream must be byte-aligned before this method is called, and will be aligned - * upon returning (i.e. it writes a whole number of bytes). This method initially resets - * the stream's CRC computations, which is useful behavior for the caller because - * it will need to write the CRC-16 at the end of the frame.

- * @param out the output stream to write to (not {@code null}) - * @throws NullPointerException if the output stream is {@code null} - * @throws IOException if an I/O exception occurred - */ - public void writeHeader(BitOutputStream out) throws IOException { - Objects.requireNonNull(out); - out.resetCrcs(); - out.writeInt(14, 0x3FFE); // Sync - out.writeInt(1, 0); // Reserved - out.writeInt(1, 1); // Blocking strategy - - int blockSizeCode = getBlockSizeCode(blockSize); - out.writeInt(4, blockSizeCode); - int sampleRateCode = getSampleRateCode(sampleRate); - out.writeInt(4, sampleRateCode); - - out.writeInt(4, channelAssignment); - out.writeInt(3, getSampleDepthCode(sampleDepth)); - out.writeInt(1, 0); // Reserved - - // Variable-length: 1 to 7 bytes - if (frameIndex != -1 && sampleOffset == -1) - writeUtf8Integer(sampleOffset, out); - else if (sampleOffset != -1 && frameIndex == -1) - writeUtf8Integer(sampleOffset, out); - else - throw new IllegalStateException(); - - // Variable-length: 0 to 2 bytes - if (blockSizeCode == 6) - out.writeInt(8, blockSize - 1); - else if (blockSizeCode == 7) - out.writeInt(16, blockSize - 1); - - // Variable-length: 0 to 2 bytes - if (sampleRateCode == 12) - out.writeInt(8, sampleRate); - else if (sampleRateCode == 13) - out.writeInt(16, sampleRate); - else if (sampleRateCode == 14) - out.writeInt(16, sampleRate / 10); - - out.writeInt(8, out.getCrc8()); - } - - - // Given a uint36 value, this writes 1 to 7 whole bytes to the given output stream. - private static void writeUtf8Integer(long val, BitOutputStream out) throws IOException { - if ((val >>> 36) != 0) - throw new IllegalArgumentException(); - int bitLen = 64 - Long.numberOfLeadingZeros(val); - if (bitLen <= 7) - out.writeInt(8, (int)val); - else { - int n = (bitLen - 2) / 5; - out.writeInt(8, (0xFF80 >>> n) | (int)(val >>> (n * 6))); - for (int i = n - 1; i >= 0; i--) - out.writeInt(8, 0x80 | ((int)(val >>> (i * 6)) & 0x3F)); - } - } - - - // Returns a uint4 value representing the given block size. Pure function. - private static int getBlockSizeCode(int blockSize) { - int result = searchFirst(BLOCK_SIZE_CODES, blockSize); - if (result != -1); // Already done - else if (1 <= blockSize && blockSize <= 256) - result = 6; - else if (1 <= blockSize && blockSize <= 65536) - result = 7; - else // blockSize < 1 || blockSize > 65536 - throw new IllegalArgumentException(); - - if ((result >>> 4) != 0) - throw new AssertionError(); - return result; - } - - - // Returns a uint4 value representing the given sample rate. Pure function. - private static int getSampleRateCode(int sampleRate) { - if (sampleRate == 0 || sampleRate < -1) - throw new IllegalArgumentException(); - int result = searchFirst(SAMPLE_RATE_CODES, sampleRate); - if (result != -1); // Already done - else if (0 <= sampleRate && sampleRate < 256) - result = 12; - else if (0 <= sampleRate && sampleRate < 65536) - result = 13; - else if (0 <= sampleRate && sampleRate < 655360 && sampleRate % 10 == 0) - result = 14; - else - result = 0; - - if ((result >>> 4) != 0) - throw new AssertionError(); - return result; - } - - - // Returns a uint3 value representing the given sample depth. Pure function. - private static int getSampleDepthCode(int sampleDepth) { - if (sampleDepth != -1 && (sampleDepth < 1 || sampleDepth > 32)) - throw new IllegalArgumentException(); - int result = searchFirst(SAMPLE_DEPTH_CODES, sampleDepth); - if (result == -1) - result = 0; - if ((result >>> 3) != 0) - throw new AssertionError(); - return result; - } - - - - /*---- Tables of constants and search functions ----*/ - - private static final int searchFirst(int[][] table, int key) { - for (int[] pair : table) { - if (pair[0] == key) - return pair[1]; - } - return -1; - } - - - private static final int searchSecond(int[][] table, int key) { - for (int[] pair : table) { - if (pair[1] == key) - return pair[0]; - } - return -1; - } - - - private static final int[][] BLOCK_SIZE_CODES = { - { 192, 1}, - { 576, 2}, - { 1152, 3}, - { 2304, 4}, - { 4608, 5}, - { 256, 8}, - { 512, 9}, - { 1024, 10}, - { 2048, 11}, - { 4096, 12}, - { 8192, 13}, - {16384, 14}, - {32768, 15}, - }; - - - private static final int[][] SAMPLE_DEPTH_CODES = { - { 8, 1}, - {12, 2}, - {16, 4}, - {20, 5}, - {24, 6}, - }; - - - private static final int[][] SAMPLE_RATE_CODES = { - { 88200, 1}, - {176400, 2}, - {192000, 3}, - { 8000, 4}, - { 16000, 5}, - { 22050, 6}, - { 24000, 7}, - { 32000, 8}, - { 44100, 9}, - { 48000, 10}, - { 96000, 11}, - }; - -} diff --git a/desktop/src/io/nayuki/flac/common/SeekTable.java b/desktop/src/io/nayuki/flac/common/SeekTable.java deleted file mode 100644 index 04b433b9..00000000 --- a/desktop/src/io/nayuki/flac/common/SeekTable.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.common; - -import java.io.ByteArrayInputStream; -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import io.nayuki.flac.decode.FlacDecoder; -import io.nayuki.flac.encode.BitOutputStream; - - -/** - * Represents precisely all the fields of a seek table metadata block. Mutable structure, - * not thread-safe. Also has methods for parsing and serializing this structure to/from bytes. - * All fields and objects can be modified freely when no method call is active. - * @see FlacDecoder - */ -public final class SeekTable { - - /*---- Fields ----*/ - - /** - * The list of seek points in this seek table. It is okay to replace this - * list as needed (the initially constructed list object is not special). - */ - public List points; - - - - /*---- Constructors ----*/ - - /** - * Constructs a blank seek table with an initially empty - * list of seek points. (Note that the empty state is legal.) - */ - public SeekTable() { - points = new ArrayList<>(); - } - - - /** - * Constructs a seek table by parsing the given byte array representing the metadata block. - * (The array must contain only the metadata payload, without the type or length fields.) - *

This constructor does not check the validity of the seek points, namely the ordering - * of seek point offsets, so calling {@link#checkValues()} on the freshly constructed object - * can fail. However, this does guarantee that every point's frameSamples field is a uint16.

- * @param b the metadata block's payload data to parse (not {@code null}) - * @throws NullPointerException if the array is {@code null} - * @throws IllegalArgumentException if the array length - * is not a multiple of 18 (size of each seek point) - */ - public SeekTable(byte[] b) { - this(); - Objects.requireNonNull(b); - if (b.length % 18 != 0) - throw new IllegalArgumentException("Data contains a partial seek point"); - try { - DataInput in = new DataInputStream(new ByteArrayInputStream(b)); - for (int i = 0; i < b.length; i += 18) { - SeekPoint p = new SeekPoint(); - p.sampleOffset = in.readLong(); - p.fileOffset = in.readLong(); - p.frameSamples = in.readUnsignedShort(); - points.add(p); - } - // Skip closing the in-memory streams - } catch (IOException e) { - throw new AssertionError(e); - } - } - - - - /*---- Methods ----*/ - - /** - * Checks the state of this object and returns silently if all these criteria pass: - *
    - *
  • No object is {@code null}
  • - *
  • The frameSamples field of each point is a uint16 value
  • - *
  • All points with sampleOffset = −1 (i.e. 0xFFF...FFF) are at the end of the list
  • - *
  • All points with sampleOffset ≠ −1 have strictly increasing - * values of sampleOffset and non-decreasing values of fileOffset
  • - *
- * @throws NullPointerException if the list or an element is {@code null} - * @throws IllegalStateException if the current list of seek points is contains invalid data - */ - public void checkValues() { - // Check list and each point - Objects.requireNonNull(points); - for (SeekPoint p : points) { - Objects.requireNonNull(p); - if ((p.frameSamples & 0xFFFF) != p.frameSamples) - throw new IllegalStateException("Frame samples outside uint16 range"); - } - - // Check ordering of points - for (int i = 1; i < points.size(); i++) { - SeekPoint p = points.get(i); - if (p.sampleOffset != -1) { - SeekPoint q = points.get(i - 1); - if (p.sampleOffset <= q.sampleOffset) - throw new IllegalStateException("Sample offsets out of order"); - if (p.fileOffset < q.fileOffset) - throw new IllegalStateException("File offsets out of order"); - } - } - } - - - /** - * Writes all the points of this seek table as a metadata block to the specified output stream, - * also indicating whether it is the last metadata block. (This does write the type and length - * fields for the metadata block, unlike the constructor which takes an array without those fields.) - * @param last whether the metadata block is the final one in the FLAC file - * @param out the output stream to write to (not {@code null}) - * @throws NullPointerException if the output stream is {@code null} - * @throws IllegalStateException if there are too many - * @throws IOException if an I/O exception occurred - * seek points (> 932067) or {@link#checkValues()} fails - */ - public void write(boolean last, BitOutputStream out) throws IOException { - // Check arguments and state - Objects.requireNonNull(out); - Objects.requireNonNull(points); - if (points.size() > ((1 << 24) - 1) / 18) - throw new IllegalStateException("Too many seek points"); - checkValues(); - - // Write metadata block header - out.writeInt(1, last ? 1 : 0); - out.writeInt(7, 3); - out.writeInt(24, points.size() * 18); - - // Write each seek point - for (SeekPoint p : points) { - out.writeInt(32, (int)(p.sampleOffset >>> 32)); - out.writeInt(32, (int)(p.sampleOffset >>> 0)); - out.writeInt(32, (int)(p.fileOffset >>> 32)); - out.writeInt(32, (int)(p.fileOffset >>> 0)); - out.writeInt(16, p.frameSamples); - } - } - - - - /*---- Helper structure ----*/ - - /** - * Represents a seek point entry in a seek table. Mutable structure, not thread-safe. - * This class itself does not check the correctness of data, but other classes might. - *

A seek point with data (sampleOffset = x, fileOffset = y, frameSamples = z) means - * that at byte position (y + (byte offset of foremost audio frame)) in the file, - * a FLAC frame begins (with the sync sequence), that frame has sample offset x - * (where sample 0 is defined as the start of the audio stream), - * and the frame contains z samples per channel. - * @see SeekTable - */ - public static final class SeekPoint { - - /** - * The sample offset in the audio stream, a uint64 value. - * A value of -1 (i.e. 0xFFF...FFF) means this is a placeholder point. - */ - public long sampleOffset; - - /** - * The byte offset relative to the start of the foremost frame, a uint64 value. - * If sampleOffset is -1, then this value is ignored. - */ - public long fileOffset; - - /** - * The number of audio samples in the target block/frame, a uint16 value. - * If sampleOffset is -1, then this value is ignored. - */ - public int frameSamples; - - } - -} diff --git a/desktop/src/io/nayuki/flac/common/StreamInfo.java b/desktop/src/io/nayuki/flac/common/StreamInfo.java deleted file mode 100644 index d8ab3e12..00000000 --- a/desktop/src/io/nayuki/flac/common/StreamInfo.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.common; - -import java.io.IOException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Objects; -import io.nayuki.flac.decode.ByteArrayFlacInput; -import io.nayuki.flac.decode.DataFormatException; -import io.nayuki.flac.decode.FlacDecoder; -import io.nayuki.flac.decode.FlacLowLevelInput; -import io.nayuki.flac.encode.BitOutputStream; - - -/** - * Represents precisely all the fields of a stream info metadata block. Mutable structure, - * not thread-safe. Also has methods for parsing and serializing this structure to/from bytes. - * All fields can be modified freely when no method call is active. - * @see FrameInfo - * @see FlacDecoder - */ -public final class StreamInfo { - - /*---- Fields about block and frame sizes ----*/ - - /** - * Minimum block size (in samples per channel) among the whole stream, a uint16 value. - * However when minBlockSize = maxBlockSize (constant block size encoding style), - * the final block is allowed to be smaller than minBlockSize. - */ - public int minBlockSize; - - /** - * Maximum block size (in samples per channel) among the whole stream, a uint16 value. - */ - public int maxBlockSize; - - /** - * Minimum frame size (in bytes) among the whole stream, a uint24 value. - * However, a value of 0 signifies that the value is unknown. - */ - public int minFrameSize; - - /** - * Maximum frame size (in bytes) among the whole stream, a uint24 value. - * However, a value of 0 signifies that the value is unknown. - */ - public int maxFrameSize; - - - /*---- Fields about stream properties ----*/ - - /** - * The sample rate of the audio stream (in hertz (Hz)), a positive uint20 value. - * Note that 0 is an invalid value. - */ - public int sampleRate; - - /** - * The number of channels in the audio stream, between 1 and 8 inclusive. - * 1 means mono, 2 means stereo, et cetera. - */ - public int numChannels; - - /** - * The bits per sample in the audio stream, in the range 4 to 32 inclusive. - */ - public int sampleDepth; - - /** - * The total number of samples per channel in the whole stream, a uint36 value. - * The special value of 0 signifies that the value is unknown (not empty zero-length stream). - */ - public long numSamples; - - /** - * The 16-byte MD5 hash of the raw uncompressed audio data serialized in little endian with - * channel interleaving (not planar). It can be all zeros to signify that the hash was not computed. - * It is okay to replace this array as needed (the initially constructed array object is not special). - */ - public byte[] md5Hash; - - - - /*---- Constructors ----*/ - - /** - * Constructs a blank stream info structure with certain default values. - */ - public StreamInfo() { - // Set these fields to legal unknown values - minFrameSize = 0; - maxFrameSize = 0; - numSamples = 0; - md5Hash = new byte[16]; - - // Set these fields to invalid (not reserved) values - minBlockSize = 0; - maxBlockSize = 0; - sampleRate = 0; - } - - - /** - * Constructs a stream info structure by parsing the specified 34-byte metadata block. - * (The array must contain only the metadata payload, without the type or length fields.) - * @param b the metadata block's payload data to parse (not {@code null}) - * @throws NullPointerException if the array is {@code null} - * @throws IllegalArgumentException if the array length is not 34 - * @throws DataFormatException if the data contains invalid values - */ - public StreamInfo(byte[] b) { - Objects.requireNonNull(b); - if (b.length != 34) - throw new IllegalArgumentException("Invalid data length"); - try { - FlacLowLevelInput in = new ByteArrayFlacInput(b); - minBlockSize = in.readUint(16); - maxBlockSize = in.readUint(16); - minFrameSize = in.readUint(24); - maxFrameSize = in.readUint(24); - if (minBlockSize < 16) - throw new DataFormatException("Minimum block size less than 16"); - if (maxBlockSize > 65535) - throw new DataFormatException("Maximum block size greater than 65535"); - if (maxBlockSize < minBlockSize) - throw new DataFormatException("Maximum block size less than minimum block size"); - if (minFrameSize != 0 && maxFrameSize != 0 && maxFrameSize < minFrameSize) - throw new DataFormatException("Maximum frame size less than minimum frame size"); - sampleRate = in.readUint(20); - if (sampleRate == 0 || sampleRate > 655350) - throw new DataFormatException("Invalid sample rate"); - numChannels = in.readUint(3) + 1; - sampleDepth = in.readUint(5) + 1; - numSamples = (long)in.readUint(18) << 18 | in.readUint(18); // uint36 - md5Hash = new byte[16]; - in.readFully(md5Hash); - // Skip closing the in-memory stream - } catch (IOException e) { - throw new AssertionError(e); - } - } - - - - /*---- Methods ----*/ - - /** - * Checks the state of this object, and either returns silently or throws an exception. - * @throws NullPointerException if the MD5 hash array is {@code null} - * @throws IllegalStateException if any field has an invalid value - */ - public void checkValues() { - if ((minBlockSize >>> 16) != 0) - throw new IllegalStateException("Invalid minimum block size"); - if ((maxBlockSize >>> 16) != 0) - throw new IllegalStateException("Invalid maximum block size"); - if ((minFrameSize >>> 24) != 0) - throw new IllegalStateException("Invalid minimum frame size"); - if ((maxFrameSize >>> 24) != 0) - throw new IllegalStateException("Invalid maximum frame size"); - if (sampleRate == 0 || (sampleRate >>> 20) != 0) - throw new IllegalStateException("Invalid sample rate"); - if (numChannels < 1 || numChannels > 8) - throw new IllegalStateException("Invalid number of channels"); - if (sampleDepth < 4 || sampleDepth > 32) - throw new IllegalStateException("Invalid sample depth"); - if ((numSamples >>> 36) != 0) - throw new IllegalStateException("Invalid number of samples"); - Objects.requireNonNull(md5Hash); - if (md5Hash.length != 16) - throw new IllegalStateException("Invalid MD5 hash length"); - } - - - /** - * Checks whether the specified frame information is consistent with values in - * this stream info object, either returning silently or throwing an exception. - * @param meta the frame info object to check (not {@code null}) - * @throws NullPointerException if the frame info is {@code null} - * @throws DataFormatException if the frame info contains bad values - */ - public void checkFrame(FrameInfo meta) { - if (meta.numChannels != numChannels) - throw new DataFormatException("Channel count mismatch"); - if (meta.sampleRate != -1 && meta.sampleRate != sampleRate) - throw new DataFormatException("Sample rate mismatch"); - if (meta.sampleDepth != -1 && meta.sampleDepth != sampleDepth) - throw new DataFormatException("Sample depth mismatch"); - if (numSamples != 0 && meta.blockSize > numSamples) - throw new DataFormatException("Block size exceeds total number of samples"); - - if (meta.blockSize > maxBlockSize) - throw new DataFormatException("Block size exceeds maximum"); - // Note: If minBlockSize == maxBlockSize, then the final block - // in the stream is allowed to be smaller than minBlockSize - - if (minFrameSize != 0 && meta.frameSize < minFrameSize) - throw new DataFormatException("Frame size less than minimum"); - if (maxFrameSize != 0 && meta.frameSize > maxFrameSize) - throw new DataFormatException("Frame size exceeds maximum"); - } - - - /** - * Writes this stream info metadata block to the specified output stream, including the - * metadata block header, writing exactly 38 bytes. (This is unlike the constructor, - * which takes an array without the type and length fields.) The output stream must - * initially be aligned to a byte boundary, and will finish at a byte boundary. - * @param last whether the metadata block is the final one in the FLAC file - * @param out the output stream to write to (not {@code null}) - * @throws NullPointerException if the output stream is {@code null} - * @throws IOException if an I/O exception occurred - */ - public void write(boolean last, BitOutputStream out) throws IOException { - // Check arguments and state - Objects.requireNonNull(out); - checkValues(); - - // Write metadata block header - out.writeInt(1, last ? 1 : 0); - out.writeInt(7, 0); // Type - out.writeInt(24, 34); // Length - - // Write stream info block fields - out.writeInt(16, minBlockSize); - out.writeInt(16, maxBlockSize); - out.writeInt(24, minFrameSize); - out.writeInt(24, maxFrameSize); - out.writeInt(20, sampleRate); - out.writeInt(3, numChannels - 1); - out.writeInt(5, sampleDepth - 1); - out.writeInt(18, (int)(numSamples >>> 18)); - out.writeInt(18, (int)(numSamples >>> 0)); - for (byte b : md5Hash) - out.writeInt(8, b); - } - - - - /*---- Static functions ----*/ - - /** - * Computes and returns the MD5 hash of the specified raw audio sample data at the specified - * bit depth. Currently, the bit depth must be a multiple of 8, between 8 and 32 inclusive. - * The returned array is a new object of length 16. - * @param samples the audio samples to hash, where - * each subarray is a channel (all not {@code null}) - * @param depth the bit depth of the audio samples - * (i.e. each sample value is a signed 'depth'-bit integer) - * @return a new 16-byte array representing the MD5 hash of the audio data - * @throws NullPointerException if the array or any subarray is {@code null} - * @throws IllegalArgumentException if the bit depth is unsupported - */ - public static byte[] getMd5Hash(int[][] samples, int depth) { - // Check arguments - Objects.requireNonNull(samples); - for (int[] chanSamples : samples) - Objects.requireNonNull(chanSamples); - if (depth < 0 || depth > 32 || depth % 8 != 0) - throw new IllegalArgumentException("Unsupported bit depth"); - - // Create hasher - MessageDigest hasher; - try { // Guaranteed available by the Java Cryptography Architecture - hasher = MessageDigest.getInstance("MD5"); - } catch (NoSuchAlgorithmException e) { - throw new AssertionError(e); - } - - // Convert samples to a stream of bytes, compute hash - int numChannels = samples.length; - int numSamples = samples[0].length; - int numBytes = depth / 8; - byte[] buf = new byte[numChannels * numBytes * Math.min(numSamples, 2048)]; - for (int i = 0, l = 0; i < numSamples; i++) { - for (int j = 0; j < numChannels; j++) { - int val = samples[j][i]; - for (int k = 0; k < numBytes; k++, l++) - buf[l] = (byte)(val >>> (k << 3)); - } - if (l == buf.length || i == numSamples - 1) { - hasher.update(buf, 0, l); - l = 0; - } - } - return hasher.digest(); - } - -} diff --git a/desktop/src/io/nayuki/flac/decode/AbstractFlacLowLevelInput.java b/desktop/src/io/nayuki/flac/decode/AbstractFlacLowLevelInput.java deleted file mode 100644 index bca3b88b..00000000 --- a/desktop/src/io/nayuki/flac/decode/AbstractFlacLowLevelInput.java +++ /dev/null @@ -1,354 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.decode; - -import java.io.EOFException; -import java.io.IOException; -import java.util.Arrays; -import java.util.Objects; - - -/** - * A basic implementation of most functionality required by FlacLowLevelInpuut. - */ -public abstract class AbstractFlacLowLevelInput implements FlacLowLevelInput { - - /*---- Fields ----*/ - - // Data from the underlying stream is first stored into this byte buffer before further processing. - private long byteBufferStartPos; - private byte[] byteBuffer; - private int byteBufferLen; - private int byteBufferIndex; - - // The buffer of next bits to return to a reader. Note that byteBufferIndex is incremented when byte - // values are put into the bit buffer, but they might not have been consumed by the ultimate reader yet. - private long bitBuffer; // Only the bottom bitBufferLen bits are valid; the top bits are garbage. - private int bitBufferLen; // Always in the range [0, 64]. - - // Current state of the CRC calculations. - private int crc8; // Always a uint8 value. - private int crc16; // Always a uint16 value. - private int crcStartIndex; // In the range [0, byteBufferLen], unless byteBufferLen = -1. - - - - /*---- Constructors ----*/ - - public AbstractFlacLowLevelInput() { - byteBuffer = new byte[4096]; - positionChanged(0); - } - - - - /*---- Methods ----*/ - - /*-- Stream position --*/ - - public long getPosition() { - return byteBufferStartPos + byteBufferIndex - (bitBufferLen + 7) / 8; - } - - - public int getBitPosition() { - return (-bitBufferLen) & 7; - } - - - // When a subclass handles seekTo() and didn't throw UnsupportedOperationException, - // it must call this method to flush the buffers of upcoming data. - protected void positionChanged(long pos) { - byteBufferStartPos = pos; - Arrays.fill(byteBuffer, (byte)0); // Defensive clearing, should have no visible effect outside of debugging - byteBufferLen = 0; - byteBufferIndex = 0; - bitBuffer = 0; // Defensive clearing, should have no visible effect outside of debugging - bitBufferLen = 0; - resetCrcs(); - } - - - // Either returns silently or throws an exception. - private void checkByteAligned() { - if (bitBufferLen % 8 != 0) - throw new IllegalStateException("Not at a byte boundary"); - } - - - /*-- Reading bitwise integers --*/ - - public int readUint(int n) throws IOException { - if (n < 0 || n > 32) - throw new IllegalArgumentException(); - while (bitBufferLen < n) { - int b = readUnderlying(); - if (b == -1) - throw new EOFException(); - bitBuffer = (bitBuffer << 8) | b; - bitBufferLen += 8; - assert 0 <= bitBufferLen && bitBufferLen <= 64; - } - int result = (int)(bitBuffer >>> (bitBufferLen - n)); - if (n != 32) { - result &= (1 << n) - 1; - assert (result >>> n) == 0; - } - bitBufferLen -= n; - assert 0 <= bitBufferLen && bitBufferLen <= 64; - return result; - } - - - public int readSignedInt(int n) throws IOException { - int shift = 32 - n; - return (readUint(n) << shift) >> shift; - } - - - public void readRiceSignedInts(int param, long[] result, int start, int end) throws IOException { - if (param < 0 || param > 31) - throw new IllegalArgumentException(); - long unaryLimit = 1L << (53 - param); - - byte[] consumeTable = RICE_DECODING_CONSUMED_TABLES[param]; - int[] valueTable = RICE_DECODING_VALUE_TABLES[param]; - while (true) { - middle: - while (start <= end - RICE_DECODING_CHUNK) { - if (bitBufferLen < RICE_DECODING_CHUNK * RICE_DECODING_TABLE_BITS) { - if (byteBufferIndex <= byteBufferLen - 8) { - fillBitBuffer(); - } else - break; - } - for (int i = 0; i < RICE_DECODING_CHUNK; i++, start++) { - // Fast decoder - int extractedBits = (int)(bitBuffer >>> (bitBufferLen - RICE_DECODING_TABLE_BITS)) & RICE_DECODING_TABLE_MASK; - int consumed = consumeTable[extractedBits]; - if (consumed == 0) - break middle; - bitBufferLen -= consumed; - result[start] = valueTable[extractedBits]; - } - } - - // Slow decoder - if (start >= end) - break; - long val = 0; - while (readUint(1) == 0) { - if (val >= unaryLimit) { - // At this point, the final decoded value would be so large that the result of the - // downstream restoreLpc() calculation would not fit in the output sample's bit depth - - // hence why we stop early and throw an exception. However, this check is conservative - // and doesn't catch all the cases where the post-LPC result wouldn't fit. - throw new DataFormatException("Residual value too large"); - } - val++; - } - val = (val << param) | readUint(param); // Note: Long masking unnecessary because param <= 31 - assert (val >>> 53) == 0; // Must fit a uint53 by design due to unaryLimit - val = (val >>> 1) ^ -(val & 1); // Transform uint53 to int53 according to Rice coding of signed numbers - assert (val >> 52) == 0 || (val >> 52) == -1; // Must fit a signed int53 by design - result[start] = val; - start++; - } - } - - - // Appends at least 8 bits to the bit buffer, or throws EOFException. - private void fillBitBuffer() throws IOException { - int i = byteBufferIndex; - int n = Math.min((64 - bitBufferLen) >>> 3, byteBufferLen - i); - byte[] b = byteBuffer; - if (n > 0) { - for (int j = 0; j < n; j++, i++) - bitBuffer = (bitBuffer << 8) | (b[i] & 0xFF); - bitBufferLen += n << 3; - } else if (bitBufferLen <= 56) { - int temp = readUnderlying(); - if (temp == -1) - throw new EOFException(); - bitBuffer = (bitBuffer << 8) | temp; - bitBufferLen += 8; - } - assert 8 <= bitBufferLen && bitBufferLen <= 64; - byteBufferIndex += n; - } - - - /*-- Reading bytes --*/ - - public int readByte() throws IOException { - checkByteAligned(); - if (bitBufferLen >= 8) - return readUint(8); - else { - assert bitBufferLen == 0; - return readUnderlying(); - } - } - - - public void readFully(byte[] b) throws IOException { - Objects.requireNonNull(b); - checkByteAligned(); - for (int i = 0; i < b.length; i++) - b[i] = (byte)readUint(8); - } - - - // Reads a byte from the byte buffer (if available) or from the underlying stream, returning either a uint8 or -1. - private int readUnderlying() throws IOException { - if (byteBufferIndex >= byteBufferLen) { - if (byteBufferLen == -1) - return -1; - byteBufferStartPos += byteBufferLen; - updateCrcs(0); - byteBufferLen = readUnderlying(byteBuffer, 0, byteBuffer.length); - crcStartIndex = 0; - if (byteBufferLen <= 0) - return -1; - byteBufferIndex = 0; - } - assert byteBufferIndex < byteBufferLen; - int temp = byteBuffer[byteBufferIndex] & 0xFF; - byteBufferIndex++; - return temp; - } - - - // Reads up to 'len' bytes from the underlying byte-based input stream into the given array subrange. - // Returns a value in the range [0, len] for a successful read, or -1 if the end of stream was reached. - protected abstract int readUnderlying(byte[] buf, int off, int len) throws IOException; - - - /*-- CRC calculations --*/ - - public void resetCrcs() { - checkByteAligned(); - crcStartIndex = byteBufferIndex - bitBufferLen / 8; - crc8 = 0; - crc16 = 0; - } - - - public int getCrc8() { - checkByteAligned(); - updateCrcs(bitBufferLen / 8); - if ((crc8 >>> 8) != 0) - throw new AssertionError(); - return crc8; - } - - - public int getCrc16() { - checkByteAligned(); - updateCrcs(bitBufferLen / 8); - if ((crc16 >>> 16) != 0) - throw new AssertionError(); - return crc16; - } - - - // Updates the two CRC values with data in byteBuffer[crcStartIndex : byteBufferIndex - unusedTrailingBytes]. - private void updateCrcs(int unusedTrailingBytes) { - int end = byteBufferIndex - unusedTrailingBytes; - for (int i = crcStartIndex; i < end; i++) { - int b = byteBuffer[i] & 0xFF; - crc8 = CRC8_TABLE[crc8 ^ b] & 0xFF; - crc16 = CRC16_TABLE[(crc16 >>> 8) ^ b] ^ ((crc16 & 0xFF) << 8); - assert (crc8 >>> 8) == 0; - assert (crc16 >>> 16) == 0; - } - crcStartIndex = end; - } - - - /*-- Miscellaneous --*/ - - // Note: This class only uses memory and has no native resources. It's not strictly necessary to - // call the implementation of AbstractFlacLowLevelInput.close() here, but it's a good habit anyway. - public void close() throws IOException { - byteBuffer = null; - byteBufferLen = -1; - byteBufferIndex = -1; - bitBuffer = 0; - bitBufferLen = -1; - crc8 = -1; - crc16 = -1; - crcStartIndex = -1; - } - - - - /*---- Tables of constants ----*/ - - // For Rice decoding - - private static final int RICE_DECODING_TABLE_BITS = 13; // Configurable, must be positive - private static final int RICE_DECODING_TABLE_MASK = (1 << RICE_DECODING_TABLE_BITS) - 1; - private static final byte[][] RICE_DECODING_CONSUMED_TABLES = new byte[31][1 << RICE_DECODING_TABLE_BITS]; - private static final int[][] RICE_DECODING_VALUE_TABLES = new int[31][1 << RICE_DECODING_TABLE_BITS]; - private static final int RICE_DECODING_CHUNK = 4; // Configurable, must be positive, and RICE_DECODING_CHUNK * RICE_DECODING_TABLE_BITS <= 64 - - static { - for (int param = 0; param < RICE_DECODING_CONSUMED_TABLES.length; param++) { - byte[] consumed = RICE_DECODING_CONSUMED_TABLES[param]; - int[] values = RICE_DECODING_VALUE_TABLES[param]; - for (int i = 0; ; i++) { - int numBits = (i >>> param) + 1 + param; - if (numBits > RICE_DECODING_TABLE_BITS) - break; - int bits = ((1 << param) | (i & ((1 << param) - 1))); - int shift = RICE_DECODING_TABLE_BITS - numBits; - for (int j = 0; j < (1 << shift); j++) { - consumed[(bits << shift) | j] = (byte)numBits; - values[(bits << shift) | j] = (i >>> 1) ^ -(i & 1); - } - } - if (consumed[0] != 0) - throw new AssertionError(); - } - } - - - // For CRC calculations - - private static byte[] CRC8_TABLE = new byte[256]; - private static char[] CRC16_TABLE = new char[256]; - - static { - for (int i = 0; i < CRC8_TABLE.length; i++) { - int temp8 = i; - int temp16 = i << 8; - for (int j = 0; j < 8; j++) { - temp8 = (temp8 << 1) ^ ((temp8 >>> 7) * 0x107); - temp16 = (temp16 << 1) ^ ((temp16 >>> 15) * 0x18005); - } - CRC8_TABLE[i] = (byte)temp8; - CRC16_TABLE[i] = (char)temp16; - } - } - -} diff --git a/desktop/src/io/nayuki/flac/decode/ByteArrayFlacInput.java b/desktop/src/io/nayuki/flac/decode/ByteArrayFlacInput.java deleted file mode 100644 index 2e998093..00000000 --- a/desktop/src/io/nayuki/flac/decode/ByteArrayFlacInput.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.decode; - -import java.io.IOException; -import java.util.Objects; - - -/** - * A FLAC input stream based on a fixed byte array. - */ -public final class ByteArrayFlacInput extends AbstractFlacLowLevelInput { - - /*---- Fields ----*/ - - // The underlying byte array to read from. - private byte[] data; - private int offset; - - - - /*---- Constructors ----*/ - - public ByteArrayFlacInput(byte[] b) { - super(); - data = Objects.requireNonNull(b); - offset = 0; - } - - - - /*---- Methods ----*/ - - public long getLength() { - return data.length; - } - - - public void seekTo(long pos) { - offset = (int)pos; - positionChanged(pos); - } - - - protected int readUnderlying(byte[] buf, int off, int len) { - if (off < 0 || off > buf.length || len < 0 || len > buf.length - off) - throw new ArrayIndexOutOfBoundsException(); - int n = Math.min(data.length - offset, len); - if (n == 0) - return -1; - System.arraycopy(data, offset, buf, off, n); - offset += n; - return n; - } - - - // Discards data buffers and invalidates this stream. Because this class and its superclass - // only use memory and have no native resources, it's okay to simply let a ByteArrayFlacInput - // be garbage-collected without calling close(). - public void close() throws IOException { - if (data != null) { - data = null; - super.close(); - } - } - -} diff --git a/desktop/src/io/nayuki/flac/decode/DataFormatException.java b/desktop/src/io/nayuki/flac/decode/DataFormatException.java deleted file mode 100644 index 80e1f513..00000000 --- a/desktop/src/io/nayuki/flac/decode/DataFormatException.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.decode; - - -/** - * Thrown when data being read violates the FLAC file format. - */ -@SuppressWarnings("serial") -public class DataFormatException extends RuntimeException { - - /*---- Constructors ----*/ - - public DataFormatException() { - super(); - } - - - public DataFormatException(String msg) { - super(msg); - } - - - public DataFormatException(String msg, Throwable cause) { - super(msg, cause); - } - -} diff --git a/desktop/src/io/nayuki/flac/decode/FlacDecoder.java b/desktop/src/io/nayuki/flac/decode/FlacDecoder.java deleted file mode 100644 index 9a2d7cf6..00000000 --- a/desktop/src/io/nayuki/flac/decode/FlacDecoder.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.decode; - -import java.io.File; -import java.io.IOException; -import java.util.Objects; - -import io.nayuki.flac.common.FrameInfo; -import io.nayuki.flac.common.SeekTable; -import io.nayuki.flac.common.StreamInfo; - -/** - * Handles high-level decoding and seeking in FLAC files. Also returns metadata - * blocks. Every object is stateful, not thread-safe, and needs to be closed. - * Sample usage: - * - *

- * // Create a decoder
- *FlacDecoder dec = new FlacDecoder(...);
- *
- *// Make the decoder process all metadata blocks internally.
- *// We could capture the returned data for extra processing.
- *// We must read all metadata before reading audio data.
- *while (dec.readAndHandleMetadataBlock() != null);
- *
- *// Read audio samples starting from beginning
- *int[][] samples = (...);
- *dec.readAudioBlock(samples, ...);
- *dec.readAudioBlock(samples, ...);
- *dec.readAudioBlock(samples, ...);
- *
- *// Seek to some position and continue reading
- *dec.seekAndReadAudioBlock(..., samples, ...);
- *dec.readAudioBlock(samples, ...);
- *dec.readAudioBlock(samples, ...);
- *
- *// Close underlying file stream
- *dec.close();
- * 
- * - * @see FrameDecoder - * @see FlacLowLevelInput - */ -public final class FlacDecoder implements AutoCloseable { - - /*---- Fields ----*/ - - public StreamInfo streamInfo; - public SeekTable seekTable; - - private FlacLowLevelInput input; - - private long metadataEndPos; - - private FrameDecoder frameDec; - - /*---- Constructors ----*/ - - // Constructs a new FLAC decoder to read the given file. - // This immediately reads the basic header but not metadata blocks. - public FlacDecoder(final File file) throws IOException { - // Initialize streams - Objects.requireNonNull(file); - this.input = new SeekableFileFlacInput(file); - - // Read basic header - if (this.input.readUint(32) != 0x664C6143) { - throw new DataFormatException("Invalid magic string"); - } - this.metadataEndPos = -1; - } - - // Constructs a new FLAC decoder to read the given file. - // This immediately reads the basic header but not metadata blocks. - public FlacDecoder(final byte[] file) throws IOException { - // Initialize streams - Objects.requireNonNull(file); - this.input = new ByteArrayFlacInput(file); - - // Read basic header - if (this.input.readUint(32) != 0x664C6143) { - throw new DataFormatException("Invalid magic string"); - } - this.metadataEndPos = -1; - } - - /*---- Methods ----*/ - - // Reads, handles, and returns the next metadata block. Returns a pair (Integer - // type, byte[] data) if the - // next metadata block exists, otherwise returns null if the final metadata - // block was previously read. - // In addition to reading and returning data, this method also updates the - // internal state - // of this object to reflect the new data seen, and throws exceptions for - // situations such as - // not starting with a stream info metadata block or encountering duplicates of - // certain blocks. - public Object[] readAndHandleMetadataBlock() throws IOException { - if (this.metadataEndPos != -1) { - return null; // All metadata already consumed - } - - // Read entire block - final boolean last = this.input.readUint(1) != 0; - final int type = this.input.readUint(7); - final int length = this.input.readUint(24); - final byte[] data = new byte[length]; - this.input.readFully(data); - - // Handle recognized block - if (type == 0) { - if (this.streamInfo != null) { - throw new DataFormatException("Duplicate stream info metadata block"); - } - this.streamInfo = new StreamInfo(data); - } - else { - if (this.streamInfo == null) { - throw new DataFormatException("Expected stream info metadata block"); - } - if (type == 3) { - if (this.seekTable != null) { - throw new DataFormatException("Duplicate seek table metadata block"); - } - this.seekTable = new SeekTable(data); - } - } - - if (last) { - this.metadataEndPos = this.input.getPosition(); - this.frameDec = new FrameDecoder(this.input, this.streamInfo.sampleDepth); - } - return new Object[] { type, data }; - } - - // Reads and decodes the next block of audio samples into the given buffer, - // returning the number of samples in the block. The return value is 0 if the - // read - // started at the end of stream, or a number in the range [1, 65536] for a valid - // block. - // All metadata blocks must be read before starting to read audio blocks. - public int readAudioBlock(final int[][] samples, final int off) throws IOException { - if (this.frameDec == null) { - throw new IllegalStateException("Metadata blocks not fully consumed yet"); - } - final FrameInfo frame = this.frameDec.readFrame(samples, off); - if (frame == null) { - return 0; - } - else { - return frame.blockSize; // In the range [1, 65536] - } - } - - // Seeks to the given sample position and reads audio samples into the given - // buffer, - // returning the number of samples filled. If audio data is available then the - // return value - // is at least 1; otherwise 0 is returned to indicate the end of stream. Note - // that the - // sample position can land in the middle of a FLAC block and will still behave - // correctly. - // In theory this method subsumes the functionality of readAudioBlock(), but - // seeking can be - // an expensive operation so readAudioBlock() should be used for ordinary - // contiguous streaming. - public int seekAndReadAudioBlock(final long pos, final int[][] samples, final int off) throws IOException { - if (this.frameDec == null) { - throw new IllegalStateException("Metadata blocks not fully consumed yet"); - } - - long[] sampleAndFilePos = getBestSeekPoint(pos); - if ((pos - sampleAndFilePos[0]) > 300000) { - sampleAndFilePos = seekBySyncAndDecode(pos); - sampleAndFilePos[1] -= this.metadataEndPos; - } - this.input.seekTo(sampleAndFilePos[1] + this.metadataEndPos); - - long curPos = sampleAndFilePos[0]; - final int[][] smpl = new int[this.streamInfo.numChannels][65536]; - while (true) { - final FrameInfo frame = this.frameDec.readFrame(smpl, 0); - if (frame == null) { - return 0; - } - final long nextPos = curPos + frame.blockSize; - if (nextPos > pos) { - for (int ch = 0; ch < smpl.length; ch++) { - System.arraycopy(smpl[ch], (int) (pos - curPos), samples[ch], off, (int) (nextPos - pos)); - } - return (int) (nextPos - pos); - } - curPos = nextPos; - } - } - - private long[] getBestSeekPoint(final long pos) { - long samplePos = 0; - long filePos = 0; - if (this.seekTable != null) { - for (final SeekTable.SeekPoint p : this.seekTable.points) { - if (p.sampleOffset <= pos) { - samplePos = p.sampleOffset; - filePos = p.fileOffset; - } - else { - break; - } - } - } - return new long[] { samplePos, filePos }; - } - - // Returns a pair (sample offset, file position) such sampleOffset <= pos and - // abs(sampleOffset - pos) - // is a relatively small number compared to the total number of samples in the - // audio file. - // This method works by skipping to arbitrary places in the file, finding a sync - // sequence, - // decoding the frame header, examining the audio position stored in the frame, - // and possibly deciding - // to skip to other places and retrying. This changes the state of the input - // streams as a side effect. - // There is a small chance of finding a valid-looking frame header but causing - // erroneous decoding later. - private long[] seekBySyncAndDecode(final long pos) throws IOException { - long start = this.metadataEndPos; - long end = this.input.getLength(); - while ((end - start) > 100000) { // Binary search - final long mid = (start + end) >>> 1; - final long[] offsets = getNextFrameOffsets(mid); - if ((offsets == null) || (offsets[0] > pos)) { - end = mid; - } - else { - start = offsets[1]; - } - } - return getNextFrameOffsets(start); - } - - // Returns a pair (sample offset, file position) describing the next frame found - // starting - // at the given file offset, or null if no frame is found before the end of - // stream. - // This changes the state of the input streams as a side effect. - private long[] getNextFrameOffsets(long filePos) throws IOException { - if ((filePos < this.metadataEndPos) || (filePos > this.input.getLength())) { - throw new IllegalArgumentException("File position out of bounds"); - } - - // Repeatedly search for a sync - while (true) { - this.input.seekTo(filePos); - - // Finite state machine to match the 2-byte sync sequence - int state = 0; - while (true) { - final int b = this.input.readByte(); - if (b == -1) { - return null; - } - else if (b == 0xFF) { - state = 1; - } - else if ((state == 1) && ((b & 0xFE) == 0xF8)) { - break; - } - else { - state = 0; - } - } - - // Sync found, rewind 2 bytes, try to decode frame header - filePos = this.input.getPosition() - 2; - this.input.seekTo(filePos); - try { - final FrameInfo frame = FrameInfo.readFrame(this.input); - return new long[] { getSampleOffset(frame), filePos }; - } - catch (final DataFormatException e) { - // Advance past the sync and search again - filePos += 2; - } - } - } - - // Calculates the sample offset of the given frame, automatically handling the - // constant-block-size case. - private long getSampleOffset(final FrameInfo frame) { - Objects.requireNonNull(frame); - if (frame.sampleOffset != -1) { - return frame.sampleOffset; - } - else if (frame.frameIndex != -1) { - return frame.frameIndex * this.streamInfo.maxBlockSize; - } - else { - throw new AssertionError(); - } - } - - // Closes the underlying input streams and discards object data. - // This decoder object becomes invalid for any method calls or field usages. - @Override - public void close() throws IOException { - if (this.input != null) { - this.streamInfo = null; - this.seekTable = null; - this.frameDec = null; - this.input.close(); - this.input = null; - } - } - -} diff --git a/desktop/src/io/nayuki/flac/decode/FlacLowLevelInput.java b/desktop/src/io/nayuki/flac/decode/FlacLowLevelInput.java deleted file mode 100644 index 24c2a80b..00000000 --- a/desktop/src/io/nayuki/flac/decode/FlacLowLevelInput.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.decode; - -import java.io.IOException; - - -/** - * A low-level input stream tailored to the needs of FLAC decoding. An overview of methods includes - * bit reading, CRC calculation, Rice decoding, and positioning and seeking (partly optional). - * @see SeekableFileFlacInput - * @see FrameDecoder - */ -public interface FlacLowLevelInput extends AutoCloseable { - - /*---- Stream position ----*/ - - // Returns the total number of bytes in the FLAC file represented by this input stream. - // This number should not change for the lifetime of this object. Implementing this is optional; - // it's intended to support blind seeking without the use of seek tables, such as binary searching - // the whole file. A class may choose to throw UnsupportedOperationException instead, - // such as for a non-seekable network input stream of unknown length. - public long getLength(); - - - // Returns the current byte position in the stream, a non-negative value. - // This increments after every 8 bits read, and a partially read byte is treated as unread. - // This value is 0 initially, is set directly by seekTo(), and potentially increases - // after every call to a read*() method. Other methods do not affect this value. - public long getPosition(); - - - // Returns the current number of consumed bits in the current byte. This starts at 0, - // increments for each bit consumed, maxes out at 7, then resets to 0 and repeats. - public int getBitPosition(); - - - // Changes the position of the next read to the given byte offset from the start of the stream. - // This also resets CRCs and sets the bit position to 0. - // Implementing this is optional; it is intended to support playback seeking. - // A class may choose to throw UnsupportedOperationException instead. - public void seekTo(long pos) throws IOException; - - - - /*---- Reading bitwise integers ----*/ - - // Reads the next given number of bits (0 <= n <= 32) as an unsigned integer (i.e. zero-extended to int32). - // However in the case of n = 32, the result will be a signed integer that represents a uint32. - public int readUint(int n) throws IOException; - - - // Reads the next given number of bits (0 <= n <= 32) as an signed integer (i.e. sign-extended to int32). - public int readSignedInt(int n) throws IOException; - - - // Reads and decodes the next batch of Rice-coded signed integers. Note that any Rice-coded integer might read a large - // number of bits from the underlying stream (but not in practice because it would be a very inefficient encoding). - // Every new value stored into the array is guaranteed to fit into a signed int53 - see FrameDecoder.restoreLpc() - // for an explanation of why this is a necessary (but not sufficient) bound on the range of decoded values. - public void readRiceSignedInts(int param, long[] result, int start, int end) throws IOException; - - - - /*---- Reading bytes ----*/ - - // Returns the next unsigned byte value (in the range [0, 255]) or -1 for EOF. - // Must be called at a byte boundary (i.e. getBitPosition() == 0), otherwise IllegalStateException is thrown. - public int readByte() throws IOException; - - - // Discards any partial bits, then reads the given array fully or throws EOFException. - // Must be called at a byte boundary (i.e. getBitPosition() == 0), otherwise IllegalStateException is thrown. - public void readFully(byte[] b) throws IOException; - - - - /*---- CRC calculations ----*/ - - // Marks the current byte position as the start of both CRC calculations. - // The effect of resetCrcs() is implied at the beginning of stream and when seekTo() is called. - // Must be called at a byte boundary (i.e. getBitPosition() == 0), otherwise IllegalStateException is thrown. - public void resetCrcs(); - - - // Returns the CRC-8 hash of all the bytes read since the most recent time one of these - // events occurred: a call to resetCrcs(), a call to seekTo(), the beginning of stream. - // Must be called at a byte boundary (i.e. getBitPosition() == 0), otherwise IllegalStateException is thrown. - public int getCrc8(); - - - // Returns the CRC-16 hash of all the bytes read since the most recent time one of these - // events occurred: a call to resetCrcs(), a call to seekTo(), the beginning of stream. - // Must be called at a byte boundary (i.e. getBitPosition() == 0), otherwise IllegalStateException is thrown. - public int getCrc16(); - - - - /*---- Miscellaneous ----*/ - - // Closes underlying objects / native resources, and possibly discards memory buffers. - // Generally speaking, this operation invalidates this input stream, so calling methods - // (other than close()) or accessing fields thereafter should be forbidden. - // The close() method must be idempotent and safe when called more than once. - // If an implementation does not have native or time-sensitive resources, it is okay for the class user - // to skip calling close() and simply let the object be garbage-collected. But out of good habit, it is - // recommended to always close a FlacLowLevelInput stream so that the logic works correctly on all types. - public void close() throws IOException; - -} diff --git a/desktop/src/io/nayuki/flac/decode/FrameDecoder.java b/desktop/src/io/nayuki/flac/decode/FrameDecoder.java deleted file mode 100644 index 7d1d12d0..00000000 --- a/desktop/src/io/nayuki/flac/decode/FrameDecoder.java +++ /dev/null @@ -1,387 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.decode; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Objects; -import io.nayuki.flac.common.FrameInfo; - - -/** - * Decodes a FLAC frame from an input stream into raw audio samples. Note that these objects are - * stateful and not thread-safe, due to the bit input stream field, private temporary arrays, etc. - *

This class only uses memory and has no native resources; however, the - * code that uses this class is responsible for cleaning up the input stream.

- * @see FlacDecoder - * @see FlacLowLevelInput - */ -public final class FrameDecoder { - - /*---- Fields ----*/ - - // Can be changed when there is no active call of readFrame(). - // Must be not null when readFrame() is called. - public FlacLowLevelInput in; - - // Can be changed when there is no active call of readFrame(). - // Must be in the range [4, 32]. - public int expectedSampleDepth; - - // Temporary arrays to hold two decoded audio channels (a.k.a. subframes). They have int64 range - // because the worst case of 32-bit audio encoded in stereo side mode uses signed 33 bits. - // The maximum possible block size is either 65536 samples per channel from the - // frame header logic, or 65535 from a strict reading of the FLAC specification. - // Two buffers are needed for stereo coding modes, but not more than two because - // all other multi-channel audio is processed independently per channel. - private long[] temp0; - private long[] temp1; - - // The number of samples (per channel) in the current block/frame being processed. - // This value is only valid while the method readFrame() is on the call stack. - // When readFrame() is active, this value is in the range [1, 65536]. - private int currentBlockSize; - - - - /*---- Constructors ----*/ - - // Constructs a frame decoder that initially uses the given stream. - // The caller is responsible for cleaning up the input stream. - public FrameDecoder(FlacLowLevelInput in, int expectDepth) { - this.in = in; - expectedSampleDepth = expectDepth; - temp0 = new long[65536]; - temp1 = new long[65536]; - currentBlockSize = -1; - } - - - - /*---- Methods ----*/ - - // Reads the next frame of FLAC data from the current bit input stream, decodes it, - // and stores output samples into the given array, and returns a new metadata object. - // The bit input stream must be initially aligned at a byte boundary. If EOF is encountered before - // any actual bytes were read, then this returns null. Otherwise this function either successfully - // decodes a frame and returns a new metadata object, or throws an appropriate exception. A frame - // may have up to 8 channels and 65536 samples, so the output arrays need to be sized appropriately. - public FrameInfo readFrame(int[][] outSamples, int outOffset) throws IOException { - // Check field states - Objects.requireNonNull(in); - if (currentBlockSize != -1) - throw new IllegalStateException("Concurrent call"); - - // Parse the frame header to see if one is available - long startByte = in.getPosition(); - FrameInfo meta = FrameInfo.readFrame(in); - if (meta == null) // EOF occurred cleanly - return null; - if (meta.sampleDepth != -1 && meta.sampleDepth != expectedSampleDepth) - throw new DataFormatException("Sample depth mismatch"); - - // Check arguments and read frame header - currentBlockSize = meta.blockSize; - Objects.requireNonNull(outSamples); - if (outOffset < 0 || outOffset > outSamples[0].length) - throw new IndexOutOfBoundsException(); - if (outSamples.length < meta.numChannels) - throw new IllegalArgumentException("Output array too small for number of channels"); - if (outOffset > outSamples[0].length - currentBlockSize) - throw new IndexOutOfBoundsException(); - - // Do the hard work - decodeSubframes(expectedSampleDepth, meta.channelAssignment, outSamples, outOffset); - - // Read padding and footer - if (in.readUint((8 - in.getBitPosition()) % 8) != 0) - throw new DataFormatException("Invalid padding bits"); - int computedCrc16 = in.getCrc16(); - if (in.readUint(16) != computedCrc16) - throw new DataFormatException("CRC-16 mismatch"); - - // Handle frame size and miscellaneous - long frameSize = in.getPosition() - startByte; - if (frameSize < 10) - throw new AssertionError(); - if ((int)frameSize != frameSize) - throw new DataFormatException("Frame size too large"); - meta.frameSize = (int)frameSize; - currentBlockSize = -1; - return meta; - } - - - // Based on the current bit input stream and the two given arguments, this method reads and decodes - // each subframe, performs stereo decoding if applicable, and writes the final uncompressed audio data - // to the array range outSamples[0 : numChannels][outOffset : outOffset + currentBlockSize]. - // Note that this method uses the private temporary arrays and passes them into sub-method calls. - private void decodeSubframes(int sampleDepth, int chanAsgn, int[][] outSamples, int outOffset) throws IOException { - // Check arguments - if (sampleDepth < 1 || sampleDepth > 32) - throw new IllegalArgumentException(); - if ((chanAsgn >>> 4) != 0) - throw new IllegalArgumentException(); - - if (0 <= chanAsgn && chanAsgn <= 7) { - // Handle 1 to 8 independently coded channels - int numChannels = chanAsgn + 1; - for (int ch = 0; ch < numChannels; ch++) { - decodeSubframe(sampleDepth, temp0); - int[] outChan = outSamples[ch]; - for (int i = 0; i < currentBlockSize; i++) - outChan[outOffset + i] = checkBitDepth(temp0[i], sampleDepth); - } - - } else if (8 <= chanAsgn && chanAsgn <= 10) { - // Handle one of the side-coded stereo methods - decodeSubframe(sampleDepth + (chanAsgn == 9 ? 1 : 0), temp0); - decodeSubframe(sampleDepth + (chanAsgn == 9 ? 0 : 1), temp1); - - if (chanAsgn == 8) { // Left-side stereo - for (int i = 0; i < currentBlockSize; i++) - temp1[i] = temp0[i] - temp1[i]; - } else if (chanAsgn == 9) { // Side-right stereo - for (int i = 0; i < currentBlockSize; i++) - temp0[i] += temp1[i]; - } else if (chanAsgn == 10) { // Mid-side stereo - for (int i = 0; i < currentBlockSize; i++) { - long side = temp1[i]; - long right = temp0[i] - (side >> 1); - temp1[i] = right; - temp0[i] = right + side; - } - } else - throw new AssertionError(); - - // Copy data from temporary to output arrays, and convert from long to int - int[] outLeft = outSamples[0]; - int[] outRight = outSamples[1]; - for (int i = 0; i < currentBlockSize; i++) { - outLeft [outOffset + i] = checkBitDepth(temp0[i], sampleDepth); - outRight[outOffset + i] = checkBitDepth(temp1[i], sampleDepth); - } - } else // 11 <= channelAssignment <= 15 - throw new DataFormatException("Reserved channel assignment"); - } - - - // Checks that 'val' is a signed 'depth'-bit integer, and either returns the - // value downcasted to an int or throws an exception if it's out of range. - // Note that depth must be in the range [1, 32] because the return value is an int. - // For example when depth = 16, the range of valid values is [-32768, 32767]. - private static int checkBitDepth(long val, int depth) { - assert 1 <= depth && depth <= 32; - // Equivalent check: (val >> (depth - 1)) == 0 || (val >> (depth - 1)) == -1 - if (val >> (depth - 1) == val >> depth) - return (int)val; - else - throw new IllegalArgumentException(val + " is not a signed " + depth + "-bit value"); - } - - - // Reads one subframe from the bit input stream, decodes it, and writes to result[0 : currentBlockSize]. - private void decodeSubframe(int sampleDepth, long[] result) throws IOException { - // Check arguments - Objects.requireNonNull(result); - if (sampleDepth < 1 || sampleDepth > 33) - throw new IllegalArgumentException(); - if (result.length < currentBlockSize) - throw new IllegalArgumentException(); - - // Read header fields - if (in.readUint(1) != 0) - throw new DataFormatException("Invalid padding bit"); - int type = in.readUint(6); - int shift = in.readUint(1); // Also known as "wasted bits-per-sample" - if (shift == 1) { - while (in.readUint(1) == 0) { // Unary coding - if (shift >= sampleDepth) - throw new DataFormatException("Waste-bits-per-sample exceeds sample depth"); - shift++; - } - } - if (!(0 <= shift && shift <= sampleDepth)) - throw new AssertionError(); - sampleDepth -= shift; - - // Read sample data based on type - if (type == 0) // Constant coding - Arrays.fill(result, 0, currentBlockSize, in.readSignedInt(sampleDepth)); - else if (type == 1) { // Verbatim coding - for (int i = 0; i < currentBlockSize; i++) - result[i] = in.readSignedInt(sampleDepth); - } else if (8 <= type && type <= 12) - decodeFixedPredictionSubframe(type - 8, sampleDepth, result); - else if (32 <= type && type <= 63) - decodeLinearPredictiveCodingSubframe(type - 31, sampleDepth, result); - else - throw new DataFormatException("Reserved subframe type"); - - // Add trailing zeros to each sample - if (shift > 0) { - for (int i = 0; i < currentBlockSize; i++) - result[i] <<= shift; - } - } - - - // Reads from the input stream, performs computation, and writes to result[0 : currentBlockSize]. - private void decodeFixedPredictionSubframe(int predOrder, int sampleDepth, long[] result) throws IOException { - // Check arguments - Objects.requireNonNull(result); - if (sampleDepth < 1 || sampleDepth > 33) - throw new IllegalArgumentException(); - if (predOrder < 0 || predOrder >= FIXED_PREDICTION_COEFFICIENTS.length) - throw new IllegalArgumentException(); - if (predOrder > currentBlockSize) - throw new DataFormatException("Fixed prediction order exceeds block size"); - if (result.length < currentBlockSize) - throw new IllegalArgumentException(); - - // Read and compute various values - for (int i = 0; i < predOrder; i++) // Non-Rice-coded warm-up samples - result[i] = in.readSignedInt(sampleDepth); - readResiduals(predOrder, result); - restoreLpc(result, FIXED_PREDICTION_COEFFICIENTS[predOrder], sampleDepth, 0); - } - - private static final int[][] FIXED_PREDICTION_COEFFICIENTS = { - {}, - {1}, - {2, -1}, - {3, -3, 1}, - {4, -6, 4, -1}, - }; - - - // Reads from the input stream, performs computation, and writes to result[0 : currentBlockSize]. - private void decodeLinearPredictiveCodingSubframe(int lpcOrder, int sampleDepth, long[] result) throws IOException { - // Check arguments - Objects.requireNonNull(result); - if (sampleDepth < 1 || sampleDepth > 33) - throw new IllegalArgumentException(); - if (lpcOrder < 1 || lpcOrder > 32) - throw new IllegalArgumentException(); - if (lpcOrder > currentBlockSize) - throw new DataFormatException("LPC order exceeds block size"); - if (result.length < currentBlockSize) - throw new IllegalArgumentException(); - - // Read non-Rice-coded warm-up samples - for (int i = 0; i < lpcOrder; i++) - result[i] = in.readSignedInt(sampleDepth); - - // Read parameters for the LPC coefficients - int precision = in.readUint(4) + 1; - if (precision == 16) - throw new DataFormatException("Invalid LPC precision"); - int shift = in.readSignedInt(5); - if (shift < 0) - throw new DataFormatException("Invalid LPC shift"); - - // Read the coefficients themselves - int[] coefs = new int[lpcOrder]; - for (int i = 0; i < coefs.length; i++) - coefs[i] = in.readSignedInt(precision); - - // Perform the main LPC decoding - readResiduals(lpcOrder, result); - restoreLpc(result, coefs, sampleDepth, shift); - } - - - // Updates the values of result[coefs.length : currentBlockSize] according to linear predictive coding. - // This method reads all the arguments and the field currentBlockSize, only writes to result, and has no other side effects. - // After this method returns, every value in result must fit in a signed sampleDepth-bit integer. - // The largest allowed sample depth is 33, hence the largest absolute value allowed in the result is 2^32. - // During the LPC restoration process, the prefix of result before index i consists of entirely int33 values. - // Because coefs.length <= 32 and each coefficient fits in a signed int15 (both according to the FLAC specification), - // the maximum (worst-case) absolute value of 'sum' is 2^32 * 2^14 * 32 = 2^51, which fits in a signed int53. - // And because of this, the maximum possible absolute value of a residual before LPC restoration is applied, - // such that the post-LPC result fits in a signed int33, is 2^51 + 2^32 which also fits in a signed int53. - // Therefore a residue that is larger than a signed int53 will necessarily not fit in the int33 result and is wrong. - private void restoreLpc(long[] result, int[] coefs, int sampleDepth, int shift) { - // Check and handle arguments - Objects.requireNonNull(result); - Objects.requireNonNull(coefs); - if (result.length < currentBlockSize) - throw new IllegalArgumentException(); - if (sampleDepth < 1 || sampleDepth > 33) - throw new IllegalArgumentException(); - if (shift < 0 || shift > 63) - throw new IllegalArgumentException(); - long lowerBound = (-1) << (sampleDepth - 1); - long upperBound = -(lowerBound + 1); - - for (int i = coefs.length; i < currentBlockSize; i++) { - long sum = 0; - for (int j = 0; j < coefs.length; j++) - sum += result[i - 1 - j] * coefs[j]; - assert (sum >> 53) == 0 || (sum >> 53) == -1; // Fits in signed int54 - sum = result[i] + (sum >> shift); - // Check that sum fits in a sampleDepth-bit signed integer, - // i.e. -(2^(sampleDepth-1)) <= sum < 2^(sampleDepth-1) - if (sum < lowerBound || sum > upperBound) - throw new DataFormatException("Post-LPC result exceeds bit depth"); - result[i] = sum; - } - } - - - // Reads metadata and Rice-coded numbers from the input stream, storing them in result[warmup : currentBlockSize]. - // The stored numbers are guaranteed to fit in a signed int53 - see the explanation in restoreLpc(). - private void readResiduals(int warmup, long[] result) throws IOException { - // Check and handle arguments - Objects.requireNonNull(result); - if (warmup < 0 || warmup > currentBlockSize) - throw new IllegalArgumentException(); - if (result.length < currentBlockSize) - throw new IllegalArgumentException(); - - int method = in.readUint(2); - if (method >= 2) - throw new DataFormatException("Reserved residual coding method"); - assert method == 0 || method == 1; - int paramBits = method == 0 ? 4 : 5; - int escapeParam = method == 0 ? 0xF : 0x1F; - - int partitionOrder = in.readUint(4); - int numPartitions = 1 << partitionOrder; - if (currentBlockSize % numPartitions != 0) - throw new DataFormatException("Block size not divisible by number of Rice partitions"); - for (int inc = currentBlockSize >>> partitionOrder, partEnd = inc, resultIndex = warmup; - partEnd <= currentBlockSize; partEnd += inc) { - - int param = in.readUint(paramBits); - if (param == escapeParam) { - int numBits = in.readUint(5); - for (; resultIndex < partEnd; resultIndex++) - result[resultIndex] = in.readSignedInt(numBits); - } else { - in.readRiceSignedInts(param, result, resultIndex, partEnd); - resultIndex = partEnd; - } - } - } - -} diff --git a/desktop/src/io/nayuki/flac/decode/SeekableFileFlacInput.java b/desktop/src/io/nayuki/flac/decode/SeekableFileFlacInput.java deleted file mode 100644 index f446ff0f..00000000 --- a/desktop/src/io/nayuki/flac/decode/SeekableFileFlacInput.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.decode; - -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.util.Objects; - - -/** - * A FLAC input stream based on a {@link RandomAccessFile}. - */ -public final class SeekableFileFlacInput extends AbstractFlacLowLevelInput { - - /*---- Fields ----*/ - - // The underlying byte-based input stream to read from. - private RandomAccessFile raf; - - - - /*---- Constructors ----*/ - - public SeekableFileFlacInput(File file) throws IOException { - super(); - Objects.requireNonNull(file); - this.raf = new RandomAccessFile(file, "r"); - } - - - - /*---- Methods ----*/ - - public long getLength() { - try { - return raf.length(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - - public void seekTo(long pos) throws IOException { - raf.seek(pos); - positionChanged(pos); - } - - - protected int readUnderlying(byte[] buf, int off, int len) throws IOException { - return raf.read(buf, off, len); - } - - - // Closes the underlying RandomAccessFile stream (very important). - public void close() throws IOException { - if (raf != null) { - raf.close(); - raf = null; - super.close(); - } - } - -} diff --git a/desktop/src/io/nayuki/flac/encode/AdvancedFlacEncoder.java b/desktop/src/io/nayuki/flac/encode/AdvancedFlacEncoder.java deleted file mode 100644 index 17004ecd..00000000 --- a/desktop/src/io/nayuki/flac/encode/AdvancedFlacEncoder.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.encode; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import io.nayuki.flac.common.StreamInfo; - - -public final class AdvancedFlacEncoder { - - public AdvancedFlacEncoder(StreamInfo info, int[][] samples, int baseSize, int[] sizeMultiples, SubframeEncoder.SearchOptions opts, BitOutputStream out) throws IOException { - int numSamples = samples[0].length; - - // Calculate compressed sizes for many block positions and sizes - @SuppressWarnings("unchecked") - SizeEstimate[][] encoderInfo = new SizeEstimate[sizeMultiples.length][(numSamples + baseSize - 1) / baseSize]; - long startTime = System.currentTimeMillis(); - for (int i = 0; i < encoderInfo[0].length; i++) { - double progress = (double)i / encoderInfo[0].length; - double timeRemain = (System.currentTimeMillis() - startTime) / 1000.0 / progress * (1 - progress); - System.err.printf("\rprogress=%.2f%% timeRemain=%ds", progress * 100, Math.round(timeRemain)); - - int pos = i * baseSize; - for (int j = 0; j < encoderInfo.length; j++) { - int n = Math.min(sizeMultiples[j] * baseSize, numSamples - pos); - long[][] subsamples = getRange(samples, pos, n); - encoderInfo[j][i] = FrameEncoder.computeBest(pos, subsamples, info.sampleDepth, info.sampleRate, opts); - } - } - System.err.println(); - - // Initialize arrays to prepare for dynamic programming - FrameEncoder[] bestEncoders = new FrameEncoder[encoderInfo[0].length]; - long[] bestSizes = new long[bestEncoders.length]; - Arrays.fill(bestSizes, Long.MAX_VALUE); - - // Use dynamic programming to calculate optimum block size switching - for (int i = 0; i < encoderInfo.length; i++) { - for (int j = bestSizes.length - 1; j >= 0; j--) { - long size = encoderInfo[i][j].sizeEstimate; - if (j + sizeMultiples[i] < bestSizes.length) - size += bestSizes[j + sizeMultiples[i]]; - if (size < bestSizes[j]) { - bestSizes[j] = size; - bestEncoders[j] = encoderInfo[i][j].encoder; - } - } - } - - // Do the actual encoding and writing - info.minBlockSize = 0; - info.maxBlockSize = 0; - info.minFrameSize = 0; - info.maxFrameSize = 0; - List blockSizes = new ArrayList<>(); - for (int i = 0; i < bestEncoders.length; ) { - FrameEncoder enc = bestEncoders[i]; - int pos = i * baseSize; - int n = Math.min(enc.metadata.blockSize, numSamples - pos); - blockSizes.add(n); - if (info.minBlockSize == 0 || n < info.minBlockSize) - info.minBlockSize = Math.max(n, 16); - info.maxBlockSize = Math.max(n, info.maxBlockSize); - - long[][] subsamples = getRange(samples, pos, n); - long startByte = out.getByteCount(); - bestEncoders[i].encode(subsamples, out); - i += (n + baseSize - 1) / baseSize; - - long frameSize = out.getByteCount() - startByte; - if (frameSize < 0 || (int)frameSize != frameSize) - throw new AssertionError(); - if (info.minFrameSize == 0 || frameSize < info.minFrameSize) - info.minFrameSize = (int)frameSize; - if (frameSize > info.maxFrameSize) - info.maxFrameSize = (int)frameSize; - } - } - - - // Returns the subrange array[ : ][off : off + len] upcasted to long. - private static long[][] getRange(int[][] array, int off, int len) { - long[][] result = new long[array.length][len]; - for (int i = 0; i < array.length; i++) { - int[] src = array[i]; - long[] dest = result[i]; - for (int j = 0; j < len; j++) - dest[j] = src[off + j]; - } - return result; - } - -} diff --git a/desktop/src/io/nayuki/flac/encode/BitOutputStream.java b/desktop/src/io/nayuki/flac/encode/BitOutputStream.java deleted file mode 100644 index b7a2dc5b..00000000 --- a/desktop/src/io/nayuki/flac/encode/BitOutputStream.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.encode; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Objects; - - -/* - * A bit-oriented output stream, with other methods tailored for FLAC usage (such as CRC calculation). - */ -public final class BitOutputStream implements AutoCloseable { - - /*---- Fields ----*/ - - private OutputStream out; // The underlying byte-based output stream to write to. - private long bitBuffer; // Only the bottom bitBufferLen bits are valid; the top bits are garbage. - private int bitBufferLen; // Always in the range [0, 64]. - private long byteCount; // Number of bytes written since the start of stream. - - // Current state of the CRC calculations. - private int crc8; // Always a uint8 value. - private int crc16; // Always a uint16 value. - - - - /*---- Constructors ----*/ - - // Constructs a FLAC-oriented bit output stream from the given byte-based output stream. - public BitOutputStream(OutputStream out) throws IOException { - this.out = Objects.requireNonNull(out); - bitBuffer = 0; - bitBufferLen = 0; - byteCount = 0; - resetCrcs(); - } - - - - /*---- Methods ----*/ - - /*-- Bit position --*/ - - // Writes between 0 to 7 zero bits, to align the current bit position to a byte boundary. - public void alignToByte() throws IOException { - writeInt((64 - bitBufferLen) % 8, 0); - } - - - // Either returns silently or throws an exception. - private void checkByteAligned() { - if (bitBufferLen % 8 != 0) - throw new IllegalStateException("Not at a byte boundary"); - } - - - /*-- Writing bitwise integers --*/ - - // Writes the lowest n bits of the given value to this bit output stream. - // This doesn't care whether val represents a signed or unsigned integer. - public void writeInt(int n, int val) throws IOException { - if (n < 0 || n > 32) - throw new IllegalArgumentException(); - - if (bitBufferLen + n > 64) { - flush(); - assert bitBufferLen + n <= 64; - } - bitBuffer <<= n; - bitBuffer |= val & ((1L << n) - 1); - bitBufferLen += n; - assert 0 <= bitBufferLen && bitBufferLen <= 64; - } - - - // Writes out whole bytes from the bit buffer to the underlying stream. After this is done, - // only 0 to 7 bits remain in the bit buffer. Also updates the CRCs on each byte written. - public void flush() throws IOException { - while (bitBufferLen >= 8) { - bitBufferLen -= 8; - int b = (int)(bitBuffer >>> bitBufferLen) & 0xFF; - out.write(b); - byteCount++; - crc8 ^= b; - crc16 ^= b << 8; - for (int i = 0; i < 8; i++) { - crc8 <<= 1; - crc16 <<= 1; - crc8 ^= (crc8 >>> 8) * 0x107; - crc16 ^= (crc16 >>> 16) * 0x18005; - assert (crc8 >>> 8) == 0; - assert (crc16 >>> 16) == 0; - } - } - assert 0 <= bitBufferLen && bitBufferLen <= 64; - out.flush(); - } - - - /*-- CRC calculations --*/ - - // Marks the current position (which must be byte-aligned) as the start of both CRC calculations. - public void resetCrcs() throws IOException { - flush(); - crc8 = 0; - crc16 = 0; - } - - - // Returns the CRC-8 hash of all the bytes written since the last call to resetCrcs() - // (or from the beginning of stream if reset was never called). - public int getCrc8() throws IOException { - checkByteAligned(); - flush(); - if ((crc8 >>> 8) != 0) - throw new AssertionError(); - return crc8; - } - - - // Returns the CRC-16 hash of all the bytes written since the last call to resetCrcs() - // (or from the beginning of stream if reset was never called). - public int getCrc16() throws IOException { - checkByteAligned(); - flush(); - if ((crc16 >>> 16) != 0) - throw new AssertionError(); - return crc16; - } - - - /*-- Miscellaneous --*/ - - // Returns the number of bytes written since the start of the stream. - public long getByteCount() { - return byteCount + bitBufferLen / 8; - } - - - // Writes out any internally buffered bit data, closes the underlying output stream, and invalidates this - // bit output stream object for any future operation. Note that a BitOutputStream only uses memory but - // does not have native resources. It is okay to flush() the pending data and simply let a BitOutputStream - // be garbage collected without calling close(), but the parent is still responsible for calling close() - // on the underlying output stream if it uses native resources (such as FileOutputStream or SocketOutputStream). - public void close() throws IOException { - if (out != null) { - checkByteAligned(); - flush(); - out.close(); - out = null; - } - } - -} diff --git a/desktop/src/io/nayuki/flac/encode/ConstantEncoder.java b/desktop/src/io/nayuki/flac/encode/ConstantEncoder.java deleted file mode 100644 index ddaa7077..00000000 --- a/desktop/src/io/nayuki/flac/encode/ConstantEncoder.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.encode; - -import java.io.IOException; - - -/* - * Under the constant coding mode, this provides size calculations on and bitstream encoding of audio sample data. - * Note that unlike the other subframe encoders which are fully general, not all data can be encoded using constant mode. - * The encoded size depends on the shift and bit depth, but not on the data length or contents. - */ -final class ConstantEncoder extends SubframeEncoder { - - // Computes the best way to encode the given values under the constant coding mode, - // returning an exact size plus a new encoder object associated with the input arguments. - // However if the sample data is non-constant then null is returned instead, - // to indicate that the data is impossible to represent in this mode. - public static SizeEstimate computeBest(long[] samples, int shift, int depth) { - if (!isConstant(samples)) - return null; - ConstantEncoder enc = new ConstantEncoder(samples, shift, depth); - long size = 1 + 6 + 1 + shift + depth; - return new SizeEstimate(size, enc); - } - - - // Constructs a constant encoder for the given data, right shift, and sample depth. - public ConstantEncoder(long[] samples, int shift, int depth) { - super(shift, depth); - } - - - // Encodes the given vector of audio sample data to the given bit output stream using - // the this encoding method (and the superclass fields sampleShift and sampleDepth). - // This requires the data array to have the same values (but not necessarily - // the same object reference) as the array that was passed to the constructor. - public void encode(long[] samples, BitOutputStream out) throws IOException { - if (!isConstant(samples)) - throw new IllegalArgumentException("Data is not constant-valued"); - if ((samples[0] >> sampleShift) << sampleShift != samples[0]) - throw new IllegalArgumentException("Invalid shift value for data"); - writeTypeAndShift(0, out); - writeRawSample(samples[0] >> sampleShift, out); - } - - - // Returns true iff the set of unique values in the array has size exactly 1. Pure function. - private static boolean isConstant(long[] data) { - if (data.length == 0) - return false; - long val = data[0]; - for (long x : data) { - if (x != val) - return false; - } - return true; - } - -} diff --git a/desktop/src/io/nayuki/flac/encode/FastDotProduct.java b/desktop/src/io/nayuki/flac/encode/FastDotProduct.java deleted file mode 100644 index aaa43054..00000000 --- a/desktop/src/io/nayuki/flac/encode/FastDotProduct.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.encode; - -import java.util.Objects; - - -/* - * Speeds up computations of a signal vector's autocorrelation by avoiding redundant - * arithmetic operations. Acts as a helper class for LinearPredictiveEncoder. - * Objects of this class are intended to be immutable, but can't enforce it because - * they store a reference to a caller-controlled array without making a private copy. - */ -final class FastDotProduct { - - /*---- Fields ----*/ - - // Not null, and precomputed.length <= data.length. - private long[] data; - - // precomputed[i] = dotProduct(0, i, data.length - i). In other words, it is the sum - // the of products of all unordered pairs of elements whose indices differ by i. - private double[] precomputed; - - - - /*---- Constructors ----*/ - - // Constructs a fast dot product calculator over the given array, with the given maximum difference in indexes. - // This pre-calculates some dot products and caches them so that future queries can be answered faster. - // To avoid the cost of copying the entire vector, a reference to the array is saved into this object. - // The values from data array are still needed when dotProduct() is called, thus no other code is allowed to modify the values. - public FastDotProduct(long[] data, int maxDelta) { - // Check arguments - this.data = Objects.requireNonNull(data); - if (maxDelta < 0 || maxDelta >= data.length) - throw new IllegalArgumentException(); - - // Precompute some dot products - precomputed = new double[maxDelta + 1]; - for (int i = 0; i < precomputed.length; i++) { - double sum = 0; - for (int j = 0; i + j < data.length; j++) - sum += (double)data[j] * data[i + j]; - precomputed[i] = sum; - } - } - - - - /*---- Methods ----*/ - - // Returns the dot product of data[off0 : off0 + len] with data[off1 : off1 + len], - // i.e. data[off0]*data[off1] + data[off0+1]*data[off1+1] + ... + data[off0+len-1]*data[off1+len-1], - // with potential rounding error. Note that all the endpoints must lie within the bounds - // of the data array. Also, this method requires abs(off0 - off1) <= maxDelta. - public double dotProduct(int off0, int off1, int len) { - if (off0 > off1) // Symmetric case - return dotProduct(off1, off0, len); - - // Check arguments - if (off0 < 0 || off1 < 0 || len < 0 || data.length - len < off1) - throw new IndexOutOfBoundsException(); - assert off0 <= off1; - int delta = off1 - off0; - if (delta > precomputed.length) - throw new IllegalArgumentException(); - - // Add up a small number of products to remove from the precomputed sum - double removal = 0; - for (int i = 0; i < off0; i++) - removal += (double)data[i] * data[i + delta]; - for (int i = off1 + len; i < data.length; i++) - removal += (double)data[i] * data[i - delta]; - return precomputed[delta] - removal; - } - -} diff --git a/desktop/src/io/nayuki/flac/encode/FixedPredictionEncoder.java b/desktop/src/io/nayuki/flac/encode/FixedPredictionEncoder.java deleted file mode 100644 index 498ad39a..00000000 --- a/desktop/src/io/nayuki/flac/encode/FixedPredictionEncoder.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.encode; - -import java.io.IOException; -import java.util.Objects; - - -/* - * Under the fixed prediction coding mode of some order, this provides size calculations on and bitstream encoding of audio sample data. - */ -final class FixedPredictionEncoder extends SubframeEncoder { - - // Computes the best way to encode the given values under the fixed prediction coding mode of the given order, - // returning a size plus a new encoder object associated with the input arguments. The maxRiceOrder argument - // is used by the Rice encoder to estimate the size of coding the residual signal. - public static SizeEstimate computeBest(long[] samples, int shift, int depth, int order, int maxRiceOrder) { - FixedPredictionEncoder enc = new FixedPredictionEncoder(samples, shift, depth, order); - samples = LinearPredictiveEncoder.shiftRight(samples, shift); - LinearPredictiveEncoder.applyLpc(samples, COEFFICIENTS[order], 0); - long temp = RiceEncoder.computeBestSizeAndOrder(samples, order, maxRiceOrder); - enc.riceOrder = (int)(temp & 0xF); - long size = 1 + 6 + 1 + shift + order * depth + (temp >>> 4); - return new SizeEstimate(size, enc); - } - - - - private final int order; - public int riceOrder; - - - public FixedPredictionEncoder(long[] samples, int shift, int depth, int order) { - super(shift, depth); - if (order < 0 || order >= COEFFICIENTS.length || samples.length < order) - throw new IllegalArgumentException(); - this.order = order; - } - - - public void encode(long[] samples, BitOutputStream out) throws IOException { - Objects.requireNonNull(samples); - Objects.requireNonNull(out); - if (samples.length < order) - throw new IllegalArgumentException(); - - writeTypeAndShift(8 + order, out); - samples = LinearPredictiveEncoder.shiftRight(samples, sampleShift); - - for (int i = 0; i < order; i++) // Warmup - writeRawSample(samples[i], out); - LinearPredictiveEncoder.applyLpc(samples, COEFFICIENTS[order], 0); - RiceEncoder.encode(samples, order, riceOrder, out); - } - - - // The linear predictive coding (LPC) coefficients for fixed prediction of orders 0 to 4 (inclusive). - private static final int[][] COEFFICIENTS = { - {}, - {1}, - {2, -1}, - {3, -3, 1}, - {4, -6, 4, -1}, - }; - -} diff --git a/desktop/src/io/nayuki/flac/encode/FlacEncoder.java b/desktop/src/io/nayuki/flac/encode/FlacEncoder.java deleted file mode 100644 index d9e9c66d..00000000 --- a/desktop/src/io/nayuki/flac/encode/FlacEncoder.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.encode; - -import java.io.IOException; -import io.nayuki.flac.common.StreamInfo; - - -public final class FlacEncoder { - - public FlacEncoder(StreamInfo info, int[][] samples, int blockSize, SubframeEncoder.SearchOptions opt, BitOutputStream out) throws IOException { - info.minBlockSize = blockSize; - info.maxBlockSize = blockSize; - info.minFrameSize = 0; - info.maxFrameSize = 0; - - for (int i = 0, pos = 0; pos < samples[0].length; i++) { - System.err.printf("frame=%d position=%d %.2f%%%n", i, pos, 100.0 * pos / samples[0].length); - int n = Math.min(samples[0].length - pos, blockSize); - long[][] subsamples = getRange(samples, pos, n); - FrameEncoder enc = FrameEncoder.computeBest(pos, subsamples, info.sampleDepth, info.sampleRate, opt).encoder; - long startByte = out.getByteCount(); - enc.encode(subsamples, out); - long frameSize = out.getByteCount() - startByte; - if (frameSize < 0 || (int)frameSize != frameSize) - throw new AssertionError(); - if (info.minFrameSize == 0 || frameSize < info.minFrameSize) - info.minFrameSize = (int)frameSize; - if (frameSize > info.maxFrameSize) - info.maxFrameSize = (int)frameSize; - pos += n; - } - } - - - // Returns the subrange array[ : ][off : off + len] upcasted to long. - private static long[][] getRange(int[][] array, int off, int len) { - long[][] result = new long[array.length][len]; - for (int i = 0; i < array.length; i++) { - int[] src = array[i]; - long[] dest = result[i]; - for (int j = 0; j < len; j++) - dest[j] = src[off + j]; - } - return result; - } - -} diff --git a/desktop/src/io/nayuki/flac/encode/FrameEncoder.java b/desktop/src/io/nayuki/flac/encode/FrameEncoder.java deleted file mode 100644 index 6d1cf186..00000000 --- a/desktop/src/io/nayuki/flac/encode/FrameEncoder.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.encode; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.Objects; -import io.nayuki.flac.common.FrameInfo; - - -/* - * Calculates/estimates the encoded size of a frame of audio sample data - * (including the frame header), and also performs the encoding to an output stream. - */ -final class FrameEncoder { - - /*---- Static functions ----*/ - - public static SizeEstimate computeBest(int sampleOffset, long[][] samples, int sampleDepth, int sampleRate, SubframeEncoder.SearchOptions opt) { - FrameEncoder enc = new FrameEncoder(sampleOffset, samples, sampleDepth, sampleRate); - int numChannels = samples.length; - @SuppressWarnings("unchecked") - SizeEstimate[] encoderInfo = new SizeEstimate[numChannels]; - if (numChannels != 2) { - enc.metadata.channelAssignment = numChannels - 1; - for (int i = 0; i < encoderInfo.length; i++) - encoderInfo[i] = SubframeEncoder.computeBest(samples[i], sampleDepth, opt); - } else { // Explore the 4 stereo encoding modes - long[] left = samples[0]; - long[] right = samples[1]; - long[] mid = new long[samples[0].length]; - long[] side = new long[mid.length]; - for (int i = 0; i < mid.length; i++) { - mid[i] = (left[i] + right[i]) >> 1; - side[i] = left[i] - right[i]; - } - SizeEstimate leftInfo = SubframeEncoder.computeBest(left , sampleDepth, opt); - SizeEstimate rightInfo = SubframeEncoder.computeBest(right, sampleDepth, opt); - SizeEstimate midInfo = SubframeEncoder.computeBest(mid , sampleDepth, opt); - SizeEstimate sideInfo = SubframeEncoder.computeBest(side , sampleDepth + 1, opt); - long mode1Size = leftInfo.sizeEstimate + rightInfo.sizeEstimate; - long mode8Size = leftInfo.sizeEstimate + sideInfo.sizeEstimate; - long mode9Size = rightInfo.sizeEstimate + sideInfo.sizeEstimate; - long mode10Size = midInfo.sizeEstimate + sideInfo.sizeEstimate; - long minimum = Math.min(Math.min(mode1Size, mode8Size), Math.min(mode9Size, mode10Size)); - if (mode1Size == minimum) { - enc.metadata.channelAssignment = 1; - encoderInfo[0] = leftInfo; - encoderInfo[1] = rightInfo; - } else if (mode8Size == minimum) { - enc.metadata.channelAssignment = 8; - encoderInfo[0] = leftInfo; - encoderInfo[1] = sideInfo; - } else if (mode9Size == minimum) { - enc.metadata.channelAssignment = 9; - encoderInfo[0] = sideInfo; - encoderInfo[1] = rightInfo; - } else if (mode10Size == minimum) { - enc.metadata.channelAssignment = 10; - encoderInfo[0] = midInfo; - encoderInfo[1] = sideInfo; - } else - throw new AssertionError(); - } - - // Add up subframe sizes - long size = 0; - enc.subEncoders = new SubframeEncoder[encoderInfo.length]; - for (int i = 0; i < enc.subEncoders.length; i++) { - size += encoderInfo[i].sizeEstimate; - enc.subEncoders[i] = encoderInfo[i].encoder; - } - - // Count length of header (always in whole bytes) - try { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - try (BitOutputStream bitout = new BitOutputStream(bout)) { - enc.metadata.writeHeader(bitout); - } - bout.close(); - size += bout.toByteArray().length * 8; - } catch (IOException e) { - throw new AssertionError(e); - } - - // Count padding and footer - size = (size + 7) / 8; // Round up to nearest byte - size += 2; // CRC-16 - return new SizeEstimate<>(size, enc); - } - - - - /*---- Fields ----*/ - - public FrameInfo metadata; - private SubframeEncoder[] subEncoders; - - - - /*---- Constructors ----*/ - - public FrameEncoder(int sampleOffset, long[][] samples, int sampleDepth, int sampleRate) { - metadata = new FrameInfo(); - metadata.sampleOffset = sampleOffset; - metadata.sampleDepth = sampleDepth; - metadata.sampleRate = sampleRate; - metadata.blockSize = samples[0].length; - metadata.channelAssignment = samples.length - 1; - } - - - - /*---- Public methods ----*/ - - public void encode(long[][] samples, BitOutputStream out) throws IOException { - // Check arguments - Objects.requireNonNull(samples); - Objects.requireNonNull(out); - if (samples[0].length != metadata.blockSize) - throw new IllegalArgumentException(); - - metadata.writeHeader(out); - - int chanAsgn = metadata.channelAssignment; - if (0 <= chanAsgn && chanAsgn <= 7) { - for (int i = 0; i < samples.length; i++) - subEncoders[i].encode(samples[i], out); - } else if (8 <= chanAsgn || chanAsgn <= 10) { - long[] left = samples[0]; - long[] right = samples[1]; - long[] mid = new long[metadata.blockSize]; - long[] side = new long[metadata.blockSize]; - for (int i = 0; i < metadata.blockSize; i++) { - mid[i] = (left[i] + right[i]) >> 1; - side[i] = left[i] - right[i]; - } - if (chanAsgn == 8) { - subEncoders[0].encode(left, out); - subEncoders[1].encode(side, out); - } else if (chanAsgn == 9) { - subEncoders[0].encode(side, out); - subEncoders[1].encode(right, out); - } else if (chanAsgn == 10) { - subEncoders[0].encode(mid, out); - subEncoders[1].encode(side, out); - } else - throw new AssertionError(); - } else - throw new AssertionError(); - out.alignToByte(); - out.writeInt(16, out.getCrc16()); - } - -} diff --git a/desktop/src/io/nayuki/flac/encode/LinearPredictiveEncoder.java b/desktop/src/io/nayuki/flac/encode/LinearPredictiveEncoder.java deleted file mode 100644 index 9ac11303..00000000 --- a/desktop/src/io/nayuki/flac/encode/LinearPredictiveEncoder.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.encode; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Objects; - - -/* - * Under the linear predictive coding (LPC) mode of some order, this provides size estimates on and bitstream encoding of audio sample data. - */ -final class LinearPredictiveEncoder extends SubframeEncoder { - - // Computes a good way to encode the given values under the linear predictive coding (LPC) mode of the given order, - // returning a size plus a new encoder object associated with the input arguments. This process of minimizing the size - // has an enormous search space, and it is impossible to guarantee the absolute optimal solution. The maxRiceOrder argument - // is used by the Rice encoder to estimate the size of coding the residual signal. The roundVars argument controls - // how many different coefficients are tested rounding both up and down, resulting in exponential time behavior. - public static SizeEstimate computeBest(long[] samples, int shift, int depth, int order, int roundVars, FastDotProduct fdp, int maxRiceOrder) { - // Check arguments - if (order < 1 || order > 32) - throw new IllegalArgumentException(); - if (roundVars < 0 || roundVars > order || roundVars > 30) - throw new IllegalArgumentException(); - - LinearPredictiveEncoder enc = new LinearPredictiveEncoder(samples, shift, depth, order, fdp); - samples = shiftRight(samples, shift); - - final double[] residues; - Integer[] indices = null; - int scaler = 1 << enc.coefShift; - if (roundVars > 0) { - residues = new double[order]; - indices = new Integer[order]; - for (int i = 0; i < order; i++) { - residues[i] = Math.abs(Math.round(enc.realCoefs[i] * scaler) - enc.realCoefs[i] * scaler); - indices[i] = i; - } - Arrays.sort(indices, new Comparator() { - public int compare(Integer x, Integer y) { - return Double.compare(residues[y], residues[x]); - } - }); - } else - residues = null; - - long bestSize = Long.MAX_VALUE; - int[] bestCoefs = enc.coefficients.clone(); - for (int i = 0; i < (1 << roundVars); i++) { - for (int j = 0; j < roundVars; j++) { - int k = indices[j]; - double coef = enc.realCoefs[k]; - int val; - if (((i >>> j) & 1) == 0) - val = (int)Math.floor(coef * scaler); - else - val = (int)Math.ceil(coef * scaler); - enc.coefficients[order - 1 - k] = Math.max(Math.min(val, (1 << (enc.coefDepth - 1)) - 1), -(1 << (enc.coefDepth - 1))); - } - - long[] newData = roundVars > 0 ? samples.clone() : samples; - applyLpc(newData, enc.coefficients, enc.coefShift); - long temp = RiceEncoder.computeBestSizeAndOrder(newData, order, maxRiceOrder); - long size = 1 + 6 + 1 + shift + order * depth + (temp >>> 4); - if (size < bestSize) { - bestSize = size; - bestCoefs = enc.coefficients.clone(); - enc.riceOrder = (int)(temp & 0xF); - } - } - enc.coefficients = bestCoefs; - return new SizeEstimate(bestSize, enc); - } - - - - private final int order; - private final double[] realCoefs; - private int[] coefficients; - private final int coefDepth; - private final int coefShift; - public int riceOrder; - - - public LinearPredictiveEncoder(long[] samples, int shift, int depth, int order, FastDotProduct fdp) { - super(shift, depth); - int numSamples = samples.length; - if (order < 1 || order > 32 || numSamples < order) - throw new IllegalArgumentException(); - this.order = order; - - // Set up matrix to solve linear least squares problem - double[][] matrix = new double[order][order + 1]; - for (int r = 0; r < matrix.length; r++) { - for (int c = 0; c < matrix[r].length; c++) { - double val; - if (c >= r) - val = fdp.dotProduct(r, c, samples.length - order); - else - val = matrix[c][r]; - matrix[r][c] = val; - } - } - - // Solve matrix, then examine range of coefficients - realCoefs = solveMatrix(matrix); - double maxCoef = 0; - for (double x : realCoefs) - maxCoef = Math.max(Math.abs(x), maxCoef); - int wholeBits = maxCoef >= 1 ? (int)(Math.log(maxCoef) / Math.log(2)) + 1 : 0; - - // Quantize and store the coefficients - coefficients = new int[order]; - coefDepth = 15; // The maximum possible - coefShift = coefDepth - 1 - wholeBits; - for (int i = 0; i < realCoefs.length; i++) { - double coef = realCoefs[realCoefs.length - 1 - i]; - int val = (int)Math.round(coef * (1 << coefShift)); - coefficients[i] = Math.max(Math.min(val, (1 << (coefDepth - 1)) - 1), -(1 << (coefDepth - 1))); - } - } - - - // Solves an n * (n+1) augmented matrix (which modifies its values as a side effect), - // returning a new solution vector of length n. - private static double[] solveMatrix(double[][] mat) { - // Gauss-Jordan elimination algorithm - int rows = mat.length; - int cols = mat[0].length; - if (rows + 1 != cols) - throw new IllegalArgumentException(); - - // Forward elimination - int numPivots = 0; - for (int j = 0; j < rows && numPivots < rows; j++) { - int pivotRow = rows; - double pivotMag = 0; - for (int i = numPivots; i < rows; i++) { - if (Math.abs(mat[i][j]) > pivotMag) { - pivotMag = Math.abs(mat[i][j]); - pivotRow = i; - } - } - if (pivotRow == rows) - continue; - - double[] temp = mat[numPivots]; - mat[numPivots] = mat[pivotRow]; - mat[pivotRow] = temp; - pivotRow = numPivots; - numPivots++; - - double factor = mat[pivotRow][j]; - for (int k = 0; k < cols; k++) - mat[pivotRow][k] /= factor; - mat[pivotRow][j] = 1; - - for (int i = pivotRow + 1; i < rows; i++) { - factor = mat[i][j]; - for (int k = 0; k < cols; k++) - mat[i][k] -= mat[pivotRow][k] * factor; - mat[i][j] = 0; - } - } - - // Back substitution - double[] result = new double[rows]; - for (int i = numPivots - 1; i >= 0; i--) { - int pivotCol = 0; - while (pivotCol < cols && mat[i][pivotCol] == 0) - pivotCol++; - if (pivotCol == cols) - continue; - result[pivotCol] = mat[i][cols - 1]; - - for (int j = i - 1; j >= 0; j--) { - double factor = mat[j][pivotCol]; - for (int k = 0; k < cols; k++) - mat[j][k] -= mat[i][k] * factor; - mat[j][pivotCol] = 0; - } - } - return result; - } - - - public void encode(long[] samples, BitOutputStream out) throws IOException { - Objects.requireNonNull(samples); - Objects.requireNonNull(out); - if (samples.length < order) - throw new IllegalArgumentException(); - - writeTypeAndShift(32 + order - 1, out); - samples = shiftRight(samples, sampleShift); - - for (int i = 0; i < order; i++) // Warmup - writeRawSample(samples[i], out); - out.writeInt(4, coefDepth - 1); - out.writeInt(5, coefShift); - for (int x : coefficients) - out.writeInt(coefDepth, x); - applyLpc(samples, coefficients, coefShift); - RiceEncoder.encode(samples, order, riceOrder, out); - } - - - - /*---- Static helper functions ----*/ - - // Applies linear prediction to data[coefs.length : data.length] so that newdata[i] = - // data[i] - ((data[i-1]*coefs[0] + data[i-2]*coefs[1] + ... + data[i-coefs.length]*coefs[coefs.length]) >> shift). - // By FLAC parameters, each data[i] must fit in a signed 33-bit integer, each coef must fit in signed int15, and coefs.length <= 32. - // When these preconditions are met, they guarantee the lack of arithmetic overflow in the computation and results, - // and each value written back to the data array fits in a signed int53. - static void applyLpc(long[] data, int[] coefs, int shift) { - // Check arguments and arrays strictly - Objects.requireNonNull(data); - Objects.requireNonNull(coefs); - if (coefs.length > 32 || shift < 0 || shift > 63) - throw new IllegalArgumentException(); - for (long x : data) { - x >>= 32; - if (x != 0 && x != -1) // Check if it fits in signed int33 - throw new IllegalArgumentException(); - } - for (int x : coefs) { - x >>= 14; - if (x != 0 && x != -1) // Check if it fits in signed int15 - throw new IllegalArgumentException(); - } - - // Perform the LPC convolution/FIR - for (int i = data.length - 1; i >= coefs.length; i--) { - long sum = 0; - for (int j = 0; j < coefs.length; j++) - sum += data[i - 1 - j] * coefs[j]; - long val = data[i] - (sum >> shift); - if ((val >> 52) != 0 && (val >> 52) != -1) // Check if it fits in signed int53 - throw new AssertionError(); - data[i] = val; - } - } - - - // Returns a new array where each result[i] = data[i] >> shift. - static long[] shiftRight(long[] data, int shift) { - Objects.requireNonNull(data); - if (shift < 0 || shift > 63) - throw new IllegalArgumentException(); - long[] result = new long[data.length]; - for (int i = 0; i < data.length; i++) - result[i] = data[i] >> shift; - return result; - } - -} diff --git a/desktop/src/io/nayuki/flac/encode/RandomAccessFileOutputStream.java b/desktop/src/io/nayuki/flac/encode/RandomAccessFileOutputStream.java deleted file mode 100644 index ac54c64a..00000000 --- a/desktop/src/io/nayuki/flac/encode/RandomAccessFileOutputStream.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.encode; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.RandomAccessFile; -import java.util.Objects; - - -/* - * An adapter from RandomAccessFile to OutputStream. These objects have no buffer, so seek() - * and write() can be safely interleaved. Also, objects of this class have no direct - * native resources - so it is safe to discard a RandomAccessFileOutputStream object without - * closing it, as long as other code will close() the underlying RandomAccessFile object. - */ -public final class RandomAccessFileOutputStream extends OutputStream { - - /*---- Fields ----*/ - - private RandomAccessFile out; - - - - /*---- Constructors ----*/ - - public RandomAccessFileOutputStream(RandomAccessFile raf) { - this.out = Objects.requireNonNull(raf); - } - - - - /*---- Methods ----*/ - - public long getPosition() throws IOException { - return out.getFilePointer(); - } - - - public void seek(long pos) throws IOException { - out.seek(pos); - } - - - public void write(int b) throws IOException { - out.write(b); - } - - - public void write(byte[] b, int off, int len) throws IOException { - out.write(b, off, len); - } - - - public void close() throws IOException { - if (out != null) { - out.close(); - out = null; - } - } - -} diff --git a/desktop/src/io/nayuki/flac/encode/RiceEncoder.java b/desktop/src/io/nayuki/flac/encode/RiceEncoder.java deleted file mode 100644 index be6a291e..00000000 --- a/desktop/src/io/nayuki/flac/encode/RiceEncoder.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.encode; - -import java.io.IOException; -import java.util.Objects; - - -/* - * Calculates/estimates the encoded size of a vector of residuals, and also performs the encoding to an output stream. - */ -final class RiceEncoder { - - /*---- Functions for size calculation ---*/ - - // Calculates the best number of bits and partition order needed to encode the values data[warmup : data.length]. - // Each value in that subrange of data must fit in a signed 53-bit integer. The result is packed in the form - // ((bestSize << 4) | bestOrder), where bestSize is an unsigned integer and bestOrder is a uint4. - // Note that the partition orders searched, and hence the resulting bestOrder, are in the range [0, maxPartOrder]. - public static long computeBestSizeAndOrder(long[] data, int warmup, int maxPartOrder) { - // Check arguments strictly - Objects.requireNonNull(data); - if (warmup < 0 || warmup > data.length) - throw new IllegalArgumentException(); - if (maxPartOrder < 0 || maxPartOrder > 15) - throw new IllegalArgumentException(); - for (long x : data) { - x >>= 52; - if (x != 0 && x != -1) // Check that it fits in a signed int53 - throw new IllegalArgumentException(); - } - - long bestSize = Integer.MAX_VALUE; - int bestOrder = -1; - - int[] escapeBits = null; - int[] bitsAtParam = null; - for (int order = maxPartOrder; order >= 0; order--) { - int partSize = data.length >>> order; - if ((partSize << order) != data.length || partSize < warmup) - continue; - int numPartitions = 1 << order; - - if (escapeBits == null) { // And bitsAtParam == null - escapeBits = new int[numPartitions]; - bitsAtParam = new int[numPartitions * 16]; - for (int i = warmup; i < data.length; i++) { - int j = i / partSize; - long val = data[i]; - escapeBits[j] = Math.max(65 - Long.numberOfLeadingZeros(val ^ (val >> 63)), escapeBits[j]); - val = (val >= 0) ? (val << 1) : (((-val) << 1) - 1); - for (int param = 0; param < 15; param++, val >>>= 1) - bitsAtParam[param + j * 16] += val + 1 + param; - } - } else { // Both arrays are non-null - // Logically halve the size of both arrays (but without reallocating to the true new size) - for (int i = 0; i < numPartitions; i++) { - int j = i << 1; - escapeBits[i] = Math.max(escapeBits[j], escapeBits[j + 1]); - for (int param = 0; param < 15; param++) - bitsAtParam[param + i * 16] = bitsAtParam[param + j * 16] + bitsAtParam[param + (j + 1) * 16]; - } - } - - long size = 4 + (4 << order); - for (int i = 0; i < numPartitions; i++) { - int min = Integer.MAX_VALUE; - if (escapeBits[i] <= 31) - min = 5 + escapeBits[i] * (partSize - (i == 0 ? warmup : 0)); - for (int param = 0; param < 15; param++) - min = Math.min(bitsAtParam[param + i * 16], min); - size += min; - } - if (size < bestSize) { - bestSize = size; - bestOrder = order; - } - } - - if (bestSize == Integer.MAX_VALUE || (bestOrder >>> 4) != 0) - throw new AssertionError(); - return bestSize << 4 | bestOrder; - } - - - // Calculates the number of bits needed to encode the sequence of values - // data[start : end] with an optimally chosen Rice parameter. - private static long computeBestSizeAndParam(long[] data, int start, int end) { - assert data != null && 0 <= start && start <= end && end <= data.length; - - // Use escape code - int bestParam; - long bestSize; - { - long accumulator = 0; - for (int i = start; i < end; i++) { - long val = data[i]; - accumulator |= val ^ (val >> 63); - } - int numBits = 65 - Long.numberOfLeadingZeros(accumulator); - assert 1 <= numBits && numBits <= 65; - if (numBits <= 31) { - bestSize = 4 + 5 + (end - start) * numBits; - bestParam = 16 + numBits; - if ((bestParam >>> 6) != 0) - throw new AssertionError(); - } else { - bestSize = Long.MAX_VALUE; - bestParam = 0; - } - } - - // Use Rice coding - for (int param = 0; param <= 14; param++) { - long size = 4; - for (int i = start; i < end; i++) { - long val = data[i]; - if (val >= 0) - val <<= 1; - else - val = ((-val) << 1) - 1; - size += (val >>> param) + 1 + param; - } - if (size < bestSize) { - bestSize = size; - bestParam = param; - } - } - return bestSize << 6 | bestParam; - } - - - - /*---- Functions for encoding data ---*/ - - // Encodes the sequence of values data[warmup : data.length] with an appropriately chosen order and Rice parameters. - // Each value in data must fit in a signed 53-bit integer. - public static void encode(long[] data, int warmup, int order, BitOutputStream out) throws IOException { - // Check arguments strictly - Objects.requireNonNull(data); - Objects.requireNonNull(out); - if (warmup < 0 || warmup > data.length) - throw new IllegalArgumentException(); - if (order < 0 || order > 15) - throw new IllegalArgumentException(); - for (long x : data) { - x >>= 52; - if (x != 0 && x != -1) // Check that it fits in a signed int53 - throw new IllegalArgumentException(); - } - - out.writeInt(2, 0); - out.writeInt(4, order); - int numPartitions = 1 << order; - int start = warmup; - int end = data.length >>> order; - for (int i = 0; i < numPartitions; i++) { - int param = (int)computeBestSizeAndParam(data, start, end) & 0x3F; - encode(data, start, end, param, out); - start = end; - end += data.length >>> order; - } - } - - - // Encodes the sequence of values data[start : end] with the given Rice parameter. - private static void encode(long[] data, int start, int end, int param, BitOutputStream out) throws IOException { - assert 0 <= param && param <= 31 && data != null && out != null; - assert 0 <= start && start <= end && end <= data.length; - - if (param < 15) { - out.writeInt(4, param); - for (int j = start; j < end; j++) - writeRiceSignedInt(data[j], param, out); - } else { - out.writeInt(4, 15); - int numBits = param - 16; - out.writeInt(5, numBits); - for (int j = start; j < end; j++) - out.writeInt(numBits, (int)data[j]); - } - } - - - private static void writeRiceSignedInt(long val, int param, BitOutputStream out) throws IOException { - assert 0 <= param && param <= 31 && out != null; - assert (val >> 52) == 0 || (val >> 52) == -1; // Fits in a signed int53 - - long unsigned = val >= 0 ? val << 1 : ((-val) << 1) - 1; - int unary = (int)(unsigned >>> param); - for (int i = 0; i < unary; i++) - out.writeInt(1, 0); - out.writeInt(1, 1); - out.writeInt(param, (int)unsigned); - } - -} diff --git a/desktop/src/io/nayuki/flac/encode/SizeEstimate.java b/desktop/src/io/nayuki/flac/encode/SizeEstimate.java deleted file mode 100644 index 80258d24..00000000 --- a/desktop/src/io/nayuki/flac/encode/SizeEstimate.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.encode; - -import java.util.Objects; - - -/* - * Pairs an integer with an arbitrary object. Immutable structure. - */ -final class SizeEstimate { - - /*---- Fields ----*/ - - public final long sizeEstimate; // Non-negative - public final E encoder; // Not null - - - - /*---- Constructors ----*/ - - public SizeEstimate(long size, E enc) { - if (size < 0) - throw new IllegalArgumentException(); - sizeEstimate = size; - encoder = Objects.requireNonNull(enc); - } - - - - /*---- Methods ----*/ - - // Returns this object if the size is less than or equal to the other object, otherwise returns other. - public SizeEstimate minimum(SizeEstimate other) { - Objects.requireNonNull(other); - if (sizeEstimate <= other.sizeEstimate) - return this; - else - return other; - } - -} diff --git a/desktop/src/io/nayuki/flac/encode/SubframeEncoder.java b/desktop/src/io/nayuki/flac/encode/SubframeEncoder.java deleted file mode 100644 index 09ae8f06..00000000 --- a/desktop/src/io/nayuki/flac/encode/SubframeEncoder.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.encode; - -import java.io.IOException; -import java.util.Objects; - - -/* - * Calculates/estimates the encoded size of a subframe of audio sample data, and also performs the encoding to an output stream. - */ -public abstract class SubframeEncoder { - - /*---- Static functions ----*/ - - // Computes/estimates the best way to encode the given vector of audio sample data at the given sample depth under - // the given search criteria, returning a size estimate plus a new encoder object associated with that size. - public static SizeEstimate computeBest(long[] samples, int sampleDepth, SearchOptions opt) { - // Check arguments - Objects.requireNonNull(samples); - if (sampleDepth < 1 || sampleDepth > 33) - throw new IllegalArgumentException(); - Objects.requireNonNull(opt); - for (long x : samples) { - x >>= sampleDepth - 1; - if (x != 0 && x != -1) // Check that the input actually fits the indicated sample depth - throw new IllegalArgumentException(); - } - - // Encode with constant if possible - SizeEstimate result = ConstantEncoder.computeBest(samples, 0, sampleDepth); - if (result != null) - return result; - - // Detect number of trailing zero bits - int shift = computeWastedBits(samples); - - // Start with verbatim as fallback - result = VerbatimEncoder.computeBest(samples, shift, sampleDepth); - - // Try fixed prediction encoding - for (int order = opt.minFixedOrder; 0 <= order && order <= opt.maxFixedOrder; order++) { - SizeEstimate temp = FixedPredictionEncoder.computeBest( - samples, shift, sampleDepth, order, opt.maxRiceOrder); - result = result.minimum(temp); - } - - // Try linear predictive coding - FastDotProduct fdp = new FastDotProduct(samples, Math.max(opt.maxLpcOrder, 0)); - for (int order = opt.minLpcOrder; 0 <= order && order <= opt.maxLpcOrder; order++) { - SizeEstimate temp = LinearPredictiveEncoder.computeBest( - samples, shift, sampleDepth, order, Math.min(opt.lpcRoundVariables, order), fdp, opt.maxRiceOrder); - result = result.minimum(temp); - } - - // Return the encoder found with the lowest bit length - return result; - } - - - // Looks at each value in the array and computes the minimum number of trailing binary zeros - // among all the elements. For example, computedwastedBits({0b10, 0b10010, 0b1100}) = 1. - // If there are no elements or every value is zero (the former actually implies the latter), then - // the return value is 0. This is because every zero value has an infinite number of trailing zeros. - private static int computeWastedBits(long[] data) { - Objects.requireNonNull(data); - long accumulator = 0; - for (long x : data) - accumulator |= x; - if (accumulator == 0) - return 0; - else { - int result = Long.numberOfTrailingZeros(accumulator); - assert 0 <= result && result <= 63; - return result; - } - } - - - - /*---- Instance members ----*/ - - protected final int sampleShift; // Number of bits to shift each sample right by. In the range [0, sampleDepth]. - protected final int sampleDepth; // Stipulate that each audio sample fits in a signed integer of this width. In the range [1, 33]. - - - // Constructs a subframe encoder on some data array with the given right shift (wasted bits) and sample depth. - // Note that every element of the array must fit in a signed depth-bit integer and have at least 'shift' trailing binary zeros. - // After the encoder object is created and when encode() is called, it must receive the same array length and values (but the object reference can be different). - // Subframe encoders should not retain a reference to the sample data array because the higher-level encoder may request and - // keep many size estimates coupled with encoder objects, but only utilize a small number of encoder objects in the end. - protected SubframeEncoder(int shift, int depth) { - if (depth < 1 || depth > 33 || shift < 0 || shift > depth) - throw new IllegalArgumentException(); - sampleShift = shift; - sampleDepth = depth; - } - - - // Encodes the given vector of audio sample data to the given bit output stream - // using the current encoding method (dictated by subclasses and field values). - // This requires the data array to have the same values (but not necessarily be the same object reference) - // as the array that was passed to the constructor when this encoder object was created. - public abstract void encode(long[] samples, BitOutputStream out) throws IOException; - - - // Writes the subframe header to the given output stream, based on the given - // type code (uint6) and this object's sampleShift field (a.k.a. wasted bits per sample). - protected final void writeTypeAndShift(int type, BitOutputStream out) throws IOException { - // Check arguments - if ((type >>> 6) != 0) - throw new IllegalArgumentException(); - Objects.requireNonNull(out); - - // Write some fields - out.writeInt(1, 0); - out.writeInt(6, type); - - // Write shift value in quasi-unary - if (sampleShift == 0) - out.writeInt(1, 0); - else { - out.writeInt(1, 1); - for (int i = 0; i < sampleShift - 1; i++) - out.writeInt(1, 0); - out.writeInt(1, 1); - } - } - - - // Writes the given value to the output stream as a signed (sampleDepth-sampleShift) bit integer. - // Note that the value to being written is equal to the raw sample value shifted right by sampleShift. - protected final void writeRawSample(long val, BitOutputStream out) throws IOException { - int width = sampleDepth - sampleShift; - if (width < 1 || width > 33) - throw new IllegalStateException(); - long temp = val >> (width - 1); - if (temp != 0 && temp != -1) - throw new IllegalArgumentException(); - if (width <= 32) - out.writeInt(width, (int)val); - else { // width == 33 - out.writeInt(1, (int)(val >>> 32)); - out.writeInt(32, (int)val); - } - } - - - - /*---- Helper structure ----*/ - - // Represents options for how to search the encoding parameters for a subframe. It is used directly by - // SubframeEncoder.computeBest() and indirectly by its sub-calls. Objects of this class are immutable. - public static final class SearchOptions { - - /*-- Fields --*/ - - // The range of orders to test for fixed prediction mode, possibly none. - // The values satisfy (minFixedOrder = maxFixedOrder = -1) || (0 <= minFixedOrder <= maxFixedOrder <= 4). - public final int minFixedOrder; - public final int maxFixedOrder; - - // The range of orders to test for linear predictive coding (LPC) mode, possibly none. - // The values satisfy (minLpcOrder = maxLpcOrder = -1) || (1 <= minLpcOrder <= maxLpcOrder <= 32). - // Note that the FLAC subset format requires maxLpcOrder <= 12 when sampleRate <= 48000. - public final int minLpcOrder; - public final int maxLpcOrder; - - // How many LPC coefficient variables to try rounding both up and down. - // In the range [0, 30]. Note that each increase by one will double the search time! - public final int lpcRoundVariables; - - // The maximum partition order used in Rice coding. The minimum is not configurable and always 0. - // In the range [0, 15]. Note that the FLAC subset format requires maxRiceOrder <= 8. - public final int maxRiceOrder; - - - /*-- Constructors --*/ - - // Constructs a search options object based on the given values, - // throwing an IllegalArgumentException if and only if they are nonsensical. - public SearchOptions(int minFixedOrder, int maxFixedOrder, int minLpcOrder, int maxLpcOrder, int lpcRoundVars, int maxRiceOrder) { - // Check argument ranges - if ((minFixedOrder != -1 || maxFixedOrder != -1) && - !(0 <= minFixedOrder && minFixedOrder <= maxFixedOrder && maxFixedOrder <= 4)) - throw new IllegalArgumentException(); - if ((minLpcOrder != -1 || maxLpcOrder != -1) && - !(1 <= minLpcOrder && minLpcOrder <= maxLpcOrder && maxLpcOrder <= 32)) - throw new IllegalArgumentException(); - if (lpcRoundVars < 0 || lpcRoundVars > 30) - throw new IllegalArgumentException(); - if (maxRiceOrder < 0 || maxRiceOrder > 15) - throw new IllegalArgumentException(); - - // Copy arguments to fields - this.minFixedOrder = minFixedOrder; - this.maxFixedOrder = maxFixedOrder; - this.minLpcOrder = minLpcOrder; - this.maxLpcOrder = maxLpcOrder; - this.lpcRoundVariables = lpcRoundVars; - this.maxRiceOrder = maxRiceOrder; - } - - - /*-- Constants for recommended defaults --*/ - - // Note that these constants are for convenience only, and offer little promises in terms of API stability. - // For example, there is no expectation that the set of search option names as a whole, - // or the values of each search option will remain the same from version to version. - // Even if a search option retains the same value across code versions, the underlying encoder implementation - // can change in such a way that the encoded output is not bit-identical or size-identical across versions. - // Therefore, treat these search options as suggestions that strongly influence the encoded FLAC output, - // but *not* as firm guarantees that the same audio data with the same options will forever produce the same result. - - // These search ranges conform to the FLAC subset format. - public static final SearchOptions SUBSET_ONLY_FIXED = new SearchOptions(0, 4, -1, -1, 0, 8); - public static final SearchOptions SUBSET_MEDIUM = new SearchOptions(0, 1, 2, 8, 0, 5); - public static final SearchOptions SUBSET_BEST = new SearchOptions(0, 1, 2, 12, 0, 8); - public static final SearchOptions SUBSET_INSANE = new SearchOptions(0, 4, 1, 12, 4, 8); - - // These cannot guarantee that an encoded file conforms to the FLAC subset (i.e. they are lax). - public static final SearchOptions LAX_MEDIUM = new SearchOptions(0, 1, 2, 22, 0, 15); - public static final SearchOptions LAX_BEST = new SearchOptions(0, 1, 2, 32, 0, 15); - public static final SearchOptions LAX_INSANE = new SearchOptions(0, 1, 2, 32, 4, 15); - - } - -} diff --git a/desktop/src/io/nayuki/flac/encode/VerbatimEncoder.java b/desktop/src/io/nayuki/flac/encode/VerbatimEncoder.java deleted file mode 100644 index 0257743d..00000000 --- a/desktop/src/io/nayuki/flac/encode/VerbatimEncoder.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * FLAC library (Java) - * - * Copyright (c) Project Nayuki - * https://www.nayuki.io/page/flac-library-java - * - * 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 3 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 program (see COPYING.txt and COPYING.LESSER.txt). - * If not, see . - */ - -package io.nayuki.flac.encode; - -import java.io.IOException; - - -/* - * Under the verbatim coding mode, this provides size calculations on and bitstream encoding of audio sample data. - * Note that the size depends on the data length, shift, and bit depth, but not on the data contents. - */ -final class VerbatimEncoder extends SubframeEncoder { - - // Computes the best way to encode the given values under the verbatim coding mode, - // returning an exact size plus a new encoder object associated with the input arguments. - public static SizeEstimate computeBest(long[] samples, int shift, int depth) { - VerbatimEncoder enc = new VerbatimEncoder(samples, shift, depth); - long size = 1 + 6 + 1 + shift + samples.length * depth; - return new SizeEstimate(size, enc); - } - - - // Constructs a constant encoder for the given data, right shift, and sample depth. - public VerbatimEncoder(long[] samples, int shift, int depth) { - super(shift, depth); - } - - - // Encodes the given vector of audio sample data to the given bit output stream using - // the this encoding method (and the superclass fields sampleShift and sampleDepth). - // This requires the data array to have the same values (but not necessarily - // the same object reference) as the array that was passed to the constructor. - public void encode(long[] samples, BitOutputStream out) throws IOException { - writeTypeAndShift(1, out); - for (long val : samples) - writeRawSample(val >> sampleShift, out); - } - -} From 8f835748601b88117cdbbab494bc439b4b013d63 Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:02:11 +0200 Subject: [PATCH 15/17] Delete core directory --- core/assets/badlogic.jpg | Bin 68465 -> 0 bytes core/assets/shaders/BoneTexture.vs | 16 - core/assets/warsmash.ini | 20 - core/assets/warsmash131notworking.ini | 42 - core/assets/warsmashPRSCMOD.ini | 26 - core/assets/warsmashRF.ini | 41 - core/assets/warsmashTTOR.ini | 22 - core/assets/warsmashUF.ini | 22 - core/assets/warsmash_131.ini | 26 - core/assets/warsmash_myHD.ini | 12 - core/build.gradle | 11 - .../com/etheller/warsmash/CodeCounter.java | 35 - .../etheller/warsmash/MathSpeedBenchmark.java | 61 - .../etheller/warsmash/SingleModelScreen.java | 5 - .../etheller/warsmash/WarsmashGdxGame.java | 535 --- .../warsmash/WarsmashGdxMapScreen.java | 517 --- .../warsmash/WarsmashGdxMenuScreen.java | 882 ----- .../warsmash/WarsmashGdxMultiScreenGame.java | 23 - .../warsmash/WarsmashPreviewApplication.java | 177 - .../etheller/warsmash/WarsmashTestGame.java | 113 - .../etheller/warsmash/WarsmashTestGame2.java | 138 - .../etheller/warsmash/WarsmashTestGame3.java | 145 - .../warsmash/WarsmashTestGameAttributes.java | 163 - .../warsmash/WarsmashTestGameAttributes2.java | 213 -- .../WarsmashTestGameTextureBuffer.java | 244 -- .../WarsmashTestGameTextureBuffer2.java | 203 - .../warsmash/WarsmashTestMyTextureGame.java | 47 - .../warsmash/common/FetchDataTypeName.java | 13 - .../warsmash/common/LoadGenericCallback.java | 7 - .../warsmash/datasources/CascDataSource.java | 225 -- .../datasources/CascDataSourceDescriptor.java | 96 - .../datasources/CompoundDataSource.java | 153 - .../CompoundDataSourceDescriptor.java | 27 - .../warsmash/datasources/DataSource.java | 49 - .../datasources/DataSourceDescriptor.java | 9 - .../datasources/FolderDataSource.java | 87 - .../FolderDataSourceDescriptor.java | 57 - .../warsmash/datasources/MpqDataSource.java | 166 - .../datasources/MpqDataSourceDescriptor.java | 78 - .../datasources/SubdirDataSource.java | 55 - .../networking/ClientToServerListener.java | 26 - .../networking/ClientToServerProtocol.java | 13 - .../warsmash/networking/GameTurnManager.java | 41 - .../warsmash/networking/MultiplayerHack.java | 6 - .../networking/ServerToClientListener.java | 24 - .../networking/ServerToClientProtocol.java | 14 - .../warsmash/networking/WarsmashClient.java | 238 -- .../networking/WarsmashClientParser.java | 112 - .../WarsmashClientSendingOrderListener.java | 46 - .../networking/WarsmashClientWriter.java | 105 - .../warsmash/networking/WarsmashServer.java | 199 - .../networking/WarsmashServerParser.java | 107 - .../networking/WarsmashServerWriter.java | 145 - .../networking/udp/OrderedUdpClient.java | 31 - .../udp/OrderedUdpClientListener.java | 5 - .../udp/OrderedUdpCommuncation.java | 107 - .../networking/udp/OrderedUdpServer.java | 81 - .../udp/OrderedUdpServerListener.java | 7 - .../warsmash/networking/udp/UdpClient.java | 93 - .../networking/udp/UdpClientListener.java | 7 - .../warsmash/networking/udp/UdpServer.java | 108 - .../networking/udp/UdpServerListener.java | 8 - .../fdf/DataSourceFDFParserBuilder.java | 48 - .../fdf/DynamicFontGeneratorHolder.java | 44 - .../warsmash/parsers/fdf/GameSkin.java | 22 - .../etheller/warsmash/parsers/fdf/GameUI.java | 1096 ------ .../etheller/warsmash/parsers/fdf/Main.java | 55 - .../warsmash/parsers/fdf/ModelExport.java | 38 - .../fdf/frames/AbstractRenderableFrame.java | 397 -- .../parsers/fdf/frames/AbstractUIFrame.java | 90 - .../parsers/fdf/frames/AnchorPoint.java | 36 - .../parsers/fdf/frames/BackdropFrame.java | 197 - .../parsers/fdf/frames/ControlFrame.java | 35 - .../parsers/fdf/frames/EditBoxFrame.java | 179 - .../fdf/frames/FilterModeTextureFrame.java | 33 - .../fdf/frames/FramePointAssignment.java | 10 - .../parsers/fdf/frames/GlueButtonFrame.java | 166 - .../fdf/frames/GlueTextButtonFrame.java | 77 - .../parsers/fdf/frames/ListBoxFrame.java | 202 - .../warsmash/parsers/fdf/frames/SetPoint.java | 58 - .../parsers/fdf/frames/SimpleButtonFrame.java | 217 -- .../parsers/fdf/frames/SimpleFrame.java | 9 - .../fdf/frames/SimpleStatusBarFrame.java | 50 - .../parsers/fdf/frames/SingleStringFrame.java | 106 - .../fdf/frames/SmartBackdropFrame.java | 77 - .../parsers/fdf/frames/SpriteFrame.java | 138 - .../parsers/fdf/frames/StringFrame.java | 496 --- .../parsers/fdf/frames/TextButtonFrame.java | 18 - .../parsers/fdf/frames/TextureFrame.java | 97 - .../warsmash/parsers/fdf/frames/UIFrame.java | 55 - .../etheller/warsmash/parsers/jass/Jass2.java | 3245 ---------------- .../warsmash/parsers/jass/JassTest.java | 64 - .../warsmash/parsers/jass/Tmpgen.java | 22 - .../warsmash/parsers/jass/Tmpgen2.java | 29 - .../scope/CommonTriggerExecutionScope.java | 412 -- .../parsers/jass/triggers/BoolExprAnd.java | 21 - .../jass/triggers/BoolExprCondition.java | 27 - .../parsers/jass/triggers/BoolExprFilter.java | 27 - .../parsers/jass/triggers/BoolExprNot.java | 19 - .../parsers/jass/triggers/BoolExprOr.java | 21 - .../parsers/jass/triggers/TriggerAction.java | 28 - .../jass/triggers/TriggerCondition.java | 28 - .../warsmash/parsers/terrain/Corner.java | 27 - .../warsmash/parsers/terrain/Terrain.java | 13 - .../warsmash/parsers/terrain/TilePathing.java | 15 - .../warsmash/parsers/w3x/War3Map.java | 147 - .../warsmash/parsers/w3x/doo/Doodad.java | 157 - .../warsmash/parsers/w3x/doo/RandomItem.java | 23 - .../parsers/w3x/doo/RandomItemSet.java | 34 - .../parsers/w3x/doo/TerrainDoodad.java | 54 - .../warsmash/parsers/w3x/doo/War3MapDoo.java | 108 - .../w3x/objectdata/MakeMeTFTBeROC.java | 98 - .../objectdata/Warcraft3MapObjectData.java | 184 - .../parsers/w3x/unitsdoo/DroppedItem.java | 26 - .../parsers/w3x/unitsdoo/DroppedItemSet.java | 38 - .../parsers/w3x/unitsdoo/InventoryItem.java | 26 - .../parsers/w3x/unitsdoo/ModifiedAbility.java | 26 - .../parsers/w3x/unitsdoo/RandomUnit.java | 23 - .../warsmash/parsers/w3x/unitsdoo/Unit.java | 428 --- .../parsers/w3x/unitsdoo/War3MapUnitsDoo.java | 76 - .../warsmash/parsers/w3x/w3e/Corner.java | 149 - .../warsmash/parsers/w3x/w3e/War3MapW3e.java | 148 - .../warsmash/parsers/w3x/w3i/Force.java | 29 - .../warsmash/parsers/w3x/w3i/Player.java | 93 - .../warsmash/parsers/w3x/w3i/RandomItem.java | 39 - .../parsers/w3x/w3i/RandomItemSet.java | 39 - .../parsers/w3x/w3i/RandomItemTable.java | 69 - .../warsmash/parsers/w3x/w3i/RandomUnit.java | 31 - .../parsers/w3x/w3i/RandomUnitTable.java | 48 - .../w3x/w3i/TechAvailabilityChange.java | 24 - .../w3x/w3i/UpgradeAvailabilityChange.java | 30 - .../warsmash/parsers/w3x/w3i/War3MapW3i.java | 456 --- .../warsmash/parsers/w3x/wpm/War3MapWpm.java | 54 - .../etheller/warsmash/units/DataTable.java | 326 -- .../com/etheller/warsmash/units/Element.java | 217 -- .../etheller/warsmash/units/GameObject.java | 101 - .../warsmash/units/HashedGameObject.java | 278 -- .../com/etheller/warsmash/units/LMUnit.java | 12 - .../etheller/warsmash/units/ObjectData.java | 13 - .../warsmash/units/StandardObjectData.java | 645 ---- .../etheller/warsmash/units/StringKey.java | 54 - .../warsmash/units/custom/Change.java | 105 - .../warsmash/units/custom/ChangeMap.java | 55 - .../units/custom/ObjectDataChangeEntry.java | 47 - .../warsmash/units/custom/ObjectMap.java | 89 - .../etheller/warsmash/units/custom/WTS.java | 12 - .../warsmash/units/custom/WTSFile.java | 94 - .../units/custom/War3ObjectDataChangeset.java | 802 ---- .../units/manager/MutableObjectData.java | 958 ----- .../MutableObjectDataChangeListener.java | 23 - .../MutableObjectDataChangeNotifier.java | 72 - .../warsmash/util/DataSourceFileHandle.java | 41 - .../etheller/warsmash/util/Descriptor.java | 6 - .../warsmash/util/FastNumberFormat.java | 24 - .../warsmash/util/FixedIntersector.java | 82 - .../etheller/warsmash/util/ImageUtils.java | 255 -- .../com/etheller/warsmash/util/IniFile.java | 84 - .../etheller/warsmash/util/Interpolator.java | 72 - .../etheller/warsmash/util/MappedData.java | 97 - .../etheller/warsmash/util/MappedDataRow.java | 7 - .../com/etheller/warsmash/util/MdlUtils.java | 198 - .../etheller/warsmash/util/ParseUtils.java | 189 - .../com/etheller/warsmash/util/Quadtree.java | 253 -- .../warsmash/util/QuadtreeIntersector.java | 13 - .../etheller/warsmash/util/RawcodeUtils.java | 62 - .../warsmash/util/RenderMathUtils.java | 699 ---- .../com/etheller/warsmash/util/SlkFile.java | 73 - .../etheller/warsmash/util/StringBundle.java | 19 - .../warsmash/util/SubscriberSetNotifier.java | 23 - core/src/com/etheller/warsmash/util/Test.java | 206 - .../com/etheller/warsmash/util/Vector4.java | 573 --- .../com/etheller/warsmash/util/War3ID.java | 83 - .../warsmash/util/WarsmashConstants.java | 39 - .../warsmash/util/WorldEditStrings.java | 81 - .../warsmash/viewer5/AudioBufferSource.java | 23 - .../warsmash/viewer5/AudioContext.java | 92 - .../warsmash/viewer5/AudioDestination.java | 5 - .../warsmash/viewer5/AudioPanner.java | 39 - .../warsmash/viewer5/BatchedInstance.java | 16 - .../com/etheller/warsmash/viewer5/Bounds.java | 41 - .../com/etheller/warsmash/viewer5/Camera.java | 346 -- .../warsmash/viewer5/CanvasProvider.java | 7 - .../warsmash/viewer5/EmittedObject.java | 15 - .../viewer5/EmittedObjectUpdater.java | 43 - .../etheller/warsmash/viewer5/Emitter.java | 82 - .../warsmash/viewer5/GdxTextureResource.java | 63 - .../warsmash/viewer5/GenericNode.java | 33 - .../warsmash/viewer5/GenericResource.java | 35 - .../com/etheller/warsmash/viewer5/Grid.java | 120 - .../etheller/warsmash/viewer5/GridCell.java | 44 - .../warsmash/viewer5/HandlerResource.java | 14 - .../com/etheller/warsmash/viewer5/Model.java | 37 - .../warsmash/viewer5/ModelInstance.java | 229 -- .../warsmash/viewer5/ModelViewer.java | 380 -- .../com/etheller/warsmash/viewer5/Node.java | 328 -- .../etheller/warsmash/viewer5/PathSolver.java | 31 - .../viewer5/RawOpenGLTextureResource.java | 157 - .../warsmash/viewer5/RenderBatch.java | 40 - .../etheller/warsmash/viewer5/Resource.java | 46 - .../warsmash/viewer5/ResourceLoader.java | 4 - .../com/etheller/warsmash/viewer5/Scene.java | 328 -- .../warsmash/viewer5/SceneLightInstance.java | 5 - .../warsmash/viewer5/SceneLightManager.java | 9 - .../etheller/warsmash/viewer5/Shaders.java | 119 - .../warsmash/viewer5/SimpleScene.java | 81 - .../warsmash/viewer5/SkeletalNode.java | 254 -- .../etheller/warsmash/viewer5/SolvedPath.java | 26 - .../etheller/warsmash/viewer5/Texture.java | 30 - .../warsmash/viewer5/TextureMapper.java | 23 - .../warsmash/viewer5/UpdatableObject.java | 5 - .../viewer5/ViewerTextureRenderable.java | 29 - .../etheller/warsmash/viewer5/WorldScene.java | 101 - .../viewer5/deprecated/ShaderProgram.java | 15 - .../deprecated/ShaderUnitDeprecated.java | 31 - .../viewer5/gl/ANGLEInstancedArrays.java | 13 - .../warsmash/viewer5/gl/AudioExtension.java | 13 - .../warsmash/viewer5/gl/ClientBuffer.java | 55 - .../warsmash/viewer5/gl/DataTexture.java | 70 - .../viewer5/gl/DynamicShadowExtension.java | 7 - .../warsmash/viewer5/gl/Extensions.java | 14 - .../etheller/warsmash/viewer5/gl/WebGL.java | 168 - .../viewer5/gl/WireframeExtension.java | 5 - .../handlers/AbstractMdxModelViewer.java | 21 - .../viewer5/handlers/EmitterObject.java | 7 - .../viewer5/handlers/ModelHandler.java | 5 - .../handlers/ModelInstanceDescriptor.java | 8 - .../viewer5/handlers/ResourceHandler.java | 16 - .../ResourceHandlerConstructionParams.java | 42 - .../viewer5/handlers/blp/BlpGdxTexture.java | 39 - .../viewer5/handlers/blp/BlpHandler.java | 28 - .../viewer5/handlers/blp/BlpTexture.java | 38 - .../viewer5/handlers/blp/DdsHandler.java | 28 - .../viewer5/handlers/blp/DdsTexture.java | 38 - .../viewer5/handlers/mdx/AnimatedObject.java | 152 - .../viewer5/handlers/mdx/Attachment.java | 40 - .../handlers/mdx/AttachmentInstance.java | 58 - .../warsmash/viewer5/handlers/mdx/Batch.java | 21 - .../viewer5/handlers/mdx/BatchGroup.java | 159 - .../warsmash/viewer5/handlers/mdx/Bone.java | 40 - .../warsmash/viewer5/handlers/mdx/Camera.java | 41 - .../viewer5/handlers/mdx/CollisionShape.java | 132 - .../viewer5/handlers/mdx/EmitterGroup.java | 73 - .../handlers/mdx/EventObjectEmitter.java | 42 - .../mdx/EventObjectEmitterObject.java | 369 -- .../viewer5/handlers/mdx/EventObjectSnd.java | 60 - .../handlers/mdx/EventObjectSndEmitter.java | 14 - .../handlers/mdx/EventObjectSplEmitter.java | 12 - .../handlers/mdx/EventObjectSplUbr.java | 63 - .../viewer5/handlers/mdx/EventObjectSpn.java | 51 - .../handlers/mdx/EventObjectSpnEmitter.java | 14 - .../handlers/mdx/EventObjectUbrEmitter.java | 12 - .../viewer5/handlers/mdx/FilterMode.java | 47 - .../viewer5/handlers/mdx/GenericGroup.java | 17 - .../viewer5/handlers/mdx/GenericIndexed.java | 5 - .../viewer5/handlers/mdx/GenericObject.java | 171 - .../handlers/mdx/GeometryEmitterFuncs.java | 468 --- .../warsmash/viewer5/handlers/mdx/Geoset.java | 166 - .../viewer5/handlers/mdx/GeosetAnimation.java | 41 - .../warsmash/viewer5/handlers/mdx/Helper.java | 13 - .../warsmash/viewer5/handlers/mdx/Layer.java | 157 - .../warsmash/viewer5/handlers/mdx/Light.java | 82 - .../viewer5/handlers/mdx/LightInstance.java | 111 - .../viewer5/handlers/mdx/Material.java | 16 - .../handlers/mdx/MdxComplexInstance.java | 939 ----- .../viewer5/handlers/mdx/MdxEmitter.java | 28 - .../viewer5/handlers/mdx/MdxHandler.java | 76 - .../viewer5/handlers/mdx/MdxModel.java | 378 -- .../viewer5/handlers/mdx/MdxNode.java | 22 - .../handlers/mdx/MdxNodeDescriptor.java | 13 - .../viewer5/handlers/mdx/MdxRenderBatch.java | 135 - .../viewer5/handlers/mdx/MdxShaders.java | 492 --- .../handlers/mdx/MdxSimpleInstance.java | 58 - .../viewer5/handlers/mdx/MdxViewer.java | 35 - .../viewer5/handlers/mdx/Particle.java | 103 - .../viewer5/handlers/mdx/Particle2.java | 109 - .../viewer5/handlers/mdx/ParticleEmitter.java | 34 - .../handlers/mdx/ParticleEmitter2.java | 57 - .../handlers/mdx/ParticleEmitter2Object.java | 154 - .../handlers/mdx/ParticleEmitterObject.java | 83 - .../viewer5/handlers/mdx/QuaternionSd.java | 32 - .../viewer5/handlers/mdx/ReplaceableIds.java | 41 - .../warsmash/viewer5/handlers/mdx/Ribbon.java | 90 - .../viewer5/handlers/mdx/RibbonEmitter.java | 73 - .../handlers/mdx/RibbonEmitterObject.java | 77 - .../viewer5/handlers/mdx/ScalarSd.java | 46 - .../warsmash/viewer5/handlers/mdx/Sd.java | 149 - .../handlers/mdx/SdArrayDescriptor.java | 24 - .../viewer5/handlers/mdx/SdSequence.java | 224 -- .../viewer5/handlers/mdx/Sequence.java | 87 - .../handlers/mdx/SequenceLoopMode.java | 9 - .../viewer5/handlers/mdx/SetupGeosets.java | 208 -- .../viewer5/handlers/mdx/SetupGroups.java | 123 - .../handlers/mdx/SetupSimpleGroups.java | 62 - .../handlers/mdx/TextureAnimation.java | 44 - .../viewer5/handlers/mdx/UInt32Sd.java | 50 - .../viewer5/handlers/mdx/VectorSd.java | 32 - .../viewer5/handlers/tga/ImageUtils.java | 179 - .../viewer5/handlers/tga/TgaFile.java | 232 -- .../viewer5/handlers/tga/TgaHandler.java | 28 - .../viewer5/handlers/tga/TgaTexture.java | 36 - .../viewer5/handlers/w3x/AnimationTokens.java | 73 - .../handlers/w3x/DynamicShadowManager.java | 139 - .../viewer5/handlers/w3x/IndexedSequence.java | 13 - .../w3x/SecondaryTagSequenceComparator.java | 41 - .../viewer5/handlers/w3x/SequenceUtils.java | 301 -- .../viewer5/handlers/w3x/SplatModel.java | 543 --- .../handlers/w3x/StandSequenceComparator.java | 11 - .../viewer5/handlers/w3x/TerrainDoodad.java | 38 - .../viewer5/handlers/w3x/TextTag.java | 45 - .../viewer5/handlers/w3x/UnitSound.java | 148 - .../viewer5/handlers/w3x/UnitSoundset.java | 23 - .../viewer5/handlers/w3x/Variations.java | 159 - .../viewer5/handlers/w3x/W3xSceneLight.java | 9 - .../handlers/w3x/W3xSceneLightManager.java | 13 - .../w3x/W3xScenePortraitLightManager.java | 106 - .../w3x/W3xSceneWorldLightManager.java | 112 - .../viewer5/handlers/w3x/W3xShaders.java | 99 - .../w3x/W3xShadersWebGLDeprecated.java | 230 -- .../viewer5/handlers/w3x/War3MapViewer.java | 2249 ----------- .../handlers/w3x/camera/CameraManager.java | 62 - .../w3x/camera/CameraPanControls.java | 10 - .../handlers/w3x/camera/CameraPreset.java | 85 - .../handlers/w3x/camera/CameraRates.java | 20 - .../w3x/camera/GameCameraManager.java | 179 - .../w3x/camera/PortraitCameraManager.java | 52 - .../w3x/environment/BuildingShadow.java | 7 - .../handlers/w3x/environment/CliffMesh.java | 103 - .../w3x/environment/GroundTexture.java | 58 - .../handlers/w3x/environment/IVec3.java | 38 - .../handlers/w3x/environment/PathingGrid.java | 462 --- .../w3x/environment/RenderCorner.java | 16 - .../handlers/w3x/environment/Shapes.java | 32 - .../handlers/w3x/environment/Terrain.java | 1567 -------- .../w3x/environment/TerrainShaders.java | 388 -- .../handlers/w3x/environment/WaveBuilder.java | 152 - .../rendersim/OrientationInterpolation.java | 61 - .../w3x/rendersim/RenderAttackInstant.java | 40 - .../w3x/rendersim/RenderAttackProjectile.java | 139 - .../w3x/rendersim/RenderDestructable.java | 190 - .../handlers/w3x/rendersim/RenderDoodad.java | 98 - .../handlers/w3x/rendersim/RenderEffect.java | 7 - .../handlers/w3x/rendersim/RenderItem.java | 205 - .../handlers/w3x/rendersim/RenderUnit.java | 566 --- .../w3x/rendersim/RenderUnitTypeData.java | 57 - .../handlers/w3x/rendersim/RenderWidget.java | 219 -- .../w3x/rendersim/ability/AbilityDataUI.java | 357 -- .../w3x/rendersim/ability/AbilityUI.java | 85 - .../w3x/rendersim/ability/IconUI.java | 52 - .../w3x/rendersim/ability/ItemUI.java | 32 - .../w3x/rendersim/ability/UnitIconUI.java | 24 - .../commandbuttons/AbilityCommandButton.java | 94 - .../commandbuttons/BasicCommandButton.java | 95 - .../commandbuttons/CommandButton.java | 38 - .../commandbuttons/CommandButtonListener.java | 40 - .../CommandCardPopulatingAbilityVisitor.java | 405 -- .../w3x/simulation/CDestructable.java | 114 - .../w3x/simulation/CDestructableType.java | 57 - .../w3x/simulation/CGameplayConstants.java | 495 --- .../handlers/w3x/simulation/CItem.java | 113 - .../handlers/w3x/simulation/CItemType.java | 156 - .../w3x/simulation/CPlayerStateListener.java | 53 - .../handlers/w3x/simulation/CSimulation.java | 526 --- .../w3x/simulation/CSimulationMapData.java | 10 - .../handlers/w3x/simulation/CUnit.java | 1747 --------- .../simulation/CUnitAnimationListener.java | 21 - .../w3x/simulation/CUnitClassification.java | 67 - .../w3x/simulation/CUnitEnumFunction.java | 11 - .../w3x/simulation/CUnitStateListener.java | 71 - .../handlers/w3x/simulation/CUnitType.java | 368 -- .../w3x/simulation/CUnitTypeRequirement.java | 21 - .../handlers/w3x/simulation/CWidget.java | 77 - .../w3x/simulation/CWidgetFilterFunction.java | 19 - .../w3x/simulation/CWorldCollision.java | 240 -- .../w3x/simulation/HandleIdAllocator.java | 14 - .../simulation/StringsToExternalizeLater.java | 6 - .../abilities/AbstractCAbility.java | 54 - .../w3x/simulation/abilities/CAbility.java | 34 - .../simulation/abilities/CAbilityAttack.java | 186 - .../simulation/abilities/CAbilityGeneric.java | 93 - .../simulation/abilities/CAbilityMove.java | 137 - .../abilities/CAbilityToggleableView.java | 5 - .../simulation/abilities/CAbilityView.java | 28 - .../simulation/abilities/CAbilityVisitor.java | 60 - .../build/AbstractCAbilityBuild.java | 131 - .../build/CAbilityBuildInProgress.java | 100 - .../abilities/build/CAbilityHumanBuild.java | 68 - .../abilities/build/CAbilityHumanRepair.java | 135 - .../abilities/build/CAbilityNagaBuild.java | 60 - .../abilities/build/CAbilityNeutralBuild.java | 60 - .../build/CAbilityNightElfBuild.java | 77 - .../abilities/build/CAbilityOrcBuild.java | 77 - .../abilities/build/CAbilityUndeadBuild.java | 77 - .../abilities/combat/CAbilityColdArrows.java | 136 - .../combat/CAbilityInvulnerable.java | 77 - .../generic/AbstractGenericNoIconAbility.java | 34 - ...bstractGenericSingleIconActiveAbility.java | 103 - ...GenericSingleIconNoSmartActiveAbility.java | 28 - .../generic/GenericNoIconAbility.java | 8 - .../GenericSingleIconActiveAbility.java | 16 - .../abilities/harvest/CAbilityHarvest.java | 236 -- .../harvest/CAbilityReturnResources.java | 92 - .../abilities/hero/CAbilityHero.java | 295 -- .../abilities/hero/CPrimaryAttribute.java | 23 - .../inventory/CAbilityInventory.java | 304 -- .../item/CAbilityItemAttackBonus.java | 84 - .../abilities/item/CAbilityItemHeal.java | 101 - .../abilities/menu/CAbilityMenu.java | 8 - .../mine/CAbilityBlightedGoldMine.java | 118 - .../abilities/mine/CAbilityGoldMine.java | 140 - .../abilities/queue/CAbilityQueue.java | 173 - .../abilities/queue/CAbilityRally.java | 111 - .../abilities/queue/CAbilityReviveHero.java | 140 - .../targeting/AbilityPointTarget.java | 34 - .../abilities/targeting/AbilityTarget.java | 9 - .../targeting/AbilityTargetItemVisitor.java | 30 - ...yTargetStillAliveAndTargetableVisitor.java | 45 - .../AbilityTargetStillAliveVisitor.java | 30 - .../targeting/AbilityTargetVisitor.java | 15 - .../targeting/AbilityTargetWidgetVisitor.java | 31 - .../abilities/test/CAbilityChannelTest.java | 91 - .../abilities/test/CAbilityCoupleInstant.java | 213 -- .../abilities/types/CAbilityType.java | 42 - .../types/CAbilityTypeLevelData.java | 17 - .../definitions/CAbilityTypeDefinition.java | 9 - .../impl/AbstractCAbilityTypeDefinition.java | 34 - .../CAbilityTypeDefinitionChannelTest.java | 33 - .../CAbilityTypeDefinitionColdArrows.java | 27 - .../CAbilityTypeDefinitionCoupleInstant.java | 48 - .../impl/CAbilityTypeDefinitionGoldMine.java | 37 - .../impl/CAbilityTypeDefinitionHarvest.java | 39 - .../CAbilityTypeDefinitionHarvestLumber.java | 38 - .../CAbilityTypeDefinitionHumanRepair.java | 37 - .../impl/CAbilityTypeDefinitionInventory.java | 42 - .../CAbilityTypeDefinitionInvulnerable.java | 30 - ...CAbilityTypeDefinitionItemAttackBonus.java | 33 - .../impl/CAbilityTypeDefinitionItemHeal.java | 34 - ...CAbilityTypeDefinitionReturnResources.java | 35 - .../types/impl/CAbilityTypeChannelTest.java | 23 - .../CAbilityTypeChannelTestLevelData.java | 20 - .../types/impl/CAbilityTypeColdArrows.java | 22 - .../impl/CAbilityTypeColdArrowsLevelData.java | 14 - .../types/impl/CAbilityTypeCoupleInstant.java | 25 - .../CAbilityTypeCoupleInstantLevelData.java | 59 - .../types/impl/CAbilityTypeGoldMine.java | 24 - .../impl/CAbilityTypeGoldMineLevelData.java | 32 - .../types/impl/CAbilityTypeHarvest.java | 24 - .../impl/CAbilityTypeHarvestLevelData.java | 45 - .../types/impl/CAbilityTypeHarvestLumber.java | 24 - .../CAbilityTypeHarvestLumberLevelData.java | 39 - .../types/impl/CAbilityTypeHumanRepair.java | 25 - .../CAbilityTypeHumanRepairLevelData.java | 38 - .../types/impl/CAbilityTypeInventory.java | 24 - .../impl/CAbilityTypeInventoryLevelData.java | 47 - .../types/impl/CAbilityTypeInvulnerable.java | 24 - .../impl/CAbilityTypeItemAttackBonus.java | 23 - .../CAbilityTypeItemAttackBonusLevelData.java | 19 - .../types/impl/CAbilityTypeItemHeal.java | 24 - .../impl/CAbilityTypeItemHealLevelData.java | 19 - .../impl/CAbilityTypeReturnResources.java | 32 - .../CAbilityTypeReturnResourcesLevelData.java | 28 - .../abilities/upgrade/CAbilityUpgrade.java | 5 - .../w3x/simulation/ai/AIDifficulty.java | 9 - .../behaviors/CAbstractRangedBehavior.java | 115 - .../w3x/simulation/behaviors/CBehavior.java | 19 - .../simulation/behaviors/CBehaviorAttack.java | 145 - .../behaviors/CBehaviorAttackListener.java | 35 - .../behaviors/CBehaviorAttackMove.java | 69 - .../simulation/behaviors/CBehaviorFollow.java | 78 - .../behaviors/CBehaviorHoldPosition.java | 42 - .../simulation/behaviors/CBehaviorMove.java | 483 --- .../simulation/behaviors/CBehaviorPatrol.java | 66 - .../simulation/behaviors/CBehaviorStop.java | 41 - .../simulation/behaviors/CRangedBehavior.java | 9 - ...yDisableWhileUnderConstructionVisitor.java | 144 - .../behaviors/build/CBehaviorHumanRepair.java | 88 - .../behaviors/build/CBehaviorOrcBuild.java | 135 - .../behaviors/build/CBehaviorUndeadBuild.java | 158 - .../behaviors/harvest/CBehaviorHarvest.java | 239 -- .../harvest/CBehaviorReturnResources.java | 235 -- .../inventory/CBehaviorDropItem.java | 71 - .../behaviors/inventory/CBehaviorGetItem.java | 70 - .../behaviors/test/CBehaviorChannelTest.java | 49 - .../test/CBehaviorCoupleInstant.java | 91 - .../w3x/simulation/combat/CAttackType.java | 46 - .../w3x/simulation/combat/CDefenseType.java | 33 - .../w3x/simulation/combat/CRegenType.java | 13 - .../w3x/simulation/combat/CTargetType.java | 139 - .../w3x/simulation/combat/CUpgradeClass.java | 13 - .../w3x/simulation/combat/CWeaponType.java | 20 - .../w3x/simulation/combat/CodeKeyType.java | 7 - .../combat/attacks/CUnitAttack.java | 271 -- .../combat/attacks/CUnitAttackInstant.java | 56 - .../combat/attacks/CUnitAttackListener.java | 9 - .../combat/attacks/CUnitAttackMissile.java | 92 - .../attacks/CUnitAttackMissileBounce.java | 135 - .../attacks/CUnitAttackMissileLine.java | 52 - .../attacks/CUnitAttackMissileSplash.java | 176 - .../combat/attacks/CUnitAttackNormal.java | 44 - .../combat/projectile/CAttackProjectile.java | 114 - .../w3x/simulation/config/CBasePlayer.java | 187 - .../w3x/simulation/config/CPlayerAPI.java | 5 - .../w3x/simulation/config/War3MapConfig.java | 153 - .../config/War3MapConfigPlayer.java | 29 - .../config/War3MapConfigStartLoc.java | 44 - .../w3x/simulation/data/CAbilityData.java | 78 - .../simulation/data/CDestructableData.java | 87 - .../w3x/simulation/data/CItemData.java | 125 - .../w3x/simulation/data/CUnitData.java | 756 ---- .../w3x/simulation/data/CUnitRace.java | 32 - .../w3x/simulation/item/CItemTypeJass.java | 15 - .../w3x/simulation/orders/COrder.java | 23 - .../orders/COrderDropItemAtPoint.java | 111 - .../w3x/simulation/orders/COrderNoTarget.java | 97 - .../simulation/orders/COrderTargetPoint.java | 110 - .../simulation/orders/COrderTargetWidget.java | 106 - .../w3x/simulation/orders/OrderIdUtils.java | 38 - .../w3x/simulation/orders/OrderIds.java | 457 --- .../pathing/CBuildingPathingType.java | 30 - .../pathing/CPathfindingProcessor.java | 486 --- .../w3x/simulation/players/CAllianceType.java | 16 - .../w3x/simulation/players/CMapControl.java | 12 - .../w3x/simulation/players/CMapFlag.java | 44 - .../w3x/simulation/players/CMapPlacement.java | 10 - .../w3x/simulation/players/CPlayer.java | 223 -- .../w3x/simulation/players/CPlayerColor.java | 25 - .../w3x/simulation/players/CPlayerEvent.java | 40 - .../simulation/players/CPlayerGameResult.java | 10 - .../w3x/simulation/players/CPlayerJass.java | 58 - .../w3x/simulation/players/CPlayerScore.java | 31 - .../w3x/simulation/players/CPlayerState.java | 42 - .../players/CPlayerUnitOrderExecutor.java | 82 - .../players/CPlayerUnitOrderListener.java | 14 - .../w3x/simulation/players/CRace.java | 32 - .../simulation/players/CRacePreference.java | 26 - .../w3x/simulation/players/CStartLocPrio.java | 9 - .../w3x/simulation/region/CRegion.java | 159 - .../region/CRegionEnumFunction.java | 11 - .../w3x/simulation/region/CRegionManager.java | 202 - .../region/CRegionTriggerEnter.java | 32 - .../region/CRegionTriggerLeave.java | 32 - .../w3x/simulation/state/CGameState.java | 9 - .../w3x/simulation/state/CUnitState.java | 10 - .../w3x/simulation/timers/CTimer.java | 89 - .../w3x/simulation/timers/CTimerJass.java | 43 - .../simulation/timers/CTimerNativeEvent.java | 24 - .../trigger/JassGameEventsWar3.java | 248 -- .../trigger/enumtypes/CAttackTypeJass.java | 9 - .../trigger/enumtypes/CBlendMode.java | 12 - .../trigger/enumtypes/CCameraField.java | 13 - .../trigger/enumtypes/CDamageType.java | 32 - .../trigger/enumtypes/CEffectType.java | 13 - .../trigger/enumtypes/CFogState.java | 22 - .../trigger/enumtypes/CGameSpeed.java | 11 - .../trigger/enumtypes/CGameType.java | 27 - .../trigger/enumtypes/CMapDensity.java | 10 - .../trigger/enumtypes/CMapDifficulty.java | 10 - .../trigger/enumtypes/CPathingTypeJass.java | 14 - .../trigger/enumtypes/CPlayerSlotState.java | 9 - .../trigger/enumtypes/CRarityControl.java | 8 - .../trigger/enumtypes/CSoundType.java | 8 - .../trigger/enumtypes/CSoundVolumeGroup.java | 14 - .../trigger/enumtypes/CTexMapFlags.java | 10 - .../trigger/enumtypes/CVersion.java | 8 - .../enumtypes/CWeaponSoundTypeJass.java | 40 - .../trigger/uidialog/JassUIDialog.java | 25 - .../trigger/uidialog/JassUIDialogButton.java | 13 - .../w3x/simulation/unit/CUnitTypeJass.java | 39 - .../util/AbilityActivationErrorHandler.java | 22 - .../util/AbilityActivationReceiver.java | 19 - .../util/AbilityTargetCheckReceiver.java | 37 - .../BooleanAbilityActivationReceiver.java | 48 - .../BooleanAbilityTargetCheckReceiver.java | 71 - .../CWidgetAbilityTargetCheckReceiver.java | 69 - .../MeleeUIAbilityActivationReceiver.java | 86 - .../util/PointAbilityTargetCheckReceiver.java | 69 - .../w3x/simulation/util/ResourceType.java | 9 - .../util/SimulationRenderController.java | 69 - .../StringMsgAbilityActivationReceiver.java | 58 - .../util/StringMsgTargetCheckReceiver.java | 101 - .../handlers/w3x/ui/CommandCardIcon.java | 240 -- .../viewer5/handlers/w3x/ui/MeleeUI.java | 3317 ----------------- .../handlers/w3x/ui/MeleeUIMinimap.java | 62 - .../handlers/w3x/ui/MenuCursorState.java | 24 - .../viewer5/handlers/w3x/ui/MenuUI.java | 1177 ------ .../handlers/w3x/ui/PlayerProfile.java | 13 - .../handlers/w3x/ui/PlayerProfileManager.java | 93 - .../viewer5/handlers/w3x/ui/QueueIcon.java | 151 - .../w3x/ui/command/ActiveCommand.java | 8 - .../w3x/ui/command/ClickableActionFrame.java | 25 - .../w3x/ui/command/ClickableFrame.java | 17 - .../command/CommandCardCommandListener.java | 7 - .../w3x/ui/command/CommandErrorListener.java | 13 - .../w3x/ui/command/FocusableFrame.java | 17 - .../w3x/ui/command/QueueIconListener.java | 5 - .../command/SettableCommandErrorListener.java | 34 - .../w3x/ui/menu/CampaignButtonUI.java | 104 - .../w3x/ui/menu/CampaignMenuData.java | 118 - .../handlers/w3x/ui/menu/CampaignMenuUI.java | 81 - .../handlers/w3x/ui/menu/CampaignMission.java | 25 - .../handlers/w3x/ui/sound/KeyedSounds.java | 29 - .../src/com/hiveworkshop/ReteraCASCUtils.java | 53 - .../blizzard/casc/ConfigurationFile.java | 118 - .../com/hiveworkshop/blizzard/casc/Key.java | 78 - .../blizzard/casc/StorageReference.java | 80 - .../blizzard/casc/info/FieldDataType.java | 25 - .../blizzard/casc/info/FieldDescriptor.java | 65 - .../hiveworkshop/blizzard/casc/info/Info.java | 149 - .../blizzard/casc/io/WarcraftIIICASC.java | 291 -- .../blizzard/casc/io/package-info.java | 6 - .../casc/nio/HashMismatchException.java | 15 - .../casc/nio/LittleHashBlockProcessor.java | 76 - .../nio/MalformedCASCStructureException.java | 15 - .../blizzard/casc/storage/BLTEContent.java | 132 - .../blizzard/casc/storage/BankStream.java | 185 - .../blizzard/casc/storage/IndexEntry.java | 60 - .../blizzard/casc/storage/IndexFile.java | 159 - .../blizzard/casc/storage/Storage.java | 334 -- .../casc/storage/StorageContainer.java | 92 - .../blizzard/casc/trash/LocalDataFiles.java | 343 -- .../blizzard/casc/trash/LocalIndexFile.java | 171 - .../casc/trash/VirtualFileSystem.java | 86 - .../blizzard/casc/vfs/FileNode.java | 24 - .../blizzard/casc/vfs/PathNode.java | 27 - .../blizzard/casc/vfs/PrefixNode.java | 26 - .../blizzard/casc/vfs/StorageReference.java | 81 - .../blizzard/casc/vfs/TVFSDecoder.java | 254 -- .../blizzard/casc/vfs/TVFSFile.java | 54 - .../blizzard/casc/vfs/VirtualFileSystem.java | 681 ---- core/src/com/hiveworkshop/json/JSONArray.java | 1458 -------- .../com/hiveworkshop/json/JSONException.java | 45 - .../src/com/hiveworkshop/json/JSONObject.java | 2551 ------------- .../com/hiveworkshop/json/JSONPointer.java | 293 -- .../json/JSONPointerException.java | 45 - .../hiveworkshop/json/JSONPropertyIgnore.java | 43 - .../hiveworkshop/json/JSONPropertyName.java | 47 - .../src/com/hiveworkshop/json/JSONString.java | 18 - .../com/hiveworkshop/json/JSONStringer.java | 79 - .../com/hiveworkshop/json/JSONTokener.java | 531 --- .../src/com/hiveworkshop/json/JSONWriter.java | 413 -- core/src/com/hiveworkshop/lang/Hex.java | 82 - .../nio/ByteBufferInputStream.java | 39 - .../rms/parsers/mdlx/AnimationMap.java | 266 -- .../rms/parsers/mdlx/InterpolationType.java | 26 - .../rms/parsers/mdlx/MdlxAnimatedObject.java | 102 - .../rms/parsers/mdlx/MdlxAttachment.java | 105 - .../rms/parsers/mdlx/MdlxBlock.java | 16 - .../rms/parsers/mdlx/MdlxBlockDescriptor.java | 44 - .../rms/parsers/mdlx/MdlxBone.java | 104 - .../rms/parsers/mdlx/MdlxCamera.java | 160 - .../rms/parsers/mdlx/MdlxChunk.java | 5 - .../rms/parsers/mdlx/MdlxCollisionShape.java | 187 - .../rms/parsers/mdlx/MdlxEventObject.java | 99 - .../rms/parsers/mdlx/MdlxExtent.java | 62 - .../rms/parsers/mdlx/MdlxFaceEffect.java | 45 - .../rms/parsers/mdlx/MdlxGenericObject.java | 278 -- .../rms/parsers/mdlx/MdlxGeoset.java | 592 --- .../rms/parsers/mdlx/MdlxGeosetAnimation.java | 136 - .../rms/parsers/mdlx/MdlxHelper.java | 28 - .../rms/parsers/mdlx/MdlxLayer.java | 369 -- .../rms/parsers/mdlx/MdlxLight.java | 222 -- .../rms/parsers/mdlx/MdlxMaterial.java | 173 - .../rms/parsers/mdlx/MdlxModel.java | 967 ----- .../rms/parsers/mdlx/MdlxParticleEmitter.java | 241 -- .../parsers/mdlx/MdlxParticleEmitter2.java | 622 ---- .../mdlx/MdlxParticleEmitterPopcorn.java | 180 - .../rms/parsers/mdlx/MdlxRibbonEmitter.java | 264 -- .../rms/parsers/mdlx/MdlxSequence.java | 121 - .../rms/parsers/mdlx/MdlxTexture.java | 120 - .../parsers/mdlx/MdlxTextureAnimation.java | 56 - .../parsers/mdlx/MdlxTimelineDescriptor.java | 18 - .../rms/parsers/mdlx/MdlxUnknownChunk.java | 31 - .../parsers/mdlx/mdl/MdlTokenInputStream.java | 208 -- .../mdlx/mdl/MdlTokenOutputStream.java | 220 -- .../rms/parsers/mdlx/mdl/MdlUtils.java | 203 - .../mdlx/timeline/MdlxFloatArrayTimeline.java | 45 - .../mdlx/timeline/MdlxFloatTimeline.java | 33 - .../parsers/mdlx/timeline/MdlxTimeline.java | 216 -- .../mdlx/timeline/MdlxUInt32Timeline.java | 34 - .../rms/parsers/mdlx/util/MdxUtils.java | 31 - .../hiveworkshop/rms/util/BinaryReader.java | 216 -- .../hiveworkshop/rms/util/BinaryWriter.java | 140 - .../com/hiveworkshop/rms/util/Descriptor.java | 6 - core/src/mpq/ArchivedFile.java | 132 - core/src/mpq/ArchivedFileExtractor.java | 66 - core/src/mpq/ArchivedFileStream.java | 131 - core/src/mpq/BlockTable.java | 78 - core/src/mpq/HashLookup.java | 35 - core/src/mpq/HashTable.java | 82 - core/src/mpq/MPQArchive.java | 291 -- core/src/mpq/MPQException.java | 29 - core/src/mpq/compression/Compression.java | 397 -- .../compression/DecompressionException.java | 25 - core/src/mpq/compression/adpcm/ADPCM.java | 118 - core/src/mpq/compression/huffman/Huffman.java | 481 --- .../mpq/compression/pkware/PKException.java | 14 - .../mpq/compression/pkware/PKExploder.java | 200 - core/src/mpq/data/ArchiveHeader.java | 98 - core/src/mpq/data/BlockTableEntry.java | 31 - core/src/mpq/data/FileHeader.java | 31 - core/src/mpq/data/HashTableEntry.java | 31 - core/src/mpq/data/Raw.java | 20 - core/src/mpq/data/RawArrays.java | 36 - core/src/mpq/data/UserDataHeader.java | 21 - core/src/mpq/util/Cryption.java | 116 - 704 files changed, 88547 deletions(-) delete mode 100644 core/assets/badlogic.jpg delete mode 100644 core/assets/shaders/BoneTexture.vs delete mode 100644 core/assets/warsmash.ini delete mode 100644 core/assets/warsmash131notworking.ini delete mode 100644 core/assets/warsmashPRSCMOD.ini delete mode 100644 core/assets/warsmashRF.ini delete mode 100644 core/assets/warsmashTTOR.ini delete mode 100644 core/assets/warsmashUF.ini delete mode 100644 core/assets/warsmash_131.ini delete mode 100644 core/assets/warsmash_myHD.ini delete mode 100644 core/build.gradle delete mode 100644 core/src/com/etheller/warsmash/CodeCounter.java delete mode 100644 core/src/com/etheller/warsmash/MathSpeedBenchmark.java delete mode 100644 core/src/com/etheller/warsmash/SingleModelScreen.java delete mode 100644 core/src/com/etheller/warsmash/WarsmashGdxGame.java delete mode 100644 core/src/com/etheller/warsmash/WarsmashGdxMapScreen.java delete mode 100644 core/src/com/etheller/warsmash/WarsmashGdxMenuScreen.java delete mode 100644 core/src/com/etheller/warsmash/WarsmashGdxMultiScreenGame.java delete mode 100644 core/src/com/etheller/warsmash/WarsmashPreviewApplication.java delete mode 100644 core/src/com/etheller/warsmash/WarsmashTestGame.java delete mode 100644 core/src/com/etheller/warsmash/WarsmashTestGame2.java delete mode 100644 core/src/com/etheller/warsmash/WarsmashTestGame3.java delete mode 100644 core/src/com/etheller/warsmash/WarsmashTestGameAttributes.java delete mode 100644 core/src/com/etheller/warsmash/WarsmashTestGameAttributes2.java delete mode 100644 core/src/com/etheller/warsmash/WarsmashTestGameTextureBuffer.java delete mode 100644 core/src/com/etheller/warsmash/WarsmashTestGameTextureBuffer2.java delete mode 100644 core/src/com/etheller/warsmash/WarsmashTestMyTextureGame.java delete mode 100644 core/src/com/etheller/warsmash/common/FetchDataTypeName.java delete mode 100644 core/src/com/etheller/warsmash/common/LoadGenericCallback.java delete mode 100644 core/src/com/etheller/warsmash/datasources/CascDataSource.java delete mode 100644 core/src/com/etheller/warsmash/datasources/CascDataSourceDescriptor.java delete mode 100644 core/src/com/etheller/warsmash/datasources/CompoundDataSource.java delete mode 100644 core/src/com/etheller/warsmash/datasources/CompoundDataSourceDescriptor.java delete mode 100644 core/src/com/etheller/warsmash/datasources/DataSource.java delete mode 100644 core/src/com/etheller/warsmash/datasources/DataSourceDescriptor.java delete mode 100644 core/src/com/etheller/warsmash/datasources/FolderDataSource.java delete mode 100644 core/src/com/etheller/warsmash/datasources/FolderDataSourceDescriptor.java delete mode 100644 core/src/com/etheller/warsmash/datasources/MpqDataSource.java delete mode 100644 core/src/com/etheller/warsmash/datasources/MpqDataSourceDescriptor.java delete mode 100644 core/src/com/etheller/warsmash/datasources/SubdirDataSource.java delete mode 100644 core/src/com/etheller/warsmash/networking/ClientToServerListener.java delete mode 100644 core/src/com/etheller/warsmash/networking/ClientToServerProtocol.java delete mode 100644 core/src/com/etheller/warsmash/networking/GameTurnManager.java delete mode 100644 core/src/com/etheller/warsmash/networking/MultiplayerHack.java delete mode 100644 core/src/com/etheller/warsmash/networking/ServerToClientListener.java delete mode 100644 core/src/com/etheller/warsmash/networking/ServerToClientProtocol.java delete mode 100644 core/src/com/etheller/warsmash/networking/WarsmashClient.java delete mode 100644 core/src/com/etheller/warsmash/networking/WarsmashClientParser.java delete mode 100644 core/src/com/etheller/warsmash/networking/WarsmashClientSendingOrderListener.java delete mode 100644 core/src/com/etheller/warsmash/networking/WarsmashClientWriter.java delete mode 100644 core/src/com/etheller/warsmash/networking/WarsmashServer.java delete mode 100644 core/src/com/etheller/warsmash/networking/WarsmashServerParser.java delete mode 100644 core/src/com/etheller/warsmash/networking/WarsmashServerWriter.java delete mode 100644 core/src/com/etheller/warsmash/networking/udp/OrderedUdpClient.java delete mode 100644 core/src/com/etheller/warsmash/networking/udp/OrderedUdpClientListener.java delete mode 100644 core/src/com/etheller/warsmash/networking/udp/OrderedUdpCommuncation.java delete mode 100644 core/src/com/etheller/warsmash/networking/udp/OrderedUdpServer.java delete mode 100644 core/src/com/etheller/warsmash/networking/udp/OrderedUdpServerListener.java delete mode 100644 core/src/com/etheller/warsmash/networking/udp/UdpClient.java delete mode 100644 core/src/com/etheller/warsmash/networking/udp/UdpClientListener.java delete mode 100644 core/src/com/etheller/warsmash/networking/udp/UdpServer.java delete mode 100644 core/src/com/etheller/warsmash/networking/udp/UdpServerListener.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/DataSourceFDFParserBuilder.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/DynamicFontGeneratorHolder.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/GameSkin.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/GameUI.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/Main.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/ModelExport.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/AbstractRenderableFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/AbstractUIFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/AnchorPoint.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/BackdropFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/ControlFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/EditBoxFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/FilterModeTextureFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/FramePointAssignment.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/GlueButtonFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/GlueTextButtonFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/ListBoxFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/SetPoint.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/SimpleButtonFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/SimpleFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/SimpleStatusBarFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/SingleStringFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/SmartBackdropFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/SpriteFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/StringFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/TextButtonFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/TextureFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/fdf/frames/UIFrame.java delete mode 100644 core/src/com/etheller/warsmash/parsers/jass/Jass2.java delete mode 100644 core/src/com/etheller/warsmash/parsers/jass/JassTest.java delete mode 100644 core/src/com/etheller/warsmash/parsers/jass/Tmpgen.java delete mode 100644 core/src/com/etheller/warsmash/parsers/jass/Tmpgen2.java delete mode 100644 core/src/com/etheller/warsmash/parsers/jass/scope/CommonTriggerExecutionScope.java delete mode 100644 core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprAnd.java delete mode 100644 core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprCondition.java delete mode 100644 core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprFilter.java delete mode 100644 core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprNot.java delete mode 100644 core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprOr.java delete mode 100644 core/src/com/etheller/warsmash/parsers/jass/triggers/TriggerAction.java delete mode 100644 core/src/com/etheller/warsmash/parsers/jass/triggers/TriggerCondition.java delete mode 100644 core/src/com/etheller/warsmash/parsers/terrain/Corner.java delete mode 100644 core/src/com/etheller/warsmash/parsers/terrain/Terrain.java delete mode 100644 core/src/com/etheller/warsmash/parsers/terrain/TilePathing.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/War3Map.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/doo/Doodad.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/doo/RandomItem.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/doo/RandomItemSet.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/doo/TerrainDoodad.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/doo/War3MapDoo.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/objectdata/MakeMeTFTBeROC.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/objectdata/Warcraft3MapObjectData.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/DroppedItem.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/DroppedItemSet.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/InventoryItem.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/ModifiedAbility.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/RandomUnit.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/Unit.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/War3MapUnitsDoo.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/w3e/Corner.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/w3e/War3MapW3e.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/w3i/Force.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/w3i/Player.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomItem.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomItemSet.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomItemTable.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomUnit.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomUnitTable.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/w3i/TechAvailabilityChange.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/w3i/UpgradeAvailabilityChange.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/w3i/War3MapW3i.java delete mode 100644 core/src/com/etheller/warsmash/parsers/w3x/wpm/War3MapWpm.java delete mode 100644 core/src/com/etheller/warsmash/units/DataTable.java delete mode 100644 core/src/com/etheller/warsmash/units/Element.java delete mode 100644 core/src/com/etheller/warsmash/units/GameObject.java delete mode 100644 core/src/com/etheller/warsmash/units/HashedGameObject.java delete mode 100644 core/src/com/etheller/warsmash/units/LMUnit.java delete mode 100644 core/src/com/etheller/warsmash/units/ObjectData.java delete mode 100644 core/src/com/etheller/warsmash/units/StandardObjectData.java delete mode 100644 core/src/com/etheller/warsmash/units/StringKey.java delete mode 100644 core/src/com/etheller/warsmash/units/custom/Change.java delete mode 100644 core/src/com/etheller/warsmash/units/custom/ChangeMap.java delete mode 100644 core/src/com/etheller/warsmash/units/custom/ObjectDataChangeEntry.java delete mode 100644 core/src/com/etheller/warsmash/units/custom/ObjectMap.java delete mode 100644 core/src/com/etheller/warsmash/units/custom/WTS.java delete mode 100644 core/src/com/etheller/warsmash/units/custom/WTSFile.java delete mode 100644 core/src/com/etheller/warsmash/units/custom/War3ObjectDataChangeset.java delete mode 100644 core/src/com/etheller/warsmash/units/manager/MutableObjectData.java delete mode 100644 core/src/com/etheller/warsmash/units/manager/MutableObjectDataChangeListener.java delete mode 100644 core/src/com/etheller/warsmash/units/manager/MutableObjectDataChangeNotifier.java delete mode 100644 core/src/com/etheller/warsmash/util/DataSourceFileHandle.java delete mode 100644 core/src/com/etheller/warsmash/util/Descriptor.java delete mode 100644 core/src/com/etheller/warsmash/util/FastNumberFormat.java delete mode 100644 core/src/com/etheller/warsmash/util/FixedIntersector.java delete mode 100644 core/src/com/etheller/warsmash/util/ImageUtils.java delete mode 100644 core/src/com/etheller/warsmash/util/IniFile.java delete mode 100644 core/src/com/etheller/warsmash/util/Interpolator.java delete mode 100644 core/src/com/etheller/warsmash/util/MappedData.java delete mode 100644 core/src/com/etheller/warsmash/util/MappedDataRow.java delete mode 100644 core/src/com/etheller/warsmash/util/MdlUtils.java delete mode 100644 core/src/com/etheller/warsmash/util/ParseUtils.java delete mode 100644 core/src/com/etheller/warsmash/util/Quadtree.java delete mode 100644 core/src/com/etheller/warsmash/util/QuadtreeIntersector.java delete mode 100644 core/src/com/etheller/warsmash/util/RawcodeUtils.java delete mode 100644 core/src/com/etheller/warsmash/util/RenderMathUtils.java delete mode 100644 core/src/com/etheller/warsmash/util/SlkFile.java delete mode 100644 core/src/com/etheller/warsmash/util/StringBundle.java delete mode 100644 core/src/com/etheller/warsmash/util/SubscriberSetNotifier.java delete mode 100644 core/src/com/etheller/warsmash/util/Test.java delete mode 100644 core/src/com/etheller/warsmash/util/Vector4.java delete mode 100644 core/src/com/etheller/warsmash/util/War3ID.java delete mode 100644 core/src/com/etheller/warsmash/util/WarsmashConstants.java delete mode 100644 core/src/com/etheller/warsmash/util/WorldEditStrings.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/AudioBufferSource.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/AudioContext.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/AudioDestination.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/AudioPanner.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/BatchedInstance.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/Bounds.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/Camera.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/CanvasProvider.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/EmittedObject.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/EmittedObjectUpdater.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/Emitter.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/GdxTextureResource.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/GenericNode.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/GenericResource.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/Grid.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/GridCell.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/HandlerResource.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/Model.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/ModelInstance.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/ModelViewer.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/Node.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/PathSolver.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/RawOpenGLTextureResource.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/RenderBatch.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/Resource.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/ResourceLoader.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/Scene.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/SceneLightInstance.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/SceneLightManager.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/Shaders.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/SimpleScene.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/SkeletalNode.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/SolvedPath.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/Texture.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/TextureMapper.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/UpdatableObject.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/ViewerTextureRenderable.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/WorldScene.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/deprecated/ShaderProgram.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/deprecated/ShaderUnitDeprecated.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/gl/ANGLEInstancedArrays.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/gl/AudioExtension.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/gl/ClientBuffer.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/gl/DataTexture.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/gl/DynamicShadowExtension.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/gl/Extensions.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/gl/WebGL.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/gl/WireframeExtension.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/AbstractMdxModelViewer.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/EmitterObject.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/ModelHandler.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/ModelInstanceDescriptor.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/ResourceHandler.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/ResourceHandlerConstructionParams.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/blp/BlpGdxTexture.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/blp/BlpHandler.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/blp/BlpTexture.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/blp/DdsHandler.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/blp/DdsTexture.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/AnimatedObject.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/Attachment.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/AttachmentInstance.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/Batch.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/BatchGroup.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/Bone.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/Camera.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/CollisionShape.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/EmitterGroup.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectEmitter.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectEmitterObject.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSnd.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSndEmitter.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSplEmitter.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSplUbr.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSpn.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSpnEmitter.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectUbrEmitter.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/FilterMode.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/GenericGroup.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/GenericIndexed.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/GenericObject.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/GeometryEmitterFuncs.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/Geoset.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/GeosetAnimation.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/Helper.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/Layer.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/Light.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/LightInstance.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/Material.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxComplexInstance.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxEmitter.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxHandler.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxModel.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxNode.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxNodeDescriptor.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxRenderBatch.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxShaders.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxSimpleInstance.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxViewer.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/Particle.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/Particle2.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitter.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitter2.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitter2Object.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitterObject.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/QuaternionSd.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/ReplaceableIds.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/Ribbon.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/RibbonEmitter.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/RibbonEmitterObject.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/ScalarSd.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/Sd.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/SdArrayDescriptor.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/SdSequence.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/Sequence.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/SequenceLoopMode.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/SetupGeosets.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/SetupGroups.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/SetupSimpleGroups.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/TextureAnimation.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/UInt32Sd.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/mdx/VectorSd.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/tga/ImageUtils.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/tga/TgaFile.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/tga/TgaHandler.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/tga/TgaTexture.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/AnimationTokens.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/DynamicShadowManager.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/IndexedSequence.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/SecondaryTagSequenceComparator.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/SequenceUtils.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/SplatModel.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/StandSequenceComparator.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/TerrainDoodad.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/TextTag.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/UnitSound.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/UnitSoundset.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/Variations.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xSceneLight.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xSceneLightManager.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xScenePortraitLightManager.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xSceneWorldLightManager.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xShaders.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xShadersWebGLDeprecated.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraManager.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraPanControls.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraPreset.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraRates.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/GameCameraManager.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/PortraitCameraManager.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/BuildingShadow.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/CliffMesh.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/GroundTexture.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/IVec3.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/PathingGrid.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/RenderCorner.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/Shapes.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/Terrain.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/TerrainShaders.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/WaveBuilder.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/OrientationInterpolation.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderAttackInstant.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderAttackProjectile.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDestructable.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDoodad.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderEffect.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderItem.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnit.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnitTypeData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderWidget.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/AbilityDataUI.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/AbilityUI.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/IconUI.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/ItemUI.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/UnitIconUI.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/AbilityCommandButton.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/BasicCommandButton.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandButton.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandButtonListener.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardPopulatingAbilityVisitor.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CDestructable.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CDestructableType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CGameplayConstants.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CItem.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CItemType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CPlayerStateListener.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulation.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulationMapData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnit.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitAnimationListener.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitClassification.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitEnumFunction.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitStateListener.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitTypeRequirement.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWidget.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWidgetFilterFunction.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWorldCollision.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/HandleIdAllocator.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/StringsToExternalizeLater.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/AbstractCAbility.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbility.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityAttack.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityGeneric.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityMove.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityToggleableView.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityView.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityVisitor.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/AbstractCAbilityBuild.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityBuildInProgress.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityHumanBuild.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityHumanRepair.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityNagaBuild.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityNeutralBuild.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityNightElfBuild.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityOrcBuild.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityUndeadBuild.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/combat/CAbilityColdArrows.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/combat/CAbilityInvulnerable.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/AbstractGenericNoIconAbility.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/AbstractGenericSingleIconActiveAbility.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/AbstractGenericSingleIconNoSmartActiveAbility.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/GenericNoIconAbility.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/GenericSingleIconActiveAbility.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/harvest/CAbilityHarvest.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/harvest/CAbilityReturnResources.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/hero/CAbilityHero.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/hero/CPrimaryAttribute.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/inventory/CAbilityInventory.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/item/CAbilityItemAttackBonus.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/item/CAbilityItemHeal.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/menu/CAbilityMenu.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/mine/CAbilityBlightedGoldMine.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/mine/CAbilityGoldMine.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityQueue.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityRally.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityReviveHero.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityPointTarget.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTarget.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetItemVisitor.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetStillAliveAndTargetableVisitor.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetStillAliveVisitor.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetVisitor.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetWidgetVisitor.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/test/CAbilityChannelTest.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/test/CAbilityCoupleInstant.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/CAbilityType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/CAbilityTypeLevelData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/CAbilityTypeDefinition.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/AbstractCAbilityTypeDefinition.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionChannelTest.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionColdArrows.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionCoupleInstant.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionGoldMine.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvest.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvestLumber.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHumanRepair.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionInventory.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionInvulnerable.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionItemAttackBonus.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionItemHeal.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionReturnResources.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeChannelTest.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeChannelTestLevelData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeColdArrows.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeColdArrowsLevelData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeCoupleInstant.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeCoupleInstantLevelData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeGoldMine.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeGoldMineLevelData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvest.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLevelData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumber.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumberLevelData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHumanRepair.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHumanRepairLevelData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeInventory.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeInventoryLevelData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeInvulnerable.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemAttackBonus.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemAttackBonusLevelData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemHeal.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemHealLevelData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeReturnResources.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeReturnResourcesLevelData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/upgrade/CAbilityUpgrade.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/ai/AIDifficulty.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CAbstractRangedBehavior.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehavior.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorAttack.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorAttackListener.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorAttackMove.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorFollow.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorHoldPosition.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorMove.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorPatrol.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorStop.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CRangedBehavior.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/AbilityDisableWhileUnderConstructionVisitor.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/CBehaviorHumanRepair.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/CBehaviorOrcBuild.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/CBehaviorUndeadBuild.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/harvest/CBehaviorHarvest.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/harvest/CBehaviorReturnResources.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/inventory/CBehaviorDropItem.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/inventory/CBehaviorGetItem.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/test/CBehaviorChannelTest.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/test/CBehaviorCoupleInstant.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CAttackType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CDefenseType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CRegenType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CTargetType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CUpgradeClass.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CWeaponType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CodeKeyType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttack.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackInstant.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackListener.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissile.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissileBounce.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissileLine.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissileSplash.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackNormal.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/projectile/CAttackProjectile.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CBasePlayer.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CPlayerAPI.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfig.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfigPlayer.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfigStartLoc.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CAbilityData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CDestructableData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CItemData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitRace.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/item/CItemTypeJass.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrder.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderDropItemAtPoint.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderNoTarget.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderTargetPoint.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderTargetWidget.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIdUtils.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIds.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/pathing/CBuildingPathingType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/pathing/CPathfindingProcessor.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CAllianceType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapControl.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapFlag.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapPlacement.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayer.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerColor.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerEvent.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerGameResult.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerJass.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerScore.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerState.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerUnitOrderExecutor.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerUnitOrderListener.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRace.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRacePreference.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CStartLocPrio.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegion.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionEnumFunction.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionManager.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionTriggerEnter.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionTriggerLeave.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CGameState.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CUnitState.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimer.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimerJass.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimerNativeEvent.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/JassGameEventsWar3.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CAttackTypeJass.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CBlendMode.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CCameraField.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CDamageType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CEffectType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CFogState.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameSpeed.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDensity.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDifficulty.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPathingTypeJass.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPlayerSlotState.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CRarityControl.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundVolumeGroup.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CTexMapFlags.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CVersion.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CWeaponSoundTypeJass.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/uidialog/JassUIDialog.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/uidialog/JassUIDialogButton.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/unit/CUnitTypeJass.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/AbilityActivationErrorHandler.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/AbilityActivationReceiver.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/AbilityTargetCheckReceiver.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/BooleanAbilityActivationReceiver.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/BooleanAbilityTargetCheckReceiver.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/CWidgetAbilityTargetCheckReceiver.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/MeleeUIAbilityActivationReceiver.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/PointAbilityTargetCheckReceiver.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/ResourceType.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/SimulationRenderController.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/StringMsgAbilityActivationReceiver.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/StringMsgTargetCheckReceiver.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/CommandCardIcon.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUI.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUIMinimap.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MenuCursorState.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MenuUI.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/PlayerProfile.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/PlayerProfileManager.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/QueueIcon.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/ActiveCommand.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/ClickableActionFrame.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/ClickableFrame.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/CommandCardCommandListener.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/CommandErrorListener.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/FocusableFrame.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/QueueIconListener.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/SettableCommandErrorListener.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignButtonUI.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignMenuData.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignMenuUI.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignMission.java delete mode 100644 core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/sound/KeyedSounds.java delete mode 100644 core/src/com/hiveworkshop/ReteraCASCUtils.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/ConfigurationFile.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/Key.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/StorageReference.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/info/FieldDataType.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/info/FieldDescriptor.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/info/Info.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/io/WarcraftIIICASC.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/io/package-info.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/nio/HashMismatchException.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/nio/LittleHashBlockProcessor.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/nio/MalformedCASCStructureException.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/storage/BLTEContent.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/storage/BankStream.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/storage/IndexEntry.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/storage/IndexFile.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/storage/Storage.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/storage/StorageContainer.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/trash/LocalDataFiles.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/trash/LocalIndexFile.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/trash/VirtualFileSystem.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/vfs/FileNode.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/vfs/PathNode.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/vfs/PrefixNode.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/vfs/StorageReference.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/vfs/TVFSDecoder.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/vfs/TVFSFile.java delete mode 100644 core/src/com/hiveworkshop/blizzard/casc/vfs/VirtualFileSystem.java delete mode 100644 core/src/com/hiveworkshop/json/JSONArray.java delete mode 100644 core/src/com/hiveworkshop/json/JSONException.java delete mode 100644 core/src/com/hiveworkshop/json/JSONObject.java delete mode 100644 core/src/com/hiveworkshop/json/JSONPointer.java delete mode 100644 core/src/com/hiveworkshop/json/JSONPointerException.java delete mode 100644 core/src/com/hiveworkshop/json/JSONPropertyIgnore.java delete mode 100644 core/src/com/hiveworkshop/json/JSONPropertyName.java delete mode 100644 core/src/com/hiveworkshop/json/JSONString.java delete mode 100644 core/src/com/hiveworkshop/json/JSONStringer.java delete mode 100644 core/src/com/hiveworkshop/json/JSONTokener.java delete mode 100644 core/src/com/hiveworkshop/json/JSONWriter.java delete mode 100644 core/src/com/hiveworkshop/lang/Hex.java delete mode 100644 core/src/com/hiveworkshop/nio/ByteBufferInputStream.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/AnimationMap.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/InterpolationType.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxAnimatedObject.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxAttachment.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxBlock.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxBlockDescriptor.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxBone.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxCamera.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxChunk.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxCollisionShape.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxEventObject.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxExtent.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxFaceEffect.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxGenericObject.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxGeoset.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxGeosetAnimation.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxHelper.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxLayer.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxLight.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxMaterial.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxModel.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxParticleEmitter.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxParticleEmitter2.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxParticleEmitterPopcorn.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxRibbonEmitter.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxSequence.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxTexture.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxTextureAnimation.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxTimelineDescriptor.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxUnknownChunk.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/mdl/MdlTokenInputStream.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/mdl/MdlTokenOutputStream.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/mdl/MdlUtils.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxFloatArrayTimeline.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxFloatTimeline.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxTimeline.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxUInt32Timeline.java delete mode 100644 core/src/com/hiveworkshop/rms/parsers/mdlx/util/MdxUtils.java delete mode 100644 core/src/com/hiveworkshop/rms/util/BinaryReader.java delete mode 100644 core/src/com/hiveworkshop/rms/util/BinaryWriter.java delete mode 100644 core/src/com/hiveworkshop/rms/util/Descriptor.java delete mode 100644 core/src/mpq/ArchivedFile.java delete mode 100644 core/src/mpq/ArchivedFileExtractor.java delete mode 100644 core/src/mpq/ArchivedFileStream.java delete mode 100644 core/src/mpq/BlockTable.java delete mode 100644 core/src/mpq/HashLookup.java delete mode 100644 core/src/mpq/HashTable.java delete mode 100644 core/src/mpq/MPQArchive.java delete mode 100644 core/src/mpq/MPQException.java delete mode 100644 core/src/mpq/compression/Compression.java delete mode 100644 core/src/mpq/compression/DecompressionException.java delete mode 100644 core/src/mpq/compression/adpcm/ADPCM.java delete mode 100644 core/src/mpq/compression/huffman/Huffman.java delete mode 100644 core/src/mpq/compression/pkware/PKException.java delete mode 100644 core/src/mpq/compression/pkware/PKExploder.java delete mode 100644 core/src/mpq/data/ArchiveHeader.java delete mode 100644 core/src/mpq/data/BlockTableEntry.java delete mode 100644 core/src/mpq/data/FileHeader.java delete mode 100644 core/src/mpq/data/HashTableEntry.java delete mode 100644 core/src/mpq/data/Raw.java delete mode 100644 core/src/mpq/data/RawArrays.java delete mode 100644 core/src/mpq/data/UserDataHeader.java delete mode 100644 core/src/mpq/util/Cryption.java diff --git a/core/assets/badlogic.jpg b/core/assets/badlogic.jpg deleted file mode 100644 index 4390da6e0f6d041590c6313d2b4c978abc00a342..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68465 zcmbq)^Lrgmu=k14*yf3?6E`;6*tTsowrx8(v2ELIY&2}rB+c9J``r5%+}Y>ZUuJe@ zHH**Aey)G+0nlV6Wh4O*5D)(5YSNn@d5us2mm;EL>SmF&`^;7 z2`HldC-AQc@DLEtkjQYz02nA}SU3nscmx07(ntY=-`zO+9n1HCdK=ttGSPgaMd6-S zdD9t!!mq@QU~+7or#N{(H=pM7;_|xVqVUz6-6>kx63a~pF9x#nS|XSp{W{tyF1i)D zWLEYLZuF;RUKcVXup4ZtEP%y7QBtTp8Y{F|N9=p!Grl7w(XY~I?E7k@k<((`AuB}| zD|>DD>ry4@;%jVuC=HzjQuNT|48}Y7J3WtvC0@mWX)9Lo_;WFu9(aqXWm=c#UE`}O zKS9)T&H2Vk^HV1L=Id^n%^duZb`*^oS|5 z7}x}JPjNFDEG%Cwhdz$M<8C92%G21hX`J=^${)m_$*( zjhrE|7!h$VU}ZA8W?09}6gonXEaE$Q#FCm)tb~a%OcocF#LMI9SzY4anQBv`RMe}~qfRtNL=#xWJ`?(*o9sgExm&%d zp8&{TEs^Wp(vaWa+YeLH?M7|Pg4Y~3r2s*c1s_tur+8m zuhMi68B!nqA}*=Gvi>u?>@(xrx|{qpN2+vP{c+oVob00C$&ejNoN%bF> z#$;A1A}3Jg#U)ATaNo7M?3&H>h7##xnAe>^{8$`Qxo?<##lOohsx)g_AqU~VmO;zb zkVe??Y_{;f%8PkVGPBLEvi-I#x!_Ai2lj2lkCz`s{0LS@je(qSUkH0FWaKb3XLx^+*4}mmQ6^gYY%Z_Hs^_T zeC$aF^KGZ3c}99vb)Z$d791B*h3>9qHmP4mj0EVa@7qn*#A>hxiR{^qiTs4sQLhWd zvxSc;ZNp`WmxT$;kSYz@4lZiqC=-Kcd0 zm$sVXkrfwV6l|EekR>OH8I}~_8%d@)Hi`x9Uvkf)li+db8l3GYt6VV!vSyNJDY)Y( zc;VFU;F{C9YO|#vGsAa-4Xq|<6x0BSY-Hh74+K~5i4<2Gbp*`6@5MdF;0g9Hchj9y zP84i(l@Ui=DRD#8d+5Yh3rrGV^mTory$M8P63!2CoU4TslWzvm@0K_cMl&-fJ`lwH z7GHkz^y_eVv4^TUoebkDHBm)~P;6T6yC%O@0rOPg%UoI`PY>t%@W#5{KP(N>@8bW; zNPPm%1ROpAj^4J$4pyfyjfQ)f0^_$Dl&DxJ32+R=n~zqaaBP!nlvzho^eq#EMJxh} z)t`XS8Fe~yYx(kO!!3sSqZ=^c;b_+ti<-P4@%_dZn&0xJ_PLst|7R~l9rKiYx)g{XvGl)Zwa0@n&m zq=|%Q|Lb2B7s5qpo~+#i41($vAg7&_;Is=M08?K*bP%0ny{+#9^9D3#yti$s1&iC+ zr9nM)Y_N&5vGcdEtSV2ro{hrP))4l>d72H5h#lI7pmjz-_CX8LbzSL5C|!fnh1DN5 zT%T*cnqSU9F15wROfY?%5~WaKOFC!s) ze?ou%^tvB%{nG~bWD~2()O!151>W+-v*YcRn388${+`Dge$KOU*f+kM7ijGyrE_(+ zd#D@YEbsFi5x?#}PS&L^B)d;jyS5(f##&5s+qPjZZfjo4C?aR&`ILmWn^uD8f{YmA zJkCzz5>A{aM37iaa~B0s#f7lDT3p_fRr{0iZr!ZxWKTy8&$X3XsKNtwqlGK!CmX~Z2v;NRkx}*TD8ZD{b}id?5MfepgB#zQxv$FYOgP7p!n+*kp- z8dt(7C0!(ur08A2FWUH7Okr`mW=l-G_Jrcis)gYnHi_d=|0v&8Rn_1mDyOLEVGc}c?4Hsbo$&@BhS#}I~!}zaz9Lmf5I?HU*JfKgw$o5`!!DIF>95@ z3GGgFi`(x*f>TxQzkYwO%yK8%?3|_!l!P#QQ_Lt(@WZGZ(&P>?cQ2kDrDO?xBX;*0 za^jvT@oqG?fa`PNK@RGRLpvECBG<&o*5al39F8GMjqJ=r?;^e*@ z8Dt$%Ya_{wh!d!`7t$Vxuzh^gGA7c(6X#Xk;)@a*8dpq)Y~ia5xS$Zl&Oq^X`PTWN z(kui_kn&>kM{3q+yvSvT97Kq4dq7Qwz?euXcmMd#lI~iSty+^_?zV5fd z>(32N4JHX4ekG7x4IF5b35_7AeO^2u^q|CZ=c9ZrnSX|B>GfRqDdvjR~<4MSVyVw)fq1IK31lUXEiPjx=SeUr4u&i`B2`jwXze zP5&Z3{~dusfEVP@`9p={ZA}I=Mm0U`n6`LAK;;e1wCS=KCc%pDkw)?N=(fGDOg=uY z3a&>IgVmzlCR7*xmev#|C<@KQ3*U$r_x!^w72AY z(i}I&Fc9~Bm2qakN@T)v18!^Ji!$%3U*F<8x4Dc;n&hQU$nYqmI~Kuk3pw9333eS2 zyO6+e`@79Ze)Avl_-aZAaw^g5RJ~}!2g!F>PlQEIRY8{ zoc0Qw4C z3B#VETG|@X08*Rb624yU_HV7MAVMKHK3R5>5VP(o2IYYgE3r=iE?wj+H%NEnD9>MD zBaM+r*m&SjiRs4#5T=yUXh-5W?;u2y$;p9kQ*nXDh1SMK-NH&kPQFa#5k*reTkn!i z<`|h%HCnHR$JAJ(tV4n8?*)11MNJtyxXLP3C^as$)X2gZooB|Wn%Ep;W5v~U#e$HZ zrpT-*5xIXVc2QZmW;;EIkC9W?!jv_-d_qcb=wJyi%aFRrEs^1R(MC}`J?XXb6A&M1 zwt|gpULGLKM-f|BCN4)3%b?K{rkkMOnc6^#9?2SAN@MM)*eoD3P)WB@2pd9#>r1Pu z$xhkI9Powzn8a=_-V*t@0c`VQTYy7Tt?g+t=3V&rnQa?2JZp(8S6n4sEeJAYG#S{|Ww_JHKMc%k%9_c5IBzBHQO;4*m_>|_# zoNOs((}f0*>3%^H0k;e%=hxc<`!dHo*JrC^0?#`3Pk{Lc?_ut9;79h^-={y-yy^aO zFB*IKjh_Irx3#`!q0LXgun^@RgW%iz0|SvepQK02wZZpeup{~iQKpxw5#w`mWlyZX z+HdWpp@pLUNm*;_!$fmw3~-Rt!GPWfg||>I6(pJ&B|itBj);OHA3cLcbz@<-y6K?kZC*d;?GO^XR1-cS5c(E_#3P+_pC z{lyCKb$2kFoTfGdne|1^Q@o_a+^k^(+Sj%uqyIjB+Eot$ zSfT6E-i7ApXQYf)%>-_Ze0k5a>*~-#An3X=jZtPmilc0;$!d^jA0ShaRxwR7KB`Il z!+aF_8~+oKb`#P7Ib^cL6RZ9Ni@DB}Xv`~F8yn3s-#B?5cTn{0cFA~)gUz^X+UAv> zD!b~%S-HqX#{EtXtbYF(-%b;l_qC$+{J#Cf*h z__NDz;~6Wm^cC_52e&C8R+$loe`EG*JOQoc0?H-dVt6yvF4xg(%>}c4xQ@UdLL3`{ zXtjfehL~UvIIU&oQ&iLqXF~XWx-awx2!z7J_fyH!k$lsBO_>O|HJTSI_*|>MtlzwE zR)n~Yt=ap2X7FD?NUbJ%eu(yvOqyt7gz1+t$(pZm>-YZHQ16|$RZ*3coi*cV>%m2n zyykiN=qZ%rBl!MZqUY`Bcy1e>8KCQrPI--`QtBq2EV;Qp&h#dQQGb$RHXB2;yB0k? zTF~JaHt%4KH+D5ipjMXxc9QFcu2ogWwf+7247=l)@FRaP7i)|5eEIHHt9D5>T9z5@ zVVE04=#dUz5Zt%BW?{xvv?DpJUohnSG+-FZ4JgT&nz8(fYW~SNp)Y=F>WO$%#p;ed zKTguYuqWgOB)RL`BEs5VG{{Vbq-}ka+^_4sgi*wycvAkVUs&GNBZ#UD*_QBquyB93 zGt^C8UILq)?AS`F=c^8k_kSY-m>j)88yi4Bgw-M@-!{;h(-oSDGi(tNiQWkIX*10CS12ssB7_6s*>lPYL+H)j8uiTg@ivZnUN6q zs`_HxiPQnotL*!M0=Y7+<5o#@l)1jJb^34duFB7q*$f4tkC(>hz@9isC*#Im^h9QC z9%}*ykgFO4Hb=G8iY#sVum-d$VwGX?tmbX8LM%Z&k$c(c3cr6(oXl%yFz{Ou?;SoEe!LNG{$DDNP`Uk}z;DY=Y7%?D*nc$?0!--B zP*8a2o%61jGNG^XG$R6KaIc^KWOVnt{n0io!#m_>`~;{|Rlo3gdB^#Gug&}5$niDP zKGdDT-q4p;YPLY7&Hh=rp}mGr+O^JN-DSROB-knsB`WHn{2=A{ih;oZU*U={Ib$jP zr;H?CJ|`xxx;Xq8S1Tc1Yi*=yku@@3blTz>CPx3FhAUa_8bKh+jF0{ub0D#yk~B$< z6f+?~la<^Sz$Tx3+=d7Ieuw-kni^TBxO|-FmAH>??hWKYI^oCW|MT+oFXyrCL6tpt zhl0L{*&&Led|&1C=@Ss}3Fu77{jmbqSCQ4Rq&Kf`EGOai6K_lRGU3hQb<`;*0DqL@ z6CmmIZ(Lb)>`WZ)*Z9BJw~bb9f;St@*G3Zf4&oFI*|M?jUFF%aW$B>5e3>7uz^q!y z&9AqA$FDaUEp!R`wwLfok-R>b$ic&Wu~Dzx>pZNZBa(3%gU7Gc-y=PaAhooxS+UR6 zs-RRlY=7um9AiRPRkV3t_q%0D_mtl(=kJ_v@+V;1Dd59><)1Vxf({Tq^pY-s)84 zNChYbToYJ%sxKLKCb2r=7*)|8p{UkWwIV2VK($FEI@(wN<-K@D==%FG;J#;U)YmZt4*Yw0fvP>X* zjggEb3MiGiMmQt91Sda5HxlOsI`H&rrzwtB*kM9U-R4K^nES%w4UU1?;!oW&sV+tm zDzpe)Q`T^cvPB(H5F|Vvznwk_t!XE4y@b;T_;EyBCT5mhKcp^G+j&A1BIoMTJAPX{ zrMuSrE@#1@UQiU9OBNTKn}o4XNi}bMYkMj=tHA3j-Wr>Gv&HWln)hB#4;p=4P}sW6 zC7^MEU9PiRSlhWI@uMv$WUpr!Q^N-9(V%k9By(pGQuAi<@i`02*AgEyE=)!VQjDwU zh1tp&dO^iAt@?JvX+X}#Wqmg{!s;O2kq{4$@bFU0Cl9@5zQh=wL02pxA zAM5dD^}u)&NkR>x$2^GezA|j+-|YUtqA+q%q>nQUPhTmHL1q8YQJe#{mZZLSpVGCYs5+5qxhI%pY1E3A^MBU7DEJqW2Dac-r*KqBqo4NH0lDa9B01idiMFUJ2B^3~w zWLtd3Wf}Ixgx*%rg9W+hDOb_+B9T^iRCqi##4nr1ehn8HNg^(vDPiDR-&V}Gx+_Q_ zlX~f`Brx(Df60mm;W?#1yqf{)cFHwj8>c)g-%3Fwf;Jgf3W+~L9%MyE;0R<1~s+X4CVp=~!UcNiOxuQyAC%F)wYSC&@Q! zH=1GE1S6PA9j>Msv}s{)wq%Y11L!6^IxD!I;mGEszLgIUzA=Z6m*fF_h4dQS z9XyVHDB;dR?pK_{SQu_PS_Ic0^3{cJ#=wDO={19VEci-pWJq{(mA8(438`Y;R-@BB z+n)W%AjiWkg~dDhMp+z1Q_L^v(r`NEwTacBiOFLeI&gw=7?0CxIbUy(<4B8b5BU#& z2GpVI#c|Yo;nX!W?{v9{1IRWdsj%IC3f~9nR8Y$^A(>5;lZsDoac?52ZDw^jbDZVz zigbdV<5F|);8VL^{P_bN^44yc_xB#GCwE%sh9bX$KP@2sEZ^ z7-9y;_|MHK-*SN!>TtC^d8J!<1&s(RTz6)BK7H`~9l`RhB*r}WB3K(-z8*wKBAqzm zjf@fqcoh8=J*Ak#po$giZzno~1{|I@F+*Txzg%6#O}v&Oh@3&&U?myhfh>|l+D;j% z=!l4sSS~!OPH#5z<%di*wZ(4|`MK_=Csh^WR|RFJ35b9BiO>|q$OT=+L<0e6E{!LO z__R2>!PA$B24mP;A!PkZ=T`|ezA@2r+RwaTQl*40XCp6`y! z`)sjN@?Vu<$0qkUC zVs?JJO*gj6%w~~_ka5VcX|3+-!8EKQ<5FUlPt=tlx0J&OyLzYd6b%iO+yrSKox6$1rlj4=BI6cAV&vF0&+S%OEgZ7z zsl}$GZn_s5#Xjc}KMCX938!+-u5?dYUf?OUB$GZ>YRUycWp?OxZw)Fp7GWU;q^rc_ zALcnERuGL7w@tBvif^-82%qU*pwhJPDy%k{{17*k;a@sp0SDy#GvAN+jpN+f^_I?%1K}YPOuU9lLn4X>!AO zH7WnGbxJCqo!az(7nMlSC6U9WC*fhp(`AOW^ALutPyg3*d&Iz8sYeAPS9yi8$apUM z8sBq@T9;W=c_4x$97UQRSac?o>JQ1*HJ$qX@{qotXnH;0cFeJH0U6JB!m?*b!2lV; zJd$i@3(llWA-fyz2|KHuM1<`p`I`k&`U)2Tzl7=6+(mj|)`Wc+x`wW88rMo^U6)W* z2fK%(a7R-Ki#I!~_HI6(wvgHmj-E65odA|JyF*@cq|7k4zm`Z5O#FKCwYvX)7p%gv zb6Ev>SrfPI?51xM-;lAOfdZ_ljy4tQa);W9b8WC& z53&bGxqY&Cb|)UD6NkL^DfBkKBv%kfgBv+*9jgO6VJr@Brk;N7XO{y&!zfg;3c zMl$NVdsQDcadpFM|LR?7e<+B*y?Eo_x?EqG(8dO8+4k=#fL~R6M2ch^j$JCd4!z-j z96RAsdC?oA*U!bc=*xwctxYysayG6%J?8lYbQPif>CNZ4o;7Vd;Is7lgyj+hSH zaHNU?AJb15Xk5cG5kika!K)=$;)H3YGc{;PX<^B5!p!LTc_FB9Pbbwj{ShME2%4MV zlfREt|6nOT~io2Y6_U$1H3NAu|iAASK8`X zq1AE2^>tIvN^8ilvthWiFy(NPS7m#Ht-9Pb#V#FZG+JSL{Sj?mebdCwb2TbMo|;QA z%Qt5|*lkKcV=%VI7TOYlnlK(TUQVB$j!u?(%%R3zSg>4dEn1qWhUq}`fx3jzRe7v} z&SKNrVY6;G#2qIq{^(-ZIb+;kEQp}Brd!kEkEqCA=O4J(;tM7)f67eA{EC8xvUs2I zHNuyojW#?<%J@*h54u=gFyi+>UfnF7zZi@U$JqR{DjNc#B-DQGMC3Ka*<- zNKPSChXOZ}tV$yVPG7n>*r#4-LCX9I0ir7&$UBbYMCn9{L!`#7=nTb_zqD6d$VvOH z)7(8$=|U00FiE1WDq-L#75HAw*=?%sSXA<5aOi7Nu!kt_!&w(AN?462X>inV5y}Ld zvoD5_Gp|$DDSGratu#`*0l6dYbsB5z)7e$~U|X-vd4fNVG>5>#sAo`NZL#CI;dQBO zqH2m+!V;5568)RohI2kaqXL6=Kn}TkpJ3SHwAnYKX>C^C1jWNk zZNKf~jW<3S6H*!q3!VN$h3Prl4b|o1?y+pXL@fW2xLD=g?re=axc8-bQ-y~W1u3Fa zl%J6g#{#8p@}Xr@{B=iMYr+YQ)e}>9!BRx+vnwc8oq%3yoZ{D(30xPaR3}44g>$P> zE^APof9rj)xw=xq@9T#(m#S9BvNDrFrc3X$G~qJ2(QOWun;}?*qY#rMs(yaoG2cGx z;1TE!&$WP@9Su4Q&+PdR(iNO;{jRv()!H`0QF8R-!4H~k+^ zy)`)UIv`e3XlXz_S>({-wWCa|BmNQ>Pk{SQ!LUTq>d|o*H5iG5gX3-))&N%=c_c; z=ALH^60Eg~^Sr-0Vm^~#Ef6U^Z6&hcu;j0pDOHoVc@@Wpb+$MvF9b)Vob50__r-C9 z%;ILwCD#Wa2N@&tEn2&OEuq#baPK@iCMhbQT1>!PsE+r-sFT<{Q4CBTr9tyuwHONt zAgPDeN}z1?K9T#9SVzlB6di)fC1>GSbZl=rzE`JR37{q;Q`7 z_#~lAMd%B%$K#AhfqQoSzWt1gpEMSKDg{$AGbR-&5EV%kjG=jD`zx2Q$F6IBM1tt8 z{6z2DisRH*m8u!i$(l|4;rvq}-Q-u_MS5m_EFp7Q>GrW@%*=Jkt#KMJZg!8%-8Ds_GPyR z3D0jhO%q2Z9^= zyMF5SC?qN!q_kvP{IU|@y>rQK-oF!w>tB;WQ#I)zg>!+}Z@+$C?U6Ad+zYfm6ox6((Fi=zI!;AZ4PtDcVLdf0w ztF;Un0G>)z=i367q#9YVZ^{@?0;32b<5D2j+7;kq8AfrtXDz?SyQHmjZl4?Y{bs3T zyyX~t4w_>gz24uys_TuW#IynWwxO4R(}^P;d=M>l2z<4~d<0oDG+N-n?5rsGN;d`; z44Gp?(sLapcYGw{@s~+Oilg5MeaSVDRczBL`T*~%u9k85+>S}i6!9jgOJtWfB}BL{ zM5sQxQH57wBT-r_RC~OYS^_BQ{w>)zc`?7n=jPj$n26i-!XgT*SM9gzswqseKx+gI zXl~KDKWjV3r*xody9+k@*P^BQCP8St0>_mWiBV_PX03R~*jYUiRUt|)A=s~SA7UOz z8aN6xcG-S(VFXvLTSJUY2uI#$hYyX$7_Y7w)k|@DSSq^X=J(~1?>s7!TfC0v6+KvT z7H05Y{l(m?czhd6^b>qXf-Z>@M%(g&zobXm&t9oJkm$-qgLbi~HRf>?{)IHlb4)#vW1^gv>6DYN(Fp8yYuo2-g5cipP3E3ivW z<+&zt$!P1ED|a!yTP?d8|4Q0I>#l+(Qq7o?IZ#fgamw+>YDxBc;N5lEXv{gYtM`#q zd6L*jN!`$IBMt;DiE`zEEu9WcW~k6pjV@vd8~Sb)m+tZ6){?PmhSfnGtXObmyqzk4 zG>&M<))YZC{F0Ax`@vf9<2%uz>h6#DO_+_^yZ1IxhKD0Ux|HP|Dz>64Wi8_StjdbC zf1dv4i)huG`P&Zc6f?R5i>vGN9HRT@@XyM~n*IyxjZ4;6_MdY)op=cInn^J0# z>MnxNW?ShQner{DE)&YQ>?}NK&Bc7(b3e@4S3VOl7!1elK~wQ&)?g;_gpIsEn}pM- zQj$FBaq6vmTnPwBH=-AU_~G#sW4!R0uavRq5_cb3yv7PjCL5NoH&+rYg^+V-=H%R> z%Ki-vv2o}2&W1W|ZCge%&7srboew`TA;t}FOf{V>T3YREee6US(5>jHhJ7?;_7jfb z@tzZuQ8;hE)eIdltmbX$Z5#Upiv=3OPfA$Xm~)X-%DQUZzHrb5}mWvaV$ zFCS9vQgbY`Vz)Y!D9o<@ErxmT4eOvWBI$8XBe;gVYTM-uwNdo73nFgog_kJ*yH+ z^C^1?S&Eq^G3+|6z#nCs-Q;Bmm?Ep{TYmW>1{8N%{2T7GPp(NMJU(VYl&>Ll(xH0sUp+e>*+pb*-8cJ_)hDi%aCx?Sy}3>E!|b&qqb{U6k549*00tfKMZ_~ytpO5t|-roT}e?9?Us{?>rdQ7|QKWz^QF1Ox)wr>1e z^lfT#Z(MRt-y32~c<0KTzpeUZ9uYT1-R#yEyosMrV2MnKYyR-x*cdWVAX1BdOqrYw z=q(a8C^&U(#hMdez`YkcwtyzOIMbd#*KKJ=z9Rc|wq4fObl`3%T1vq9S|xr!m#S$G zvW{~~b)QdewdW{%9n>k=(F4u(`T0?Tq|D3zJ;Jworp+CDAtO~!W+QE?rEE6NCh9?c z)zH$pPtU0fqNMMJ-+;CRSg?L`psiCg=G+0=fliJE$)1$8W9XM}c4TY(>l}g}RsbFH z@1mEC<>LbosD>b@T*oKmuf%Rk@C8A9wq+f9m%pvs47rjF zFq43KoFo%myL=+pw14?K1j-Q!BGLp|^eHAf`3jN(z)ra>-}IcoYAq5T3-xD&h1BiD;rK+kM z>uLXmYCua>tEphiPw%eV-^N9x_4_=uFmzCD`Yc`$n4zdsc>haK*w%3Rp}6?mzJk&*gN)aO6E18?1$8`svndC zu(WN>v=BV)4(ieG;0CauXx}t%cCkc2T#L-lBUtkIl4U|9cJw4fG~OO4;eq2-OrP2t z7M#SVbBGo?z1%-E+kbBg;lve-8I~ckG|45td@Kz*BrwZjAEII1uvw-+!EW?>mLw6< z*4jB)K(e`YU0UZR&KQg8R2tW7nP9k}kSk90ZOffws7PO);aky`Ki9TzZSj{*O6%kc zS-MPTM zge56HIT6LbQaCWEnXot#r7K#~i)hwuw!X6*81eav!O=z}laj4Hj^o&sd|TFh5l0pnMi$5nvODu{D~K zj5gU@(@Xmaf1Y!=1I`ZkdW|{vPGsS5L-X#de=YdB>a^D}OV!~Si{cTq+dttXkkzg3 z+Qv0!;i zu5n|EK=Sh{LFc4+q;GzE)tQiPpR$5PNsqwg9mmDh3sAg|>p=yaet$44TW>d4tMrm+-5 zCgkK`jo~*BTP`sZ-!K}A_dR?s;5ed|)!Cq72h1>lZb-WZP0e3;twlkM(P5)A5Y7?o zUF6h6Ow%5I8^@?!MnhqdJnA;TRubdoo*gD1@U{5Af(~P1UT#h{gT5FXEXTAX*2zj4 zV99rMm-xC4<0l`j@O1^M5Z&3?{P!N5;XMbkS2|r^uWch-*x2L`9JNjYK#su5$a%Al^YbuLCE_gC>|tB9IV6j8;BG4QJBX2sl0va<=?s%d1ly21%> zf!WA`f0HUNH>O9X2WhA%drGVE8`>JiY6o&D&hxG$zj%esY&F_L^E@j+vrd8jAe)`3 zKe7Oy`WU4R(HZ`tGF6qhjFU})xQQ|?Gdf@s29prP)jBW>JX{(q1F=jUE5AECMY@nF z7tD!v3^>N9s1<=hd9C}3eJAaV-a1|*ZYaNWH4s z`As1aNfF+P;8wiB8cBHYCCVWJEn}mt0s+6D&3bpRIo*OX-&#?$K*{p@u%0gapw0!>G=qx%TQbw%M;6K>bTy52mBQ^p@>yId>DI>6^VXoiUKCty7ScdY>)#<<`|`N z#d}s?{hZX!MUK9CzpRP&go(2eh8fAwd8%%>O16!HHK`S@3?oeCqncQe-l%5fu}02^VBsFx`-XwBGpB6MJD)~P4g$_ z7*V(Wt#!MCv9BnLSNO|rE6J+6YNxgp(Z15hXU>f244EKyonIQ5a7f&$XsQ@FT^iCULNQR=Y2=xm?$9L`nB^q0D=L z19p5faGtrg2Ed4opmJrwOp`}GMl0mwNETHuEO`=J%#wq*(n%OgrkM@uW-2}E zTcA+ypz|cxe*Li*{Ue_xYSC^{DI&Ha)sG-ozw~zsqB98sOWgrCXCurPFTCKeOqsMF zQq($zkNqX|&6%b8BZNAJ7QNoIFwOdD)qBb(O%>eys?65QG@`K513z-{cs=ye7aE=R zo%fYqmDvi)neUyHn1PAwuP$8x{qJXJdh#GN{(&vsHJp*r z>7tva=fS$eq7TtMCs?-zPVY&Ni82hM(h z)7r;#?5;JSxrC;?iAWGeTw_+rSm|a)mP>y)rPFrbv~VG5{9>cZGE7YUs4PTV=zD~F z2>?YTt$IR<9(bevb+*m`A)-MUY8|C;e$kp)kqs|l5q+Zp;zu51ao`)RYRycN%<;YK zQT!wUrwvz&TX9cjoAbUaIyf=)J;^h>4ZDu&s_v_5F36=a)#kNgOnZR3HiOT71oKQ1 zmCP92d>EjTgp4N>&XpXbrm%a)S*AL<@nnZetiQ6NBj^ZQcTWgKEKjP0j0ZZS?=~9Z zQaPn1`|Zk|qakhWZUeQkTN{qDT%%;QCuJd1arff=mvO~|(fYLZhudN7bjyr8Gl;t# z?+ZTh$>5$zN+w7~0v61XN;Nj@>>W*ggu_8Co2G?vH~6iaY*9dDB@W5F;>dmH#*Z3V zK{|sg&8lrHW^4oHH}BZ}*0#1?2>xtbZDq7g^ybPGww9oPM;_A6crhm%aS88H?zKh0 z!p+Uk*L$RY0bGx`p8(=N24}xL9Nu4H19rT>d;;P=^n!3%L)P!4-*0+SMrj-)4O`0& z9`Kw7oGqIZICj38u=krn=zYb|wJG@o^zQunZBNKlcc0Z|g8$U?Ueb4D^Y05=m8#Hi zbme$Br6OXyz?zyLMHBK#mF2|H4(&FJ%UN5x4M4ZaW0de~!A?tDX*cZ?QxT%#{CgPvLfH$i;_^mJtp0V#r6vN(-Npho+1&e^wyEtcYw zGDhVLPevy#NNkjEF;7(8VU*&*%u73gdYqxl# zLS=06e;RHcvnP5fh`$}BG@fN<_Ky~RGYRE-F=vP}N;ZRzwUHxwxQo)RER9ods}BT* zBV7F<8L{s82MV6xxB52-8CZCoxR0Yq4d6IrA7@4sqW8RGkTu$58;y8-Aq@2|bO^-n z|5SdEkAB>~_ZTm+#3lro8Ounx4x)U~%o?nCcTiY49d! zTkQ`dR_Lzb{zuZ9f!>OoMuNKVBJZc3E!D{K1ByT~fvnxgK zQrpVbu~ihKvn+h$U&o;r==U+2u98oJuOw7@F950sjoT=!9En*}79{`X*Z@-8r_akLz zny#A?ESQnqyCI`pK6W^MuZcKdio@I;FC#uUpCu2HyZ0J9DI{*UIJl{rKhE#uAz7)ErVSOqME)9Q(j4GrIP1ES4;L} zr7+r!M0M1e`7MRD#!YK;lU&}t33GLlT-sz8R%C2(#AD~%+{>F~EyIc-M-!w#cW z8>{eXo%4+SclLU_v0XM#J<2;8sjk{*I&%~uE%A-xrwJ z_b)2vDyplva<4jZ<8N;G!iF07d*{9pVMYTZM~NGGw?Gj=9Be_10E`^5k;DOwsKy0@ zXxPL?wW!oY)emAm%$HHt?#PpYb|#>o$dE%am0i(+qzIZK-P`9WKhc?62WIRro*yWh zDEu#7qq>ij!99?DmTmXH^n1Iv{(OT!?!5*70LOl=`t`u!jNOqW;h6E`+PHfC`{mJS z$&)6C?%~tNj+}0q4Vtz=H5YKJj%QJuQp`;! zLZm%7wxi^AG!^D^yJb_V#;Tj4R>X;~`(uP9Z*sk0!DQH~#kG*ppcrmmYHV~VMY zt>xT}v&X?rk8cj`Vp#M-%rqJtYjrmcinWp_OD%-wL8qt5p+Xs^&XReP3OMZZOORP| zh@~kC;nmXqF6>@AjwdMTk1JJ0K*iHH55x?VbKQUWY?Z4`l+n)d7%F(Xr?wO=BChuo`a~hD1v4%4x}PcgxBxi}lrVkw z`K~bCu7+Rbvo*AAo?2_J?e%qF6~AwJL+Op9@NicrUUbEfP;#y8n0n29gb}5kU@I4*G`3ABK?y-apeT#H+PT)BHdTftR1RU zO<>FGp7RxC;RnoC2)4mYiws)om9#;Nm0v%f4PjiNi3@=3>jI@C0jx4t`?7mSnBetd zm%16vCg5fV02V=LcIO4b@#={UPV%yulvFWqrK=p}2d=ZV@yQUzanx3o&l)wEw^5tV zoj@%u_Ui7f)d^ATHC9c!8TL;OP~X~)Y?v3B6#Dly=+^fS(!1N~bKZ!Hs$zK4@C)Qa z$>Jd9^@VcMqvtYimDhfdy7zw*uZgr`^>#$Iu0$fq^wQUMn}!9&H+>BN_7v7iDa3MD zIElN_MNxdbwD_*My`Fxg75N#mMtFnn2eQlIUFf1TU2;{_@ z3SeIzTuE`t*NQ}WARz*9m97~?_c85rT&S#rNcO#?Yn<1y&2t{r?Q+@`_J1)YM?}LJ^}!LXhRRwHRkJQ88fJSwl`nc>_Qg}7`1ET32NjF z$~U1@z1hw&vf!m7SidyVF*Xk*i)e7q*}mxSrT2n~An8|$4jU*ehNPP|sa?j@ajsR{ z36X})<*@Su^Od#Ne~3w7PlfG_V<~I1JnDwqqlEX)7tIfgn5UDDRw)z`%vi3Dt2HMy z=ee@U2xPjFM8>*F^<^WFJs#!zO7_IpEt{D^o6+d7lM9GT9qjQ4%7Vyp`_cDR#^|%D zoyOTbqRx8k9Np2&FxyC$B_TgU+f(GTG5XBZEGt}4G*RG&7Fq##mTht}d6^<@ED*iq zzN1Wro+XG_)U<3MNMf-#^(-J-SI1TMMde(s08lTgT+@PTLrh$*zkMB^_lUYKd6bCpy`el$Y~qB%RD%tVRIEk@%21T50uA z_p<1@?pP<|&oGUSSR3L_81;cFw8fXkp! ziz;!%RBtA4&3J`agQoF$onKH?oXsMf9IzZkcc)#}ui#X!w!C%Jc5-gQerj$WrZZee zSPYO_BXTznT=HDvAJA5qOa3>s^RcR08kliRxr5s%oS{gFw>j?NwI=pl-)I-$(l|t9 zw>2}3Lw2aj*mJ84O_IW1atT_Pi($~3&tfS zw<`E0V`g5oaG=vhXKKiOvQ8o%I`0z00a(PPrDG=S%AzY}h6eXl;*(1SfFTOY8iAG> z3Hoaqm-qFL%up!b2G|wnSabd1D&(jbxT*Tm4u8lSRLAoE7wdZT99ZcS%Zu5OR)m8rhLg+k2cVWQY z)3A!357A;l#q6!8;6jNZWy_0oQHGDhRORg2?j(g!_1jxgTAbik1wihi;1k^ECZHqE zuDY(v6MR<;EMRkb?Bt>B2rEUd8&;Jn7@^rrQYzuY*u1i&k|unpfn;LpC5>H1k4Xdl zF?XAtmExw)j`Up@%~3lJzPV*LxcdFnE=O3BlRJPGcV$Xm#v<%R9ht@9g-9Z+lv&}? zjpM9?ZsE$?gnDoiOe7@@8lOD}<%5`RwzF5PYx`z7DC(Pz0c7=oH!_%kaiGLU%@UPO zK+xg!jg40hX7hPb$#Cb>vb*9KK06YFrKEuevPo0DcJA^$$)fCTJiU3&J#uMla*3)F zAlchlgSdqo2S%KIF&63mu{BdOgJh*Gqlvj_l8KDKTo~61=_Y8ZR5IuIjn>N>|h>w?u-Uvd7N$s_sjZ=^6xOFNMyagQJY72sT_xBTErsDy`&F zAD3F59L2zUQr#aQa*R-L`55Nf@0B_N$*k+*5>pXi8%7z&AImoxx#xSIhyy(B!5_3U zU^O3sXXG|&*|T+aXx%2PmUuyQmngZTQ40LB+S%3-B7mI9HiQZJf?%WN4p_J-FbCB* zey)q)Vn`23QU%_UDymJiQ{??_t+#aV>Gg5Fr~QisA@SD7hWU7}UUXbaplF-l zvTVfUwruQkl$t(g5Q`5{^W@krt1>uDnbJE7iiT6|&r(Rq@$0=!5y?Dw*t>fx-5j4f z`IDnU79i9#d!r&2S2jr9KYYM?Ur{R#gxU-*8xT)Axq5Qht}FQX_6=OJe(;Gls54RG z+iD<|k~Tw8Ga$Fc?i&P0yskc!R2B1yUn=UnQMP>=P>CF3#{J7)_DlE%mhkcf4zj>VH^=`_~X zguYolkC~hYL$_~>GexY3dJW7Pk#en&d8*bx93guM%R;d?69*U~>pO@n%!T zsf9^Kv#U7tkugGgC;DEude-ZThZA`w?;jFY+=?{>BPfZo6)04F$;)>zL#<+uO^kNY zxzX}S0qqAGucxUdH6c#qfYXl5nWWhM>g4M z2S3;*25ljDiU>DV(Yn<7KS;vKjHIHuQb3)^KC85sNvHMU@pSVf2P88)R;P-55?B zZOExe_h3nyiMx@;$268aft_0XKDJ+~Sd(uH2sjSxco)#_Ed(JUY!1dXfd*w#H^z^X z#6}EZY@?Dr+%Yg?g=#pgBr~b#vYQH5G+oOo4=LRcu3i|N@~a$+%7xzQy{L*ODyq4P zyg53_`d+Bp;v?FEU7jMG>*U0%m&on5!D3y0)skDdZLW6H?1HbT*k&ng<+@3H(Hh$^ zmTQpPWWlXq#~&)ZzS2tXarpolXb_U9sj(7hyqG}Q1ae6qB*@4a023^bBpld716Fc4 zuyVtkwtg_12M!rOWZ?&GS5*a5Q*K|nis^%Qx?jv4iSC9z=%AGO4#zUe#Vp)QEQcNa zu9rn@;DsJWHNzyTslkPHT*F6og>+WPj^ezPH!v8FH6$&Xwvl8-4{(&&ee3%>APn@YkIo947ura#z^OO z<3+GXZ4pT{(m^*5$`&N?X2O7g4$Oh+8MmXs02oNg7A#ydeUaQe&%sqG8;_=Jp)h#* zNWV@sAJcS*PV8fhkWF1;wah^!lP4)YzU~>Mt{dS1;L&!Gc~N-$c^9S{^EdMA<|gm* zk!j^OTNbUkf(~6*6%7)JKbqY)2&CzbmMxI0J+);evdS@Z=_Hi*E*=gc>xkS}s>`-> z&FE^a6Il*R5{xR;RvvrX{1}MucJiLZk=yPuC$ge@JgfANgzkGJr4}6mfe|OwZmIFP14~DqK8+!5o^K-nN z3vFC0CNP=228+lIcZ2@`WfDjP-Edv5kC2C3VvvBx4~c+E>y z=n(Q*wo}U1B)f~N0`n@?-g1qLDs-|uipB;oP%z_0j21$C`F2uCE@50_6Y{>zV^jPi z8x!eZ+y3iXh@7gqd2+c{7w|WYem?Q1R3}sNjaEJ)gUwJ@Wnh}h2km<-nmGOn*b~Lt zph(WzDYB~%2-884DE?eIMll@-(QVu2czRx!r#D_bFI@FKx88zo_I<*9sxXdpbsLCU zodq=$mh2S6mh)plE1JNLj<;#CMww)#e{Qx>yI07tBZuiI`Jk~Z2Azd zl>Y!VmYWJq+eu(kHno4p{O`MBN|g$2oKTwz(SdsgsyZob}Ss|fSFP{ zA-P|ZhwpsTCPl7?F2ZzyM1=-1=1i3#?HD6Pj3=5zgAvM&7=ji&gnN}5#x>4WL`BwG z*FDW^QC#OLHLXPDT;*O75kD%bsED7wuJ!Effi)cP*TtjHihddMffq^S8Io$VHwy)n z^o_?Sjg?Im^wWLV9gde2a8s>ulwS)X&Fg*CZs9HVHGZ2qRB9UZ;d3SIEo zulkaRp^a`B(6SEBYoMf*+IJ9<%1#Z&j*!#K>?a4BZFWgsI3m8pIcD6>!D+vv-Fm#d~{^Z+>8w zAj2tIP(ov4M9A*CP2)BQ&z5qzmh9o9XO9umF*h0r%bYc8&+Dn(w`%|{cWToyhtpe<8P8DzqRS%3e3eQvAvy$eu}ibYO1RkTy&dBiY>soa zSpHEts&igV-nFl6(HCz;*R;h;(FL5#BIK*q5lX&mR8A!)YH(>s2AxJpXUgb`!dHfJ zg35`nlvZyOAGD-Npk-s4OfQ4Ec5lxm1IOLlAKFqK%k}S5pP3esL%&8G2RMzwZ8x=e zn)#d$794!^W}&j9ifLrMv!sKhHk^J#3EHxbL(B}c1GC*>#6104Q~bkc(z1J2Qrg=a zJyKrg$&AEdtG6u#CI~Cmz#_3(H02@VzUbiI8a^XFG~~#=1H4#lW#`w9&8le=r_ZE% zyT_Hc2<6DUcy~;)+J%h`tKK^~y<5JtvY~{y zE1!kS%wfp0{G9S^9?0ZN*PP?GHf-KoUXm0wjjg;DSb5mBIzXh2tCx9-@ArhylaOcu z6JwB;q`1u7YA z%CiLwt{BVenD8sC1GM9@xmnwQoVKYjgt(l74>FGLUCSd6d2q)rSF~-DJ?DoPOCtR3 z(D80@w6?d+z|JzVo>*}UfczfIug5}SQFj%4U%2y)xYk=%$qn0zf@FHOP%XPGUox+t zG;2ZV4=3na(2A-t9OViomMKgHYZ|I-N|r^}Z0GPe>Na%d;#gQG)*n?^@y80fu&k+> z@5oL?%u9x3vMi(WAnb#LZa48~d5F5D&LQui72Qoj$^%?rx*|&~q+*g7;p-;+ilLOD zw!FP5WWsO&Nr*eA(&Er~by^CysNw~zO9|w5w;B06l#?%gx6NF<3@=i^0CV+k5go*r z{c{0;&7xaM1WYYxi5V>7y^#U5O}&y887VVnGlDaKlwzaUKa0g@==*93);k{INjs?F9%JJ@|I7-a#&EL*T*^JgZ4Z&i$%a3_-qgs!pOxCtFM&{5uirkp6vWrYkySqPhg zyJ?gZcfRF^NAm1+c$dWQPq`=|`VKW}qKh^{<(w%}=8faNa;z0@qapw*$mtX8RoCFz zl)7S?vx%!uhd<76gu+U5OmCcPvbe|1+eG%?I%+t)-gxqu-}E_t)T)GTW<$#Xh7GsD zuwbK-!^7$jnS4QE0w9_xDZyLm2#>sr5L zP>Wr)=xJi0lOvML!li!(<0qBbB6%JwQYLGuy9op&xdcZvXh4V;511vE4qBd|cV5d4-Z}wy{YY1~jYHs=cXD1wr4edC~5yi{1 za3BoQ64??g<`Me~sNG#_R#$WqJ7`n31U}HNWy}#N8Js}mLgg`Yj8@Yd=(yuSojYRV z8vI`Z$>_JuZnnFi;WU;{boIF%SN6C608PcaP*wNkZ84{=h#Y3jtLy--W78N!yjybs z4+?eg=VTqUajt#^+pnT8M?Y<{1O*ao(3rIV{2hJvPyDvKF9bQb|1M%XhkaQMcRGh1%`@=3_P4RxNNo4+e16 z4HipS_Q$iTnk8h)n`mlBJ{6sL@-OHV8U71q>dFVX35j$qveqEh(3?V8Z~*~dIABTNDBW{( zE0%PNlSZ_!l`kvV+@g6R;yHQP6tb?KfqbRKve8BuV}k54#B)KP7$L97Ax1RFVTUF? zja75qjpU%c3z+t_764*6;7)rU-ci1AD)Oo&a-unoRd}4J*DIQ=d*pAZ1>}#&Z8zg% znx!|*qUoV&9_^lnsA|NDq&7os*t@jZK{0V^WxM6ahHS3rkeSM`G=q4Yb4Mg{#Gyq) zgD)g{FQO_AQKl!C{qHeh1*_|j`xlWNeetTU*->Pfj1C-nIN9N;5%P{%g^vOrlEe%c ze9ePIwpDz4xlMQ1YjkgyzSPXcDBQL}`e7z%S#uvgMH{}8zlz367}1123mOb96;_Z= zWe-rOa)H(?@e&~QV?9epPEnOy3HEgUe~hOhWgJvsRj;s;*CcVT3*m3NERr>O`dYrj zYm1$W6k7> z>5ZB`E~YjjKF7Jj4ck=kX*G6)Kn}hq_>);d;8ANayqNZVeVNr8s=!x)>%Z2bzKohE*KM^6JX&{wso8}RZwz*uOKiNnS|y?BeN{|>#aO< z9HGQ0YB79XqP~M2ps$TpOG{N0Q0uEJ;f@&m>@$NC8pbGmR!73OuQoZeQ?xJb{aY^WP+#-62<8UE!!(x&f@m6ykB!fG~0fA znV9Vhrw!I@0u@(+l1D4C6n_E!9SI=%Xk=WWi!yZu+nt0*eJQDify$z}Z|2%>F}(Pdkz zgVbvHac$*=8#i66@sepJVoOyNXS=5BLa;GEBOcPXf1IAn2{}=+&YL%t&m0Ultp&;S z{*N9y2?mM}!pb0q$v4RjVbF95=4EF}b~P)M7*%Dbli|G^IBSb3t^wxQCp6L`@`Q3I zf}|u;SFPHmC9$Vv6K|P4g)wr~Juvn_eRj>!(;IA}0RWE&6%+CRN5nI0QlAvAu`%7L z+N_6SaNK}0H*az)8&7o-x#(lz*e$CZ+o@Kk8~Y$xWOa&4intHvde_*>xJE`8tIs8M zh0qpk(OJk6q!^F#3C~UvM3yh`(TJ(b*cbl*5${i@y^SB#s`PBS^t~@j*DhLlw7qjF z_MbT{M>zQ=FJ#1+{S-&5;Nz~<(AE2A2(z-aC`u`3Hf+yzb}rR27hc^!w+eaMienkhzdm~p zs)y*Faju)?@5Pldx=E(3iF__MSo>ww_6b~BZv`Ib#}7mPs3J)H zSy@XIPj>|vX3A(>s#l1qOwtNWp_KG*C5Eh)HRF{;8@o;K_eAhKj$S>LTHaIJl&4Kc zZO5U*+VC-dub0WP01eGI0pDoU)cWh#nYSqr_Gy`Y1?t$Q%wY3z0s`qi9t*#Kb21DG!g}l7&o~>zhngnM;Gq zmD^{VY+lPZ4`)*)F3s*qx5+mj1Ao0Hd4-~WFUG$+>#Mx$j={;mMuDqdpe&o)cwXM!7N$*jd4oI^gvTya-hOB^L@}1tgw3uR~qJi1Y*4Q$?d^TF_GQ zeTm~n?(O;}QC!evx8w+g{{SYj=u(u`G}}j(IY~Xa046+iA{k%BUS>_9w;*=H`tGAdfm zu?I3P;G3{${c{Gdo*Qth*CG)5wy7$jqtW@vqo=D{c3^(XGXtkubnGs{u=~{;-ry-w z#OL+6%XZ2mOo4~AJz_eHS6PkAfylY!6wqM_4MT+EgsCA61leb~$41eCmZQe?((zXp zcQ5h}%i@_gXz6BixAL8ndzA2&jiAvP9M$WT@~*q<^^BQE+&mxd#uUr+8(|&OTj1YR zZsOg)8QbjdBpG}J$MD>q?S}91cwbdXI(tjxMMWQt(b4_rsoBSODaMpog=22A%wC=B z@-o{Zq^x-R5S{IxWg07)*r=%f;*GjN@$MIQM7J-SkPgV|{ZNo+t0e#i`+2=O5>dR35gv=l-naJ+Y7av+I!k<>fa1 z+qaZYQCH6%-pOSbkN6{zyni%JTVD98{{Uwf9CPm`r@Q&5%_6VA^6o_c0FN3M{!u-g z?o{sGq?XMuk^H~Yu7^BbIRsE66lxnJ_7ua!RJEW&*`TX(gw@q%4(upW*U27Xd^Ht*bz)s9%+Z-D?gVD)=4*;(9<-GwmyQu;%(a6~$yl}!^x9zZ zR8&gA%x+rjTQrC%8$~v|{Eo1mzAhWLcHMT4&_&BvNUGV>X9?)DcP-b`WR^j6RM%wI zMP&BbHBwVuv{OyC(|vQUbB|7kOkWfI{ORrmekFbBw|{P+sD&1TF0h#&BBg>MxNL)s zW=v$+P@%OvO%xlN?1ls|0g>wB*D>T*S0&CHS8Deheb6Plm2p7UsEFlWdyO4?TIYS$ zTsMjCRaJYR!g0^njD4~H03Z}dArRiBt!qBa04Ys$)?`J-^tI6ChBBH-u_r8sgfU+j zOnXGMO`G?1GICeWHgNJuBs%TJTqb&HA8j+objVoruPO_usToquaIq~T;vg3E1&aC% zV!G_w%9%`Ia}o;fT|z_HDy3Y(yM`?olzgDING>d40lj=Y_`>M@zJ000)LP_seB_g} z_55jiT2fi_&Dtp8$?0t@`o5D$ciU!2V@w<@Lqv4h(rD_MZ=UMlYgm5Dhl;tXn(rG! zqpB@%lXUWxcW|>Lp4+0crBquvwjp+c*j3(+5^UodtExJp#jed!Y~y#X9$KCs@u2Ch z;y4+X;d`rwSiAmmf~ug&X+z4YCx*ri{5x43B69BRc0U}VH^1M6RE@p28n1#(84Ub# z@`Q{1Sm8N|{J1N>pBgMsKWU4?J%a6+@%_Udk3N3w!!#0}RTsn&qITU&%}Uiky#X&HGQuQm%9OQY&h^GCly zqs5+Uh(T#v33GK2Y{A>@(sU68e%yw{ai&=3M;lX0!}d8TvTl^#r|vs463Zostc!aN zn2TBtv<9lGY$S4zBXg>OB}+0xDJDeDtWjoBT@+cc5c(;rbfW}^*yg(%B405+-m48R zijMFBITb@Kj3P-L7vEMJm|SGOU$`|Kw!&(=Nt1aFte4w%=&b!cFzHDJOYuSIg5*MS z?>bb-Cu%w!)(g0>N(FoS8ikUWp{rNlhdIHXRt=v~9K=Ob)e{WJ#;g9%@*;hlIWZiI z$L!xaKm6F7{xoYnpq~uf{{ZC@1uyJA29#3r9@?pcHhX1(tmUyoTlB(Pa-(&NoB&;nSt>bd!3Al_IgA3^Bm{&Q@ z2F9eZ2^4m*u^hBZZM5AIa{<#j-4ZG9qPbPP36@j(Y_@UrOs2la=WFL}ako!$&NcVr z;?BEUdu@$<{{YT)*EQa_+c?L+IM+LCjOX~y*#5Y%XNHdgQNI?m>0S3Oy-8e`jLx_x zS1ia3X$XyD6^a{@MI|NEV$_49Qh7XqVvvw}w2?Z08e-IH#Mo~WUCQVaZyP%B>qn#A z)9HJ2cKVBSDl=@SB7t4{N}`&VA(1F~6?0b7!M>*>5`-8(O8C@vb4sH0__%mrPumBO_x%MS=RS!5{KOpD5r@VW0P(P?j3QbSE;S7@gdB9h zq5-6X+r1<=4i_9ji}0n)f-XFWQsh`Us`T&J+<=gj6L(qn)WRbRRc!1UKRf4OwltxG ze~WL0B69fs#a42 zL>4PN;S0p!v$0cykZe{j2=rDtSC_dJslvH!894Ti{3lnfm^(e+HOusfuB&$XLE!g2 zn&mYSPgOVB`zqSBmOK=O+U<-a=$Z`MI8z%Wf~qT~`fCbpA8Y>r!?Xh=u@gPg7ls&+ zL6cpo>NRmVGTCiDB?}Gx(^>?z4nmCM#@+eW3>ejyI%f6Q)tTgu3fXcaP<8S(;<^_M(OTQ&Ch@W@&Hemt&KWLu z>tAJ0#Y`2(i%J=ERm`5QHeY6zUBrO4>Ls#SPYn0ko`_WL@ZU}I^YzITB8%S-J>L{Jgv51MS3wD^rJUx z9Ot86=AhlM4&Pjpg*1o&Z$9XyF$jsua;Vk=v3p8TjIn{ z=KU+$mZHi#BN~FR(p5fb7(;gK+LwP1ts>1fh}U4SgI2C&F5^+S=rsNXOBz#M_jL1P zd*h$kXzEM8P7-z9J1NZ6i$&FP`T#h(-WmeHD&KDbj##^hlF|Nv>1}ZdAq?FFO z>x}N3O?J*T#xtLGG3mnf1-HlJExY-w3px#(!l|~Rx^M{*xiyUE<(aTV^eYJ}u#Ssc zK}#f}dl9JmtFyv;Tv(P3I*7nh*6sWV?qO^s5_8(U-WE5(8C5t`N1{39A|j&y0KPPG zdpVqPipulfI#OJzR7L3yd#+=(bzu){hT)?z*6QO;*WX06cwo^-t2;F%k`>t<92}HL z$d!3XMYOIth3Dfc&4Gp+6ICCHy=YiTY-`x_b3%Hv9#I&`8I zOu2GQ_muJ^6oxSz=aKGnl~sJkFl=bX#*A!gHH>3XtYcc7HLYt=8rGsBA|fIpC$c7& zrRp)e?Cx1((!)6E)!zqCr;M^tfa+ThoGUb4no#043X5#fCcCz8?u3eeCcrFX@)nx@B@((NB4q2I{e91SvkIYvV{{OBkM5 zavlRTCVGkJ+%Tgre~gSLjE)gI9@qHF&K2W-YOiS;jzx1F!<))-iOOku7oKY>)NUUX zo!t^$xc4cEpd~hz6DIhe=Gv`BF2d|=;Wq*F-P(j2Ij@p-A&R)bvV~A&Fy`rmctd?k zAEvJLguJq;8pMxl!$YOiV9w_U|$Yy*Y6#>k`R?e=38(N*nt7QJc<+iXRiABmAhSqwViSMQ=L% zW(6d~l^s*L4;bNA@y{qxIf|TqdG6zn&bY%@^0_ovp$tY}ziYAaJA^XLlcx>RG9yA_ z&uTP^C@7wf*(6{Xg8DUcs;H(!TL=0ltENqsNSNGSPkWZ(thT7^+ZFlvF&weZ;1-KR z2e#U#b`S-1#pvSx3Q~WpT{aP2uH#T)+jxpow9_8j+O1WuP zjI)DI%Dd&K)MPfjK!n~K46e1B3y;>2I5aiw~=Fy=*4KiN^w%g-Ivw>+sjmqFom9BGF+}=W>AQ0c?4;@VKap zDz_S1fT|&~2|=n5tu0+LixWag5)yp@ ztGG6(%G33Z%BQ7?9?YOV4znjX|}!R)V)j7-a0zAMbLD` z;wp%fa(XuKTI#^kd0><$T39da%LKy1h_Pp}al{)3cE!Yj^X;@CeDLHQ>%ZJqUsFbb zJ@LeSzd{y=MlGs(!-|=(Qzf)WBgp%=ZlolDk^4-D6DH#{eTAj*g1R?jDv0lmWpQ^- zh3I@h+>#mfUk?ulMMr#(b72E6zKx@Y)?g%7`gcx#GO~(d#*Bh%^4Xx_U4FRPaqP0= zboFY}4nC>!?U^Fs%0=$&Emp;8YSWw|J!whU_95HC%)8s#F$sLUWGWL8X<3Mhi6bGI zN+PlM;AZzDxU~3?MPE=^vmoTI` zUWn!@u@Gvm;q6}Dey07?p~tEF!en*P{gfwlHqOo(MToXb{{XR#S*&@p)iL~k!rL#H zYoC69oN14CKaBc-UZp=BpVU3d)PDQt8cHL^!fCE^zsvfBG;bkIOye2&Fs2g(x+!d@ z@sFt8Ju~sCjdtYYb74Be1Ia+tRdC=oZ?bZz+SwqndZ+EfBD=X$-?O3Uw5qehpd>3Uv`8eW&B>3TG2dR~{Pq1HXe$~-#?{PU=;$Zb?D$}SZK z9HYfZ&86G6+eFrF3xNbgl*U-HDyoWZ_5>B{VY;oOg02{}#_lxSg?A&-al~yw;TcFT z2Qi{reVNf_$+E#H7dppqqy5uf$vG>2To!g3Y*fO$Fx%#6NW67>FjY4yw32tBZ+55UxS2`mgmDKP8kmnoE$xSTDnc^%}(HY*t<;%b4iijD|-nUxoxFspBjR!h^XlmHPX+0A&U63 z4M1VNgl_M%u#Jz4O1@JsEp+EIfQ#_H20b||)A0AT1fI@n6&KpPKF^cev#`ADY0|em zjzcZAA+bJ&y{&_0eub0Gou7xhqJG@Cr)x0CU|>mGpri5loMe6*#Rd)v1V}+~P|ILn zNe@)-_Evz*ZwbeeuOXHmiYp@MTh#zrc$0;))k%qx@|(Wi(Oq`obeS_q=c>8xbKZeRxy#C`k$`LYRaIW@ zSKU`j)(%l72@8!#rZQK#9UO^*EhdlJHXweX611RJBM=Z=2Rw!wR5<4(vQ~iCea}T6J+I+#gI8C za3nrZYW0(q_I;{IJZh%;uABhGXp59(c*ZgY6o$yM8d@N*3W#@>-pVz2*cEWfh*v&B zAk{=vN2)4~>GZ0k#Xtn6UN{JdRp;%%+OPNbPj7F3boTtFxbVfBk#u-^0&}*cH`#xt z&Yu4OiyLUwefRf!zn}hVRXzUz^n3mP0LQ79XHnfxQ%5V(mW5|NuL9W2mn&SonnR7m zb(e!}qZ}(CiT(6=<&MVG$u{kq$i(R68|PSh#hdlrk0OI+FPw}=QpX zC9#zp9gVgqC9B7XG&dJG^-LOL8>?-Ks=$HHO;L>hSEpl4e}&5s`- zZrIwaw{RQkhokpq8!;+7S3_U0cH+rB9e4BWn@*dS!n#(YIPbo?vbwQqILk9qVTI_( z^ScIdV>^*uu1Llhh^&>S5wXS9DP@5Yj)-N<^wbk)&;TkHH|n!38YYzLZyy~~Fz6~y z?+;8p=783~$OQiY6UpPVaA|pY^y)(7bK%XEE-}V~oFM8#?c$k!e9+`vrl#Z+TSG>G zmq>W_x;e^QM?=XXJFbSb72ekuL)b|`Z3USOq%K2@6(9l;ZcS}K z6@_phanyv(^$~7GCUY)-d5XTze2uxVm`P$FdLzc99&ALc2Q2lE;!`y~dPZ@lo-UTbsmbVt<)OKKY|idE1M+_+oAZ z{2CH>q(Dac8>M2s7kHkPR+U_g?MJP954b|YE6SJvi>fX<@6HSKO{%Q2#F@!C^Y4QL zSDS~d;%?BBHz;V(*Ry1Ieu0dBV|$%kI3uUi*q%hkk?IV2)5!fHkJWI z0fcW6WeJ}LFDjZ7-Gn+e#gW6V&u<&veNf?aQobyqC3Pi-@`iY@N$;`rZAP+c8ON$*P?Xe<|< zsyX};&84fVZ71*=W0`AyX_K3X&f+~Oe(r?Aa2gOy{CSDG`*3g)XGh?hn-!P`OeA2J zt(B#n+@=Z8l8Xvq0w%?yq|90HD9vpv$sHDU*Jh3)(K|xk4uTCuHxiy7Au(Gd9p&Qx z0B;|sz>lw&v4mrWMz!pFT*tBPM=|VjD_qw#$f)MI6;aJpR8#=ZKrp{mMNSu4Yn;b5 z>~giuRC8R_R=KWf@{Ve!3W|z|sHmu@smg1iMQ1!6YF5?Vq8Yv#hO*$0`v^O2RdBwj z37bbo$%ZAW&ln1JuDUTOhBZ;xv97n*7}>z~OJ{b;JJ6XTu<3+iRE{^>X!+5FR7pH* zo!mBN?Im6`$Hn}6o;1~Vn`ar3mX*oomu_)Os znV>`MTD#I+6d>qxY$dWx_XQ_F3nE)KPg2ffWYkr|(yfa)*u80{+wZQLW8&X^wbNXC z@sEDnXBgKW{O1_Qzd6P|`OYzq^Ug8rmW|rMe?o2seYev@<&Tf#HuFj+V7^=&T+Q8 zV>r%npI>i6&&FSpo<{BnTl)5hyTMpC6+RiBvUtAW=8)+QknNsiXbC9Lb_8lHP~av> z>@)$Qz}u5#7{a3vHn`QKK#_h^JywQ$g5^7HmRw=El?CQAeNQ9DBC8^)pGj!g=4(#^ zS!=AL#+D$@gg{M-@&&ClbBwH2W07@UGsO}-`O%=*Lbiz(WT?^XtEESq3TS|5iIQVU zib8;+Gg^;DVIAAu+U^{Rh`ldM()5qlmrK(0y)Q|%=2{&FE4ts1OKsIufDJ;<$MsQ7b{QM{@y zzavNlW_QRqK+k`y#9*22$3Iit)b`~$_xz@a7p3Z}oeS-1@FjEi5wtC5c=UnB*&+7w zzi1mz*5vTp@6DKJ@)?@XtR`6`_;@#1`Sl*(M;nm+#ea%ICFDbKt#|q0^O11QscPDr za?Rl15v}xl10GCIaVgl$(rmRLIwsI;F&SPG)7)%YF8YLwNwvClp$Z_R|EJxW|@@Lv8kCORN@`8IQ zw=toy)pTsM`=mD%p3MG6+BJDLlGjzuY;`=oF5enLV)JmQv{U0n+S`_TgA?_~{>?9l zemzuaq1@t^L{7!IUBh|*09KT3a=p$KXQM<@+P_#x8bvi&Df7sVCf2HMZIMS9dWlRb zJU`oPw`e{JSVd7|S#N&n+-1cX1Y%o~GqvShfxa}W?lb}ziE^%<`5+ zF9BW8erWAhFG~~YeVUg)#2Cd8Cy2dboa8G4_orhrQ3XC3uC~@ z(yVLYdW?d|Bkfi)-zTwr+=}5E=A+t{c9M~=S3RiLIaN^e?QCq{-#THWaH_3i-N2Zu z_fdt2(GQ=p_A$KvbbNWYl{v?cYhm>lFw*t?BVG^rDt+uqSL?=)-zuFJduUch1p|ID9~0bI2HEU-83s8}-e5&Ua23^C#xVoxEVw=8C%K z?tZyHO-Yvm(d)mt*!d`nzO1s;VAWPC7Hv?%VnyO%b$X(0#cv0m91d-eS+nPva`HTa zs}sksvYY8mgGY^1T4Wb9UW%-TRZRr;HZq=x?yZjwF^c3*bw)0{VG#~d08Q>Gh`|l1 z_i+g1V;Y~;%8CB~9aw+BPc~w`ia#-g8-1-$PtE1*MLx=V1^9{5NiOzL$GEjKyggljut3b_UW`9 zG-&pTqS1>6EfGblHf>T#yJqPof+^^pn(L2$t`_%0JhI&#$j>(-TCh zNW{Ihm12;_zh;6HBr+s+H4%dVMlrRlYf&VeD9nWtEJ6POf;4dftNWms)^{)ScOA;V zbyZbgeJ@r0_L}bcXRcyQ~ zvS63QojBSj2v7F;w{{WAFzc|Ky*v>Jx zxV%_iE$#R<9P-Q|YSqT1u=v$&HnwPhM`o&Bw7e$RPB3h1QHRJTbYr;BND){ zO9FE+tY#Ke1{Z5aVG`481Yr?5x$ifHsHWxYIgOPZxKKLzXn07~Sr?hYWy4S%ANvC- zT-3$u1~CBDi9O}JF6<3iKXS4!S#GLtG4flDGBz)fzDk?d_MC~LmqQD`sVk~Fox4LX z41w=c)-jkA{-Cq0X}wT$OG9aun08+>=i1q5JPKtWs|Ubi2d7b41&d{tMn6B-vRyD5 z82u09?(64?MHdn)D1%uAZ))H@lMB|2o(a0esDV2s#HiJXBPOpDITe%522ZN_P$!J* zvy)&h+$O;=vNFzGuGOyF*giPy&S|XkV7j=e+i-kxd-{&lWl+nd5?7S9uBZpHAy6v; zSsW@J9IL4t2>kUpoYJT*XH?SXwSAJ-F=3Y4D(iJ;75&$|QraiTavCDgzNL1TCqswC zW5R9TVy&Q1DXOV-{o~R3keodT?F%+Z97%@vDp7C6N5>7QZ}FANeq|iVp0Ol+H zQ)1VG#52^a=v9>XO}|Y^&h0rvw#A(13o&Vt?Gr^! z8RI+ptxqjb3rRuZ+;YSo8x@$_!mpl$i^C?C8#HbUKumgC5MtwB9xotsS;FJ4EQ?5_ zN+B85#zSvo9vbx7u|uM*BgTzuGXDS=FwOhUx8;iF+b(*xu;QHQJRfk&tMubWSU~Q+ zcC30BV*W=%&fT2iOGFEVwiTp(Xl<+P%^~_x}JP)3r@~S6_VIddf9X z*i!38xLkF(4lo*X9h_9n>tm88i|q|IbP<5hA@@y8ZJAVZGj_&|$|E~7dfqP5Ng|c^ z2bLIVTdI)1sorr1R@pTBDtr#BmYhqhIK;{mN!3ugY9R@fMv34y%7rHaf{F<-RCz`u zWKA9y#*YUs{{UAAG94A<0-?P^#_I9B+8Vv2VXSQ;QF_!hgE~6xy^(FB7G))}4NYYZ ziX1XsAl3bE8DcRshKt00zK!8@SCFWFL~PNmtHBRQsZ@1I8dSpg)+Ny3b`Xcma^WP0 z*f6%l&&1yRy>wl=x)KzmqBpu5B-v%i7z(}!q>BYv5V^*i?WX$grhXmt+gbZ|HBzJkr}l0{#sQrW29SSNPVp8e))bA-H!27puc!kqf-#MO!ZalS~{#H*pv zSVe&O_z;g|c7qMldlqLJ%d++5ha@wg!8t@(!-n*42PuLJT4Foe9@J+8w*v?2UmQ|i z!is`zx=trh+Vqv5I3NsWil~FKc9$s{oWe%xkhHbKlT*s+#F5?*MdXdr$5bf0-G9nQ z2BF)uUWr55k4pQi)OdQOB>1MGnV3!fS>jb+7<%JX2ByYX!GmRkJtM0m#Y@D;)o~yL z8hI?)^zQar{MQq?;>|o;b}5GO&WoWzX%*)qa+KS}4%rozcsU?WsYBtPAU#Fx`dD~% zHED$O{DNU!v3B6lZDbX+zF97jn>rnf>yK%wLA_WeC7x%vOenbSPV1Nj zS9=JtvN$j@Fu1bhtSRu~CFrdLDDCv3F(Y>O;1?S~oJ>k*N{NeKl-79hgsxbu8{F5+ zs3Tm@0-mVPK#Xoe5o@0W#Cp8XYh#1oYOQz-NeM0W;`gU29J(=(t=v77ZoEmu)!RCH zHG&e^m0er>;}2PnB<~`03zf8NJ=260c#;k_MaKUCOUK5?{{Vtr#s2`SS{MHSiGNp; z^u1_peiI!P*p&$n2+HVKk1M@BR^a7E610lW!K<$)+@G)=u0bjt2;?LD*htH06Ij+M2DV=+ zN0}ErC{^lkr}u*FV)59JmE@%)`k?D(Oq!Qih-L!?Zdu31CG9iyUGy!V_EYe;(icnF z3`NlZCZbZS9>W);iGmA`KD#j0$21#SWf6%=&~i1?_Hsze;|MTa7pTL@Dx+pMgy?9& z`LzRh!y;@pD=C)K_FQH(Ge>NgZbm?Q7HC*zIzA-nh~`_nB4KyA|k{q?|RweJ4+QT;hd$gCh4Bhn7hb(a83YQgXDqkTS8zio&psBRZzCJ zLs=fze-I2(SY_&b^W$QDE@K!TUpWX0#hJP3sHvpOh;-f32{|=d*fG+NR27kgpX7Wc zSHzr-5rJ#$b@8iN`d*i>E9cBbvUo_F#-oQ0YT@w*@0=vjlNK!z-NUz!9WT0QHfq%b z)LFxYl+h$o({&WzT{X_wG-|qD)ptUzLwIVuf{$|9k=}}&)tvMh(}f!4O%agD_OK=m znlXA9yHZX{*A=YLHdEO^?uE7@;zTUVa^V;@c3?OkpVZ|(BIK@acFhJxDNc8&tGP~% z+p%k_xvX*y6_n(%t;QFS4N2L_hK9_))N$iXKDGOdvn)lnQ+Bl$J**EZG`B=s{AtQO ze>R5nX(|HDcXe50Aqus#>mv5E)c^pg>cGUJl1HIuk^#*zHqywCvk*t^yUOD6VRBaT zKhNVsEOXEF=akPW^%P3P@+oGmz1cRUM!fz~{H*NO4bYUA7tdWXPJ)jWGv0l<4^&gg z7Z=yUQ}-RLYpG-Wtr?zob*Arj)paRSgjxH@T=qtR>GQ~jBX69GtiQ5b$Z5)LzMS#^ z{w%ak76ljdJs}^_RmuZIw8W74wTqGEj5={5aN@X&kAcL75`3%8O){RyaQ)K7MX9oH zN3^?kSCPeeTiNaLw_U|x%zrnpj$3t2S}7>dkIg2^2vUZu4lLhfbu3is(p2utB+Q>A z-xVVIw40ldJTak{8d^JtIXV@?yrW6-><{F*7ga-9i!gB}`!?QPHX^FV=d(vBsk*A7 zw6bDI(cM}ovf7Po^|+?{;hPrvX;VKJKB0lOI|ePGrk2*`JJ@H|$za~qJ!S<>CM3L) zYucUuHM*1NF`zKxMoWV__>qX&6{@XVV3kWU(Pxpr-RqOR6;s*rh}SeNPv6Gg^D3h9 z*EC3}!}TluFH6$(%Wj^HV-1=W8w_4Tb@Bqj0T}$rf=;&1t%r*i)mOwHINMxpwx~2{ zg3GJ6y6v1Mp4rB^&++Syw~&6aJKUX{fAsN$)ok9*p1xin9Yx)`*adb47V(PWKb0N) zJMQRQC^$C6);})H2AGe2mJP)@ z*{<6mWgU9i1(jWkYawhSQwvDD6qrfl49GG?p z^Ns8}Vf2%H`4ylQewV|)$s@#oB~(H+_>oA@;7VhN({2r-8cb@TKbFN$Q6&*mk2zbw zSih8Tg06c06(lF+zQodP!*IB#Bl8{m7_v=EaQ$FoA^c|<7?SnM-Jxss-nQ0 z+D>WI;gi-q1lg?i)jH#>1g<{qGDAghAK5<*d;nAohr(f+r5RF ziO0uPZ-ZHKdcGWd6>4dOl#H2k6@13?tD=q`9~6@d3q)s9!CJ*eg#;=_%FH~B&@v8C ziSyu|P)HlNOoo3sicYn+ri301uq^n^KNXrt+y!zwL8O{J8%RSk$O_8n%xd^0x=N|_ znZ}=MH_Mu{nvCRCr6CTCTULA?w5@MTuyMJg!*-l9sUs6BA7z+{V^3mnGE#!|y;mo* z3xj2q<&!7_6QWXywLdHnZtt|*Y4hm66`c89#qAK#t6IT*X7ZK27^k{-64+oykXKKP z7dZ%(%IYVe>}gV#2MNW@t|Qc-9WpT^F{X5zPvD%kW*kmT|=$93l?$?I{IZI*W1 zh)-&Wy_Py`dJ3Ix;F>a$C-rTscy5x(y5d-(#B)qFP=t-aGCJoZ-;ItqdAw*u&$T?f z3AIElfsS*Cg)ePdu#0D{B;e(9)J$|ic!Q^eUkyW7<;aSv#?NFDDU{}WtUzMw5}uh5 zR2E~A=!iI;j2DnD_N6+;zpdlZ9&Bw=O6!0zI7pdWdp=n(%Ju9_WQns_yMU({w_}%X zh?!tbc^0buexGO6mWcd^?l#oXqVL&!L&vcueJurpQV7DGaQ)8+u1e1%wjAu7&!OT? zC5Gw=``P*vg3~(w4>^!aqwS~hBb9UlFB5?=Dq;g6uk6(o1u>6COH+e6#=`B+0;p<; zWR8}sI<2=a3OL=|#al929A5OaF%K$fSs{SY@du8C6j7ha`+Pnh9U|aTE8;RUcdveA z8?ro__NAB-x)o%b3n>)=lE9`T+nT4Tw|dN_6_j--d<^B-s+Hf*=;zUxhOS~Gx9DXp zEin@@CyTA3pe6F5=5Y77lYXYXo4^IllB`8NuHHx8!Hw2j)6G;&+Bc+Ku_n>cA*>2A zpspv4BH_O7?cn%oa!f=Um`q{)LH+O$G9yhIBo8O=%jc z>#!VeK7|pBG@Zboe$u*7yGq38;hH2`H93(7imwWvwOC0=m0?m44qItXyCUJPZW-j- zXay=dNGX$Nw^^dBJ0`gomq?soU?XT&$NiC1o-2PGpk!5G6CL*nsv z4Am4Ua!_i+@`Kpc9fJe0Y-KCCQJ5hq(fIgNT;I*ED`ygGK|M6Frc#PyYJ(K)`gu7~ zxX03a27LpQP7Icg!_B>rs$vrkd<(;1`BLl)67Q|ACuLy~+ls9=oQ5ekttc*hrsNA0 zPwZ(Tq{+oWRKaw!n6_yi9w~@>IVp%?;MFt%fcC*<5^?4YXN6y~D*ph(T0fB*78Mm? zOyAXoa2BMC+#w|_BsH{5#O^~4kINu(hX9u|5+!BI=X2H}BqCgd`ndeAZ7_N$^H<~< zNmLIa85)Ydz7)HCzd2qG=<5WUO)5L|h@tIBzIBGop;oF}ram-zcMe?W#fUjOHI$1< z)!7YH%gtfMT@qp@Izcya*5mDNg1k-?b!ZBJpUEn#dSGZ>D5@+(IuTuNQFG~rscX=c znA-l8BF;kiw2*wZp^L&M1Eg{}e1Vzt49z9)P7W9BT#j_BM@XoOspmfJRo6Ogoim){ zUA@`HJ^0VNIQQfD#@O3m>x}w9?tb0SZpI0b;29v*)tL+jNA&}1T_U<@p2;<~u{)I$ z)mBdwd7*2S23HHhWOxcjIa7sY*0>%~PnA=8VSK zzY@(~l>H}aZHJ=x%-Jbb$UA9*+U-@G8}O3 zjVJ_3Kd19NVq@AttD4sV)2QwOAxVz(b7VlD9g4n|+Og~fuO2oH)Hd3M&;IdKa3+`~ zVu$9q<=l2FUX6005;dK92=JAviYakQ7U@11xTRpRt8}Bu&P)l)d_EE&fy7@8e$RRbYi|YRXBmO>a zytPWD?jB39pFB+^QVka9N~ElXJT33}X}pc0D#_vQHuq=!Rru!4asFvz`1Q}%$tQ}V zmYmJMTXCs8R-G#wE|lc(kS1S47n{oCo8q5xwU#@B4D0)cm?&04u^`>#g%{$wbt6##?W$v8 zpJ*l~KFp1WMmM&ubSGq|2}~i``K!^`t^UEc>lO{>F)VQ|qX0jtaVb&;`;2;H`D55t zqeinUOjfyT?SLl7m=$UfktVWC7}bfn`%{zcW#KDsqrCN|DLzen0X?<$(b|aQaNMfo zk1%X=Qd|PPOB{&hV~-iZl5T<0>u#y9!KWvlS+(>gHn8Gm5s=HKamd&;Lo}+i6Yii zFYf8ar6V2vk>*>!ekJfCjb1i5EeF9=Su#T~L+-&1upB@v?`K28#n2hfuK0$vjD6(< z9I}wqGCAF7<+h4$le8WP{2E#)9#UC6YmIeKW40@{S8aYq`faXpTR&%8!M7K5j8CgN zKEplHqb#m}?+fRcYLc~;=_aUNMqn@)Bn4y&qav)3i%m9`$r#!Pf=XYfCqPT^t(mZ9 z403KwWV7R@%UuIKFG1xm3B1gf`g{5x$ug*GzT584eMF{A;c; zjgnbC^N-_gw#G5;$T;wI* zSi{#nn#;|p$=MRZ)#B9F&P1ic$GoXkncsT`*ZOWHqC91DUm8#iCju z(UT_WHE7iY@$S(U?U2zlQA8?MFV;J>Qp9O-UQ%^KL(Y?7I68WCdj*+fv zG0#4aVMA3WjN71x+iCqGTH&Mj&Sy1%vVU>T`#e<#nIz*~cRjv$G-#kYg?Y@ru<--; zUkP~li4e;oI%~<;A|1+-@lfMX5bgQ)E81y+<<~-O>rY(?Tt`PV%fvjt`KO=q6<29?b6A&Y}K=L_EmQd7guc(K?D-hbyitj z^-VPO+kN)eU2~ioHA`+t=UPg}_OiNUttU}cRh2X2yOpAm;KHkTyg&>;_Pmm_ub{{_ z2Mmq3i8Y8648qQ`W2?Pl5>~`|wUVuzxfbqD1MKz(^8Wzj>ay`s#*@B+l{pe#)G*cj zE1WAA=(&ESmvfUE=XmQvLzt5a_eca&Z8I&iOeSPD%whuG3=BnSsn~!sb)xWN+B7dW z&^~57+jSJ7j7k&J-RCM59?`pE8%-uJKxrno)F0&O)Unhl}_ zolVI`Vl}y0dNr}=KOiBz*?A|8T%JJfX1wXguty7N6sg!qjG1Q)t4ES%>uTa9wpMSI zEc}?LwFSmSIz5!gw6(JAj|!T)RlU5%L<`I5 zD(c{jvg|A+Ij9J5z{e6qf(&iryOjOo$0U-lBkV^J?P55OXvW@E6S?GiqguxE%bct9 zx7~DdJ)2$kn>I<1?He{t1a(UZYX1QG;?Jus^UZpO-%QhRvuIMOBsy#8=&?CY zD!UHGY07BzSn9C6D`rPW8eP#^IP95!GS+({#B8LD83##O9;UWDNbYG9wF*R$|7s!jFoRaL{W696fg31sq-W*G+cceYMj~HO|}bzHzR)>#j4Mw%csy z7}s5KjORJdag1Xb&U5bd&ZpWy^De`#=UZ`KFV1jZm@3n#KD1`>hnoIBecFN)&dr&O zDA#=NB&usSe-@!v(M=;$N$O4}Oq)mpMQa&)yMB;*T+2GG-O8*Mm~xdvW6>emh?NUoLZ>B&=;^eVnMj7uN!$t|Y=Ic^tkNqW=KnNOM(M z)nCIHh@>mO3{Dg4a~j}t-?Xy68ZNA7>je{W!xb0fs(5?^tTU6^86tp*K?Ud^(RcpV5ckR z5~S(YwW|mv(~6op(mMtTVGlP53vC&(DgFB>|2OX7R>_iLo3K3Mo;@7r?S)Z27tswQ$uJSde(6M6Cav9v166#n~9`Fy~`o3qf^JbOd~a+>G?YTIV5Bd$XMG4 z@yPpud*#FA$E$8?gk@JVk5P$1hwY8RHihxOA5~?eTPSpVmG|K@3a*5OOyGK&E-k9E zJz-K18p>GZ;8`9D11MB$)egTc6#k#%PC^DFsGtzqF*r;93cjON0ecEPVowRpI!-Gd zoXBYV2;G3za$09zz^4+~lvNud9$Kq_Mj{p1^F`~q1PanqU{hcs-^%3&NmXa*Ba{tr zUbBVRoc&)|&Ld}L&#XgDj7nZe)^n25*J5LB3cf{)VeA!h5+x1{>*%ocv}9|CPVla+ zKJtUt_5fPmHDJg9Nrl(4D*jqAnW}o3bNQT>t&E`xug+boZ(aRQNWY825?&lRUWr!I z*AWu(XuA5W0$nN`XG81%03n?N)o{41CgK@SU~EG{3C5kmIdhk(nHaIb2bUZoHri)Q z(^d4(Fm_Fj5LGJuQ|iHYCHC`5$5b#783Cq^S~I>Yf0-2MXyf``If{;_>6%h2z>1+w z$HKIff|NU%G>pS5$uKCmvzEki-=o4rYzd1^Oh~^oE;1KCD(N{al^3#Dr_kK(6g%7g zHRach6BDK=+a+E^3v&*S)odurfIAtjs`d4l4-BKhBXQ{CkHnRd5iG9T;!5ELgruim z5-;~c?g9Oe4DuCP!sz+kp&#gITp474BIlWm+$E10i92ua1bsu)ypa1=0UkHkI>t>d zRtWV}w9Y^fRmL;0)w87Cwr6e;%wivUN^Z4Uy+wr9G#1Y>H{FZI+h|Z=`EY^qw;xR9 zzEjxP)^Y|(D3)=O>`{6AJxd0SKNhjxitC<&B<3$OCYR~SEC;}l0^Q6_Q8+*l^LqIm%lNSotkQ@%pdHtb+>5uUyYF5 zxY_kR^A&Jj4rSwM0f!XN8|0L856Z zq9uy1(MKa+WzN-nJGhVE?qKztj?K%bK;yd$ios+OCh9zV=@%JS41)+)e7JPJ68QGj zvs|pEb=!TuKX!BJny(;TF6#L}3>G?<29O~Lh-`4k%YtlA9Xn2;+6&%Ye zLCzJpmi4LVY zZN@r;#ZoMl1wL;~1G^K-kV@x8Bl#n$ZJIPv%c7c8PcYFQcm{W_f{IU38e}xtz2m#u zYsENFmKfEE1l#I0dLkW-`VxEvdZQ!SMq;mx>a7%^r=^sr-wC7iv-CZ?o5uwQ+`=0@ znc?gb+5|OGkvoDe-3JEPvchjRXbM&h%FS3!;w?!#)TV)*I}mM>$vJNsmPQdYewM_(#&t0d za`lU{G1!AkVELmzGCcM_%+$oT(Mh}2$89Ef=Mf01YGZxUMdpNEu_L}4ZMN*!`DT)i z@3TigF-Hx)SNG}*3+dab{10(uzZa>u!}44{N~5y2SVOCzNap3OIIpaV3QH=RDCq9! zvR+V30+J-?env=&%NUoqJ5#wh{dG@b=K;%F(Zj?mDeSNESyG0rS4S2*O&VqB?4cD~ z!C^*HfSrepAz0v@*=}d=Z!o^kVFB@D!#3&;4Q(Vvs!-`EbJ7~DKxNNr`Qu97Zrf5) z9$uEplrB$kq7H?31T!ljc0h~<#(FS={{Tkg*-h;pN|4yTOv8?zL8&9%GuuTi&V8Wl zdk8B#DgALXAtPQZ7zL^08Ou^_;Z|Yi`E1YEcL{3(^n0)-3JIPv-ayEwo_5FoiBiqN0@-`#67?wR`@%lKMnS*6mlLlj}IE4!(x~GFhFsyM#&p|qD8+iUu z1c8`WILq2U()G;mnR^e~Iq}&M4JD-IsCh!<{S#uSgphY7>#)p#?j3f*QE1#zAYEZt z$A(6m4lE%Z^&M1)#s%t%MA7@O*9HcI_Rslfp?478$>clpm?i_ht(hg_Bt+bR2NPh$ zS2;#NIKbMLdmU7o$m-3I_K^8XjGsSbi8rYX(dov|&Lg;3E_wr>49ju+l_EJuJQWs^ zCC#imUD!yr)$Av)shB7K01WW#qeYYgax(>wMQ)=M+UfPCbbAPLVHvB!jz|a>`=U8G zLN&aiwNX)1lvGqyUKdi&$N`Z6y{BIWuZ@)&9g@_CVh2UpN6m+}RJ4YdyMO=|n(oy_ zB?z24OlVN-bl)yXmLSAyB$s&Y1XQ$ETqBR;Dr=1Y0Mnmb<-E~(xa4cQxqMdjZxXvh zqhy?+Cg>B#+s5J3SVXo`#zp$Qopl#~nZytzwYyXd0I=Vi`dX74O_Wv z&*eQ?vzLl)EpjRL@^?3`R*7`wcU0p2t!C4|bzGNM3NG2`*JVSwViq8QQSDBA9g*i}8h zoNuqY{y%;({{XlD0Qd3gtbWWl<+F_WiRhU}JHHL}tvk#n%kU zlOn2!_lRthWkj_}YXUonVGW0s3_^Rz#W>wlkmlGmQTL?DPoy^m$h2 zE(PM-`nxx4M;rB3+ecY28X~6_;i=ieayisUv{*%kdOVnUD^M`#qk?sWaN8FbR?8elR|mTWr!N0zuCKFo+ddf@}M!UmKEdK!VH=)Zm9F`4f98rcB+1rM=(e_E<1UAm9 zZsk2w+ih&v8`>qAI)noO2jDr3cDg`AR*^{LdCW#N92Fl;ENC^LAPj~KU@$(7u%5!( zu^!cr(B-KZ4CP#6DZ1vtynf?hs6P+t9*}cZdp!}-&@MW^w9Qi@0haPKL z7*2sSr?ZUkneTLSBZjQAKZRCr+W7F~th~`pbzhw+7Y)8VXCD()t0=my_SfJ2blDx# z&Yth%;rC}B$Gg!_lS*UI(C&}P%d!d~p18`-9;@(ao%Y7rO#~Cy8?Noz+1G7bvuKj; z-0zQ;-4#^MHOMOBk1n;v-O1pt(6Ei+P9BV!6EHelV0#GM6l5|*B?v^+qD!2!Y_lC0 zN4Jx@-3&Eg&{FE^MBw$>INw^n`EB#pKDo`vDXwFjJ=iiBGas4VqrO{I9en)k#n>7v zMvk{`7CWPCDue4Y2x}yfJi-p5PZ+Qi!ec9@x-N@%)2UvhHx8)Sv+!ZJIKPpY%CL|* zaIs${yrq{M))7WX(q1yOv7rzwd2HU#Q(p>HHk`q3!BJa5iq~big_p{xCPe{hVaGue zBFY-!4dZPsVH}>GF$Ctkww5X=aYjLrt(NDE1ehLreEpJ>x0`WK9-LH2*GQ9!UG{+2 zDQ@{DtLeKFRpHs!a!%SL zaI;OO6D>o%Fc!0cw_8=_He9ntSx@O=uxRQ;q{p4Pbjh+K1-emZjZ)Kf(`SOk+*}!0nwrQ3PC-Bs^*xsP*eq6_GXA z3)&%A*b|t8Nw8|kx`4%5Qh^O5D8o@)iq8^@3Y(c8kJ!*yn~%7o7!+;BiV=79$cRD9 zt(wIkdKdD5gQyG z&Ql!mw<*cxP^JH=O19q)X4_|9@FqLiExT*G#?^Jkq9(n!{#G!a7Ca&nqAW5_FdEFUMdtCiTC zxsYrjRhk_0asL3b!aRfWtxq2=L{k3%)HHmiUE}AFWv{uwGz)s}hGO74Cfch7*z4F49wY+$D+F?q18ycVkTNsU5$Tz% zMly_6636I%(~U*cf!WjR!HiAYO~hnTX}p}oK#MjiCfn_p*)t2rp0i6SC4||hyOcF= zvlWxmEnK!+X6T*E(V>~cEBOqD$^u3*Hb%zJ~b;?U^nn51q#EdsLH3?Nhp zTeVE6`g1yJsKRE78z@%<-N(;0bkwYNIoj5DLx-jV%6aCm+|bx1IL4l>1kTSbH9kr_ zDm@;L0*;L|rinj%<)VqJBrEi<&L4DGvV}^xjJAotCeiBptFSG{eNY0uoTw^oPt5F1 zt+24^s=+?mbWFOolF9JU9HBtpULeCM3{mU+jmyzw5O#)LvsqRg^%LWQHMAn+I|{@4UOhOP$68L0KN*De=Z-G1zwSy}>WbE;IUT=37K!ywI(1!;RKyO!b3L^5 zl|$=$j?A$o$h(b+Fp*h-VJ~4v3=th3eJoham{TGk7o#|1ra6XJS3>Oejarz;xiwp$x*2)>FUvPMIzI7A!LNt zgi7@eXwhk$nwCH!boD?Ftf{GQRl4c>it2>jb-!xVnF|UG{tPU9&cZ9zMr~NEQl^u1 zDai72Cc!0h_?@#daSjrltrUz*3e}+{&|9V(HU9u*4(Bq$UjUu3lu{y2G?P~rm33}` zA@HAwg?qD!O=l~Z1W2x=!@k3zugRig2xX}?S^c!2$B$rqkVggQ3GrxRg~0J?k+)x?Iu7s`3424pOmhIz!CTxy>8KWEH+|knoa_j z6h-TOx_|TsCjS7tpZ@^m7N!S5AN9G|@BVa&{{WVksRhcf=7PML$I3#jDD^_1&~OKm z*<7Oiuer=R_2$wMOeVlxO>CP6w*+~yknfakP5{)=BC?Q}DTL#Ng|ID_q#KtaQ(9BZ zSc_Ia(wzBSR_?ks17+H?c&~r*bb1>m=F< z*ch?$?*cL(C-L|%+kM}Z{?GSSc#r;{O2mC1?If8cy}0{{R4YK#0Fu zjr#up>ZWo30PI#8oILXijn+;2*P0L6eCrpuE$XVf-XkZ|s5zbeQ!0%{ENJ|`X;BgA z*sZc=kpNOoh=8*FA=9fKI~g=awPMK2=C%SAly*$d_17oX-EVo@6FTX2^k9cC=FP==cfb23&ySB}cqMcGk(0zHF1DC}eUt z_lV>0pUtBoGj5bZH z;mpcz;j2AV7dP1MWfzbpQqb+e(xOHhIV_VMXCGqiq>+}yB7+*}`O3?al^t#GQKV#6 zr3hsvCkbz^0e~z`p4@pYIj?2oVwTt3!hkC&5qxG&$fY2L*ZEXvCo5cd>h?5>=C(kc z!t&&6bvIS-R+$~Ky9{Dmd?Vd@())5-lqP(EXjt9up23C0wM~o<+0?NDC=pQ`$k@cjwkI%-0Y5dG5@o4f<1mqj z$&Ym}JivQ~ixgrn=d97;h}d8D*$l!cDC0c>v>T_GWXH%zbK|(3lGD^tw5E+1@`B?I zU4+yN#8Dj2Rqvqr4*RoArm~hOX5^Qv+hfZdc`LJF2#K z3$dCtTMr?!##?K%jkRI2%aMz}bb~@{h-kwq7jKkOZtW2&ra(bL?GbqS0app0*|eO^ zIV=uQF0Cg()NsdgAjlGq8*8rHYMB7!v`2Q!EWzFr`eNY;B&z}q{$nys+&A4sc91sr zVbAY{VY2%YJq=pfuFH)g9?*^oN+eXn7VBu`$f-aOx*!0OYnIWuR$pdm9BLIs3!*uK zZOgh(8aoZ3zXj>p4lX!KDGFm!U(v0GIhJC!DctxXpA3`b)8utNL>Qz^ib|Vswf*3T zXR%yH=WRYC8=GA!12-Qfy4+l1OXJt>2Ht12^chwynPTQ}g?6>GmYy}vJ$T3~CPjQ> zt)&EsEMTmFU=c>r+vAI(?Oq}2z#RJaXm@J9z}SQ8noE+~jC&n^o{mVq1e@l|w)qJZ zQ59Og5|Wy?aC32l2MlMKOXO81K5aXVQkcRjgneIQW^%TpqxlLqFSxp0NtF69|8gArpvhFgwcPa0HNv5J7BV~6@{Oo5+%DV%bkuLKt2ZgMr5>U+4 z+g;l(LF;Tc%a-}~<2&uLE!e-+M6M0GekClZp>LlImh8dUdR@ZMer6dKoi$|DT z-}-3Yh}Rh&1r2QB%u~f^p3&X5O*hVfHx4wiiolWvs%I;neeUV*pA_E}%E)RwVXR}`juqZIhO6$n zI(;Ix_Dz#RMyX>MO+7u?$H9;1{tj{O&;Hzd{{ZRrqv{KNOSW;SUdmW` zR(YAh{YPVWl8$7$x~k&Ll@=9cU1WJsK=OE^p-N(@ffbKrIDs2RO8KVL9$) zJZCeDI+B{Use2Np5ePz9)pnxgq8>ApRuUBQqDVSw<<4Fj8MyD3x>zcjrJg(yqrs{l z4#-h02_*2Ics9F&NQ(&u#R0ImvGc8C!xC;0j>v)*^tMK|(W_0{4AIWbwnyfq#a$ch zu2%YGv#wLzy!lwAE2+ma*)C)am^F3^G-gmJrs*ZB!i>g-yDB)EOJN09M?_R_vLrIs z8o6{G$sxE?M7;6Cj71X8!?%%1X;gDWYosdJ3e_j5<2+9_FU*g!qp+82My79%VJtFP3p)nQOfAXKOTo6aDFMJW)oxa zsBCa`L0m3YQ7bSmIs|fh!UQg=#7&rT$ZI5%MI~2NXHJsQG*VSv_tiZ&+g&#Q0P{J* zl+FkU4K^owN*Uy{PqR~^Q#uhM3~_{*{Z#bJpm2wQNj%$aH7^h|Fi{q5+&<8AofI62 z7^9xtZvN%(_8B*BFgqE)*dAeSxQ$jLMPo9T)+LyWGGRjm%CfpDpHV)<_`W*yhaL+>4i#lB9X)Um5fSBhK~G!< zJkB(uAxiVT!H)pDjy@eVW&D2O%l2qzB}y^4tHF$1EvLnm93V3;4ldVCwZ=1)zT)@$ z-u<;x;oDs`{ZqCxi$XJrBe?Eju8=-d8=%`4OyjXxZ4@SAJkrEx*fakaYTq4~@Q3o5Ju-0je{KZgrW zInHyO=Q+-E>Uv7Ub6VZMHb=PFUKNGpQ!VSo3ab&f$ZZP_DdWv7(AzqF<-H>erWjfP z)0RjCF}YhUTK@nOXD33vTy8e;^$rcUo4Z+N;^7sWdyv@`*+wU~l+KlDQ)7%ntD6?a zgAB*=sZJbevprF+=BZ|s{#jAVc6r=5%k*WuMvIB_zOu(dDk%GcWK@X<#z!`i5q~Hn zCd0XM=WpeXjLu9EA8hlZI*PT&oMas%A&5BwMnbO^Bb<% zfmBfuqm?MYd&domPR|7Vkbu_jRWP(_Dv_y6(SzS)Kw>X-Y{|=)&D=kD^)yz-msNp* zlLt;#bDLgrv6-YUCc9{i0y8Dh!~7S7L{8zR93Bwm7dMjD~N4+1f-q&BuGimF^@@&?TvLv z1aJgwskwRB;OsGQ_H@=&Rn)R$D(m6bwtbZQS;-DCqx#EB2@X8#30@{OPcm6oyz)w~ zDL865>ejUro_ksIrPk2hjz~~P9uk52cHisGKsM=;f_se-;JBPk1CoE zvsCDDCweBbN}&2`%TmtWC%&$>TkDvrd2N}w%Krc_M-7{)qhy*VqXgUC*2t`CDl2N~ zWGqW;n%*reX^Gs|LllKnkt9S!Uc(}|A!E~m4W}W5=9ElwPH%_y&EZ>*xVffvxwQ?* zw)bPU^B~;&ylLn%hbEm$!M>uFY*H#Dn&&l^R&szud|76zhg~>EgFZl?;WyHZQ#_?- zM8#t=7cuk}X|aP6SiA@2x=!$CZjEM`V2kpOpS__pdwo(Ue97%vDiM6KAX5_uyBGbCm*M9);+>bqFVYQDqjKv~z7>$X$m8D0X$7ACXJ6|7@#oU@AL66JWQ1j1TjBw>4CQ=%G zu^|j!H2Wt%wyKqW>-f=3=^NjV;<1h^m{eUErL$o2Y&cv$Xo)(iWe;O9c9&OQ-4pku zkCJ%014gqQZixcrn(6LA!?8pcYn&vje0tcf{;J`*P+5I{T;7v+0D6C^;2jw_lFce* zgRetIYxsTq!ZQaXEF7{xt&KEPk4sAi%SgqxWfwt z9_U47wgnAfLaQ#J3n8paLm{<%f>D>C%o~8sMoXus?l?RG#SCJ*m=n^sujVfZ>KaR2 zz$`dPGLkslc((jrzKitFHS@JYY{%}B9Wc(K#d|So4o_diNSnE)D?;JTQr2kAq^+Pg zPqr5AV=`#0RI?`JmPnLYii1?$&U9)}Tm8S!(Z1TFE-DP2iO@NN)O_n!Ok?pnxS*4* z!cyF!RP$`a;CvY^jJ_a!2$`uoVXm!|WIsjOG?G4QqH1WoH>?qITcJtIm_+TM(cP)H z;1w%p*Be*+xI3kY#DWbNHg6!6uv10A<(u3kvAv$^??VmrZnH7T5qYkq3p>gayA0K6 z4n=?StfETJB^S7{6l+_YF(8hFOscrn8tzLjDiBlr8F;u>a!2fmoR8`*K;e{LLf%mW z6Sm1ZYC#W>I*Q6Ds{|a4mZ)y*IR`?JeBW0sQF`BH5zg7pxK*QsTxtCO04b@a-{yro#wFY?e`4Vkuf8oyi!70)@dcJ~{}f^>Po+k5-k9ZKZTUOVTD2 zCvLa5ar%j$i*8;olGs^H+u~strLKxN5@kfI0WP6dTC&JiHSUjW`Or!R3DZ7U_{@=C zAcf10ot>yUg20x%t!;T!B7I1gtH~R#AdY3Ph3_B;<5uKHw{rXta*7Q!+*ZU!s(g0q zjmzW`dd=p|*3wXK-+OHf%{#9@bocA*@qhMR{KGV|SefL<_R0R;nUH=diPl44Zfzg_ zOnxuRvg`04_hI(`0LXvb Tq2=M{#H!Mq{{UmLu>;B9LkYv&E-5o?WkX9U3HTQc zGq=T|7N!tba>#rA`npea{r>!W{e7F?(|2xWtlM+Vmb0qmhQ#McXsEoY79Xs#KLy#@ zjC^0}sN!KNjz@F8eg6RBh8Va0t7ACP(Oz!F6+LY@Fc`)aY&h`PVp>FN%Glyyn)kJ{ zRjqTH&RmW5MPF}iI-9Sx-w$2b+kR(7ks(^)7)l*ID$luG{q1+pS>LA51w0gt`0q0S-&jPDe0q9k4}$48~c zG*!tJpEztenZld38B9Ofw)o%^8gmwhSkzZU*o|%ya%-ID0Ol;BE+*}CIbGIM zD9ecHkc^CmAc)fOyI}bw3NYRB>70*-5W6v5M4L|nzrhmIB(8!ni0_d0$P@feYfScNe5E>y z77Z?-iK~~aM?IA36+qU_+bt=9nqAt@7%bJhrF7huiMoD3qgD=g(<})qyL@br=g#w- zuMOEejXbPENkq(So??MpWG$gMh5;OEP#BbndfmLOo0Jt?b94wu8P>3nT5MtKNdExO zLsP)g+4_g0uCX+?1vi#eQrrGza}uS4!>mZ{eP5gj2zy`}KVrWcR!-$-%!W!M4x(^q z7*TAC%w?%8c3*{LG3Ir(ab-HvUX)LCEk5Zkf0|m=CHqa7m71VsGDvNyFRpaSeIm-j zX9?EQLeex@ps1aPr#5sxIMDl-F%Ztmk_IZxUx>+d4 zLh|vcyp4pOT^=nLuLe47LqW16vY9!GiSC=m%+X}KW{y#hIc%aIT18a1P19u+WF6y| z3cGwJWvAA#H%$jD$}?+|aA$NIixS2V>2gHfxNwV1k7149CN=ZaT)5G?$h9Q4o2`wJ zYOAGpLq+k7RqKw5H4=eUb-J|jHbhEWD~QRak6pDlD;*Kic7l!LOC&p8!>=Kb*Rn`3 zmySjKv8=7COB$I(KqN@>4-xWB)XM;Bs=P7Shp9!6Chp$J3g}`Ya6&^8!GLEQv$>2Y zBTjJDRqR0#7*VOJwo9OHpRMb2{QIeq^%?SK4(69@_TvaxBFO9^xrB!cB%IuQ+rv(_2k<(_$So@!mci$*}H`7k5WzW+fIfHT0SY1}QmU_6}`u zMdWI+lF4QP;{(W=ZaI+0Dj^7GF^VdQ-7u8hLStW#%#$$Qq+$OcQkQqF+ zTGOGq;PW>#*go43jy!1PG|`dA-{nM|kJU%YH*T8jwpfc-f?s56%C#bVW91Vji$*@S zDA$}W=d0MM7L!Ej;>1v0Wi{T%uIHnUvPC>-!z1-VH9d$m%VzGGI@=066}#e)O(e;Vj2g5MZa!b~HqCqP&WF&%QzjF?bt&*HI(8$tsL5Zqhx z&Ek3sEbM!S2s1V%xO48e{W_*NE!mLM3jW`MNTY9e7bFCJ4*3UR%c8o?9gTW|EAIJ= z#x5J>yT--`iguFu!Wy?zbk@RAyDHkC3}L0qwx*AFs4EnV#_Z&@W4^3{X+)Ij)0k1D z%Rr7qf)xfR=^MDEaL?j$M~h=_&3bO?%E_Ck&Z8!Df4ujQ;16|ii)wOQ?dDB+TU!#e zc}6yAH<;WJK71GhjAWCM{Ke@OD`!(A_8R8*S+jdDwtR&%+65sU5`v?zZ^&_uD?BMT6JUU6{5?yR77bl`zwH zY~>bP6v7TojyG`CVhoyS`*H74MZP^A@2ee#zy1QogPpCl$mq|fcuPVr;M>j!2 z$0@1P*Za0dR_JWL(Sy2YDIuIrp{+#jn9YA6GZMykB{cfzS zpT4=w_eRo+O+Gf#Qw&c@7&EU2Wi(Jva0${RAtYWE&|<)Z90|WZb5RW* zzARZ0gIX{YgU4>(qBWMNqlDTp(ZY%(#h#w+eiTr`NNJ2?KMpaE7`Rsd}Dv164}CAy?KPSS9DnA!)?~xJZrkBC%4YjtHSsmzm(U!v2DM; zg+i)p!L+I~G@ngib6pmy?5dU@U(78SZt(i$y`LnTG}b+8Rg2cru&vn&n3A6jA2CL& zLOnbo6W1jC{{U(6XK8eeO&5!}y;;zcYnr8)90oh=?;OYKn-GLdoq#!;mqgYG+0%&I zQoAr+(G(JBK|rqF;l^2*(q!0{Yzld1r>+#);EGbhu0skCq{#Pr4NUf+hva&>>gRSN z-l~fBEBo8e-VIfWWP6E@)NTeI$RttJkc=Fe?5c?Lmp8yPM)pTT z5KL7&BTDf4V#mtvpM`*%#>!6Wo}-yW1wW1vI3WsIQ7cH2Me|p3KwnPUaFXKMDAQLW zhm}S`<;%Qd1lArecNiYZZ*pi7@v5-_#{wIUy4F`Aa+vuTmthI$#doQw(RJ89*Hu#0 zRDIiHZFW^G=Nn-)l*YN+K86<^nozxZ0Dm=FZp~X6V~W^nI}6>^&m`uitC9ZzVNc@s zy!yG!bmUzhhdB7li+0=krJUzo6VdXMqRtu*LD-~3#=hJ4_wAet-LRj$INhMXtW)B~ z68h&U?u&nazvEL};~&%1a?RbknYB7o%)!M7ZI}sYU|BAw6S<>S=1?g{cpSd{iRa0_Vq{l5W#jLi%GFXv(Hj=8P5=x#XG~=m6>Y=ra{{RA^ zh_2;Py2EhQv_qO!D)M_wbaUn3Qr$mNB-SHMDsc?wp{OgCmO#3$O-kZQC!~2xNdqgk z(W=`zNOOkiE2iotwq7cqs_A&Wa7Uc)<~P+b0W)`lwWGEY^s_PrABy}~q&{#R+)?#} z9}SLuxj>Ji3$r*#D#XwrGEVd;@(3Ois_k>xTASWCw>DZ>Je(&sLV~lnzpT~?ir4oR zWm!w&_x+z0cl){euYbe%_xkU<;r{Qa{{TLh*}Yd8Hvz5b;z=}&uyJ8cO`9kaJAjQu z^Nop;YKw&$V?`O^>RDfQ4xJZt(N{xR3vq{P?S~SBC)~+)@S@t_(O}k|M-yf;+A_K* zU&_4fXPoXTjaRv$Xw~KR5fXKTSa49# z{b#IY;&5lDmjmZCGP%G;)I{Oa-d>JrgL+CEhMS@u6N_ zwV+wuzkI)@Tw51Gj(?)q3aSWNO(ixoS~UrgO^Mk=8BL+?>k7^xwY^FWe~}OwrLq}D<3PFM+^spJVL>-1IsWP z1P)0*kSA9~7Z4K9$zyCz5u6ExR$q_K=sTRgBcZo`j zMJI%T>dm%bQ z*%h{MjTSW6gOcEeXjw9#vfv8LlR=|U9T|1<1lG9ConOi(v5F40pFt{PHTYKs#S+?5 zPTQ5o*htAdeA8AUaXYt8J|N>nkT%*p(IE_Di@Dtr$vG~%=aWovKk3)E36|C#wkG#t zU>2$+sx$lgb-I!5AXz%yb%)_aOk)i-k>lbYt9|hIcG}|`BZ&PL>1!}7d1Dr(D=m8- z4)}0$HYI*JQeYbqG&I==*z%2>Z-GLLNEyZCWSKU5Ct$HQVB{|b2TcGZ5JAU7tRM^M z+dpQrl2ypf%xKkEIc?nNITlNibnk37-NFhsWXY?yF5Wg>!xWHc<<72@YL3hLL9TDQ z6zGvHw&1rC2g7}R9hx>Ij^CwBf)pEX8kJMO#`i~X)p+m?9F1(TA4?qxZb2WA?f(E; z(Dvq@TZnJcd#QuCxdk$nL{`?mY}~JJ*)_H8BF0IP!)_U9-sW0MaETy}1kcDY>F^gu zX^0J>C9~$-k4^Hii09!6=>Y-yilwUg{nW2XlUWW-p5| z4;5zOPX#TAh4llfqH_8DqoH);h8AX(aN|aM3j&Ot;*MUo3Pl$iH-7c%&C+m9pyB9Y zzM8vu(1WB|ZnCfBldf>uJjzQMr!7*V3KBR7T#8B?5s0A!k@Nt&EHHe59nZFY_(1s} zQU%88sxR0eW<9H<2L5v$L}kd265r zsxdw*9m+Y<7A!Zl$kGhtYh4(P=H%`7LmM%-`Gs{Z>EvBXZsp}Gt1$U^-A$ekg5b7B z@fDd>f&FygUdRt)hAMVnWHE>*nk34ohA=K78Ovk2IV!^ib{ZdS%J!W1mqJ4x{Di>Ti*tIqN11O20KS2ml8 zmX(W6VyniA+tbTlmwts)cPhE|wY)mx9@4SbcXS#=rtt9u9kl0!=kLeA_0@PU3aY4_ zCo95z_)dM3pU)a|FTXE!UEtP6;YtQm5Iuj{kP9cTP6@hM5Y3>xY0HyR&~%W~w9y7! z_Qt`QnUL5|oyoQ6N0F&c@sY88hSs4E*Hc|`>++97KAdvJzt0qXsaITFutJ;K48I@0X`5+HY3)+37t7EBgkd0gXjK&8)L`0eAU088o> z1cc7w^4=@Cp|!P#J6?9uP=)0iAtaDiljDd)-NnVVfyo$8BF$t~<1vNZh(;SGFC3U) z(a<8~#A6kyeWSzFWfrB260G{CUUM9gt3bqlXEzSw_p`T$sBFTqSj-+auHsq} zV&%9IL7O7Uqa=m6Gaw+FsWEKp8qll{B3z#;-oCEm9KmJRT;d{oG_&Vb$gY$NAhTsM z$rv3##K%SMiFY@f7Y2aVEZMMU8jlvJtSNc%Po>D%HcY(vXmpyp@?X8T!Pl=tvbYFy zH$%t76%_TX>Lw?zD%GErCeS2c3^nXJOz(xZYY$)@pmPgL1)Pf54rUIF3*0G)3P4^V zB!BF_THz^-2BGK}eOYhRbz57!-8X2#N7-O(NvxJDh}g-@CTSLt$e{qlgRoo*cOZ?< zS-ckd6yeaQ%z`cqKCjLN*Gnnm-=73|Bb3sbj-G2l*EQvla1#jPQX%DwB8O3&r6}o% zG*9!Cq2nX%rIV(R60v0E?Q7;pgs-N-JyFBs-#50cLJJ-Z{ zdi-asy2qN`vReJ0TUL6by|*m15VD)N2Pa>LmB_lhRvk!zIDo&6oR*Zs@MTf8#9#pd za(z)>BOJ&lp>9d6Z=CF0(j6IHNg)??Qzz(1$;s3A=WL+&Ao&$xamM+&3M#wSBWA#A z8ANb2j-RxXahO5CQt}emwDITw(wLtS@dU=vYp3O&utzfL1RtZ(xv=7R6F{5}|cRh{G7HKCkO0r|m zwY);K=}66W7_KN2+^SoRBarfn&H0Aylh3B`dP(s1!z_nVDB>q2;Tp+hP{TUDEHUd# z#QdX2y%*5eUF8ZhWW{M{q&q;Bn2A!bM5Qx}I#|jk8RV8q&^dz5VsSA40F%iV7z073 z4oO(W1#Vr41-cWiP$aujz5 zc=E(fB%09*@l7G@Yn`P;ku585L?Z-Ji51TY`+u+WiJ?_j?yA4ldDLO4e2ViNIi-hJ zO?k4$v$@2@nHsg=b<@6!6B4l^l29X_0yHjFa7DTCpy}K;!;d}4S*W2^Wp^oPn26*0 z)^l5wZ!38<-XeZYxrRjFtYtkF&zBXKZ1x_~+}rZn>!j<7dMJ+azKgCpVdMA=4nxP+ zQ|PI^r!|<7PFZJ}KhkNDJ`tH!kw@N`s#C7f04JD~*erhCNJ1AyF$4 zI?HJA+(ybyYzfN7a}$*=PFRq}k=W&UF~S0Ey3EuN+4woyQIPa2Eu~Rfk_{tDA^5pWSOnbJQx~#%`1592FmVBk z2aQCw10+6HQZ^^ac{iIMc=(oGF;MnuSL_F(Xxjc{K&klBwR_lQ$p!1FTM_XXlL)#} zW~T(}L`2*glAW3mWIC`rkZXl9{WpQ$KzEW&1l554QgR zx!heicmC<|>M`YN1p1bCFl8eAFGa{`3ip?#_jcB1=072^?H480G|$fUK9) z)qP#m5=m>DT>Me&dIn2NRK~h61s_53{UbhtW(F!;TtSO&?}gkdG7T;{se^BfIF9qRA~WMf`&?+zT!-Bq zTdLiM+Dt!q-A`GNtuJP53+pSXxYp8>N?g4oHJ{mMy23#*n3*E=>-VNeuF}d93>($l zzgnU%S&q@^RXBh7xy#oGw{bOxg`P>Fd{;Or1)YN)I1}1>;sZ9Hv4weupgE>AugR2v~iSdX1#sI}GJ-3a}4_ z%cUMT+<9TcNUR$PX;)y&KV9<=n0mC32LWI@8Ca_%Y>hJhYq+fW8VgJ1u()g~7VX(K zia});1ks?8jkZe~2@}9LA2b2+OZ6s%^Il=Dt`cq@?P)N^m@JA33VmGF^d*9y5rca~S3Y ztvg@BH_QX)ZItK0nl0B?Fa+g!gNwcTn$;@RHlZat_akU5v_%9 zbO?j91erjUW>ZuWH@VwiVK{YG6*^=x-mfu6QIVtE<9EH}YFKrbBX)WhZZ-;5S#4Na zKwvfnl;-?7%(g9JCK!;~R36qu>RZk-wQWtT zD}HG@m7Hx4g3@S)8!6T;71Tt05GIV;h<8zQwO=EjvSUP8jyY=buiCM95t($X2`d@t zs`_D-8QK+JM33e8q!He+sZdhUr(%|(>pzc|uMq>!HcZ$B6lyc7`cC2P6 z9gR&nZoToj(>_FN9(%E)kkShcnliGlsI{3^%&dsqLN0F0ttK;ChFatf)(FWw+BIHE z!oUg3r6b}3R@YtRKKJPx2a-IPSRG2spZd~ez!euTT^w^5vboZei`5+McGzdSwyPFO zxD5xb1s-7vfFlHiW;ut%9@yH(MjDQ?o(9@V>H9;3{geHF=%3}RcRTlA^IZT2J>y8i zFDnk+ytyvh!8yelAgXF;3^x4}P=99a!-hL(RUTr&GW%toHeb|CH)&IJ;3 zbsB9Ul*Ub}^q{xQk1}>=6jdazucqbBjh45yqmx(&lw0-XTm@K#VJZ>>M~w=-Q-x1A zl1~Pg5@?>Y*6kuOeS;Jl9a_aFU>?ZiN9U`_TK&`G6Rzc5t7vP`_QxJ{pN{FzH`{B~ z^)**5hQ@nuZhwec6{5)1(HQ$TwfU%R##u)opKko4v%{ixq>jzsr8Zk#IDkGa6P4A%r{{zrg{=Iu zH-Zg`%&oe0&CPI9mbB97=PPU-o-P#-idphkBjxQMS#U_ja(G3(7>8Rz!rSq<)M`^u zx>U->qEi_Z!m=g~7ZRJtT7XaGpv z!@$;+-n4D39sHeG(G%9>G3yZ!@d&v?Q^#;2oImM)YMJ+kH{D%V(|i?ZaxYhLpjb@8 z_`TuWiFtE%C*3@-`cU9ilQ@*sc70AI=w6cM$VQp7WF=!HWf(CR7a$Tm(y&!y@#?VF zG#cQYvBrCH+`pfU^Cv*aq|=FQUu4MV0s6wRjg3ZePD8HrW%m${my>&_1{PU+v#^t6=Q*nB}T^TgS zX!>niM{4rG9@^0=HpZ5~7|l|+qVZ_lRMc*BB&CV2Ee()^~ESvDdr zyJgT0qBkm*q@o@(ou<>{_08Wi=Nh>BYP1afh*L6Jk5?v}%4LURHjJGyHLJLLaE~0T zCOC83{{Y%EsxVA_jScE*f#6}T7)B!eTgKd}ee$eTQE!ba3XH&`FnXh_dK~p&{x%#u zO|z*K>JKuB?pS#V7*HsTT^IOPwSCnQSNBv!*VA71{{V&VZ~d1lf8eRAw_4q8#F8Fd zj8JjTeYcy+Yx!lNWq`1B?5c9X6qM%Liqa7IE2&f}H^xz?<{%@qqoYqFF;TPlxyBCU zGDL}32Q+dwQQk}MyZG9B&GoH0TJweZ2Rl;YMWhN_H0s*o%MzM%S!lTgxjD2(J;jw1 z=}yXyX8c5LNc7qR_BXFt8!4=z0jq*7G`yJi>K*Gv(RAg%&9VC9vH9BK=qLR#Vg;uJ z(P>S!u?0X?f=%64XWqKE;q!ZTIemym?ecrg*6>B4 z$n!Mj4-2&J(Kr79OAC(lTW8W4Npy%toU@gELBL#f6_4~hA`J$gMW#GAd&cT3B7W+2&Q9L>1FXJFQ`oXLu?JCc zZD0}x)(klbEpEVRhoVq~%1XwjTOB?CY@nM@FY%Yo)85$P+A@+>#fep&Fdm0nC2aF? z>2&OBmkj;b1ltxZqWg*OGt<&?n+xa#-e?j<>R9*0dU}R zxQ$x%A@kTRk6|p0T^trt{{WR&EVmUAb92r$bW` z{{WFA`@a0DT{ixeAq480imsH?g`p)Yx#dd$RueXkAzx@yc$hKgkuLE>L5Lz#Q*D}P zj;=H`EIa*OYqK47-cj`YI)k~TzA|MEs>-jNA=gJd2HwYGQ8jrKjSglXx;pBZbv1f^ z%s*kBAtYyA*Rj+~&aBBq$fLXgXzD;k`xZ&HN?rCvdk7y|S@L=JCel^!_Gj-J`kJdE z(du>8AkuMD6o+2LEgFW=HC{b|S$5iRo#~1v1n078)BcHxr*$8AcHh*kmkuT*(V;Oi z^3QV5W_6)CElWae9Ip#bWhhj^X?Vm^tCi1ek$MQ2*fThERS>Bils{y~G>D(|wxD8Y zL!&HW0KkrD`I!ubwdIcco?eybKr^kX7zLRIa$R){LMs8R8cx`q1STp(1(pQL$3aeF z&LU%7#T`aWj#Mc)#EMW1!!jeyx^J23C8Fq?Z_5uq19MSVkq9-RQ*fn@>X@#>s|~LX z&Mcl7=gVcqbPNFJ`y5PNv1-T_0{B2Psn`;Sa~I7)N)er!X(H1l(Tc31blkzh@{10gUIf+$Cx{|Ct}(*sam#?uqPI488AZzrnO+#xC0H9*5xVl zHS9Dq(>z6S$dm``aau_o~zp-DIW+GCUG=}L$vi52Q$IrOctM+S4mi zx>{i}pCWR?jN0#+N{=dOqNG~p!-hsBdSfZ3zuiPOT}9Q#Ro8i!!Vm$lE^eG$b&Um8 z^d-JarE6NH48 zIr{P)#=)w2z7jXg_dmkvnyBzPQPi4AOI`(1KQFexMPWWhd0vZ!2#U;J%HBg6Mv2z5 ziAsf}QMg#?q~r4vNXX{rA}L2>flV44RNs{zim4$7qL7%qa-jWX(%I#5XuW3}KPRH4 zlc5d3%Z<`fVvO9Ef;uiRRBLoFi>Jv)4#VQJD4Jj;)Mn-Z=4h=j35|)-TlW66{nl>uToHP>u09NT}hNs>9ZPd@p&V{4Ltq)qO zS8;?p6kS(nLHgIAY#Pt0XOmi@BVo%R&^E8(aVawhEuKgl*#|p5rRnKePL0-21Then zh$2XJg=!s@RH9;WK+sT#8lq3*I?rjXBUHzy^=Dvm(4X7l0myc?rGst?m%GkMqms!K zf>3#bDAN^cr~@HUI1nf-Z-2zbo{|TVP8KUHB52bSk0}-w+{vDCZO?r1h&}^-9;WrG zv-yAI--Uh&i!Txk8^+(VKH2^ui5^<~AAJ7+68aB+`&M+q-c&jf^$UtI=y)?`FCo#2 zz_pUryNx!vPt=g(Ef2;jlJ;(_Ga+{h4p>B6X2@YwjVKZm3WYi}yb>}pFo~hBXsX@6 zJi+Ql^fgx@r>4F;It!$wmxJn>CRWsIc0nN*4E8G`718a&X)}t5k6+cLb<3MqK;;7K zB211JttBwiSB%Jv(eVEO=*aC$FyT%xk;kb@s*!Q2HxAye?V3i)zNGIGbfNAi8%dyB1=XCfY$Z%=;b{2u%0ZB%-w^3SRLuZB&?ddbpgJdQQZUGfC9Kw3fyy zq~AxkG-!-ZY<{fq@4%ix5b_1pXK8!)r0NcNg7Pmr67nB?bstW!pGQnshpu^4T_Scx znuoE3sCP%Yn#b!cN6yql_}l14EIR(L1K7 z`#ZaQe#XneVfA%w)cbP;g7<`sVcTSQM7a>blw~h139P<&KfazNzuFWpWifuvHvj})tym;(_6D+T*Me8{! zvQ$K@!x+xfR_B>q!qJ^(}BTaq?x) z5fMGSz{BG2VDabeO3qP`Ee{s9gw8ZqUqRa9kYix*Z1%$CerY8(=wyokokZNzp)082 zk-OYPYv^_CItf#$S`Hs4c-tpJj4UCWdX`9Tx69H{BeJp6@-hQPi+_nOch+qR2+0nSeE#NkzVg!%dEHBnDC3?8~((>i%8J9Pml~ z=gts0l)fB(wN0q%R&H9YDPlc$Tvua>2#dl006cEMEr6s_R~C{)7!0vqkgVen*pY~P zFs6+WjtZ}OGqSvR`Fn*!VR0!BMKJ5GI3Pm1Ju<7tK-4|R-2q<9EJ!;kylz19oZcWb z9WNsZ4=Em#VgOP;+zv#NWDVcM{GM!L2#{tfUoklJCAEm}CwkkTO zs^ELV>2tKj(rPBkdl`*T*Q_oz4P@@@9W0K3t=EASk-RG`8cbNVVV@S&ksT=Rleq)Y zH5IRBKy7|zt>bKLS~|SC07Gi4HJ?EgpUKdG&Em3nx(jJJtm!JzjHtLrW8-PsuA_qW zV=taWiVq|c9&m$mgRYT3&b;qf+0&f$To#&hR7`4M*VszRIVFi7lC4C>pi*J-GVupf zOCbpzK7j|zFMJ|8t6C8Vuz<{1+Jxn1jZL?-U$p3#)+rt})3%U>nKUC3pVPg+$Y*M) z(6T|96cTnZAhImFo^h}u3OmX=JS$p{Q!Uc_g9J*mU9zjQUHMq~T<6X@=rY~i<))yg z@h7I{f&g)R$DrhP?b+1P*;!>Pf_0dI5r~vC0T;6(uBC_sBNC0>0S3NYQ(5Ua9Ce)P zX9*wWL{-#h`!94|9UW&GiSv=^#QvDEAyca$ERQT>z3IxF#S~Ld!{>r((gO)pvhvPf zNd(vI;$+NbI%M-J9o!>Kv9j_!`= zxrD+VMqM8ky|WdruIXsQ8=H!k9}pPTE9MCS<`U7yEEvX1B3F9E_;NQX-^v#>Yi#n@ zDnDIu%`p)2A8uFIAD8HNLd~1Ql7&m_8w%#5cp!yxl22+L#g;c%GPZIbpolP0IbPm;&nae_`aoO7w}+AWLHBw`mDHa%X<--S;-_d z&egbSRUsaM*7dvS_oGIGy@Tb$p=?mF;1gJlR`muG*e#P{xJIpwiZ9TT%H@vYqED~W zV%sw@VkFFK=_(~#D)e$vqH{@fu33Y#Q#(l#^j>~m?pq;BoU1z0o2sSM(Ku-e{&Q8p zHik@qvwH diff --git a/core/assets/shaders/BoneTexture.vs b/core/assets/shaders/BoneTexture.vs deleted file mode 100644 index 5dfa5b7f..00000000 --- a/core/assets/shaders/BoneTexture.vs +++ /dev/null @@ -1,16 +0,0 @@ -uniform sampler2D u_boneMap; -uniform float u_vectorSize; -uniform float u_rowSize; -mat4 fetchMatrix(float column, float row) { - column *= u_vectorSize * 4.0; - row *= u_rowSize; - // Add in half texel to sample in the middle of the texel. - // Otherwise, since the sample is directly on the boundry, small floating point errors can cause the sample to get the wrong pixel. - // This is mostly noticable with NPOT textures, which the bone maps are. - column += 0.5 * u_vectorSize; - row += 0.5 * u_rowSize; - return mat4(texture2D(u_boneMap, vec2(column, row)), - texture2D(u_boneMap, vec2(column + u_vectorSize, row)), - texture2D(u_boneMap, vec2(column + u_vectorSize * 2.0, row)), - texture2D(u_boneMap, vec2(column + u_vectorSize * 3.0, row))); -} \ No newline at end of file diff --git a/core/assets/warsmash.ini b/core/assets/warsmash.ini deleted file mode 100644 index cb2f17dd..00000000 --- a/core/assets/warsmash.ini +++ /dev/null @@ -1,20 +0,0 @@ -[DataSources] -Count=9 -Type00=MPQ -Path00="D:\Games\Warcraft III Patch 1.22\war3.mpq" -Type01=MPQ -Path01="D:\Games\Warcraft III Patch 1.22\War3x.mpq" -Type02=MPQ -Path02="D:\Games\Warcraft III Patch 1.22\War3xlocal.mpq" -Type03=MPQ -Path03="D:\Games\Warcraft III Patch 1.22\War3Patch.mpq" -Type04=MPQ -Path04="D:\Games\Warcraft III Patch 1.22\Warsmash\War3Mod.mpq" -Type05=Folder -Path05="..\..\resources" -Type06=Folder -Path06="D:\Backups\Warsmash\Data" -Type07=Folder -Path07="D:\Games\Warcraft III Patch 1.22\Maps" -Type08=Folder -Path08="." diff --git a/core/assets/warsmash131notworking.ini b/core/assets/warsmash131notworking.ini deleted file mode 100644 index 140c51a7..00000000 --- a/core/assets/warsmash131notworking.ini +++ /dev/null @@ -1,42 +0,0 @@ -[DataSources] -Count=5 -Type00=CASC -Path00="D:\Games\Warcraft III Patch 1.31\" -Prefixes00="war3.w3mod","war3.w3mod\_deprecated.w3mod","war3.w3mod\_locales\enus.w3mod" -Type01=Folder -Path01="..\..\resources" -Type02=Folder -Path02="D:\Backups\Warsmash\Data" -Type03=Folder -Path03="D:\Games\Warcraft III Patch 1.22\Maps" -Type04=Folder -Path04="." - -[Map] -//FilePath="CombatUnitTests.w3x" -//FilePath="PitchRoll.w3x" -//FilePath="PeonStartingBase.w3x" -//FilePath="MyStromguarde.w3m" -//FilePath="ColdArrows.w3m" -//FilePath="DungeonGoldMine.w3m" -//FilePath="PlayerPeasants.w3m" -//FilePath="FireLord.w3x" -//FilePath="Maps\Campaign\NightElf03.w3m" -//FilePath="PhoenixAttack.w3x" -//FilePath="LightEnvironmentTest.w3x" -//FilePath="TorchLight2.w3x" -FilePath="OrcAssault.w3x" -//FilePath="FrostyVsFarm.w3m" -//FilePath="ModelTest.w3x" -//FilePath="SpinningSample.w3x" -//FilePath="Maps\Campaign\Prologue02.w3m" -//FilePath="Pathing.w3x" -//FilePath="ItemFacing.w3x" -//FilePath=SomeParticleTests.w3x -//FilePath="PeonMiningMultiHall.w3x" -//FilePath="QuadtreeBugs.w3x" -//FilePath="test2.w3x" -//FilePath="FarseerHoldPositionTest.w3x" -//FilePath="Ramps.w3m" -//FilePath="V1\Farm.w3x" -//FilePath="TheSheepAttack.w3x" \ No newline at end of file diff --git a/core/assets/warsmashPRSCMOD.ini b/core/assets/warsmashPRSCMOD.ini deleted file mode 100644 index 0c75d66c..00000000 --- a/core/assets/warsmashPRSCMOD.ini +++ /dev/null @@ -1,26 +0,0 @@ -// This is the Warsmash INI file for Project Revolution -// PRSCMOD - -[DataSources] -Count=9 -Type00=MPQ -Path00="D:\Games\Warcraft III Project Revolution\War3\The Sheep Attack\war3.mpq" -Type01=MPQ -Path01="D:\Games\Warcraft III Project Revolution\War3\The Sheep Attack\War3x.mpq" -Type02=MPQ -Path02="D:\Games\Warcraft III Project Revolution\War3\The Sheep Attack\War3xlocal.mpq" -Type03=MPQ -Path03="D:\Games\Warcraft III Project Revolution\War3\The Sheep Attack\war3patch.mpq" -Type04=MPQ -Path04="D:\Games\Warcraft III Project Revolution\PRSCMOD\Revolution.mpq" -Type05=MPQ -Path05="D:\Games\Warcraft III Project Revolution\PRSCMOD\Sound.mpq" -Type06=Folder -Path06="D:\Games\Warcraft III Project Revolution\ProjectRevolusmash" -Type07=Folder -Path07="..\..\resources" -Type08=Folder -Path08="D:\Games\Warcraft III Project Revolution\PRSCMOD\PR-Maps" - -[Map] -FilePath="ProjectRevolusmash.w3x" \ No newline at end of file diff --git a/core/assets/warsmashRF.ini b/core/assets/warsmashRF.ini deleted file mode 100644 index 9279a95f..00000000 --- a/core/assets/warsmashRF.ini +++ /dev/null @@ -1,41 +0,0 @@ -[DataSources] -Count=5 -Type00=CASC -Path00="C:\Program Files\Warcraft III" -Prefixes00=war3.w3mod,war3.w3mod\_deprecated.w3mod,war3.w3mod\_locales\enus.w3mod,war3.w3mod\_hd.w3mod,war3.w3mod\_hd.w3mod\_locales\enus.w3mod -Type01=Folder -Path01="..\..\resources" -Type02=Folder -Path02="D:\Backups\Warsmash\Data" -Type03=Folder -Path03="D:\Games\Warcraft III Patch 1.22\Maps" -Type04=Folder -Path04="." - -[Map] -//FilePath="CombatUnitTests.w3x" -//FilePath="PitchRoll.w3x" -FilePath="PeonStartingBase.w3x" -//FilePath="MyStromguarde.w3m" -//FilePath="ColdArrows.w3m" -//FilePath="DungeonGoldMine.w3m" -//FilePath="PlayerPeasants.w3m" -//FilePath="FireLord.w3x" -//FilePath="Maps\Campaign\NightElf03.w3m" -//FilePath="PhoenixAttack.w3x" -//FilePath="LightEnvironmentTest.w3x" -//FilePath="TorchLight2.w3x" -//FilePath="OrcAssault.w3x" -//FilePath="FrostyVsFarm.w3m" -//FilePath="ModelTest.w3x" -//FilePath="SpinningSample.w3x" -//FilePath="Maps\Campaign\Prologue02.w3m" -//FilePath="Pathing.w3x" -//FilePath="ItemFacing.w3x" -//FilePath=SomeParticleTests.w3x -//FilePath="PeonMiningMultiHall.w3x" -//FilePath="QuadtreeBugs.w3x" -//FilePath="test2.w3x" -//FilePath="FarseerHoldPositionTest.w3x" -//FilePath="Ramps.w3m" -//FilePath="V1\Farm.w3x" diff --git a/core/assets/warsmashTTOR.ini b/core/assets/warsmashTTOR.ini deleted file mode 100644 index b1b9c905..00000000 --- a/core/assets/warsmashTTOR.ini +++ /dev/null @@ -1,22 +0,0 @@ -// This is the Warsmash INI file for Project Revolution -// PRSCMOD - -[DataSources] -Count=7 -Type00=MPQ -Path00="D:\Games\Warcraft III Project Revolution\War3\The Sheep Attack\war3.mpq" -Type01=MPQ -Path01="D:\Games\Warcraft III Project Revolution\War3\The Sheep Attack\War3x.mpq" -Type02=MPQ -Path02="D:\Games\Warcraft III Project Revolution\War3\The Sheep Attack\War3xlocal.mpq" -Type03=MPQ -Path03="D:\Games\Warcraft III Project Revolution\War3\The Sheep Attack\war3patch_TTOR.mpq" -Type04=Folder -Path04="D:\Games\Warcraft III Project Revolution\ProjectRevolusmash" -Type05=Folder -Path05="..\..\resources" -Type06=Folder -Path06="D:\Games\Warcraft III Project Revolution\War3\The Sheep Attack\Maps" - -[Map] -FilePath="(2)BootyBay.w3m" \ No newline at end of file diff --git a/core/assets/warsmashUF.ini b/core/assets/warsmashUF.ini deleted file mode 100644 index eac283a6..00000000 --- a/core/assets/warsmashUF.ini +++ /dev/null @@ -1,22 +0,0 @@ -// This is the Warsmash INI file for Project Revolution -// PRSCMOD - -[DataSources] -Count=7 -Type00=MPQ -Path00="D:\Games\Warcraft III Patch 1.27 Redownload\Warcraft III\war3.mpq" -Type01=MPQ -Path01="D:\Games\Warcraft III Patch 1.27 Redownload\Warcraft III\War3x.mpq" -Type02=MPQ -Path02="D:\Games\Warcraft III Patch 1.27 Redownload\Warcraft III\War3xlocal.mpq" -Type03=MPQ -Path03="D:\Games\Warcraft III Patch 1.27 Redownload\Warcraft III\war3patch.mpq" -Type04=MPQ -Path04="D:\Games\Warcraft III Patch 1.27 Redownload\Warcraft III\War3Mod.mpq" -Type05=Folder -Path05="..\..\resources" -Type06=Folder -Path06="D:\Games\Warcraft III Patch 1.27 Redownload\Warcraft III\Maps" - -[Map] -FilePath="Maps\Campaign\Prologue01.w3m" \ No newline at end of file diff --git a/core/assets/warsmash_131.ini b/core/assets/warsmash_131.ini deleted file mode 100644 index ad076616..00000000 --- a/core/assets/warsmash_131.ini +++ /dev/null @@ -1,26 +0,0 @@ -[DataSources] -Count=5 -Type00=Folder -Path00="D:\Games\Warcraft III CASC 1.31\war3.w3mod" -Type01=Folder -Path01="D:\Games\Warcraft III CASC 1.31\war3.w3mod\_locales\enus.w3mod" -Type02=Folder -Path02="..\..\resources" -Type03=Folder -Path03="D:\Backups\Warsmash\Data" -Type04=Folder -Path04="." - -[Map] -//FilePath="PitchRoll.w3x" -//FilePath="ReforgedGeorgeVacation.w3x" -//FilePath="Maps\Campaign\NightElf03.w3m" -//FilePath="PrivateDontShare/Cult 8.w3x" -//FilePath="TorchLight2.w3x" -//FilePath="OrcAssault.w3x" -//FilePath="PeonStartingBase.w3x" -//FilePath="PhoenixAttack.w3x" -//FilePath="OperationReforged.w3x" -//FilePath="AzerothRoleplay1.909t03DecoratedV2.w3x" -//FilePath="American Colo EX 1.0 unpro.w3x" -FilePath="TheSheepAttack.w3x" diff --git a/core/assets/warsmash_myHD.ini b/core/assets/warsmash_myHD.ini deleted file mode 100644 index 1f0e7fca..00000000 --- a/core/assets/warsmash_myHD.ini +++ /dev/null @@ -1,12 +0,0 @@ -[DataSources] -Count=5 -Type00=Folder -Path00="D:\Backups\Warcraft\Data\UIMod" -Type01=Folder -Path01="..\..\resources" -Type02=Folder -Path02="D:\Backups\Warsmash\Data" -Type03=Folder -Path03="D:\Games\Warcraft III Patch 1.22\Maps" -Type04=Folder -Path04="." diff --git a/core/build.gradle b/core/build.gradle deleted file mode 100644 index 13c049ad..00000000 --- a/core/build.gradle +++ /dev/null @@ -1,11 +0,0 @@ -apply plugin: "java" - -sourceCompatibility = 1.8 -[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' - -sourceSets.main.java.srcDirs = [ "src/" ] - - -eclipse.project { - name = appName + "-core" -} diff --git a/core/src/com/etheller/warsmash/CodeCounter.java b/core/src/com/etheller/warsmash/CodeCounter.java deleted file mode 100644 index 0dda7968..00000000 --- a/core/src/com/etheller/warsmash/CodeCounter.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.etheller.warsmash; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; - -public class CodeCounter { - - public static void main(final String[] args) { - final int sourceLines = countFile(new File("src/com")); - System.out.println(sourceLines); - } - - public static int countFile(final File file) { - if (file.isDirectory()) { - int sum = 0; - for (final File subFile : file.listFiles()) { - sum += countFile(subFile); - } - return sum; - } - else { - try { - if (file.getName().toLowerCase().endsWith(".java")) { - return Files.readAllLines(file.toPath()).size(); - } - } - catch (final IOException e) { - e.printStackTrace(); - } - return 0; - } - } - -} diff --git a/core/src/com/etheller/warsmash/MathSpeedBenchmark.java b/core/src/com/etheller/warsmash/MathSpeedBenchmark.java deleted file mode 100644 index 99688689..00000000 --- a/core/src/com/etheller/warsmash/MathSpeedBenchmark.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.etheller.warsmash; - -public class MathSpeedBenchmark { - private static final int NUMBER_OF_ITERATIONS = 100000000; - - public static void main(final String[] args) { - // Let us solve for Ground Distance two ways. - - long sumCosineTime = 0; - long sumSquareRootTime = 0; - final float[] thrallXs = new float[NUMBER_OF_ITERATIONS]; - final float[] thrallYs = new float[NUMBER_OF_ITERATIONS]; - final float[] murlocXs = new float[NUMBER_OF_ITERATIONS]; - final float[] murlocYs = new float[NUMBER_OF_ITERATIONS]; - for (int i = 0; i < NUMBER_OF_ITERATIONS; i++) { - - thrallXs[i] = getRandomFloat(-25000.0f, 25000.0f); - thrallYs[i] = getRandomFloat(-25000.0f, 25000.0f); - murlocXs[i] = getRandomFloat(-25000.0f, 25000.0f); - murlocYs[i] = getRandomFloat(-25000.0f, 25000.0f); - } - final long clockTime1 = System.currentTimeMillis(); - for (int i = 0; i < NUMBER_OF_ITERATIONS; i++) { - final float distance2 = groundDistanceSqrt(thrallXs[i], thrallYs[i], murlocXs[i], murlocYs[i]); - } - final long clockTime2 = System.currentTimeMillis(); - for (int i = 0; i < NUMBER_OF_ITERATIONS; i++) { - final float distance1 = groundDistanceCos(thrallXs[i], thrallYs[i], murlocXs[i], murlocYs[i]); - } - final long clockTime3 = System.currentTimeMillis(); -// if (Math.abs(distance2 - distance1) > 0.1) { -// System.out.println(thrallX + "," + thrallY); -// System.out.println(murlocX + "," + murlocY); -// System.err.println(distance1 + " != " + distance2); -// throw new RuntimeException("You have failed to do mathematics."); -// } - sumCosineTime = clockTime2 - clockTime1; - sumSquareRootTime = clockTime3 - clockTime2; - System.out.println("Square Root: " + sumCosineTime); - System.out.println("Cosine: " + sumSquareRootTime); - } - - static float getRandomFloat(final float min, final float max) { - final float range = max - min; - return (float) ((Math.random() * range) + min); - } - - static float groundDistanceSqrt(final float thrallX, final float thrallY, final float murlocX, - final float murlocY) { - final float dx = murlocX - thrallX; - final float dy = murlocY - thrallY; - return (float) StrictMath.sqrt((dx * dx) + (dy * dy)); - } - - static float groundDistanceCos(final float thrallX, final float thrallY, final float murlocX, final float murlocY) { - final float dx = murlocX - thrallX; - final float dy = murlocY - thrallY; - final double angle = StrictMath.atan2(dy, dx); - return (float) (dx / StrictMath.cos(angle)); - } -} diff --git a/core/src/com/etheller/warsmash/SingleModelScreen.java b/core/src/com/etheller/warsmash/SingleModelScreen.java deleted file mode 100644 index cf583e14..00000000 --- a/core/src/com/etheller/warsmash/SingleModelScreen.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash; - -public interface SingleModelScreen { - void setModel(String path); -} diff --git a/core/src/com/etheller/warsmash/WarsmashGdxGame.java b/core/src/com/etheller/warsmash/WarsmashGdxGame.java deleted file mode 100644 index 9ff816f2..00000000 --- a/core/src/com/etheller/warsmash/WarsmashGdxGame.java +++ /dev/null @@ -1,535 +0,0 @@ -package com.etheller.warsmash; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.IntBuffer; - -import com.badlogic.gdx.ApplicationAdapter; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.audio.Music; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.math.Quaternion; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.util.DataSourceFileHandle; -import com.etheller.warsmash.viewer5.Camera; -import com.etheller.warsmash.viewer5.CanvasProvider; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.SolvedPath; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxViewer; -import com.etheller.warsmash.viewer5.handlers.mdx.Sequence; -import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode; - -public class WarsmashGdxGame extends ApplicationAdapter implements CanvasProvider { - private static final boolean SPIN = false; - private static final boolean ADVANCE_ANIMS = true; - private DataSource codebase; - private ModelViewer viewer; - private MdxModel model; - private CameraManager cameraManager; - public static int VAO; - private final Rectangle tempRect = new Rectangle(); - - private BitmapFont font; - private SpriteBatch batch; - private final DataTable warsmashIni; - - public WarsmashGdxGame(final DataTable warsmashIni) { - this.warsmashIni = warsmashIni; - } - - @Override - public void create() { - - final ByteBuffer tempByteBuffer = ByteBuffer.allocateDirect(4); - tempByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final IntBuffer temp = tempByteBuffer.asIntBuffer(); -// - Gdx.gl30.glGenVertexArrays(1, temp); - VAO = temp.get(0); - - Gdx.gl30.glBindVertexArray(VAO); - - final String renderer = Gdx.gl.glGetString(GL20.GL_RENDERER); - System.err.println("Renderer: " + renderer); - - this.codebase = WarsmashGdxMapScreen.parseDataSources(this.warsmashIni); - this.viewer = new MdxViewer(this.codebase, this, new Vector3(0.3f, 0.3f, -0.25f)); - - this.viewer.addHandler(new MdxHandler()); - this.viewer.enableAudio(); - - final Scene scene = this.viewer.addSimpleScene(); - scene.enableAudio(); - - this.cameraManager = new CameraManager(); - this.cameraManager.setupCamera(scene); - - final String musicPath = "Sound\\Music\\mp3Music\\Mainscreen.mp3"; - final Music music = Gdx.audio.newMusic(new DataSourceFileHandle(this.viewer.dataSource, musicPath)); -// music.setVolume(0.2f); - music.setLooping(true); - music.play(); - -// this.mainModel = (MdxModel) this.viewer.load("Doodads\\Cinematic\\ArthasIllidanFight\\ArthasIllidanFight.mdx", -// this.mainModel = (MdxModel) this.viewer.load("UI\\Glues\\SinglePlayer\\NightElf_Exp\\NightElf_Exp.mdx", -// this.mainModel = (MdxModel) this.viewer.load("Abilities\\Spells\\Orc\\FeralSpirit\\feralspirittarget.mdx", -// new PathSolver() { -// @Override -// public SolvedPath solve(final String src, final Object solverParams) { -// return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); -// } -// }, null); - -// final EventObjectEmitterObject evt = this.mainModel.getEventObjects().get(1); -// for (final Sequence seq : this.mainModel.getSequences()) { -// System.out.println(seq.getName() + ": " + Arrays.toString(seq.getInterval())); -// } -// System.out.println(Arrays.toString(evt.keyFrames)); -// System.out.println(evt.name); - -// this.mainInstance = (MdxComplexInstance) this.mainModel.addInstance(0); - -// this.mainInstance.setScene(scene); -// -// final int animIndex = 0; -// this.modelCamera = this.mainModel.cameras.get(animIndex); -// this.mainInstance.setSequence(animIndex); -// -// this.mainInstance.setSequenceLoopMode(SequenceLoopMode.LOOP_TO_NEXT_ANIMATION); - -// acolytesHarvestingSceneJoke2(scene); - -// singleModelScene(scene, "Buildings\\Undead\\Necropolis\\Necropolis.mdx", "birth"); -// singleModelScene(scene, "Units\\Orc\\KotoBeast\\KotoBeast.mdx", "spell slam"); - singleModelScene(scene, "UI\\Glues\\MainMenu\\MainMenu3D\\MainMenu3D.mdx", "Stand"); - this.modelCamera = this.mainModel.cameras.get(0); - - System.out.println("Loaded"); - Gdx.gl30.glClearColor(0.5f, 0.5f, 0.5f, 1); // TODO remove white background - - this.font = new BitmapFont(); - this.batch = new SpriteBatch(); - } - - private void makeDruidSquare(final Scene scene) { - final MdxModel model2 = (MdxModel) this.viewer.load("units\\nightelf\\druidoftheclaw\\druidoftheclaw.mdx", - new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - makePerfectSquare(scene, model2, 15); - } - - private void singleAcolyteScene(final Scene scene) { - final MdxModel model2 = (MdxModel) this.viewer.load("units\\undead\\acolyte\\acolyte.mdx", new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - - final MdxComplexInstance instance3 = (MdxComplexInstance) model2.addInstance(0); - - instance3.setScene(scene); - - int animIndex = 0; - for (final Sequence s : model2.getSequences()) { - if (s.getName().toLowerCase().startsWith("stand work")) { - animIndex = model2.getSequences().indexOf(s); - } - } - instance3.setSequence(animIndex); - - instance3.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - } - - private void singleModelScene(final Scene scene, final String path, final String animName) { - final MdxModel model2 = (MdxModel) this.viewer.load(path, new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - - final MdxComplexInstance instance3 = (MdxComplexInstance) model2.addInstance(0); - - instance3.setScene(scene); - - int animIndex = 0; - for (final Sequence s : model2.getSequences()) { - if (s.getName().toLowerCase().startsWith(animName)) { - animIndex = model2.getSequences().indexOf(s); - break; - } - } - instance3.setSequence(animIndex); - - instance3.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - this.mainInstance = instance3; - this.mainModel = model2; - } - - private void acolytesHarvestingScene(final Scene scene) { - - final MdxModel acolyteModel = (MdxModel) this.viewer.load("units\\undead\\acolyte\\acolyte.mdx", - new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - final MdxModel mineEffectModel = (MdxModel) this.viewer - .load("abilities\\spells\\undead\\undeadmine\\undeadminecircle.mdx", new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - for (int i = 0; i < 5; i++) { - final MdxComplexInstance acolyteInstance = (MdxComplexInstance) acolyteModel.addInstance(0); - - acolyteInstance.setScene(scene); - - int animIndex = i % acolyteModel.getSequences().size(); - for (final Sequence s : acolyteModel.getSequences()) { - if (s.getName().toLowerCase().startsWith("stand work")) { - animIndex = acolyteModel.getSequences().indexOf(s); - } - } - acolyteInstance.setSequence(animIndex); - - acolyteInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - - final double angle = ((Math.PI * 2) / 5) * i; - acolyteInstance.localLocation.x = (float) Math.cos(angle) * 256; - acolyteInstance.localLocation.y = (float) Math.sin(angle) * 256; - acolyteInstance.localRotation.setFromAxisRad(0, 0, 1, (float) (angle + Math.PI)); - - final MdxComplexInstance effectInstance = (MdxComplexInstance) mineEffectModel.addInstance(0); - - effectInstance.setScene(scene); - - effectInstance.setSequence(1); - - effectInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - effectInstance.localLocation.x = (float) Math.cos(angle) * 256; - effectInstance.localLocation.y = (float) Math.sin(angle) * 256; - effectInstance.localRotation.setFromAxisRad(0, 0, 1, (float) (angle)); - - } - final MdxModel mineModel = (MdxModel) this.viewer.load("buildings\\undead\\hauntedmine\\hauntedmine.mdx", - new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - final MdxComplexInstance mineInstance = (MdxComplexInstance) mineModel.addInstance(0); - - mineInstance.setScene(scene); - - mineInstance.setSequence(2); - - mineInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - } - - private void acolytesHarvestingSceneJoke2(final Scene scene) { - - final MdxModel acolyteModel = (MdxModel) this.viewer.load("units\\undead\\acolyte\\acolyte.mdx", - new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - final MdxModel mineEffectModel = (MdxModel) this.viewer - .load("abilities\\spells\\undead\\undeadmine\\undeadminecircle.mdx", new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - for (int i = 0; i < 5; i++) { - final MdxComplexInstance acolyteInstance = (MdxComplexInstance) acolyteModel.addInstance(0); - - acolyteInstance.setScene(scene); - - int animIndex = i % acolyteModel.getSequences().size(); - for (final Sequence s : acolyteModel.getSequences()) { - if (s.getName().toLowerCase().startsWith("stand work")) { - animIndex = acolyteModel.getSequences().indexOf(s); - } - } - acolyteInstance.setSequence(animIndex); - - acolyteInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - - final double angle = ((Math.PI * 2) / 5) * i; - acolyteInstance.localLocation.x = (float) Math.cos(angle) * 256; - acolyteInstance.localLocation.y = (float) Math.sin(angle) * 256; - acolyteInstance.localRotation.setFromAxisRad(0, 0, 1, (float) (angle + Math.PI)); - - final MdxComplexInstance effectInstance = (MdxComplexInstance) mineEffectModel.addInstance(0); - - effectInstance.setScene(scene); - - effectInstance.setSequence(1); - - effectInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - effectInstance.localLocation.x = (float) Math.cos(angle) * 256; - effectInstance.localLocation.y = (float) Math.sin(angle) * 256; - effectInstance.localRotation.setFromAxisRad(0, 0, 1, (float) (angle)); - - } - final MdxModel mineModel = (MdxModel) this.viewer.load("units\\orc\\spiritwolf\\spiritwolf.mdx", - new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - final MdxComplexInstance mineInstance = (MdxComplexInstance) mineModel.addInstance(0); - - mineInstance.setScene(scene); - - mineInstance.setSequence(0); - mineInstance.localScale.x = 2; - mineInstance.localScale.y = 2; - mineInstance.localScale.z = 2; - - mineInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - final MdxModel mineModel2 = (MdxModel) this.viewer - .load("abilities\\spells\\undead\\unsummon\\unsummontarget.mdx", new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - final MdxComplexInstance mineInstance2 = (MdxComplexInstance) mineModel2.addInstance(0); - - mineInstance2.setScene(scene); - - mineInstance2.setSequence(0); - - mineInstance2.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - } - - private void makeFourHundred(final Scene scene, final MdxModel model2) { - for (int i = 0; i < 400; i++) { - final MdxComplexInstance instance3 = (MdxComplexInstance) model2.addInstance(0); - instance3.localLocation.x = (((i % 20) - 10) * 128); - instance3.localLocation.y = (((i / 20) - 10) * 128); - - instance3.setScene(scene); - - final int animIndex = i % model2.getSequences().size(); - instance3.setSequence(animIndex); - - instance3.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - } - } - - private void makePerfectSquare(final Scene scene, final MdxModel model2, final int n) { - final int n2 = n * n; - for (int i = 0; i < n2; i++) { - final MdxComplexInstance instance3 = (MdxComplexInstance) model2.addInstance(0); - instance3.localLocation.x = (((i % n) - (n / 2)) * 128); - instance3.localLocation.y = (((i / n) - (n / 2)) * 128); - - instance3.setScene(scene); - - final int animIndex = i % model2.getSequences().size(); - instance3.setSequence(animIndex); - - instance3.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - } - } - - public static void bindDefaultVertexArray() { - Gdx.gl30.glBindVertexArray(VAO); - } - - private int frame = 0; - private MdxComplexInstance mainInstance; - private MdxModel mainModel; - private com.etheller.warsmash.viewer5.handlers.mdx.Camera modelCamera; - private final float[] cameraPositionTemp = new float[3]; - private final float[] cameraTargetTemp = new float[3]; - private final boolean firstFrame = true; - - @Override - public void render() { - Gdx.gl30.glBindVertexArray(VAO); - if (SPIN) { - this.cameraManager.horizontalAngle += 0.0001; - if (this.cameraManager.horizontalAngle > (2 * Math.PI)) { - this.cameraManager.horizontalAngle = 0; - } - } -// this.modelCamera = this.mainModel.cameras.get(this.mainInstance.sequence); - this.cameraManager.updateCamera(); - this.viewer.updateAndRender(); - -// gl.glDrawElements(GL20.GL_TRIANGLES, this.elements, GL20.GL_UNSIGNED_SHORT, this.faceOffset); - -// this.batch.begin(); -// this.font.draw(this.batch, Integer.toString(Gdx.graphics.getFramesPerSecond()), 0, 0); -// this.batch.end(); - - this.frame++; - if ((this.frame % 1000) == 0) { - System.out.println(Integer.toString(Gdx.graphics.getFramesPerSecond())); - } - - if (ADVANCE_ANIMS && this.mainInstance.sequenceEnded) { - final int sequence = (this.mainInstance.sequence + 1) % this.mainModel.getSequences().size(); - this.mainInstance.setSequence(sequence); - this.mainInstance.frame += (int) (Gdx.graphics.getRawDeltaTime() * 1000); - } -// if (this.firstFrame) { -// final Music music = Gdx.audio.newMusic(new DataSourceFileHandle(this.viewer.dataSource, -// "Sound\\Ambient\\DoodadEffects\\FinalCinematic.mp3")); -// music.setVolume(0.2f); -// music.setLooping(true); -// music.play(); -// this.firstFrame = false; -// } - } - - @Override - public void dispose() { - } - - @Override - public float getWidth() { - return Gdx.graphics.getWidth(); - } - - @Override - public float getHeight() { - return Gdx.graphics.getHeight(); - } - - @Override - public void resize(final int width, final int height) { - this.tempRect.width = width; - this.tempRect.height = height; - this.cameraManager.camera.viewport(this.tempRect); - } - - class CameraManager { - private CanvasProvider canvas; - private Camera camera; - private float moveSpeed; - private float rotationSpeed; - private float zoomFactor; - private float horizontalAngle; - private float verticalAngle; - private float distance; - private Vector3 position; - private Vector3 target; - private Vector3 worldUp; - private Vector3 vecHeap; - private Vector3 vecHeap2; - private Quaternion quatHeap; - private Quaternion quatHeap2; - - // An orbit camera setup example. - // Left mouse button controls the orbit itself. - // The right mouse button allows to move the camera and the point it's looking - // at on the XY plane. - // Scrolling zooms in and out. - private void setupCamera(final Scene scene) { - this.canvas = scene.viewer.canvas; - this.camera = scene.camera; - this.moveSpeed = 2; - this.rotationSpeed = (float) (Math.PI / 180); - this.zoomFactor = 0.1f; - this.horizontalAngle = (float) (Math.PI / 2); - this.verticalAngle = (float) (Math.PI / 4); - this.distance = 500; - this.position = new Vector3(); - this.target = new Vector3(0, 0, 50); - this.worldUp = new Vector3(0, 0, 1); - this.vecHeap = new Vector3(); - this.vecHeap2 = new Vector3(); - this.quatHeap = new Quaternion(); - this.quatHeap2 = new Quaternion(); - - updateCamera(); - -// cameraUpdate(); - } - - private void updateCamera() { - // Limit the vertical angle so it doesn't flip. - // Since the camera uses a quaternion, flips don't matter to it, but this feels - // better. - this.verticalAngle = (float) Math.min(Math.max(0.01, this.verticalAngle), Math.PI - 0.01); - - this.quatHeap.idt(); - this.quatHeap.setFromAxisRad(0, 0, 1, this.horizontalAngle); - this.quatHeap2.idt(); - this.quatHeap2.setFromAxisRad(1, 0, 0, this.verticalAngle); - this.quatHeap.mul(this.quatHeap2); - - this.position.set(0, 0, 1); - this.quatHeap.transform(this.position); - this.position.scl(this.distance); - this.position = this.position.add(this.target); - if (WarsmashGdxGame.this.modelCamera != null) { - WarsmashGdxGame.this.modelCamera.getPositionTranslation(WarsmashGdxGame.this.cameraPositionTemp, - WarsmashGdxGame.this.mainInstance.sequence, WarsmashGdxGame.this.mainInstance.frame, - WarsmashGdxGame.this.mainInstance.counter); - WarsmashGdxGame.this.modelCamera.getTargetTranslation(WarsmashGdxGame.this.cameraTargetTemp, - WarsmashGdxGame.this.mainInstance.sequence, WarsmashGdxGame.this.mainInstance.frame, - WarsmashGdxGame.this.mainInstance.counter); - - this.position.set(WarsmashGdxGame.this.modelCamera.position); - this.target.set(WarsmashGdxGame.this.modelCamera.targetPosition); -// this.vecHeap2.set(this.target); -// this.vecHeap2.sub(this.position); -// this.vecHeap.set(this.vecHeap2); -// this.vecHeap.crs(this.worldUp); -// this.vecHeap.crs(this.vecHeap2); -// this.vecHeap.nor(); -// this.vecHeap.scl(this.camera.rect.height / 2f); -// this.position.add(this.vecHeap); - - this.position.add(WarsmashGdxGame.this.cameraPositionTemp[0], - WarsmashGdxGame.this.cameraPositionTemp[1], WarsmashGdxGame.this.cameraPositionTemp[2]); - this.target.add(WarsmashGdxGame.this.cameraTargetTemp[0], WarsmashGdxGame.this.cameraTargetTemp[1], - WarsmashGdxGame.this.cameraTargetTemp[2]); - this.camera.perspective(WarsmashGdxGame.this.modelCamera.fieldOfView * 0.75f, - Gdx.graphics.getWidth() / (float) Gdx.graphics.getHeight(), - WarsmashGdxGame.this.modelCamera.nearClippingPlane, - WarsmashGdxGame.this.modelCamera.farClippingPlane); - } - else { - this.camera.perspective(70, this.camera.getAspect(), 100, 5000); - } - - this.camera.moveToAndFace(this.position, this.target, this.worldUp); - } - -// private void cameraUpdate() { -// -// } - } - - public DataSource getCodebase() { - return this.codebase; - } -} diff --git a/core/src/com/etheller/warsmash/WarsmashGdxMapScreen.java b/core/src/com/etheller/warsmash/WarsmashGdxMapScreen.java deleted file mode 100644 index 59c09e22..00000000 --- a/core/src/com/etheller/warsmash/WarsmashGdxMapScreen.java +++ /dev/null @@ -1,517 +0,0 @@ -package com.etheller.warsmash; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.IntBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.InputProcessor; -import com.badlogic.gdx.Screen; -import com.badlogic.gdx.audio.Music; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.GL30; -import com.badlogic.gdx.graphics.OrthographicCamera; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.utils.viewport.ExtendViewport; -import com.etheller.warsmash.datasources.CascDataSourceDescriptor; -import com.etheller.warsmash.datasources.CompoundDataSourceDescriptor; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.datasources.DataSourceDescriptor; -import com.etheller.warsmash.datasources.FolderDataSourceDescriptor; -import com.etheller.warsmash.datasources.MpqDataSourceDescriptor; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.jass.Jass2.RootFrameListener; -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.units.Element; -import com.etheller.warsmash.util.DataSourceFileHandle; -import com.etheller.warsmash.util.ImageUtils; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.Model; -import com.etheller.warsmash.viewer5.ModelInstance; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.RenderBatch; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.TextureMapper; -import com.etheller.warsmash.viewer5.handlers.ModelHandler; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; -import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraPreset; -import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraRates; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerUnitOrderListener; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.MeleeUI; - -public class WarsmashGdxMapScreen implements InputProcessor, Screen { - public static final boolean ENABLE_AUDIO = true; - private static final boolean ENABLE_MUSIC = false; - private final War3MapViewer viewer; - private final Rectangle tempRect = new Rectangle(); - - // libGDX stuff - private OrthographicCamera uiCamera; - private SpriteBatch batch; - private ExtendViewport uiViewport; - private GlyphLayout glyphLayout; - - private Texture solidGreenTexture; - - private ShapeRenderer shapeRenderer; - - private MdxModel timeIndicator; - - private Scene uiScene; - private MeleeUI meleeUI; - - private Music currentMusic; - private final WarsmashGdxMultiScreenGame screenManager; - private final WarsmashGdxMenuScreen menuScreen; - private final CPlayerUnitOrderListener uiOrderListener; - - public WarsmashGdxMapScreen(final War3MapViewer mapViewer, final WarsmashGdxMultiScreenGame screenManager, - final WarsmashGdxMenuScreen menuScreen, final CPlayerUnitOrderListener uiOrderListener) { - this.viewer = mapViewer; - this.screenManager = screenManager; - this.menuScreen = menuScreen; - this.uiOrderListener = uiOrderListener; - } - - /* - * (non-Javadoc) - * - * @see com.badlogic.gdx.ApplicationAdapter#create() - */ - @Override - public void show() { - - final ByteBuffer tempByteBuffer = ByteBuffer.allocateDirect(4); - tempByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final IntBuffer temp = tempByteBuffer.asIntBuffer(); - - Gdx.gl30.glGenVertexArrays(1, temp); - WarsmashGdxGame.VAO = temp.get(0); - - Gdx.gl30.glBindVertexArray(WarsmashGdxGame.VAO); - - final String renderer = Gdx.gl.glGetString(GL20.GL_RENDERER); - System.err.println("Renderer: " + renderer); - - final Element cameraData = this.viewer.miscData.get("Camera"); - Element cameraListenerData = this.viewer.miscData.get("Listener"); - if (cameraListenerData == null) { - cameraListenerData = new Element("Listener", new DataTable(null)); - } - final CameraPreset[] cameraPresets = new CameraPreset[6]; - for (int i = 0; i < cameraPresets.length; i++) { - cameraPresets[i] = new CameraPreset(cameraData.getFieldFloatValue("AOA", i), - cameraData.getFieldFloatValue("FOV", i), cameraData.getFieldFloatValue("Rotation", i), - cameraData.getFieldFloatValue("Rotation", i + cameraPresets.length), - cameraData.getFieldFloatValue("Rotation", i + (cameraPresets.length * 2)), - cameraData.getFieldFloatValue("Distance", i), cameraData.getFieldFloatValue("FarZ", i), - cameraData.getFieldFloatValue("NearZ", i), cameraData.getFieldFloatValue("Height", i), - cameraListenerData.getFieldFloatValue("ListenerDistance", i), - cameraListenerData.getFieldFloatValue("ListenerAOA", i)); - } - - System.out.println("Loaded"); - Gdx.gl30.glClearColor(0.0f, 0.0f, 0.0f, 1); // TODO remove white background - Gdx.gl30.glEnable(GL30.GL_SCISSOR_TEST); - - final Scene portraitScene = this.viewer.addSimpleScene(); - this.uiScene = this.viewer.addSimpleScene(); - this.uiScene.alpha = true; - if (ENABLE_AUDIO) { - this.uiScene.enableAudio(); - } - -// this.mainModel = (MdxModel) this.viewer.load("UI\\Glues\\MainMenu\\MainMenu3D_exp\\MainMenu3D_exp.mdx", - - // libGDX stuff - final int width = Gdx.graphics.getWidth(); - final int height = Gdx.graphics.getHeight(); - - this.glyphLayout = new GlyphLayout(); - - // Constructs a new OrthographicCamera, using the given viewport width and - // height - // Height is multiplied by aspect ratio. - this.uiCamera = new OrthographicCamera(); - int aspect3By4Width; - int aspect3By4Height; - if (width < ((height * 4) / 3)) { - aspect3By4Width = width; - aspect3By4Height = (width * 3) / 4; - } - else { - aspect3By4Width = (height * 4) / 3; - aspect3By4Height = height; - } - this.uiViewport = new ExtendViewport(aspect3By4Width, aspect3By4Height, this.uiCamera); - this.uiViewport.update(width, height); - - this.uiCamera.position.set(this.uiViewport.getMinWorldWidth() / 2, this.uiViewport.getMinWorldHeight() / 2, 0); - this.uiCamera.update(); - - this.batch = new SpriteBatch(); - -// this.consoleUITexture = new Texture(new DataSourceFileHandle(this.viewer.dataSource, "AlphaUi.png")); - - this.solidGreenTexture = ImageUtils.getAnyExtensionTexture(this.viewer.dataSource, - "ReplaceableTextures\\TeamColor\\TeamColor06.blp"); - - Gdx.input.setInputProcessor(this); - - this.shapeRenderer = new ShapeRenderer(); - -// Jass2.loadJUI(this.codebase, this.uiViewport, fontGenerator, this.uiScene, this.viewer, -// new RootFrameListener() { -// @Override -// public void onCreate(final GameUI rootFrame) { -// WarsmashGdxMapGame.this.gameUI = rootFrame; -// } -// }, "Scripts\\common.jui", "Scripts\\melee.jui"); - final Element cameraRatesElement = this.viewer.miscData.get("CameraRates"); - final CameraRates cameraRates = new CameraRates(cameraRatesElement.getFieldFloatValue("AOA"), - cameraRatesElement.getFieldFloatValue("FOV"), cameraRatesElement.getFieldFloatValue("Rotation"), - cameraRatesElement.getFieldFloatValue("Distance"), cameraRatesElement.getFieldFloatValue("Forward"), - cameraRatesElement.getFieldFloatValue("Strafe")); - this.meleeUI = new MeleeUI(this.viewer.mapMpq, this.uiViewport, this.uiScene, portraitScene, cameraPresets, - cameraRates, this.viewer, new RootFrameListener() { - @Override - public void onCreate(final GameUI rootFrame) { - WarsmashGdxMapScreen.this.viewer.setGameUI(rootFrame); - - if (ENABLE_MUSIC) { - final String musicField = rootFrame - .getSkinField("Music_V" + WarsmashConstants.GAME_VERSION); - final String[] musics = musicField.split(";"); - String musicPath = musics[(int) (Math.random() * musics.length)]; - if (false) { - musicPath = "Sound\\Music\\mp3Music\\PH1.mp3"; - } - final Music music = Gdx.audio.newMusic( - new DataSourceFileHandle(WarsmashGdxMapScreen.this.viewer.dataSource, musicPath)); - music.setVolume(1.0f); - music.setLooping(true); - music.play(); - WarsmashGdxMapScreen.this.currentMusic = music; - } - } - }, this.uiOrderListener, new Runnable() { - @Override - public void run() { - WarsmashGdxMapScreen.this.menuScreen.onReturnFromGame(); - WarsmashGdxMapScreen.this.screenManager.setScreen(WarsmashGdxMapScreen.this.menuScreen); - } - }); - this.viewer.getCommandErrorListener().setDelegate(this.meleeUI); - final ModelInstance libgdxContentInstance = new LibGDXContentLayerModel(null, this.viewer, "", - this.viewer.mapPathSolver, "").addInstance(); - libgdxContentInstance.setScene(this.uiScene); - this.meleeUI.main(); - - updateUIScene(); - - resize(width, height); - - try { - this.viewer.loadAfterUI(); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - public static DataSource parseDataSources(final DataTable warsmashIni) { - final Element dataSourcesConfig = warsmashIni.get("DataSources"); - final int dataSourcesCount = dataSourcesConfig.getFieldValue("Count"); - final List dataSourcesList = new ArrayList<>(); - for (int i = 0; i < dataSourcesCount; i++) { - final String type = dataSourcesConfig.getField("Type" + (i < 10 ? "0" : "") + i); - final String path = dataSourcesConfig.getField("Path" + (i < 10 ? "0" : "") + i); - switch (type) { - case "Folder": { - dataSourcesList.add(new FolderDataSourceDescriptor(path)); - break; - } - case "MPQ": { - dataSourcesList.add(new MpqDataSourceDescriptor(path)); - break; - } - case "CASC": { - final String prefixes = dataSourcesConfig.getField("Prefixes" + (i < 10 ? "0" : "") + i); - dataSourcesList.add(new CascDataSourceDescriptor(path, Arrays.asList(prefixes.split(",")))); - break; - } - default: - throw new RuntimeException("Unknown data source type: " + type); - } - } - return new CompoundDataSourceDescriptor(dataSourcesList).createDataSource(); - } - - private void updateUIScene() { - this.tempRect.x = this.uiViewport.getScreenX(); - this.tempRect.y = this.uiViewport.getScreenY(); - this.tempRect.width = this.uiViewport.getScreenWidth(); - this.tempRect.height = this.uiViewport.getScreenHeight(); - this.uiScene.camera.viewport(this.tempRect); - final float worldWidth = this.uiViewport.getWorldWidth(); - final float worldHeight = this.uiViewport.getWorldHeight(); - final float xScale = worldWidth / this.uiViewport.getMinWorldWidth(); - final float yScale = worldHeight / this.uiViewport.getMinWorldHeight(); - final float uiSceneWidth = 0.8f * xScale; - final float uiSceneHeight = 0.6f * yScale; - final float uiSceneX = ((0.8f - uiSceneWidth) / 2); - final float uiSceneY = ((0.6f - uiSceneHeight) / 2); - this.uiScene.camera.ortho(uiSceneX, uiSceneWidth + uiSceneX, uiSceneY, uiSceneHeight + uiSceneY, -1024f, 1024); - } - - @Override - public void render(final float delta) { - this.uiCamera.update(); - Gdx.gl30.glEnable(GL30.GL_SCISSOR_TEST); - final float deltaTime = Gdx.graphics.getDeltaTime(); - Gdx.gl30.glBindVertexArray(WarsmashGdxGame.VAO); - this.meleeUI.update(deltaTime); - this.viewer.updateAndRender(); - - Gdx.gl30.glDisable(GL30.GL_SCISSOR_TEST); - - Gdx.gl30.glDisable(GL30.GL_CULL_FACE); - - this.viewer.webGL.useShaderProgram(null); - - Gdx.gl30.glActiveTexture(GL30.GL_TEXTURE0); - } - - private void renderLibGDXContent() { - - Gdx.gl30.glDisable(GL30.GL_SCISSOR_TEST); - - Gdx.gl30.glDisable(GL30.GL_CULL_FACE); - - this.viewer.webGL.useShaderProgram(null); - - Gdx.gl30.glActiveTexture(GL30.GL_TEXTURE0); - - this.uiViewport.apply(); - this.batch.setProjectionMatrix(this.uiCamera.combined); - this.batch.begin(); - this.meleeUI.render(this.batch, this.glyphLayout); - this.batch.end(); - - Gdx.gl30.glEnable(GL30.GL_SCISSOR_TEST); - Gdx.gl30.glBindVertexArray(WarsmashGdxGame.VAO); - } - - @Override - public void dispose() { - this.meleeUI.dispose(); - } - - @Override - public void resize(final int width, final int height) { -// super.resize(width, height); - - this.uiViewport.update(width, height); - this.uiCamera.position.set(this.uiViewport.getMinWorldWidth() / 2, this.uiViewport.getMinWorldHeight() / 2, 0); - - this.meleeUI.resize(setupWorldFrameViewport(width, height)); - updateUIScene(); - - } - - private Rectangle setupWorldFrameViewport(final int width, final int height) { - this.tempRect.x = 0; - this.tempRect.width = width; - final float topHeight = 0.02666f * height; - final float bottomHeight = 0.21333f * height; - this.tempRect.y = (int) bottomHeight; - this.tempRect.height = height - (int) (topHeight + bottomHeight); - return this.tempRect; - } - - @Override - public boolean keyDown(final int keycode) { - this.meleeUI.keyDown(keycode); - return true; - } - - @Override - public boolean keyUp(final int keycode) { - this.meleeUI.keyUp(keycode); - return true; - } - - @Override - public boolean keyTyped(final char character) { - if (character == '1') { - Gdx.input.setCursorCatched(!Gdx.input.isCursorCatched()); - } - return false; - } - - @Override - public boolean touchDown(final int screenX, final int screenY, final int pointer, final int button) { - final float worldScreenY = this.viewer.canvas.getHeight() - screenY; - - if (this.meleeUI.touchDown(screenX, screenY, worldScreenY, button)) { - return false; - } - return false; - } - - @Override - public boolean touchUp(final int screenX, final int screenY, final int pointer, final int button) { - final float worldScreenY = this.viewer.canvas.getHeight() - screenY; - - if (this.meleeUI.touchUp(screenX, screenY, worldScreenY, button)) { - return false; - } - return false; - } - - @Override - public boolean touchDragged(final int screenX, final int screenY, final int pointer) { - final float worldScreenY = this.viewer.canvas.getHeight() - screenY; - if (this.meleeUI.touchDragged(screenX, screenY, worldScreenY, pointer)) { - return false; - } - return false; - } - - @Override - public boolean mouseMoved(final int screenX, final int screenY) { - final float worldScreenY = this.viewer.canvas.getHeight() - screenY; - if (this.meleeUI.mouseMoved(screenX, screenY, worldScreenY)) { - return false; - } - return false; - } - - @Override - public boolean scrolled(final int amount) { - this.meleeUI.scrolled(amount); - return true; - } - - private static class Message { - private final float time; - private final String text; - - public Message(final float time, final String text) { - this.time = time; - this.text = text; - } - } - - private class LibGDXContentLayerModelInstance extends ModelInstance { - - public LibGDXContentLayerModelInstance(final Model model) { - super(model); - } - - @Override - public void updateAnimations(final float dt) { - - } - - @Override - public void clearEmittedObjects() { - - } - - @Override - protected void updateLights(final Scene scene2) { - - } - - @Override - public void renderOpaque(final Matrix4 mvp) { - - } - - @Override - public void renderTranslucent() { - renderLibGDXContent(); - } - - @Override - public void load() { - } - - @Override - protected RenderBatch getBatch(final TextureMapper textureMapper2) { - throw new UnsupportedOperationException("NOT API"); - } - - @Override - public void setReplaceableTexture(final int replaceableTextureId, final String replaceableTextureFile) { - - } - - @Override - public boolean isBatched() { - return super.isBatched(); - } - - @Override - protected void removeLights(final Scene scene2) { - // TODO Auto-generated method stub - - } - - } - - private class LibGDXContentLayerModel extends Model { - - public LibGDXContentLayerModel(final ModelHandler handler, final ModelViewer viewer, final String extension, - final PathSolver pathSolver, final String fetchUrl) { - super(handler, viewer, extension, pathSolver, fetchUrl); - this.ok = true; - } - - @Override - protected ModelInstance createInstance(final int type) { - return new LibGDXContentLayerModelInstance(this); - } - - @Override - protected void lateLoad() { - } - - @Override - protected void load(final InputStream src, final Object options) { - } - - @Override - protected void error(final Exception e) { - } - - } - - @Override - public void pause() { - } - - @Override - public void resume() { - } - - @Override - public void hide() { - if (this.currentMusic != null) { - this.currentMusic.stop(); - } - } -} diff --git a/core/src/com/etheller/warsmash/WarsmashGdxMenuScreen.java b/core/src/com/etheller/warsmash/WarsmashGdxMenuScreen.java deleted file mode 100644 index 2faf476b..00000000 --- a/core/src/com/etheller/warsmash/WarsmashGdxMenuScreen.java +++ /dev/null @@ -1,882 +0,0 @@ -package com.etheller.warsmash; - -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.IntBuffer; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.InputProcessor; -import com.badlogic.gdx.Screen; -import com.badlogic.gdx.audio.Music; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.GL30; -import com.badlogic.gdx.graphics.OrthographicCamera; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Quaternion; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.utils.viewport.ExtendViewport; -import com.badlogic.gdx.utils.viewport.FitViewport; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.jass.Jass2.RootFrameListener; -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.util.DataSourceFileHandle; -import com.etheller.warsmash.util.ImageUtils; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.Camera; -import com.etheller.warsmash.viewer5.CanvasProvider; -import com.etheller.warsmash.viewer5.Model; -import com.etheller.warsmash.viewer5.ModelInstance; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.RenderBatch; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.SolvedPath; -import com.etheller.warsmash.viewer5.TextureMapper; -import com.etheller.warsmash.viewer5.handlers.ModelHandler; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxViewer; -import com.etheller.warsmash.viewer5.handlers.mdx.Sequence; -import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.MenuUI; - -public class WarsmashGdxMenuScreen implements InputProcessor, Screen, SingleModelScreen { - private static final boolean ENABLE_AUDIO = true; - private static final boolean ENABLE_MUSIC = true; - private DataSource codebase; - private MdxViewer viewer; - private MdxModel model; - private CameraManager cameraManager; - private final Rectangle tempRect = new Rectangle(); - - // libGDX stuff - private OrthographicCamera uiCamera; - private SpriteBatch batch; - private Viewport uiViewport; - private GlyphLayout glyphLayout; - - private final DataTable warsmashIni; - private Scene uiScene; - private Texture solidGreenTexture; - private MenuUI menuUI; - private final WarsmashGdxMultiScreenGame game; - private Music currentMusic; - private boolean hasPlayedStandHack = false; - private boolean loaded = false; - - public WarsmashGdxMenuScreen(final DataTable warsmashIni, final WarsmashGdxMultiScreenGame game) { - this.warsmashIni = warsmashIni; - this.game = game; - } - - @Override - public void show() { - if (!this.loaded) { - this.loaded = true; - final ByteBuffer tempByteBuffer = ByteBuffer.allocateDirect(4); - tempByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final IntBuffer temp = tempByteBuffer.asIntBuffer(); -// - Gdx.gl30.glGenVertexArrays(1, temp); - WarsmashGdxGame.VAO = temp.get(0); - - Gdx.gl30.glBindVertexArray(WarsmashGdxGame.VAO); - - final String renderer = Gdx.gl.glGetString(GL20.GL_RENDERER); - System.err.println("Renderer: " + renderer); - - this.codebase = WarsmashGdxMapScreen.parseDataSources(this.warsmashIni); - this.viewer = new MdxViewer(this.codebase, this.game, Vector3.Zero); - - this.viewer.addHandler(new MdxHandler()); - this.viewer.enableAudio(); - - this.scene = this.viewer.addSimpleScene(); - this.scene.enableAudio(); - - this.uiScene = this.viewer.addSimpleScene(); - this.uiScene.alpha = true; - if (ENABLE_AUDIO) { - this.uiScene.enableAudio(); - } - final int width = Gdx.graphics.getWidth(); - final int height = Gdx.graphics.getHeight(); - - this.glyphLayout = new GlyphLayout(); - - // Constructs a new OrthographicCamera, using the given viewport width and - // height - // Height is multiplied by aspect ratio. - this.uiCamera = new OrthographicCamera(); - int aspect3By4Width; - int aspect3By4Height; - if (width < ((height * 4) / 3)) { - aspect3By4Width = width; - aspect3By4Height = (width * 3) / 4; - } - else { - aspect3By4Width = (height * 4) / 3; - aspect3By4Height = height; - } - this.uiViewport = new FitViewport(aspect3By4Width, aspect3By4Height, this.uiCamera); - this.uiViewport.update(width, height); - - this.uiCamera.position.set(getMinWorldWidth() / 2, getMinWorldHeight() / 2, 0); - this.uiCamera.update(); - - this.batch = new SpriteBatch(); - -// this.consoleUITexture = new Texture(new DataSourceFileHandle(this.viewer.dataSource, "AlphaUi.png")); - - this.solidGreenTexture = ImageUtils.getAnyExtensionTexture(this.viewer.dataSource, - "ReplaceableTextures\\TeamColor\\TeamColor06.blp"); - - this.cameraManager = new CameraManager(); - this.cameraManager.setupCamera(this.scene); - -// this.mainModel = (MdxModel) this.viewer.load("Doodads\\Cinematic\\ArthasIllidanFight\\ArthasIllidanFight.mdx", -// this.mainModel = (MdxModel) this.viewer.load("UI\\Glues\\SinglePlayer\\NightElf_Exp\\NightElf_Exp.mdx", -// this.mainModel = (MdxModel) this.viewer.load("Abilities\\Spells\\Orc\\FeralSpirit\\feralspirittarget.mdx", -// new PathSolver() { -// @Override -// public SolvedPath solve(final String src, final Object solverParams) { -// return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); -// } -// }, null); - -// final EventObjectEmitterObject evt = this.mainModel.getEventObjects().get(1); -// for (final Sequence seq : this.mainModel.getSequences()) { -// System.out.println(seq.getName() + ": " + Arrays.toString(seq.getInterval())); -// } -// System.out.println(Arrays.toString(evt.keyFrames)); -// System.out.println(evt.name); - -// this.mainInstance = (MdxComplexInstance) this.mainModel.addInstance(0); - -// this.mainInstance.setScene(scene); -// -// final int animIndex = 0; -// this.modelCamera = this.mainModel.cameras.get(animIndex); -// this.mainInstance.setSequence(animIndex); -// -// this.mainInstance.setSequenceLoopMode(SequenceLoopMode.LOOP_TO_NEXT_ANIMATION); - -// acolytesHarvestingSceneJoke2(scene); - -// singleModelScene(scene, "Buildings\\Undead\\Necropolis\\Necropolis.mdx", "birth"); -// singleModelScene(scene, "Units\\Orc\\KotoBeast\\KotoBeast.mdx", "spell slam"); - - System.out.println("Loaded"); - Gdx.gl30.glClearColor(0.0f, 0.0f, 0.0f, 1); - - this.menuUI = new MenuUI(this.viewer.dataSource, this.uiViewport, this.uiScene, this.viewer, this.game, - this, this.warsmashIni, new RootFrameListener() { - @Override - public void onCreate(final GameUI rootFrame) { -// WarsmashGdxMapGame.this.viewer.setGameUI(rootFrame); - - if (ENABLE_MUSIC) { - final String musicField = rootFrame - .getSkinField("GlueMusic_V" + WarsmashConstants.GAME_VERSION); - final String[] musics = musicField.split(";"); - final String musicPath = musics[(int) (Math.random() * musics.length)]; - final Music music = Gdx.audio.newMusic(new DataSourceFileHandle( - WarsmashGdxMenuScreen.this.viewer.dataSource, musicPath)); -// music.setVolume(0.2f); - music.setLooping(true); - music.play(); - WarsmashGdxMenuScreen.this.currentMusic = music; - } - - singleModelScene(WarsmashGdxMenuScreen.this.scene, War3MapViewer.mdx(rootFrame - .getSkinField("GlueSpriteLayerBackground_V" + WarsmashConstants.GAME_VERSION)), - "Stand"); - WarsmashGdxMenuScreen.this.modelCamera = WarsmashGdxMenuScreen.this.mainModel.cameras - .get(0); - } - }); - - final ModelInstance libgdxContentInstance = new LibGDXContentLayerModel(null, this.viewer, "", - PathSolver.DEFAULT, "").addInstance(); - libgdxContentInstance.setLocation(0f, 0f, -0.5f); - libgdxContentInstance.setScene(this.uiScene); - this.menuUI.main(); - - updateUIScene(); - - resize(width, height); - } - - Gdx.input.setInputProcessor(this); - if (this.currentMusic != null) { - this.currentMusic.play(); - } - - } - - private float getMinWorldWidth() { - if (this.uiViewport instanceof ExtendViewport) { - return ((ExtendViewport) this.uiViewport).getMinWorldWidth(); - } - return this.uiViewport.getWorldWidth(); - } - - private float getMinWorldHeight() { - if (this.uiViewport instanceof ExtendViewport) { - return ((ExtendViewport) this.uiViewport).getMinWorldHeight(); - } - return this.uiViewport.getWorldHeight(); - } - - private void updateUIScene() { - this.tempRect.x = this.uiViewport.getScreenX(); - this.tempRect.y = this.uiViewport.getScreenY(); - this.tempRect.width = this.uiViewport.getScreenWidth(); - this.tempRect.height = this.uiViewport.getScreenHeight(); - this.uiScene.camera.viewport(this.tempRect); - final float worldWidth = this.uiViewport.getWorldWidth(); - final float worldHeight = this.uiViewport.getWorldHeight(); - final float xScale = worldWidth / getMinWorldWidth(); - final float yScale = worldHeight / getMinWorldHeight(); - final float uiSceneWidth = 0.8f * xScale; - final float uiSceneHeight = 0.6f * yScale; - final float uiSceneX = ((0.8f - uiSceneWidth) / 2); - final float uiSceneY = ((0.6f - uiSceneHeight) / 2); - this.uiScene.camera.ortho(uiSceneX, uiSceneWidth + uiSceneX, uiSceneY, uiSceneHeight + uiSceneY, -1024f, 1024); - } - - private void makeDruidSquare(final Scene scene) { - final MdxModel model2 = (MdxModel) this.viewer.load("units\\nightelf\\druidoftheclaw\\druidoftheclaw.mdx", - new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - makePerfectSquare(scene, model2, 15); - } - - private void singleAcolyteScene(final Scene scene) { - final MdxModel model2 = (MdxModel) this.viewer.load("units\\undead\\acolyte\\acolyte.mdx", new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - - final MdxComplexInstance instance3 = (MdxComplexInstance) model2.addInstance(0); - - instance3.setScene(scene); - - int animIndex = 0; - for (final Sequence s : model2.getSequences()) { - if (s.getName().toLowerCase().startsWith("stand work")) { - animIndex = model2.getSequences().indexOf(s); - } - } - instance3.setSequence(animIndex); - - instance3.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - } - - private void singleModelScene(final Scene scene, final String path, final String animName) { - final MdxModel model2 = (MdxModel) this.viewer.load(path, new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - - final MdxComplexInstance instance3 = (MdxComplexInstance) model2.addInstance(0); - - instance3.setScene(scene); - - int animIndex = 0; - for (final Sequence s : model2.getSequences()) { - if (s.getName().toLowerCase().startsWith(animName)) { - animIndex = model2.getSequences().indexOf(s); - break; - } - } - instance3.setSequence(animIndex); - - instance3.setSequenceLoopMode(SequenceLoopMode.NEVER_LOOP); - this.mainInstance = instance3; - this.mainModel = model2; - } - - @Override - public void setModel(final String path) { - if (this.mainInstance != null) { - this.mainInstance.detach(); - } - if (path == null) { - this.modelCamera = null; - this.mainInstance = null; - this.mainModel = null; - } - else { - singleModelScene(this.scene, War3MapViewer.mdx(path), "birth"); - WarsmashGdxMenuScreen.this.modelCamera = WarsmashGdxMenuScreen.this.mainModel.cameras.get(0); - // this hack is because we only have the queued animation system in RenderWidget - // which is stupid and back and needs to get moved to the model instance - // itself... our model instance class is a - // hacky replica of a model viewer tool with a bunch of irrelevant loop type - // settings instead of what it should be - this.hasPlayedStandHack = false; - } - - } - - private void acolytesHarvestingScene(final Scene scene) { - - final MdxModel acolyteModel = (MdxModel) this.viewer.load("units\\undead\\acolyte\\acolyte.mdx", - new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - final MdxModel mineEffectModel = (MdxModel) this.viewer - .load("abilities\\spells\\undead\\undeadmine\\undeadminecircle.mdx", new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - for (int i = 0; i < 5; i++) { - final MdxComplexInstance acolyteInstance = (MdxComplexInstance) acolyteModel.addInstance(0); - - acolyteInstance.setScene(scene); - - int animIndex = i % acolyteModel.getSequences().size(); - for (final Sequence s : acolyteModel.getSequences()) { - if (s.getName().toLowerCase().startsWith("stand work")) { - animIndex = acolyteModel.getSequences().indexOf(s); - } - } - acolyteInstance.setSequence(animIndex); - - acolyteInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - - final double angle = ((Math.PI * 2) / 5) * i; - acolyteInstance.localLocation.x = (float) Math.cos(angle) * 256; - acolyteInstance.localLocation.y = (float) Math.sin(angle) * 256; - acolyteInstance.localRotation.setFromAxisRad(0, 0, 1, (float) (angle + Math.PI)); - - final MdxComplexInstance effectInstance = (MdxComplexInstance) mineEffectModel.addInstance(0); - - effectInstance.setScene(scene); - - effectInstance.setSequence(1); - - effectInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - effectInstance.localLocation.x = (float) Math.cos(angle) * 256; - effectInstance.localLocation.y = (float) Math.sin(angle) * 256; - effectInstance.localRotation.setFromAxisRad(0, 0, 1, (float) (angle)); - - } - final MdxModel mineModel = (MdxModel) this.viewer.load("buildings\\undead\\hauntedmine\\hauntedmine.mdx", - new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - final MdxComplexInstance mineInstance = (MdxComplexInstance) mineModel.addInstance(0); - - mineInstance.setScene(scene); - - mineInstance.setSequence(2); - - mineInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - } - - private void acolytesHarvestingSceneJoke2(final Scene scene) { - - final MdxModel acolyteModel = (MdxModel) this.viewer.load("units\\undead\\acolyte\\acolyte.mdx", - new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - final MdxModel mineEffectModel = (MdxModel) this.viewer - .load("abilities\\spells\\undead\\undeadmine\\undeadminecircle.mdx", new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - for (int i = 0; i < 5; i++) { - final MdxComplexInstance acolyteInstance = (MdxComplexInstance) acolyteModel.addInstance(0); - - acolyteInstance.setScene(scene); - - int animIndex = i % acolyteModel.getSequences().size(); - for (final Sequence s : acolyteModel.getSequences()) { - if (s.getName().toLowerCase().startsWith("stand work")) { - animIndex = acolyteModel.getSequences().indexOf(s); - } - } - acolyteInstance.setSequence(animIndex); - - acolyteInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - - final double angle = ((Math.PI * 2) / 5) * i; - acolyteInstance.localLocation.x = (float) Math.cos(angle) * 256; - acolyteInstance.localLocation.y = (float) Math.sin(angle) * 256; - acolyteInstance.localRotation.setFromAxisRad(0, 0, 1, (float) (angle + Math.PI)); - - final MdxComplexInstance effectInstance = (MdxComplexInstance) mineEffectModel.addInstance(0); - - effectInstance.setScene(scene); - - effectInstance.setSequence(1); - - effectInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - effectInstance.localLocation.x = (float) Math.cos(angle) * 256; - effectInstance.localLocation.y = (float) Math.sin(angle) * 256; - effectInstance.localRotation.setFromAxisRad(0, 0, 1, (float) (angle)); - - } - final MdxModel mineModel = (MdxModel) this.viewer.load("units\\orc\\spiritwolf\\spiritwolf.mdx", - new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - final MdxComplexInstance mineInstance = (MdxComplexInstance) mineModel.addInstance(0); - - mineInstance.setScene(scene); - - mineInstance.setSequence(0); - mineInstance.localScale.x = 2; - mineInstance.localScale.y = 2; - mineInstance.localScale.z = 2; - - mineInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - final MdxModel mineModel2 = (MdxModel) this.viewer - .load("abilities\\spells\\undead\\unsummon\\unsummontarget.mdx", new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - return new SolvedPath(src, src.substring(src.lastIndexOf('.')), true); - } - }, null); - final MdxComplexInstance mineInstance2 = (MdxComplexInstance) mineModel2.addInstance(0); - - mineInstance2.setScene(scene); - - mineInstance2.setSequence(0); - - mineInstance2.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - } - - private void makeFourHundred(final Scene scene, final MdxModel model2) { - for (int i = 0; i < 400; i++) { - final MdxComplexInstance instance3 = (MdxComplexInstance) model2.addInstance(0); - instance3.localLocation.x = (((i % 20) - 10) * 128); - instance3.localLocation.y = (((i / 20) - 10) * 128); - - instance3.setScene(scene); - - final int animIndex = i % model2.getSequences().size(); - instance3.setSequence(animIndex); - - instance3.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - } - } - - private void makePerfectSquare(final Scene scene, final MdxModel model2, final int n) { - final int n2 = n * n; - for (int i = 0; i < n2; i++) { - final MdxComplexInstance instance3 = (MdxComplexInstance) model2.addInstance(0); - instance3.localLocation.x = (((i % n) - (n / 2)) * 128); - instance3.localLocation.y = (((i / n) - (n / 2)) * 128); - - instance3.setScene(scene); - - final int animIndex = i % model2.getSequences().size(); - instance3.setSequence(animIndex); - - instance3.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - } - } - - public static void bindDefaultVertexArray() { - Gdx.gl30.glBindVertexArray(WarsmashGdxGame.VAO); - } - - private final int frame = 0; - private MdxComplexInstance mainInstance; - private MdxModel mainModel; - private com.etheller.warsmash.viewer5.handlers.mdx.Camera modelCamera; - private final float[] cameraPositionTemp = new float[3]; - private final float[] cameraTargetTemp = new float[3]; - private final boolean firstFrame = true; - private Scene scene; - - @Override - public void render(final float delta) { - - Gdx.gl30.glEnable(GL30.GL_SCISSOR_TEST); - final float deltaTime = Gdx.graphics.getDeltaTime(); - Gdx.gl30.glBindVertexArray(WarsmashGdxGame.VAO); - this.cameraManager.updateCamera(); - this.menuUI.update(deltaTime); - if ((this.mainInstance != null) && this.mainInstance.sequenceEnded - && (((this.mainModel.getSequences().get(this.mainInstance.sequence).getFlags() & 0x1) == 0) - || !this.hasPlayedStandHack)) { - SequenceUtils.randomStandSequence(this.mainInstance); - this.hasPlayedStandHack = true; - } - this.viewer.updateAndRender(); - - Gdx.gl30.glDisable(GL30.GL_SCISSOR_TEST); - - Gdx.gl30.glDisable(GL30.GL_CULL_FACE); - - this.viewer.webGL.useShaderProgram(null); - - Gdx.gl30.glActiveTexture(GL30.GL_TEXTURE0); - } - - @Override - public void dispose() { - this.menuUI.dispose(); - } - - @Override - public void resize(final int width, final int height) { - this.tempRect.width = width; - this.tempRect.height = height; - final float fourThirdsHeight = (this.tempRect.height * 4) / 3; - if (fourThirdsHeight < this.tempRect.width) { - final float dx = this.tempRect.width - fourThirdsHeight; - this.tempRect.width = fourThirdsHeight; - this.tempRect.x = dx / 2; - } - else { - final float threeFourthsWidth = (this.tempRect.width * 3) / 4; - if (threeFourthsWidth < this.tempRect.height) { - final float dy = this.tempRect.height - threeFourthsWidth; - this.tempRect.height = threeFourthsWidth; - this.tempRect.y = dy; - } - } - this.cameraManager.camera.viewport(this.tempRect); - -// super.resize(width, height); - - this.uiViewport.update(width, height); - this.uiCamera.position.set(getMinWorldWidth() / 2, getMinWorldHeight() / 2, 0); - - this.menuUI.resize(); - updateUIScene(); - - } - - class CameraManager { - private CanvasProvider canvas; - private Camera camera; - private float moveSpeed; - private float rotationSpeed; - private float zoomFactor; - private float horizontalAngle; - private float verticalAngle; - private float distance; - private Vector3 position; - private Vector3 target; - private Vector3 worldUp; - private Vector3 vecHeap; - private Vector3 vecHeap2; - private Quaternion quatHeap; - private Quaternion quatHeap2; - - // An orbit camera setup example. - // Left mouse button controls the orbit itself. - // The right mouse button allows to move the camera and the point it's looking - // at on the XY plane. - // Scrolling zooms in and out. - private void setupCamera(final Scene scene) { - this.canvas = scene.viewer.canvas; - this.camera = scene.camera; - this.moveSpeed = 2; - this.rotationSpeed = (float) (Math.PI / 180); - this.zoomFactor = 0.1f; - this.horizontalAngle = (float) (Math.PI / 2); - this.verticalAngle = (float) (Math.PI / 4); - this.distance = 500; - this.position = new Vector3(); - this.target = new Vector3(0, 0, 50); - this.worldUp = new Vector3(0, 0, 1); - this.vecHeap = new Vector3(); - this.vecHeap2 = new Vector3(); - this.quatHeap = new Quaternion(); - this.quatHeap2 = new Quaternion(); - - updateCamera(); - -// cameraUpdate(); - } - - private void updateCamera() { - // Limit the vertical angle so it doesn't flip. - // Since the camera uses a quaternion, flips don't matter to it, but this feels - // better. - this.verticalAngle = (float) Math.min(Math.max(0.01, this.verticalAngle), Math.PI - 0.01); - - this.quatHeap.idt(); - this.quatHeap.setFromAxisRad(0, 0, 1, this.horizontalAngle); - this.quatHeap2.idt(); - this.quatHeap2.setFromAxisRad(1, 0, 0, this.verticalAngle); - this.quatHeap.mul(this.quatHeap2); - - this.position.set(0, 0, 1); - this.quatHeap.transform(this.position); - this.position.scl(this.distance); - this.position = this.position.add(this.target); - if (WarsmashGdxMenuScreen.this.modelCamera != null) { - WarsmashGdxMenuScreen.this.modelCamera.getPositionTranslation( - WarsmashGdxMenuScreen.this.cameraPositionTemp, WarsmashGdxMenuScreen.this.mainInstance.sequence, - WarsmashGdxMenuScreen.this.mainInstance.frame, WarsmashGdxMenuScreen.this.mainInstance.counter); - WarsmashGdxMenuScreen.this.modelCamera.getTargetTranslation(WarsmashGdxMenuScreen.this.cameraTargetTemp, - WarsmashGdxMenuScreen.this.mainInstance.sequence, WarsmashGdxMenuScreen.this.mainInstance.frame, - WarsmashGdxMenuScreen.this.mainInstance.counter); - - this.position.set(WarsmashGdxMenuScreen.this.modelCamera.position); - this.target.set(WarsmashGdxMenuScreen.this.modelCamera.targetPosition); -// this.vecHeap2.set(this.target); -// this.vecHeap2.sub(this.position); -// this.vecHeap.set(this.vecHeap2); -// this.vecHeap.crs(this.worldUp); -// this.vecHeap.crs(this.vecHeap2); -// this.vecHeap.nor(); -// this.vecHeap.scl(this.camera.rect.height / 2f); -// this.position.add(this.vecHeap); - - this.position.add(WarsmashGdxMenuScreen.this.cameraPositionTemp[0], - WarsmashGdxMenuScreen.this.cameraPositionTemp[1], - WarsmashGdxMenuScreen.this.cameraPositionTemp[2]); - this.target.add(WarsmashGdxMenuScreen.this.cameraTargetTemp[0], - WarsmashGdxMenuScreen.this.cameraTargetTemp[1], WarsmashGdxMenuScreen.this.cameraTargetTemp[2]); - this.camera.perspective(WarsmashGdxMenuScreen.this.modelCamera.fieldOfView * 0.6f, - this.camera.rect.width / this.camera.rect.height, - WarsmashGdxMenuScreen.this.modelCamera.nearClippingPlane, - WarsmashGdxMenuScreen.this.modelCamera.farClippingPlane); - } - else { - this.camera.perspective(70, this.camera.getAspect(), 100, 5000); - } - - this.camera.moveToAndFace(this.position, this.target, this.worldUp); - } - -// private void cameraUpdate() { -// -// } - } - - public DataSource getCodebase() { - return this.codebase; - } - - @Override - public boolean keyDown(final int keycode) { - return this.menuUI.keyDown(keycode); - } - - @Override - public boolean keyUp(final int keycode) { - return this.menuUI.keyUp(keycode); - } - - @Override - public boolean keyTyped(final char character) { - return this.menuUI.keyTyped(character); - } - - @Override - public boolean touchDown(final int screenX, final int screenY, final int pointer, final int button) { - final float worldScreenY = this.game.getHeight() - screenY; - - if (this.menuUI.touchDown(screenX, screenY, worldScreenY, button)) { - return false; - } - return false; - } - - @Override - public boolean touchUp(final int screenX, final int screenY, final int pointer, final int button) { - final float worldScreenY = this.game.getHeight() - screenY; - - if (this.menuUI.touchUp(screenX, screenY, worldScreenY, button)) { - return false; - } - return false; - } - - @Override - public boolean touchDragged(final int screenX, final int screenY, final int pointer) { - final float worldScreenY = this.game.getHeight() - screenY; - if (this.menuUI.touchDragged(screenX, screenY, worldScreenY, pointer)) { - return false; - } - return false; - } - - @Override - public boolean mouseMoved(final int screenX, final int screenY) { - final float worldScreenY = this.game.getHeight() - screenY; - if (this.menuUI.mouseMoved(screenX, screenY, worldScreenY)) { - return false; - } - return false; - } - - @Override - public boolean scrolled(final int amount) { - // TODO Auto-generated method stub - return false; - } - - private void renderLibGDXContent() { - - Gdx.gl30.glDisable(GL30.GL_SCISSOR_TEST); - - Gdx.gl30.glDisable(GL30.GL_CULL_FACE); - - this.viewer.webGL.useShaderProgram(null); - - Gdx.gl30.glActiveTexture(GL30.GL_TEXTURE0); - - this.uiViewport.apply(); - this.batch.setProjectionMatrix(this.uiCamera.combined); - this.batch.begin(); - this.menuUI.render(this.batch, this.glyphLayout); - this.batch.end(); - - Gdx.gl30.glEnable(GL30.GL_SCISSOR_TEST); - Gdx.gl30.glBindVertexArray(WarsmashGdxGame.VAO); - } - - private class LibGDXContentLayerModelInstance extends ModelInstance { - - public LibGDXContentLayerModelInstance(final Model model) { - super(model); - } - - @Override - public void updateAnimations(final float dt) { - - } - - @Override - public void clearEmittedObjects() { - - } - - @Override - protected void updateLights(final Scene scene2) { - - } - - @Override - public void renderOpaque(final Matrix4 mvp) { - - } - - @Override - public void renderTranslucent() { - renderLibGDXContent(); - } - - @Override - public void load() { - } - - @Override - protected RenderBatch getBatch(final TextureMapper textureMapper2) { - throw new UnsupportedOperationException("NOT API"); - } - - @Override - public void setReplaceableTexture(final int replaceableTextureId, final String replaceableTextureFile) { - - } - - @Override - public boolean isBatched() { - return super.isBatched(); - } - - @Override - protected void removeLights(final Scene scene2) { - // TODO Auto-generated method stub - - } - - } - - private class LibGDXContentLayerModel extends Model { - - public LibGDXContentLayerModel(final ModelHandler handler, final ModelViewer viewer, final String extension, - final PathSolver pathSolver, final String fetchUrl) { - super(handler, viewer, extension, pathSolver, fetchUrl); - this.ok = true; - } - - @Override - protected ModelInstance createInstance(final int type) { - return new LibGDXContentLayerModelInstance(this); - } - - @Override - protected void lateLoad() { - } - - @Override - protected void load(final InputStream src, final Object options) { - } - - @Override - protected void error(final Exception e) { - } - - } - - @Override - public void hide() { - if (this.currentMusic != null) { - this.currentMusic.stop(); - } - this.menuUI.hide(); - } - - @Override - public void pause() { - } - - @Override - public void resume() { - } - - public void startMap(final String finalFileToLoad) { - this.menuUI.startMap(finalFileToLoad); - } - - public void onReturnFromGame() { - this.menuUI.onReturnFromGame(); - } -} diff --git a/core/src/com/etheller/warsmash/WarsmashGdxMultiScreenGame.java b/core/src/com/etheller/warsmash/WarsmashGdxMultiScreenGame.java deleted file mode 100644 index 2ba3bb47..00000000 --- a/core/src/com/etheller/warsmash/WarsmashGdxMultiScreenGame.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.etheller.warsmash; - -import com.badlogic.gdx.Game; -import com.badlogic.gdx.Gdx; -import com.etheller.warsmash.viewer5.CanvasProvider; - -public class WarsmashGdxMultiScreenGame extends Game implements CanvasProvider { - - @Override - public void create() { - } - - @Override - public float getWidth() { - return Gdx.graphics.getWidth(); - } - - @Override - public float getHeight() { - return Gdx.graphics.getHeight(); - } - -} diff --git a/core/src/com/etheller/warsmash/WarsmashPreviewApplication.java b/core/src/com/etheller/warsmash/WarsmashPreviewApplication.java deleted file mode 100644 index 36d628a5..00000000 --- a/core/src/com/etheller/warsmash/WarsmashPreviewApplication.java +++ /dev/null @@ -1,177 +0,0 @@ -package com.etheller.warsmash; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.IntBuffer; - -import com.badlogic.gdx.ApplicationAdapter; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.viewer5.CanvasProvider; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.handlers.ResourceHandlerConstructionParams; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxViewer; -import com.etheller.warsmash.viewer5.handlers.w3x.camera.PortraitCameraManager; -import com.hiveworkshop.rms.parsers.mdlx.MdlxModel; -import com.hiveworkshop.rms.parsers.mdlx.util.MdxUtils; - -public class WarsmashPreviewApplication extends ApplicationAdapter implements CanvasProvider { - private DataSource codebase; - private ModelViewer viewer; - private MdxModel model; - private PortraitCameraManager cameraManager; - public static int VAO; - private final Rectangle tempRect = new Rectangle(); - - private BitmapFont font; - private SpriteBatch batch; - private final DataTable warsmashIni; - - public WarsmashPreviewApplication(final DataTable warsmashIni) { - this.warsmashIni = warsmashIni; - } - - @Override - public void create() { - - final ByteBuffer tempByteBuffer = ByteBuffer.allocateDirect(4); - tempByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final IntBuffer temp = tempByteBuffer.asIntBuffer(); -// - Gdx.gl30.glGenVertexArrays(1, temp); - VAO = temp.get(0); - - Gdx.gl30.glBindVertexArray(VAO); - - final String renderer = Gdx.gl.glGetString(GL20.GL_RENDERER); - System.err.println("Renderer: " + renderer); - - this.codebase = WarsmashGdxMapScreen.parseDataSources(this.warsmashIni); - this.viewer = new MdxViewer(this.codebase, this, new Vector3(0.3f, 0.3f, -0.25f)); - - this.mdxHandler = new MdxHandler(); - this.viewer.addHandler(this.mdxHandler); - this.viewer.enableAudio(); - - this.scene = this.viewer.addSimpleScene(); - this.scene.enableAudio(); - - this.cameraManager = new PortraitCameraManager(); - this.cameraManager.setupCamera(this.scene); - this.cameraManager.distance = 500; - this.cameraManager.horizontalAngle = (float) ((Math.PI) / 2); - - System.out.println("Loaded"); - Gdx.gl30.glClearColor(0.5f, 0.5f, 0.5f, 1); // TODO remove white background - - this.font = new BitmapFont(); - this.batch = new SpriteBatch(); - } - - public static void bindDefaultVertexArray() { - Gdx.gl30.glBindVertexArray(VAO); - } - - private int frame = 0; - private MdxComplexInstance mainInstance; - private MdxModel mainModel; - private com.etheller.warsmash.viewer5.handlers.mdx.Camera modelCamera; - private final float[] cameraPositionTemp = new float[3]; - private final float[] cameraTargetTemp = new float[3]; - private final boolean firstFrame = true; - private Scene scene; - private MdxHandler mdxHandler; - - @Override - public void render() { - Gdx.gl30.glBindVertexArray(VAO); - this.cameraManager.updateCamera(); - this.viewer.updateAndRender(); - - this.frame++; - if ((this.frame % 1000) == 0) { - System.out.println(Integer.toString(Gdx.graphics.getFramesPerSecond())); - } - - } - - @Override - public void dispose() { - } - - @Override - public float getWidth() { - return Gdx.graphics.getWidth(); - } - - @Override - public float getHeight() { - return Gdx.graphics.getHeight(); - } - - @Override - public void resize(final int width, final int height) { - this.tempRect.width = width; - this.tempRect.height = height; - this.cameraManager.camera.viewport(this.tempRect); - } - - public DataSource getCodebase() { - return this.codebase; - } - - public MdlxModel loadCustomModel(final String filename) { - clearMainInstance(); - final MdxModel mdx = (MdxModel) this.mdxHandler.construct(new ResourceHandlerConstructionParams(this.viewer, - this.mdxHandler, ".mdx", PathSolver.DEFAULT, filename)); - final MdlxModel mdlxModel; - try (FileInputStream stream = new FileInputStream(filename)) { - mdlxModel = MdxUtils.loadMdlx(stream); - mdx.load(mdlxModel); - mdx.ok = true; -// mdx.lateLoad(); - } - catch (final FileNotFoundException e) { - throw new RuntimeException(e); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - this.mainModel = mdx; - final MdxComplexInstance instance = (MdxComplexInstance) mdx.addInstance(); -// this.cameraManager.setModelInstance(instance, mdx); - instance.setScene(this.scene); - this.mainInstance = instance; - return mdlxModel; - } - - private void clearMainInstance() { - if (this.mainInstance != null) { - this.mainInstance.detach(); - this.mainInstance = null; - } - this.mainModel = null; - } - - public PortraitCameraManager getCameraManager() { - return this.cameraManager; - } - - public MdxComplexInstance getMainInstance() { - return this.mainInstance; - } -} diff --git a/core/src/com/etheller/warsmash/WarsmashTestGame.java b/core/src/com/etheller/warsmash/WarsmashTestGame.java deleted file mode 100644 index 635aac10..00000000 --- a/core/src/com/etheller/warsmash/WarsmashTestGame.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.etheller.warsmash; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.nio.ShortBuffer; - -import com.badlogic.gdx.ApplicationAdapter; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; - -public class WarsmashTestGame extends ApplicationAdapter { - private int arrayBuffer; - private int elementBuffer; - private int VAO; - - @Override - public void create() { - Gdx.gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // colour to use when clearing - - final ByteBuffer tempByteBuffer = ByteBuffer.allocateDirect(4); - tempByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final IntBuffer temp = tempByteBuffer.asIntBuffer(); - - Gdx.gl30.glGenVertexArrays(1, temp); - this.VAO = temp.get(0); - - Gdx.gl30.glBindVertexArray(this.VAO); - - this.shaderProgram = new ShaderProgram(vsSimple, fsSimple); - if (!this.shaderProgram.isCompiled()) { - throw new IllegalStateException(this.shaderProgram.getLog()); - } - - this.arrayBuffer = Gdx.gl.glGenBuffer(); - this.elementBuffer = Gdx.gl.glGenBuffer(); - System.out.println("arrayBuffer: " + this.arrayBuffer + ", elementBuffer: " + this.elementBuffer); - - Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.arrayBuffer); - - this.shaderProgram.enableVertexAttribute("a_position"); - this.shaderProgram.setVertexAttribute("a_position", 3, GL20.GL_FLOAT, false, 0, 0); - - Gdx.gl.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, this.elementBuffer); - - final ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(4 * 9); - vertexByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - this.vertexBuffer = vertexByteBuffer.asFloatBuffer(); - - this.vertexBuffer.put(0, -1f); - this.vertexBuffer.put(1, -1f); - this.vertexBuffer.put(2, 0); - this.vertexBuffer.put(3, 1f); - this.vertexBuffer.put(4, -1f); - this.vertexBuffer.put(5, 0); - this.vertexBuffer.put(6, 0f); - this.vertexBuffer.put(7, 1f); - this.vertexBuffer.put(8, 0); - - Gdx.gl.glBufferData(GL20.GL_ARRAY_BUFFER, 9 * 4, null, GL20.GL_STATIC_DRAW); - - final ByteBuffer faceByteBuffer = ByteBuffer.allocateDirect(6); - faceByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - this.faceBuffer = faceByteBuffer.asShortBuffer(); - - this.faceBuffer.put(0, (short) 0); - this.faceBuffer.put(1, (short) 1); - this.faceBuffer.put(2, (short) 2); - - Gdx.gl.glBufferData(GL20.GL_ELEMENT_ARRAY_BUFFER, 3 * 2, null, GL20.GL_STATIC_DRAW); - - } - - @Override - public void render() { - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); - -// Gdx.gl30.glBindVertexArray(this.VAO); - this.shaderProgram.begin(); - Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.arrayBuffer); - Gdx.gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, 0, 9 * 4, this.vertexBuffer); - Gdx.gl.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, this.elementBuffer); - Gdx.gl.glBufferSubData(GL20.GL_ELEMENT_ARRAY_BUFFER, 0, 3 * 2, this.faceBuffer); - Gdx.gl.glDrawElements(GL20.GL_TRIANGLES, 9, GL20.GL_UNSIGNED_SHORT, 0); -// Gdx.gl.glDrawArrays(GL20.GL_TRIANGLES, 0, 3); - this.shaderProgram.end(); - } - - @Override - public void dispose() { - } - - @Override - public void resize(final int width, final int height) { - } - - public static final String vsSimple = "\r\n" + // - " attribute vec3 a_position;\r\n" + // - " void main() {\r\n" + // - " gl_Position = vec4(a_position, 1.0);\r\n" + // - " }\r\n"; - - public static final String fsSimple = "\r\n" + // - " void main() {\r\n" + // - " gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);\r\n" + // - " }\r\n"; - private ShaderProgram shaderProgram; - private FloatBuffer vertexBuffer; - private ShortBuffer faceBuffer; - -} diff --git a/core/src/com/etheller/warsmash/WarsmashTestGame2.java b/core/src/com/etheller/warsmash/WarsmashTestGame2.java deleted file mode 100644 index 82612840..00000000 --- a/core/src/com/etheller/warsmash/WarsmashTestGame2.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.etheller.warsmash; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; - -import com.badlogic.gdx.ApplicationAdapter; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.GL30; - -public class WarsmashTestGame2 extends ApplicationAdapter { - private int VBO; - private int VAO; - - @Override - public void create() { - final ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(4 * 9); - vertexByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final FloatBuffer vertexBuffer = vertexByteBuffer.asFloatBuffer(); - - vertexBuffer.put(0, -0.5f); - vertexBuffer.put(1, -0.5f); - vertexBuffer.put(2, 0); - vertexBuffer.put(3, 0.5f); - vertexBuffer.put(4, -0.5f); - vertexBuffer.put(5, 0); - vertexBuffer.put(6, 0f); - vertexBuffer.put(7, 0.5f); - vertexBuffer.put(8, 0); - vertexBuffer.clear(); - - Gdx.gl30.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - Gdx.gl30.glEnable(GL20.GL_DEPTH_TEST); -// Gdx.gl30.glEnable(GL20.GL_CULL_FACE); - - final ByteBuffer tempByteBuffer = ByteBuffer.allocateDirect(4); - System.out.println(tempByteBuffer.order()); - tempByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final IntBuffer temp = tempByteBuffer.asIntBuffer(); - - Gdx.gl30.glGenBuffers(1, temp); - this.VBO = temp.get(0); - - temp.clear(); - Gdx.gl30.glGenVertexArrays(1, temp); - this.VAO = temp.get(0); - - Gdx.gl30.glBindVertexArray(this.VAO); - - Gdx.gl30.glBindBuffer(GL30.GL_ARRAY_BUFFER, this.VBO); - Gdx.gl30.glBufferData(GL30.GL_ARRAY_BUFFER, 9 * 4, vertexByteBuffer, GL30.GL_STATIC_DRAW); - - Gdx.gl30.glVertexAttribPointer(0, 3, GL30.GL_FLOAT, false, 3 * 4, 0); - Gdx.gl30.glEnableVertexAttribArray(0); - - final int vertexShader = Gdx.gl30.glCreateShader(GL30.GL_VERTEX_SHADER); - Gdx.gl30.glShaderSource(vertexShader, vsSimple); - Gdx.gl30.glCompileShader(vertexShader); - - temp.clear(); - Gdx.gl30.glGetShaderiv(vertexShader, GL30.GL_COMPILE_STATUS, temp); - int success = temp.get(0); - if (success == 0) { - final String infoLog = Gdx.gl30.glGetShaderInfoLog(vertexShader); - System.err.println(infoLog); - throw new IllegalStateException("bad vertex shader"); - } - - final int fragmentShader = Gdx.gl30.glCreateShader(GL30.GL_FRAGMENT_SHADER); - Gdx.gl30.glShaderSource(fragmentShader, fsSimple); - Gdx.gl30.glCompileShader(fragmentShader); - - temp.clear(); - Gdx.gl30.glGetShaderiv(fragmentShader, GL30.GL_COMPILE_STATUS, temp); - success = temp.get(0); - if (success == 0) { - final String infoLog = Gdx.gl30.glGetShaderInfoLog(fragmentShader); - System.err.println(infoLog); - throw new IllegalStateException("bad fragment shader"); - } - - this.shaderProgram = Gdx.gl30.glCreateProgram(); - - Gdx.gl30.glAttachShader(this.shaderProgram, vertexShader); - Gdx.gl30.glAttachShader(this.shaderProgram, fragmentShader); - Gdx.gl30.glLinkProgram(this.shaderProgram); - - temp.clear(); - Gdx.gl30.glGetProgramiv(this.shaderProgram, GL30.GL_LINK_STATUS, temp); - success = temp.get(0); - if (success == 0) { - final String infoLog = Gdx.gl30.glGetProgramInfoLog(this.shaderProgram); - System.err.println(infoLog); - throw new IllegalStateException("bad program"); - } - - Gdx.gl30.glDeleteShader(vertexShader); - Gdx.gl30.glDeleteShader(fragmentShader); - } - - @Override - public void render() { - Gdx.gl30.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); - Gdx.gl30.glUseProgram(this.shaderProgram); - Gdx.gl30.glBindVertexArray(this.VAO); - - Gdx.gl30.glDrawArrays(GL30.GL_TRIANGLES, 0, 3); - } - - @Override - public void dispose() { - } - - @Override - public void resize(final int width, final int height) { - final int side = Math.min(width, height); - Gdx.gl30.glViewport((width - side) / 2, (height - side) / 2, side, side); - - } - - public static final String vsSimple = "\r\n" + // - "#version 450 core\r\n" + // - " layout(location = 0) in vec3 aPos;\r\n" + // - " void main() {\r\n" + // - " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\r\n" + // - " }\r\n"; - - public static final String fsSimple = "\r\n" + // - "#version 450 core\r\n" + // - " out vec4 FragColor;\r\n" + // - " void main() {\r\n" + // - " FragColor = vec4(0.2f, 1.0f, 0.2f, 1.0f);\r\n" + // - " }\r\n"; - private int shaderProgram; - -} diff --git a/core/src/com/etheller/warsmash/WarsmashTestGame3.java b/core/src/com/etheller/warsmash/WarsmashTestGame3.java deleted file mode 100644 index f2b0ee7b..00000000 --- a/core/src/com/etheller/warsmash/WarsmashTestGame3.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.etheller.warsmash; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; - -import com.badlogic.gdx.ApplicationAdapter; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.GL30; - -public class WarsmashTestGame3 extends ApplicationAdapter { - private int VBO; - private int VAO; - - @Override - public void create() { - Gdx.gl30.glBindVertexArray(0); - - this.vertexByteBuffer = ByteBuffer.allocateDirect(4 * 9); - this.vertexByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final FloatBuffer vertexBuffer = this.vertexByteBuffer.asFloatBuffer(); - - vertexBuffer.put(0, -0.5f); - vertexBuffer.put(1, -0.5f); - vertexBuffer.put(2, 0); - vertexBuffer.put(3, 0.5f); - vertexBuffer.put(4, -0.5f); - vertexBuffer.put(5, 0); - vertexBuffer.put(6, 0f); - vertexBuffer.put(7, 0.5f); - vertexBuffer.put(8, 0); - vertexBuffer.clear(); - - Gdx.gl30.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - Gdx.gl30.glEnable(GL20.GL_DEPTH_TEST); -// Gdx.gl30.glEnable(GL20.GL_CULL_FACE); - - final ByteBuffer tempByteBuffer = ByteBuffer.allocateDirect(4); - tempByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final IntBuffer temp = tempByteBuffer.asIntBuffer(); - - Gdx.gl30.glGenVertexArrays(1, temp); - this.VAO = temp.get(0); - - Gdx.gl30.glBindVertexArray(this.VAO); - - temp.clear(); - Gdx.gl30.glGenBuffers(1, temp); - this.VBO = temp.get(0); - - Gdx.gl30.glBindBuffer(GL30.GL_ARRAY_BUFFER, this.VBO); - Gdx.gl30.glBufferData(GL30.GL_ARRAY_BUFFER, 9 * 4, this.vertexByteBuffer, GL30.GL_STATIC_DRAW); - - Gdx.gl30.glVertexAttribPointer(0, 3, GL30.GL_FLOAT, false, 3 * 4, 0); - Gdx.gl30.glEnableVertexAttribArray(0); - - final int vertexShader = Gdx.gl30.glCreateShader(GL30.GL_VERTEX_SHADER); - Gdx.gl30.glShaderSource(vertexShader, vsSimple); - Gdx.gl30.glCompileShader(vertexShader); - - temp.clear(); - Gdx.gl30.glGetShaderiv(vertexShader, GL30.GL_COMPILE_STATUS, temp); - int success = temp.get(0); - if (success == 0) { - final String infoLog = Gdx.gl30.glGetShaderInfoLog(vertexShader); - System.err.println(infoLog); - throw new IllegalStateException("bad vertex shader"); - } - - final int fragmentShader = Gdx.gl30.glCreateShader(GL30.GL_FRAGMENT_SHADER); - Gdx.gl30.glShaderSource(fragmentShader, fsSimple); - Gdx.gl30.glCompileShader(fragmentShader); - - temp.clear(); - Gdx.gl30.glGetShaderiv(fragmentShader, GL30.GL_COMPILE_STATUS, temp); - success = temp.get(0); - if (success == 0) { - final String infoLog = Gdx.gl30.glGetShaderInfoLog(fragmentShader); - System.err.println(infoLog); - throw new IllegalStateException("bad fragment shader"); - } - - this.shaderProgram = Gdx.gl30.glCreateProgram(); - - Gdx.gl30.glAttachShader(this.shaderProgram, vertexShader); - Gdx.gl30.glAttachShader(this.shaderProgram, fragmentShader); - Gdx.gl30.glLinkProgram(this.shaderProgram); - - temp.clear(); - Gdx.gl30.glGetProgramiv(this.shaderProgram, GL30.GL_LINK_STATUS, temp); - success = temp.get(0); - if (success == 0) { - final String infoLog = Gdx.gl30.glGetProgramInfoLog(this.shaderProgram); - System.err.println(infoLog); - throw new IllegalStateException("bad program"); - } - - Gdx.gl30.glDeleteShader(vertexShader); - Gdx.gl30.glDeleteShader(fragmentShader); - } - - @Override - public void render() { - - Gdx.gl30.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); - Gdx.gl30.glBindVertexArray(this.VAO); - Gdx.gl30.glUseProgram(this.shaderProgram); - Gdx.gl30.glBindBuffer(GL30.GL_ARRAY_BUFFER, this.VBO); - Gdx.gl30.glVertexAttribPointer(0, 3, GL30.GL_FLOAT, false, 3 * 4, 0); - Gdx.gl30.glEnableVertexAttribArray(0); - - Gdx.gl30.glDrawArrays(GL30.GL_TRIANGLES, 0, 3); - } - - @Override - public void dispose() { - } - - @Override - public void resize(final int width, final int height) { - final int side = Math.min(width, height); - Gdx.gl30.glViewport((width - side) / 2, (height - side) / 2, side, side); - - } - - public static final String vsSimple = "\r\n" + // - "#version 450 core\r\n" + // - " layout(location = 0) in vec3 aPos;\r\n" + // - " void main() {\r\n" + // - " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\r\n" + // - " }\r\n"; - - public static final String fsSimple = "\r\n" + // - "#version 450 core\r\n" + // - " out vec4 FragColor;\r\n" + // - " void main() {\r\n" + // - " FragColor = vec4(0.2f, 1.0f, 0.2f, 1.0f);\r\n" + // - " }\r\n"; - private int shaderProgram; - - private ByteBuffer vertexByteBuffer; - -} diff --git a/core/src/com/etheller/warsmash/WarsmashTestGameAttributes.java b/core/src/com/etheller/warsmash/WarsmashTestGameAttributes.java deleted file mode 100644 index 36e4fa92..00000000 --- a/core/src/com/etheller/warsmash/WarsmashTestGameAttributes.java +++ /dev/null @@ -1,163 +0,0 @@ -package com.etheller.warsmash; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.nio.ShortBuffer; - -import com.badlogic.gdx.ApplicationAdapter; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; - -public class WarsmashTestGameAttributes extends ApplicationAdapter { - private int arrayBuffer; - private int elementBuffer; - private int VAO; - - @Override - public void create() { - Gdx.gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // colour to use when clearing - - final ByteBuffer tempByteBuffer = ByteBuffer.allocateDirect(4); - tempByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final IntBuffer temp = tempByteBuffer.asIntBuffer(); - - Gdx.gl30.glGenVertexArrays(1, temp); - this.VAO = temp.get(0); - - Gdx.gl30.glBindVertexArray(this.VAO); - - this.shaderProgram = new ShaderProgram(vsSimple, fsSimple); - if (!this.shaderProgram.isCompiled()) { - throw new IllegalStateException(this.shaderProgram.getLog()); - } - - this.arrayBuffer = Gdx.gl.glGenBuffer(); - this.elementBuffer = Gdx.gl.glGenBuffer(); - System.out.println("arrayBuffer: " + this.arrayBuffer + ", elementBuffer: " + this.elementBuffer); - - Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.arrayBuffer); - - Gdx.gl.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, this.elementBuffer); - - final ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(4 * 9); - vertexByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - this.vertexBuffer = vertexByteBuffer.asFloatBuffer(); - - this.vertexBuffer.put(0, -1f); - this.vertexBuffer.put(1, -1f); - this.vertexBuffer.put(2, 0); - this.vertexBuffer.put(3, 1f); - this.vertexBuffer.put(4, -1f); - this.vertexBuffer.put(5, 0); - this.vertexBuffer.put(6, 0f); - this.vertexBuffer.put(7, 1f); - this.vertexBuffer.put(8, 0); - - Gdx.gl.glBufferData(GL20.GL_ARRAY_BUFFER, ((9 * 4) * 2) + 3, null, GL20.GL_STATIC_DRAW); - Gdx.gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, 0, 9 * 4, this.vertexBuffer); - - final ByteBuffer vertex2ByteBuffer = ByteBuffer.allocateDirect(4 * 9); - vertex2ByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final FloatBuffer vertexBuffer2 = vertex2ByteBuffer.asFloatBuffer(); - - vertexBuffer2.put(0, -1f); - vertexBuffer2.put(1, -1f); - vertexBuffer2.put(2, 0); - vertexBuffer2.put(3, 1f); - vertexBuffer2.put(4, -1f); - vertexBuffer2.put(5, 0); - vertexBuffer2.put(6, 0f); - vertexBuffer2.put(7, 1f); - vertexBuffer2.put(8, 0); - - Gdx.gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, 9 * 4, 9 * 4, vertexBuffer2); - - final ByteBuffer skinByteBuffer = ByteBuffer.allocateDirect(3); - skinByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - skinByteBuffer.put((byte) 34); - skinByteBuffer.put((byte) 35); - skinByteBuffer.put((byte) 36); - skinByteBuffer.clear(); - Gdx.gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, 9 * 4 * 2, 3, skinByteBuffer); - -// this.shaderProgram.setVertexAttribute("a_position", 3, GL20.GL_FLOAT, false, 0, 0); -// this.shaderProgram.enableVertexAttribute("a_position"); -// this.shaderProgram.setVertexAttribute("a_position2", 3, GL20.GL_FLOAT, false, 0, 4 * 9); -// this.shaderProgram.enableVertexAttribute("a_position2"); -// this.shaderProgram.setVertexAttribute("a_boneNumber", 1, GL20.GL_UNSIGNED_BYTE, false, 1, 4 * 9 * 2); -// this.shaderProgram.enableVertexAttribute("a_boneNumber"); - - final ByteBuffer faceByteBuffer = ByteBuffer.allocateDirect(6); - faceByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - this.faceBuffer = faceByteBuffer.asShortBuffer(); - - this.faceBuffer.put(0, (short) 0); - this.faceBuffer.put(1, (short) 1); - this.faceBuffer.put(2, (short) 2); - - Gdx.gl.glBufferData(GL20.GL_ELEMENT_ARRAY_BUFFER, 3 * 2, null, GL20.GL_STATIC_DRAW); - - final int glGetError = Gdx.gl.glGetError(); - System.out.println(glGetError); - } - - @Override - public void render() { - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); - -// Gdx.gl30.glBindVertexArray(this.VAO); - this.shaderProgram.begin(); - - Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.arrayBuffer); - this.shaderProgram.setVertexAttribute("a_position", 3, GL20.GL_FLOAT, false, 0, 0); - this.shaderProgram.enableVertexAttribute("a_position"); - this.shaderProgram.setVertexAttribute("a_position2", 3, GL20.GL_FLOAT, false, 0, 4 * 9); - this.shaderProgram.enableVertexAttribute("a_position2"); - this.shaderProgram.setVertexAttribute("a_boneNumber", 1, GL20.GL_UNSIGNED_BYTE, false, 1, 4 * 9 * 2); - this.shaderProgram.enableVertexAttribute("a_boneNumber"); - Gdx.gl.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, this.elementBuffer); - Gdx.gl.glBufferSubData(GL20.GL_ELEMENT_ARRAY_BUFFER, 0, 3 * 2, this.faceBuffer); - Gdx.gl.glDrawElements(GL20.GL_TRIANGLES, 3, GL20.GL_UNSIGNED_SHORT, 0); -// Gdx.gl.glDrawArrays(GL20.GL_TRIANGLES, 0, 3); - this.shaderProgram.end(); - } - - @Override - public void dispose() { - } - - @Override - public void resize(final int width, final int height) { - } - - public static final String vsSimple = "\r\n" + // - " attribute vec3 a_position;\r\n" + // - " attribute vec3 a_position2;\r\n" + // - " attribute float a_boneNumber;\r\n" + // - " varying float fragNumber;\r\n" + // - " void main() {\r\n" + // - " gl_Position = vec4(a_position2.x, a_position2.y, a_position2.z, 1.0);\r\n" + // - " fragNumber = a_boneNumber;\r\n" + // - " }\r\n"; - - public static final String fsSimple = "\r\n" + // - " varying float fragNumber;\r\n" + // - " void main() {\r\n" + // - " if( fragNumber > 35.5 ) {\r\n" + // - " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\r\n" + // - " } else if( fragNumber > 34.5 ) {\r\n" + // - " gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);\r\n" + // - " } else if( fragNumber > 33.5 ) {\r\n" + // - " gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);\r\n" + // - " } else {\r\n" + // - " gl_FragColor = vec4(fragNumber*100.0, fragNumber, fragNumber, 1.0);\r\n" + // - " }\r\n" + // - " }\r\n"; - private ShaderProgram shaderProgram; - private FloatBuffer vertexBuffer; - private ShortBuffer faceBuffer; - -} diff --git a/core/src/com/etheller/warsmash/WarsmashTestGameAttributes2.java b/core/src/com/etheller/warsmash/WarsmashTestGameAttributes2.java deleted file mode 100644 index bc65a6c7..00000000 --- a/core/src/com/etheller/warsmash/WarsmashTestGameAttributes2.java +++ /dev/null @@ -1,213 +0,0 @@ -package com.etheller.warsmash; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.nio.ShortBuffer; -import java.util.Arrays; - -import com.badlogic.gdx.ApplicationAdapter; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.etheller.warsmash.datasources.CompoundDataSourceDescriptor; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.datasources.DataSourceDescriptor; -import com.etheller.warsmash.datasources.FolderDataSourceDescriptor; -import com.hiveworkshop.rms.parsers.mdlx.MdlxGeoset; -import com.hiveworkshop.rms.parsers.mdlx.MdlxModel; - -public class WarsmashTestGameAttributes2 extends ApplicationAdapter { - private int arrayBuffer; - private int elementBuffer; - private int VAO; - private DataSource codebase; - - @Override - public void create() { - final FolderDataSourceDescriptor war3mpq = new FolderDataSourceDescriptor( - "D:\\NEEDS_ORGANIZING\\MPQBuild\\War3.mpq\\war3.mpq"); - final FolderDataSourceDescriptor testingFolder = new FolderDataSourceDescriptor( - "D:\\NEEDS_ORGANIZING\\MPQBuild\\Test"); - this.codebase = new CompoundDataSourceDescriptor(Arrays.asList(war3mpq, testingFolder)) - .createDataSource(); - - final MdlxModel model; - try { - model = new MdlxModel(this.codebase.read("Buildings\\Other\\TempArtB\\TempArtB.mdx")); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - - Gdx.gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // colour to use when clearing - - final ByteBuffer tempByteBuffer = ByteBuffer.allocateDirect(4); - tempByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final IntBuffer temp = tempByteBuffer.asIntBuffer(); - - Gdx.gl30.glGenVertexArrays(1, temp); - this.VAO = temp.get(0); - - Gdx.gl30.glBindVertexArray(this.VAO); - - this.shaderProgram = new ShaderProgram(vsSimple, fsSimple); - if (!this.shaderProgram.isCompiled()) { - throw new IllegalStateException(this.shaderProgram.getLog()); - } - - this.arrayBuffer = Gdx.gl.glGenBuffer(); - this.elementBuffer = Gdx.gl.glGenBuffer(); - System.out.println("arrayBuffer: " + this.arrayBuffer + ", elementBuffer: " + this.elementBuffer); - - Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.arrayBuffer); - - Gdx.gl.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, this.elementBuffer); - - final MdlxGeoset geoset0 = model.getGeosets().get(0); - final float[] vertices = geoset0.getVertices(); - final ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(4 * 9); - vertexByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - this.vertexBuffer = vertexByteBuffer.asFloatBuffer(); - - this.vertexBuffer.put(0, -1f); - this.vertexBuffer.put(1, -1f); - this.vertexBuffer.put(2, 0); - this.vertexBuffer.put(3, 1f); - this.vertexBuffer.put(4, -1f); - this.vertexBuffer.put(5, 0); - this.vertexBuffer.put(6, 0f); - this.vertexBuffer.put(7, 1f); - this.vertexBuffer.put(8, 0); - - Gdx.gl.glBufferData(GL20.GL_ARRAY_BUFFER, ((9 * 4) * 2) + 3, null, GL20.GL_STATIC_DRAW); - Gdx.gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, 0, 9 * 4, this.vertexBuffer); - - final ByteBuffer vertex2ByteBuffer = ByteBuffer.allocateDirect(4 * 9); - vertex2ByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final FloatBuffer vertexBuffer2 = vertex2ByteBuffer.asFloatBuffer(); - - vertexBuffer2.put(0, -1f); - vertexBuffer2.put(1, -1f); - vertexBuffer2.put(2, 0); - vertexBuffer2.put(3, 1f); - vertexBuffer2.put(4, -1f); - vertexBuffer2.put(5, 0); - vertexBuffer2.put(6, 0f); - vertexBuffer2.put(7, 1f); - vertexBuffer2.put(8, 0); - - Gdx.gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, 9 * 4, 9 * 4, vertexBuffer2); - - final ByteBuffer skinByteBuffer = ByteBuffer.allocateDirect(3); - skinByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - skinByteBuffer.put((byte) 34); - skinByteBuffer.put((byte) 35); - skinByteBuffer.put((byte) 36); - skinByteBuffer.clear(); - Gdx.gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, 9 * 4 * 2, 3, skinByteBuffer); - -// this.shaderProgram.setVertexAttribute("a_position", 3, GL20.GL_FLOAT, false, 0, 0); -// this.shaderProgram.enableVertexAttribute("a_position"); -// this.shaderProgram.setVertexAttribute("a_position2", 3, GL20.GL_FLOAT, false, 0, 4 * 9); -// this.shaderProgram.enableVertexAttribute("a_position2"); -// this.shaderProgram.setVertexAttribute("a_boneNumber", 1, GL20.GL_UNSIGNED_BYTE, false, 1, 4 * 9 * 2); -// this.shaderProgram.enableVertexAttribute("a_boneNumber"); - - final ByteBuffer faceByteBuffer = ByteBuffer.allocateDirect(6); - faceByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - this.faceBuffer = faceByteBuffer.asShortBuffer(); - - this.faceBuffer.put(0, (short) 0); - this.faceBuffer.put(1, (short) 1); - this.faceBuffer.put(2, (short) 2); - - Gdx.gl.glBufferData(GL20.GL_ELEMENT_ARRAY_BUFFER, 3 * 2, null, GL20.GL_STATIC_DRAW); - - final int glGetError = Gdx.gl.glGetError(); - System.out.println(glGetError); - } - - @Override - public void render() { - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); - -// Gdx.gl30.glBindVertexArray(this.VAO); - this.shaderProgram.begin(); - - Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.arrayBuffer); - this.shaderProgram.setVertexAttribute("a_position", 3, GL20.GL_FLOAT, false, 0, 0); - this.shaderProgram.enableVertexAttribute("a_position"); - this.shaderProgram.setVertexAttribute("a_position2", 3, GL20.GL_FLOAT, false, 0, 4 * 9); - this.shaderProgram.enableVertexAttribute("a_position2"); - this.shaderProgram.setVertexAttribute("a_boneNumber", 1, GL20.GL_UNSIGNED_BYTE, false, 1, 4 * 9 * 2); - this.shaderProgram.enableVertexAttribute("a_boneNumber"); - Gdx.gl.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, this.elementBuffer); - Gdx.gl.glBufferSubData(GL20.GL_ELEMENT_ARRAY_BUFFER, 0, 3 * 2, this.faceBuffer); - Gdx.gl.glDrawElements(GL20.GL_TRIANGLES, 3, GL20.GL_UNSIGNED_SHORT, 0); -// Gdx.gl.glDrawArrays(GL20.GL_TRIANGLES, 0, 3); - this.shaderProgram.end(); - } - - @Override - public void dispose() { - } - - @Override - public void resize(final int width, final int height) { - } - - public static final String vsSimple = "\r\n" + // - " attribute vec3 a_position;\r\n" + // - " attribute vec3 a_position2;\r\n" + // - " attribute float a_boneNumber;\r\n" + // - " varying float fragNumber;\r\n" + // - " void main() {\r\n" + // - " gl_Position = vec4(a_position2.x, a_position2.y, a_position2.z, 1.0);\r\n" + // - " fragNumber = a_boneNumber;\r\n" + // - " }\r\n"; - - public static final String fsSimple = "\r\n" + // - " varying float fragNumber;\r\n" + // - " void main() {\r\n" + // - " if( fragNumber > 35.5 ) {\r\n" + // - " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\r\n" + // - " } else if( fragNumber > 34.5 ) {\r\n" + // - " gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);\r\n" + // - " } else if( fragNumber > 33.5 ) {\r\n" + // - " gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);\r\n" + // - " } else {\r\n" + // - " gl_FragColor = vec4(fragNumber*100.0, fragNumber, fragNumber, 1.0);\r\n" + // - " }\r\n" + // - " }\r\n"; - private ShaderProgram shaderProgram; - private FloatBuffer vertexBuffer; - private ShortBuffer faceBuffer; - - private static ShortBuffer wrapFaces(final int[] faces) { - final ShortBuffer wrapper = ByteBuffer.allocateDirect(faces.length * 2).order(ByteOrder.nativeOrder()) - .asShortBuffer(); - for (final int face : faces) { - wrapper.put((short) face); - } - wrapper.clear(); - return wrapper; - } - - private static ByteBuffer wrap(final byte[] skin) { - final ByteBuffer wrapper = ByteBuffer.allocateDirect(skin.length).order(ByteOrder.nativeOrder()); - wrapper.put(skin); - wrapper.clear(); - return wrapper; - } - - private static FloatBuffer wrap(final float[] positions) { - final FloatBuffer wrapper = ByteBuffer.allocateDirect(positions.length * 4).order(ByteOrder.nativeOrder()) - .asFloatBuffer(); - wrapper.put(positions); - wrapper.clear(); - return wrapper; - } -} diff --git a/core/src/com/etheller/warsmash/WarsmashTestGameTextureBuffer.java b/core/src/com/etheller/warsmash/WarsmashTestGameTextureBuffer.java deleted file mode 100644 index c0f7930b..00000000 --- a/core/src/com/etheller/warsmash/WarsmashTestGameTextureBuffer.java +++ /dev/null @@ -1,244 +0,0 @@ -package com.etheller.warsmash; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.nio.ShortBuffer; - -import com.badlogic.gdx.ApplicationAdapter; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.GL30; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.etheller.warsmash.viewer5.Shaders; - -public class WarsmashTestGameTextureBuffer extends ApplicationAdapter { - private int arrayBuffer; - private int elementBuffer; - private int VAO; - private ShaderProgram shaderProgram; - private FloatBuffer vertexBuffer; - private ShortBuffer faceBuffer; - - @Override - public void create() { -// ShaderProgram.pedantic = false; - Gdx.gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // colour to use when clearing - - final ByteBuffer tempByteBuffer = ByteBuffer.allocateDirect(4); - tempByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final IntBuffer temp = tempByteBuffer.asIntBuffer(); - - Gdx.gl30.glGenVertexArrays(1, temp); - this.VAO = temp.get(0); - - Gdx.gl30.glBindVertexArray(this.VAO); - - System.out.println(vsSimple); - this.shaderProgram = new ShaderProgram(vsSimple, fsSimple); - if (!this.shaderProgram.isCompiled()) { - throw new IllegalStateException(this.shaderProgram.getLog()); - } - - this.arrayBuffer = Gdx.gl.glGenBuffer(); - this.elementBuffer = Gdx.gl.glGenBuffer(); - System.out.println("arrayBuffer: " + this.arrayBuffer + ", elementBuffer: " + this.elementBuffer); - - Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.arrayBuffer); - - Gdx.gl.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, this.elementBuffer); - - final ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(4 * 9); - vertexByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - this.vertexBuffer = vertexByteBuffer.asFloatBuffer(); - - this.vertexBuffer.put(0, -1f); - this.vertexBuffer.put(1, -1f); - this.vertexBuffer.put(2, 0); - this.vertexBuffer.put(3, 1f); - this.vertexBuffer.put(4, -1f); - this.vertexBuffer.put(5, 0); - this.vertexBuffer.put(6, 0f); - this.vertexBuffer.put(7, 1f); - this.vertexBuffer.put(8, 0); - - Gdx.gl.glBufferData(GL20.GL_ARRAY_BUFFER, ((9 * 4) * 2) + 3, null, GL20.GL_STATIC_DRAW); - Gdx.gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, 0, 9 * 4, this.vertexBuffer); - - final ByteBuffer vertex2ByteBuffer = ByteBuffer.allocateDirect(4 * 9); - vertex2ByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final FloatBuffer vertexBuffer2 = vertex2ByteBuffer.asFloatBuffer(); - - vertexBuffer2.put(0, -1f); - vertexBuffer2.put(1, -1f); - vertexBuffer2.put(2, 0); - vertexBuffer2.put(3, 1f); - vertexBuffer2.put(4, -1f); - vertexBuffer2.put(5, 0); - vertexBuffer2.put(6, 0f); - vertexBuffer2.put(7, 1f); - vertexBuffer2.put(8, 0); - - Gdx.gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, 9 * 4, 9 * 4, vertexBuffer2); - - final ByteBuffer skinByteBuffer = ByteBuffer.allocateDirect(3); - skinByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - skinByteBuffer.put((byte) 34); - skinByteBuffer.put((byte) 35); - skinByteBuffer.put((byte) 36); - skinByteBuffer.clear(); - Gdx.gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, 9 * 4 * 2, 3, skinByteBuffer); - -// this.shaderProgram.setVertexAttribute("a_position", 3, GL20.GL_FLOAT, false, 0, 0); -// this.shaderProgram.enableVertexAttribute("a_position"); -// this.shaderProgram.setVertexAttribute("a_position2", 3, GL20.GL_FLOAT, false, 0, 4 * 9); -// this.shaderProgram.enableVertexAttribute("a_position2"); -// this.shaderProgram.setVertexAttribute("a_boneNumber", 1, GL20.GL_UNSIGNED_BYTE, false, 1, 4 * 9 * 2); -// this.shaderProgram.enableVertexAttribute("a_boneNumber"); -// this.shaderProgram.setUniformi("u_boneMap", 15); - - final ByteBuffer faceByteBuffer = ByteBuffer.allocateDirect(6); - faceByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - this.faceBuffer = faceByteBuffer.asShortBuffer(); - - this.faceBuffer.put(0, (short) 0); - this.faceBuffer.put(1, (short) 1); - this.faceBuffer.put(2, (short) 2); - - Gdx.gl.glBufferData(GL20.GL_ELEMENT_ARRAY_BUFFER, 3 * 2, null, GL20.GL_STATIC_DRAW); - - final int glGetError = Gdx.gl.glGetError(); - System.out.println(glGetError); - - final ByteBuffer vertex3ByteBuffer = ByteBuffer.allocateDirect(4 * 16); - vertex3ByteBuffer.order(ByteOrder.nativeOrder()); - this.vertexTextureBuffer3 = vertex3ByteBuffer.asFloatBuffer(); - - this.vertexTextureBuffer3.put(0, 0.5f); - this.vertexTextureBuffer3.put(1, 0); - this.vertexTextureBuffer3.put(2, 0); - this.vertexTextureBuffer3.put(3, 0); - this.vertexTextureBuffer3.put(4, 0); - this.vertexTextureBuffer3.put(5, 1); - this.vertexTextureBuffer3.put(6, 0); - this.vertexTextureBuffer3.put(7, 0); - this.vertexTextureBuffer3.put(8, 0); - this.vertexTextureBuffer3.put(9, 0); - this.vertexTextureBuffer3.put(10, 1); - this.vertexTextureBuffer3.put(11, 0); - this.vertexTextureBuffer3.put(12, 0.0f); - this.vertexTextureBuffer3.put(13, 0.0f); - this.vertexTextureBuffer3.put(14, 0); - this.vertexTextureBuffer3.put(15, 1); - -// this.vertexTextureBuffer = Gdx.gl.glGenBuffer(); - this.vertexTexture = Gdx.gl.glGenTexture(); - - Gdx.gl.glActiveTexture(GL20.GL_TEXTURE15); -// Gdx.gl.glBindBuffer(GL20.GL_TEXTURE_2D, this.vertexTextureBuffer); -// Gdx.gl.glBindBuffer(GL20.GL_TEXTURE_2D, 0); - - Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, this.vertexTexture); - Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_S, GL20.GL_CLAMP_TO_EDGE); - Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_T, GL20.GL_CLAMP_TO_EDGE); - Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER, GL20.GL_NEAREST); - Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER, GL20.GL_NEAREST); - Gdx.gl.glTexImage2D(GL20.GL_TEXTURE_2D, 0, GL30.GL_RGBA, 4, 1, 0, GL30.GL_RGBA, GL20.GL_FLOAT, - this.vertexTextureBuffer3); - } - - @Override - public void render() { - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); - -// Gdx.gl30.glBindVertexArray(this.VAO); - this.shaderProgram.begin(); - - Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.arrayBuffer); - this.shaderProgram.setVertexAttribute("a_position", 3, GL20.GL_FLOAT, false, 0, 0); - this.shaderProgram.enableVertexAttribute("a_position"); - this.shaderProgram.setVertexAttribute("a_position2", 3, GL20.GL_FLOAT, false, 0, 4 * 9); - this.shaderProgram.enableVertexAttribute("a_position2"); - this.shaderProgram.setVertexAttribute("a_boneNumber", 1, GL20.GL_UNSIGNED_BYTE, false, 1, 4 * 9 * 2); - this.shaderProgram.enableVertexAttribute("a_boneNumber"); - - Gdx.gl.glActiveTexture(GL20.GL_TEXTURE15); - Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, this.vertexTexture); - Gdx.gl.glTexSubImage2D(GL20.GL_TEXTURE_2D, 0, 0, 0, 4, 1, GL30.GL_RGBA, GL20.GL_FLOAT, - this.vertexTextureBuffer3); - this.shaderProgram.setUniformi("u_boneMap", 15); - this.shaderProgram.setUniformf("u_vectorSize", 1f / 4); - this.shaderProgram.setUniformf("u_rowSize", 1); - - Gdx.gl.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, this.elementBuffer); - Gdx.gl.glBufferSubData(GL20.GL_ELEMENT_ARRAY_BUFFER, 0, 3 * 2, this.faceBuffer); - Gdx.gl.glDrawElements(GL20.GL_TRIANGLES, 3, GL20.GL_UNSIGNED_SHORT, 0); -// Gdx.gl.glDrawArrays(GL20.GL_TRIANGLES, 0, 3); - this.shaderProgram.end(); - } - - @Override - public void dispose() { - } - - @Override - public void resize(final int width, final int height) { - } - - public static final String boneTexture = ""// - + " uniform samplerBuffer u_boneMap;\r\n" + // - // " uniform uint u_vectorSize;\r\n" + // - " uniform uint u_rowSize;\r\n" + // - " mat4 fetchMatrix(uint column, uint row) {\r\n" + // - // " column *= u_vectorSize * 4.0;\r\n" + // - // " row *= u_rowSize;\r\n" + // - " // Add in half texel to sample in the middle of the texel.\r\n" + // - " // Otherwise, since the sample is directly on the boundry, small floating point errors can cause the sample to get the wrong pixel.\r\n" - + // - " // This is mostly noticable with NPOT textures, which the bone maps are.\r\n" + // - // " column += 0.5 * u_vectorSize;\r\n" + // - // " row += 0.5 * u_rowSize;\r\n" + // - " return mat4(texelFetch(u_boneMap, row * u_rowSize + column * 4),\r\n" + // - " texelFetch(u_boneMap, row * u_rowSize + column * 4 + 1),\r\n" + // - " texelFetch(u_boneMap, row * u_rowSize + column * 4 + 2),\r\n" + // - " texelFetch(u_boneMap, row * u_rowSize + column * 4 + 3);\r\n" + // - " }"; - - public static final String vsSimple = "\r\n" + // - "\r\n" + // - " attribute vec3 a_position;\r\n" + // - " attribute vec3 a_position2;\r\n" + // - " attribute float a_boneNumber;\r\n" + // - " varying float fragNumber;\r\n" + // - Shaders.boneTexture + "\r\n" + // - " void main() {\r\n" + // - " mat4 bone = fetchMatrix(0.0, 0.0);\r\n" + // - " if( a_boneNumber <= 34.5 ) {\r\n" + // - " gl_Position = vec4(a_position2.x * bone[0][0], a_position2.y, a_position2.z, 1.0);\r\n" + // - " } else {\r\n" + // - " gl_Position = vec4(a_position2.x, a_position2.y, a_position2.z, 1.0);\r\n" + // - " }\r\n" + // - " fragNumber = a_boneNumber;\r\n" + // - " }\r\n"; - - public static final String fsSimple = "\r\n" + // - " varying float fragNumber;\r\n" + // - Shaders.boneTexture + "\r\n" + // - " void main() {\r\n" + // - " mat4 bone = fetchMatrix(0.0, 0.0);\r\n" + // - " if( fragNumber > 35.5 ) {\r\n" + // - " gl_FragColor = bone[0];//vec4(1.0, 0.0, 0.0, 1.0);\r\n" + // - " } else if( fragNumber > 34.5 ) {\r\n" + // - " gl_FragColor = bone[1];//vec4(0.0, 1.0, 1.0, 1.0);\r\n" + // - " } else if( fragNumber > 33.5 ) {\r\n" + // - " gl_FragColor = bone[2];//vec4(1.0, 0.0, 1.0, 1.0);\r\n" + // - " } else {\r\n" + // - " gl_FragColor = vec4(fragNumber*100.0, fragNumber, fragNumber, 1.0);\r\n" + // - " }\r\n" + // - " }\r\n"; - private int vertexTexture; - private int vertexTextureBuffer; - private FloatBuffer vertexTextureBuffer3; - -} diff --git a/core/src/com/etheller/warsmash/WarsmashTestGameTextureBuffer2.java b/core/src/com/etheller/warsmash/WarsmashTestGameTextureBuffer2.java deleted file mode 100644 index 5a892c65..00000000 --- a/core/src/com/etheller/warsmash/WarsmashTestGameTextureBuffer2.java +++ /dev/null @@ -1,203 +0,0 @@ -package com.etheller.warsmash; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.nio.ShortBuffer; - -import com.badlogic.gdx.ApplicationAdapter; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.etheller.warsmash.viewer5.Shaders; -import com.etheller.warsmash.viewer5.gl.DataTexture; - -public class WarsmashTestGameTextureBuffer2 extends ApplicationAdapter { - private int arrayBuffer; - private int elementBuffer; - private int VAO; - - @Override - public void create() { -// ShaderProgram.pedantic = false; - Gdx.gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // colour to use when clearing - - final ByteBuffer tempByteBuffer = ByteBuffer.allocateDirect(4); - tempByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final IntBuffer temp = tempByteBuffer.asIntBuffer(); - - Gdx.gl30.glGenVertexArrays(1, temp); - this.VAO = temp.get(0); - - Gdx.gl30.glBindVertexArray(this.VAO); - - System.out.println(vsSimple); - this.shaderProgram = new ShaderProgram(vsSimple, fsSimple); - if (!this.shaderProgram.isCompiled()) { - throw new IllegalStateException(this.shaderProgram.getLog()); - } - - this.arrayBuffer = Gdx.gl.glGenBuffer(); - this.elementBuffer = Gdx.gl.glGenBuffer(); - System.out.println("arrayBuffer: " + this.arrayBuffer + ", elementBuffer: " + this.elementBuffer); - - Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.arrayBuffer); - - Gdx.gl.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, this.elementBuffer); - - final ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(4 * 9); - vertexByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - this.vertexBuffer = vertexByteBuffer.asFloatBuffer(); - - this.vertexBuffer.put(0, -1f); - this.vertexBuffer.put(1, -1f); - this.vertexBuffer.put(2, 0); - this.vertexBuffer.put(3, 1f); - this.vertexBuffer.put(4, -1f); - this.vertexBuffer.put(5, 0); - this.vertexBuffer.put(6, 0f); - this.vertexBuffer.put(7, 1f); - this.vertexBuffer.put(8, 0); - - Gdx.gl.glBufferData(GL20.GL_ARRAY_BUFFER, ((9 * 4) * 2) + 3, null, GL20.GL_STATIC_DRAW); - Gdx.gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, 0, 9 * 4, this.vertexBuffer); - - final ByteBuffer vertex2ByteBuffer = ByteBuffer.allocateDirect(4 * 9); - vertex2ByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final FloatBuffer vertexBuffer2 = vertex2ByteBuffer.asFloatBuffer(); - - vertexBuffer2.put(0, -1f); - vertexBuffer2.put(1, -1f); - vertexBuffer2.put(2, 0); - vertexBuffer2.put(3, 1f); - vertexBuffer2.put(4, -1f); - vertexBuffer2.put(5, 0); - vertexBuffer2.put(6, 0f); - vertexBuffer2.put(7, 1f); - vertexBuffer2.put(8, 0); - - Gdx.gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, 9 * 4, 9 * 4, vertexBuffer2); - - final ByteBuffer skinByteBuffer = ByteBuffer.allocateDirect(3); - skinByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - skinByteBuffer.put((byte) 34); - skinByteBuffer.put((byte) 35); - skinByteBuffer.put((byte) 36); - skinByteBuffer.clear(); - Gdx.gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, 9 * 4 * 2, 3, skinByteBuffer); - -// this.shaderProgram.setVertexAttribute("a_position", 3, GL20.GL_FLOAT, false, 0, 0); -// this.shaderProgram.enableVertexAttribute("a_position"); -// this.shaderProgram.setVertexAttribute("a_position2", 3, GL20.GL_FLOAT, false, 0, 4 * 9); -// this.shaderProgram.enableVertexAttribute("a_position2"); -// this.shaderProgram.setVertexAttribute("a_boneNumber", 1, GL20.GL_UNSIGNED_BYTE, false, 1, 4 * 9 * 2); -// this.shaderProgram.enableVertexAttribute("a_boneNumber"); -// this.shaderProgram.setUniformi("u_boneMap", 15); - - final ByteBuffer faceByteBuffer = ByteBuffer.allocateDirect(6); - faceByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - this.faceBuffer = faceByteBuffer.asShortBuffer(); - - this.faceBuffer.put(0, (short) 0); - this.faceBuffer.put(1, (short) 1); - this.faceBuffer.put(2, (short) 2); - - Gdx.gl.glBufferData(GL20.GL_ELEMENT_ARRAY_BUFFER, 3 * 2, null, GL20.GL_STATIC_DRAW); - - final int glGetError = Gdx.gl.glGetError(); - System.out.println(glGetError); - - final ByteBuffer vertex3ByteBuffer = ByteBuffer.allocateDirect(4 * 16); - vertex3ByteBuffer.order(ByteOrder.LITTLE_ENDIAN); - final FloatBuffer vertexBuffer3 = vertex3ByteBuffer.asFloatBuffer(); - - vertexBuffer3.put(0, 1); - vertexBuffer3.put(1, 0); - vertexBuffer3.put(2, 0); - vertexBuffer3.put(3, 0); - vertexBuffer3.put(4, 0); - vertexBuffer3.put(5, 1); - vertexBuffer3.put(6, 0); - vertexBuffer3.put(7, 0); - vertexBuffer3.put(8, 0); - vertexBuffer3.put(9, 0); - vertexBuffer3.put(10, 1); - vertexBuffer3.put(11, 0); - vertexBuffer3.put(12, 0.0f); - vertexBuffer3.put(13, 0.0f); - vertexBuffer3.put(14, 0); - vertexBuffer3.put(15, 1); - - this.dataTexture = new DataTexture(Gdx.gl, 4, 4, 1); - this.dataTexture.bindAndUpdate(vertexBuffer3); - } - - @Override - public void render() { - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); - -// Gdx.gl30.glBindVertexArray(this.VAO); - this.shaderProgram.begin(); - - this.dataTexture.bind(15); - - Gdx.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.arrayBuffer); - this.shaderProgram.setVertexAttribute("a_position", 3, GL20.GL_FLOAT, false, 0, 0); - this.shaderProgram.enableVertexAttribute("a_position"); - this.shaderProgram.setVertexAttribute("a_position2", 3, GL20.GL_FLOAT, false, 0, 4 * 9); - this.shaderProgram.enableVertexAttribute("a_position2"); - this.shaderProgram.setVertexAttribute("a_boneNumber", 1, GL20.GL_UNSIGNED_BYTE, false, 1, 4 * 9 * 2); - this.shaderProgram.enableVertexAttribute("a_boneNumber"); - - this.shaderProgram.setUniformi("u_boneMap", 15); - this.shaderProgram.setUniformf("u_vectorSize", 1f / this.dataTexture.getWidth()); - this.shaderProgram.setUniformf("u_rowSize", 1); - - Gdx.gl.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, this.elementBuffer); - Gdx.gl.glBufferSubData(GL20.GL_ELEMENT_ARRAY_BUFFER, 0, 3 * 2, this.faceBuffer); - Gdx.gl.glDrawElements(GL20.GL_TRIANGLES, 3, GL20.GL_UNSIGNED_SHORT, 0); -// Gdx.gl.glDrawArrays(GL20.GL_TRIANGLES, 0, 3); - this.shaderProgram.end(); - } - - @Override - public void dispose() { - } - - @Override - public void resize(final int width, final int height) { - } - - public static final String vsSimple = "\r\n" + // - "\r\n" + // - " attribute vec3 a_position;\r\n" + // - " attribute vec3 a_position2;\r\n" + // - " attribute float a_boneNumber;\r\n" + // - " varying float fragNumber;\r\n" + // - Shaders.boneTexture + "\r\n" + // - " void main() {\r\n" + // - " mat4 bone = fetchMatrix(0.0, 0.0);\r\n" + // - " gl_Position = bone * vec4(a_position2.x, a_position2.y, a_position2.z, 1.0);\r\n" + // - " fragNumber = a_boneNumber;\r\n" + // - " }\r\n"; - - public static final String fsSimple = "\r\n" + // - " varying float fragNumber;\r\n" + // - " void main() {\r\n" + // - " if( fragNumber > 35.5 ) {\r\n" + // - " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\r\n" + // - " } else if( fragNumber > 34.5 ) {\r\n" + // - " gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);\r\n" + // - " } else if( fragNumber > 33.5 ) {\r\n" + // - " gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);\r\n" + // - " } else {\r\n" + // - " gl_FragColor = vec4(fragNumber*100.0, fragNumber, fragNumber, 1.0);\r\n" + // - " }\r\n" + // - " }\r\n"; - private ShaderProgram shaderProgram; - private FloatBuffer vertexBuffer; - private ShortBuffer faceBuffer; - private DataTexture dataTexture; - -} diff --git a/core/src/com/etheller/warsmash/WarsmashTestMyTextureGame.java b/core/src/com/etheller/warsmash/WarsmashTestMyTextureGame.java deleted file mode 100644 index edc1cec2..00000000 --- a/core/src/com/etheller/warsmash/WarsmashTestMyTextureGame.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.etheller.warsmash; - -import java.util.Arrays; - -import com.badlogic.gdx.ApplicationAdapter; -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.etheller.warsmash.datasources.CompoundDataSourceDescriptor; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.datasources.DataSourceDescriptor; -import com.etheller.warsmash.datasources.FolderDataSourceDescriptor; -import com.etheller.warsmash.util.ImageUtils; - -public class WarsmashTestMyTextureGame extends ApplicationAdapter { - - private DataSource codebase; - private Texture texture; - private SpriteBatch batch; - - @Override - public void create() { - - final FolderDataSourceDescriptor war3mpq = new FolderDataSourceDescriptor("E:\\Backups\\Warcraft\\Data\\127"); - final FolderDataSourceDescriptor testingFolder = new FolderDataSourceDescriptor( - "D:\\NEEDS_ORGANIZING\\MPQBuild\\Test"); - final FolderDataSourceDescriptor currentFolder = new FolderDataSourceDescriptor("."); - this.codebase = new CompoundDataSourceDescriptor( - Arrays.asList(war3mpq, testingFolder, currentFolder)).createDataSource(); - - this.texture = ImageUtils.getAnyExtensionTexture(this.codebase, "Textures\\Dust3x.blp"); - Gdx.gl.glClearColor(0, 0, 0, 1); - this.batch = new SpriteBatch(); - this.batch.enableBlending(); - } - - @Override - public void render() { - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); - - this.batch.begin(); - this.batch.draw(this.texture, 20, 20, 256, 256); - this.batch.end(); - } - -} diff --git a/core/src/com/etheller/warsmash/common/FetchDataTypeName.java b/core/src/com/etheller/warsmash/common/FetchDataTypeName.java deleted file mode 100644 index 1d4b35b4..00000000 --- a/core/src/com/etheller/warsmash/common/FetchDataTypeName.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.common; - -/** - * These will probably change the further I get from the source material I am - * copying from. - */ -public enum FetchDataTypeName { - IMAGE, - TEXT, - SLK, - ARRAY_BUFFER, - BLOB; -} diff --git a/core/src/com/etheller/warsmash/common/LoadGenericCallback.java b/core/src/com/etheller/warsmash/common/LoadGenericCallback.java deleted file mode 100644 index d7c4c297..00000000 --- a/core/src/com/etheller/warsmash/common/LoadGenericCallback.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.etheller.warsmash.common; - -import java.io.InputStream; - -public interface LoadGenericCallback { - Object call(InputStream data); // TODO typing -} diff --git a/core/src/com/etheller/warsmash/datasources/CascDataSource.java b/core/src/com/etheller/warsmash/datasources/CascDataSource.java deleted file mode 100644 index 5f92f16d..00000000 --- a/core/src/com/etheller/warsmash/datasources/CascDataSource.java +++ /dev/null @@ -1,225 +0,0 @@ -package com.etheller.warsmash.datasources; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import com.hiveworkshop.blizzard.casc.io.WarcraftIIICASC; -import com.hiveworkshop.blizzard.casc.io.WarcraftIIICASC.FileSystem; -import com.hiveworkshop.json.JSONArray; -import com.hiveworkshop.json.JSONObject; -import com.hiveworkshop.json.JSONTokener; - -public class CascDataSource implements DataSource { - private final String[] prefixes; - private WarcraftIIICASC warcraftIIICASC; - private FileSystem rootFileSystem; - private List listFile; - private Map fileAliases; - - public CascDataSource(final String warcraft3InstallPath, final String[] prefixes) { - this.prefixes = prefixes; - for (int i = 0; i < (prefixes.length / 2); i++) { - final String temp = prefixes[i]; - prefixes[i] = prefixes[prefixes.length - i - 1]; - prefixes[prefixes.length - i - 1] = temp; - } - - try { - this.warcraftIIICASC = new WarcraftIIICASC(Paths.get(warcraft3InstallPath), true); - this.rootFileSystem = this.warcraftIIICASC.getRootFileSystem(); - this.listFile = this.rootFileSystem.enumerateFiles(); - this.fileAliases = new HashMap<>(); - if (this.has("filealiases.json")) { - try (InputStream stream = this.getResourceAsStream("filealiases.json")) { - stream.mark(4); - if ('\ufeff' != stream.read()) { - stream.reset(); // not the BOM marker - } - final JSONArray jsonObject = new JSONArray(new JSONTokener(stream)); - for (int i = 0; i < jsonObject.length(); i++) { - final JSONObject alias = jsonObject.getJSONObject(i); - final String src = alias.getString("src"); - final String dest = alias.getString("dest"); - this.fileAliases.put(src.toLowerCase(Locale.US).replace('/', '\\'), - dest.toLowerCase(Locale.US).replace('/', '\\')); - if ((src.toLowerCase(Locale.US).contains(".blp") - || dest.toLowerCase(Locale.US).contains(".blp")) - && (!alias.has("assetType") || "Texture".equals(alias.getString("assetType")))) { - // This case: I saw a texture that resolves in game but was failing in our code - // here, because of this entry: - // {"src":"Units/Human/WarWagon/SiegeEngine.blp", - // "dest":"Textures/Steamtank.blp", "assetType": "Texture"}, - // Our repo here checks BLP then DDS at a high-up application level thing, and - // the problem is that this entry is written using .BLP but we must be able to - // resolve .DDS when we go to look it up. The actual model is .BLP so maybe - // that's how the game does it, but my alias mapping is happening after the - // .BLP->.DDS dynamic fix, and not before. - this.fileAliases.put(src.toLowerCase(Locale.US).replace('/', '\\').replace(".blp", ".dds"), - dest.toLowerCase(Locale.US).replace('/', '\\').replace(".blp", ".dds")); - } - } - } - } - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public InputStream getResourceAsStream(String filepath) { - filepath = filepath.toLowerCase(Locale.US).replace('/', '\\').replace(':', '\\'); - final String resolvedAlias = this.fileAliases.get(filepath); - if (resolvedAlias != null) { - filepath = resolvedAlias; - } - for (final String prefix : this.prefixes) { - final String tempFilepath = prefix + "\\" + filepath; - final InputStream stream = internalGetResourceAsStream(tempFilepath); - if (stream != null) { - return stream; - } - } - return internalGetResourceAsStream(filepath); - } - - private InputStream internalGetResourceAsStream(final String tempFilepath) { - try { - if (this.rootFileSystem.isFile(tempFilepath) && this.rootFileSystem.isFileAvailable(tempFilepath)) { - final ByteBuffer buffer = this.rootFileSystem.readFileData(tempFilepath); - if (buffer.hasArray()) { - return new ByteArrayInputStream(buffer.array()); - } - final byte[] data = new byte[buffer.remaining()]; - buffer.clear(); - buffer.get(data); - return new ByteArrayInputStream(data); - } - } - catch (final IOException e) { - throw new RuntimeException("CASC parser error for: " + tempFilepath, e); - } - return null; - } - - @Override - public ByteBuffer read(String path) { - path = path.toLowerCase(Locale.US).replace('/', '\\').replace(':', '\\'); - final String resolvedAlias = this.fileAliases.get(path); - if (resolvedAlias != null) { - path = resolvedAlias; - } - for (final String prefix : this.prefixes) { - final String tempFilepath = prefix + "\\" + path; - final ByteBuffer stream = internalRead(tempFilepath); - if (stream != null) { - return stream; - } - } - return internalRead(path); - } - - private ByteBuffer internalRead(final String tempFilepath) { - try { - if (this.rootFileSystem.isFile(tempFilepath) && this.rootFileSystem.isFileAvailable(tempFilepath)) { - final ByteBuffer buffer = this.rootFileSystem.readFileData(tempFilepath); - return buffer; - } - } - catch (final IOException e) { - throw new RuntimeException("CASC parser error for: " + tempFilepath, e); - } - return null; - } - - @Override - public File getFile(String filepath) { - filepath = filepath.toLowerCase(Locale.US).replace('/', '\\').replace(':', '\\'); - final String resolvedAlias = this.fileAliases.get(filepath); - if (resolvedAlias != null) { - filepath = resolvedAlias; - } - for (final String prefix : this.prefixes) { - final String tempFilepath = prefix + "\\" + filepath; - final File file = internalGetFile(tempFilepath); - if (file != null) { - return file; - } - } - return internalGetFile(filepath); - } - - private File internalGetFile(final String tempFilepath) { - try { - if (this.rootFileSystem.isFile(tempFilepath) && this.rootFileSystem.isFileAvailable(tempFilepath)) { - final ByteBuffer buffer = this.rootFileSystem.readFileData(tempFilepath); - String tmpdir = System.getProperty("java.io.tmpdir"); - if (!tmpdir.endsWith(File.separator)) { - tmpdir += File.separator; - } - final String tempDir = tmpdir + "MatrixEaterExtract/"; - final File tempProduct = new File(tempDir + tempFilepath.replace('\\', File.separatorChar)); - tempProduct.delete(); - tempProduct.getParentFile().mkdirs(); - try (final FileChannel fileChannel = FileChannel.open(tempProduct.toPath(), StandardOpenOption.CREATE, - StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.TRUNCATE_EXISTING)) { - fileChannel.write(buffer); - } - tempProduct.deleteOnExit(); - return tempProduct; - } - } - catch (final IOException e) { - throw new RuntimeException("CASC parser error for: " + tempFilepath, e); - } - return null; - } - - @Override - public boolean has(String filepath) { - filepath = filepath.toLowerCase(Locale.US).replace('/', '\\').replace(':', '\\'); - final String resolvedAlias = this.fileAliases.get(filepath); - if (resolvedAlias != null) { - filepath = resolvedAlias; - } - for (final String prefix : this.prefixes) { - final String tempFilepath = prefix + "\\" + filepath; - try { - if (this.rootFileSystem.isFile(tempFilepath)) { - return true; - } - } - catch (final IOException e) { - throw new RuntimeException("CASC parser error for: " + tempFilepath, e); - } - } - try { - return this.rootFileSystem.isFile(filepath); - } - catch (final IOException e) { - throw new RuntimeException("CASC parser error for: " + filepath, e); - } - } - - @Override - public Collection getListfile() { - return this.listFile; - } - - @Override - public void close() throws IOException { - this.warcraftIIICASC.close(); - } - -} diff --git a/core/src/com/etheller/warsmash/datasources/CascDataSourceDescriptor.java b/core/src/com/etheller/warsmash/datasources/CascDataSourceDescriptor.java deleted file mode 100644 index 4c590a41..00000000 --- a/core/src/com/etheller/warsmash/datasources/CascDataSourceDescriptor.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.etheller.warsmash.datasources; - -import java.util.Collections; -import java.util.List; - -public class CascDataSourceDescriptor implements DataSourceDescriptor { - /** - * Generated serial id - */ - private static final long serialVersionUID = 832549098549298820L; - private final String gameInstallPath; - private final List prefixes; - - public CascDataSourceDescriptor(final String gameInstallPath, final List prefixes) { - this.gameInstallPath = gameInstallPath; - this.prefixes = prefixes; - } - - @Override - public DataSource createDataSource() { - return new CascDataSource(this.gameInstallPath, this.prefixes.toArray(new String[this.prefixes.size()])); - } - - @Override - public String getDisplayName() { - return "CASC: " + this.gameInstallPath; - } - - public void addPrefix(final String prefix) { - this.prefixes.add(prefix); - } - - public void deletePrefix(final int index) { - this.prefixes.remove(index); - } - - public void movePrefixUp(final int index) { - if (index > 0) { - Collections.swap(this.prefixes, index, index - 1); - } - } - - public void movePrefixDown(final int index) { - if (index < (this.prefixes.size() - 1)) { - Collections.swap(this.prefixes, index, index + 1); - } - } - - public String getGameInstallPath() { - return this.gameInstallPath; - } - - public List getPrefixes() { - return this.prefixes; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + ((this.gameInstallPath == null) ? 0 : this.gameInstallPath.hashCode()); - result = (prime * result) + ((this.prefixes == null) ? 0 : this.prefixes.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final CascDataSourceDescriptor other = (CascDataSourceDescriptor) obj; - if (this.gameInstallPath == null) { - if (other.gameInstallPath != null) { - return false; - } - } - else if (!this.gameInstallPath.equals(other.gameInstallPath)) { - return false; - } - if (this.prefixes == null) { - if (other.prefixes != null) { - return false; - } - } - else if (!this.prefixes.equals(other.prefixes)) { - return false; - } - return true; - } -} diff --git a/core/src/com/etheller/warsmash/datasources/CompoundDataSource.java b/core/src/com/etheller/warsmash/datasources/CompoundDataSource.java deleted file mode 100644 index c4273022..00000000 --- a/core/src/com/etheller/warsmash/datasources/CompoundDataSource.java +++ /dev/null @@ -1,153 +0,0 @@ -package com.etheller.warsmash.datasources; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -public class CompoundDataSource implements DataSource { - private final List mpqList = new ArrayList<>(); - - public CompoundDataSource(final List dataSources) { - if (dataSources != null) { - for (final DataSource dataSource : dataSources) { - this.mpqList.add(dataSource); - } - } - } - - Map cache = new HashMap<>(); - - @Override - public File getFile(final String filepath) { - if (this.cache.containsKey(filepath)) { - return this.cache.get(filepath); - } - try { - for (int i = this.mpqList.size() - 1; i >= 0; i--) { - final DataSource mpq = this.mpqList.get(i); - final File tempProduct = mpq.getFile(filepath); - if (tempProduct != null) { - this.cache.put(filepath, tempProduct); - return tempProduct; - } - } - } - catch (final IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return null; - } - - @Override - public ByteBuffer read(final String path) throws IOException { - try { - for (int i = this.mpqList.size() - 1; i >= 0; i--) { - final DataSource mpq = this.mpqList.get(i); - final ByteBuffer buffer = mpq.read(path); - if (buffer != null) { - return buffer; - } - } - } - catch (final IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return null; - } - - @Override - public InputStream getResourceAsStream(final String filepath) { - try { - for (int i = this.mpqList.size() - 1; i >= 0; i--) { - final DataSource mpq = this.mpqList.get(i); - final InputStream resourceAsStream = mpq.getResourceAsStream(filepath); - if (resourceAsStream != null) { - return resourceAsStream; - } - } - } - catch (final IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return null; - } - - @Override - public boolean has(final String filepath) { - if (this.cache.containsKey(filepath)) { - return true; - } - for (int i = this.mpqList.size() - 1; i >= 0; i--) { - final DataSource mpq = this.mpqList.get(i); - if (mpq.has(filepath)) { - return true; - } - } - return false; - } - - public void refresh(final List dataSourceDescriptors) { - for (final DataSource dataSource : this.mpqList) { - try { - dataSource.close(); - } - catch (final NullPointerException e) { - e.printStackTrace(); - } - catch (final IOException e) { - e.printStackTrace(); - } - } - this.cache.clear(); - this.mpqList.clear(); - if (dataSourceDescriptors != null) { - for (final DataSourceDescriptor descriptor : dataSourceDescriptors) { - this.mpqList.add(descriptor.createDataSource()); - } - } - } - - public interface LoadedMPQ { - void unload(); - - boolean hasListfile(); - - boolean has(String path); - } - - public Set getMergedListfile() { - final Set listfile = new HashSet<>(); - for (final DataSource mpqGuy : this.mpqList) { - final Collection dataSourceListfile = mpqGuy.getListfile(); - if (dataSourceListfile != null) { - for (final String element : dataSourceListfile) { - listfile.add(element); - } - } - } - return listfile; - } - - @Override - public Collection getListfile() { - return getMergedListfile(); - } - - @Override - public void close() throws IOException { - for (final DataSource mpqGuy : this.mpqList) { - mpqGuy.close(); - } - } -} diff --git a/core/src/com/etheller/warsmash/datasources/CompoundDataSourceDescriptor.java b/core/src/com/etheller/warsmash/datasources/CompoundDataSourceDescriptor.java deleted file mode 100644 index 0c1a9579..00000000 --- a/core/src/com/etheller/warsmash/datasources/CompoundDataSourceDescriptor.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.etheller.warsmash.datasources; - -import java.util.ArrayList; -import java.util.List; - -public class CompoundDataSourceDescriptor implements DataSourceDescriptor { - private final List dataSourceDescriptors; - - public CompoundDataSourceDescriptor(final List dataSourceDescriptors) { - this.dataSourceDescriptors = dataSourceDescriptors; - } - - @Override - public DataSource createDataSource() { - final List dataSources = new ArrayList<>(); - for (final DataSourceDescriptor descriptor : this.dataSourceDescriptors) { - dataSources.add(descriptor.createDataSource()); - } - return new CompoundDataSource(dataSources); - } - - @Override - public String getDisplayName() { - return "CompoundDataSourceDescriptor"; - } - -} diff --git a/core/src/com/etheller/warsmash/datasources/DataSource.java b/core/src/com/etheller/warsmash/datasources/DataSource.java deleted file mode 100644 index bb82b22e..00000000 --- a/core/src/com/etheller/warsmash/datasources/DataSource.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.etheller.warsmash.datasources; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.util.Collection; - -public interface DataSource { - /** - * Efficiently return a stream instance that will read the data source file's - * contents directly from the data source. For example, this will read a file - * within an MPQ or CASC storage without extracting it. - * - * @param filepath - * @return - * @throws IOException - */ - InputStream getResourceAsStream(String filepath) throws IOException; - - /** - * Inefficiently copy a file from the data source onto the Hard Drive of the - * computer, and then return a java File instance pointed at the file. - * - * @param filepath - * @return - * @throws IOException - */ - File getFile(String filepath) throws IOException; - - ByteBuffer read(String path) throws IOException; - - /** - * Returns true if the data source contains a valid entry for a particular file. - * Some data sources (MPQs) may contain files for which this returns true, even - * though they cannot list the file in their Listfile. - * - * @param filepath - * @return - */ - boolean has(String filepath); - - /** - * @return a list of data source contents, or null if no list is provided - */ - Collection getListfile(); - - void close() throws IOException; -} diff --git a/core/src/com/etheller/warsmash/datasources/DataSourceDescriptor.java b/core/src/com/etheller/warsmash/datasources/DataSourceDescriptor.java deleted file mode 100644 index 2b4fd30d..00000000 --- a/core/src/com/etheller/warsmash/datasources/DataSourceDescriptor.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.datasources; - -import java.io.Serializable; - -public interface DataSourceDescriptor extends Serializable { - DataSource createDataSource(); - - String getDisplayName(); -} diff --git a/core/src/com/etheller/warsmash/datasources/FolderDataSource.java b/core/src/com/etheller/warsmash/datasources/FolderDataSource.java deleted file mode 100644 index 356eb7ea..00000000 --- a/core/src/com/etheller/warsmash/datasources/FolderDataSource.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.etheller.warsmash.datasources; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; -import java.util.function.Consumer; - -public class FolderDataSource implements DataSource { - - private final Path folderPath; - private final Set listfile; - - public FolderDataSource(final Path folderPath) { - this.folderPath = folderPath; - this.listfile = new HashSet<>(); - try { - Files.walk(folderPath).filter(Files::isRegularFile).forEach(new Consumer() { - @Override - public void accept(final Path t) { - FolderDataSource.this.listfile.add(folderPath.relativize(t).toString()); - } - }); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public InputStream getResourceAsStream(String filepath) throws IOException { - filepath = fixFilepath(filepath); - if (!has(filepath)) { - return null; - } - return Files.newInputStream(this.folderPath.resolve(filepath), StandardOpenOption.READ); - } - - @Override - public File getFile(String filepath) throws IOException { - filepath = fixFilepath(filepath); - if (!has(filepath)) { - return null; - } - return new File(this.folderPath.toString() + File.separatorChar + filepath); - } - - @Override - public ByteBuffer read(String path) throws IOException { - path = fixFilepath(path); - if (!has(path)) { - return null; - } - return ByteBuffer.wrap(Files.readAllBytes(Paths.get(this.folderPath.toString(), path))); - } - - @Override - public boolean has(String filepath) { - filepath = fixFilepath(filepath); - if ("".equals(filepath)) { - return false; // special case for folder data source, dont do this - } - final Path resolvedPath = this.folderPath.resolve(filepath); - return Files.exists(resolvedPath) && !Files.isDirectory(resolvedPath); - } - - @Override - public Collection getListfile() { - return this.listfile; - } - - @Override - public void close() { - } - - private static String fixFilepath(final String filepath) { - return filepath.replace('\\', File.separatorChar).replace('/', File.separatorChar).replace(':', - File.separatorChar); - } -} diff --git a/core/src/com/etheller/warsmash/datasources/FolderDataSourceDescriptor.java b/core/src/com/etheller/warsmash/datasources/FolderDataSourceDescriptor.java deleted file mode 100644 index 174aad33..00000000 --- a/core/src/com/etheller/warsmash/datasources/FolderDataSourceDescriptor.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.etheller.warsmash.datasources; - -import java.nio.file.Paths; - -public class FolderDataSourceDescriptor implements DataSourceDescriptor { - /** - * Generated serial id - */ - private static final long serialVersionUID = -476724730967709309L; - private final String folderPath; - - public FolderDataSourceDescriptor(final String folderPath) { - this.folderPath = folderPath; - } - - @Override - public DataSource createDataSource() { - return new FolderDataSource(Paths.get(this.folderPath)); - } - - @Override - public String getDisplayName() { - return "Folder: " + this.folderPath; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + ((this.folderPath == null) ? 0 : this.folderPath.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final FolderDataSourceDescriptor other = (FolderDataSourceDescriptor) obj; - if (this.folderPath == null) { - if (other.folderPath != null) { - return false; - } - } - else if (!this.folderPath.equals(other.folderPath)) { - return false; - } - return true; - } - -} diff --git a/core/src/com/etheller/warsmash/datasources/MpqDataSource.java b/core/src/com/etheller/warsmash/datasources/MpqDataSource.java deleted file mode 100644 index 9bdfbbd2..00000000 --- a/core/src/com/etheller/warsmash/datasources/MpqDataSource.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.etheller.warsmash.datasources; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.nio.channels.SeekableByteChannel; -import java.nio.file.Files; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import mpq.ArchivedFile; -import mpq.ArchivedFileExtractor; -import mpq.ArchivedFileStream; -import mpq.HashLookup; -import mpq.MPQArchive; -import mpq.MPQException; - -public class MpqDataSource implements DataSource { - - private final MPQArchive archive; - private final SeekableByteChannel inputChannel; - private final ArchivedFileExtractor extractor = new ArchivedFileExtractor(); - - public MpqDataSource(final MPQArchive archive, final SeekableByteChannel inputChannel) { - this.archive = archive; - this.inputChannel = inputChannel; - } - - public MPQArchive getArchive() { - return this.archive; - } - - public SeekableByteChannel getInputChannel() { - return this.inputChannel; - } - - @Override - public InputStream getResourceAsStream(final String filepath) throws IOException { - ArchivedFile file = null; - try { - file = this.archive.lookupHash2(new HashLookup(filepath)); - } - catch (final MPQException exc) { - if (exc.getMessage().equals("lookup not found")) { - return null; - } - else { - throw new IOException(exc); - } - } - final ArchivedFileStream stream = new ArchivedFileStream(this.inputChannel, this.extractor, file); - final InputStream newInputStream = Channels.newInputStream(stream); - return newInputStream; - } - - @Override - public ByteBuffer read(final String path) throws IOException { - ArchivedFile file = null; - try { - file = this.archive.lookupHash2(new HashLookup(path)); - } - catch (final MPQException exc) { - if (exc.getMessage().equals("lookup not found")) { - return null; - } - else { - throw new IOException(exc); - } - } - try (final ArchivedFileStream stream = new ArchivedFileStream(this.inputChannel, this.extractor, file)) { - final long size = stream.size(); - final ByteBuffer buffer = ByteBuffer.allocate((int) size); - stream.read(buffer); - return buffer; - } - } - - @Override - public File getFile(final String filepath) throws IOException { - // TODO Auto-generated method stub - // System.out.println("getting it from the outside: " + - // filepath); - ArchivedFile file = null; - try { - file = this.archive.lookupHash2(new HashLookup(filepath)); - } - catch (final MPQException exc) { - if (exc.getMessage().equals("lookup not found")) { - return null; - } - else { - throw new IOException(exc); - } - } - final ArchivedFileStream stream = new ArchivedFileStream(this.inputChannel, this.extractor, file); - final InputStream newInputStream = Channels.newInputStream(stream); - String tmpdir = System.getProperty("java.io.tmpdir"); - if (!tmpdir.endsWith(File.separator)) { - tmpdir += File.separator; - } - final String tempDir = tmpdir + "RMSExtract/"; - final File tempProduct = new File(tempDir + filepath.replace('\\', File.separatorChar)); - tempProduct.delete(); - tempProduct.getParentFile().mkdirs(); - Files.copy(newInputStream, tempProduct.toPath()); - tempProduct.deleteOnExit(); - return tempProduct; - } - - @Override - public boolean has(final String filepath) { - try { - this.archive.lookupPath(filepath); - return true; - } - catch (final MPQException exc) { - if (exc.getMessage().equals("lookup not found")) { - return false; - } - else { - throw new RuntimeException(exc); - } - } - } - - @Override - public Collection getListfile() { - try { - final Set listfile = new HashSet<>(); - ArchivedFile listfileContents; - listfileContents = this.archive.lookupHash2(new HashLookup("(listfile)")); - final ArchivedFileStream stream = new ArchivedFileStream(this.inputChannel, this.extractor, - listfileContents); - final InputStream newInputStream = Channels.newInputStream(stream); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(newInputStream))) { - String line; - while ((line = reader.readLine()) != null) { - listfile.add(line); - } - } - catch (final IOException exc) { - throw new RuntimeException(exc); - } - return listfile; - } - catch (final MPQException exc) { - if (exc.getMessage().equals("lookup not found")) { - return null; - } - else { - throw new RuntimeException(exc); - } - } - } - - @Override - public void close() throws IOException { - this.inputChannel.close(); - } - -} diff --git a/core/src/com/etheller/warsmash/datasources/MpqDataSourceDescriptor.java b/core/src/com/etheller/warsmash/datasources/MpqDataSourceDescriptor.java deleted file mode 100644 index 276a6661..00000000 --- a/core/src/com/etheller/warsmash/datasources/MpqDataSourceDescriptor.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.etheller.warsmash.datasources; - -import java.io.IOException; -import java.nio.channels.SeekableByteChannel; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; -import java.util.EnumSet; - -import mpq.MPQArchive; -import mpq.MPQException; - -public class MpqDataSourceDescriptor implements DataSourceDescriptor { - /** - * Generated serial id - */ - private static final long serialVersionUID = 8424254987711783598L; - private final String mpqFilePath; - - public MpqDataSourceDescriptor(final String mpqFilePath) { - this.mpqFilePath = mpqFilePath; - } - - @Override - public DataSource createDataSource() { - try { - SeekableByteChannel sbc; - sbc = Files.newByteChannel(Paths.get(this.mpqFilePath), EnumSet.of(StandardOpenOption.READ)); - return new MpqDataSource(new MPQArchive(sbc), sbc); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - catch (final MPQException e) { - throw new RuntimeException(e); - } - } - - @Override - public String getDisplayName() { - return "MPQ Archive: " + this.mpqFilePath; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + ((this.mpqFilePath == null) ? 0 : this.mpqFilePath.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final MpqDataSourceDescriptor other = (MpqDataSourceDescriptor) obj; - if (this.mpqFilePath == null) { - if (other.mpqFilePath != null) { - return false; - } - } - else if (!this.mpqFilePath.equals(other.mpqFilePath)) { - return false; - } - return true; - } - - public String getMpqFilePath() { - return this.mpqFilePath; - } -} diff --git a/core/src/com/etheller/warsmash/datasources/SubdirDataSource.java b/core/src/com/etheller/warsmash/datasources/SubdirDataSource.java deleted file mode 100644 index 708d340d..00000000 --- a/core/src/com/etheller/warsmash/datasources/SubdirDataSource.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.etheller.warsmash.datasources; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class SubdirDataSource implements DataSource { - private final DataSource dataSource; - private final String subdir; - - public SubdirDataSource(final DataSource dataSource, final String subdir) { - this.dataSource = dataSource; - this.subdir = subdir; - } - - @Override - public File getFile(final String filepath) throws IOException { - return this.dataSource.getFile(this.subdir + filepath); - } - - @Override - public ByteBuffer read(final String path) throws IOException { - return this.dataSource.read(this.subdir + path); - } - - @Override - public InputStream getResourceAsStream(final String filepath) throws IOException { - return this.dataSource.getResourceAsStream(this.subdir + filepath); - } - - @Override - public boolean has(final String filepath) { - return this.dataSource.has(this.subdir + filepath); - } - - @Override - public Collection getListfile() { - final List results = new ArrayList<>(); - for (final String x : this.dataSource.getListfile()) { - if (x.startsWith(this.subdir)) { - results.add(x.substring(this.subdir.length())); - } - } - return results; - } - - @Override - public void close() throws IOException { - this.dataSource.close(); - } -} diff --git a/core/src/com/etheller/warsmash/networking/ClientToServerListener.java b/core/src/com/etheller/warsmash/networking/ClientToServerListener.java deleted file mode 100644 index 972606ec..00000000 --- a/core/src/com/etheller/warsmash/networking/ClientToServerListener.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.etheller.warsmash.networking; - -import java.net.SocketAddress; - -public interface ClientToServerListener { - void joinGame(SocketAddress sourceAddress); - - void issueTargetOrder(SocketAddress sourceAddress, int unitHandleId, int abilityHandleId, int orderId, - int targetHandleId, boolean queue); - - void issuePointOrder(SocketAddress sourceAddress, int unitHandleId, int abilityHandleId, int orderId, float x, - float y, boolean queue); - - void issueDropItemAtPointOrder(SocketAddress sourceAddress, int unitHandleId, int abilityHandleId, int orderId, - int targetHandleId, float x, float y, final boolean queue); - - void issueImmediateOrder(SocketAddress sourceAddress, int unitHandleId, int abilityHandleId, int orderId, - boolean queue); - - void unitCancelTrainingItem(SocketAddress sourceAddress, int unitHandleId, int cancelIndex); - - void finishedTurn(SocketAddress sourceAddress, int gameTurnTick); - - void framesSkipped(int nFramesSkipped); - -} diff --git a/core/src/com/etheller/warsmash/networking/ClientToServerProtocol.java b/core/src/com/etheller/warsmash/networking/ClientToServerProtocol.java deleted file mode 100644 index 50faac5f..00000000 --- a/core/src/com/etheller/warsmash/networking/ClientToServerProtocol.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.networking; - -public class ClientToServerProtocol { - - public static final int ISSUE_TARGET_ORDER = 1; - public static final int ISSUE_POINT_ORDER = 2; - public static final int ISSUE_DROP_ITEM_ORDER = 3; - public static final int ISSUE_IMMEDIATE_ORDER = 4; - public static final int UNIT_CANCEL_TRAINING = 5; - public static final int FINISHED_TURN = 6; - public static final int JOIN_GAME = 7; - public static final int FRAMES_SKIPPED = 8; -} diff --git a/core/src/com/etheller/warsmash/networking/GameTurnManager.java b/core/src/com/etheller/warsmash/networking/GameTurnManager.java deleted file mode 100644 index 3fc5f1ee..00000000 --- a/core/src/com/etheller/warsmash/networking/GameTurnManager.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.etheller.warsmash.networking; - -public interface GameTurnManager { - int getLatestCompletedTurn(); - - void turnCompleted(int gameTurnTick); - - void framesSkipped(float skippedCount); - - GameTurnManager PAUSED = new GameTurnManager() { - @Override - public int getLatestCompletedTurn() { - return Integer.MIN_VALUE; - } - - @Override - public void turnCompleted(final int gameTurnTick) { - System.err.println("got turnCompleted(" + gameTurnTick + ") while paused !!"); - } - - @Override - public void framesSkipped(final float skippedCount) { - } - }; - - GameTurnManager LOCAL = new GameTurnManager() { - @Override - public int getLatestCompletedTurn() { - return Integer.MAX_VALUE; - } - - @Override - public void turnCompleted(final int gameTurnTick) { - } - - @Override - public void framesSkipped(final float skippedCount) { - } - }; - -} diff --git a/core/src/com/etheller/warsmash/networking/MultiplayerHack.java b/core/src/com/etheller/warsmash/networking/MultiplayerHack.java deleted file mode 100644 index a8a640b3..00000000 --- a/core/src/com/etheller/warsmash/networking/MultiplayerHack.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.etheller.warsmash.networking; - -public class MultiplayerHack { - public static String MULTIPLAYER_HACK_SERVER_ADDR = null; - public static int LP_VAL = 0; -} diff --git a/core/src/com/etheller/warsmash/networking/ServerToClientListener.java b/core/src/com/etheller/warsmash/networking/ServerToClientListener.java deleted file mode 100644 index 9903ca2e..00000000 --- a/core/src/com/etheller/warsmash/networking/ServerToClientListener.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.networking; - -public interface ServerToClientListener { - void acceptJoin(int playerIndex); - - void issueTargetOrder(int playerIndex, int unitHandleId, int abilityHandleId, int orderId, int targetHandleId, - boolean queue); - - void issuePointOrder(int playerIndex, int unitHandleId, int abilityHandleId, int orderId, float x, float y, - boolean queue); - - void issueDropItemAtPointOrder(int playerIndex, int unitHandleId, int abilityHandleId, int orderId, - int targetHandleId, float x, float y, final boolean queue); - - void issueImmediateOrder(int playerIndex, int unitHandleId, int abilityHandleId, int orderId, boolean queue); - - void unitCancelTrainingItem(int playerIndex, int unitHandleId, int cancelIndex); - - void startGame(); - - void finishedTurn(int gameTurnTick); - - void heartbeat(); -} diff --git a/core/src/com/etheller/warsmash/networking/ServerToClientProtocol.java b/core/src/com/etheller/warsmash/networking/ServerToClientProtocol.java deleted file mode 100644 index 0c88662a..00000000 --- a/core/src/com/etheller/warsmash/networking/ServerToClientProtocol.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.etheller.warsmash.networking; - -public class ServerToClientProtocol { - - public static final int ISSUE_TARGET_ORDER = 1; - public static final int ISSUE_POINT_ORDER = 2; - public static final int ISSUE_DROP_ITEM_ORDER = 3; - public static final int ISSUE_IMMEDIATE_ORDER = 4; - public static final int UNIT_CANCEL_TRAINING = 5; - public static final int FINISHED_TURN = 6; - public static final int ACCEPT_JOIN = 7; - public static final int START_GAME = 8; - public static final int HEARTBEAT = 9; -} diff --git a/core/src/com/etheller/warsmash/networking/WarsmashClient.java b/core/src/com/etheller/warsmash/networking/WarsmashClient.java deleted file mode 100644 index 21f56a29..00000000 --- a/core/src/com/etheller/warsmash/networking/WarsmashClient.java +++ /dev/null @@ -1,238 +0,0 @@ -package com.etheller.warsmash.networking; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.*; - -import com.badlogic.gdx.Gdx; -import com.etheller.warsmash.networking.udp.OrderedUdpClient; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerUnitOrderExecutor; - -public class WarsmashClient implements ServerToClientListener, GameTurnManager { - private final OrderedUdpClient udpClient; - private final War3MapViewer game; - private final Map indexToExecutor = new HashMap<>(); - private int latestCompletedTurn = -1; - private int latestLocallyRequestedTurn = -1; - private final WarsmashClientWriter writer; - private final Queue queuedMessages = new ArrayDeque<>(); - - public WarsmashClient(final InetAddress serverAddress, final War3MapViewer game) - throws UnknownHostException, IOException { - this.udpClient = new OrderedUdpClient(serverAddress, WarsmashConstants.PORT_NUMBER, - new WarsmashClientParser(this)); - this.game = game; - this.writer = new WarsmashClientWriter(this.udpClient); - } - - public CPlayerUnitOrderExecutor getExecutor(final int playerIndex) { - CPlayerUnitOrderExecutor executor = this.indexToExecutor.get(playerIndex); - if (executor == null) { - executor = new CPlayerUnitOrderExecutor(this.game.simulation, playerIndex); - this.indexToExecutor.put(playerIndex, executor); - } - return executor; - } - - public void startThread() { - new Thread(this.udpClient).start(); - } - - @Override - public void acceptJoin(final int playerIndex) { - this.game.setLocalPlayerIndex(playerIndex); - } - - @Override - public void issueTargetOrder(final int playerIndex, final int unitHandleId, final int abilityHandleId, - final int orderId, final int targetHandleId, final boolean queue) { - final CPlayerUnitOrderExecutor executor = getExecutor(playerIndex); - Gdx.app.postRunnable(new Runnable() { - @Override - public void run() { - int currentServerTurnInProgress = latestCompletedTurn + 1; - if(currentServerTurnInProgress > latestLocallyRequestedTurn) { - queuedMessages.add(new QueuedMessage(latestCompletedTurn) { - @Override - public void run() { - executor.issueTargetOrder(unitHandleId, abilityHandleId, orderId, targetHandleId, queue); - } - }); - } else if(currentServerTurnInProgress == latestLocallyRequestedTurn) { - executor.issueTargetOrder(unitHandleId, abilityHandleId, orderId, targetHandleId, queue); - } else { - System.err.println("Turn tick system mismatch: " + currentServerTurnInProgress + " < " + latestLocallyRequestedTurn); - } - } - }); - } - - @Override - public void issuePointOrder(final int playerIndex, final int unitHandleId, final int abilityHandleId, - final int orderId, final float x, final float y, final boolean queue) { - final CPlayerUnitOrderExecutor executor = getExecutor(playerIndex); - Gdx.app.postRunnable(new Runnable() { - @Override - public void run() { - int currentServerTurnInProgress = latestCompletedTurn + 1; - if(currentServerTurnInProgress > latestLocallyRequestedTurn) { - queuedMessages.add(new QueuedMessage(latestCompletedTurn) { - @Override - public void run() { - executor.issuePointOrder(unitHandleId, abilityHandleId, orderId, x, y, queue); - } - }); - } else if(currentServerTurnInProgress == latestLocallyRequestedTurn) { - executor.issuePointOrder(unitHandleId, abilityHandleId, orderId, x, y, queue);; - } else { - System.err.println("Turn tick system mismatch: " + currentServerTurnInProgress + " < " + latestLocallyRequestedTurn); - } - } - }); - - } - - @Override - public void issueDropItemAtPointOrder(final int playerIndex, final int unitHandleId, final int abilityHandleId, - final int orderId, final int targetHandleId, final float x, final float y, final boolean queue) { - final CPlayerUnitOrderExecutor executor = getExecutor(playerIndex); - Gdx.app.postRunnable(new Runnable() { - @Override - public void run() { - int currentServerTurnInProgress = latestCompletedTurn + 1; - if(currentServerTurnInProgress > latestLocallyRequestedTurn) { - queuedMessages.add(new QueuedMessage(latestCompletedTurn) { - @Override - public void run() { - executor.issueDropItemAtPointOrder(unitHandleId, abilityHandleId, orderId, targetHandleId, x, y, queue); - } - }); - } else if(currentServerTurnInProgress == latestLocallyRequestedTurn) { - executor.issueDropItemAtPointOrder(unitHandleId, abilityHandleId, orderId, targetHandleId, x, y, queue); - } else { - System.err.println("Turn tick system mismatch: " + currentServerTurnInProgress + " < " + latestLocallyRequestedTurn); - } - } - }); - } - - @Override - public void issueImmediateOrder(final int playerIndex, final int unitHandleId, final int abilityHandleId, - final int orderId, final boolean queue) { - final CPlayerUnitOrderExecutor executor = getExecutor(playerIndex); - Gdx.app.postRunnable(new Runnable() { - @Override - public void run() { - int currentServerTurnInProgress = latestCompletedTurn + 1; - if(currentServerTurnInProgress > latestLocallyRequestedTurn) { - queuedMessages.add(new QueuedMessage(latestCompletedTurn) { - @Override - public void run() { - executor.issueImmediateOrder(unitHandleId, abilityHandleId, orderId, queue); - } - }); - } else if(currentServerTurnInProgress == latestLocallyRequestedTurn) { - executor.issueImmediateOrder(unitHandleId, abilityHandleId, orderId, queue); - } else { - System.err.println("Turn tick system mismatch: " + currentServerTurnInProgress + " < " + latestLocallyRequestedTurn); - } - } - }); - } - - @Override - public void unitCancelTrainingItem(final int playerIndex, final int unitHandleId, final int cancelIndex) { - final CPlayerUnitOrderExecutor executor = getExecutor(playerIndex); - Gdx.app.postRunnable(new Runnable() { - @Override - public void run() { - int currentServerTurnInProgress = latestCompletedTurn + 1; - if(currentServerTurnInProgress > latestLocallyRequestedTurn) { - queuedMessages.add(new QueuedMessage(latestCompletedTurn) { - @Override - public void run() { - executor.unitCancelTrainingItem(unitHandleId, cancelIndex); - } - }); - } else if(currentServerTurnInProgress == latestLocallyRequestedTurn) { - executor.unitCancelTrainingItem(unitHandleId, cancelIndex); - } else { - System.err.println("Turn tick system mismatch: " + currentServerTurnInProgress + " < " + latestLocallyRequestedTurn); - } - } - }); - } - - @Override - public void finishedTurn(final int gameTurnTick) { - if(WarsmashConstants.VERBOSE_LOGGING) { - System.out.println("finishedTurn " + gameTurnTick); - } - Gdx.app.postRunnable(new Runnable() { - @Override - public void run() { - WarsmashClient.this.latestCompletedTurn = gameTurnTick; - } - }); - } - - @Override - public void turnCompleted(final int gameTurnTick) { - this.writer.finishedTurn(gameTurnTick); - this.writer.send(); - latestLocallyRequestedTurn = gameTurnTick; - while(!queuedMessages.isEmpty() && queuedMessages.peek().messageTurnTick == latestLocallyRequestedTurn) { - queuedMessages.poll().run(); - } - } - - @Override - public void startGame() { - Gdx.app.postRunnable(new Runnable() { - @Override - public void run() { - WarsmashClient.this.game.setGameTurnManager(WarsmashClient.this); - } - }); - } - - @Override - public void framesSkipped(final float skippedCount) { - this.writer.framesSkipped((int) skippedCount); - this.writer.send(); - } - - @Override - public void heartbeat() { - // Not doing anything here at the moment. The act of the server sending us that packet - // will let the middle layer UDP system know to re-request any lost packets based - // on the heartbeat seq no. But at app layer, here, we can ignore it. - System.out.println("got heartbeat() from server"); - } - - @Override - public int getLatestCompletedTurn() { - return this.latestCompletedTurn; - } - - public WarsmashClientWriter getWriter() { - return this.writer; - } - - private static abstract class QueuedMessage implements Runnable { - private int messageTurnTick; - - public QueuedMessage(int messageTurnTick) { - this.messageTurnTick = messageTurnTick; - } - - public final int getMessageTurnTick() { - return messageTurnTick; - } - - public abstract void run(); - } -} diff --git a/core/src/com/etheller/warsmash/networking/WarsmashClientParser.java b/core/src/com/etheller/warsmash/networking/WarsmashClientParser.java deleted file mode 100644 index 86b6fcbf..00000000 --- a/core/src/com/etheller/warsmash/networking/WarsmashClientParser.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.etheller.warsmash.networking; - -import java.nio.ByteBuffer; - -import com.etheller.warsmash.networking.udp.OrderedUdpClientListener; - -public class WarsmashClientParser implements OrderedUdpClientListener { - private final ServerToClientListener listener; - - public WarsmashClientParser(final ServerToClientListener listener) { - this.listener = listener; - } - - @Override - public void cantReplay(final int seqNo) { - throw new IllegalStateException("Cant replay seqNo=" + seqNo + " !"); - } - - @Override - public void parse(final ByteBuffer buffer) { - final int initialLimit = buffer.limit(); - try { - while (buffer.hasRemaining()) { - final int length = buffer.getInt(); - if (length > buffer.remaining()) { - // this packet is junk to us, so we will skip and continue (drop system will - // handle it) - System.err.println("Got mismatched protocol length " + length + " > " + buffer.remaining() + "!!"); - } - final int protocol = buffer.getInt(); - switch (protocol) { - case ServerToClientProtocol.ISSUE_TARGET_ORDER: { - final int playerIndex = buffer.getInt(); - final int unitHandleId = buffer.getInt(); - final int abilityHandleId = buffer.getInt(); - final int orderId = buffer.getInt(); - final int targetHandleId = buffer.getInt(); - final boolean queue = buffer.get() == 1; - this.listener.issueTargetOrder(playerIndex, unitHandleId, abilityHandleId, orderId, targetHandleId, - queue); - break; - } - case ServerToClientProtocol.ISSUE_POINT_ORDER: { - final int playerIndex = buffer.getInt(); - final int unitHandleId = buffer.getInt(); - final int abilityHandleId = buffer.getInt(); - final int orderId = buffer.getInt(); - final float x = buffer.getFloat(); - final float y = buffer.getFloat(); - final boolean queue = buffer.get() == 1; - this.listener.issuePointOrder(playerIndex, unitHandleId, abilityHandleId, orderId, x, y, queue); - break; - } - case ServerToClientProtocol.ISSUE_DROP_ITEM_ORDER: { - final int playerIndex = buffer.getInt(); - final int unitHandleId = buffer.getInt(); - final int abilityHandleId = buffer.getInt(); - final int orderId = buffer.getInt(); - final int targetHandleId = buffer.getInt(); - final float x = buffer.getFloat(); - final float y = buffer.getFloat(); - final boolean queue = buffer.get() == 1; - this.listener.issueDropItemAtPointOrder(playerIndex, unitHandleId, abilityHandleId, orderId, - targetHandleId, x, y, queue); - break; - } - case ServerToClientProtocol.ISSUE_IMMEDIATE_ORDER: { - final int playerIndex = buffer.getInt(); - final int unitHandleId = buffer.getInt(); - final int abilityHandleId = buffer.getInt(); - final int orderId = buffer.getInt(); - final boolean queue = buffer.get() == 1; - this.listener.issueImmediateOrder(playerIndex, unitHandleId, abilityHandleId, orderId, queue); - break; - } - case ServerToClientProtocol.UNIT_CANCEL_TRAINING: { - final int playerIndex = buffer.getInt(); - final int unitHandleId = buffer.getInt(); - final int cancelIndex = buffer.getInt(); - this.listener.unitCancelTrainingItem(playerIndex, unitHandleId, cancelIndex); - break; - } - case ServerToClientProtocol.FINISHED_TURN: { - final int gameTurnTick = buffer.getInt(); - this.listener.finishedTurn(gameTurnTick); - break; - } - case ServerToClientProtocol.ACCEPT_JOIN: { - final int playerIndex = buffer.getInt(); - this.listener.acceptJoin(playerIndex); - break; - } - case ServerToClientProtocol.START_GAME: { - this.listener.startGame(); - break; - } - case ServerToClientProtocol.HEARTBEAT: { - this.listener.heartbeat(); - break; - } - - default: - System.err.println("Got unknown protocol: " + protocol); - break; - } - } - } - finally { - buffer.position(initialLimit); - } - } -} diff --git a/core/src/com/etheller/warsmash/networking/WarsmashClientSendingOrderListener.java b/core/src/com/etheller/warsmash/networking/WarsmashClientSendingOrderListener.java deleted file mode 100644 index 9fd00f48..00000000 --- a/core/src/com/etheller/warsmash/networking/WarsmashClientSendingOrderListener.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.etheller.warsmash.networking; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerUnitOrderListener; - -public class WarsmashClientSendingOrderListener implements CPlayerUnitOrderListener { - private final WarsmashClientWriter writer; - - public WarsmashClientSendingOrderListener(final WarsmashClientWriter writer) { - this.writer = writer; - } - - @Override - public void issueTargetOrder(final int unitHandleId, final int abilityHandleId, final int orderId, - final int targetHandleId, final boolean queue) { - this.writer.issueTargetOrder(unitHandleId, abilityHandleId, orderId, targetHandleId, queue); - this.writer.send(); - } - - @Override - public void issuePointOrder(final int unitHandleId, final int abilityHandleId, final int orderId, final float x, - final float y, final boolean queue) { - this.writer.issuePointOrder(unitHandleId, abilityHandleId, orderId, x, y, queue); - this.writer.send(); - } - - @Override - public void issueDropItemAtPointOrder(final int unitHandleId, final int abilityHandleId, final int orderId, - final int targetHandleId, final float x, final float y, final boolean queue) { - this.writer.issueDropItemAtPointOrder(unitHandleId, abilityHandleId, orderId, targetHandleId, x, y, queue); - this.writer.send(); - } - - @Override - public void issueImmediateOrder(final int unitHandleId, final int abilityHandleId, final int orderId, - final boolean queue) { - this.writer.issueImmediateOrder(unitHandleId, abilityHandleId, orderId, queue); - this.writer.send(); - } - - @Override - public void unitCancelTrainingItem(final int unitHandleId, final int cancelIndex) { - this.writer.unitCancelTrainingItem(unitHandleId, cancelIndex); - this.writer.send(); - } - -} diff --git a/core/src/com/etheller/warsmash/networking/WarsmashClientWriter.java b/core/src/com/etheller/warsmash/networking/WarsmashClientWriter.java deleted file mode 100644 index e0504409..00000000 --- a/core/src/com/etheller/warsmash/networking/WarsmashClientWriter.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.etheller.warsmash.networking; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import com.etheller.warsmash.networking.udp.OrderedUdpClient; - -public class WarsmashClientWriter { - private final OrderedUdpClient client; - private final ByteBuffer sendBuffer = ByteBuffer.allocate(1024).order(ByteOrder.BIG_ENDIAN); - - public WarsmashClientWriter(final OrderedUdpClient client) { - this.client = client; - } - - public void issueTargetOrder(final int unitHandleId, final int abilityHandleId, final int orderId, - final int targetHandleId, final boolean queue) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4 + 4 + 4 + 4 + 4 + 1); - this.sendBuffer.putInt(ClientToServerProtocol.ISSUE_TARGET_ORDER); - this.sendBuffer.putInt(unitHandleId); - this.sendBuffer.putInt(abilityHandleId); - this.sendBuffer.putInt(orderId); - this.sendBuffer.putInt(targetHandleId); - this.sendBuffer.put(queue ? (byte) 1 : (byte) 0); - } - - public void issuePointOrder(final int unitHandleId, final int abilityHandleId, final int orderId, final float x, - final float y, final boolean queue) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4 + 4 + 4 + 4 + 4 + 4 + 1); - this.sendBuffer.putInt(ClientToServerProtocol.ISSUE_POINT_ORDER); - this.sendBuffer.putInt(unitHandleId); - this.sendBuffer.putInt(abilityHandleId); - this.sendBuffer.putInt(orderId); - this.sendBuffer.putFloat(x); - this.sendBuffer.putFloat(y); - this.sendBuffer.put(queue ? (byte) 1 : (byte) 0); - } - - public void issueDropItemAtPointOrder(final int unitHandleId, final int abilityHandleId, final int orderId, - final int targetHandleId, final float x, final float y, final boolean queue) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4 + 4 + 4 + 4 + 4 + 4 + 4 + 1); - this.sendBuffer.putInt(ClientToServerProtocol.ISSUE_DROP_ITEM_ORDER); - this.sendBuffer.putInt(unitHandleId); - this.sendBuffer.putInt(abilityHandleId); - this.sendBuffer.putInt(orderId); - this.sendBuffer.putInt(targetHandleId); - this.sendBuffer.putFloat(x); - this.sendBuffer.putFloat(y); - this.sendBuffer.put(queue ? (byte) 1 : (byte) 0); - } - - public void issueImmediateOrder(final int unitHandleId, final int abilityHandleId, final int orderId, - final boolean queue) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4 + 4 + 4 + 4 + 1); - this.sendBuffer.putInt(ClientToServerProtocol.ISSUE_IMMEDIATE_ORDER); - this.sendBuffer.putInt(unitHandleId); - this.sendBuffer.putInt(abilityHandleId); - this.sendBuffer.putInt(orderId); - this.sendBuffer.put(queue ? (byte) 1 : (byte) 0); - } - - public void unitCancelTrainingItem(final int unitHandleId, final int cancelIndex) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4 + 4 + 4); - this.sendBuffer.putInt(ClientToServerProtocol.UNIT_CANCEL_TRAINING); - this.sendBuffer.putInt(unitHandleId); - this.sendBuffer.putInt(cancelIndex); - } - - public void finishedTurn(final int gameTurnTick) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4 + 4); - this.sendBuffer.putInt(ClientToServerProtocol.FINISHED_TURN); - this.sendBuffer.putInt(gameTurnTick); - } - - public void framesSkipped(final int skippedCount) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4 + 4); - this.sendBuffer.putInt(ClientToServerProtocol.FRAMES_SKIPPED); - this.sendBuffer.putInt(skippedCount); - } - - public void joinGame() { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4); - this.sendBuffer.putInt(ClientToServerProtocol.JOIN_GAME); - } - - public void send() { - this.sendBuffer.flip(); - try { - this.client.send(this.sendBuffer); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/core/src/com/etheller/warsmash/networking/WarsmashServer.java b/core/src/com/etheller/warsmash/networking/WarsmashServer.java deleted file mode 100644 index 6dafe6c1..00000000 --- a/core/src/com/etheller/warsmash/networking/WarsmashServer.java +++ /dev/null @@ -1,199 +0,0 @@ -package com.etheller.warsmash.networking; - -import java.io.IOException; -import java.net.SocketAddress; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Scanner; - -import com.etheller.warsmash.networking.udp.OrderedUdpServer; -import com.etheller.warsmash.util.WarsmashConstants; - -public class WarsmashServer implements ClientToServerListener { - private static final int MAGIC_DELAY_OFFSET = 4; - private final OrderedUdpServer udpServer; - private final Map socketAddressToPlayerIndex = new HashMap<>(); - private final Map clientToTurnFinished = new HashMap<>(); - private final List turnActions = new ArrayList<>(); - private final WarsmashServerWriter writer; - private int currentTurnTick = MAGIC_DELAY_OFFSET; - private boolean gameStarted = false; - private long lastServerHeartbeatTime = 0; - - public WarsmashServer() throws IOException { - this.udpServer = new OrderedUdpServer(WarsmashConstants.PORT_NUMBER, new WarsmashServerParser(this)); - this.writer = new WarsmashServerWriter(this.udpServer, this.socketAddressToPlayerIndex.keySet()); - } - - public void startThread() { - new Thread(this.udpServer).start(); - } - - public void startGame() { - this.gameStarted = true; - WarsmashServer.this.writer.startGame(); - WarsmashServer.this.writer.send(); - startTurn(); - } - - private void startTurn() { - System.out.println("sending finishedTurn " + this.currentTurnTick); - WarsmashServer.this.writer.finishedTurn(this.currentTurnTick); - WarsmashServer.this.writer.send(); - this.currentTurnTick++; - } - - private int getPlayerIndex(final SocketAddress sourceAddress) { - Integer playerIndex = this.socketAddressToPlayerIndex.get(sourceAddress); - if (playerIndex == null) { - playerIndex = this.socketAddressToPlayerIndex.size(); - this.socketAddressToPlayerIndex.put(sourceAddress, playerIndex); - } - return playerIndex; - } - - @Override - public void joinGame(final SocketAddress sourceAddress) { - System.out.println("joinGame " + sourceAddress); - final int playerIndex = getPlayerIndex(sourceAddress); - WarsmashServer.this.writer.acceptJoin(playerIndex); - WarsmashServer.this.writer.send(sourceAddress); - } - - @Override - public void issueTargetOrder(final SocketAddress sourceAddress, final int unitHandleId, final int abilityHandleId, - final int orderId, final int targetHandleId, final boolean queue) { - System.out.println("issueTargetOrder from " + sourceAddress); - final int playerIndex = getPlayerIndex(sourceAddress); - this.turnActions.add(new Runnable() { - @Override - public void run() { - WarsmashServer.this.writer.issueTargetOrder(playerIndex, unitHandleId, abilityHandleId, orderId, - targetHandleId, queue); - WarsmashServer.this.writer.send(); - } - }); - } - - @Override - public void issuePointOrder(final SocketAddress sourceAddress, final int unitHandleId, final int abilityHandleId, - final int orderId, final float x, final float y, final boolean queue) { - System.out.println("issuePointOrder from " + sourceAddress); - final int playerIndex = getPlayerIndex(sourceAddress); - this.turnActions.add(new Runnable() { - @Override - public void run() { - WarsmashServer.this.writer.issuePointOrder(playerIndex, unitHandleId, abilityHandleId, orderId, x, y, - queue); - WarsmashServer.this.writer.send(); - } - }); - } - - @Override - public void issueDropItemAtPointOrder(final SocketAddress sourceAddress, final int unitHandleId, - final int abilityHandleId, final int orderId, final int targetHandleId, final float x, final float y, - final boolean queue) { - System.out.println("issueDropItemAtPointOrder from " + sourceAddress); - final int playerIndex = getPlayerIndex(sourceAddress); - this.turnActions.add(new Runnable() { - @Override - public void run() { - WarsmashServer.this.writer.issueDropItemAtPointOrder(playerIndex, unitHandleId, abilityHandleId, - orderId, targetHandleId, x, y, queue); - WarsmashServer.this.writer.send(); - } - }); - } - - @Override - public void issueImmediateOrder(final SocketAddress sourceAddress, final int unitHandleId, - final int abilityHandleId, final int orderId, final boolean queue) { - System.out.println("issueImmediateOrder from " + sourceAddress); - final int playerIndex = getPlayerIndex(sourceAddress); - this.turnActions.add(new Runnable() { - @Override - public void run() { - WarsmashServer.this.writer.issueImmediateOrder(playerIndex, unitHandleId, abilityHandleId, orderId, - queue); - WarsmashServer.this.writer.send(); - } - }); - } - - @Override - public void unitCancelTrainingItem(final SocketAddress sourceAddress, final int unitHandleId, - final int cancelIndex) { - System.out.println("unitCancelTrainingItem from " + sourceAddress); - final int playerIndex = getPlayerIndex(sourceAddress); - this.turnActions.add(new Runnable() { - @Override - public void run() { - WarsmashServer.this.writer.unitCancelTrainingItem(playerIndex, unitHandleId, cancelIndex); - WarsmashServer.this.writer.send(); - } - }); - } - - @Override - public void finishedTurn(final SocketAddress sourceAddress, final int clientGameTurnTick) { - final int gameTurnTick = clientGameTurnTick + MAGIC_DELAY_OFFSET; - if (WarsmashConstants.VERBOSE_LOGGING) { - System.out.println("finishedTurn(" + gameTurnTick + ") from " + sourceAddress); - } - if (!this.gameStarted) { - throw new IllegalStateException( - "Client should not send us finishedTurn() message when game has not started!"); - } - this.clientToTurnFinished.put(sourceAddress, clientGameTurnTick); - boolean allDone = true; - for (final SocketAddress clientAddress : this.socketAddressToPlayerIndex.keySet()) { - final Integer turnFinishedValue = this.clientToTurnFinished.get(clientAddress); - if ((turnFinishedValue == null) || (turnFinishedValue < clientGameTurnTick)) { - allDone = false; - } - } - if (allDone) { - for (final Runnable turnAction : this.turnActions) { - turnAction.run(); - } - this.turnActions.clear(); - startTurn(); - } - } - - @Override - public void framesSkipped(final int nFramesSkipped) { - // dont care for now - final long currentTimeMillis = System.currentTimeMillis(); - if ((currentTimeMillis - this.lastServerHeartbeatTime) > 3000) { - // 3 seconds of frame skipping, make sure we keep in contact with client - System.out.println("sending server heartbeat()"); - WarsmashServer.this.writer.heartbeat(); - WarsmashServer.this.writer.send(); - this.lastServerHeartbeatTime = currentTimeMillis; - } - } - - public static void main(final String[] args) { - try { - final WarsmashServer server = new WarsmashServer(); - server.startThread(); - - final Scanner scanner = new Scanner(System.in); - while (scanner.hasNextLine()) { - final String line = scanner.nextLine(); - if ("start".equals(line)) { - server.startGame(); - break; - } - } - scanner.close(); - } - catch (final IOException e) { - e.printStackTrace(); - } - } -} diff --git a/core/src/com/etheller/warsmash/networking/WarsmashServerParser.java b/core/src/com/etheller/warsmash/networking/WarsmashServerParser.java deleted file mode 100644 index 4e7a1f7e..00000000 --- a/core/src/com/etheller/warsmash/networking/WarsmashServerParser.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.etheller.warsmash.networking; - -import java.io.IOException; -import java.net.SocketAddress; -import java.nio.ByteBuffer; - -import com.etheller.warsmash.networking.udp.OrderedUdpServerListener; - -public class WarsmashServerParser implements OrderedUdpServerListener { - - private final ClientToServerListener listener; - - public WarsmashServerParser(final ClientToServerListener clientToServerListener) throws IOException { - this.listener = clientToServerListener; - } - - @Override - public void parse(final SocketAddress sourceAddress, final ByteBuffer buffer) { - final int initialLimit = buffer.limit(); - try { - while (buffer.hasRemaining()) { - final int length = buffer.getInt(); - if (length > buffer.remaining()) { - // this packet is junk to us, so we will skip and continue (drop system will - // handle it) - System.err.println("Got mismatched protocol length " + length + " > " + buffer.remaining() + "!!"); - break; - } - final int protocol = buffer.getInt(); - switch (protocol) { - case ClientToServerProtocol.ISSUE_TARGET_ORDER: { - final int unitHandleId = buffer.getInt(); - final int abilityHandleId = buffer.getInt(); - final int orderId = buffer.getInt(); - final int targetHandleId = buffer.getInt(); - final boolean queue = buffer.get() == 1; - this.listener.issueTargetOrder(sourceAddress, unitHandleId, abilityHandleId, orderId, - targetHandleId, queue); - break; - } - case ClientToServerProtocol.ISSUE_POINT_ORDER: { - final int unitHandleId = buffer.getInt(); - final int abilityHandleId = buffer.getInt(); - final int orderId = buffer.getInt(); - final float x = buffer.getFloat(); - final float y = buffer.getFloat(); - final boolean queue = buffer.get() == 1; - this.listener.issuePointOrder(sourceAddress, unitHandleId, abilityHandleId, orderId, x, y, queue); - break; - } - case ClientToServerProtocol.ISSUE_DROP_ITEM_ORDER: { - final int unitHandleId = buffer.getInt(); - final int abilityHandleId = buffer.getInt(); - final int orderId = buffer.getInt(); - final int targetHandleId = buffer.getInt(); - final float x = buffer.getFloat(); - final float y = buffer.getFloat(); - final boolean queue = buffer.get() == 1; - this.listener.issueDropItemAtPointOrder(sourceAddress, unitHandleId, abilityHandleId, orderId, - targetHandleId, x, y, queue); - break; - } - case ClientToServerProtocol.ISSUE_IMMEDIATE_ORDER: { - final int unitHandleId = buffer.getInt(); - final int abilityHandleId = buffer.getInt(); - final int orderId = buffer.getInt(); - final boolean queue = buffer.get() == 1; - this.listener.issueImmediateOrder(sourceAddress, unitHandleId, abilityHandleId, orderId, queue); - break; - } - case ClientToServerProtocol.UNIT_CANCEL_TRAINING: { - final int unitHandleId = buffer.getInt(); - final int cancelIndex = buffer.getInt(); - this.listener.unitCancelTrainingItem(sourceAddress, unitHandleId, cancelIndex); - break; - } - case ClientToServerProtocol.FINISHED_TURN: { - final int gameTurnTick = buffer.getInt(); - this.listener.finishedTurn(sourceAddress, gameTurnTick); - break; - } - case ClientToServerProtocol.JOIN_GAME: { - this.listener.joinGame(sourceAddress); - break; - } - case ClientToServerProtocol.FRAMES_SKIPPED: { - final int nFramesSkipped = buffer.getInt(); - this.listener.framesSkipped(nFramesSkipped); - break; - } - - default: - System.err.println("Got unknown protocol: " + protocol); - break; - } - } - } - finally { - buffer.position(initialLimit); - } - } - - @Override - public void cantReplay(final SocketAddress sourceAddress, final int seqNo) { - throw new IllegalStateException("Cant replay " + seqNo + " to " + sourceAddress + " !"); - } -} diff --git a/core/src/com/etheller/warsmash/networking/WarsmashServerWriter.java b/core/src/com/etheller/warsmash/networking/WarsmashServerWriter.java deleted file mode 100644 index ae6dbae3..00000000 --- a/core/src/com/etheller/warsmash/networking/WarsmashServerWriter.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.etheller.warsmash.networking; - -import java.io.IOException; -import java.net.SocketAddress; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Set; - -import com.etheller.warsmash.networking.udp.OrderedUdpServer; - -public class WarsmashServerWriter implements ServerToClientListener { - private final OrderedUdpServer server; - private final ByteBuffer sendBuffer = ByteBuffer.allocate(1024).order(ByteOrder.BIG_ENDIAN); - private final Set allKnownAddressesToSend; - - public WarsmashServerWriter(final OrderedUdpServer server, final Set allKnownAddressesToSend) { - this.server = server; - this.allKnownAddressesToSend = allKnownAddressesToSend; - } - - @Override - public void issueTargetOrder(final int playerIndex, final int unitHandleId, final int abilityHandleId, - final int orderId, final int targetHandleId, final boolean queue) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4 + 4 + 4 + 4 + 4 + 4 + 1); - this.sendBuffer.putInt(ServerToClientProtocol.ISSUE_TARGET_ORDER); - this.sendBuffer.putInt(playerIndex); - this.sendBuffer.putInt(unitHandleId); - this.sendBuffer.putInt(abilityHandleId); - this.sendBuffer.putInt(orderId); - this.sendBuffer.putInt(targetHandleId); - this.sendBuffer.put(queue ? (byte) 1 : (byte) 0); - } - - @Override - public void issuePointOrder(final int playerIndex, final int unitHandleId, final int abilityHandleId, - final int orderId, final float x, final float y, final boolean queue) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4 + 4 + 4 + 4 + 4 + 4 + 4 + 1); - this.sendBuffer.putInt(ServerToClientProtocol.ISSUE_POINT_ORDER); - this.sendBuffer.putInt(playerIndex); - this.sendBuffer.putInt(unitHandleId); - this.sendBuffer.putInt(abilityHandleId); - this.sendBuffer.putInt(orderId); - this.sendBuffer.putFloat(x); - this.sendBuffer.putFloat(y); - this.sendBuffer.put(queue ? (byte) 1 : (byte) 0); - } - - @Override - public void issueDropItemAtPointOrder(final int playerIndex, final int unitHandleId, final int abilityHandleId, - final int orderId, final int targetHandleId, final float x, final float y, final boolean queue) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 1); - this.sendBuffer.putInt(ServerToClientProtocol.ISSUE_DROP_ITEM_ORDER); - this.sendBuffer.putInt(playerIndex); - this.sendBuffer.putInt(unitHandleId); - this.sendBuffer.putInt(abilityHandleId); - this.sendBuffer.putInt(orderId); - this.sendBuffer.putInt(targetHandleId); - this.sendBuffer.putFloat(x); - this.sendBuffer.putFloat(y); - this.sendBuffer.put(queue ? (byte) 1 : (byte) 0); - } - - @Override - public void issueImmediateOrder(final int playerIndex, final int unitHandleId, final int abilityHandleId, - final int orderId, final boolean queue) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4 + 4 + 4 + 4 + 4 + 1); - this.sendBuffer.putInt(ServerToClientProtocol.ISSUE_IMMEDIATE_ORDER); - this.sendBuffer.putInt(playerIndex); - this.sendBuffer.putInt(unitHandleId); - this.sendBuffer.putInt(abilityHandleId); - this.sendBuffer.putInt(orderId); - this.sendBuffer.put(queue ? (byte) 1 : (byte) 0); - } - - @Override - public void unitCancelTrainingItem(final int playerIndex, final int unitHandleId, final int cancelIndex) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4 + 4 + 4 + 4 + 4 + 1); - this.sendBuffer.putInt(ServerToClientProtocol.UNIT_CANCEL_TRAINING); - this.sendBuffer.putInt(playerIndex); - this.sendBuffer.putInt(unitHandleId); - this.sendBuffer.putInt(cancelIndex); - } - - @Override - public void finishedTurn(final int gameTurnTick) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4 + 4); - this.sendBuffer.putInt(ServerToClientProtocol.FINISHED_TURN); - this.sendBuffer.putInt(gameTurnTick); - } - - @Override - public void heartbeat() { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4); - this.sendBuffer.putInt(ServerToClientProtocol.HEARTBEAT); - } - - @Override - public void acceptJoin(final int playerIndex) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4 + 4); - this.sendBuffer.putInt(ServerToClientProtocol.ACCEPT_JOIN); - this.sendBuffer.putInt(playerIndex); - } - - @Override - public void startGame() { - this.sendBuffer.clear(); - this.sendBuffer.putInt(4); - this.sendBuffer.putInt(ServerToClientProtocol.START_GAME); - } - - public void send(final SocketAddress sourceAddress) { - this.sendBuffer.flip(); - try { - this.server.send(sourceAddress, this.sendBuffer); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - public void send() { - this.sendBuffer.flip(); - try { - for (final SocketAddress address : this.allKnownAddressesToSend) { - final int pos = this.sendBuffer.position(); - final int limit = this.sendBuffer.limit(); - this.server.send(address, this.sendBuffer); - this.sendBuffer.position(pos); - this.sendBuffer.limit(limit); - } - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/core/src/com/etheller/warsmash/networking/udp/OrderedUdpClient.java b/core/src/com/etheller/warsmash/networking/udp/OrderedUdpClient.java deleted file mode 100644 index 8e7329ed..00000000 --- a/core/src/com/etheller/warsmash/networking/udp/OrderedUdpClient.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.etheller.warsmash.networking.udp; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; - -public class OrderedUdpClient extends OrderedUdpCommuncation implements Runnable { - private final UdpClient udpClient; - - public OrderedUdpClient(final InetAddress serverAddress, final int portNumber, - final OrderedUdpClientListener listener) throws UnknownHostException, IOException { - super(listener); - this.udpClient = new UdpClient(serverAddress, portNumber, this); - } - - @Override - protected void trySend(final ByteBuffer data) { - try { - this.udpClient.send(data); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void run() { - this.udpClient.run(); - } -} diff --git a/core/src/com/etheller/warsmash/networking/udp/OrderedUdpClientListener.java b/core/src/com/etheller/warsmash/networking/udp/OrderedUdpClientListener.java deleted file mode 100644 index cc4d0ee3..00000000 --- a/core/src/com/etheller/warsmash/networking/udp/OrderedUdpClientListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.networking.udp; - -public interface OrderedUdpClientListener extends UdpClientListener { - void cantReplay(int seqNo); -} diff --git a/core/src/com/etheller/warsmash/networking/udp/OrderedUdpCommuncation.java b/core/src/com/etheller/warsmash/networking/udp/OrderedUdpCommuncation.java deleted file mode 100644 index c2c7185f..00000000 --- a/core/src/com/etheller/warsmash/networking/udp/OrderedUdpCommuncation.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.etheller.warsmash.networking.udp; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.ArrayDeque; -import java.util.HashMap; -import java.util.Map; -import java.util.Queue; - -public abstract class OrderedUdpCommuncation implements UdpClientListener { - private static final int MAX_STORED_SENT_DATA_SIZE = 10000; - - private static final int ORDERED_UDP_MESSAGE = 'M'; - private static final int ORDERED_UDP_REPLAY_REQUEST = 'R'; - - private final Map seqNoToDataSent; - private final Map seqNoToDataReceived; - private final Queue seqNosStored; - private int nextSendSeqNo; - private int nextReceiveSeqNo; - private final OrderedUdpClientListener delegate; - private final ByteBuffer sendBuffer; - - public OrderedUdpCommuncation(final OrderedUdpClientListener delegate) { - this.seqNoToDataSent = new HashMap<>(); - this.seqNoToDataReceived = new HashMap<>(); - this.seqNosStored = new ArrayDeque<>(); - this.sendBuffer = ByteBuffer.allocate(1024).order(ByteOrder.BIG_ENDIAN); - this.delegate = delegate; - } - - public void send(final ByteBuffer data) throws IOException { - final ByteBuffer writeBuffer = ByteBuffer.allocate(1024).order(ByteOrder.BIG_ENDIAN); - writeBuffer.clear(); - final Integer seqNo = this.nextSendSeqNo; // only autobox once, would be ideal to not box at all - writeBuffer.putInt(ORDERED_UDP_MESSAGE); - writeBuffer.putInt(seqNo); - writeBuffer.put(data); - writeBuffer.flip(); - final int position = writeBuffer.position(); - trySend(writeBuffer); - writeBuffer.position(position); - if (this.seqNosStored.size() == MAX_STORED_SENT_DATA_SIZE) { - this.seqNoToDataSent.remove(this.seqNosStored.poll()); - } - this.seqNosStored.offer(seqNo); - this.seqNoToDataSent.put(seqNo, writeBuffer); - this.nextSendSeqNo++; - } - - // it's udp so we're just trying, we don't really know if it'll drop or not - protected abstract void trySend(final ByteBuffer data); - - @Override - public void parse(ByteBuffer readBuffer) { - final int messageType = readBuffer.getInt(); - switch (messageType) { - case ORDERED_UDP_MESSAGE: { - final int serverSeqNo = readBuffer.getInt(); - if (serverSeqNo > this.nextReceiveSeqNo) { - // ahead, need to queue it and request replay - for (int i = this.nextReceiveSeqNo; i < serverSeqNo; i++) { - requestReplay(i); - } - final ByteBuffer queuedReceivedData = ByteBuffer.allocate(readBuffer.remaining()) - .order(ByteOrder.BIG_ENDIAN); - queuedReceivedData.put(readBuffer); - this.seqNoToDataReceived.put(serverSeqNo, queuedReceivedData); - } - else if (serverSeqNo < this.nextReceiveSeqNo) { - // dup, ignore - } - else { - // exactly equal - do { - this.delegate.parse(readBuffer); - this.nextReceiveSeqNo++; - } - while ((readBuffer = this.seqNoToDataReceived.remove(this.nextReceiveSeqNo)) != null); - } - break; - } - case ORDERED_UDP_REPLAY_REQUEST: - final int requestedSeqNo = readBuffer.getInt(); - final ByteBuffer replayData = this.seqNoToDataSent.get(requestedSeqNo); - if (replayData == null) { - this.delegate.cantReplay(requestedSeqNo); - } - else { - System.err.println("Replay requested for packet with seqNo=" + requestedSeqNo + ", we will send it!"); - final int position = replayData.position(); - trySend(replayData); - replayData.position(position); - } - break; - } - } - - private void requestReplay(final int i) { - this.sendBuffer.clear(); - this.sendBuffer.putInt(ORDERED_UDP_REPLAY_REQUEST); - this.sendBuffer.putInt(i); - this.sendBuffer.flip(); - trySend(this.sendBuffer); - } -} diff --git a/core/src/com/etheller/warsmash/networking/udp/OrderedUdpServer.java b/core/src/com/etheller/warsmash/networking/udp/OrderedUdpServer.java deleted file mode 100644 index e973cc2a..00000000 --- a/core/src/com/etheller/warsmash/networking/udp/OrderedUdpServer.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.etheller.warsmash.networking.udp; - -import java.io.IOException; -import java.net.SocketAddress; -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; - -public class OrderedUdpServer implements UdpServerListener, Runnable { - private final OrderedUdpServerListener listener; - private final UdpServer udpServer; - private final Map addrToClient = new HashMap<>(); - - public OrderedUdpServer(final int port, final OrderedUdpServerListener listener) throws IOException { - this.listener = listener; - this.udpServer = new UdpServer(port, this); - } - - @Override - public void parse(final SocketAddress sourceAddress, final ByteBuffer buffer) { - getClient(sourceAddress).parse(buffer); - } - - public void send(final SocketAddress destination, final ByteBuffer buffer) throws IOException { - getClient(destination).send(buffer); - } - - private OrderedKnownClient getClient(final SocketAddress sourceAddress) { - OrderedKnownClient orderedKnownClient = this.addrToClient.get(sourceAddress); - if (orderedKnownClient == null) { - orderedKnownClient = new OrderedKnownClient(sourceAddress, new OrderedAddressedSender(sourceAddress)); - this.addrToClient.put(sourceAddress, orderedKnownClient); - } - return orderedKnownClient; - } - - private class OrderedKnownClient extends OrderedUdpCommuncation { - - private final SocketAddress sourceAddress; - - public OrderedKnownClient(final SocketAddress sourceAddress, final OrderedUdpClientListener listener) { - super(listener); - this.sourceAddress = sourceAddress; - } - - @Override - protected void trySend(final ByteBuffer data) { - try { - OrderedUdpServer.this.udpServer.send(this.sourceAddress, data); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - } - - private class OrderedAddressedSender implements OrderedUdpClientListener { - private final SocketAddress sourceAddress; - - public OrderedAddressedSender(final SocketAddress sourceAddress) { - this.sourceAddress = sourceAddress; - } - - @Override - public void parse(final ByteBuffer buffer) { - OrderedUdpServer.this.listener.parse(this.sourceAddress, buffer); - } - - @Override - public void cantReplay(final int seqNo) { - OrderedUdpServer.this.listener.cantReplay(this.sourceAddress, seqNo); - } - - } - - @Override - public void run() { - this.udpServer.run(); - } -} diff --git a/core/src/com/etheller/warsmash/networking/udp/OrderedUdpServerListener.java b/core/src/com/etheller/warsmash/networking/udp/OrderedUdpServerListener.java deleted file mode 100644 index 64b5df9d..00000000 --- a/core/src/com/etheller/warsmash/networking/udp/OrderedUdpServerListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.etheller.warsmash.networking.udp; - -import java.net.SocketAddress; - -public interface OrderedUdpServerListener extends UdpServerListener { - void cantReplay(SocketAddress sourceAddress, int seqNo); -} diff --git a/core/src/com/etheller/warsmash/networking/udp/UdpClient.java b/core/src/com/etheller/warsmash/networking/udp/UdpClient.java deleted file mode 100644 index 99ae5d0e..00000000 --- a/core/src/com/etheller/warsmash/networking/udp/UdpClient.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.etheller.warsmash.networking.udp; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.DatagramChannel; - -import com.etheller.warsmash.util.WarsmashConstants; - -public class UdpClient implements Runnable { - private final DatagramChannel channel; - private final ByteBuffer readBuffer; - private boolean running; - private final UdpClientListener clientListener; - - public UdpClient(final InetAddress serverAddress, final int portNumber, final UdpClientListener clientListener) - throws UnknownHostException, IOException { - this.channel = DatagramChannel.open().connect(new InetSocketAddress(serverAddress, portNumber)); - this.channel.configureBlocking(true); - this.readBuffer = ByteBuffer.allocate(1024); - this.clientListener = clientListener; - this.readBuffer.order(ByteOrder.BIG_ENDIAN); - } - - public void send(final ByteBuffer data) throws IOException { - this.channel.write(data); - } - - public void setRunning(final boolean running) { - this.running = running; - } - - @Override - public void run() { - this.running = true; - while (this.running) { - try { - this.readBuffer.clear(); - this.channel.receive(this.readBuffer); - this.readBuffer.flip(); - this.clientListener.parse(this.readBuffer); - } - catch (final IOException e) { - System.err.println("Error reading from channel:"); - e.printStackTrace(); - } - } - } - - static UdpClient warsmashUdpClient; - - public static void main(final String[] args) { - try { - warsmashUdpClient = new UdpClient(InetAddress.getLocalHost(), WarsmashConstants.PORT_NUMBER, - new UdpClientListener() { - @Override - public void parse(final ByteBuffer buffer) { - System.out.println("got " + buffer.remaining() + " bytes, pos=" + buffer.position() - + ", lim=" + buffer.limit()); - System.out.println("got from server: " + buffer.getInt()); - } - }); - new Thread(warsmashUdpClient).start(); - - final ByteBuffer sendBuffer = ByteBuffer.allocate(1024); - for (int i = 0; i < 10; i++) { - sendBuffer.clear(); - sendBuffer.put((byte) (1 + i)); - sendBuffer.put((byte) 3); - sendBuffer.put((byte) 5); - sendBuffer.put((byte) 7); - sendBuffer.flip(); - warsmashUdpClient.send(sendBuffer); - try { - Thread.sleep(1000); - } - catch (final InterruptedException e) { - e.printStackTrace(); - } - } - } - catch (final UnknownHostException e) { - e.printStackTrace(); - } - catch (final IOException e) { - e.printStackTrace(); - } - } - -} diff --git a/core/src/com/etheller/warsmash/networking/udp/UdpClientListener.java b/core/src/com/etheller/warsmash/networking/udp/UdpClientListener.java deleted file mode 100644 index 8ce037ce..00000000 --- a/core/src/com/etheller/warsmash/networking/udp/UdpClientListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.etheller.warsmash.networking.udp; - -import java.nio.ByteBuffer; - -public interface UdpClientListener { - void parse(ByteBuffer buffer); -} diff --git a/core/src/com/etheller/warsmash/networking/udp/UdpServer.java b/core/src/com/etheller/warsmash/networking/udp/UdpServer.java deleted file mode 100644 index 2d62c14a..00000000 --- a/core/src/com/etheller/warsmash/networking/udp/UdpServer.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.etheller.warsmash.networking.udp; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.DatagramChannel; -import java.nio.channels.SelectionKey; -import java.nio.channels.Selector; -import java.util.Iterator; -import java.util.Set; - -import com.etheller.warsmash.util.WarsmashConstants; - -public class UdpServer implements Runnable { - - private final Selector selector; - private boolean running; - private final SelectionKey key; - private final ByteBuffer readBuffer; - private final UdpServerListener serverListener; - - public UdpServer(final int portNumber, final UdpServerListener serverListener) throws IOException { - this.serverListener = serverListener; - this.selector = Selector.open(); - this.channel = DatagramChannel.open().bind(new InetSocketAddress(portNumber)); - this.channel.configureBlocking(false); - this.key = this.channel.register(this.selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); - this.readBuffer = ByteBuffer.allocate(1024); - this.readBuffer.order(ByteOrder.BIG_ENDIAN); - } - - public void send(final SocketAddress destination, final ByteBuffer buffer) throws IOException { - this.channel.send(buffer, destination); - } - - @Override - public void run() { - this.running = true; - while (this.running) { - try { - final int selectedKeyCount = this.selector.select(); - if (selectedKeyCount > 0) { - final Set selectedKeys = this.selector.selectedKeys(); - - final Iterator keyIterator = selectedKeys.iterator(); - - while (keyIterator.hasNext()) { - final SelectionKey key = keyIterator.next(); - - if (key.isReadable()) { - final DatagramChannel channel = (DatagramChannel) key.channel(); - this.readBuffer.clear(); - final SocketAddress receiveAddr = channel.receive(this.readBuffer); - this.readBuffer.flip(); - this.serverListener.parse(receiveAddr, this.readBuffer); - } - - keyIterator.remove(); - } - } - } - catch (final IOException e) { - System.err.println("Error reading from channel:"); - e.printStackTrace(); - } - } - } - - public void setRunning(final boolean running) { - this.running = running; - } - - static UdpServer warsmashGameServer; - private final DatagramChannel channel; - - public static void main(final String[] args) { - try { - warsmashGameServer = new UdpServer(WarsmashConstants.PORT_NUMBER, new UdpServerListener() { - int n = 0; - ByteBuffer sendBuffer = ByteBuffer.allocate(1024); - - @Override - public void parse(final SocketAddress sourceAddress, final ByteBuffer buffer) { - System.out.println("Got packet from: " + sourceAddress); - while (buffer.hasRemaining()) { - System.out.println("Received: " + buffer.get()); - } - try { - this.sendBuffer.clear(); - this.sendBuffer.putInt(this.n++); - this.sendBuffer.flip(); - warsmashGameServer.send(sourceAddress, this.sendBuffer); - } - catch (final IOException e) { - e.printStackTrace(); - } - } - }); - new Thread(warsmashGameServer).start(); - } - catch (final IOException e) { - e.printStackTrace(); - } - } - -} diff --git a/core/src/com/etheller/warsmash/networking/udp/UdpServerListener.java b/core/src/com/etheller/warsmash/networking/udp/UdpServerListener.java deleted file mode 100644 index 471ae7e3..00000000 --- a/core/src/com/etheller/warsmash/networking/udp/UdpServerListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.etheller.warsmash.networking.udp; - -import java.net.SocketAddress; -import java.nio.ByteBuffer; - -public interface UdpServerListener { - void parse(SocketAddress sourceAddress, ByteBuffer buffer); -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/DataSourceFDFParserBuilder.java b/core/src/com/etheller/warsmash/parsers/fdf/DataSourceFDFParserBuilder.java deleted file mode 100644 index a2bec5bb..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/DataSourceFDFParserBuilder.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.etheller.warsmash.parsers.fdf; - -import java.io.IOException; - -import org.antlr.v4.runtime.BaseErrorListener; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; - -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.fdfparser.FDFLexer; -import com.etheller.warsmash.fdfparser.FDFParser; -import com.etheller.warsmash.fdfparser.FDFParserBuilder; - -public class DataSourceFDFParserBuilder implements FDFParserBuilder { - private final DataSource dataSource; - - public DataSourceFDFParserBuilder(final DataSource dataSource) { - this.dataSource = dataSource; - } - - @Override - public FDFParser build(final String path) { - FDFLexer lexer; - try { - lexer = new FDFLexer(CharStreams.fromStream(this.dataSource.getResourceAsStream(path))); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - final FDFParser fdfParser = new FDFParser(new CommonTokenStream(lexer)); - final BaseErrorListener errorListener = new BaseErrorListener() { - @Override - public void syntaxError(final Recognizer recognizer, final Object offendingSymbol, final int line, - final int charPositionInLine, final String msg, final RecognitionException e) { - String sourceName = path; - if (!sourceName.isEmpty()) { - sourceName = String.format("%s:%d:%d: ", sourceName, line, charPositionInLine); - } - - System.err.println(sourceName + "line " + line + ":" + charPositionInLine + " " + msg); - } - }; - fdfParser.addErrorListener(errorListener); - return fdfParser; - } -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/parsers/fdf/DynamicFontGeneratorHolder.java b/core/src/com/etheller/warsmash/parsers/fdf/DynamicFontGeneratorHolder.java deleted file mode 100644 index feb4a4ad..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/DynamicFontGeneratorHolder.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.etheller.warsmash.parsers.fdf; - -import java.util.HashMap; -import java.util.Map; - -import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.units.Element; -import com.etheller.warsmash.util.DataSourceFileHandle; - -public class DynamicFontGeneratorHolder { - private final DataSource dataSource; - private final Element skin; - private final Map fontNameToGenerator; - - public DynamicFontGeneratorHolder(final DataSource dataSource, final Element skin) { - this.dataSource = dataSource; - this.skin = skin; - this.fontNameToGenerator = new HashMap<>(); - } - - public FreeTypeFontGenerator getFontGenerator(final String font) { - FreeTypeFontGenerator fontGenerator = this.fontNameToGenerator.get(font); - if (fontGenerator == null) { - final String fontName = this.skin.getField(font); - if (fontName == null) { - throw new IllegalStateException("No such font: " + font); - } - if (!this.dataSource.has(fontName)) { - throw new IllegalStateException("No such font file: " + fontName + " (for \"" + font + "\")"); - } - fontGenerator = new FreeTypeFontGenerator(new DataSourceFileHandle(this.dataSource, fontName)); - this.fontNameToGenerator.put(font, fontGenerator); - } - return fontGenerator; - } - - public void dispose() { - for (final FreeTypeFontGenerator generator : this.fontNameToGenerator.values()) { - generator.dispose(); - } - this.fontNameToGenerator.clear(); - } -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/GameSkin.java b/core/src/com/etheller/warsmash/parsers/fdf/GameSkin.java deleted file mode 100644 index ccbcf448..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/GameSkin.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.etheller.warsmash.parsers.fdf; - -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.units.Element; - -public class GameSkin { - private final Element skin; - private final DataTable skinsTable; - - public GameSkin(final Element skin, final DataTable skinsTable) { - this.skin = skin; - this.skinsTable = skinsTable; - } - - public Element getSkin() { - return this.skin; - } - - public DataTable getSkinsTable() { - return this.skinsTable; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/GameUI.java b/core/src/com/etheller/warsmash/parsers/fdf/GameUI.java deleted file mode 100644 index d55e532d..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/GameUI.java +++ /dev/null @@ -1,1096 +0,0 @@ -package com.etheller.warsmash.parsers.fdf; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.Map; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; -import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter; -import com.badlogic.gdx.utils.viewport.ExtendViewport; -import com.badlogic.gdx.utils.viewport.FitViewport; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.fdfparser.FDFParser; -import com.etheller.warsmash.fdfparser.FrameDefinitionVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.AnchorDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.BackdropCornerFlags; -import com.etheller.warsmash.parsers.fdf.datamodel.ControlStyle; -import com.etheller.warsmash.parsers.fdf.datamodel.FontDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.FrameClass; -import com.etheller.warsmash.parsers.fdf.datamodel.FrameDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; -import com.etheller.warsmash.parsers.fdf.datamodel.FrameTemplateEnvironment; -import com.etheller.warsmash.parsers.fdf.datamodel.SetPointDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.TextJustify; -import com.etheller.warsmash.parsers.fdf.datamodel.Vector2Definition; -import com.etheller.warsmash.parsers.fdf.datamodel.Vector4Definition; -import com.etheller.warsmash.parsers.fdf.datamodel.fields.StringPairFrameDefinitionField; -import com.etheller.warsmash.parsers.fdf.frames.AbstractUIFrame; -import com.etheller.warsmash.parsers.fdf.frames.BackdropFrame; -import com.etheller.warsmash.parsers.fdf.frames.ControlFrame; -import com.etheller.warsmash.parsers.fdf.frames.EditBoxFrame; -import com.etheller.warsmash.parsers.fdf.frames.FilterModeTextureFrame; -import com.etheller.warsmash.parsers.fdf.frames.GlueButtonFrame; -import com.etheller.warsmash.parsers.fdf.frames.GlueTextButtonFrame; -import com.etheller.warsmash.parsers.fdf.frames.ListBoxFrame; -import com.etheller.warsmash.parsers.fdf.frames.SetPoint; -import com.etheller.warsmash.parsers.fdf.frames.SimpleButtonFrame; -import com.etheller.warsmash.parsers.fdf.frames.SimpleFrame; -import com.etheller.warsmash.parsers.fdf.frames.SimpleStatusBarFrame; -import com.etheller.warsmash.parsers.fdf.frames.SpriteFrame; -import com.etheller.warsmash.parsers.fdf.frames.StringFrame; -import com.etheller.warsmash.parsers.fdf.frames.TextButtonFrame; -import com.etheller.warsmash.parsers.fdf.frames.TextureFrame; -import com.etheller.warsmash.parsers.fdf.frames.UIFrame; -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.units.Element; -import com.etheller.warsmash.units.custom.WTS; -import com.etheller.warsmash.util.ImageUtils; -import com.etheller.warsmash.util.StringBundle; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.handlers.AbstractMdxModelViewer; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.FocusableFrame; -import com.hiveworkshop.rms.parsers.mdlx.MdlxLayer.FilterMode; - -public final class GameUI extends AbstractUIFrame implements UIFrame { - public static final boolean DEBUG = false; - private static final boolean PIN_FAIL_IS_FATAL = true; - private final DataSource dataSource; - private final Element skin; - private final Viewport viewport; - private final Scene uiScene; - private final AbstractMdxModelViewer modelViewer; - private final int racialCommandIndex; - private final FrameTemplateEnvironment templates; - private final Map pathToTexture = new HashMap<>(); - private final boolean autoPosition = false; - private final FreeTypeFontGenerator fontGenerator; - private final FreeTypeFontParameter fontParam; - private final Map nameToFrame = new HashMap<>(); - private final Viewport fdfCoordinateResolutionDummyViewport; - private final DataTable skinData; - private final Element errorStrings; - private final GlyphLayout glyphLayout; - private final WTS mapStrings; - private final BitmapFont font; - private final BitmapFont font20; - private final DynamicFontGeneratorHolder dynamicFontGeneratorHolder; - - public GameUI(final DataSource dataSource, final GameSkin skin, final Viewport viewport, final Scene uiScene, - final AbstractMdxModelViewer modelViewer, final int racialCommandIndex, final WTS mapStrings) { - super("GameUI", null); - this.dataSource = dataSource; - this.skin = skin.getSkin(); - this.viewport = viewport; - this.uiScene = uiScene; - this.modelViewer = modelViewer; - this.racialCommandIndex = racialCommandIndex; - if (viewport instanceof ExtendViewport) { - this.renderBounds.set(0, 0, ((ExtendViewport) viewport).getMinWorldWidth(), - ((ExtendViewport) viewport).getMinWorldHeight()); - } - else { - this.renderBounds.set(0, 0, viewport.getWorldWidth(), viewport.getWorldHeight()); - } - this.templates = new FrameTemplateEnvironment(); - - this.dynamicFontGeneratorHolder = new DynamicFontGeneratorHolder(this.modelViewer.dataSource, this.skin); - this.fontGenerator = this.dynamicFontGeneratorHolder.getFontGenerator("MasterFont"); - final FreeTypeFontParameter fontParam = new FreeTypeFontParameter(); - fontParam.size = 32; - this.font = this.fontGenerator.generateFont(fontParam); - fontParam.size = 20; - this.font20 = this.fontGenerator.generateFont(fontParam); - this.fontParam = new FreeTypeFontParameter(); - this.fdfCoordinateResolutionDummyViewport = new FitViewport(0.8f, 0.6f); - this.skinData = skin.getSkinsTable(); - this.errorStrings = this.skinData.get("Errors"); - this.glyphLayout = new GlyphLayout(); - this.mapStrings = mapStrings; - } - - public static GameSkin loadSkin(final DataSource dataSource, final String skin) { - final DataTable skinsTable = new DataTable(StringBundle.EMPTY); - try (InputStream stream = dataSource.getResourceAsStream("UI\\war3skins.txt")) { - skinsTable.readTXT(stream, true); - try (InputStream miscDataTxtStream = dataSource.getResourceAsStream("Units\\CommandFunc.txt")) { - skinsTable.readTXT(miscDataTxtStream, true); - } - try (InputStream miscDataTxtStream = dataSource.getResourceAsStream("Units\\CommandStrings.txt")) { - skinsTable.readTXT(miscDataTxtStream, true); - } - } - catch (final IOException e) { - throw new RuntimeException(e); - } - // TODO eliminate duplicate read of skin TXT!! - if (dataSource.has("war3mapSkin.txt")) { - try (InputStream miscDataTxtStream = dataSource.getResourceAsStream("war3mapSkin.txt")) { - skinsTable.readTXT(miscDataTxtStream, true); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } -// final Element main = skinsTable.get("Main"); -// final String skinsField = main.getField("Skins"); -// final String[] skins = skinsField.split(","); - final Element defaultSkin = skinsTable.get("Default"); - final Element userSkin = skinsTable.get(skin); - final Element customSkin = skinsTable.get("CustomSkin"); - for (final String key : defaultSkin.keySet()) { - if (!userSkin.hasField(key)) { - userSkin.setField(key, defaultSkin.getField(key)); - } - } - if (customSkin != null) { - for (final String key : customSkin.keySet()) { - userSkin.setField(key, customSkin.getField(key)); - } - } - return new GameSkin(userSkin, skinsTable); - } - - public static GameSkin loadSkin(final DataSource dataSource, final int skinIndex) { - final DataTable skinsTable = new DataTable(StringBundle.EMPTY); - try (InputStream stream = dataSource.getResourceAsStream("UI\\war3skins.txt")) { - skinsTable.readTXT(stream, true); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - // TODO eliminate duplicate read of skin TXT!! - if (dataSource.has("war3mapSkin.txt")) { - try (InputStream miscDataTxtStream = dataSource.getResourceAsStream("war3mapSkin.txt")) { - skinsTable.readTXT(miscDataTxtStream, true); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - final Element main = skinsTable.get("Main"); - final String skinsField = main.getField("Skins"); - final String[] skins = skinsField.split(","); - final Element defaultSkin = skinsTable.get("Default"); - final Element userSkin; - if ((skinIndex >= 0) && (skinIndex < skins.length)) { - userSkin = skinsTable.get(skins[skinIndex]); - } - else { - userSkin = new Element("UserSkin", skinsTable); - } - final Element customSkin = skinsTable.get("CustomSkin"); - for (final String key : defaultSkin.keySet()) { - if (!userSkin.hasField(key)) { - userSkin.setField(key, defaultSkin.getField(key)); - } - } - if (customSkin != null) { - for (final String key : customSkin.keySet()) { - userSkin.setField(key, customSkin.getField(key)); - } - } - return new GameSkin(userSkin, skinsTable); - } - - public void loadTOCFile(final String tocFilePath) throws IOException { - final DataSourceFDFParserBuilder dataSourceFDFParserBuilder = new DataSourceFDFParserBuilder(this.dataSource); - final FrameDefinitionVisitor fdfVisitor = new FrameDefinitionVisitor(this.templates, - dataSourceFDFParserBuilder); - System.err.println("Loading TOC file: " + tocFilePath); - try (BufferedReader reader = new BufferedReader( - new InputStreamReader(this.dataSource.getResourceAsStream(tocFilePath)))) { - String line; - int tocLines = 0; - while ((line = reader.readLine()) != null) { - final FDFParser firstFileParser = dataSourceFDFParserBuilder.build(line); - fdfVisitor.visit(firstFileParser.program()); - tocLines++; - } - System.out.println("TOC file loaded " + tocLines + " lines"); - } - } - - public boolean hasSkinField(final String file) { - return (file != null) && this.skin.hasField(file); - } - - public String getSkinField(String file) { - if ((file != null) && this.skin.hasField(file)) { - file = this.skin.getField(file); - } - else { - throw new IllegalStateException("Decorated file name lookup not available: " + file); - } - return file; - } - - public String trySkinField(String file) { - if ((file != null) && this.skin.hasField(file)) { - file = this.skin.getField(file); - } - return file; - } - - public DataTable getSkinData() { - return this.skinData; - } - - public UIFrame createFrame(final String name, final UIFrame owner, final int priority, final int createContext) { - final FrameDefinition frameDefinition = this.templates.getFrame(name); - final UIFrame inflatedFrame = inflate(frameDefinition, owner, null, frameDefinition.has("DecorateFileNames")); - if (owner == this) { - add(inflatedFrame); - } - return inflatedFrame; - } - - public UIFrame createSimpleFrame(final String name, final UIFrame owner, final int createContext) { - final FrameDefinition frameDefinition = this.templates.getFrame(name); - if (frameDefinition == null) { - final SimpleFrame simpleFrame = new SimpleFrame(name, owner); - add(simpleFrame); - return simpleFrame; - } - else if (frameDefinition.getFrameClass() == FrameClass.Frame) { - final UIFrame inflated = inflate(frameDefinition, owner, null, frameDefinition.has("DecorateFileNames")); - if (this.autoPosition) { - inflated.positionBounds(this, this.viewport); - } - add(inflated); - return inflated; - } - return null; - } - - public TextureFrame createTextureFrame(final String name, final UIFrame parent, final boolean decorateFileNames, - final Vector4Definition texCoord) { - final TextureFrame textureFrame = new TextureFrame(name, parent, decorateFileNames, texCoord); - this.nameToFrame.put(name, textureFrame); - add(textureFrame); - return textureFrame; - } - - public TextureFrame createTextureFrame(final String name, final UIFrame parent, final boolean decorateFileNames, - final Vector4Definition texCoord, final FilterMode filterMode) { - final FilterModeTextureFrame textureFrame = new FilterModeTextureFrame(name, parent, decorateFileNames, - texCoord); - textureFrame.setFilterMode(filterMode); - this.nameToFrame.put(name, textureFrame); - add(textureFrame); - return textureFrame; - } - - public StringFrame createStringFrame(final String name, final UIFrame parent, final Color color, - final TextJustify justifyH, final TextJustify justifyV, final float fdfFontSize) { - this.fontParam.size = (int) convertY(this.viewport, fdfFontSize); - if (this.fontParam.size == 0) { - this.fontParam.size = 128; - } - final BitmapFont frameFont = this.fontGenerator.generateFont(this.fontParam); - final StringFrame stringFrame = new StringFrame(name, parent, color, justifyH, justifyV, frameFont, name, null, - null); - this.nameToFrame.put(name, stringFrame); - add(stringFrame); - return stringFrame; - } - - public UIFrame inflate(final FrameDefinition frameDefinition, final UIFrame parent, - final FrameDefinition parentDefinitionIfAvailable, final boolean inDecorateFileNames) { - UIFrame inflatedFrame = null; - BitmapFont frameFont = null; - Viewport viewport2 = this.viewport; - switch (frameDefinition.getFrameClass()) { - case Frame: - if ("SIMPLEFRAME".equals(frameDefinition.getFrameType())) { - final SimpleFrame simpleFrame = new SimpleFrame(frameDefinition.getName(), parent); - // TODO: we should not need to put ourselves in this map 2x, but we do - // since there are nested inflate calls happening before the general case - // mapping - this.nameToFrame.put(frameDefinition.getName(), simpleFrame); - for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) { - simpleFrame.add(inflate(childDefinition, simpleFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames"))); - } - inflatedFrame = simpleFrame; - } - else if ("SIMPLESTATUSBAR".equals(frameDefinition.getFrameType())) { - final boolean decorateFileNames = frameDefinition.has("DecorateFileNames") - || ((parentDefinitionIfAvailable != null) - && parentDefinitionIfAvailable.has("DecorateFileNames")); - final SimpleStatusBarFrame simpleStatusBarFrame = new SimpleStatusBarFrame(frameDefinition.getName(), - parent, decorateFileNames, false, 0.0f); - for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) { - simpleStatusBarFrame.add(inflate(childDefinition, simpleStatusBarFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames"))); - } - final String barTexture = frameDefinition.getString("BarTexture"); - if (barTexture != null) { - simpleStatusBarFrame.getBarFrame().setTexture(barTexture, this); - simpleStatusBarFrame.getBorderFrame().setTexture(barTexture + "Border", this); - } - inflatedFrame = simpleStatusBarFrame; - } - else if ("SPRITE".equals(frameDefinition.getFrameType())) { - final SpriteFrame spriteFrame = new SpriteFrame(frameDefinition.getName(), parent, this.uiScene, - viewport2); - String backgroundArt = frameDefinition.getString("BackgroundArt"); - if (frameDefinition.has("DecorateFileNames") || inDecorateFileNames) { - if (backgroundArt != null) { - if (this.skin.hasField(backgroundArt)) { - backgroundArt = this.skin.getField(backgroundArt); - } - } - } - if (backgroundArt != null) { - setSpriteFrameModel(spriteFrame, backgroundArt); - } - viewport2 = this.viewport; // TODO was fdfCoordinateResolutionDummyViewport here previously, but is that - // a good idea? - this.nameToFrame.put(frameDefinition.getName(), spriteFrame); - for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) { - spriteFrame.add(inflate(childDefinition, spriteFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames"))); - } - inflatedFrame = spriteFrame; - } - else if ("FRAME".equals(frameDefinition.getFrameType()) - || "DIALOG".equals(frameDefinition.getFrameType())) { - final SimpleFrame simpleFrame = new SimpleFrame(frameDefinition.getName(), parent); - // TODO: we should not need to put ourselves in this map 2x, but we do - // since there are nested inflate calls happening before the general case - // mapping - this.nameToFrame.put(frameDefinition.getName(), simpleFrame); - for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) { - simpleFrame.add(inflate(childDefinition, simpleFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames"))); - } - inflatedFrame = simpleFrame; - } - else if ("TEXT".equals(frameDefinition.getFrameType())) { - final Float textLength = frameDefinition.getFloat("TextLength"); - TextJustify justifyH = frameDefinition.getTextJustify("FontJustificationH"); - if (justifyH == null) { - justifyH = TextJustify.LEFT; - } - TextJustify justifyV = frameDefinition.getTextJustify("FontJustificationV"); - if (justifyV == null) { - justifyV = TextJustify.MIDDLE; - } - for (final SetPointDefinition setPoint : frameDefinition.getSetPoints()) { - if (((setPoint.getMyPoint() == FramePoint.TOP) && (setPoint.getOtherPoint() == FramePoint.TOP)) - || ((setPoint.getMyPoint() == FramePoint.BOTTOM) - && (setPoint.getOtherPoint() == FramePoint.BOTTOM))) { - justifyH = TextJustify.CENTER; - } - } - - Color fontColor; - final Vector4Definition fontColorDefinition = frameDefinition.getVector4("FontColor"); - if (fontColorDefinition == null) { - fontColor = Color.WHITE; - } - else { - fontColor = new Color(fontColorDefinition.getX(), fontColorDefinition.getY(), - fontColorDefinition.getZ(), fontColorDefinition.getW()); - } - - Color fontHighlightColor; - final Vector4Definition fontHighlightColorDefinition = frameDefinition.getVector4("FontHighlightColor"); - if (fontHighlightColorDefinition == null) { - fontHighlightColor = null; - } - else { - fontHighlightColor = new Color(fontHighlightColorDefinition.getX(), - fontHighlightColorDefinition.getY(), fontHighlightColorDefinition.getZ(), - fontHighlightColorDefinition.getW()); - } - - Color fontDisabledColor; - final Vector4Definition fontDisabledColorDefinition = frameDefinition.getVector4("FontDisabledColor"); - if (fontDisabledColorDefinition == null) { - fontDisabledColor = null; - } - else { - fontDisabledColor = new Color(fontDisabledColorDefinition.getX(), - fontDisabledColorDefinition.getY(), fontDisabledColorDefinition.getZ(), - fontDisabledColorDefinition.getW()); - } - - Color fontShadowColor; - final Vector4Definition fontShadowColorDefinition = frameDefinition.getVector4("FontShadowColor"); - if (fontShadowColorDefinition == null) { - fontShadowColor = null; - } - else { - fontShadowColor = new Color(fontShadowColorDefinition.getX(), fontShadowColorDefinition.getY(), - fontShadowColorDefinition.getZ(), fontShadowColorDefinition.getW()); - } - final FontDefinition font = frameDefinition.getFont("FrameFont"); - final Float height = frameDefinition.getFloat("Height"); - this.fontParam.size = (int) convertY(viewport2, - (font == null ? (height == null ? 0.06f : height) : font.getFontSize())); - if (this.fontParam.size == 0) { - this.fontParam.size = 24; - } - frameFont = this.dynamicFontGeneratorHolder.getFontGenerator(font.getFontName()) - .generateFont(this.fontParam); - String textString = frameDefinition.getName(); - String text = frameDefinition.getString("Text"); - if (text != null) { - final String decoratedString = this.templates.getDecoratedString(text); - if (decoratedString != text) { - text = decoratedString; - } - textString = text; - } - final StringFrame stringFrame = new StringFrame(frameDefinition.getName(), parent, fontColor, justifyH, - justifyV, frameFont, textString, fontHighlightColor, fontDisabledColor); - if (fontShadowColor != null) { - final Vector2Definition shadowOffset = frameDefinition.getVector2("FontShadowOffset"); - stringFrame.setFontShadowColor(fontShadowColor); - stringFrame.setFontShadowOffsetX(convertX(viewport2, shadowOffset.getX())); - stringFrame.setFontShadowOffsetY(convertY(viewport2, shadowOffset.getY())); - } - inflatedFrame = stringFrame; - } - else if ("GLUETEXTBUTTON".equals(frameDefinition.getFrameType())) { - // ButtonText & ControlBackdrop - final GlueTextButtonFrame glueButtonFrame = new GlueTextButtonFrame(frameDefinition.getName(), parent); - // TODO: we should not need to put ourselves in this map 2x, but we do - // since there are nested inflate calls happening before the general case - // mapping - this.nameToFrame.put(frameDefinition.getName(), glueButtonFrame); - final String controlBackdropKey = frameDefinition.getString("ControlBackdrop"); - final String controlPushedBackdropKey = frameDefinition.getString("ControlPushedBackdrop"); - final String controlDisabledBackdropKey = frameDefinition.getString("ControlDisabledBackdrop"); - final String controlMouseOverHighlightKey = frameDefinition.getString("ControlMouseOverHighlight"); - final String buttonTextKey = frameDefinition.getString("ButtonText"); - for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) { - if (childDefinition.getName().equals(controlBackdropKey)) { - final UIFrame inflatedChild = inflate(childDefinition, glueButtonFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - glueButtonFrame.setControlBackdrop(inflatedChild); - } - else if (childDefinition.getName().equals(controlPushedBackdropKey)) { - final UIFrame inflatedChild = inflate(childDefinition, glueButtonFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - glueButtonFrame.setControlPushedBackdrop(inflatedChild); - } - else if (childDefinition.getName().equals(controlDisabledBackdropKey)) { - final UIFrame inflatedChild = inflate(childDefinition, glueButtonFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - glueButtonFrame.setControlDisabledBackdrop(inflatedChild); - } - else if (childDefinition.getName().equals(controlMouseOverHighlightKey)) { - final UIFrame inflatedChild = inflate(childDefinition, glueButtonFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - glueButtonFrame.setControlMouseOverHighlight(inflatedChild); - } - else if (childDefinition.getName().equals(buttonTextKey)) { - final UIFrame inflatedChild = inflate(childDefinition, glueButtonFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - glueButtonFrame.setButtonText(inflatedChild); - } - } - final EnumSet controlStyle = ControlStyle - .parseControlStyle(frameDefinition.getString("ControlStyle")); - if (controlStyle.contains(ControlStyle.AUTOTRACK) - && controlStyle.contains(ControlStyle.HIGHLIGHTONMOUSEOVER)) { - glueButtonFrame.setHighlightOnMouseOver(true); - } - inflatedFrame = glueButtonFrame; - } - else if ("SIMPLEBUTTON".equals(frameDefinition.getFrameType())) { - // ButtonText & ControlBackdrop - final SimpleButtonFrame simpleButtonFrame = new SimpleButtonFrame(frameDefinition.getName(), parent); - // TODO: we should not need to put ourselves in this map 2x, but we do - // since there are nested inflate calls happening before the general case - // mapping - this.nameToFrame.put(frameDefinition.getName(), simpleButtonFrame); - final StringPairFrameDefinitionField normalTextDefinition = frameDefinition.getStringPair("NormalText"); - final StringPairFrameDefinitionField disabledTextDefinition = frameDefinition - .getStringPair("DisabledText"); - final StringPairFrameDefinitionField highlightTextDefinition = frameDefinition - .getStringPair("HighlightText"); - final String normalTextureDefinition = frameDefinition.getString("NormalTexture"); - final String pushedTextureDefinition = frameDefinition.getString("PushedTexture"); - final String disabledTextureDefinition = frameDefinition.getString("DisabledTexture"); - final String useHighlightDefinition = frameDefinition.getString("UseHighlight"); - - final boolean decorateFileNamesOnThisFrame = frameDefinition.has("DecorateFileNames") - || inDecorateFileNames; - final UIFrame normalText = inflate(this.templates.getFrame(normalTextDefinition.getFirst()), - simpleButtonFrame, frameDefinition, decorateFileNamesOnThisFrame); - setDecoratedText((StringFrame) normalText, normalTextDefinition.getSecond()); - normalText.setSetAllPoints(true); - final UIFrame disabledText = inflate(this.templates.getFrame(disabledTextDefinition.getFirst()), - simpleButtonFrame, frameDefinition, decorateFileNamesOnThisFrame); - setDecoratedText((StringFrame) disabledText, disabledTextDefinition.getSecond()); - disabledText.setSetAllPoints(true); - final UIFrame highlightText = inflate(this.templates.getFrame(highlightTextDefinition.getFirst()), - simpleButtonFrame, frameDefinition, decorateFileNamesOnThisFrame); - setDecoratedText((StringFrame) highlightText, highlightTextDefinition.getSecond()); - highlightText.setSetAllPoints(true); - final UIFrame normalTexture = inflate(this.templates.getFrame(normalTextureDefinition), - simpleButtonFrame, frameDefinition, decorateFileNamesOnThisFrame); - normalTexture.setSetAllPoints(true); - final UIFrame pushedTexture = inflate(this.templates.getFrame(pushedTextureDefinition), - simpleButtonFrame, frameDefinition, decorateFileNamesOnThisFrame); - pushedTexture.setSetAllPoints(true); - final UIFrame disabledTexture = inflate(this.templates.getFrame(disabledTextureDefinition), - simpleButtonFrame, frameDefinition, decorateFileNamesOnThisFrame); - disabledTexture.setSetAllPoints(true); - final UIFrame useHighlight = inflate(this.templates.getFrame(useHighlightDefinition), simpleButtonFrame, - frameDefinition, decorateFileNamesOnThisFrame); - useHighlight.setSetAllPoints(true); - simpleButtonFrame.setButtonText(normalText); - simpleButtonFrame.setDisabledText(disabledText); - simpleButtonFrame.setHighlightText(highlightText); - simpleButtonFrame.setControlBackdrop(normalTexture); - simpleButtonFrame.setControlDisabledBackdrop(disabledTexture); - simpleButtonFrame.setControlMouseOverHighlight(useHighlight); - simpleButtonFrame.setControlPushedBackdrop(pushedTexture); - - final Vector2Definition pushedTextOffset = frameDefinition.getVector2("ButtonPushedTextOffset"); - if (pushedTextOffset != null) { - final UIFrame pushedNormalText = inflate(this.templates.getFrame(normalTextDefinition.getFirst()), - simpleButtonFrame, frameDefinition, decorateFileNamesOnThisFrame); - setDecoratedText((StringFrame) pushedNormalText, normalTextDefinition.getSecond()); - final UIFrame pushedHighlightText = inflate( - this.templates.getFrame(highlightTextDefinition.getFirst()), simpleButtonFrame, - frameDefinition, decorateFileNamesOnThisFrame); - setDecoratedText((StringFrame) pushedHighlightText, highlightTextDefinition.getSecond()); - pushedNormalText.addSetPoint(new SetPoint(FramePoint.TOPLEFT, simpleButtonFrame, FramePoint.TOPLEFT, - GameUI.convertX(viewport2, pushedTextOffset.getX()), - GameUI.convertY(viewport2, pushedTextOffset.getY()))); - pushedNormalText.addSetPoint(new SetPoint(FramePoint.BOTTOMRIGHT, simpleButtonFrame, - FramePoint.BOTTOMRIGHT, GameUI.convertX(viewport2, pushedTextOffset.getX()), - GameUI.convertY(viewport2, pushedTextOffset.getY()))); - pushedHighlightText.addSetPoint(new SetPoint(FramePoint.TOPLEFT, simpleButtonFrame, - FramePoint.TOPLEFT, GameUI.convertX(viewport2, pushedTextOffset.getX()), - GameUI.convertY(viewport2, pushedTextOffset.getY()))); - pushedHighlightText.addSetPoint(new SetPoint(FramePoint.BOTTOMRIGHT, simpleButtonFrame, - FramePoint.BOTTOMRIGHT, GameUI.convertX(viewport2, pushedTextOffset.getX()), - GameUI.convertY(viewport2, pushedTextOffset.getY()))); - simpleButtonFrame.setPushedText(pushedNormalText); - simpleButtonFrame.setPushedHighlightText(pushedHighlightText); - } - else { - simpleButtonFrame.setPushedText(normalText); - simpleButtonFrame.setPushedHighlightText(highlightText); - } - - inflatedFrame = simpleButtonFrame; - } - else if ("GLUEBUTTON".equals(frameDefinition.getFrameType())) { - // ButtonText & ControlBackdrop - final GlueButtonFrame glueButtonFrame = new GlueButtonFrame(frameDefinition.getName(), parent); - // TODO: we should not need to put ourselves in this map 2x, but we do - // since there are nested inflate calls happening before the general case - // mapping - this.nameToFrame.put(frameDefinition.getName(), glueButtonFrame); - final String controlBackdropKey = frameDefinition.getString("ControlBackdrop"); - final String controlPushedBackdropKey = frameDefinition.getString("ControlPushedBackdrop"); - final String controlDisabledBackdropKey = frameDefinition.getString("ControlDisabledBackdrop"); - final String controlMouseOverHighlightKey = frameDefinition.getString("ControlMouseOverHighlight"); - for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) { - if (childDefinition.getName().equals(controlBackdropKey)) { - final UIFrame inflatedChild = inflate(childDefinition, glueButtonFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - glueButtonFrame.setControlBackdrop(inflatedChild); - } - else if (childDefinition.getName().equals(controlPushedBackdropKey)) { - final UIFrame inflatedChild = inflate(childDefinition, glueButtonFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - glueButtonFrame.setControlPushedBackdrop(inflatedChild); - } - else if (childDefinition.getName().equals(controlDisabledBackdropKey)) { - final UIFrame inflatedChild = inflate(childDefinition, glueButtonFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - glueButtonFrame.setControlDisabledBackdrop(inflatedChild); - } - else if (childDefinition.getName().equals(controlMouseOverHighlightKey)) { - final UIFrame inflatedChild = inflate(childDefinition, glueButtonFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - glueButtonFrame.setControlMouseOverHighlight(inflatedChild); - } - } - final EnumSet controlStyle = ControlStyle - .parseControlStyle(frameDefinition.getString("ControlStyle")); - if (controlStyle.contains(ControlStyle.AUTOTRACK) - && controlStyle.contains(ControlStyle.HIGHLIGHTONMOUSEOVER)) { - glueButtonFrame.setHighlightOnMouseOver(true); - } - inflatedFrame = glueButtonFrame; - } - else if ("TEXTBUTTON".equals(frameDefinition.getFrameType())) { - // ButtonText & ControlBackdrop - final TextButtonFrame glueButtonFrame = new TextButtonFrame(frameDefinition.getName(), parent); - // TODO: we should not need to put ourselves in this map 2x, but we do - // since there are nested inflate calls happening before the general case - // mapping - this.nameToFrame.put(frameDefinition.getName(), glueButtonFrame); - final String controlBackdropKey = frameDefinition.getString("ControlBackdrop"); - final String controlPushedBackdropKey = frameDefinition.getString("ControlPushedBackdrop"); - final String controlDisabledBackdropKey = frameDefinition.getString("ControlDisabledBackdrop"); - final String controlMouseOverHighlightKey = frameDefinition.getString("ControlMouseOverHighlight"); - final Vector2Definition pushedTextOffset = frameDefinition.getVector2("ButtonPushedTextOffset"); - if (pushedTextOffset != null) { - glueButtonFrame.setButtonPushedTextOffsetX(pushedTextOffset.getX()); - glueButtonFrame.setButtonPushedTextOffsetY(pushedTextOffset.getY()); - } - for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) { - if (childDefinition.getName().equals(controlBackdropKey)) { - final UIFrame inflatedChild = inflate(childDefinition, glueButtonFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - glueButtonFrame.setControlBackdrop(inflatedChild); - } - else if (childDefinition.getName().equals(controlPushedBackdropKey)) { - final UIFrame inflatedChild = inflate(childDefinition, glueButtonFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - glueButtonFrame.setControlPushedBackdrop(inflatedChild); - } - else if (childDefinition.getName().equals(controlDisabledBackdropKey)) { - final UIFrame inflatedChild = inflate(childDefinition, glueButtonFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - glueButtonFrame.setControlDisabledBackdrop(inflatedChild); - } - else if (childDefinition.getName().equals(controlMouseOverHighlightKey)) { - final UIFrame inflatedChild = inflate(childDefinition, glueButtonFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - glueButtonFrame.setControlMouseOverHighlight(inflatedChild); - } - } - final EnumSet controlStyle = ControlStyle - .parseControlStyle(frameDefinition.getString("ControlStyle")); - if (controlStyle.contains(ControlStyle.AUTOTRACK) - && controlStyle.contains(ControlStyle.HIGHLIGHTONMOUSEOVER)) { - glueButtonFrame.setHighlightOnMouseOver(true); - } - inflatedFrame = glueButtonFrame; - } - else if ("EDITBOX".equals(frameDefinition.getFrameType())) { - final float editBorderSize = convertX(viewport2, frameDefinition.getFloat("EditBorderSize")); - final Vector4Definition editCursorColorDefinition = frameDefinition.getVector4("EditCursorColor"); - Color editCursorColor; - if (editCursorColorDefinition == null) { - editCursorColor = Color.WHITE; - } - else { - editCursorColor = new Color(editCursorColorDefinition.getX(), editCursorColorDefinition.getY(), - editCursorColorDefinition.getZ(), editCursorColorDefinition.getW()); - } - final EditBoxFrame editBoxFrame = new EditBoxFrame(frameDefinition.getName(), parent, editBorderSize, - editCursorColor); - // TODO: we should not need to put ourselves in this map 2x, but we do - // since there are nested inflate calls happening before the general case - // mapping - this.nameToFrame.put(frameDefinition.getName(), editBoxFrame); - final String controlBackdropKey = frameDefinition.getString("ControlBackdrop"); - final String editTextFrameKey = frameDefinition.getString("EditTextFrame"); - for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) { - if (childDefinition.getName().equals(controlBackdropKey)) { - final UIFrame inflatedChild = inflate(childDefinition, editBoxFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - editBoxFrame.setControlBackdrop(inflatedChild); - } - else if (childDefinition.getName().equals(editTextFrameKey)) { - final UIFrame inflatedChild = inflate(childDefinition, editBoxFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - final StringFrame editTextFrame = (StringFrame) inflatedChild; - inflatedChild.setSetAllPoints(true, editBorderSize); - editBoxFrame.setEditTextFrame(editTextFrame); - setText(editTextFrame, ""); - } - } - inflatedFrame = editBoxFrame; - } - else if ("CONTROL".equals(frameDefinition.getFrameType())) { - final ControlFrame controlFrame = new ControlFrame(frameDefinition.getName(), parent); - // TODO: we should not need to put ourselves in this map 2x, but we do - // since there are nested inflate calls happening before the general case - // mapping - this.nameToFrame.put(frameDefinition.getName(), controlFrame); - final String controlBackdropKey = frameDefinition.getString("ControlBackdrop"); - for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) { - if (childDefinition.getName().equals(controlBackdropKey)) { - final UIFrame inflatedChild = inflate(childDefinition, controlFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - controlFrame.setControlBackdrop(inflatedChild); - } - } - inflatedFrame = controlFrame; - } - else if ("LISTBOX".equals(frameDefinition.getFrameType())) { - // TODO advanced components here - final ListBoxFrame controlFrame = new ListBoxFrame(frameDefinition.getName(), parent, viewport2); - // TODO: we should not need to put ourselves in this map 2x, but we do - // since there are nested inflate calls happening before the general case - // mapping - this.nameToFrame.put(frameDefinition.getName(), controlFrame); - final String controlBackdropKey = frameDefinition.getString("ControlBackdrop"); - for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) { - if (childDefinition.getName().equals(controlBackdropKey)) { - final UIFrame inflatedChild = inflate(childDefinition, controlFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames")); - inflatedChild.setSetAllPoints(true); - controlFrame.setControlBackdrop(inflatedChild); - } - } - inflatedFrame = controlFrame; - } - else if ("HIGHLIGHT".equals(frameDefinition.getFrameType())) { - final String highlightType = frameDefinition.getString("HighlightType"); - if (!"FILETEXTURE".equals(highlightType)) { - throw new IllegalStateException( - "Our engine does not know how to handle a non-FILETEXTURE highlight"); - } - final String highlightAlphaFile = frameDefinition.getString("HighlightAlphaFile"); - final String highlightAlphaMode = frameDefinition.getString("HighlightAlphaMode"); - final FilterModeTextureFrame textureFrame = new FilterModeTextureFrame(frameDefinition.getName(), - parent, inDecorateFileNames || frameDefinition.has("DecorateFileNames"), null); - textureFrame.setTexture(highlightAlphaFile, this); - if ("ADD".equals(highlightAlphaMode)) { - textureFrame.setFilterMode(FilterMode.ADDALPHA); - } - return textureFrame; - } - else if ("BACKDROP".equals(frameDefinition.getFrameType())) { - final boolean tileBackground = frameDefinition.has("BackdropTileBackground"); - final boolean mirrored = frameDefinition.has("BackdropMirrored"); - String backgroundString = frameDefinition.getString("BackdropBackground"); - String cornerFlagsString = frameDefinition.getString("BackdropCornerFlags"); - if (cornerFlagsString == null) { - cornerFlagsString = ""; - } - final EnumSet cornerFlags = BackdropCornerFlags - .parseCornerFlags(cornerFlagsString); - final Float cornerSizeNullable = frameDefinition.getFloat("BackdropCornerSize"); - final float cornerSize = GameUI.convertX(viewport2, - cornerSizeNullable == null ? 0.0f : cornerSizeNullable); - final Float backgroundSizeNullable = frameDefinition.getFloat("BackdropBackgroundSize"); - final float backgroundSize = GameUI.convertX(viewport2, - backgroundSizeNullable == null ? 0.0f : backgroundSizeNullable); - Vector4Definition backgroundInsets = frameDefinition.getVector4("BackdropBackgroundInsets"); - if (backgroundInsets != null) { - backgroundInsets = new Vector4Definition(GameUI.convertX(viewport2, backgroundInsets.getX()), - GameUI.convertY(viewport2, backgroundInsets.getY()), - GameUI.convertX(viewport2, backgroundInsets.getZ()), - GameUI.convertY(viewport2, backgroundInsets.getW())); - } - else { - backgroundInsets = new Vector4Definition(0, 0, 0, 0); - } - final boolean decorateFileNames = frameDefinition.has("DecorateFileNames") || inDecorateFileNames; - String edgeFileString = frameDefinition.getString("BackdropEdgeFile"); - System.out.println(frameDefinition.getName() + " wants edge file: " + edgeFileString); - if (decorateFileNames && (edgeFileString != null)) { - edgeFileString = trySkinField(edgeFileString); - } - if (decorateFileNames && (edgeFileString != null)) { - backgroundString = trySkinField(backgroundString); - } - final Texture background = backgroundString == null ? null : loadTexture(backgroundString); - final Texture edgeFile = edgeFileString == null ? null : loadTexture(edgeFileString); - System.out.println(frameDefinition.getName() + " got edge file: " + edgeFile); - - final BackdropFrame backdropFrame = new BackdropFrame(frameDefinition.getName(), parent, - decorateFileNames, tileBackground, background, cornerFlags, cornerSize, backgroundSize, - backgroundInsets, edgeFile, mirrored); - this.nameToFrame.put(frameDefinition.getName(), backdropFrame); - for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) { - backdropFrame.add(inflate(childDefinition, backdropFrame, frameDefinition, decorateFileNames)); - } - inflatedFrame = backdropFrame; - } - break; - case Layer: - final SimpleFrame simpleFrame = new SimpleFrame(frameDefinition.getName(), parent); - simpleFrame.setSetAllPoints(true); - this.nameToFrame.put(frameDefinition.getName(), simpleFrame); - for (final FrameDefinition childDefinition : frameDefinition.getInnerFrames()) { - simpleFrame.add(inflate(childDefinition, simpleFrame, frameDefinition, - inDecorateFileNames || childDefinition.has("DecorateFileNames"))); - } - inflatedFrame = simpleFrame; - break; - case String: - final Float textLength = frameDefinition.getFloat("TextLength"); - TextJustify justifyH = frameDefinition.getTextJustify("FontJustificationH"); - if (justifyH == null) { - justifyH = TextJustify.CENTER; - } - TextJustify justifyV = frameDefinition.getTextJustify("FontJustificationV"); - if (justifyV == null) { - justifyV = TextJustify.MIDDLE; - } - - Color fontColor; - final Vector4Definition fontColorDefinition = frameDefinition.getVector4("FontColor"); - if (fontColorDefinition == null) { - fontColor = Color.WHITE; - } - else { - fontColor = new Color(fontColorDefinition.getX(), fontColorDefinition.getY(), - fontColorDefinition.getZ(), fontColorDefinition.getW()); - } - final FontDefinition font = frameDefinition.getFont("Font"); - this.fontParam.size = (int) convertY(viewport2, font.getFontSize()); - if (this.fontParam.size == 0) { - this.fontParam.size = 24; - } - frameFont = this.dynamicFontGeneratorHolder.getFontGenerator(font.getFontName()) - .generateFont(this.fontParam); - String textString = frameDefinition.getName(); - String text = frameDefinition.getString("Text"); - if (text != null) { - final String decoratedString = this.templates.getDecoratedString(text); - if (decoratedString != text) { - text = decoratedString; - } - textString = text; - } - final StringFrame stringFrame = new StringFrame(frameDefinition.getName(), parent, fontColor, justifyH, - justifyV, frameFont, textString, null, null); - inflatedFrame = stringFrame; - break; - case Texture: - final String file = frameDefinition.getString("File"); - final boolean decorateFileNames = frameDefinition.has("DecorateFileNames") || inDecorateFileNames; - final Vector4Definition texCoord = frameDefinition.getVector4("TexCoord"); - TextureFrame textureFrame; - final String alphaMode = frameDefinition.getString("AlphaMode"); - if ((alphaMode != null) && alphaMode.equals("ADD")) { - final FilterModeTextureFrame filterModeTextureFrame = new FilterModeTextureFrame( - frameDefinition.getName(), parent, decorateFileNames, texCoord); - filterModeTextureFrame.setFilterMode(FilterMode.ADDALPHA); - textureFrame = filterModeTextureFrame; - } - else { - textureFrame = new TextureFrame(frameDefinition.getName(), parent, decorateFileNames, texCoord); - } - textureFrame.setTexture(file, this); - inflatedFrame = textureFrame; - break; - default: - break; - } - if (inflatedFrame != null) { - if (frameDefinition.has("SetAllPoints")) { - inflatedFrame.setSetAllPoints(true); - } - Float width = frameDefinition.getFloat("Width"); - if (width != null) { - inflatedFrame.setWidth(convertX(viewport2, width)); - } - else { - width = frameDefinition.getFloat("TextLength"); - if (width != null) { - if (frameFont != null) { - inflatedFrame.setWidth(convertX(viewport2, width * frameFont.getSpaceWidth())); - } - } - } - final Float height = frameDefinition.getFloat("Height"); - if (height != null) { - inflatedFrame.setHeight(convertY(viewport2, height)); - } - for (final AnchorDefinition anchor : frameDefinition.getAnchors()) { - inflatedFrame.addAnchor(new AnchorDefinition(anchor.getMyPoint(), - convertX(this.viewport, anchor.getX()), convertY(this.viewport, anchor.getY()))); - } - for (final SetPointDefinition setPointDefinition : frameDefinition.getSetPoints()) { - final UIFrame otherFrameByName = getFrameByName(setPointDefinition.getOther(), - 0 /* TODO: createContext */); - if (otherFrameByName == null) { - System.err.println("Failing to pin " + frameDefinition.getName() + " to " - + setPointDefinition.getOther() + " because it was null!"); - if (PIN_FAIL_IS_FATAL) { - throw new IllegalStateException("Failing to pin " + frameDefinition.getName() + " to " - + setPointDefinition.getOther() + " because it was null!"); - } - } - else { - inflatedFrame.addSetPoint(new SetPoint(setPointDefinition.getMyPoint(), otherFrameByName, - setPointDefinition.getOtherPoint(), convertX(this.viewport, setPointDefinition.getX()), - convertY(this.viewport, setPointDefinition.getY()))); - } - } - this.nameToFrame.put(frameDefinition.getName(), inflatedFrame); - } - else { - // TODO in production throw some kind of exception here - } - return inflatedFrame; - } - - public void setSpriteFrameModel(final SpriteFrame spriteFrame, String backgroundArt) { - if (backgroundArt.toLowerCase().endsWith(".mdl") || backgroundArt.toLowerCase().endsWith(".mdx")) { - backgroundArt = backgroundArt.substring(0, backgroundArt.length() - 4); - } - backgroundArt += ".mdx"; - final MdxModel model = (MdxModel) this.modelViewer.load(backgroundArt, this.modelViewer.mapPathSolver, - this.modelViewer.solverParams); - spriteFrame.setModel(model); - } - - public UIFrame createFrameByType(final String typeName, final String name, final UIFrame owner, - final String inherits, final int createContext) { - // TODO idk what inherits is doing yet, and I didn't implement createContext yet - // even though it looked like just mapping/indexing on int - final FrameDefinition baseTemplateDef = this.templates.getFrame(name); - final FrameDefinition frameDefinition = new FrameDefinition(FrameClass.Frame, typeName, name); - if (baseTemplateDef != null) { - frameDefinition.inheritFrom(baseTemplateDef, "WITHCHILDREN".equals(inherits)); - } - final UIFrame inflatedFrame = inflate(frameDefinition, owner, null, frameDefinition.has("DecorateFileNames")); - if (this == owner) { - add(inflatedFrame); - } - return inflatedFrame; - } - - public UIFrame getFrameByName(final String name, final int createContext) { - return this.nameToFrame.get(name); - } - - public static float convertX(final Viewport viewport, final float fdfX) { - if (viewport instanceof ExtendViewport) { - return (fdfX / 0.8f) * ((ExtendViewport) viewport).getMinWorldWidth(); - } - return (fdfX / 0.8f) * viewport.getWorldWidth(); - } - - public static float convertY(final Viewport viewport, final float fdfY) { - if (viewport instanceof ExtendViewport) { - return (fdfY / 0.6f) * ((ExtendViewport) viewport).getMinWorldHeight(); - } - return (fdfY / 0.6f) * viewport.getWorldHeight(); - } - - public static float unconvertX(final Viewport viewport, final float nonFdfX) { - if (viewport instanceof ExtendViewport) { - return (nonFdfX / ((ExtendViewport) viewport).getMinWorldWidth()) * 0.8f; - } - return (nonFdfX / viewport.getWorldWidth()) * 0.8f; - } - - public static float unconvertY(final Viewport viewport, final float nonFdfY) { - if (viewport instanceof ExtendViewport) { - return (nonFdfY / ((ExtendViewport) viewport).getMinWorldHeight()) * 0.6f; - } - return (nonFdfY / viewport.getWorldHeight()) * 0.6f; - } - - public Texture loadTexture(String path) { - final int lastDotIndex = path.lastIndexOf('.'); - if (lastDotIndex == -1) { - path = path + ".blp"; - } - else { - path = path.substring(0, lastDotIndex) + ".blp"; - } - Texture texture = this.pathToTexture.get(path); - if (texture == null) { - try { - texture = ImageUtils.getAnyExtensionTexture(this.dataSource, path); - this.pathToTexture.put(path, texture); - } - catch (final Exception exc) { - - } - } - return texture; - } - - @Override - public final void positionBounds(final GameUI gameUI, final Viewport viewport) { - innerPositionBounds(this, viewport); - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - super.internalRender(batch, baseFont, glyphLayout); - } - - @Override - public void add(final UIFrame childFrame) { - super.add(childFrame); - this.nameToFrame.put(childFrame.getName(), childFrame); - } - - public Scene getUiScene() { - return this.uiScene; - } - - public FrameTemplateEnvironment getTemplates() { - return this.templates; - } - - public String getErrorString(final String key) { - String errorString = this.errorStrings.getField(key, this.racialCommandIndex); - if (errorString.startsWith("TRIGSTR_")) { - errorString = this.mapStrings.get(Integer.parseInt(errorString.substring(8))); - } - return errorString; - } - - public GlyphLayout getGlyphLayout() { - return this.glyphLayout; - } - - public void setText(final StringFrame stringFrame, final String text) { - stringFrame.setText(text, this, this.viewport); - } - - public void setDecoratedText(final StringFrame stringFrame, final String text) { - stringFrame.setText(this.templates.getDecoratedString(text), this, this.viewport); - } - - public BitmapFont getFont() { - return this.font; - } - - public BitmapFont getFont20() { - return this.font20; - } - - public FreeTypeFontGenerator getFontGenerator() { - return this.fontGenerator; - } - - public void dispose() { - this.dynamicFontGeneratorHolder.dispose(); - } - - public FocusableFrame getNextFocusFrame() { - // TODO to support tabbing thru menus and stuff, we will have to implement this - return null; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/Main.java b/core/src/com/etheller/warsmash/parsers/fdf/Main.java deleted file mode 100644 index 02a6fc1a..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/Main.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.etheller.warsmash.parsers.fdf; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.util.Arrays; - -import com.etheller.warsmash.datasources.CompoundDataSourceDescriptor; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.datasources.DataSourceDescriptor; -import com.etheller.warsmash.datasources.FolderDataSourceDescriptor; -import com.etheller.warsmash.fdfparser.FDFParser; -import com.etheller.warsmash.fdfparser.FrameDefinitionVisitor; -import com.etheller.warsmash.parsers.fdf.datamodel.FrameDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.FrameTemplateEnvironment; - -public class Main { - public static final boolean REPORT_SYNTAX_ERRORS = true; - - public static void main(final String[] args) { - if (args.length < 1) { - System.err.println("Usage: "); - return; - } - try { - - final FolderDataSourceDescriptor war3mpq = new FolderDataSourceDescriptor( - "E:\\Backups\\Warcraft\\Data\\127"); - final FolderDataSourceDescriptor testingFolder = new FolderDataSourceDescriptor( - "E:\\Backups\\Warsmash\\Data"); - final FolderDataSourceDescriptor currentFolder = new FolderDataSourceDescriptor("."); - final DataSource dataSource = new CompoundDataSourceDescriptor( - Arrays.asList(war3mpq, testingFolder, currentFolder)).createDataSource(); - - final FrameTemplateEnvironment templates = new FrameTemplateEnvironment(); - final DataSourceFDFParserBuilder dataSourceFDFParserBuilder = new DataSourceFDFParserBuilder(dataSource); - final FrameDefinitionVisitor fdfVisitor = new FrameDefinitionVisitor(templates, dataSourceFDFParserBuilder); - try (BufferedReader reader = new BufferedReader( - new InputStreamReader(dataSource.getResourceAsStream("UI\\FrameDef\\FrameDef.toc")))) { - String line; - while ((line = reader.readLine()) != null) { - final FDFParser firstFileParser = dataSourceFDFParserBuilder.build(line); - fdfVisitor.visit(firstFileParser.program()); - } - } - - final FrameDefinition bnetChat = templates.getFrame("ConsoleUI"); - System.out.println("Value of ConsoleUI: " + bnetChat); - } - catch (final Exception exc) { - exc.printStackTrace(); - System.err.println(exc.getMessage()); - } - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/ModelExport.java b/core/src/com/etheller/warsmash/parsers/fdf/ModelExport.java deleted file mode 100644 index 243a4555..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/ModelExport.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.etheller.warsmash.parsers.fdf; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; - -import com.etheller.warsmash.datasources.CompoundDataSourceDescriptor; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.datasources.DataSourceDescriptor; -import com.etheller.warsmash.datasources.FolderDataSourceDescriptor; -import com.hiveworkshop.rms.parsers.mdlx.MdlxModel; -import com.hiveworkshop.rms.parsers.mdlx.util.MdxUtils; - -public class ModelExport { - - public static void main(final String[] args) { - - final FolderDataSourceDescriptor war3mpq = new FolderDataSourceDescriptor("E:\\Backups\\Warcraft\\Data\\127"); - final FolderDataSourceDescriptor testingFolder = new FolderDataSourceDescriptor("E:\\Backups\\Warsmash\\Data"); - final FolderDataSourceDescriptor currentFolder = new FolderDataSourceDescriptor("."); - final DataSource dataSource = new CompoundDataSourceDescriptor( - Arrays.asList(war3mpq, testingFolder, currentFolder)).createDataSource(); - - try (InputStream modelStream = dataSource - .getResourceAsStream("UI\\Glues\\MainMenu\\MainMenu3D\\MainMenu3D.mdx")) { - final MdlxModel model = new MdlxModel(dataSource.read("UI\\Glues\\MainMenu\\MainMenu3D\\MainMenu3D.mdx")); - try (FileOutputStream fos = new FileOutputStream(new File("C:\\Temp\\MainMenu3D.mdl"))) { - MdxUtils.saveMdl(model, fos); - } - } - catch (final IOException e) { - e.printStackTrace(); - } - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/AbstractRenderableFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/AbstractRenderableFrame.java deleted file mode 100644 index 418840ff..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/AbstractRenderableFrame.java +++ /dev/null @@ -1,397 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import java.util.EnumMap; - -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.AnchorDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; - -public abstract class AbstractRenderableFrame implements UIFrame { - private static final FramePoint[] LEFT_ANCHOR_PRIORITY = { FramePoint.LEFT, FramePoint.TOPLEFT, - FramePoint.BOTTOMLEFT }; - private static final FramePoint[] RIGHT_ANCHOR_PRIORITY = { FramePoint.RIGHT, FramePoint.TOPRIGHT, - FramePoint.BOTTOMRIGHT }; - private static final FramePoint[] CENTER_HORIZ_ANCHOR_PRIORITY = { FramePoint.CENTER, FramePoint.TOP, - FramePoint.BOTTOM }; - private static final FramePoint[] CENTER_VERT_ANCHOR_PRIORITY = { FramePoint.CENTER, FramePoint.LEFT, - FramePoint.RIGHT }; - private static final FramePoint[] TOP_ANCHOR_PRIORITY = { FramePoint.TOP, FramePoint.TOPLEFT, FramePoint.TOPRIGHT }; - private static final FramePoint[] BOTTOM_ANCHOR_PRIORITY = { FramePoint.BOTTOM, FramePoint.BOTTOMLEFT, - FramePoint.BOTTOMRIGHT }; - private static final boolean DEBUG_LOG = false; - protected String name; - protected UIFrame parent; - protected boolean visible = true; - protected int level; - protected final Rectangle renderBounds = new Rectangle(0, 0, 0, 0); // in libgdx rendering space - private final EnumMap framePointToAssignment = new EnumMap<>(FramePoint.class); - protected float assignedHeight; - protected float assignedWidth; - - public AbstractRenderableFrame(final String name, final UIFrame parent) { - this.name = name; - this.parent = parent; - } - - @Override - public void setSetAllPoints(final boolean setAllPoints) { - for (final FramePoint framePoint : FramePoint.values()) { - if (!this.framePointToAssignment.containsKey(framePoint)) { - this.framePointToAssignment.put(framePoint, new SetPoint(framePoint, this.parent, framePoint, 0, 0)); - } - } - } - - @Override - public void setSetAllPoints(final boolean setAllPoints, final float inset) { - this.framePointToAssignment.put(FramePoint.TOPLEFT, - new SetPoint(FramePoint.TOPLEFT, this.parent, FramePoint.TOPLEFT, inset, -inset)); - this.framePointToAssignment.put(FramePoint.LEFT, - new SetPoint(FramePoint.LEFT, this.parent, FramePoint.LEFT, inset, 0)); - this.framePointToAssignment.put(FramePoint.BOTTOMLEFT, - new SetPoint(FramePoint.BOTTOMLEFT, this.parent, FramePoint.BOTTOMLEFT, inset, inset)); - this.framePointToAssignment.put(FramePoint.BOTTOM, - new SetPoint(FramePoint.BOTTOM, this.parent, FramePoint.BOTTOM, 0, inset)); - this.framePointToAssignment.put(FramePoint.BOTTOMRIGHT, - new SetPoint(FramePoint.BOTTOMRIGHT, this.parent, FramePoint.BOTTOMRIGHT, -inset, inset)); - this.framePointToAssignment.put(FramePoint.RIGHT, - new SetPoint(FramePoint.RIGHT, this.parent, FramePoint.RIGHT, -inset, 0)); - this.framePointToAssignment.put(FramePoint.TOPRIGHT, - new SetPoint(FramePoint.TOPRIGHT, this.parent, FramePoint.TOPRIGHT, -inset, -inset)); - this.framePointToAssignment.put(FramePoint.TOP, - new SetPoint(FramePoint.TOP, this.parent, FramePoint.TOP, 0, -inset)); - this.framePointToAssignment.put(FramePoint.CENTER, - new SetPoint(FramePoint.CENTER, this.parent, FramePoint.CENTER, 0, 0)); - } - - @Override - public void setWidth(final float width) { - this.assignedWidth = width; - this.renderBounds.width = width; - } - - @Override - public float getAssignedWidth() { - return this.assignedWidth; - } - - @Override - public float getAssignedHeight() { - return this.assignedHeight; - } - - @Override - public void setHeight(final float height) { - this.assignedHeight = height; - this.renderBounds.height = height; - } - - private FramePointAssignment getByPriority(final FramePoint[] priorities) { - for (final FramePoint priorityFramePoint : priorities) { - final FramePointAssignment framePointAssignment = this.framePointToAssignment.get(priorityFramePoint); - if (framePointAssignment != null) { - return framePointAssignment; - } - } - return null; - } - - public void clearFramePointAssignments() { - this.framePointToAssignment.clear(); - } - - private FramePointAssignment getLeftAnchor() { - return getByPriority(LEFT_ANCHOR_PRIORITY); - } - - private FramePointAssignment getRightAnchor() { - return getByPriority(RIGHT_ANCHOR_PRIORITY); - } - - private FramePointAssignment getTopAnchor() { - return getByPriority(TOP_ANCHOR_PRIORITY); - } - - private FramePointAssignment getBottomAnchor() { - return getByPriority(BOTTOM_ANCHOR_PRIORITY); - } - - private FramePointAssignment getCenterHorizontalAnchor() { - return getByPriority(CENTER_HORIZ_ANCHOR_PRIORITY); - } - - private FramePointAssignment getCenterVerticalAnchor() { - return getByPriority(CENTER_VERT_ANCHOR_PRIORITY); - } - - @Override - public float getFramePointX(final FramePoint framePoint) { - switch (framePoint) { - case CENTER: - case BOTTOM: - case TOP: - return this.renderBounds.x + (this.renderBounds.width / 2); - case BOTTOMLEFT: - case LEFT: - case TOPLEFT: - return this.renderBounds.x; - case BOTTOMRIGHT: - case RIGHT: - case TOPRIGHT: - return this.renderBounds.x + this.renderBounds.width; - default: - return 0; - } - } - - @Override - public void setFramePointX(final FramePoint framePoint, final float x) { - if (this.renderBounds.width == 0) { - this.renderBounds.x = x; - return; - } - switch (framePoint) { - case CENTER: - case BOTTOM: - case TOP: - this.renderBounds.x = x - (this.renderBounds.width / 2); - return; - case BOTTOMLEFT: - case LEFT: - case TOPLEFT: - if (getRightAnchor() != null) { - final float oldRightX = this.renderBounds.x + this.renderBounds.width; - this.renderBounds.x = x; - this.renderBounds.width = oldRightX - x; - } - else { - // no right anchor, keep width - this.renderBounds.x = x; - } - return; - case BOTTOMRIGHT: - case RIGHT: - case TOPRIGHT: - if (getLeftAnchor() != null) { - this.renderBounds.width = x - this.renderBounds.x; - } - else { - this.renderBounds.x = x - this.renderBounds.width; - } - return; - default: - return; - } - } - - @Override - public float getFramePointY(final FramePoint framePoint) { - switch (framePoint) { - case LEFT: - case CENTER: - case RIGHT: - return this.renderBounds.y + (this.renderBounds.height / 2); - case BOTTOMLEFT: - case BOTTOM: - case BOTTOMRIGHT: - return this.renderBounds.y; - case TOPLEFT: - case TOP: - case TOPRIGHT: - return this.renderBounds.y + this.renderBounds.height; - default: - return 0; - } - } - - @Override - public void setFramePointY(final FramePoint framePoint, final float y) { - if (this.renderBounds.height == 0) { - this.renderBounds.y = y; - return; - } - switch (framePoint) { - case LEFT: - case CENTER: - case RIGHT: - this.renderBounds.y = y - (this.renderBounds.height / 2); - return; - case TOPLEFT: - case TOP: - case TOPRIGHT: - if (getBottomAnchor() != null) { - this.renderBounds.height = y - this.renderBounds.y; - } - else { - this.renderBounds.y = y - this.renderBounds.height; - } - return; - case BOTTOMLEFT: - case BOTTOM: - case BOTTOMRIGHT: - if (getTopAnchor() != null) { - final float oldBottomY = this.renderBounds.y + this.renderBounds.height; - this.renderBounds.y = y; - this.renderBounds.height = oldBottomY - y; - } - else { - this.renderBounds.y = y; - } - return; - default: - return; - } - } - - @Override - public void addAnchor(final AnchorDefinition anchorDefinition) { - this.framePointToAssignment.put(anchorDefinition.getMyPoint(), new SetPoint(anchorDefinition.getMyPoint(), - this.parent, anchorDefinition.getMyPoint(), anchorDefinition.getX(), anchorDefinition.getY())); - } - - @Override - public void addSetPoint(final SetPoint setPointDefinition) { - this.framePointToAssignment.put(setPointDefinition.getMyPoint(), setPointDefinition); - } - - @Override - public void positionBounds(final GameUI gameUI, final Viewport viewport) { - if (this.parent == null) { - // TODO this is a bit of a hack, remove later - return; - } - if (this.framePointToAssignment.isEmpty()) { - this.renderBounds.x = this.parent.getFramePointX(FramePoint.LEFT); - this.renderBounds.y = this.parent.getFramePointY(FramePoint.BOTTOM); - } - else { - final FramePointAssignment leftAnchor = getLeftAnchor(); - final FramePointAssignment rightAnchor = getRightAnchor(); - final FramePointAssignment topAnchor = getTopAnchor(); - final FramePointAssignment bottomAnchor = getBottomAnchor(); - final FramePointAssignment centerHorizontalAnchor = getCenterHorizontalAnchor(); - final FramePointAssignment centerVerticalAnchor = getCenterVerticalAnchor(); - if (leftAnchor != null) { - this.renderBounds.x = leftAnchor.getX(gameUI, viewport); - if (this.assignedWidth == 0) { - if (rightAnchor != null) { - this.renderBounds.width = rightAnchor.getX(gameUI, viewport) - this.renderBounds.x; - } - else if (centerHorizontalAnchor != null) { - this.renderBounds.width = (centerHorizontalAnchor.getX(gameUI, viewport) - this.renderBounds.x) - * 2; - } - } - } - else if (rightAnchor != null) { - this.renderBounds.x = rightAnchor.getX(gameUI, viewport) - this.renderBounds.width; - if (centerHorizontalAnchor != null) { - this.renderBounds.width = (this.renderBounds.x - centerHorizontalAnchor.getX(gameUI, viewport)) * 2; - } - } - else if (centerHorizontalAnchor != null) { - this.renderBounds.x = centerHorizontalAnchor.getX(gameUI, viewport) - (this.renderBounds.width / 2); - } - if (bottomAnchor != null) { - this.renderBounds.y = bottomAnchor.getY(gameUI, viewport); - if (this.assignedHeight == 0) { - if (topAnchor != null) { - this.renderBounds.height = topAnchor.getY(gameUI, viewport) - this.renderBounds.y; - } - else if (centerVerticalAnchor != null) { - this.renderBounds.height = (centerVerticalAnchor.getY(gameUI, viewport) - this.renderBounds.y) - * 2; - } - } - } - else if (topAnchor != null) { - this.renderBounds.y = topAnchor.getY(gameUI, viewport) - this.renderBounds.height; - if (centerVerticalAnchor != null) { - this.renderBounds.height = (this.renderBounds.y - centerVerticalAnchor.getY(gameUI, viewport)) * 2; - } - } - else if (centerVerticalAnchor != null) { - this.renderBounds.y = centerVerticalAnchor.getY(gameUI, viewport) - (this.renderBounds.height / 2); - } - } - if (DEBUG_LOG) { - System.out.println(getClass().getSimpleName() + ":" + this.name + ":" + hashCode() - + " finishing position bounds: " + this.renderBounds); - } - innerPositionBounds(gameUI, viewport); - } - - protected abstract void innerPositionBounds(GameUI gameUI, final Viewport viewport); - - @Override - public boolean isVisible() { - return this.visible; - } - - public int getLevel() { - return this.level; - } - - @Override - public void setVisible(final boolean visible) { - this.visible = visible; - } - - public void setLevel(final int level) { - this.level = level; - } - - @Override - public final void render(final SpriteBatch batch, final BitmapFont font20, final GlyphLayout glyphLayout) { - if (this.visible) { - internalRender(batch, font20, glyphLayout); - } - } - - @Override - public UIFrame getParent() { - return this.parent; - } - - @Override - public boolean isVisibleOnScreen() { - boolean visibleOnScreen = this.visible; - UIFrame ancestor = this.parent; - while (visibleOnScreen && (ancestor != null)) { - visibleOnScreen &= ancestor.isVisible(); - ancestor = ancestor.getParent(); - } - return visibleOnScreen; - } - - protected abstract void internalRender(SpriteBatch batch, BitmapFont baseFont, GlyphLayout glyphLayout); - - @Override - public UIFrame touchDown(final float screenX, final float screenY, final int button) { - return null; - } - - @Override - public UIFrame touchUp(final float screenX, final float screenY, final int button) { - return null; - } - - @Override - public UIFrame getFrameChildUnderMouse(final float screenX, final float screenY) { - return null; - } - - @Override - public String getName() { - return this.name; - } - - public Rectangle getRenderBounds() { - return this.renderBounds; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/AbstractUIFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/AbstractUIFrame.java deleted file mode 100644 index 5727e28a..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/AbstractUIFrame.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; - -public abstract class AbstractUIFrame extends AbstractRenderableFrame implements UIFrame { - private final List childFrames = new ArrayList<>(); - - public void add(final UIFrame childFrame) { - if (childFrame == null) { - return; - } - this.childFrames.add(childFrame); - } - - public void remove(final UIFrame childFrame) { - if (childFrame == null) { - return; - } - this.childFrames.remove(childFrame); - } - - public AbstractUIFrame(final String name, final UIFrame parent) { - super(name, parent); - } - - @Override - public void setVisible(final boolean visible) { - super.setVisible(visible); - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - for (final UIFrame childFrame : this.childFrames) { - childFrame.render(batch, baseFont, glyphLayout); - } - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - for (final UIFrame childFrame : this.childFrames) { - childFrame.positionBounds(gameUI, viewport); - } - } - - @Override - public UIFrame touchDown(final float screenX, final float screenY, final int button) { - if (isVisible()) { - for (final UIFrame childFrame : this.childFrames) { - final UIFrame clickedChild = childFrame.touchDown(screenX, screenY, button); - if (clickedChild != null) { - return clickedChild; - } - } - } - return super.touchDown(screenX, screenY, button); - } - - @Override - public UIFrame touchUp(final float screenX, final float screenY, final int button) { - if (isVisible()) { - for (final UIFrame childFrame : this.childFrames) { - final UIFrame clickedChild = childFrame.touchUp(screenX, screenY, button); - if (clickedChild != null) { - return clickedChild; - } - } - } - return super.touchUp(screenX, screenY, button); - } - - @Override - public UIFrame getFrameChildUnderMouse(final float screenX, final float screenY) { - if (isVisible()) { - for (final UIFrame childFrame : this.childFrames) { - final UIFrame clickedChild = childFrame.getFrameChildUnderMouse(screenX, screenY); - if (clickedChild != null) { - return clickedChild; - } - } - } - return super.getFrameChildUnderMouse(screenX, screenY); - } -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/AnchorPoint.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/AnchorPoint.java deleted file mode 100644 index 01566c92..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/AnchorPoint.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; - -public class AnchorPoint implements FramePointAssignment { - private final FramePoint framePoint; - private final float x; - private final float y; - - public AnchorPoint(final FramePoint framePoint, final float x, final float y) { - this.framePoint = framePoint; - this.x = x; - this.y = y; - } - - public float getX() { - return this.x; - } - - public float getY() { - return this.y; - } - - @Override - public float getX(final GameUI gameUI, final Viewport uiViewport) { - return gameUI.getFramePointX(this.framePoint) + this.x; - } - - @Override - public float getY(final GameUI gameUI, final Viewport uiViewport) { - return gameUI.getFramePointY(this.framePoint) + this.y; - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/BackdropFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/BackdropFrame.java deleted file mode 100644 index 9e599288..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/BackdropFrame.java +++ /dev/null @@ -1,197 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import java.util.EnumSet; - -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.etheller.warsmash.parsers.fdf.datamodel.BackdropCornerFlags; -import com.etheller.warsmash.parsers.fdf.datamodel.Vector4Definition; - -public class BackdropFrame extends AbstractUIFrame { - private final boolean decorateFileNames; - private final boolean tileBackground; - private final Texture background; - private final EnumSet cornerFlags; - private final float cornerSize; - private float backgroundSize; - private final Vector4Definition backgroundInsets; - private final Texture edgeFile; - private final float edgeFileWidth; - private final float edgeUVWidth; - private final float edgeFileHeight; - private final float edgeUVHeight; - private final boolean mirrored; - - public BackdropFrame(final String name, final UIFrame parent, final boolean decorateFileNames, - final boolean tileBackground, final Texture background, final EnumSet cornerFlags, - final float cornerSize, final float backgroundSize, final Vector4Definition backgroundInsets, - final Texture edgeFile, final boolean mirrored) { - super(name, parent); - this.decorateFileNames = decorateFileNames; - this.tileBackground = tileBackground && (backgroundSize > 0); - this.background = background; - this.cornerFlags = cornerFlags; - this.cornerSize = cornerSize; - this.backgroundSize = backgroundSize; - this.backgroundInsets = backgroundInsets; - this.edgeFile = edgeFile; - this.edgeFileWidth = edgeFile == null ? 0.0f : edgeFile.getWidth(); - this.edgeFileHeight = edgeFile == null ? 0.0f : edgeFile.getHeight(); - this.edgeUVWidth = 1f / 8f; - this.edgeUVHeight = 1f; - this.mirrored = mirrored; - this.backgroundSize -= (backgroundInsets.getX() + backgroundInsets.getY() + backgroundInsets.getZ() - + backgroundInsets.getW()) / 2f; - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - if (this.background != null) { - final float backgroundX = this.renderBounds.x + this.backgroundInsets.getX(); - final float backgroundY = this.renderBounds.y + this.backgroundInsets.getY(); - final float backgroundWidth = this.renderBounds.width - this.backgroundInsets.getX() - - this.backgroundInsets.getZ(); - final float backgroundHeight = this.renderBounds.height - this.backgroundInsets.getY() - - this.backgroundInsets.getW(); - if (this.tileBackground) { - final float backgroundVerticalRepeatCount = (backgroundHeight / this.backgroundSize); - final float backgroundHorizontalRepeatCount = backgroundWidth / this.backgroundSize; - final float backgroundHeightRemainder = backgroundHeight % this.backgroundSize; - final float backgroundHeightRemainderRatio = backgroundHeightRemainder / this.backgroundSize; - final float backgroundWidthRemainder = backgroundWidth % this.backgroundSize; - final float backgroundWidthRemainderRatio = backgroundWidthRemainder / this.backgroundSize; - final int backgroundVerticalFloorRepeatCount = (int) Math.floor(backgroundVerticalRepeatCount); - final int backgroundHorizontalFloorRepeatCount = (int) Math.floor(backgroundHorizontalRepeatCount); - for (int j = 0; j < backgroundVerticalFloorRepeatCount; j++) { - for (int i = 0; i < backgroundHorizontalFloorRepeatCount; i++) { - batch.draw(this.background, backgroundX + (i * this.backgroundSize), - backgroundY + (j * this.backgroundSize), this.backgroundSize, this.backgroundSize); - } - batch.draw(this.background, - backgroundX + ((backgroundHorizontalFloorRepeatCount) * this.backgroundSize), - backgroundY + (j * this.backgroundSize), backgroundWidthRemainder, this.backgroundSize, 0, - 1.0f, backgroundWidthRemainderRatio, 0); - } - for (int i = 0; i < backgroundHorizontalFloorRepeatCount; i++) { - batch.draw(this.background, backgroundX + (i * this.backgroundSize), - backgroundY + (backgroundVerticalFloorRepeatCount * this.backgroundSize), - this.backgroundSize, backgroundHeightRemainder, 0, 1.0f, 1.0f, - backgroundHeightRemainderRatio); - } - batch.draw(this.background, - backgroundX + ((backgroundHorizontalFloorRepeatCount) * this.backgroundSize), - backgroundY + (backgroundVerticalFloorRepeatCount * this.backgroundSize), - backgroundWidthRemainder, backgroundHeightRemainder, 0, 1.0f, backgroundWidthRemainderRatio, - backgroundHeightRemainderRatio); - } - else { - if (this.mirrored) { - batch.draw(this.background, backgroundX, backgroundY, backgroundWidth, backgroundHeight, 0, 0, - this.background.getWidth(), this.background.getHeight(), true, false); - } - else { - batch.draw(this.background, backgroundX, backgroundY, backgroundWidth, backgroundHeight); - } - } - } - if (this.edgeFile != null) { - if (this.cornerFlags.contains(BackdropCornerFlags.BL)) { - batch.draw(this.edgeFile, this.renderBounds.x, this.renderBounds.y, this.cornerSize, this.cornerSize, - this.edgeUVWidth * 6, this.edgeUVHeight, this.edgeUVWidth * 7, 0); - } - if (this.cornerFlags.contains(BackdropCornerFlags.BR)) { - batch.draw(this.edgeFile, (this.renderBounds.x + this.renderBounds.width) - this.cornerSize, - this.renderBounds.y, this.cornerSize, this.cornerSize, this.edgeUVWidth * 7, this.edgeUVHeight, - this.edgeUVWidth * 8, 0); - } - if (this.cornerFlags.contains(BackdropCornerFlags.UL)) { - batch.draw(this.edgeFile, this.renderBounds.x, - this.renderBounds.y + (this.renderBounds.height - this.cornerSize), this.cornerSize, - this.cornerSize, this.edgeUVWidth * 4, this.edgeUVHeight, this.edgeUVWidth * 5, 0); - } - if (this.cornerFlags.contains(BackdropCornerFlags.UR)) { - batch.draw(this.edgeFile, (this.renderBounds.x + this.renderBounds.width) - this.cornerSize, - this.renderBounds.y + (this.renderBounds.height - this.cornerSize), this.cornerSize, - this.cornerSize, this.edgeUVWidth * 5, this.edgeUVHeight, this.edgeUVWidth * 6, 0); - } - final float borderVerticalRepeatCount = (this.renderBounds.height / this.cornerSize); - final float heightRemainder = this.renderBounds.height % this.cornerSize; - final float heightRemainderRatio = heightRemainder / this.cornerSize; - final int borderVerticalRepeatCountLessOne = (int) (borderVerticalRepeatCount - 1); - if (this.cornerFlags.contains(BackdropCornerFlags.L)) { - for (int i = 1; i < borderVerticalRepeatCountLessOne; i++) { - batch.draw(this.edgeFile, this.renderBounds.x, this.renderBounds.y + (this.cornerSize * i), - this.cornerSize, this.cornerSize, this.edgeUVWidth * 0, this.edgeUVHeight, - this.edgeUVWidth * 1, 0); - } - if (borderVerticalRepeatCountLessOne > 0) { - batch.draw(this.edgeFile, this.renderBounds.x, - this.renderBounds.y + (this.cornerSize * borderVerticalRepeatCountLessOne), this.cornerSize, - heightRemainder, this.edgeUVWidth * 0, heightRemainderRatio, this.edgeUVWidth * 1, 0); - } - } - if (this.cornerFlags.contains(BackdropCornerFlags.R)) { - for (int i = 1; i < borderVerticalRepeatCountLessOne; i++) { - batch.draw(this.edgeFile, (this.renderBounds.x + this.renderBounds.width) - this.cornerSize, - this.renderBounds.y + (this.cornerSize * i), this.cornerSize, this.cornerSize, - this.edgeUVWidth * 1, this.edgeUVHeight, this.edgeUVWidth * 2, 0); - } - if (borderVerticalRepeatCountLessOne > 0) { - batch.draw(this.edgeFile, (this.renderBounds.x + this.renderBounds.width) - this.cornerSize, - this.renderBounds.y + (this.cornerSize * borderVerticalRepeatCountLessOne), this.cornerSize, - heightRemainder, this.edgeUVWidth * 1, heightRemainderRatio, this.edgeUVWidth * 2, 0); - } - } - - final float borderHorizontalRepeatCount = this.renderBounds.width / this.cornerSize; - final float widthRemainder = (this.renderBounds.width % this.cornerSize) / this.cornerSize; - final int widthRemainderByHeight = (int) (widthRemainder * this.edgeFileHeight); - final int widthRemainderByCornerSize = (int) (widthRemainder * this.cornerSize); - final int borderHorizontalRepeatCountLessOne = (int) (borderHorizontalRepeatCount - 1); - final float halfPi = 270; - if (this.cornerFlags.contains(BackdropCornerFlags.B)) { - for (int i = 1; i < borderHorizontalRepeatCountLessOne; i++) { - batch.draw(this.edgeFile, this.renderBounds.x + (this.cornerSize * i), this.renderBounds.y, - this.cornerSize / 2, this.cornerSize / 2, this.cornerSize, this.cornerSize, 1.0f, 1.0f, - halfPi, (int) ((this.edgeFileWidth * 3f) / 8f), 0, (int) (this.edgeFileWidth / 8), - (int) this.edgeFileHeight, false, false); - } - if (borderHorizontalRepeatCountLessOne > 0) { - batch.draw(this.edgeFile, - (this.renderBounds.x + (this.cornerSize * borderHorizontalRepeatCountLessOne)) - - ((this.cornerSize - widthRemainderByCornerSize) / 2), - this.renderBounds.y + ((this.cornerSize - widthRemainderByCornerSize) / 2), - this.cornerSize / 2, widthRemainderByCornerSize / 2, this.cornerSize, - widthRemainderByCornerSize, 1.0f, 1.0f, halfPi, (int) ((this.edgeFileWidth * 3f) / 8f), 0, - (int) (this.edgeFileWidth / 8), widthRemainderByHeight, false, false); - } - } - if (this.cornerFlags.contains(BackdropCornerFlags.T)) { - for (int i = 1; i < borderHorizontalRepeatCountLessOne; i++) { - batch.draw(this.edgeFile, this.renderBounds.x + (this.cornerSize * i), - this.renderBounds.y + (this.renderBounds.height - this.cornerSize), this.cornerSize / 2, - this.cornerSize / 2, this.cornerSize, this.cornerSize, 1.0f, 1.0f, halfPi, - (int) ((this.edgeFileWidth * 2f) / 8f), 0, (int) (this.edgeFileWidth / 8), - (int) this.edgeFileHeight, false, false); - } - if (borderHorizontalRepeatCountLessOne > 0) { - batch.draw(this.edgeFile, - (this.renderBounds.x + (this.cornerSize * borderHorizontalRepeatCountLessOne)) - - ((this.cornerSize - widthRemainderByCornerSize) / 2), - this.renderBounds.y - + (this.renderBounds.height - ((this.cornerSize + widthRemainderByCornerSize) / 2)), - this.cornerSize / 2, widthRemainderByCornerSize / 2, this.cornerSize, - widthRemainderByCornerSize, 1.0f, 1.0f, halfPi, (int) ((this.edgeFileWidth * 2f) / 8f), 0, - (int) (this.edgeFileWidth / 8), widthRemainderByHeight, false, false); - } - } - } - super.internalRender(batch, baseFont, glyphLayout); - } - - public float getCornerSize() { - return this.cornerSize; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/ControlFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/ControlFrame.java deleted file mode 100644 index dd6a3099..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/ControlFrame.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; - -public class ControlFrame extends AbstractRenderableFrame { - - private UIFrame controlBackdrop; - - public ControlFrame(final String name, final UIFrame parent) { - super(name, parent); - } - - public void setControlBackdrop(final UIFrame controlBackdrop) { - this.controlBackdrop = controlBackdrop; - } - - public UIFrame getControlBackdrop() { - return this.controlBackdrop; - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - this.controlBackdrop.positionBounds(gameUI, viewport); - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - this.controlBackdrop.render(batch, baseFont, glyphLayout); - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/EditBoxFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/EditBoxFrame.java deleted file mode 100644 index db1fbcd0..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/EditBoxFrame.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import com.badlogic.gdx.Input; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.utils.TimeUtils; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.FocusableFrame; - -public class EditBoxFrame extends AbstractRenderableFrame implements FocusableFrame { - - private UIFrame controlBackdrop; - private final float editBorderSize; - private final Color editCursorColor; - private StringFrame editTextFrame; - private boolean focused = false; - private int cursorIndex; - - // TODO design in such a way that references to these are not held !! very bad - // code design here - private GameUI gameUI; - private Viewport viewport; - private GlyphLayout glyphLayout; - private Runnable onChange; - - public EditBoxFrame(final String name, final UIFrame parent, final float editBorderSize, - final Color editCursorColor) { - super(name, parent); - this.editBorderSize = editBorderSize; - this.editCursorColor = editCursorColor; - } - - public void setControlBackdrop(final UIFrame controlBackdrop) { - this.controlBackdrop = controlBackdrop; - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - this.gameUI = gameUI; - this.viewport = viewport; - this.controlBackdrop.positionBounds(gameUI, viewport); - this.editTextFrame.positionBounds(gameUI, viewport); - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - this.glyphLayout = glyphLayout; - this.controlBackdrop.render(batch, baseFont, glyphLayout); - this.editTextFrame.render(batch, baseFont, glyphLayout); - if (this.focused) { - final long time = TimeUtils.millis(); - if ((time % 500) > 250) { - final BitmapFont frameFont = this.editTextFrame.getFrameFont(); - frameFont.setColor(this.editCursorColor); - final int cursorRenderPosition = Math.min(this.cursorIndex, this.editTextFrame.getText().length()); - this.cursorIndex = cursorRenderPosition; - glyphLayout.setText(frameFont, this.editTextFrame.getText().substring(0, cursorRenderPosition)); - final float cursorXOffset = glyphLayout.width; - glyphLayout.setText(frameFont, "|"); - frameFont.draw(batch, "|", - (this.editTextFrame.getFramePointX(FramePoint.LEFT) + cursorXOffset) - (glyphLayout.width / 2), - this.editTextFrame.getFramePointY(FramePoint.LEFT) + ((frameFont.getCapHeight()) / 2)); - } - } - } - - public void setEditTextFrame(final StringFrame editTextFrame) { - this.editTextFrame = editTextFrame; - } - - @Override - public boolean isFocusable() { - return true; - } - - @Override - public void onFocusGained() { - this.focused = true; - } - - @Override - public void onFocusLost() { - this.focused = false; - } - - @Override - public boolean keyDown(final int keycode) { - switch (keycode) { - case Input.Keys.LEFT: { - this.cursorIndex = Math.max(0, this.cursorIndex - 1); - break; - } - case Input.Keys.RIGHT: { - final String text = this.editTextFrame.getText(); - this.cursorIndex = Math.min(text.length(), this.cursorIndex + 1); - break; - } - case Input.Keys.BACKSPACE: { - final String prevText = this.editTextFrame.getText(); - final int prevTextLength = prevText.length(); - final int cursorIndex = Math.min(this.cursorIndex, prevTextLength); - if (cursorIndex >= 1) { - this.cursorIndex = cursorIndex - 1; - final String newText = prevText.substring(0, cursorIndex - 1) - + prevText.substring(cursorIndex, prevTextLength); - this.editTextFrame.setText(newText, this.gameUI, this.viewport); - if (this.onChange != null) { - this.onChange.run(); - } - } - break; - } - } - return false; - } - - @Override - public boolean keyUp(final int keycode) { - return false; - } - - @Override - public boolean keyTyped(final char character) { - if (Character.isAlphabetic(character) || Character.isDigit(character)) { - final String prevText = this.editTextFrame.getText(); - final int prevTextLength = prevText.length(); - final int cursorIndex = Math.min(this.cursorIndex, prevTextLength); - final String newText = prevText.substring(0, cursorIndex) + character - + prevText.substring(cursorIndex, prevTextLength); - this.editTextFrame.setText(newText, this.gameUI, this.viewport); - this.cursorIndex++; - if (this.onChange != null) { - this.onChange.run(); - } - } - return false; - } - - @Override - public UIFrame touchDown(final float screenX, final float screenY, final int button) { - if (isVisible() && this.renderBounds.contains(screenX, screenY)) { - - final String text = this.editTextFrame.getText(); - int indexFound = -1; - final float fpXOfEditText = this.editTextFrame.getFramePointX(FramePoint.LEFT); - float lastX = 0; - for (int i = 0; i < text.length(); i++) { - final BitmapFont frameFont = this.editTextFrame.getFrameFont(); - this.glyphLayout.setText(frameFont, this.editTextFrame.getText().substring(0, i)); - final float x = fpXOfEditText + this.glyphLayout.width; - if (((x + lastX) / 2) > screenX) { - indexFound = i - 1; - break; - } - lastX = x; - } - if (indexFound == -1) { - indexFound = text.length(); - } - this.cursorIndex = indexFound; - - return this; - } - return super.touchDown(screenX, screenY, button); - } - - public String getText() { - return this.editTextFrame.getText(); - } - - public void setOnChange(final Runnable onChange) { - this.onChange = onChange; - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/FilterModeTextureFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/FilterModeTextureFrame.java deleted file mode 100644 index 3b72c3a5..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/FilterModeTextureFrame.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.etheller.warsmash.parsers.fdf.datamodel.Vector4Definition; -import com.hiveworkshop.rms.parsers.mdlx.MdlxLayer.FilterMode; - -public class FilterModeTextureFrame extends TextureFrame { - private int blendSrc; - private int blendDst; - - public FilterModeTextureFrame(final String name, final UIFrame parent, final boolean decorateFileNames, - final Vector4Definition texCoord) { - super(name, parent, decorateFileNames, texCoord); - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - final int blendDstFunc = batch.getBlendDstFunc(); - final int blendSrcFunc = batch.getBlendSrcFunc(); - batch.setBlendFunction(this.blendSrc, this.blendDst); - super.internalRender(batch, baseFont, glyphLayout); - batch.setBlendFunction(blendSrcFunc, blendDstFunc); - } - - public void setFilterMode(final FilterMode filterMode) { - final int[] layerFilterMode = com.etheller.warsmash.viewer5.handlers.mdx.FilterMode.layerFilterMode(filterMode); - this.blendSrc = layerFilterMode[0]; - this.blendDst = layerFilterMode[1]; - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/FramePointAssignment.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/FramePointAssignment.java deleted file mode 100644 index 66706a71..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/FramePointAssignment.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; - -public interface FramePointAssignment { - float getX(GameUI gameUI, Viewport uiViewport); - - float getY(GameUI gameUI, Viewport uiViewport); -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/GlueButtonFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/GlueButtonFrame.java deleted file mode 100644 index f71be580..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/GlueButtonFrame.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.ClickableFrame; - -public class GlueButtonFrame extends AbstractRenderableFrame implements ClickableFrame { - private UIFrame controlBackdrop; - private UIFrame controlPushedBackdrop; - private UIFrame controlDisabledBackdrop; - private UIFrame controlMouseOverHighlight; - - private boolean enabled = true; - private boolean highlightOnMouseOver; - private boolean mouseOver = false; - - private UIFrame activeChild; - - private Runnable onClick; - - public GlueButtonFrame(final String name, final UIFrame parent) { - super(name, parent); - } - - public void setControlBackdrop(final UIFrame controlBackdrop) { - this.controlBackdrop = controlBackdrop; - if (this.activeChild == null) { - this.activeChild = controlBackdrop; - } - } - - public void setControlPushedBackdrop(final UIFrame controlPushedBackdrop) { - this.controlPushedBackdrop = controlPushedBackdrop; - } - - public void setControlDisabledBackdrop(final UIFrame controlDisabledBackdrop) { - this.controlDisabledBackdrop = controlDisabledBackdrop; - } - - public void setControlMouseOverHighlight(final UIFrame controlMouseOverHighlight) { - this.controlMouseOverHighlight = controlMouseOverHighlight; - } - - public void setEnabled(final boolean enabled) { - this.enabled = enabled; - if (this.enabled) { - this.activeChild = this.controlBackdrop; - } - else { - this.activeChild = this.controlDisabledBackdrop; - } - } - - public boolean isEnabled() { - return this.enabled; - } - - public void setHighlightOnMouseOver(final boolean highlightOnMouseOver) { - this.highlightOnMouseOver = highlightOnMouseOver; - } - - public void setOnClick(final Runnable onClick) { - this.onClick = onClick; - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - if (this.controlBackdrop != null) { - this.controlBackdrop.positionBounds(gameUI, viewport); - } - if (this.controlPushedBackdrop != null) { - this.controlPushedBackdrop.positionBounds(gameUI, viewport); - } - if (this.controlDisabledBackdrop != null) { - this.controlDisabledBackdrop.positionBounds(gameUI, viewport); - } - if (this.controlMouseOverHighlight != null) { - this.controlMouseOverHighlight.positionBounds(gameUI, viewport); - } - if (this.enabled) { - this.activeChild = this.controlBackdrop; - } - else { - this.activeChild = this.controlDisabledBackdrop; - } - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - if (this.activeChild != null) { - this.activeChild.render(batch, baseFont, glyphLayout); - } - if (this.mouseOver) { - this.controlMouseOverHighlight.render(batch, baseFont, glyphLayout); - } - } - - @Override - public void mouseDown(final GameUI gameUI, final Viewport uiViewport) { - if (this.enabled) { - this.activeChild = this.controlPushedBackdrop; - } - } - - @Override - public void mouseUp(final GameUI gameUI, final Viewport uiViewport) { - if (this.enabled) { - this.activeChild = this.controlBackdrop; - } - } - - @Override - public void mouseEnter(final GameUI gameUI, final Viewport uiViewport) { - if (this.highlightOnMouseOver) { - this.mouseOver = true; - onMouseEnter(); - } - } - - protected void onMouseEnter() { - } - - @Override - public void mouseExit(final GameUI gameUI, final Viewport uiViewport) { - this.mouseOver = false; - onMouseExit(); - } - - protected void onMouseExit() { - } - - @Override - public void onClick(final int button) { - if (this.onClick != null) { - this.onClick.run(); - } - } - - @Override - public UIFrame touchUp(final float screenX, final float screenY, final int button) { - if (isVisible() && this.enabled && this.renderBounds.contains(screenX, screenY)) { - return this; - } - return super.touchUp(screenX, screenY, button); - } - - @Override - public UIFrame touchDown(final float screenX, final float screenY, final int button) { - if (isVisible() && this.enabled && this.renderBounds.contains(screenX, screenY)) { - return this; - } - return super.touchDown(screenX, screenY, button); - } - - @Override - public UIFrame getFrameChildUnderMouse(final float screenX, final float screenY) { - if (isVisible() && this.enabled && this.renderBounds.contains(screenX, screenY)) { - return this; - } - return super.getFrameChildUnderMouse(screenX, screenY); - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/GlueTextButtonFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/GlueTextButtonFrame.java deleted file mode 100644 index fc0ba43d..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/GlueTextButtonFrame.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; - -public class GlueTextButtonFrame extends GlueButtonFrame { - private UIFrame buttonText; - - public GlueTextButtonFrame(final String name, final UIFrame parent) { - super(name, parent); - } - - public void setButtonText(final UIFrame buttonText) { - this.buttonText = buttonText; - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - super.innerPositionBounds(gameUI, viewport); - if (this.buttonText != null) { - this.buttonText.positionBounds(gameUI, viewport); - } - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - super.internalRender(batch, baseFont, glyphLayout); - if (this.buttonText != null) { - this.buttonText.render(batch, baseFont, glyphLayout); - } - } - - @Override - public void setEnabled(final boolean enabled) { - super.setEnabled(enabled); - if (this.buttonText instanceof StringFrame) { - final StringFrame stringButtonText = (StringFrame) this.buttonText; - final Color fontColor = enabled ? stringButtonText.getFontOriginalColor() - : stringButtonText.getFontDisabledColor(); - if (fontColor != null) { - stringButtonText.setColor(fontColor); - } - } - } - - @Override - protected void onMouseEnter() { - super.onMouseEnter(); - if (isEnabled()) { - if (this.buttonText instanceof StringFrame) { - final StringFrame stringFrame = (StringFrame) this.buttonText; - final Color fontHighlightColor = stringFrame.getFontHighlightColor(); - if (fontHighlightColor != null) { - stringFrame.setColor(fontHighlightColor); - } - } - } - } - - @Override - protected void onMouseExit() { - super.onMouseExit(); - if (isEnabled()) { - if (this.buttonText instanceof StringFrame) { - final StringFrame stringFrame = (StringFrame) this.buttonText; - final Color fontOriginalColor = stringFrame.getFontOriginalColor(); - if (fontOriginalColor != null) { - stringFrame.setColor(fontOriginalColor); - } - } - } - } -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/ListBoxFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/ListBoxFrame.java deleted file mode 100644 index 3816045d..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/ListBoxFrame.java +++ /dev/null @@ -1,202 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Pixmap.Format; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; -import com.etheller.warsmash.parsers.fdf.datamodel.TextJustify; - -public class ListBoxFrame extends ControlFrame { - // TODO where are these colors in the UI definition files? - private static final Color SELECT_COLOR = Color.BLUE; - private static final Color MOUSE_OVER_HIGHLIGHT_COLOR = new Color(0.3f, 0.3f, 1.0f, 0.25f); - - private final List listItems = new ArrayList<>(); - private final List stringFrames = new ArrayList<>(); - private BitmapFont frameFont; - private float listBoxBorder; - private int selectedIndex = -1; - private int mouseOverIndex = -1; - - private final TextureFrame selectionFrame; - private final TextureFrame mouseHighlightFrame; - private GameUI gameUI; - private Viewport viewport; - private Runnable onSelect; - - public ListBoxFrame(final String name, final UIFrame parent, final Viewport viewport) { - super(name, parent); - this.listBoxBorder = GameUI.convertX(viewport, 0.01f); - this.selectionFrame = new TextureFrame(null, this, false, null); - this.mouseHighlightFrame = new TextureFrame(null, this, false, null); - final Pixmap pixmap = new Pixmap(1, 1, Format.RGBA8888); - pixmap.setColor(SELECT_COLOR); - pixmap.fill(); - this.selectionFrame.setTexture(new Texture(pixmap)); - final Pixmap mousePixmap = new Pixmap(1, 1, Format.RGBA8888); - mousePixmap.setColor(MOUSE_OVER_HIGHLIGHT_COLOR); - mousePixmap.fill(); - this.mouseHighlightFrame.setTexture(new Texture(mousePixmap)); - } - - public void setListBoxBorder(final float listBoxBorder) { - this.listBoxBorder = listBoxBorder; - } - - public float getListBoxBorder() { - return this.listBoxBorder; - } - - public void setFrameFont(final BitmapFont frameFont) { - this.frameFont = frameFont; - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - this.gameUI = gameUI; - this.viewport = viewport; - super.innerPositionBounds(gameUI, viewport); - updateUI(gameUI, viewport); - } - - private void positionChildren(final GameUI gameUI, final Viewport viewport) { - for (final SingleStringFrame frame : this.stringFrames) { - frame.positionBounds(gameUI, viewport); - } - this.selectionFrame.positionBounds(gameUI, viewport); - this.mouseHighlightFrame.positionBounds(gameUI, viewport); - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - super.internalRender(batch, baseFont, glyphLayout); - this.selectionFrame.render(batch, baseFont, glyphLayout); - this.mouseHighlightFrame.render(batch, baseFont, glyphLayout); - for (final SingleStringFrame frame : this.stringFrames) { - frame.render(batch, baseFont, glyphLayout); - } - } - - public void addItem(final String item, final GameUI gameUI, final Viewport viewport) { - this.listItems.add(item); - updateUI(gameUI, viewport); - } - - public void setItems(final List items, final GameUI gameUI, final Viewport viewport) { - this.listItems.clear(); - this.listItems.addAll(items); - updateUI(gameUI, viewport); - } - - public void removeItem(final String item, final GameUI gameUI, final Viewport viewport) { - this.listItems.remove(item); - updateUI(gameUI, viewport); - } - - public void removeItem(final int index, final GameUI gameUI, final Viewport viewport) { - this.listItems.remove(index); - updateUI(gameUI, viewport); - } - - public void setSelectedIndex(final int selectedIndex) { - this.selectedIndex = selectedIndex; - } - - public int getSelectedIndex() { - return this.selectedIndex; - } - - private void updateUI(final GameUI gameUI, final Viewport viewport) { - this.stringFrames.clear(); - SingleStringFrame prev = null; - int i = 0; - boolean foundSelected = false; - boolean foundMouseOver = false; - for (final String string : this.listItems) { - final boolean selected = (i == this.selectedIndex); - final boolean mousedOver = (i == this.mouseOverIndex); - final SingleStringFrame stringFrame = new SingleStringFrame("LISTY" + i++, this, Color.WHITE, - TextJustify.LEFT, TextJustify.MIDDLE, this.frameFont); - stringFrame.setText(string); - stringFrame.setWidth(this.renderBounds.width - (this.listBoxBorder * 2)); - stringFrame.setHeight(this.frameFont.getLineHeight()); - if (prev != null) { - stringFrame.addSetPoint(new SetPoint(FramePoint.TOPLEFT, prev, FramePoint.BOTTOMLEFT, 0, 0)); - } - else { - stringFrame.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this, FramePoint.TOPLEFT, this.listBoxBorder, - -this.listBoxBorder)); - } - this.stringFrames.add(stringFrame); - prev = stringFrame; - if (selected) { - this.selectionFrame - .addSetPoint(new SetPoint(FramePoint.TOPLEFT, stringFrame, FramePoint.TOPLEFT, 0, 0)); - this.selectionFrame - .addSetPoint(new SetPoint(FramePoint.BOTTOMRIGHT, stringFrame, FramePoint.BOTTOMRIGHT, 0, 0)); - foundSelected = true; - } - else if (mousedOver) { - this.mouseHighlightFrame - .addSetPoint(new SetPoint(FramePoint.TOPLEFT, stringFrame, FramePoint.TOPLEFT, 0, 0)); - this.mouseHighlightFrame - .addSetPoint(new SetPoint(FramePoint.BOTTOMRIGHT, stringFrame, FramePoint.BOTTOMRIGHT, 0, 0)); - foundMouseOver = true; - } - } - this.selectionFrame.setVisible(foundSelected); - this.mouseHighlightFrame.setVisible(foundMouseOver); - positionChildren(gameUI, viewport); - } - - @Override - public UIFrame touchDown(final float screenX, final float screenY, final int button) { - if (isVisible() && this.renderBounds.contains(screenX, screenY)) { - int index = 0; - for (final SingleStringFrame stringFrame : this.stringFrames) { - if (stringFrame.getRenderBounds().contains(screenX, screenY)) { - this.selectedIndex = index; - } - index++; - } - updateUI(this.gameUI, this.viewport); - if (this.onSelect != null) { - this.onSelect.run(); - } - return this; - } - return super.touchDown(screenX, screenY, button); - } - - @Override - public UIFrame getFrameChildUnderMouse(final float screenX, final float screenY) { - if (isVisible() && this.renderBounds.contains(screenX, screenY)) { - int index = 0; - int mouseOverIndex = -1; - for (final SingleStringFrame stringFrame : this.stringFrames) { - if (stringFrame.getRenderBounds().contains(screenX, screenY)) { - mouseOverIndex = index; - } - index++; - } - if (this.mouseOverIndex != mouseOverIndex) { - this.mouseOverIndex = mouseOverIndex; - updateUI(this.gameUI, this.viewport); - } - } - return super.getFrameChildUnderMouse(screenX, screenY); - } - - public void setOnSelect(final Runnable onSelect) { - this.onSelect = onSelect; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/SetPoint.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/SetPoint.java deleted file mode 100644 index f8ff31e6..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/SetPoint.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; - -public class SetPoint implements FramePointAssignment { - private final FramePoint myPoint; - private final UIFrame other; - private final FramePoint otherPoint; - private final float x; - private final float y; - - public SetPoint(final FramePoint myPoint, final UIFrame other, final FramePoint otherPoint, final float x, - final float y) { - this.myPoint = myPoint; - this.other = other; - this.otherPoint = otherPoint; - this.x = x; - this.y = y; - } - - public FramePoint getMyPoint() { - return this.myPoint; - } - - public UIFrame getOther() { - return this.other; - } - - public FramePoint getOtherPoint() { - return this.otherPoint; - } - - public float getX() { - return this.x; - } - - public float getY() { - return this.y; - } - - @Override - public float getX(final GameUI gameUI, final Viewport uiViewport) { - return this.other.getFramePointX(this.otherPoint) + this.x; - } - - @Override - public float getY(final GameUI gameUI, final Viewport uiViewport) { - return this.other.getFramePointY(this.otherPoint) + this.y; - } - - @Override - public String toString() { - return "SetPoint [myPoint=" + this.myPoint + ", other=" + this.other + ", otherPoint=" + this.otherPoint - + ", x=" + this.x + ", y=" + this.y + "]"; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/SimpleButtonFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/SimpleButtonFrame.java deleted file mode 100644 index 610a8c83..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/SimpleButtonFrame.java +++ /dev/null @@ -1,217 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.ClickableFrame; - -public class SimpleButtonFrame extends AbstractRenderableFrame implements ClickableFrame { - - private UIFrame controlBackdrop; - private UIFrame controlPushedBackdrop; - private UIFrame controlDisabledBackdrop; - private UIFrame controlMouseOverHighlight; - - private boolean enabled = true; - private boolean highlightOnMouseOver; - private boolean mouseOver = false; - private boolean pushed = false; - - private UIFrame activeChild; - private UIFrame activeTextChild; - - private UIFrame buttonText; - private UIFrame disabledText; - private UIFrame highlightText; - - private UIFrame pushedText; - private UIFrame pushedHighlightText; - - private Runnable onClick; - - public SimpleButtonFrame(final String name, final UIFrame parent) { - super(name, parent); - } - - public void setControlBackdrop(final UIFrame controlBackdrop) { - this.controlBackdrop = controlBackdrop; - if (this.activeChild == null) { - this.activeChild = controlBackdrop; - } - } - - public void setControlPushedBackdrop(final UIFrame controlPushedBackdrop) { - this.controlPushedBackdrop = controlPushedBackdrop; - } - - public void setControlDisabledBackdrop(final UIFrame controlDisabledBackdrop) { - this.controlDisabledBackdrop = controlDisabledBackdrop; - } - - public void setControlMouseOverHighlight(final UIFrame controlMouseOverHighlight) { - this.controlMouseOverHighlight = controlMouseOverHighlight; - this.highlightOnMouseOver |= controlMouseOverHighlight != null; - } - - public void setEnabled(final boolean enabled) { - this.enabled = enabled; - if (this.enabled) { - this.activeChild = this.controlBackdrop; - this.activeTextChild = this.buttonText; - } - else { - this.activeChild = this.controlDisabledBackdrop; - this.activeTextChild = this.disabledText; - } - } - - public void setHighlightOnMouseOver(final boolean highlightOnMouseOver) { - this.highlightOnMouseOver = highlightOnMouseOver; - } - - public void setOnClick(final Runnable onClick) { - this.onClick = onClick; - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - if (this.controlBackdrop != null) { - this.controlBackdrop.positionBounds(gameUI, viewport); - } - if (this.controlPushedBackdrop != null) { - this.controlPushedBackdrop.positionBounds(gameUI, viewport); - } - if (this.controlDisabledBackdrop != null) { - this.controlDisabledBackdrop.positionBounds(gameUI, viewport); - } - if (this.controlMouseOverHighlight != null) { - this.controlMouseOverHighlight.positionBounds(gameUI, viewport); - } - if (this.buttonText != null) { - this.buttonText.positionBounds(gameUI, viewport); - } - if (this.pushedText != null) { - this.pushedText.positionBounds(gameUI, viewport); - } - if (this.disabledText != null) { - this.disabledText.positionBounds(gameUI, viewport); - } - if (this.highlightText != null) { - this.highlightText.positionBounds(gameUI, viewport); - } - if (this.pushedHighlightText != null) { - this.pushedHighlightText.positionBounds(gameUI, viewport); - } - if (this.enabled) { - this.activeChild = this.controlBackdrop; - this.activeTextChild = this.buttonText; - } - else { - this.activeChild = this.controlDisabledBackdrop; - this.activeTextChild = this.disabledText; - } - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - if (this.activeChild != null) { - this.activeChild.render(batch, baseFont, glyphLayout); - } - if (this.activeTextChild != null) { - this.activeTextChild.render(batch, baseFont, glyphLayout); - } - if (this.mouseOver) { - this.controlMouseOverHighlight.render(batch, baseFont, glyphLayout); - } - } - - @Override - public void mouseDown(final GameUI gameUI, final Viewport uiViewport) { - if (this.enabled) { - this.activeChild = this.controlPushedBackdrop; - this.pushed = true; - this.activeTextChild = this.mouseOver ? this.pushedHighlightText : this.pushedText; - } - } - - @Override - public void mouseUp(final GameUI gameUI, final Viewport uiViewport) { - if (this.enabled) { - this.activeChild = this.controlBackdrop; - this.activeTextChild = this.mouseOver ? this.highlightText : this.buttonText; - } - this.pushed = false; - } - - @Override - public void mouseEnter(final GameUI gameUI, final Viewport uiViewport) { - if (this.highlightOnMouseOver) { - this.mouseOver = true; - if (this.enabled) { - this.activeTextChild = this.pushed ? this.pushedHighlightText : this.highlightText; - } - } - } - - @Override - public void mouseExit(final GameUI gameUI, final Viewport uiViewport) { - this.mouseOver = false; - if (this.enabled) { - this.activeTextChild = this.pushed ? this.pushedText : this.buttonText; - } - } - - @Override - public void onClick(final int button) { - if (this.onClick != null) { - this.onClick.run(); - } - } - - @Override - public UIFrame touchUp(final float screenX, final float screenY, final int button) { - if (isVisible() && this.enabled && this.renderBounds.contains(screenX, screenY)) { - return this; - } - return super.touchUp(screenX, screenY, button); - } - - @Override - public UIFrame touchDown(final float screenX, final float screenY, final int button) { - if (isVisible() && this.enabled && this.renderBounds.contains(screenX, screenY)) { - return this; - } - return super.touchDown(screenX, screenY, button); - } - - @Override - public UIFrame getFrameChildUnderMouse(final float screenX, final float screenY) { - if (isVisible() && this.enabled && this.renderBounds.contains(screenX, screenY)) { - return this; - } - return super.getFrameChildUnderMouse(screenX, screenY); - } - - public void setButtonText(final UIFrame buttonText) { - this.buttonText = buttonText; - } - - public void setPushedHighlightText(final UIFrame pushedHighlightText) { - this.pushedHighlightText = pushedHighlightText; - } - - public void setPushedText(final UIFrame pushedText) { - this.pushedText = pushedText; - } - - public void setHighlightText(final UIFrame highlightText) { - this.highlightText = highlightText; - this.highlightOnMouseOver |= highlightText != null; - } - - public void setDisabledText(final UIFrame disabledText) { - this.disabledText = disabledText; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/SimpleFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/SimpleFrame.java deleted file mode 100644 index b90dd097..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/SimpleFrame.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -public class SimpleFrame extends AbstractUIFrame { - - public SimpleFrame(final String name, final UIFrame parent) { - super(name, parent); - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/SimpleStatusBarFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/SimpleStatusBarFrame.java deleted file mode 100644 index 4fad3cc4..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/SimpleStatusBarFrame.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; -import com.etheller.warsmash.parsers.fdf.datamodel.Vector4Definition; - -public class SimpleStatusBarFrame extends AbstractUIFrame { - private final boolean decorateFileNames; - private final TextureFrame barFrame; - private final TextureFrame borderFrame; - private final float barInset; - - public SimpleStatusBarFrame(final String name, final UIFrame parent, final boolean decorateFileNames, - final boolean borderBelow, final float barInset) { - super(name, parent); - this.decorateFileNames = decorateFileNames; - this.barInset = barInset; - this.barFrame = new TextureFrame(name + "Bar", this, decorateFileNames, new Vector4Definition(0, 1, 0, 1)); - this.borderFrame = new TextureFrame(name + "Border", this, decorateFileNames, - new Vector4Definition(0, 1, 0, 1)); - this.borderFrame.setSetAllPoints(true); - this.barFrame.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this, FramePoint.TOPLEFT, barInset, -barInset)); - this.barFrame.addSetPoint(new SetPoint(FramePoint.BOTTOMLEFT, this, FramePoint.BOTTOMLEFT, barInset, barInset)); - this.barFrame.setSetAllPoints(true, barInset); - if (borderBelow) { - add(this.borderFrame); - add(this.barFrame); - } - else { - add(this.barFrame); - add(this.borderFrame); - } - } - - public boolean isDecorateFileNames() { - return this.decorateFileNames; - } - - public void setValue(final float value) { - this.barFrame.setTexCoord(0, value, 0, 1); - this.barFrame.setWidth(((this.renderBounds.width - (this.barInset * 2)) * value)); - } - - public TextureFrame getBarFrame() { - return this.barFrame; - } - - public TextureFrame getBorderFrame() { - return this.borderFrame; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/SingleStringFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/SingleStringFrame.java deleted file mode 100644 index b6968d49..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/SingleStringFrame.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.TextJustify; - -public class SingleStringFrame extends AbstractRenderableFrame { - private Color color; - private String text = "Default string"; - private final TextJustify justifyH; - private final TextJustify justifyV; - private final BitmapFont frameFont; - private Color fontShadowColor; - private float fontShadowOffsetX; - private float fontShadowOffsetY; - private float alpha = 1.0f; - - public SingleStringFrame(final String name, final UIFrame parent, final Color color, final TextJustify justifyH, - final TextJustify justifyV, final BitmapFont frameFont) { - super(name, parent); - this.color = color; - this.justifyH = justifyH; - this.justifyV = justifyV; - this.frameFont = frameFont; - this.text = name; - } - - public void setText(final String text) { - if (text == null) { - throw new IllegalArgumentException(); - } - this.text = text; - } - - public void setColor(final Color color) { - this.color = color; - } - - public Color getColor() { - return this.color; - } - - public void setFontShadowColor(final Color fontShadowColor) { - this.fontShadowColor = fontShadowColor; - } - - public void setFontShadowOffsetX(final float fontShadowOffsetX) { - this.fontShadowOffsetX = fontShadowOffsetX; - } - - public void setFontShadowOffsetY(final float fontShadowOffsetY) { - this.fontShadowOffsetY = fontShadowOffsetY; - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - glyphLayout.setText(this.frameFont, this.text); - final float x; - switch (this.justifyH) { - case CENTER: - x = this.renderBounds.x + ((this.renderBounds.width - glyphLayout.width) / 2); - break; - case RIGHT: - x = (this.renderBounds.x + this.renderBounds.width) - glyphLayout.width; - break; - case LEFT: - default: - x = this.renderBounds.x; - break; - } - final float y; - switch (this.justifyV) { - case MIDDLE: - y = this.renderBounds.y + ((this.renderBounds.height + this.frameFont.getLineHeight()) / 2); - break; - case TOP: - y = (this.renderBounds.y + this.renderBounds.height); - break; - case BOTTOM: - default: - y = this.renderBounds.y + this.frameFont.getLineHeight(); - break; - } - if (this.fontShadowColor != null) { - this.frameFont.setColor(this.fontShadowColor.r, this.fontShadowColor.g, this.fontShadowColor.b, - this.fontShadowColor.a * this.alpha); - this.frameFont.draw(batch, this.text, x + this.fontShadowOffsetX, y + this.fontShadowOffsetY); - } - this.frameFont.setColor(this.color.r, this.color.g, this.color.b, this.color.a * this.alpha); - this.frameFont.draw(batch, this.text, x, y); - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - } - - public void setAlpha(final float alpha) { - this.alpha = alpha; - - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/SmartBackdropFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/SmartBackdropFrame.java deleted file mode 100644 index d7ea5758..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/SmartBackdropFrame.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import java.util.EnumSet; - -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.BackdropCornerFlags; -import com.etheller.warsmash.parsers.fdf.datamodel.Vector4Definition; -import com.etheller.warsmash.viewer5.Scene; -import com.hiveworkshop.rms.parsers.mdlx.MdlxGeoset; -import com.hiveworkshop.rms.parsers.mdlx.MdlxLayer; -import com.hiveworkshop.rms.parsers.mdlx.MdlxLayer.FilterMode; -import com.hiveworkshop.rms.parsers.mdlx.MdlxMaterial; -import com.hiveworkshop.rms.parsers.mdlx.MdlxModel; -import com.hiveworkshop.rms.parsers.mdlx.MdlxTexture; -import com.hiveworkshop.rms.parsers.mdlx.MdlxTexture.WrapMode; - -public class SmartBackdropFrame extends SpriteFrame { - private final boolean decorateFileNames; - private final boolean tileBackground; - private final String backgroundString; - private final EnumSet cornerFlags; - private final float cornerSize; - private final float backgroundSize; - private final Vector4Definition backgroundInsets; - private final String edgeFileString; - - public SmartBackdropFrame(final String name, final UIFrame parent, final Scene scene, final Viewport uiViewport, - final boolean decorateFileNames, final boolean tileBackground, final String backgroundString, - final EnumSet cornerFlags, final float cornerSize, final float backgroundSize, - final Vector4Definition backgroundInsets, final String edgeFileString) { - super(name, parent, scene, uiViewport); - this.decorateFileNames = decorateFileNames; - this.tileBackground = tileBackground; - this.backgroundString = backgroundString; - this.cornerFlags = cornerFlags; - this.cornerSize = cornerSize; - this.backgroundSize = backgroundSize; - this.backgroundInsets = backgroundInsets; - this.edgeFileString = edgeFileString; - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - generateBackdropModel(); - super.innerPositionBounds(gameUI, viewport); - } - - private MdlxModel generateBackdropModel() { - final MdlxModel model = new MdlxModel(); - final int edgeFileMaterialId = generateMaterial(model, this.edgeFileString, true); - final int backgroundMaterialId = generateMaterial(model, this.backgroundString, this.tileBackground); - final MdlxGeoset edgeGeoset = new MdlxGeoset(); - final float[] edgeGeosetVertices = new float[32 * 4]; - return model; - } - - private int generateMaterial(final MdlxModel model, final String path, final boolean wrap) { - final MdlxTexture edgeFileReference = new MdlxTexture(); - if (wrap) { - edgeFileReference.setWrapMode(WrapMode.REPEAT_BOTH); - } - edgeFileReference.setPath(path); - final int textureId = model.getTextures().size(); - model.getTextures().add(edgeFileReference); - final MdlxMaterial edgeFileMaterial = new MdlxMaterial(); - final MdlxLayer edgeFileMaterialLayer = new MdlxLayer(); - edgeFileMaterialLayer.setAlpha(1.0f); - edgeFileMaterialLayer.setFilterMode(FilterMode.BLEND); - edgeFileMaterialLayer.setTextureId(textureId); - edgeFileMaterial.getLayers().add(edgeFileMaterialLayer); - final int materialId = model.getMaterials().size(); - model.getMaterials().add(edgeFileMaterial); - return materialId; - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/SpriteFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/SpriteFrame.java deleted file mode 100644 index 79e32f28..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/SpriteFrame.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; - -public class SpriteFrame extends AbstractUIFrame { - - protected final Scene scene; - protected final Viewport uiViewport; - private MdxComplexInstance instance; - private float zDepth; - - public SpriteFrame(final String name, final UIFrame parent, final Scene scene, final Viewport uiViewport) { - super(name, parent); - this.scene = scene; - this.uiViewport = uiViewport; - } - - public void setModel(final MdxModel model) { - if (this.instance != null) { - this.scene.removeInstance(this.instance); - } - if (model != null) { - this.instance = (MdxComplexInstance) model.addInstance(); - this.instance.setSequenceLoopMode(SequenceLoopMode.MODEL_LOOP); - this.instance.setScene(this.scene); - this.instance.setLocation(this.renderBounds.x, this.renderBounds.y, this.zDepth); - } - else { - this.instance = null; - } - } - - @Override - public void setVisible(final boolean visible) { - super.setVisible(visible); - updateInstanceLocation(this.uiViewport); - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - super.internalRender(batch, baseFont, glyphLayout); - } - - @Override - public void setFramePointX(final FramePoint framePoint, final float x) { - super.setFramePointX(framePoint, x); - updateInstanceLocation(this.uiViewport); - } - - @Override - public void setFramePointY(final FramePoint framePoint, final float y) { - super.setFramePointY(framePoint, y); - updateInstanceLocation(this.uiViewport); - } - - public void setZDepth(final float depth) { - this.zDepth = depth; - updateInstanceLocation(this.uiViewport); - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - super.innerPositionBounds(gameUI, viewport); - updateInstanceLocation(viewport); - } - - public void setSequence(final int index) { - if (this.instance != null) { - this.instance.setSequence(index); - } - } - - public void setSequence(final String animationName) { - if (this.instance != null) { - SequenceUtils.randomSequence(this.instance, animationName.toLowerCase()); - } - } - - public void setSequence(final PrimaryTag animationName) { - if (this.instance != null) { - SequenceUtils.randomSequence(this.instance, animationName); - } - } - - public void setAnimationSpeed(final float speedRatio) { - if (this.instance != null) { - this.instance.setAnimationSpeed(speedRatio); - } - } - - public void setFrame(final int animationFrame) { - if (this.instance != null) { - this.instance.setFrame(animationFrame); - } - } - - public void setFrameByRatio(final float ratioOfAnimationCompleted) { - if (this.instance != null) { - this.instance.setFrameByRatio(ratioOfAnimationCompleted); - } - } - - private void updateInstanceLocation(final Viewport viewport) { - if (this.instance != null) { - this.instance.setLocation(GameUI.unconvertX(viewport, this.renderBounds.x), - GameUI.unconvertY(viewport, this.renderBounds.y), this.zDepth); - if (isVisible()) { - this.instance.show(); - } - else { - this.instance.hide(); - } - } - } - - public boolean isSequenceEnded() { - return this.instance.sequenceEnded; - } - - public void setReplaceableId(final int replaceableId, final String blpPath) { - if (this.instance != null) { - this.instance.setReplaceableTexture(replaceableId, blpPath); - } - - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/StringFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/StringFrame.java deleted file mode 100644 index 11cfeb17..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/StringFrame.java +++ /dev/null @@ -1,496 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.AnchorDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; -import com.etheller.warsmash.parsers.fdf.datamodel.TextJustify; - -public class StringFrame extends AbstractRenderableFrame { - private final List internalFrames = new ArrayList<>(); - private Color color; - private String text = "Default string"; - private final TextJustify justifyH; - private final TextJustify justifyV; - private final BitmapFont frameFont; - private Color fontShadowColor; - private float fontShadowOffsetX; - private float fontShadowOffsetY; - private float alpha = 1.0f; - private final SimpleFrame internalFramesContainer; - private float predictedViewportHeight; - - static ShapeRenderer shapeRenderer = new ShapeRenderer(); - private final Color fontHighlightColor; - private final Color fontDisabledColor; - private final Color fontColor; - - public StringFrame(final String name, final UIFrame parent, final Color color, final TextJustify justifyH, - final TextJustify justifyV, final BitmapFont frameFont, final String text, final Color fontHighlightColor, - final Color fontDisabledColor) { - super(name, parent); - this.fontColor = color; - this.color = color; - this.justifyH = justifyH; - this.justifyV = justifyV; - this.frameFont = frameFont; - this.text = text; - this.fontHighlightColor = fontHighlightColor; - this.fontDisabledColor = fontDisabledColor; - this.internalFramesContainer = new SimpleFrame(null, this); - } - - public String getText() { - return this.text; - } - - public void setText(final String text, final GameUI gameUI, final Viewport viewport) { - if (text == null) { - throw new IllegalArgumentException(); - } - this.text = text; - positionBounds(gameUI, viewport); - } - - public void setColor(final Color color) { - for (final SingleStringFrame internalFrame : this.internalFrames) { - if (internalFrame.getColor() == this.color) { - internalFrame.setColor(color); - } - } - this.color = color; - } - - public Color getColor() { - return this.color; - } - - public Color getFontOriginalColor() { - return this.fontColor; - } - - public Color getFontDisabledColor() { - return this.fontDisabledColor; - } - - public Color getFontHighlightColor() { - return this.fontHighlightColor; - } - - public void setFontShadowColor(final Color fontShadowColor) { - this.fontShadowColor = fontShadowColor; - for (final SingleStringFrame internalFrame : this.internalFrames) { - internalFrame.setFontShadowColor(fontShadowColor); - } - } - - public void setFontShadowOffsetX(final float fontShadowOffsetX) { - this.fontShadowOffsetX = fontShadowOffsetX; - for (final SingleStringFrame internalFrame : this.internalFrames) { - internalFrame.setFontShadowOffsetX(fontShadowOffsetX); - } - } - - public void setFontShadowOffsetY(final float fontShadowOffsetY) { - this.fontShadowOffsetY = fontShadowOffsetY; - for (final SingleStringFrame internalFrame : this.internalFrames) { - internalFrame.setFontShadowOffsetY(fontShadowOffsetY); - } - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - this.internalFramesContainer.render(batch, baseFont, glyphLayout); - - if (GameUI.DEBUG) { - batch.end(); - shapeRenderer.setProjectionMatrix(batch.getProjectionMatrix()); - shapeRenderer.setColor(1f, 1f, 1f, 1f); - shapeRenderer.begin(ShapeType.Line); - shapeRenderer.rect(this.renderBounds.x, this.renderBounds.y, this.renderBounds.width, - this.renderBounds.height); - - shapeRenderer.end(); - - batch.begin(); - } - } - - @Override - public void positionBounds(final GameUI gameUI, final Viewport viewport) { - createInternalFrames(gameUI.getGlyphLayout()); - if (this.renderBounds.height == 0) { - this.renderBounds.height = getPredictedViewportHeight(); - } - super.positionBounds(gameUI, viewport); - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - this.internalFramesContainer.positionBounds(gameUI, viewport); - } - - private void createInternalFrames(final GlyphLayout glyphLayout) { - for (final SingleStringFrame internalFrame : this.internalFrames) { - this.internalFramesContainer.remove(internalFrame); - } - this.internalFrames.clear(); - final StringBuilder currentLine = new StringBuilder(); - final StringBuilder currentWord = new StringBuilder(); - float currentXCoordForWord = 0; - float currentXCoordForFrames = 0; - final float usedWidth = 0; - float usedHeight = 0; - float usedWidthMax = 0; - final float startingBoundsWidth = this.renderBounds.width; - final boolean firstInLine = false; - Color currentColor = this.color; - for (int i = 0; i < this.text.length(); i++) { - final char c = this.text.charAt(i); - switch (c) { - case '|': { - // special control character - if ((i + 1) < this.text.length()) { - final char escapedCharacter = this.text.charAt(i + 1); - switch (escapedCharacter) { - case 'c': - case 'C': - if ((i + 9) < this.text.length()) { - int colorInt; - try { - final String upperCase = this.text.substring(i + 2, i + 10).toUpperCase(); - colorInt = (int) Long.parseLong(upperCase, 16); - } - catch (final NumberFormatException exc) { - currentWord.append(c); - break; - } - i += 9; - { - final String wordString = currentWord.toString(); - currentWord.setLength(0); - glyphLayout.setText(this.frameFont, wordString); - final float wordWidth = glyphLayout.width; - if ((startingBoundsWidth > 0) - && ((currentXCoordForWord + wordWidth) >= startingBoundsWidth)) { - final String currentLineString = currentLine.toString(); - currentLine.setLength(0); - glyphLayout.setText(this.frameFont, currentLineString); - usedWidthMax = Math.max(currentXCoordForFrames + glyphLayout.width, usedWidthMax); - final SingleStringFrame singleStringFrame = new SingleStringFrame(currentLineString, - this.internalFramesContainer, currentColor, TextJustify.LEFT, - TextJustify.TOP, this.frameFont); - singleStringFrame.setHeight(this.frameFont.getLineHeight()); - singleStringFrame.setWidth(glyphLayout.width); - singleStringFrame.setAlpha(this.alpha); - singleStringFrame.setFontShadowColor(this.fontShadowColor); - singleStringFrame.setFontShadowOffsetX(this.fontShadowOffsetX); - singleStringFrame.setFontShadowOffsetY(this.fontShadowOffsetY); - singleStringFrame.addAnchor(new AnchorDefinition(FramePoint.TOPLEFT, - currentXCoordForFrames, usedHeight)); - this.internalFrames.add(singleStringFrame); - usedHeight += this.frameFont.getLineHeight(); - currentXCoordForWord = 0; - currentXCoordForFrames = 0; - } - currentXCoordForWord += wordWidth; - currentLine.append(wordString); - - final String currentLineString = currentLine.toString(); - currentLine.setLength(0); - glyphLayout.setText(this.frameFont, currentLineString); - usedWidthMax = Math.max(currentXCoordForFrames + glyphLayout.width, usedWidthMax); - final SingleStringFrame singleStringFrame = new SingleStringFrame(currentLineString, - this.internalFramesContainer, currentColor, TextJustify.LEFT, TextJustify.TOP, - this.frameFont); - singleStringFrame.setHeight(this.frameFont.getLineHeight()); - singleStringFrame.setWidth(glyphLayout.width); - singleStringFrame.setAlpha(this.alpha); - singleStringFrame.setFontShadowColor(this.fontShadowColor); - singleStringFrame.setFontShadowOffsetX(this.fontShadowOffsetX); - singleStringFrame.setFontShadowOffsetY(this.fontShadowOffsetY); - singleStringFrame.addAnchor( - new AnchorDefinition(FramePoint.TOPLEFT, currentXCoordForFrames, -usedHeight)); - this.internalFrames.add(singleStringFrame); - currentXCoordForFrames = currentXCoordForWord; - - currentColor = new Color((colorInt << 8) | (colorInt >>> 24)); - } - } - break; - case 'r': - case 'R': - i++; { - final String wordString = currentWord.toString(); - currentWord.setLength(0); - glyphLayout.setText(this.frameFont, wordString); - final float wordWidth = glyphLayout.width; - if ((startingBoundsWidth > 0) && ((currentXCoordForWord + wordWidth) >= startingBoundsWidth)) { - final String currentLineString = currentLine.toString(); - currentLine.setLength(0); - glyphLayout.setText(this.frameFont, currentLineString); - usedWidthMax = Math.max(currentXCoordForFrames + glyphLayout.width, usedWidthMax); - final SingleStringFrame singleStringFrame = new SingleStringFrame(currentLineString, - this.internalFramesContainer, currentColor, TextJustify.LEFT, TextJustify.TOP, - this.frameFont); - singleStringFrame.setHeight(this.frameFont.getLineHeight()); - singleStringFrame.setWidth(glyphLayout.width); - singleStringFrame.setAlpha(this.alpha); - singleStringFrame.setFontShadowColor(this.fontShadowColor); - singleStringFrame.setFontShadowOffsetX(this.fontShadowOffsetX); - singleStringFrame.setFontShadowOffsetY(this.fontShadowOffsetY); - singleStringFrame.addAnchor( - new AnchorDefinition(FramePoint.TOPLEFT, currentXCoordForFrames, -usedHeight)); - this.internalFrames.add(singleStringFrame); - usedHeight += this.frameFont.getLineHeight(); - currentXCoordForWord = 0; - currentXCoordForFrames = 0; - } - currentXCoordForWord += wordWidth; - currentLine.append(wordString); - - final String currentLineString = currentLine.toString(); - currentLine.setLength(0); - glyphLayout.setText(this.frameFont, currentLineString); - usedWidthMax = Math.max(currentXCoordForFrames + glyphLayout.width, usedWidthMax); - final SingleStringFrame singleStringFrame = new SingleStringFrame(currentLineString, - this.internalFramesContainer, currentColor, TextJustify.LEFT, TextJustify.TOP, - this.frameFont); - singleStringFrame.setHeight(this.frameFont.getLineHeight()); - singleStringFrame.setWidth(glyphLayout.width); - singleStringFrame.setAlpha(this.alpha); - singleStringFrame.setFontShadowColor(this.fontShadowColor); - singleStringFrame.setFontShadowOffsetX(this.fontShadowOffsetX); - singleStringFrame.setFontShadowOffsetY(this.fontShadowOffsetY); - singleStringFrame.addAnchor( - new AnchorDefinition(FramePoint.TOPLEFT, currentXCoordForFrames, -usedHeight)); - this.internalFrames.add(singleStringFrame); - currentXCoordForFrames = currentXCoordForWord; - } - currentColor = this.color; - break; - case 'n': - case 'N': { - - final String wordString = currentWord.toString(); - currentWord.setLength(0); - glyphLayout.setText(this.frameFont, wordString); - final float wordWidth = glyphLayout.width; - if ((startingBoundsWidth > 0) && ((currentXCoordForWord + wordWidth) >= startingBoundsWidth)) { - final String currentLineString = currentLine.toString(); - currentLine.setLength(0); - glyphLayout.setText(this.frameFont, currentLineString); - usedWidthMax = Math.max(currentXCoordForFrames + glyphLayout.width, usedWidthMax); - final SingleStringFrame singleStringFrame = new SingleStringFrame(currentLineString, - this.internalFramesContainer, currentColor, TextJustify.LEFT, TextJustify.TOP, - this.frameFont); - singleStringFrame.setHeight(this.frameFont.getLineHeight()); - singleStringFrame.setWidth(glyphLayout.width); - singleStringFrame.setAlpha(this.alpha); - singleStringFrame.setFontShadowColor(this.fontShadowColor); - singleStringFrame.setFontShadowOffsetX(this.fontShadowOffsetX); - singleStringFrame.setFontShadowOffsetY(this.fontShadowOffsetY); - singleStringFrame.addAnchor( - new AnchorDefinition(FramePoint.TOPLEFT, currentXCoordForFrames, -usedHeight)); - this.internalFrames.add(singleStringFrame); - usedHeight += this.frameFont.getLineHeight(); - currentXCoordForWord = 0; - currentXCoordForFrames = 0; - } - currentXCoordForWord += wordWidth; - currentLine.append(wordString); - - final String currentLineString = currentLine.toString(); - currentLine.setLength(0); - glyphLayout.setText(this.frameFont, currentLineString); - usedWidthMax = Math.max(currentXCoordForFrames + glyphLayout.width, usedWidthMax); - final SingleStringFrame singleStringFrame = new SingleStringFrame(currentLineString, - this.internalFramesContainer, currentColor, TextJustify.LEFT, TextJustify.TOP, - this.frameFont); - singleStringFrame.setHeight(this.frameFont.getLineHeight()); - singleStringFrame.setWidth(glyphLayout.width); - singleStringFrame.setAlpha(this.alpha); - singleStringFrame.setFontShadowColor(this.fontShadowColor); - singleStringFrame.setFontShadowOffsetX(this.fontShadowOffsetX); - singleStringFrame.setFontShadowOffsetY(this.fontShadowOffsetY); - singleStringFrame.addAnchor( - new AnchorDefinition(FramePoint.TOPLEFT, currentXCoordForFrames, -usedHeight)); - this.internalFrames.add(singleStringFrame); - usedHeight += this.frameFont.getLineHeight(); - currentXCoordForWord = 0; - currentXCoordForFrames = 0; - - } - i++; - break; - default: - currentWord.append(c); - break; - } - } - } - break; - case ' ': - currentWord.append(' '); - final String wordString = currentWord.toString(); - currentWord.setLength(0); - glyphLayout.setText(this.frameFont, wordString); - final float wordWidth = glyphLayout.width; - if ((startingBoundsWidth > 0) && ((currentXCoordForWord + wordWidth) >= startingBoundsWidth)) { - final String currentLineString = currentLine.toString(); - currentLine.setLength(0); - glyphLayout.setText(this.frameFont, currentLineString); - usedWidthMax = Math.max(currentXCoordForFrames + glyphLayout.width, usedWidthMax); - final SingleStringFrame singleStringFrame = new SingleStringFrame(currentLineString, - this.internalFramesContainer, currentColor, TextJustify.LEFT, TextJustify.TOP, - this.frameFont); - singleStringFrame.setHeight(this.frameFont.getLineHeight()); - singleStringFrame.setWidth(glyphLayout.width); - singleStringFrame.setAlpha(this.alpha); - singleStringFrame.setFontShadowColor(this.fontShadowColor); - singleStringFrame.setFontShadowOffsetX(this.fontShadowOffsetX); - singleStringFrame.setFontShadowOffsetY(this.fontShadowOffsetY); - singleStringFrame - .addAnchor(new AnchorDefinition(FramePoint.TOPLEFT, currentXCoordForFrames, -usedHeight)); - this.internalFrames.add(singleStringFrame); - usedHeight += this.frameFont.getLineHeight(); - currentXCoordForWord = 0; - currentXCoordForFrames = 0; - } - currentXCoordForWord += wordWidth; - currentLine.append(wordString); - break; - default: - currentWord.append(c); - break; - } - } - - { - - final String wordString = currentWord.toString(); - currentWord.setLength(0); - glyphLayout.setText(this.frameFont, wordString); - final float wordWidth = glyphLayout.width; - if ((startingBoundsWidth > 0) && ((currentXCoordForWord + wordWidth) >= startingBoundsWidth)) { - final String currentLineString = currentLine.toString(); - currentLine.setLength(0); - glyphLayout.setText(this.frameFont, currentLineString); - usedWidthMax = Math.max(currentXCoordForFrames + glyphLayout.width, usedWidthMax); - final SingleStringFrame singleStringFrame = new SingleStringFrame(currentLineString, - this.internalFramesContainer, currentColor, TextJustify.LEFT, TextJustify.TOP, this.frameFont); - singleStringFrame.setHeight(this.frameFont.getLineHeight()); - singleStringFrame.setWidth(glyphLayout.width); - singleStringFrame.setAlpha(this.alpha); - singleStringFrame.setFontShadowColor(this.fontShadowColor); - singleStringFrame.setFontShadowOffsetX(this.fontShadowOffsetX); - singleStringFrame.setFontShadowOffsetY(this.fontShadowOffsetY); - singleStringFrame - .addAnchor(new AnchorDefinition(FramePoint.TOPLEFT, currentXCoordForFrames, -usedHeight)); - this.internalFrames.add(singleStringFrame); - usedHeight += this.frameFont.getLineHeight(); - currentXCoordForWord = 0; - currentXCoordForFrames = 0; - } - currentXCoordForWord += wordWidth; - currentLine.append(wordString); - - final String currentLineString = currentLine.toString(); - currentLine.setLength(0); - glyphLayout.setText(this.frameFont, currentLineString); - usedWidthMax = Math.max(currentXCoordForFrames + glyphLayout.width, usedWidthMax); - final SingleStringFrame singleStringFrame = new SingleStringFrame(currentLineString, - this.internalFramesContainer, currentColor, TextJustify.LEFT, TextJustify.TOP, this.frameFont); - singleStringFrame.setHeight(this.frameFont.getLineHeight()); - singleStringFrame.setWidth(glyphLayout.width); - singleStringFrame.setAlpha(this.alpha); - singleStringFrame.setFontShadowColor(this.fontShadowColor); - singleStringFrame.setFontShadowOffsetX(this.fontShadowOffsetX); - singleStringFrame.setFontShadowOffsetY(this.fontShadowOffsetY); - singleStringFrame.addAnchor(new AnchorDefinition(FramePoint.TOPLEFT, currentXCoordForFrames, -usedHeight)); - this.internalFrames.add(singleStringFrame); - currentXCoordForFrames = currentXCoordForWord; - usedHeight += this.frameFont.getCapHeight(); - } - - this.internalFramesContainer.setWidth(usedWidthMax); - this.internalFramesContainer.setHeight(usedHeight); - this.predictedViewportHeight = (usedHeight - this.frameFont.getCapHeight()) + this.frameFont.getLineHeight(); - - this.internalFramesContainer.clearFramePointAssignments(); - switch (this.justifyH) { - case CENTER: - switch (this.justifyV) { - case MIDDLE: - this.internalFramesContainer.addAnchor(new AnchorDefinition(FramePoint.CENTER, 0, 0)); - break; - case BOTTOM: - this.internalFramesContainer.addAnchor(new AnchorDefinition(FramePoint.BOTTOM, 0, 0)); - break; - case TOP: - default: - this.internalFramesContainer.addAnchor(new AnchorDefinition(FramePoint.TOP, 0, 0)); - break; - } - break; - case RIGHT: - switch (this.justifyV) { - case MIDDLE: - this.internalFramesContainer.addAnchor(new AnchorDefinition(FramePoint.RIGHT, 0, 0)); - break; - case BOTTOM: - this.internalFramesContainer.addAnchor(new AnchorDefinition(FramePoint.BOTTOMRIGHT, 0, 0)); - break; - case TOP: - default: - this.internalFramesContainer.addAnchor(new AnchorDefinition(FramePoint.TOPRIGHT, 0, 0)); - break; - } - break; - case LEFT: - default: - switch (this.justifyV) { - case MIDDLE: - this.internalFramesContainer.addAnchor(new AnchorDefinition(FramePoint.LEFT, 0, 0)); - break; - case BOTTOM: - this.internalFramesContainer.addAnchor(new AnchorDefinition(FramePoint.BOTTOMLEFT, 0, 0)); - break; - case TOP: - default: - this.internalFramesContainer.addAnchor(new AnchorDefinition(FramePoint.TOPLEFT, 0, 0)); - break; - } - break; - } - - for (final SingleStringFrame internalFrame : this.internalFrames) { - this.internalFramesContainer.add(internalFrame); - } - } - - public void setAlpha(final float alpha) { - this.alpha = alpha; - for (final SingleStringFrame internalFrame : this.internalFrames) { - internalFrame.setAlpha(alpha); - } - - } - - public float getPredictedViewportHeight() { - return this.predictedViewportHeight; - } - - public BitmapFont getFrameFont() { - return this.frameFont; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/TextButtonFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/TextButtonFrame.java deleted file mode 100644 index 6e081349..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/TextButtonFrame.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -public class TextButtonFrame extends GlueTextButtonFrame { - private float buttonPushedTextOffsetX; - private float buttonPushedTextOffsetY; - - public TextButtonFrame(final String name, final UIFrame parent) { - super(name, parent); - } - - public void setButtonPushedTextOffsetX(final float buttonPushedTextOffsetX) { - this.buttonPushedTextOffsetX = buttonPushedTextOffsetX; - } - - public void setButtonPushedTextOffsetY(final float buttonPushedTextOffsetY) { - this.buttonPushedTextOffsetY = buttonPushedTextOffsetY; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/TextureFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/TextureFrame.java deleted file mode 100644 index 77945e4f..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/TextureFrame.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.Vector4Definition; - -public class TextureFrame extends AbstractRenderableFrame { - private TextureRegion texture; - private final boolean decorateFileNames; - private final Vector4Definition texCoord; - private Color color; - - public TextureFrame(final String name, final UIFrame parent, final boolean decorateFileNames, - final Vector4Definition texCoord) { - super(name, parent); - this.decorateFileNames = decorateFileNames; - this.texCoord = texCoord; - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - if (this.texture == null) { - return; - } - if (this.color != null) { - batch.setColor(this.color); - } - batch.draw(this.texture, this.renderBounds.x, this.renderBounds.y, this.renderBounds.width, - this.renderBounds.height); - if (this.color != null) { - batch.setColor(1f, 1f, 1f, 1f); - } - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - } - - public void setColor(final Color color) { - this.color = color; - } - - public void setColor(final float r, final float g, final float b, final float a) { - if (this.color == null) { - this.color = new Color(); - } - this.color.r = r; - this.color.g = g; - this.color.b = b; - this.color.a = a; - - } - - public void setTexture(String file, final GameUI gameUI) { - if (this.decorateFileNames) { - file = gameUI.trySkinField(file); - } - final Texture texture = gameUI.loadTexture(file); - if (texture != null) { - setTexture(texture); - } - } - - public void setTexCoord(final float x, final float y, final float z, final float w) { - this.texCoord.set(x, y, z, w); - if (this.texture != null) { - this.texture.setRegion(this.texCoord.getX(), this.texCoord.getZ(), this.texCoord.getY(), - this.texCoord.getW()); - } - } - - public void setTexture(final Texture texture) { - if (texture == null) { - this.texture = null; - return; - } - final TextureRegion texRegion; - if (this.texCoord != null) { - texRegion = new TextureRegion(texture, this.texCoord.getX(), this.texCoord.getZ(), this.texCoord.getY(), - this.texCoord.getW()); - } - else { - texRegion = new TextureRegion(texture); - } - this.texture = texRegion; - } - - public void setTexture(final TextureRegion texture) { - this.texture = texture; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/fdf/frames/UIFrame.java b/core/src/com/etheller/warsmash/parsers/fdf/frames/UIFrame.java deleted file mode 100644 index 3bd83b1f..00000000 --- a/core/src/com/etheller/warsmash/parsers/fdf/frames/UIFrame.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.etheller.warsmash.parsers.fdf.frames; - -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.AnchorDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; - -public interface UIFrame { - public void render(SpriteBatch batch, BitmapFont baseFont, GlyphLayout glyphLayout); - - public float getFramePointX(FramePoint framePoint); - - public float getFramePointY(FramePoint framePoint); - - void setFramePointX(final FramePoint framePoint, final float x); - - void setFramePointY(final FramePoint framePoint, final float y); - - void positionBounds(GameUI gameUI, final Viewport viewport); - - void addAnchor(final AnchorDefinition anchorDefinition); - - void addSetPoint(SetPoint setPointDefinition); - - void setWidth(final float width); - - void setHeight(final float height); - - float getAssignedWidth(); - - float getAssignedHeight(); - - void setSetAllPoints(boolean setAllPoints); - - void setSetAllPoints(boolean setAllPoints, float inset); - - void setVisible(boolean visible); - - UIFrame getParent(); - - boolean isVisible(); - - boolean isVisibleOnScreen(); - - UIFrame touchDown(float screenX, float screenY, int button); - - UIFrame touchUp(float screenX, float screenY, int button); - - UIFrame getFrameChildUnderMouse(float screenX, float screenY); - - String getName(); -} diff --git a/core/src/com/etheller/warsmash/parsers/jass/Jass2.java b/core/src/com/etheller/warsmash/parsers/jass/Jass2.java deleted file mode 100644 index d71ee1a5..00000000 --- a/core/src/com/etheller/warsmash/parsers/jass/Jass2.java +++ /dev/null @@ -1,3245 +0,0 @@ -package com.etheller.warsmash.parsers.jass; - -import java.awt.geom.Point2D; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Locale; - -import org.antlr.v4.runtime.BaseErrorListener; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.interpreter.JassLexer; -import com.etheller.interpreter.JassParser; -import com.etheller.interpreter.ast.function.JassFunction; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.scope.trigger.RemovableTriggerEvent; -import com.etheller.interpreter.ast.scope.trigger.Trigger; -import com.etheller.interpreter.ast.scope.trigger.TriggerBooleanExpression; -import com.etheller.interpreter.ast.scope.variableevent.CLimitOp; -import com.etheller.interpreter.ast.value.BooleanJassValue; -import com.etheller.interpreter.ast.value.HandleJassType; -import com.etheller.interpreter.ast.value.HandleJassValue; -import com.etheller.interpreter.ast.value.IntegerJassValue; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.RealJassValue; -import com.etheller.interpreter.ast.value.StringJassValue; -import com.etheller.interpreter.ast.value.visitor.BooleanJassValueVisitor; -import com.etheller.interpreter.ast.value.visitor.IntegerJassValueVisitor; -import com.etheller.interpreter.ast.value.visitor.JassFunctionJassValueVisitor; -import com.etheller.interpreter.ast.value.visitor.ObjectJassValueVisitor; -import com.etheller.interpreter.ast.value.visitor.RealJassValueVisitor; -import com.etheller.interpreter.ast.value.visitor.StringJassValueVisitor; -import com.etheller.interpreter.ast.visitors.JassProgramVisitor; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.parsers.fdf.GameSkin; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.AnchorDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; -import com.etheller.warsmash.parsers.fdf.frames.SetPoint; -import com.etheller.warsmash.parsers.fdf.frames.StringFrame; -import com.etheller.warsmash.parsers.fdf.frames.UIFrame; -import com.etheller.warsmash.parsers.jass.scope.CommonTriggerExecutionScope; -import com.etheller.warsmash.parsers.jass.triggers.BoolExprAnd; -import com.etheller.warsmash.parsers.jass.triggers.BoolExprCondition; -import com.etheller.warsmash.parsers.jass.triggers.BoolExprFilter; -import com.etheller.warsmash.parsers.jass.triggers.BoolExprNot; -import com.etheller.warsmash.parsers.jass.triggers.BoolExprOr; -import com.etheller.warsmash.parsers.jass.triggers.TriggerAction; -import com.etheller.warsmash.parsers.jass.triggers.TriggerCondition; -import com.etheller.warsmash.units.Element; -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.ItemUI; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructableType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitEnumFunction; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.ai.AIDifficulty; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.CPlayerAPI; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.War3MapConfig; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.item.CItemTypeJass; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIdUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapControl; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapFlag; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapPlacement; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerColor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerGameResult; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerJass; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerScore; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerState; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRace; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRacePreference; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CStartLocPrio; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.region.CRegion; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.region.CRegionTriggerEnter; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.state.CGameState; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.state.CUnitState; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.timers.CTimerJass; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.timers.CTimerNativeEvent; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.JassGameEventsWar3; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CAttackTypeJass; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CBlendMode; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CCameraField; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CDamageType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CEffectType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CFogState; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CGameSpeed; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CGameType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CMapDensity; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CMapDifficulty; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CPathingTypeJass; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CPlayerSlotState; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CRarityControl; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CSoundType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CSoundVolumeGroup; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CTexMapFlags; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CVersion; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CWeaponSoundTypeJass; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.unit.CUnitTypeJass; - -public class Jass2 { - public static final boolean REPORT_SYNTAX_ERRORS = true; - - public static CommonEnvironment loadCommon(final DataSource dataSource, final Viewport uiViewport, - final Scene uiScene, final War3MapViewer war3MapViewer, final RootFrameListener rootFrameListener, - final String... files) { - - final JassProgramVisitor jassProgramVisitor = new JassProgramVisitor(); - final CommonEnvironment environment = new CommonEnvironment(jassProgramVisitor, dataSource, uiViewport, uiScene, - war3MapViewer, rootFrameListener); - for (final String jassFile : files) { - try { - JassLexer lexer; - try { - lexer = new JassLexer(CharStreams.fromStream(dataSource.getResourceAsStream(jassFile))); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - final JassParser parser = new JassParser(new CommonTokenStream(lexer)); -// parser.removeErrorListener(ConsoleErrorListener.INSTANCE); - parser.addErrorListener(new BaseErrorListener() { - @Override - public void syntaxError(final Recognizer recognizer, final Object offendingSymbol, - final int line, final int charPositionInLine, final String msg, - final RecognitionException e) { - if (!REPORT_SYNTAX_ERRORS) { - return; - } - - final String sourceName = String.format("%s:%d:%d: ", jassFile, line, charPositionInLine); - - System.err.println(sourceName + "line " + line + ":" + charPositionInLine + " " + msg); - } - }); - jassProgramVisitor.visit(parser.program()); - } - catch (final Exception e) { - e.printStackTrace(); - } - } - jassProgramVisitor.getJassNativeManager().checkUnregisteredNatives(); - return environment; - } - - public static JUIEnvironment loadJUI(final DataSource dataSource, final Viewport uiViewport, final Scene uiScene, - final War3MapViewer war3MapViewer, final RootFrameListener rootFrameListener, final String... files) { - - final JassProgramVisitor jassProgramVisitor = new JassProgramVisitor(); - final JUIEnvironment environment = new JUIEnvironment(jassProgramVisitor, dataSource, uiViewport, uiScene, - war3MapViewer, rootFrameListener); - for (final String jassFile : files) { - try { - JassLexer lexer; - try { - lexer = new JassLexer(CharStreams.fromStream(dataSource.getResourceAsStream(jassFile))); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - final JassParser parser = new JassParser(new CommonTokenStream(lexer)); -// parser.removeErrorListener(ConsoleErrorListener.INSTANCE); - parser.addErrorListener(new BaseErrorListener() { - @Override - public void syntaxError(final Recognizer recognizer, final Object offendingSymbol, - final int line, final int charPositionInLine, final String msg, - final RecognitionException e) { - if (!REPORT_SYNTAX_ERRORS) { - return; - } - - final String sourceName = String.format("%s:%d:%d: ", jassFile, line, charPositionInLine); - - System.err.println(sourceName + "line " + line + ":" + charPositionInLine + " " + msg); - } - }); - jassProgramVisitor.visit(parser.program()); - } - catch (final Exception e) { - e.printStackTrace(); - } - } - jassProgramVisitor.getJassNativeManager().checkUnregisteredNatives(); - return environment; - } - - public static interface RootFrameListener { - void onCreate(GameUI rootFrame); - } - - private static final class JUIEnvironment { - private GameUI gameUI; - private Element skin; - - public JUIEnvironment(final JassProgramVisitor jassProgramVisitor, final DataSource dataSource, - final Viewport uiViewport, final Scene uiScene, final War3MapViewer war3MapViewer, - final RootFrameListener rootFrameListener) { - final GlobalScope globals = jassProgramVisitor.getGlobals(); - final HandleJassType frameHandleType = globals.registerHandleType("framehandle"); - final HandleJassType framePointType = globals.registerHandleType("framepointtype"); - final HandleJassType triggerType = globals.registerHandleType("trigger"); - final HandleJassType triggerActionType = globals.registerHandleType("triggeraction"); - final HandleJassType triggerConditionType = globals.registerHandleType("triggercondition"); - final HandleJassType boolExprType = globals.registerHandleType("boolexpr"); - final HandleJassType conditionFuncType = globals.registerHandleType("conditionfunc"); - final HandleJassType filterType = globals.registerHandleType("filterfunc"); - jassProgramVisitor.getJassNativeManager().createNative("LogError", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String stringValue = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - System.err.println(stringValue); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertFramePointType", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int value = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(framePointType, FramePoint.values()[value]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("CreateRootFrame", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String skinArg = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - final GameSkin skin = GameUI.loadSkin(dataSource, skinArg); - final GameUI gameUI = new GameUI(dataSource, skin, uiViewport, uiScene, war3MapViewer, 0, - war3MapViewer.getAllObjectData().getWts()); - JUIEnvironment.this.gameUI = gameUI; - JUIEnvironment.this.skin = skin.getSkin(); - rootFrameListener.onCreate(gameUI); - return new HandleJassValue(frameHandleType, gameUI); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("LoadTOCFile", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String tocFileName = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - try { - JUIEnvironment.this.gameUI.loadTOCFile(tocFileName); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return BooleanJassValue.TRUE; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("CreateSimpleFrame", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String templateName = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - final UIFrame ownerFrame = arguments.get(1).visit(ObjectJassValueVisitor.getInstance()); - final int createContext = arguments.get(2).visit(IntegerJassValueVisitor.getInstance()); - - final UIFrame simpleFrame = JUIEnvironment.this.gameUI.createSimpleFrame(templateName, ownerFrame, - createContext); - - return new HandleJassValue(frameHandleType, simpleFrame); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("CreateFrame", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String templateName = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - final UIFrame ownerFrame = arguments.get(1).visit(ObjectJassValueVisitor.getInstance()); - final int priority = arguments.get(2).visit(IntegerJassValueVisitor.getInstance()); - final int createContext = arguments.get(3).visit(IntegerJassValueVisitor.getInstance()); - - final UIFrame simpleFrame = JUIEnvironment.this.gameUI.createFrame(templateName, ownerFrame, - priority, createContext); - - return new HandleJassValue(frameHandleType, simpleFrame); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetFrameByName", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String templateName = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - final int createContext = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - - final UIFrame simpleFrame = JUIEnvironment.this.gameUI.getFrameByName(templateName, createContext); - return new HandleJassValue(frameHandleType, simpleFrame); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("FrameSetAnchor", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final UIFrame frame = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final FramePoint framePoint = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final double x = arguments.get(2).visit(RealJassValueVisitor.getInstance()); - final double y = arguments.get(3).visit(RealJassValueVisitor.getInstance()); - - frame.addAnchor(new AnchorDefinition(framePoint, GameUI.convertX(uiViewport, (float) x), - GameUI.convertY(uiViewport, (float) y))); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("FrameSetAbsPoint", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final UIFrame frame = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final FramePoint framePoint = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final double x = arguments.get(2).visit(RealJassValueVisitor.getInstance()); - final double y = arguments.get(3).visit(RealJassValueVisitor.getInstance()); - - frame.setFramePointX(framePoint, GameUI.convertX(uiViewport, (float) x)); - frame.setFramePointY(framePoint, GameUI.convertY(uiViewport, (float) y)); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("FrameSetPoint", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final UIFrame frame = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final FramePoint framePoint = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final UIFrame otherFrame = arguments.get(2).visit(ObjectJassValueVisitor.getInstance()); - final FramePoint otherPoint = arguments.get(3) - .visit(ObjectJassValueVisitor.getInstance()); - final double x = arguments.get(2).visit(RealJassValueVisitor.getInstance()); - final double y = arguments.get(3).visit(RealJassValueVisitor.getInstance()); - - frame.addSetPoint(new SetPoint(framePoint, otherFrame, otherPoint, - GameUI.convertX(uiViewport, (float) x), GameUI.convertY(uiViewport, (float) y))); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("FrameSetText", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final StringFrame frame = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final String text = arguments.get(1).visit(StringJassValueVisitor.getInstance()); - - JUIEnvironment.this.gameUI.setText(frame, text); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("FrameSetTextColor", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final StringFrame frame = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final int colorInt = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - frame.setColor(new Color(colorInt)); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertColor", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int a = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - final int r = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - final int g = arguments.get(2).visit(IntegerJassValueVisitor.getInstance()); - final int b = arguments.get(3).visit(IntegerJassValueVisitor.getInstance()); - return new IntegerJassValue(a | (b << 8) | (g << 16) | (r << 24)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("FramePositionBounds", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final UIFrame frame = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - frame.positionBounds(JUIEnvironment.this.gameUI, uiViewport); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SkinGetField", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String fieldName = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - return new StringJassValue(JUIEnvironment.this.skin.getField(fieldName)); - } - }); - setupTriggerAPI(jassProgramVisitor, triggerType, triggerActionType, triggerConditionType, boolExprType, - conditionFuncType, filterType); - } - } - - private static final class CommonEnvironment { - private GameUI gameUI; - private Element skin; - - public CommonEnvironment(final JassProgramVisitor jassProgramVisitor, final DataSource dataSource, - final Viewport uiViewport, final Scene uiScene, final War3MapViewer war3MapViewer, - final RootFrameListener rootFrameListener) { - final Rectangle tempRect = new Rectangle(); - final CSimulation simulation = war3MapViewer.simulation; - final GlobalScope globals = jassProgramVisitor.getGlobals(); - final HandleJassType agentType = globals.registerHandleType("agent"); - final HandleJassType eventType = globals.registerHandleType("event"); - final HandleJassType playerType = globals.registerHandleType("player"); - final HandleJassType widgetType = globals.registerHandleType("widget"); - final HandleJassType unitType = globals.registerHandleType("unit"); - final HandleJassType destructableType = globals.registerHandleType("destructable"); - final HandleJassType itemType = globals.registerHandleType("item"); - final HandleJassType abilityType = globals.registerHandleType("ability"); - final HandleJassType buffType = globals.registerHandleType("buff"); - final HandleJassType forceType = globals.registerHandleType("force"); - final HandleJassType groupType = globals.registerHandleType("group"); - final HandleJassType triggerType = globals.registerHandleType("trigger"); - final HandleJassType triggerconditionType = globals.registerHandleType("triggercondition"); - final HandleJassType triggeractionType = globals.registerHandleType("triggeraction"); - final HandleJassType timerType = globals.registerHandleType("timer"); - final HandleJassType locationType = globals.registerHandleType("location"); - final HandleJassType regionType = globals.registerHandleType("region"); - final HandleJassType rectType = globals.registerHandleType("rect"); - final HandleJassType boolexprType = globals.registerHandleType("boolexpr"); - final HandleJassType soundType = globals.registerHandleType("sound"); - final HandleJassType conditionfuncType = globals.registerHandleType("conditionfunc"); - final HandleJassType filterfuncType = globals.registerHandleType("filterfunc"); - final HandleJassType unitpoolType = globals.registerHandleType("unitpool"); - final HandleJassType itempoolType = globals.registerHandleType("itempool"); - final HandleJassType raceType = globals.registerHandleType("race"); - final HandleJassType alliancetypeType = globals.registerHandleType("alliancetype"); - final HandleJassType racepreferenceType = globals.registerHandleType("racepreference"); - final HandleJassType gamestateType = globals.registerHandleType("gamestate"); - final HandleJassType igamestateType = globals.registerHandleType("igamestate"); - final HandleJassType fgamestateType = globals.registerHandleType("fgamestate"); - final HandleJassType playerstateType = globals.registerHandleType("playerstate"); - final HandleJassType playerscoreType = globals.registerHandleType("playerscore"); - final HandleJassType playergameresultType = globals.registerHandleType("playergameresult"); - final HandleJassType unitstateType = globals.registerHandleType("unitstate"); - final HandleJassType aidifficultyType = globals.registerHandleType("aidifficulty"); - final HandleJassType eventidType = globals.registerHandleType("eventid"); - final HandleJassType gameeventType = globals.registerHandleType("gameevent"); - final HandleJassType playereventType = globals.registerHandleType("playerevent"); - final HandleJassType playeruniteventType = globals.registerHandleType("playerunitevent"); - final HandleJassType uniteventType = globals.registerHandleType("unitevent"); - final HandleJassType limitopType = globals.registerHandleType("limitop"); - final HandleJassType widgeteventType = globals.registerHandleType("widgetevent"); - final HandleJassType dialogeventType = globals.registerHandleType("dialogevent"); - final HandleJassType unittypeType = globals.registerHandleType("unittype"); - final HandleJassType gamespeedType = globals.registerHandleType("gamespeed"); - final HandleJassType gamedifficultyType = globals.registerHandleType("gamedifficulty"); - final HandleJassType gametypeType = globals.registerHandleType("gametype"); - final HandleJassType mapflagType = globals.registerHandleType("mapflag"); - final HandleJassType mapvisibilityType = globals.registerHandleType("mapvisibility"); - final HandleJassType mapsettingType = globals.registerHandleType("mapsetting"); - final HandleJassType mapdensityType = globals.registerHandleType("mapdensity"); - final HandleJassType mapcontrolType = globals.registerHandleType("mapcontrol"); - final HandleJassType playerslotstateType = globals.registerHandleType("playerslotstate"); - final HandleJassType volumegroupType = globals.registerHandleType("volumegroup"); - final HandleJassType camerafieldType = globals.registerHandleType("camerafield"); - final HandleJassType camerasetupType = globals.registerHandleType("camerasetup"); - final HandleJassType playercolorType = globals.registerHandleType("playercolor"); - final HandleJassType placementType = globals.registerHandleType("placement"); - final HandleJassType startlocprioType = globals.registerHandleType("startlocprio"); - final HandleJassType raritycontrolType = globals.registerHandleType("raritycontrol"); - final HandleJassType blendmodeType = globals.registerHandleType("blendmode"); - final HandleJassType texmapflagsType = globals.registerHandleType("texmapflags"); - final HandleJassType effectType = globals.registerHandleType("effect"); - final HandleJassType effecttypeType = globals.registerHandleType("effecttype"); - final HandleJassType weathereffectType = globals.registerHandleType("weathereffect"); - final HandleJassType terraindeformationType = globals.registerHandleType("terraindeformation"); - final HandleJassType fogstateType = globals.registerHandleType("fogstate"); - final HandleJassType fogmodifierType = globals.registerHandleType("fogmodifier"); - final HandleJassType dialogType = globals.registerHandleType("dialog"); - final HandleJassType buttonType = globals.registerHandleType("button"); - final HandleJassType questType = globals.registerHandleType("quest"); - final HandleJassType questitemType = globals.registerHandleType("questitem"); - final HandleJassType defeatconditionType = globals.registerHandleType("defeatcondition"); - final HandleJassType timerdialogType = globals.registerHandleType("timerdialog"); - final HandleJassType leaderboardType = globals.registerHandleType("leaderboard"); - final HandleJassType multiboardType = globals.registerHandleType("multiboard"); - final HandleJassType multiboarditemType = globals.registerHandleType("multiboarditem"); - final HandleJassType trackableType = globals.registerHandleType("trackable"); - final HandleJassType gamecacheType = globals.registerHandleType("gamecache"); - final HandleJassType versionType = globals.registerHandleType("version"); - final HandleJassType itemtypeType = globals.registerHandleType("itemtype"); - final HandleJassType texttagType = globals.registerHandleType("texttag"); - final HandleJassType attacktypeType = globals.registerHandleType("attacktype"); - final HandleJassType damagetypeType = globals.registerHandleType("damagetype"); - final HandleJassType weapontypeType = globals.registerHandleType("weapontype"); - final HandleJassType soundtypeType = globals.registerHandleType("soundtype"); - final HandleJassType lightningType = globals.registerHandleType("lightning"); - final HandleJassType pathingtypeType = globals.registerHandleType("pathingtype"); - final HandleJassType imageType = globals.registerHandleType("image"); - final HandleJassType ubersplatType = globals.registerHandleType("ubersplat"); - final HandleJassType hashtableType = globals.registerHandleType("hashtable"); - - jassProgramVisitor.getJassNativeManager().createNative("ConvertRace", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(raceType, CRace.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertAllianceType", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(alliancetypeType, CAllianceType.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertRacePref", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(racepreferenceType, CRacePreference.getById(i)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertIGameState", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(igamestateType, CGameState.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertFGameState", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(fgamestateType, CGameState.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertPlayerState", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(playerstateType, CPlayerState.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertPlayerScore", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(playerscoreType, CPlayerScore.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertGameResult", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(playergameresultType, CPlayerGameResult.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertUnitState", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(unitstateType, CUnitState.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertAIDifficulty", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(aidifficultyType, AIDifficulty.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertGameEvent", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(gameeventType, JassGameEventsWar3.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertPlayerEvent", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(playereventType, JassGameEventsWar3.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertPlayerUnitEvent", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(playeruniteventType, JassGameEventsWar3.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertWidgetEvent", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(widgeteventType, JassGameEventsWar3.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertDialogEvent", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(dialogeventType, JassGameEventsWar3.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertUnitEvent", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(uniteventType, JassGameEventsWar3.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertLimitOp", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(limitopType, CLimitOp.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertUnitType", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(unittypeType, CUnitTypeJass.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertGameSpeed", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(gamespeedType, CGameSpeed.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertPlacement", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(placementType, CMapPlacement.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertStartLocPrio", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(startlocprioType, CStartLocPrio.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertGameDifficulty", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(gamedifficultyType, CMapDifficulty.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertGameType", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(gametypeType, CGameType.getById(i)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertMapFlag", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(gametypeType, CMapFlag.getById(i)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertMapVisibility", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(mapvisibilityType, null); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertMapSetting", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(mapsettingType, null); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertMapDensity", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(mapdensityType, CMapDensity.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertMapControl", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(mapcontrolType, CMapControl.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertPlayerColor", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(playercolorType, CMapControl.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertPlayerSlotState", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(playerslotstateType, CPlayerSlotState.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertVolumeGroup", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(volumegroupType, CSoundVolumeGroup.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertCameraField", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(camerafieldType, CCameraField.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertBlendMode", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(blendmodeType, CBlendMode.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertRarityControl", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(raritycontrolType, CRarityControl.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertTexMapFlags", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(texmapflagsType, CTexMapFlags.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertFogState", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(fogstateType, CFogState.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertEffectType", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(effecttypeType, CEffectType.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertVersion", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(versionType, CVersion.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertItemType", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(itemtypeType, CItemTypeJass.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertAttackType", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(attacktypeType, CAttackTypeJass.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertDamageType", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(attacktypeType, CDamageType.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertWeaponType", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(weapontypeType, CWeaponSoundTypeJass.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertSoundType", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(soundtypeType, CSoundType.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ConvertPathingType", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final int i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(pathingtypeType, CPathingTypeJass.VALUES[i]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("OrderId", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String idString = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - final int orderId = OrderIdUtils.getOrderId(idString); - return new IntegerJassValue(orderId); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("OrderId2String", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer id = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new StringJassValue(OrderIdUtils.getStringFromOrderId(id)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("UnitId", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String idString = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - final CUnitType unitType = simulation.getUnitData().getUnitTypeByJassLegacyName(idString); - if (unitType == null) { - return new IntegerJassValue(0); - } - return new IntegerJassValue(unitType.getTypeId().getValue()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("UnitId2String", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer id = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - final War3ID war3id = new War3ID(id); - return new StringJassValue(simulation.getUnitData().getUnitType(war3id).getLegacyName()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("AbilityId", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new IntegerJassValue(0); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("AbilityId2String", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new StringJassValue(""); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetObjectName", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer id = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - final War3ID war3id = new War3ID(id); - final CUnitType unitType = simulation.getUnitData().getUnitType(war3id); - if (unitType != null) { - return new StringJassValue(unitType.getName()); - } - // TODO for now this looks in the ability editor data, not the fast symbol table - // layer on top, because the layer on top forgot to have a name value... - final MutableGameObject abilityEditorData = war3MapViewer.getAllObjectData().getAbilities() - .get(war3id); - if (abilityEditorData != null) { - return new StringJassValue(abilityEditorData.getName()); - } - final ItemUI itemUI = war3MapViewer.getAbilityDataUI().getItemUI(war3id); - if (itemUI != null) { - return new StringJassValue(itemUI.getName()); - } - final CDestructableType destructableType = simulation.getDestructableData().getUnitType(war3id); - if (destructableType != null) { - return new StringJassValue(destructableType.getName()); - } - return new StringJassValue(""); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Deg2Rad", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); - return new RealJassValue(StrictMath.toRadians(value)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Rad2Deg", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); - return new RealJassValue(StrictMath.toDegrees(value)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Sin", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); - return new RealJassValue(StrictMath.sin(value)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Cos", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); - return new RealJassValue(StrictMath.cos(value)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Tan", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); - return new RealJassValue(StrictMath.tan(value)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Asin", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); - final double result = StrictMath.asin(value); - if (Double.isNaN(result)) { - return new RealJassValue(0); - } - return new RealJassValue(result); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Acos", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); - final double result = StrictMath.acos(value); - if (Double.isNaN(result)) { - return new RealJassValue(0); - } - return new RealJassValue(result); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Atan", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); - final double result = StrictMath.atan(value); - if (Double.isNaN(result)) { - return new RealJassValue(0); - } - return new RealJassValue(result); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Atan2", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Double y = arguments.get(0).visit(RealJassValueVisitor.getInstance()); - final Double x = arguments.get(1).visit(RealJassValueVisitor.getInstance()); - final double result = StrictMath.atan2(y, x); - if (Double.isNaN(result)) { - return new RealJassValue(0); - } - return new RealJassValue(result); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SquareRoot", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Double value = arguments.get(0).visit(RealJassValueVisitor.getInstance()); - final double result = StrictMath.sqrt(value); - return new RealJassValue(result); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Pow", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Double y = arguments.get(0).visit(RealJassValueVisitor.getInstance()); - final Double x = arguments.get(1).visit(RealJassValueVisitor.getInstance()); - final double result = StrictMath.pow(y, x); - if (Double.isNaN(result)) { - return new RealJassValue(0); - } - return new RealJassValue(result); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("I2R", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new RealJassValue(i.doubleValue()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("R2I", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Double r = arguments.get(0).visit(RealJassValueVisitor.getInstance()); - return new IntegerJassValue(r.intValue()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("I2S", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer i = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new StringJassValue(i.toString()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("R2S", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Double r = arguments.get(0).visit(RealJassValueVisitor.getInstance()); - return new StringJassValue(r.toString()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("R2SW", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Double r = arguments.get(0).visit(RealJassValueVisitor.getInstance()); - final int width = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - final int precision = arguments.get(2).visit(IntegerJassValueVisitor.getInstance()); - return new StringJassValue(String.format("%" + precision + "." + width + "f", r)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("S2I", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String s = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - try { - final int intValue = Integer.parseInt(s); - return new IntegerJassValue(intValue); - } - catch (final Exception exc) { - return new IntegerJassValue(0); - } - } - }); - jassProgramVisitor.getJassNativeManager().createNative("S2R", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String s = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - try { - final double parsedValue = Double.parseDouble(s); - return new RealJassValue(parsedValue); - } - catch (final Exception exc) { - return new RealJassValue(0); - } - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SubString", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String s = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - final int start = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - final int end = arguments.get(2).visit(IntegerJassValueVisitor.getInstance()); - return new StringJassValue(s.substring(start, end)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("StringLength", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String s = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - return new IntegerJassValue(s.length()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("StringCase", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String s = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - final boolean upper = arguments.get(1).visit(BooleanJassValueVisitor.getInstance()); - return new StringJassValue(upper ? s.toUpperCase(Locale.US) : s.toLowerCase(Locale.US)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("StringHash", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String s = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - return new IntegerJassValue(s.hashCode()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetLocalizedString", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String key = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - // TODO this might be wrong, or a subset of the needed return values - final String decoratedString = war3MapViewer.getGameUI().getTemplates().getDecoratedString(key); - if (key.equals(decoratedString)) { - System.err.println("GetLocalizedString: NOT FOUND: " + key); - } - return new StringJassValue(decoratedString); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetLocalizedHotkey", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String key = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - // TODO this might be wrong, or a subset of the needed return values - final String decoratedString = war3MapViewer.getGameUI().getTemplates().getDecoratedString(key); - if (key.equals(decoratedString)) { - System.err.println("GetLocalizedHotkey: NOT FOUND: " + key); - } - return new IntegerJassValue(decoratedString.charAt(0)); - } - }); - final War3MapConfig mapConfig = war3MapViewer.getMapConfig(); - registerConfigNatives(jassProgramVisitor, mapConfig, startlocprioType, gametypeType, placementType, - gamespeedType, gamedifficultyType, mapdensityType, locationType, playerType, playercolorType, - mapcontrolType, playerslotstateType, simulation); - - // ============================================================================ - // Timer API - // - jassProgramVisitor.getJassNativeManager().createNative("CreateTimer", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(timerType, new CTimerJass(globalScope)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("DestroyTimer", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CTimerJass timer = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - simulation.unregisterTimer(timer); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TimerStart", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CTimerJass timer = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final Double timeout = arguments.get(1).visit(RealJassValueVisitor.getInstance()); - final boolean periodic = arguments.get(2).visit(BooleanJassValueVisitor.getInstance()); - final JassFunction handlerFunc = arguments.get(3).visit(JassFunctionJassValueVisitor.getInstance()); - if (!timer.isRunning()) { - timer.setTimeoutTime(timeout.floatValue()); - timer.setRepeats(periodic); - timer.setHandlerFunc(handlerFunc); - timer.start(simulation); - } - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TimerGetElapsed", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CTimerJass timer = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return new RealJassValue(timer.getElapsed(simulation)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TimerGetRemaining", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CTimerJass timer = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return new RealJassValue(timer.getRemaining(simulation)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TimerGetTimeout", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CTimerJass timer = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return new RealJassValue(timer.getTimeoutTime()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("PauseTimer", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CTimerJass timer = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - timer.pause(simulation); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ResumeTimer", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CTimerJass timer = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - timer.resume(simulation); - return null; - } - }); - - // ============================================================================ - // Group API - // - jassProgramVisitor.getJassNativeManager().createNative("CreateGroup", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(groupType, new ArrayList()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("DestroyGroup", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - System.err.println( - "DestroyGroup called but in Java we don't have a destructor, so we need to unregister later when that is implemented"); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupAddUnit", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final CUnit whichUnit = arguments.get(1).visit(ObjectJassValueVisitor.getInstance()); - group.add(whichUnit); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupRemoveUnit", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final CUnit whichUnit = arguments.get(1).visit(ObjectJassValueVisitor.getInstance()); - group.remove(whichUnit); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupClear", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - group.clear(); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupEnumUnitsOfType", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final String unitname = arguments.get(1).visit(StringJassValueVisitor.getInstance()); - final TriggerBooleanExpression filter = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - for (final CUnit unit : simulation.getUnits()) { - if (unitname.equals(unit.getUnitType().getLegacyName())) { - if (filter.evaluate(globalScope, - CommonTriggerExecutionScope.filterScope(triggerScope, unit))) { - // TODO the trigger scope for evaluation here might need to be a clean one? - group.add(unit); - } - } - } - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupEnumUnitsOfPlayer", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final CPlayerJass player = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final TriggerBooleanExpression filter = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - for (final CUnit unit : simulation.getUnits()) { - if (unit.getPlayerIndex() == player.getId()) { - if (filter.evaluate(globalScope, - CommonTriggerExecutionScope.filterScope(triggerScope, unit))) { - // TODO the trigger scope for evaluation here might need to be a clean one? - group.add(unit); - } - } - } - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupEnumUnitsOfTypeCounted", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final String unitname = arguments.get(1).visit(StringJassValueVisitor.getInstance()); - final TriggerBooleanExpression filter = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - final Integer countLimit = arguments.get(3).visit(IntegerJassValueVisitor.getInstance()); - int count = 0; - for (final CUnit unit : simulation.getUnits()) { - if (unitname.equals(unit.getUnitType().getLegacyName())) { - if (filter.evaluate(globalScope, - CommonTriggerExecutionScope.filterScope(triggerScope, unit))) { - // TODO the trigger scope for evaluation here might need to be a clean one? - group.add(unit); - count++; - if (count >= countLimit) { - break; - } - } - } - } - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupEnumUnitsInRect", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final Rectangle rect = arguments.get(1).visit(ObjectJassValueVisitor.getInstance()); - final TriggerBooleanExpression filter = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - simulation.getWorldCollision().enumUnitsInRect(rect, new CUnitEnumFunction() { - @Override - public boolean call(final CUnit unit) { - if (filter.evaluate(globalScope, - CommonTriggerExecutionScope.filterScope(triggerScope, unit))) { - // TODO the trigger scope for evaluation here might need to be a clean one? - group.add(unit); - } - return false; - } - }); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupEnumUnitsInRectCounted", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final Rectangle rect = arguments.get(1).visit(ObjectJassValueVisitor.getInstance()); - final TriggerBooleanExpression filter = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - final Integer countLimit = arguments.get(3).visit(IntegerJassValueVisitor.getInstance()); - simulation.getWorldCollision().enumUnitsInRect(rect, new CUnitEnumFunction() { - int count = 0; - - @Override - public boolean call(final CUnit unit) { - if (filter.evaluate(globalScope, - CommonTriggerExecutionScope.filterScope(triggerScope, unit))) { - // TODO the trigger scope for evaluation here might need to be a clean one? - group.add(unit); - this.count++; - if (this.count >= countLimit) { - return true; - } - } - return false; - } - }); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupEnumUnitsInRange", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final float x = arguments.get(1).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float y = arguments.get(2).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float radius = arguments.get(3).visit(RealJassValueVisitor.getInstance()).floatValue(); - final TriggerBooleanExpression filter = arguments.get(4) - .visit(ObjectJassValueVisitor.getInstance()); - simulation.getWorldCollision().enumUnitsInRect(tempRect.set(x - radius, y - radius, radius, radius), - new CUnitEnumFunction() { - - @Override - public boolean call(final CUnit unit) { - if (unit.distance(x, y) <= radius) { - if (filter.evaluate(globalScope, - CommonTriggerExecutionScope.filterScope(triggerScope, unit))) { - // TODO the trigger scope for evaluation here might need to be a clean one? - group.add(unit); - } - } - return false; - } - }); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupEnumUnitsInRangeOfLoc", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final Point2D.Double whichLocation = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final float x = (float) whichLocation.x; - final float y = (float) whichLocation.y; - final float radius = arguments.get(2).visit(RealJassValueVisitor.getInstance()).floatValue(); - final TriggerBooleanExpression filter = arguments.get(3) - .visit(ObjectJassValueVisitor.getInstance()); - simulation.getWorldCollision().enumUnitsInRect(tempRect.set(x - radius, y - radius, radius, radius), - new CUnitEnumFunction() { - - @Override - public boolean call(final CUnit unit) { - if (unit.distance(x, y) <= radius) { - if (filter.evaluate(globalScope, - CommonTriggerExecutionScope.filterScope(triggerScope, unit))) { - // TODO the trigger scope for evaluation here might need to be a clean one? - group.add(unit); - } - } - return false; - } - }); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupEnumUnitsInRangeCounted", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final float x = arguments.get(1).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float y = arguments.get(2).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float radius = arguments.get(3).visit(RealJassValueVisitor.getInstance()).floatValue(); - final TriggerBooleanExpression filter = arguments.get(4) - .visit(ObjectJassValueVisitor.getInstance()); - final Integer countLimit = arguments.get(5).visit(IntegerJassValueVisitor.getInstance()); - simulation.getWorldCollision().enumUnitsInRect(tempRect.set(x - radius, y - radius, radius, radius), - new CUnitEnumFunction() { - int count = 0; - - @Override - public boolean call(final CUnit unit) { - if (unit.distance(x, y) <= radius) { - if (filter.evaluate(globalScope, - CommonTriggerExecutionScope.filterScope(triggerScope, unit))) { - // TODO the trigger scope for evaluation here might need to be a clean one? - group.add(unit); - this.count++; - if (this.count >= countLimit) { - return true; - } - } - } - return false; - } - }); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupEnumUnitsInRangeOfLocCounted", - new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0) - .visit(ObjectJassValueVisitor.>getInstance()); - final Point2D.Double whichLocation = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final float x = (float) whichLocation.x; - final float y = (float) whichLocation.y; - final float radius = arguments.get(2).visit(RealJassValueVisitor.getInstance()) - .floatValue(); - final TriggerBooleanExpression filter = arguments.get(3) - .visit(ObjectJassValueVisitor.getInstance()); - final Integer countLimit = arguments.get(4).visit(IntegerJassValueVisitor.getInstance()); - simulation.getWorldCollision().enumUnitsInRect( - tempRect.set(x - radius, y - radius, radius, radius), new CUnitEnumFunction() { - int count = 0; - - @Override - public boolean call(final CUnit unit) { - if (unit.distance(x, y) <= radius) { - if (filter.evaluate(globalScope, - CommonTriggerExecutionScope.filterScope(triggerScope, unit))) { - // TODO the trigger scope for evaluation here might need to be a - // clean one? - group.add(unit); - this.count++; - if (this.count >= countLimit) { - return true; - } - } - } - return false; - } - }); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupEnumUnitsSelected", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final CPlayerJass whyichPlayer = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final TriggerBooleanExpression filter = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - throw new UnsupportedOperationException("GroupEnumUnitsSelected not supported yet."); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupImmediateOrder", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final String order = arguments.get(1).visit(StringJassValueVisitor.getInstance()); - final int orderId = OrderIdUtils.getOrderId(order); - boolean success = true; - for (final CUnit unit : group) { - success &= unit.order(simulation, orderId, null); - } - return BooleanJassValue.of(success); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupImmediateOrderById", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final int order = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - boolean success = true; - for (final CUnit unit : group) { - success &= unit.order(simulation, order, null); - } - return BooleanJassValue.of(success); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupPointOrder", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final String order = arguments.get(1).visit(StringJassValueVisitor.getInstance()); - final Double x = arguments.get(2).visit(RealJassValueVisitor.getInstance()); - final Double y = arguments.get(3).visit(RealJassValueVisitor.getInstance()); - final AbilityPointTarget target = new AbilityPointTarget(x.floatValue(), y.floatValue()); - final int orderId = OrderIdUtils.getOrderId(order); - boolean success = true; - for (final CUnit unit : group) { - success &= unit.order(simulation, orderId, target); - } - return BooleanJassValue.of(success); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupPointOrderLoc", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final String order = arguments.get(1).visit(StringJassValueVisitor.getInstance()); - final Point2D.Double whichLocation = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - final AbilityPointTarget target = new AbilityPointTarget((float) whichLocation.x, - (float) whichLocation.y); - final int orderId = OrderIdUtils.getOrderId(order); - boolean success = true; - for (final CUnit unit : group) { - success &= unit.order(simulation, orderId, target); - } - return BooleanJassValue.of(success); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupPointOrderById", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final int orderId = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - final Double x = arguments.get(2).visit(RealJassValueVisitor.getInstance()); - final Double y = arguments.get(3).visit(RealJassValueVisitor.getInstance()); - final AbilityPointTarget target = new AbilityPointTarget(x.floatValue(), y.floatValue()); - boolean success = true; - for (final CUnit unit : group) { - success &= unit.order(simulation, orderId, target); - } - return BooleanJassValue.of(success); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupPointOrderByIdLoc", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final int orderId = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - final Point2D.Double whichLocation = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - final AbilityPointTarget target = new AbilityPointTarget((float) whichLocation.x, - (float) whichLocation.y); - boolean success = true; - for (final CUnit unit : group) { - success &= unit.order(simulation, orderId, target); - } - return BooleanJassValue.of(success); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupTargetOrder", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final String order = arguments.get(1).visit(StringJassValueVisitor.getInstance()); - final CWidget target = arguments.get(2).visit(ObjectJassValueVisitor.getInstance()); - final int orderId = OrderIdUtils.getOrderId(order); - boolean success = true; - for (final CUnit unit : group) { - success &= unit.order(simulation, orderId, target); - } - return BooleanJassValue.of(success); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GroupTargetOrderById", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final int orderId = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - final CWidget target = arguments.get(2).visit(ObjectJassValueVisitor.getInstance()); - boolean success = true; - for (final CUnit unit : group) { - success &= unit.order(simulation, orderId, target); - } - return BooleanJassValue.of(success); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ForGroup", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - final JassFunction callback = arguments.get(1).visit(JassFunctionJassValueVisitor.getInstance()); - for (final CUnit unit : group) { - callback.call(Collections.emptyList(), globalScope, - CommonTriggerExecutionScope.enumScope(triggerScope, unit)); - } - return new HandleJassValue(unitType, group.get(0)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("FirstOfGroup", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List group = arguments.get(0).visit(ObjectJassValueVisitor.>getInstance()); - return new HandleJassValue(unitType, group.get(0)); - } - }); - // ============================================================================ - // Force API - // - jassProgramVisitor.getJassNativeManager().createNative("CreateForce", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(forceType, new ArrayList()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("DestroyForce", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List force = arguments.get(0) - .visit(ObjectJassValueVisitor.>getInstance()); - System.err.println( - "DestroyForce called but in Java we don't have a destructor, so we need to unregister later when that is implemented"); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ForceAddPlayer", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List force = arguments.get(0) - .visit(ObjectJassValueVisitor.>getInstance()); - final CPlayerJass player = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - force.add(player); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ForceRemovePlayer", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List force = arguments.get(0) - .visit(ObjectJassValueVisitor.>getInstance()); - final CPlayerJass player = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - force.remove(player); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ForceClear", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List force = arguments.get(0) - .visit(ObjectJassValueVisitor.>getInstance()); - force.clear(); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ForceEnumPlayers", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List force = arguments.get(0) - .visit(ObjectJassValueVisitor.>getInstance()); - final TriggerBooleanExpression filter = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) { - final CPlayerJass jassPlayer = simulation.getPlayer(i); - if (filter.evaluate(globalScope, - CommonTriggerExecutionScope.filterScope(triggerScope, jassPlayer))) { - force.add(jassPlayer); - } - } - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ForceEnumPlayersCounted", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List force = arguments.get(0) - .visit(ObjectJassValueVisitor.>getInstance()); - final TriggerBooleanExpression filter = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final Integer countLimit = arguments.get(2).visit(IntegerJassValueVisitor.getInstance()); - int count = 0; - for (int i = 0; (i < WarsmashConstants.MAX_PLAYERS) && (count < countLimit); i++) { - final CPlayerJass jassPlayer = simulation.getPlayer(i); - if (filter.evaluate(globalScope, - CommonTriggerExecutionScope.filterScope(triggerScope, jassPlayer))) { - force.add(jassPlayer); - count++; - } - } - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ForceEnumAllies", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List force = arguments.get(0) - .visit(ObjectJassValueVisitor.>getInstance()); - final CPlayerJass player = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final TriggerBooleanExpression filter = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) { - final CPlayerJass jassPlayer = simulation.getPlayer(i); - if (player.hasAlliance(i, CAllianceType.PASSIVE)) { - if (filter.evaluate(globalScope, - CommonTriggerExecutionScope.filterScope(triggerScope, jassPlayer))) { - force.add(jassPlayer); - } - } - } - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ForceEnumEnemies", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List force = arguments.get(0) - .visit(ObjectJassValueVisitor.>getInstance()); - final CPlayerJass player = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final TriggerBooleanExpression filter = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) { - final CPlayerJass jassPlayer = simulation.getPlayer(i); - if (!player.hasAlliance(i, CAllianceType.PASSIVE)) { - if (filter.evaluate(globalScope, - CommonTriggerExecutionScope.filterScope(triggerScope, jassPlayer))) { - force.add(jassPlayer); - } - } - } - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ForForce", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final List force = arguments.get(0) - .visit(ObjectJassValueVisitor.>getInstance()); - final JassFunction callback = arguments.get(1).visit(JassFunctionJassValueVisitor.getInstance()); - for (final CPlayerJass player : force) { - callback.call(Collections.emptyList(), globalScope, - CommonTriggerExecutionScope.enumScope(triggerScope, player)); - } - return null; - } - }); - // ============================================================================ - // Region and Location API - // - jassProgramVisitor.getJassNativeManager().createNative("Rect", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final float minx = arguments.get(0).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float miny = arguments.get(1).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float maxx = arguments.get(2).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float maxy = arguments.get(3).visit(RealJassValueVisitor.getInstance()).floatValue(); - return new HandleJassValue(rectType, new Rectangle(minx, miny, maxx - minx, maxy - miny)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("RectFromLoc", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Point2D.Double min = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final Point2D.Double max = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final float minx = (float) min.x; - final float miny = (float) min.y; - final float maxx = (float) max.x; - final float maxy = (float) max.y; - return new HandleJassValue(rectType, new Rectangle(minx, miny, maxx - minx, maxy - miny)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("RemoveRect", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Rectangle rect = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - System.err.println( - "RemoveRect called but in Java we don't have a destructor, so we need to unregister later when that is implemented"); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetRect", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Rectangle rect = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final float minx = arguments.get(1).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float miny = arguments.get(2).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float maxx = arguments.get(3).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float maxy = arguments.get(4).visit(RealJassValueVisitor.getInstance()).floatValue(); - rect.set(minx, miny, maxx - minx, maxy - miny); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetRectFromLoc", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Rectangle rect = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final Point2D.Double min = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final Point2D.Double max = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - final float minx = (float) min.x; - final float miny = (float) min.y; - final float maxx = (float) max.x; - final float maxy = (float) max.y; - rect.set(minx, miny, maxx - minx, maxy - miny); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("MoveRectTo", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Rectangle rect = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final float newCenterX = arguments.get(1).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float newCenterY = arguments.get(2).visit(RealJassValueVisitor.getInstance()).floatValue(); - rect.setCenter(newCenterX, newCenterY); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("MoveRectToLoc", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Rectangle rect = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final Point2D.Double newCenterLoc = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - rect.setCenter((float) newCenterLoc.x, (float) newCenterLoc.y); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetRectCenterX", new JassFunction() { - Vector2 centerHeap = new Vector2(); - - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Rectangle rect = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return new RealJassValue(rect.getCenter(this.centerHeap).x); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetRectCenterY", new JassFunction() { - Vector2 centerHeap = new Vector2(); - - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Rectangle rect = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return new RealJassValue(rect.getCenter(this.centerHeap).y); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetRectMinX", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Rectangle rect = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return new RealJassValue(rect.getX()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetRectMinY", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Rectangle rect = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return new RealJassValue(rect.getY()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetRectMaxX", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Rectangle rect = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return new RealJassValue(rect.getX() + rect.getWidth()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetRectMaxY", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Rectangle rect = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return new RealJassValue(rect.getY() + rect.getHeight()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("CreateRegion", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(regionType, new CRegion()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("RemoveRegion", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CRegion region = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - region.remove(simulation.getRegionManager()); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("RegionAddRect", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CRegion region = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final Rectangle rect = arguments.get(1).visit(ObjectJassValueVisitor.getInstance()); - region.addRect(rect, simulation.getRegionManager()); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("RegionClearRect", new JassFunction() { - - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CRegion region = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final Rectangle rect = arguments.get(1).visit(ObjectJassValueVisitor.getInstance()); - region.clearRect(rect, simulation.getRegionManager()); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("RegionAddCell", new JassFunction() { - - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CRegion region = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final float x = arguments.get(1).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float y = arguments.get(2).visit(RealJassValueVisitor.getInstance()).floatValue(); - region.addCell(x, y, simulation.getRegionManager()); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("RegionAddCellAtLoc", new JassFunction() { - - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CRegion region = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final Point2D.Double whichLocation = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - region.addCell((float) whichLocation.x, (float) whichLocation.y, simulation.getRegionManager()); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("RegionClearCell", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CRegion region = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final float x = arguments.get(1).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float y = arguments.get(2).visit(RealJassValueVisitor.getInstance()).floatValue(); - region.clearCell(x, y, simulation.getRegionManager()); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("RegionClearCellAtLoc", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CRegion region = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final Point2D.Double whichLocation = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - region.clearCell((float) whichLocation.x, (float) whichLocation.y, simulation.getRegionManager()); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Location", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final float x = arguments.get(0).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float y = arguments.get(1).visit(RealJassValueVisitor.getInstance()).floatValue(); - return new HandleJassValue(locationType, new Point2D.Double(x, y)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("RemoveLocation", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Point2D.Double whichLocation = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - System.err.println( - "RemoveRect called but in Java we don't have a destructor, so we need to unregister later when that is implemented"); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("MoveLocation", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Point2D.Double whichLocation = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final float x = arguments.get(1).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float y = arguments.get(2).visit(RealJassValueVisitor.getInstance()).floatValue(); - whichLocation.x = x; - whichLocation.y = y; - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetLocationX", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Point2D.Double whichLocation = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - return new RealJassValue(whichLocation.x); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetLocationY", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Point2D.Double whichLocation = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - return new RealJassValue(whichLocation.y); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetLocationZ", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Point2D.Double whichLocation = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - return new RealJassValue( - war3MapViewer.terrain.getGroundHeight((float) whichLocation.x, (float) whichLocation.y)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("IsUnitInRegion", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CRegion whichRegion = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final CUnit whichUnit = arguments.get(1).visit(ObjectJassValueVisitor.getInstance()); - return BooleanJassValue.of(whichUnit.isInRegion(whichRegion)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("IsPointInRegion", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CRegion whichRegion = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final float x = arguments.get(1).visit(RealJassValueVisitor.getInstance()).floatValue(); - final float y = arguments.get(2).visit(RealJassValueVisitor.getInstance()).floatValue(); - return BooleanJassValue.of(whichRegion.contains(x, y, simulation.getRegionManager())); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("IsLocationInRegion", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CRegion whichRegion = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final Point2D.Double whichLocation = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - return BooleanJassValue.of(whichRegion.contains((float) whichLocation.x, (float) whichLocation.y, - simulation.getRegionManager())); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetWorldBounds", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final float worldMinX = simulation.getPathingGrid().getWorldX(0) - 16f; - final float worldMinY = simulation.getPathingGrid().getWorldY(0) - 16f; - final float worldMaxX = simulation.getPathingGrid() - .getWorldX(simulation.getPathingGrid().getWidth() - 1) + 16f; - final float worldMaxY = simulation.getPathingGrid() - .getWorldY(simulation.getPathingGrid().getHeight() - 1) + 16f; - return new HandleJassValue(rectType, - new Rectangle(worldMinX, worldMinY, worldMaxX - worldMinX, worldMaxY - worldMinY)); - } - }); - // ============================================================================ - // Native trigger interface - // - setupTriggerAPI(jassProgramVisitor, triggerType, triggeractionType, triggerconditionType, boolexprType, - conditionfuncType, filterfuncType); - jassProgramVisitor.getJassNativeManager().createNative("GetFilterUnit", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(unitType, ((CommonTriggerExecutionScope) triggerScope).getFilterUnit()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetEnumUnit", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(unitType, ((CommonTriggerExecutionScope) triggerScope).getEnumUnit()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetFilterDestructable", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(destructableType, - ((CommonTriggerExecutionScope) triggerScope).getFilterDestructable()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetEnumDestructable", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(destructableType, - ((CommonTriggerExecutionScope) triggerScope).getEnumDestructable()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetFilterItem", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(itemType, ((CommonTriggerExecutionScope) triggerScope).getFilterItem()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetEnumItem", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(itemType, ((CommonTriggerExecutionScope) triggerScope).getEnumItem()); - } - }); - - // ============================================================================ - // Trigger Game Event API - // ============================================================================ - jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterVariableEvent", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final String varName = arguments.get(1).visit(ObjectJassValueVisitor.getInstance()); - final CLimitOp limitOp = arguments.get(2).visit(ObjectJassValueVisitor.getInstance()); - final Double limitval = arguments.get(3).visit(RealJassValueVisitor.getInstance()); - final RemovableTriggerEvent event = globalScope.registerVariableEvent(trigger, varName, limitOp, - limitval.doubleValue()); - return new HandleJassValue(eventType, event); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterTimerEvent", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final Double timeout = arguments.get(1).visit(RealJassValueVisitor.getInstance()); - final Boolean periodic = arguments.get(2).visit(BooleanJassValueVisitor.getInstance()); - final CTimerNativeEvent timer = new CTimerNativeEvent(globalScope, trigger); - timer.setRepeats(periodic.booleanValue()); - timer.setTimeoutTime(timeout.floatValue()); - simulation.registerTimer(timer); - return new HandleJassValue(eventType, new RemovableTriggerEvent() { - @Override - public void remove() { - simulation.unregisterTimer(timer); - } - }); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterTimerExpireEvent", - new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final CTimerJass timer = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - timer.addEvent(trigger); - return new HandleJassValue(eventType, new RemovableTriggerEvent() { - @Override - public void remove() { - timer.removeEvent(trigger); - } - }); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterGameStateEvent", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final CGameState whichState = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final CLimitOp opcode = arguments.get(2).visit(ObjectJassValueVisitor.getInstance()); - final Double limitval = arguments.get(2).visit(RealJassValueVisitor.getInstance()); - if (whichState != CGameState.TIME_OF_DAY) { - // TODO not yet impl - throw new UnsupportedOperationException("Not yet implemented: TriggerRegisterGameStateEvent"); - } - return new HandleJassValue(eventType, - simulation.registerTimeOfDayEvent(globalScope, trigger, opcode, limitval.doubleValue())); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterDialogEvent", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException("Not yet implemented: TriggerRegisterDialogEvent"); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterDialogButtonEvent", - new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException( - "Not yet implemented: TriggerRegisterDialogButtonEvent"); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetEventGameState", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException("Not yet implemented: GetEventGameState"); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterGameEvent", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException("Not yet implemented: TriggerRegisterGameEvent"); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetWinningPlayer", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException("Not yet implemented: GetWinningPlayer"); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterEnterRegion", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final CRegion region = arguments.get(1).visit(ObjectJassValueVisitor.getInstance()); - final TriggerBooleanExpression boolexpr = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - return new HandleJassValue(eventType, - region.add(new CRegionTriggerEnter(globalScope, trigger, boolexpr))); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetTriggeringRegion", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(unitType, - ((CommonTriggerExecutionScope) triggerScope).getEnteringUnit()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetEnteringUnit", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(unitType, - ((CommonTriggerExecutionScope) triggerScope).getEnteringUnit()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterLeaveRegion", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final CRegion region = arguments.get(1).visit(ObjectJassValueVisitor.getInstance()); - final TriggerBooleanExpression boolexpr = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - return new HandleJassValue(eventType, - region.add(new CRegionTriggerEnter(globalScope, trigger, boolexpr))); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetLeavingUnit", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(unitType, ((CommonTriggerExecutionScope) triggerScope).getLeavingUnit()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterTrackableHitEvent", - new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException( - "TriggerRegisterTrackableHitEvent not yet implemented ???"); - // dont feel like implementing this atm, although it probably wouldnt be that - // hard to do - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterTrackableTrackEvent", - new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException( - "TriggerRegisterTrackableTrackEvent not yet implemented ???"); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetTriggeringTrackable", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException("GetTriggeringTrackable not yet implemented ???"); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetClickedButton", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException("GetClickedButton not yet implemented ???"); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetClickedDialog", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException("GetClickedDialog not yet implemented ???"); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetTournamentFinishSoonTimeRemaining", - new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException( - "GetTournamentFinishSoonTimeRemaining not yet implemented ???"); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetTournamentFinishNowRule", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException("GetTournamentFinishNowRule not yet implemented ???"); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetTournamentFinishNowPlayer", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException("GetTournamentFinishNowPlayer not yet implemented ???"); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetTournamentScore", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException("GetTournamentScore not yet implemented ???"); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetSaveBasicFilename", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException("GetSaveBasicFilename not yet implemented ???"); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerRegisterPlayerEvent", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger whichTrigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final CPlayerJass whichPlayer = arguments.get(1).visit(ObjectJassValueVisitor.getInstance()); - final JassGameEventsWar3 whichPlayerEvent = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - return new HandleJassValue(eventType, - whichPlayer.addEvent(globalScope, whichTrigger, whichPlayerEvent)); - } - }); - } - - private void registerConfigNatives(final JassProgramVisitor jassProgramVisitor, final War3MapConfig mapConfig, - final HandleJassType startlocprioType, final HandleJassType gametypeType, - final HandleJassType placementType, final HandleJassType gamespeedType, - final HandleJassType gamedifficultyType, final HandleJassType mapdensityType, - final HandleJassType locationType, final HandleJassType playerType, - final HandleJassType playercolorType, final HandleJassType mapcontrolType, - final HandleJassType playerslotstateType, final CPlayerAPI playerAPI) { - jassProgramVisitor.getJassNativeManager().createNative("SetMapName", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String name = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - mapConfig.setMapName(name); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetMapDescription", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String name = arguments.get(0).visit(StringJassValueVisitor.getInstance()); - mapConfig.setMapDescription(name); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetTeams", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer teamCount = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - mapConfig.setTeamCount(teamCount); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetPlayers", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer playerCount = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - mapConfig.setPlayerCount(playerCount); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("DefineStartLocation", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - final Double x = arguments.get(1).visit(RealJassValueVisitor.getInstance()); - final Double y = arguments.get(2).visit(RealJassValueVisitor.getInstance()); - mapConfig.getStartLoc(whichStartLoc).setX(x.floatValue()); - mapConfig.getStartLoc(whichStartLoc).setY(y.floatValue()); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("DefineStartLocationLoc", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - final Point2D.Double whichLocation = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - mapConfig.getStartLoc(whichStartLoc).setX((float) whichLocation.x); - mapConfig.getStartLoc(whichStartLoc).setY((float) whichLocation.y); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetStartLocPrioCount", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - final Integer prioSlotCount = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - mapConfig.getStartLoc(whichStartLoc).setStartLocPrioCount(prioSlotCount); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetStartLocPrio", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - final Integer prioSlotIndex = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - final Integer otherStartLocIndex = arguments.get(2).visit(IntegerJassValueVisitor.getInstance()); - final CStartLocPrio priority = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - mapConfig.getStartLoc(whichStartLoc).setStartLocPrio(prioSlotIndex, otherStartLocIndex, priority); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetStartLocPrioSlot", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - final Integer prioSlotIndex = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - return new IntegerJassValue( - mapConfig.getStartLoc(whichStartLoc).getOtherStartIndices()[prioSlotIndex]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetStartLocPrio", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - final Integer prioSlotIndex = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(startlocprioType, - mapConfig.getStartLoc(whichStartLoc).getOtherStartLocPriorities()[prioSlotIndex]); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetGameTypeSupported", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CGameType gameType = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final Boolean value = arguments.get(1).visit(BooleanJassValueVisitor.getInstance()); - mapConfig.setGameTypeSupported(gameType, value); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetMapFlag", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CMapFlag mapFlag = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final Boolean value = arguments.get(1).visit(BooleanJassValueVisitor.getInstance()); - mapConfig.setMapFlag(mapFlag, value); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetGamePlacement", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CMapPlacement placement = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - mapConfig.setPlacement(placement); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetGameSpeed", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CGameSpeed gameSpeed = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - mapConfig.setGameSpeed(gameSpeed); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetGameDifficulty", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CMapDifficulty gameDifficulty = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - mapConfig.setGameDifficulty(gameDifficulty); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetResourceDensity", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CMapDensity resourceDensity = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - mapConfig.setResourceDensity(resourceDensity); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetCreatureDensity", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CMapDensity creatureDensity = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - mapConfig.setCreatureDensity(creatureDensity); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetTeams", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new IntegerJassValue(mapConfig.getTeamCount()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetPlayers", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new IntegerJassValue(mapConfig.getPlayerCount()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("IsGameTypeSupported", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CGameType gameType = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return new BooleanJassValue(mapConfig.isGameTypeSupported(gameType)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetGameTypeSelected", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(gametypeType, mapConfig.getGameTypeSelected()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("IsMapFlagSet", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CMapFlag mapFlag = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return new BooleanJassValue(mapConfig.isMapFlagSet(mapFlag)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetGamePlacement", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(placementType, mapConfig.getPlacement()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetGameSpeed", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(gamespeedType, mapConfig.getGameSpeed()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetGameDifficulty", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(gamedifficultyType, mapConfig.getGameDifficulty()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetResourceDensity", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(mapdensityType, mapConfig.getResourceDensity()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetCreatureDensity", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(mapdensityType, mapConfig.getCreatureDensity()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetStartLocationX", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new RealJassValue(mapConfig.getStartLoc(whichStartLoc).getX()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetStartLocationY", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new RealJassValue(mapConfig.getStartLoc(whichStartLoc).getY()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetStartLocationLoc", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Integer whichStartLoc = arguments.get(0).visit(IntegerJassValueVisitor.getInstance()); - return new HandleJassValue(locationType, new Point2D.Double( - mapConfig.getStartLoc(whichStartLoc).getX(), mapConfig.getStartLoc(whichStartLoc).getY())); - } - }); - // PlayerAPI - - jassProgramVisitor.getJassNativeManager().createNative("SetPlayerTeam", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final Integer whichTeam = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - player.setTeam(whichTeam); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetPlayerStartLocation", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final Integer startLocIndex = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - player.setStartLocationIndex(startLocIndex); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ForcePlayerStartLocation", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final Integer startLocIndex = arguments.get(1).visit(IntegerJassValueVisitor.getInstance()); - player.forceStartLocation(startLocIndex); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetPlayerColor", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final CPlayerColor playerColor = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - player.setColor(playerColor.ordinal()); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetPlayerAlliance", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final CPlayerJass otherPlayer = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final CAllianceType whichAllianceSetting = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - final Boolean value = arguments.get(3).visit(BooleanJassValueVisitor.getInstance()); - player.setAlliance(otherPlayer.getId(), whichAllianceSetting, value); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetPlayerTaxRate", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final CPlayerJass otherPlayer = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final CPlayerState whichResource = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - final int taxRate = arguments.get(3).visit(IntegerJassValueVisitor.getInstance()); - player.setTaxRate(otherPlayer.getId(), whichResource, taxRate); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetPlayerRacePreference", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final CRacePreference whichRacePreference = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - player.setRacePref(whichRacePreference); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetPlayerRaceSelectable", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final Boolean value = arguments.get(1).visit(BooleanJassValueVisitor.getInstance()); - player.setRaceSelectable(value); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetPlayerController", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final CMapControl controlType = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - player.setController(controlType); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetPlayerName", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final String name = arguments.get(1).visit(StringJassValueVisitor.getInstance()); - player.setName(name); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("SetPlayerOnScoreScreen", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final Boolean value = arguments.get(1).visit(BooleanJassValueVisitor.getInstance()); - player.setOnScoreScreen(value); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetPlayerTeam", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - return new IntegerJassValue(player.getTeam()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetPlayerStartLocation", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - return new IntegerJassValue(player.getStartLocationIndex()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetPlayerColor", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - return new HandleJassValue(playercolorType, CPlayerColor.getColorByIndex(player.getColor())); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetPlayerSelectable", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - return new BooleanJassValue(player.isSelectable()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetPlayerController", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - return new HandleJassValue(mapcontrolType, player.getController()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetPlayerSlotState", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - return new HandleJassValue(playerslotstateType, player.getController()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetPlayerTaxRate", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final CPlayerJass otherPlayer = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final CPlayerState whichResource = arguments.get(2) - .visit(ObjectJassValueVisitor.getInstance()); - return new IntegerJassValue(player.getTaxRate(otherPlayer.getId(), whichResource)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("IsPlayerRacePrefSet", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final CRacePreference racePref = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - return new BooleanJassValue(player.isRacePrefSet(racePref)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetPlayerName", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final CPlayerJass player = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - return new StringJassValue(player.getName()); - } - }); - } - } - - private static void setupTriggerAPI(final JassProgramVisitor jassProgramVisitor, final HandleJassType triggerType, - final HandleJassType triggeractionType, final HandleJassType triggerconditionType, - final HandleJassType boolexprType, final HandleJassType conditionfuncType, - final HandleJassType filterfuncType) { - // ============================================================================ - // Native trigger interface - // - jassProgramVisitor.getJassNativeManager().createNative("CreateTrigger", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(triggerType, new Trigger()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("DestroyTrigger", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - trigger.destroy(); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ResetTrigger", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - trigger.reset(); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("EnableTrigger", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - trigger.setEnabled(true); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("DisableTrigger", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - trigger.setEnabled(false); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("IsTriggerEnabled", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return BooleanJassValue.of(trigger.isEnabled()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerWaitOnSleeps", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final Boolean value = arguments.get(1).visit(BooleanJassValueVisitor.getInstance()); - trigger.setWaitOnSleeps(value.booleanValue()); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("IsTriggerWaitOnSleeps", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return BooleanJassValue.of(trigger.isWaitOnSleeps()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetTriggeringTrigger", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - return new HandleJassValue(triggerType, triggerScope.getTriggeringTrigger()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetTriggerEventId", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - throw new UnsupportedOperationException("GetTriggerEventId not yet implemented ???"); - // TODO I need to review what eventid is, I'm forgetting, sorry - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetTriggerEvalCount", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return new IntegerJassValue(trigger.getEvalCount()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("GetTriggerExecCount", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger trigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - return new IntegerJassValue(trigger.getExecCount()); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("ExecuteFunc", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final String funcName = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final JassFunction functionByName = globalScope.getFunctionByName(funcName); - if (functionByName != null) { - // TODO below TriggerExecutionScope.EMPTY is probably not correct - functionByName.call(Collections.emptyList(), globalScope, TriggerExecutionScope.EMPTY); - } - return null; - } - }); - - // ============================================================================ - // Boolean Expr API ( for compositing trigger conditions and unit filter - // funcs...) - // ============================================================================ - jassProgramVisitor.getJassNativeManager().createNative("And", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final TriggerBooleanExpression operandA = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final TriggerBooleanExpression operandB = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - return new HandleJassValue(boolexprType, new BoolExprAnd(operandA, operandB)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Or", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final TriggerBooleanExpression operandA = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - final TriggerBooleanExpression operandB = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - return new HandleJassValue(boolexprType, new BoolExprOr(operandA, operandB)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Not", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final TriggerBooleanExpression operand = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - return new HandleJassValue(boolexprType, new BoolExprNot(operand)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Condition", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final JassFunction func = arguments.get(0).visit(JassFunctionJassValueVisitor.getInstance()); - return new HandleJassValue(conditionfuncType, new BoolExprCondition(func)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("DestroyCondition", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final BoolExprCondition condition = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - System.err.println( - "DestroyCondition called but in Java we don't have a destructor, so we need to unregister later when that is implemented"); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("Filter", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final JassFunction func = arguments.get(0).visit(JassFunctionJassValueVisitor.getInstance()); - return new HandleJassValue(filterfuncType, new BoolExprFilter(func)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("DestroyFilter", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final BoolExprFilter filter = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - System.err.println( - "DestroyFilter called but in Java we don't have a destructor, so we need to unregister later when that is implemented"); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("DestroyBoolExpr", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final TriggerBooleanExpression boolexpr = arguments.get(0) - .visit(ObjectJassValueVisitor.getInstance()); - System.err.println( - "DestroyBoolExpr called but in Java we don't have a destructor, so we need to unregister later when that is implemented"); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerAddCondition", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger whichTrigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final TriggerBooleanExpression condition = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - final int index = whichTrigger.addCondition(condition); - return new HandleJassValue(triggerconditionType, new TriggerCondition(condition, whichTrigger, index)); - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerRemoveCondition", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger whichTrigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final TriggerCondition condition = arguments.get(1) - .visit(ObjectJassValueVisitor.getInstance()); - if (condition.getTrigger() != whichTrigger) { - throw new IllegalArgumentException("Unable to remove condition, wrong trigger"); - } - whichTrigger.removeConditionAtIndex(condition.getConditionIndex()); - return null; - } - }); - jassProgramVisitor.getJassNativeManager().createNative("TriggerAddAction", new JassFunction() { - @Override - public JassValue call(final List arguments, final GlobalScope globalScope, - final TriggerExecutionScope triggerScope) { - final Trigger whichTrigger = arguments.get(0).visit(ObjectJassValueVisitor.getInstance()); - final JassFunction actionFunc = arguments.get(1).visit(JassFunctionJassValueVisitor.getInstance()); - final int actionIndex = whichTrigger.addAction(actionFunc); - return new HandleJassValue(triggeractionType, new TriggerAction(whichTrigger, actionFunc, actionIndex)); - } - }); - } -} diff --git a/core/src/com/etheller/warsmash/parsers/jass/JassTest.java b/core/src/com/etheller/warsmash/parsers/jass/JassTest.java deleted file mode 100644 index 629dd51f..00000000 --- a/core/src/com/etheller/warsmash/parsers/jass/JassTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.etheller.warsmash.parsers.jass; - -import java.io.IOException; -import java.util.Arrays; - -import org.antlr.v4.runtime.BaseErrorListener; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; - -import com.etheller.interpreter.JassLexer; -import com.etheller.interpreter.JassParser; -import com.etheller.interpreter.ast.visitors.JassProgramVisitor; -import com.etheller.warsmash.datasources.CompoundDataSourceDescriptor; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.datasources.DataSourceDescriptor; -import com.etheller.warsmash.datasources.FolderDataSourceDescriptor; - -public class JassTest { - public static final boolean REPORT_SYNTAX_ERRORS = true; - - public static void main(final String[] args) { - final JassProgramVisitor jassProgramVisitor = new JassProgramVisitor(); - try { - final FolderDataSourceDescriptor war3mpq = new FolderDataSourceDescriptor( - "E:\\Backups\\Warcraft\\Data\\127"); - final FolderDataSourceDescriptor testingFolder = new FolderDataSourceDescriptor( - "E:\\Backups\\Warsmash\\Data"); - final FolderDataSourceDescriptor currentFolder = new FolderDataSourceDescriptor("."); - final DataSource dataSource = new CompoundDataSourceDescriptor( - Arrays.asList(war3mpq, testingFolder, currentFolder)).createDataSource(); - JassLexer lexer; - try { - lexer = new JassLexer(CharStreams.fromStream(dataSource.getResourceAsStream("Scripts\\common.j"))); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - final JassParser parser = new JassParser(new CommonTokenStream(lexer)); - parser.addErrorListener(new BaseErrorListener() { - @Override - public void syntaxError(final Recognizer recognizer, final Object offendingSymbol, final int line, - final int charPositionInLine, final String msg, final RecognitionException e) { - if (!REPORT_SYNTAX_ERRORS) { - return; - } - - String sourceName = recognizer.getInputStream().getSourceName(); - if (!sourceName.isEmpty()) { - sourceName = String.format("%s:%d:%d: ", sourceName, line, charPositionInLine); - } - - System.err.println(sourceName + "line " + line + ":" + charPositionInLine + " " + msg); - } - }); - jassProgramVisitor.visit(parser.program()); - } - catch (final Exception e) { - e.printStackTrace(); - } - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/jass/Tmpgen.java b/core/src/com/etheller/warsmash/parsers/jass/Tmpgen.java deleted file mode 100644 index 7d327903..00000000 --- a/core/src/com/etheller/warsmash/parsers/jass/Tmpgen.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.etheller.warsmash.parsers.jass; - -import java.util.Scanner; - -public class Tmpgen { - - public static void main(final String[] args) { - // final HandleJassType eventType = globals.registerHandleType("event"); - - final Scanner scanner = new Scanner(System.in); - while (scanner.hasNextLine()) { - final String line = scanner.nextLine(); - if (line.startsWith("type ")) { - final String[] splitLine = line.split("\\s+"); - System.out.println("final HandleJassType " + splitLine[1] + "Type = globals.registerHandleType(\"" - + splitLine[1] + "\");"); - } - } - - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/jass/Tmpgen2.java b/core/src/com/etheller/warsmash/parsers/jass/Tmpgen2.java deleted file mode 100644 index b9124c16..00000000 --- a/core/src/com/etheller/warsmash/parsers/jass/Tmpgen2.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.etheller.warsmash.parsers.jass; - -import java.util.Scanner; - -public class Tmpgen2 { - - public static void main(final String[] args) { - // final HandleJassType eventType = globals.registerHandleType("event"); - - final Scanner scanner = new Scanner(System.in); - while (scanner.hasNextLine()) { - final String line = scanner.nextLine(); - final String[] splitLine = line.trim().split("\\s+"); - if (line.trim().startsWith("//")) { - System.out.println(line); - } - else { - if (splitLine.length > 3) { - System.out.println(splitLine[2] + ","); - } - else { - System.out.println(); - } - } - } - - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/jass/scope/CommonTriggerExecutionScope.java b/core/src/com/etheller/warsmash/parsers/jass/scope/CommonTriggerExecutionScope.java deleted file mode 100644 index 492cfc66..00000000 --- a/core/src/com/etheller/warsmash/parsers/jass/scope/CommonTriggerExecutionScope.java +++ /dev/null @@ -1,412 +0,0 @@ -package com.etheller.warsmash.parsers.jass.scope; - -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.scope.trigger.Trigger; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerJass; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.region.CRegion; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.timers.CTimerJass; - -public class CommonTriggerExecutionScope extends TriggerExecutionScope { - private CUnit triggeringUnit; - private CUnit filterUnit; - private CUnit enumUnit; - private CDestructable filterDestructable; - private CDestructable enumDestructable; - private CItem filterItem; - private CItem enumItem; - private CPlayerJass filterPlayer; - private CPlayerJass enumPlayer; - private CTimerJass expiringTimer; - private CUnit enteringUnit; - private CUnit leavingUnit; - private CRegion triggeringRegion; - private CPlayerJass triggeringPlayer; - private CUnit levelingUnit; - private CUnit learningUnit; - private int learnedSkill; - private int learnedSkillLevel; - private CUnit revivableUnit; - private CUnit revivingUnit; - private CUnit attacker; - private CUnit rescuer; - private CUnit dyingUnit; - private CUnit killingUnit; - private CUnit decayingUnit; - private CUnit constructingStructure; - private CUnit cancelledStructure; - private CUnit constructedStructure; - private CUnit researchingUnit; - private int researched; - private int trainedUnitType; - private CUnit trainedUnit; - private CUnit detectedUnit; - private CUnit summoningUnit; - private CUnit summonedUnit; - private CUnit transportUnit; - private CUnit loadedUnit; - private CUnit sellingUnit; - private CUnit soldUnit; - private CUnit buyingUnit; - private CUnit soldItem; - private CUnit changingUnit; - private CPlayerJass changingUnitPrevOwner; - private CUnit manipulatingUnit; - private CItem manipulatedItem; - private CUnit orderedUnit; - private int issuedOrderId; - private float orderPointX; - private float orderPointY; - private CWidget orderTarget; - private CDestructable orderTargetDestructable; - private CItem orderTargetItem; - private CUnit orderTargetUnit; - - public CommonTriggerExecutionScope(final Trigger triggeringTrigger) { - super(triggeringTrigger); - } - - public CommonTriggerExecutionScope(final TriggerExecutionScope parentScope) { - super(parentScope.getTriggeringTrigger()); - if (parentScope instanceof CommonTriggerExecutionScope) { - copyFrom((CommonTriggerExecutionScope) parentScope); - } - } - - public CommonTriggerExecutionScope(final CommonTriggerExecutionScope parentScope) { - super(parentScope.getTriggeringTrigger()); - copyFrom(parentScope); - } - - private void copyFrom(final CommonTriggerExecutionScope parentScope) { - this.triggeringUnit = parentScope.triggeringUnit; - this.filterUnit = parentScope.filterUnit; - this.enumUnit = parentScope.enumUnit; - this.filterDestructable = parentScope.filterDestructable; - this.enumDestructable = parentScope.enumDestructable; - this.filterItem = parentScope.filterItem; - this.enumItem = parentScope.enumItem; - this.filterPlayer = parentScope.filterPlayer; - this.enumPlayer = parentScope.enumPlayer; - this.expiringTimer = parentScope.expiringTimer; - this.enteringUnit = parentScope.enteringUnit; - this.leavingUnit = parentScope.leavingUnit; - this.triggeringRegion = parentScope.triggeringRegion; - this.triggeringPlayer = parentScope.triggeringPlayer; - this.levelingUnit = parentScope.levelingUnit; - this.learningUnit = parentScope.learningUnit; - this.learnedSkill = parentScope.learnedSkill; - this.learnedSkillLevel = parentScope.learnedSkillLevel; - this.revivableUnit = parentScope.revivableUnit; - this.attacker = parentScope.attacker; - this.rescuer = parentScope.rescuer; - this.dyingUnit = parentScope.dyingUnit; - this.killingUnit = parentScope.killingUnit; - this.decayingUnit = parentScope.decayingUnit; - this.constructingStructure = parentScope.constructingStructure; - this.cancelledStructure = parentScope.cancelledStructure; - this.constructedStructure = parentScope.constructedStructure; - this.researchingUnit = parentScope.researchingUnit; - this.researched = parentScope.researched; - this.trainedUnitType = parentScope.trainedUnitType; - this.trainedUnit = parentScope.trainedUnit; - this.detectedUnit = parentScope.detectedUnit; - this.summoningUnit = parentScope.summoningUnit; - this.summonedUnit = parentScope.summonedUnit; - this.transportUnit = parentScope.transportUnit; - this.loadedUnit = parentScope.loadedUnit; - this.sellingUnit = parentScope.sellingUnit; - this.soldUnit = parentScope.soldUnit; - this.buyingUnit = parentScope.buyingUnit; - this.soldItem = parentScope.soldItem; - this.changingUnit = parentScope.changingUnit; - this.changingUnitPrevOwner = parentScope.changingUnitPrevOwner; - this.manipulatingUnit = parentScope.manipulatingUnit; - this.manipulatedItem = parentScope.manipulatedItem; - this.orderedUnit = parentScope.orderedUnit; - this.issuedOrderId = parentScope.issuedOrderId; - this.orderPointX = parentScope.orderPointX; - this.orderPointY = parentScope.orderPointY; - this.orderTarget = parentScope.orderTarget; - this.orderTargetDestructable = parentScope.orderTargetDestructable; - this.orderTargetItem = parentScope.orderTargetItem; - this.orderTargetUnit = parentScope.orderTargetUnit; - } - - public CUnit getEnumUnit() { - return this.enumUnit; - } - - public CUnit getTriggeringUnit() { - return this.triggeringUnit; - } - - public CUnit getFilterUnit() { - return this.filterUnit; - } - - public CDestructable getFilterDestructable() { - return this.filterDestructable; - } - - public CDestructable getEnumDestructable() { - return this.enumDestructable; - } - - public CItem getFilterItem() { - return this.filterItem; - } - - public CItem getEnumItem() { - return this.enumItem; - } - - public CPlayerJass getFilterPlayer() { - return this.filterPlayer; - } - - public CPlayerJass getEnumPlayer() { - return this.enumPlayer; - } - - public CTimerJass getExpiringTimer() { - return this.expiringTimer; - } - - public CUnit getEnteringUnit() { - return this.enteringUnit; - } - - public CUnit getLeavingUnit() { - return this.leavingUnit; - } - - public CRegion getTriggeringRegion() { - return this.triggeringRegion; - } - - public CPlayerJass getTriggeringPlayer() { - return this.triggeringPlayer; - } - - public CUnit getLevelingUnit() { - return this.levelingUnit; - } - - public CUnit getLearningUnit() { - return this.learningUnit; - } - - public int getLearnedSkill() { - return this.learnedSkill; - } - - public int getLearnedSkillLevel() { - return this.learnedSkillLevel; - } - - public CUnit getRevivableUnit() { - return this.revivableUnit; - } - - public CUnit getRevivingUnit() { - return this.revivingUnit; - } - - public CUnit getAttacker() { - return this.attacker; - } - - public CUnit getRescuer() { - return this.rescuer; - } - - public CUnit getDyingUnit() { - return this.dyingUnit; - } - - public CUnit getKillingUnit() { - return this.killingUnit; - } - - public CUnit getDecayingUnit() { - return this.decayingUnit; - } - - public CUnit getConstructingStructure() { - return this.constructingStructure; - } - - public CUnit getCancelledStructure() { - return this.cancelledStructure; - } - - public CUnit getConstructedStructure() { - return this.constructedStructure; - } - - public CUnit getResearchingUnit() { - return this.researchingUnit; - } - - public int getResearched() { - return this.researched; - } - - public int getTrainedUnitType() { - return this.trainedUnitType; - } - - public CUnit getTrainedUnit() { - return this.trainedUnit; - } - - public CUnit getDetectedUnit() { - return this.detectedUnit; - } - - public CUnit getSummoningUnit() { - return this.summoningUnit; - } - - public CUnit getSummonedUnit() { - return this.summonedUnit; - } - - public CUnit getTransportUnit() { - return this.transportUnit; - } - - public CUnit getLoadedUnit() { - return this.loadedUnit; - } - - public CUnit getSellingUnit() { - return this.sellingUnit; - } - - public CUnit getSoldUnit() { - return this.soldUnit; - } - - public CUnit getBuyingUnit() { - return this.buyingUnit; - } - - public CUnit getSoldItem() { - return this.soldItem; - } - - public CUnit getChangingUnit() { - return this.changingUnit; - } - - public CPlayerJass getChangingUnitPrevOwner() { - return this.changingUnitPrevOwner; - } - - public CUnit getManipulatingUnit() { - return this.manipulatingUnit; - } - - public CItem getManipulatedItem() { - return this.manipulatedItem; - } - - public CUnit getOrderedUnit() { - return this.orderedUnit; - } - - public int getIssuedOrderId() { - return this.issuedOrderId; - } - - public float getOrderPointX() { - return this.orderPointX; - } - - public float getOrderPointY() { - return this.orderPointY; - } - - public CWidget getOrderTarget() { - return this.orderTarget; - } - - public CDestructable getOrderTargetDestructable() { - return this.orderTargetDestructable; - } - - public CItem getOrderTargetItem() { - return this.orderTargetItem; - } - - public CUnit getOrderTargetUnit() { - return this.orderTargetUnit; - } - - public static CommonTriggerExecutionScope filterScope(final TriggerExecutionScope parentScope, - final CUnit filterUnit) { - final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(parentScope); - scope.filterUnit = filterUnit; - return scope; - } - - public static CommonTriggerExecutionScope enumScope(final TriggerExecutionScope parentScope, final CUnit enumUnit) { - final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(parentScope); - scope.enumUnit = enumUnit; - return scope; - } - - public static CommonTriggerExecutionScope filterScope(final TriggerExecutionScope parentScope, - final CPlayerJass filterPlayer) { - final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(parentScope); - scope.filterPlayer = filterPlayer; - return scope; - } - - public static CommonTriggerExecutionScope enumScope(final TriggerExecutionScope parentScope, - final CPlayerJass enumPlayer) { - final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(parentScope); - scope.enumPlayer = enumPlayer; - return scope; - } - - public static CommonTriggerExecutionScope expiringTimer(final CTimerJass cTimerJass) { - final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(TriggerExecutionScope.EMPTY); - scope.expiringTimer = cTimerJass; - return scope; - } - - public static CommonTriggerExecutionScope unitEnterRegionScope(final TriggerExecutionScope parentScope, - final CUnit enteringUnit, final CRegion triggeringRegion) { - final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(parentScope); - scope.enteringUnit = enteringUnit; - scope.triggeringRegion = triggeringRegion; - return scope; - } - - public static CommonTriggerExecutionScope unitLeaveRegionScope(final TriggerExecutionScope parentScope, - final CUnit leavingUnit, final CRegion triggeringRegion) { - final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(parentScope); - scope.leavingUnit = leavingUnit; - scope.triggeringRegion = triggeringRegion; - return scope; - } - - public static CommonTriggerExecutionScope playerHeroLevelScope(final CUnit hero) { - final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(TriggerExecutionScope.EMPTY); - scope.levelingUnit = hero; - return scope; - } - - public static CommonTriggerExecutionScope playerHeroRevivableScope(final CUnit hero) { - final CommonTriggerExecutionScope scope = new CommonTriggerExecutionScope(TriggerExecutionScope.EMPTY); - scope.revivableUnit = hero; - return scope; - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprAnd.java b/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprAnd.java deleted file mode 100644 index 26deb4e1..00000000 --- a/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprAnd.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.etheller.warsmash.parsers.jass.triggers; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.scope.trigger.TriggerBooleanExpression; - -public class BoolExprAnd implements TriggerBooleanExpression { - private final TriggerBooleanExpression operandA; - private final TriggerBooleanExpression operandB; - - public BoolExprAnd(final TriggerBooleanExpression operandA, final TriggerBooleanExpression operandB) { - this.operandA = operandA; - this.operandB = operandB; - } - - @Override - public boolean evaluate(final GlobalScope globalScope, final TriggerExecutionScope triggerScope) { - return this.operandA.evaluate(globalScope, triggerScope) && this.operandB.evaluate(globalScope, triggerScope); - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprCondition.java b/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprCondition.java deleted file mode 100644 index 34ef2922..00000000 --- a/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprCondition.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.etheller.warsmash.parsers.jass.triggers; - -import java.util.Collections; - -import com.etheller.interpreter.ast.function.JassFunction; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.scope.trigger.TriggerBooleanExpression; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.visitor.BooleanJassValueVisitor; - -public class BoolExprCondition implements TriggerBooleanExpression { - private final JassFunction takesNothingReturnsBooleanFunction; - - public BoolExprCondition(final JassFunction returnsBooleanFunction) { - this.takesNothingReturnsBooleanFunction = returnsBooleanFunction; - } - - @Override - public boolean evaluate(final GlobalScope globalScope, final TriggerExecutionScope triggerScope) { - final JassValue booleanJassReturnValue = this.takesNothingReturnsBooleanFunction.call(Collections.EMPTY_LIST, - globalScope, triggerScope); - final Boolean booleanReturnValue = booleanJassReturnValue.visit(BooleanJassValueVisitor.getInstance()); - return booleanReturnValue.booleanValue(); - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprFilter.java b/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprFilter.java deleted file mode 100644 index b3a6e273..00000000 --- a/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprFilter.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.etheller.warsmash.parsers.jass.triggers; - -import java.util.Collections; - -import com.etheller.interpreter.ast.function.JassFunction; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.scope.trigger.TriggerBooleanExpression; -import com.etheller.interpreter.ast.value.JassValue; -import com.etheller.interpreter.ast.value.visitor.BooleanJassValueVisitor; - -public class BoolExprFilter implements TriggerBooleanExpression { - private final JassFunction takesNothingReturnsBooleanFunction; - - public BoolExprFilter(final JassFunction returnsBooleanFunction) { - this.takesNothingReturnsBooleanFunction = returnsBooleanFunction; - } - - @Override - public boolean evaluate(final GlobalScope globalScope, final TriggerExecutionScope triggerScope) { - final JassValue booleanJassReturnValue = this.takesNothingReturnsBooleanFunction.call(Collections.EMPTY_LIST, - globalScope, triggerScope); - final Boolean booleanReturnValue = booleanJassReturnValue.visit(BooleanJassValueVisitor.getInstance()); - return booleanReturnValue.booleanValue(); - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprNot.java b/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprNot.java deleted file mode 100644 index 0f2cc52e..00000000 --- a/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprNot.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.etheller.warsmash.parsers.jass.triggers; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.scope.trigger.TriggerBooleanExpression; - -public class BoolExprNot implements TriggerBooleanExpression { - private final TriggerBooleanExpression operand; - - public BoolExprNot(final TriggerBooleanExpression operand) { - this.operand = operand; - } - - @Override - public boolean evaluate(final GlobalScope globalScope, final TriggerExecutionScope triggerScope) { - return this.operand.evaluate(globalScope, triggerScope); - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprOr.java b/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprOr.java deleted file mode 100644 index a59cd83e..00000000 --- a/core/src/com/etheller/warsmash/parsers/jass/triggers/BoolExprOr.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.etheller.warsmash.parsers.jass.triggers; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.scope.trigger.TriggerBooleanExpression; - -public class BoolExprOr implements TriggerBooleanExpression { - private final TriggerBooleanExpression operandA; - private final TriggerBooleanExpression operandB; - - public BoolExprOr(final TriggerBooleanExpression operandA, final TriggerBooleanExpression operandB) { - this.operandA = operandA; - this.operandB = operandB; - } - - @Override - public boolean evaluate(final GlobalScope globalScope, final TriggerExecutionScope triggerScope) { - return this.operandA.evaluate(globalScope, triggerScope) || this.operandB.evaluate(globalScope, triggerScope); - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/jass/triggers/TriggerAction.java b/core/src/com/etheller/warsmash/parsers/jass/triggers/TriggerAction.java deleted file mode 100644 index 7620f13e..00000000 --- a/core/src/com/etheller/warsmash/parsers/jass/triggers/TriggerAction.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.etheller.warsmash.parsers.jass.triggers; - -import com.etheller.interpreter.ast.function.JassFunction; -import com.etheller.interpreter.ast.scope.trigger.Trigger; - -public class TriggerAction { - private final Trigger trigger; - private final JassFunction actionFunc; - private final int actionIndex; - - public TriggerAction(final Trigger trigger, final JassFunction actionFunc, final int actionIndex) { - this.trigger = trigger; - this.actionFunc = actionFunc; - this.actionIndex = actionIndex; - } - - public Trigger getTrigger() { - return this.trigger; - } - - public JassFunction getActionFunc() { - return this.actionFunc; - } - - public int getActionIndex() { - return this.actionIndex; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/jass/triggers/TriggerCondition.java b/core/src/com/etheller/warsmash/parsers/jass/triggers/TriggerCondition.java deleted file mode 100644 index 8ee32d73..00000000 --- a/core/src/com/etheller/warsmash/parsers/jass/triggers/TriggerCondition.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.etheller.warsmash.parsers.jass.triggers; - -import com.etheller.interpreter.ast.scope.trigger.Trigger; -import com.etheller.interpreter.ast.scope.trigger.TriggerBooleanExpression; - -public class TriggerCondition { - private final TriggerBooleanExpression boolexpr; - private final Trigger trigger; - private final int conditionIndex; - - public TriggerCondition(final TriggerBooleanExpression boolexpr, final Trigger trigger, final int index) { - this.boolexpr = boolexpr; - this.trigger = trigger; - this.conditionIndex = index; - } - - public TriggerBooleanExpression getBoolexpr() { - return this.boolexpr; - } - - public Trigger getTrigger() { - return this.trigger; - } - - public int getConditionIndex() { - return this.conditionIndex; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/terrain/Corner.java b/core/src/com/etheller/warsmash/parsers/terrain/Corner.java deleted file mode 100644 index f3f71f2b..00000000 --- a/core/src/com/etheller/warsmash/parsers/terrain/Corner.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.etheller.warsmash.parsers.terrain; - -public class Corner { - boolean mapEdge; - - int groundTexture; - float height; - float waterHeight; - boolean ramp; - boolean blight; - boolean water; - boolean boundary; - boolean cliff; - boolean romp; - int groundVariation; - int cliffVariation; - int cliffTexture; - int layerHeight; - - public float finalGroundHeight() { - return 0; - } - - public float finalWaterHeight() { - return 0; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/terrain/Terrain.java b/core/src/com/etheller/warsmash/parsers/terrain/Terrain.java deleted file mode 100644 index 950474b4..00000000 --- a/core/src/com/etheller/warsmash/parsers/terrain/Terrain.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.parsers.terrain; - -import com.badlogic.gdx.utils.FloatArray; - -public class Terrain { - private FloatArray groundHeights; - private FloatArray groundCornerHeights; - - private FloatArray waterHeights; - - public Terrain() { - } -} diff --git a/core/src/com/etheller/warsmash/parsers/terrain/TilePathing.java b/core/src/com/etheller/warsmash/parsers/terrain/TilePathing.java deleted file mode 100644 index 1c2d6610..00000000 --- a/core/src/com/etheller/warsmash/parsers/terrain/TilePathing.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.etheller.warsmash.parsers.terrain; - -public class TilePathing { - boolean unwalkable = false; - boolean unflyable = false; - boolean unbuildable = false; - - public byte mask() { - byte mask = 0; - mask |= this.unwalkable ? 0b00000010 : 0; - mask |= this.unflyable ? 0b00000100 : 0; - mask |= this.unbuildable ? 0b00001000 : 0; - return mask; - } -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/parsers/w3x/War3Map.java b/core/src/com/etheller/warsmash/parsers/w3x/War3Map.java deleted file mode 100644 index 409d53a7..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/War3Map.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.etheller.warsmash.parsers.w3x; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.channels.SeekableByteChannel; -import java.util.Arrays; -import java.util.Collection; - -import org.apache.commons.compress.utils.IOUtils; -import org.apache.commons.compress.utils.SeekableInMemoryByteChannel; - -import com.etheller.warsmash.datasources.CompoundDataSource; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.datasources.MpqDataSource; -import com.etheller.warsmash.parsers.w3x.doo.War3MapDoo; -import com.etheller.warsmash.parsers.w3x.objectdata.Warcraft3MapObjectData; -import com.etheller.warsmash.parsers.w3x.unitsdoo.War3MapUnitsDoo; -import com.etheller.warsmash.parsers.w3x.w3e.War3MapW3e; -import com.etheller.warsmash.parsers.w3x.w3i.War3MapW3i; -import com.etheller.warsmash.parsers.w3x.wpm.War3MapWpm; -import com.etheller.warsmash.units.custom.WTS; -import com.google.common.io.LittleEndianDataInputStream; - -import mpq.MPQArchive; -import mpq.MPQException; - -/** - * Warcraft 3 map (W3X and W3M). - */ -public class War3Map implements DataSource { - - private CompoundDataSource dataSource; - private MpqDataSource internalMpqContentsDataSource; - - public War3Map(final DataSource dataSource, final String mapFileName) { - try { - // Slightly complex. Here's the theory: - // 1.) Copy map into RAM - // 2.) Setup a Data Source that will read assets - // from either the map or the game, giving the map priority. - SeekableByteChannel sbc; - try (InputStream mapStream = dataSource.getResourceAsStream(mapFileName)) { - final byte[] mapData = IOUtils.toByteArray(mapStream); - sbc = new SeekableInMemoryByteChannel(mapData); - this.internalMpqContentsDataSource = new MpqDataSource(new MPQArchive(sbc), sbc); - this.dataSource = new CompoundDataSource(Arrays.asList(dataSource, this.internalMpqContentsDataSource)); - } - } - catch (final IOException e) { - throw new RuntimeException(e); - } - catch (final MPQException e) { - throw new RuntimeException(e); - } - } - - public War3MapW3i readMapInformation() throws IOException { - War3MapW3i mapInfo; - try (LittleEndianDataInputStream stream = new LittleEndianDataInputStream( - this.dataSource.getResourceAsStream("war3map.w3i"))) { - mapInfo = new War3MapW3i(stream); - } - return mapInfo; - } - - public War3MapW3e readEnvironment() throws IOException { - War3MapW3e environment; - try (LittleEndianDataInputStream stream = new LittleEndianDataInputStream( - this.dataSource.getResourceAsStream("war3map.w3e"))) { - environment = new War3MapW3e(stream); - } - return environment; - } - - public War3MapWpm readPathing() throws IOException { - War3MapWpm pathingMap; - try (LittleEndianDataInputStream stream = new LittleEndianDataInputStream( - this.dataSource.getResourceAsStream("war3map.wpm"))) { - pathingMap = new War3MapWpm(stream); - } - return pathingMap; - } - - public War3MapDoo readDoodads() throws IOException { - War3MapDoo doodadsFile; - try (LittleEndianDataInputStream stream = new LittleEndianDataInputStream( - this.dataSource.getResourceAsStream("war3map.doo"))) { - doodadsFile = new War3MapDoo(stream); - } - return doodadsFile; - } - - public War3MapUnitsDoo readUnits() throws IOException { - War3MapUnitsDoo unitsFile; - try (LittleEndianDataInputStream stream = new LittleEndianDataInputStream( - this.dataSource.getResourceAsStream("war3mapUnits.doo"))) { - unitsFile = new War3MapUnitsDoo(stream); - } - return unitsFile; - } - - public Warcraft3MapObjectData readModifications() throws IOException { - final Warcraft3MapObjectData changes = Warcraft3MapObjectData.load(this.dataSource, true); - return changes; - } - - public Warcraft3MapObjectData readModifications(final WTS preloadedWTS) throws IOException { - final Warcraft3MapObjectData changes = Warcraft3MapObjectData.load(this.dataSource, true, preloadedWTS); - return changes; - } - - @Override - public InputStream getResourceAsStream(final String filepath) throws IOException { - return this.dataSource.getResourceAsStream(filepath); - } - - @Override - public File getFile(final String filepath) throws IOException { - return this.dataSource.getFile(filepath); - } - - @Override - public boolean has(final String filepath) { - return this.dataSource.has(filepath); - } - - @Override - public ByteBuffer read(final String path) throws IOException { - return this.dataSource.read(path); - } - - @Override - public Collection getListfile() { - return this.internalMpqContentsDataSource.getListfile(); - } - - @Override - public void close() throws IOException { - this.dataSource.close(); - } - - public CompoundDataSource getCompoundDataSource() { - return this.dataSource; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/doo/Doodad.java b/core/src/com/etheller/warsmash/parsers/w3x/doo/Doodad.java deleted file mode 100644 index 913e388e..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/doo/Doodad.java +++ /dev/null @@ -1,157 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.doo; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class Doodad { - private War3ID id; - private int variation; - private final float[] location = new float[3]; - private float angle; - private final float[] scale = { 1f, 1f, 1f }; - private short flags; // short to store unsigned byte, java problem - private short life; // short to store unsigned byte, java problem - private long itemTable = -1; // long to store unsigned int32, java problem - private final List itemSets = new ArrayList<>(); - private int editorId; - private final short[] u1 = new short[8]; // short to store unsigned byte, java problem - - public void load(final LittleEndianDataInputStream stream, final int version) throws IOException { - this.id = ParseUtils.readWar3ID(stream); - this.variation = stream.readInt(); - ParseUtils.readFloatArray(stream, this.location); - this.angle = stream.readFloat(); - ParseUtils.readFloatArray(stream, this.scale); - this.flags = ParseUtils.readUInt8(stream); - this.life = ParseUtils.readUInt8(stream); - - if (version > 7) { - this.itemTable = ParseUtils.readUInt32(stream); - - for (long i = 0, l = ParseUtils.readUInt32(stream); i < l; i++) { - final RandomItemSet itemSet = new RandomItemSet(); - - itemSet.load(stream); - - this.itemSets.add(itemSet); - } - } - - this.editorId = stream.readInt(); - } - - public void save(final LittleEndianDataOutputStream stream, final int version) throws IOException { - ParseUtils.writeWar3ID(stream, this.id); - ; - stream.writeInt(this.variation); - ParseUtils.writeFloatArray(stream, this.location); - stream.writeFloat(this.angle); - ParseUtils.writeFloatArray(stream, this.scale); - ParseUtils.writeUInt8(stream, this.flags); - ParseUtils.writeUInt8(stream, this.life); - - if (version > 7) { - ParseUtils.writeUInt32(stream, this.itemTable); - ParseUtils.writeUInt32(stream, this.itemSets.size()); - - for (final RandomItemSet itemSet : this.itemSets) { - itemSet.save(stream); - } - } - - stream.writeInt(this.editorId); - } - - public int getByteLength(final int version) { - int size = 42; - - if (version > 7) { - size += 8; - - for (final RandomItemSet itemSet : this.itemSets) { - size += itemSet.getByteLength(); - } - } - - return size; - } - - public War3ID getId() { - return this.id; - } - - public void setId(final War3ID id) { - this.id = id; - } - - public int getVariation() { - return this.variation; - } - - public void setVariation(final int variation) { - this.variation = variation; - } - - public float getAngle() { - return this.angle; - } - - public void setAngle(final float angle) { - this.angle = angle; - } - - public short getFlags() { - return this.flags; - } - - public void setFlags(final short flags) { - this.flags = flags; - } - - public short getLife() { - return this.life; - } - - public void setLife(final short life) { - this.life = life; - } - - public long getItemTable() { - return this.itemTable; - } - - public void setItemTable(final long itemTable) { - this.itemTable = itemTable; - } - - public int getEditorId() { - return this.editorId; - } - - public void setEditorId(final int editorId) { - this.editorId = editorId; - } - - public float[] getLocation() { - return this.location; - } - - public float[] getScale() { - return this.scale; - } - - public List getItemSets() { - return this.itemSets; - } - - public short[] getU1() { - return this.u1; - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/doo/RandomItem.java b/core/src/com/etheller/warsmash/parsers/w3x/doo/RandomItem.java deleted file mode 100644 index 26fd3c2f..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/doo/RandomItem.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.doo; - -import java.io.IOException; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class RandomItem { - private War3ID id; - private int chance; - - public void load(final LittleEndianDataInputStream stream) throws IOException { - this.id = ParseUtils.readWar3ID(stream); - this.chance = stream.readInt(); - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - ParseUtils.writeWar3ID(stream, this.id); - stream.writeInt(this.chance); - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/doo/RandomItemSet.java b/core/src/com/etheller/warsmash/parsers/w3x/doo/RandomItemSet.java deleted file mode 100644 index f115b8e3..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/doo/RandomItemSet.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.doo; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.ParseUtils; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class RandomItemSet { - private final List items = new ArrayList<>(); - - public void load(final LittleEndianDataInputStream stream) throws IOException { - for (long i = 0, l = ParseUtils.readUInt32(stream); i < l; i++) { - final RandomItem item = new RandomItem(); - - item.load(stream); - - this.items.add(item); - } - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - ParseUtils.writeUInt32(stream, this.items.size()); - for (final RandomItem item : this.items) { - item.save(stream); - } - } - - public int getByteLength() { - return 4 + (this.items.size() * 8); - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/doo/TerrainDoodad.java b/core/src/com/etheller/warsmash/parsers/w3x/doo/TerrainDoodad.java deleted file mode 100644 index 5390166e..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/doo/TerrainDoodad.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.doo; - -import java.io.IOException; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -/** - * A terrain doodad. - * - * This type of doodad works much like cliffs. It uses the height of the - * terrain, and gets affected by the ground heightmap. It cannot be manipulated - * in any way in the World Editor once placed. Indeed, the only way to change it - * is to remove it by changing cliffs around it. - */ -public class TerrainDoodad { - private War3ID id; - private long u1; - private final long[] location = new long[2]; - - public void load(final LittleEndianDataInputStream stream, final int version) throws IOException { - this.id = ParseUtils.readWar3ID(stream); - this.u1 = ParseUtils.readUInt32(stream); - ParseUtils.readUInt32Array(stream, this.location); - } - - public void save(final LittleEndianDataOutputStream stream, final int version) throws IOException { - ParseUtils.writeWar3ID(stream, this.id); - ParseUtils.writeUInt32(stream, this.u1); - ParseUtils.writeUInt32Array(stream, this.location); - } - - public War3ID getId() { - return this.id; - } - - public long getU1() { - return this.u1; - } - - public long[] getLocation() { - return this.location; - } - - public void setId(final War3ID id) { - this.id = id; - } - - public void setU1(final long u1) { - this.u1 = u1; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/doo/War3MapDoo.java b/core/src/com/etheller/warsmash/parsers/w3x/doo/War3MapDoo.java deleted file mode 100644 index 828fca23..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/doo/War3MapDoo.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.doo; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -/** - * war3map.doo - the doodad and destructible file. - */ -public class War3MapDoo { - private static final War3ID MAGIC_NUMBER = War3ID.fromString("W3do"); - private int version = 0; - private final short[] u1 = new short[4]; - private final List doodads = new ArrayList<>(); - private final short[] u2 = new short[4]; - private final List terrainDoodads = new ArrayList<>(); - - public War3MapDoo(final LittleEndianDataInputStream stream) throws IOException { - if (stream != null) { - this.load(stream); - } - } - - private boolean load(final LittleEndianDataInputStream stream) throws IOException { - final War3ID firstId = ParseUtils.readWar3ID(stream); - if (!MAGIC_NUMBER.equals(firstId)) { - return false; - } - - this.version = stream.readInt(); - ParseUtils.readUInt8Array(stream, this.u1); - - for (int i = 0, l = stream.readInt(); i < l; i++) { - final Doodad doodad = new Doodad(); - - doodad.load(stream, this.version); - - this.doodads.add(doodad); - } - - ParseUtils.readUInt8Array(stream, this.u2); - - for (int i = 0, l = stream.readInt(); i < l; i++) { - final TerrainDoodad terrainDoodad = new TerrainDoodad(); - - terrainDoodad.load(stream, this.version); - - this.terrainDoodads.add(terrainDoodad); - } - - return true; - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - - ParseUtils.writeWar3ID(stream, MAGIC_NUMBER); - stream.writeInt(this.version); - ParseUtils.writeUInt8Array(stream, this.u1); - ParseUtils.writeUInt32(stream, this.doodads.size()); - - for (final Doodad doodad : this.doodads) { - doodad.save(stream, this.version); - } - - ParseUtils.writeUInt8Array(stream, this.u2); - ParseUtils.writeUInt32(stream, this.terrainDoodads.size()); - - for (final TerrainDoodad terrainDoodad : this.terrainDoodads) { - terrainDoodad.save(stream, this.version); - } - } - - public int getByteLength() { - int size = 24 + (this.terrainDoodads.size() * 16); - - for (final Doodad doodad : this.doodads) { - size += doodad.getByteLength(this.version); - } - - return size; - } - - public int getVersion() { - return this.version; - } - - public short[] getU1() { - return this.u1; - } - - public List getDoodads() { - return this.doodads; - } - - public short[] getU2() { - return this.u2; - } - - public List getTerrainDoodads() { - return this.terrainDoodads; - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/objectdata/MakeMeTFTBeROC.java b/core/src/com/etheller/warsmash/parsers/w3x/objectdata/MakeMeTFTBeROC.java deleted file mode 100644 index 92a14de0..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/objectdata/MakeMeTFTBeROC.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.objectdata; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Arrays; - -import com.etheller.warsmash.datasources.CompoundDataSourceDescriptor; -import com.etheller.warsmash.datasources.FolderDataSourceDescriptor; -import com.etheller.warsmash.datasources.MpqDataSourceDescriptor; -import com.etheller.warsmash.units.GameObject; -import com.etheller.warsmash.units.ObjectData; -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataOutputStream; - -public class MakeMeTFTBeROC { - - public static void main(final String[] args) { - - try { - final MpqDataSourceDescriptor reignOfChaosData = new MpqDataSourceDescriptor( - "E:\\Games\\Warcraft III Patch 1.14\\war3.mpq"); - final Warcraft3MapObjectData reignOfChaosUnitData = Warcraft3MapObjectData - .load(reignOfChaosData.createDataSource(), true); - - final FolderDataSourceDescriptor tftDesc1 = new FolderDataSourceDescriptor( - "D:\\NEEDS_ORGANIZING\\Reforged Beta 13991\\war3.w3mod"); - final FolderDataSourceDescriptor tftDesc2 = new FolderDataSourceDescriptor( - "D:\\NEEDS_ORGANIZING\\Reforged Beta 13991\\war3.w3mod\\_balance\\custom_v1.w3mod"); - final FolderDataSourceDescriptor tftDesc3 = new FolderDataSourceDescriptor( - "D:\\NEEDS_ORGANIZING\\Reforged Beta 13991\\war3.w3mod\\_locales\\enus.w3mod"); - final CompoundDataSourceDescriptor frozenThroneData = new CompoundDataSourceDescriptor( - Arrays.asList(tftDesc1, tftDesc2, tftDesc3)); - - final Warcraft3MapObjectData frozenThroneUnitData = Warcraft3MapObjectData - .load(frozenThroneData.createDataSource(), true); - for (final War3ID unitId : reignOfChaosUnitData.getUnits().keySet()) { - final MutableGameObject reignOfChaosUnit = reignOfChaosUnitData.getUnits().get(unitId); - final MutableGameObject frozenThroneEquivalentUnit = frozenThroneUnitData.getUnits().get(unitId); - if (frozenThroneEquivalentUnit == null) { - System.err.println("No TFT equivalent for: " + reignOfChaosUnit.getName()); - continue; - } - final ObjectData metaDataSlk = reignOfChaosUnitData.getUnits().getSourceSLKMetaData(); - for (final String fieldTypeId : metaDataSlk.keySet()) { - final War3ID fieldTypeIdCode = War3ID.fromString(fieldTypeId); - final GameObject unitFieldInformation = metaDataSlk.get(fieldTypeId); - if (unitFieldInformation.getFieldValue("useItem") == 1) { - continue; - } - final String fieldType = unitFieldInformation.getField("type"); - switch (fieldType) { - case "int": - frozenThroneEquivalentUnit.setField(fieldTypeIdCode, 0, - reignOfChaosUnit.getFieldAsInteger(fieldTypeIdCode, 0)); - break; - case "real": - case "unreal": - frozenThroneEquivalentUnit.setField(fieldTypeIdCode, 0, - reignOfChaosUnit.getFieldAsFloat(fieldTypeIdCode, 0)); - break; - case "bool": - frozenThroneEquivalentUnit.setField(fieldTypeIdCode, 0, - reignOfChaosUnit.getFieldAsBoolean(fieldTypeIdCode, 0)); - break; - case "string": - case "abilityList": - case "stringList": - case "soundLabel": - case "unitList": - case "itemList": - case "techList": - case "intList": - case "model": - case "char": - case "icon": - frozenThroneEquivalentUnit.setField(fieldTypeIdCode, 0, - reignOfChaosUnit.getFieldAsString(fieldTypeIdCode, 0)); - break; - default: // treat as string - break; - - } - } - } - - try (LittleEndianDataOutputStream outputStream = new LittleEndianDataOutputStream( - new FileOutputStream("C:\\Users\\micro\\OneDrive\\Documents\\Warcraft III\\Data\\roc.w3u"))) { - frozenThroneUnitData.getUnits().getEditorData().save(outputStream, false); - } - - } - catch (final IOException e) { - e.printStackTrace(); - } - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/objectdata/Warcraft3MapObjectData.java b/core/src/com/etheller/warsmash/parsers/w3x/objectdata/Warcraft3MapObjectData.java deleted file mode 100644 index 8236c53f..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/objectdata/Warcraft3MapObjectData.java +++ /dev/null @@ -1,184 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.objectdata; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.units.StandardObjectData; -import com.etheller.warsmash.units.StandardObjectData.WarcraftData; -import com.etheller.warsmash.units.custom.WTS; -import com.etheller.warsmash.units.custom.WTSFile; -import com.etheller.warsmash.units.custom.War3ObjectDataChangeset; -import com.etheller.warsmash.units.manager.MutableObjectData; -import com.etheller.warsmash.units.manager.MutableObjectData.WorldEditorDataType; -import com.etheller.warsmash.util.WorldEditStrings; -import com.google.common.io.LittleEndianDataInputStream; - -public final class Warcraft3MapObjectData { - private final MutableObjectData units; - private final MutableObjectData items; - private final MutableObjectData destructibles; - private final MutableObjectData doodads; - private final MutableObjectData abilities; - private final MutableObjectData buffs; - private final MutableObjectData upgrades; - private final List datas; - private transient Map typeToData = new HashMap<>(); - private final WTS wts; - - public Warcraft3MapObjectData(final MutableObjectData units, final MutableObjectData items, - final MutableObjectData destructibles, final MutableObjectData doodads, final MutableObjectData abilities, - final MutableObjectData buffs, final MutableObjectData upgrades, final WTS wts) { - this.units = units; - this.items = items; - this.destructibles = destructibles; - this.doodads = doodads; - this.abilities = abilities; - this.buffs = buffs; - this.upgrades = upgrades; - this.datas = new ArrayList<>(); - this.datas.add(units); - this.datas.add(items); - this.datas.add(destructibles); - this.datas.add(doodads); - this.datas.add(abilities); - this.datas.add(buffs); - this.datas.add(upgrades); - for (final MutableObjectData data : this.datas) { - this.typeToData.put(data.getWorldEditorDataType(), data); - } - this.wts = wts; - } - - public MutableObjectData getDataByType(final WorldEditorDataType type) { - return this.typeToData.get(type); - } - - public MutableObjectData getUnits() { - return this.units; - } - - public MutableObjectData getItems() { - return this.items; - } - - public MutableObjectData getDestructibles() { - return this.destructibles; - } - - public MutableObjectData getDoodads() { - return this.doodads; - } - - public MutableObjectData getAbilities() { - return this.abilities; - } - - public MutableObjectData getBuffs() { - return this.buffs; - } - - public MutableObjectData getUpgrades() { - return this.upgrades; - } - - public List getDatas() { - return this.datas; - } - - public WTS getWts() { - return this.wts; - } - - public static WTS loadWTS(final DataSource dataSource) throws IOException { - final WTS wts = dataSource.has("war3map.wts") ? new WTSFile(dataSource.getResourceAsStream("war3map.wts")) - : WTS.DO_NOTHING; - return wts; - } - - public static Warcraft3MapObjectData load(final DataSource dataSource, final boolean inlineWTS) throws IOException { - final WTS wts = loadWTS(dataSource); - return load(dataSource, inlineWTS, wts); - } - - public static Warcraft3MapObjectData load(final DataSource dataSource, final boolean inlineWTS, final WTS wts) - throws IOException { - - final StandardObjectData standardObjectData = new StandardObjectData(dataSource); - final WarcraftData standardUnits = standardObjectData.getStandardUnits(); - final WarcraftData standardItems = standardObjectData.getStandardItems(); - final WarcraftData standardDoodads = standardObjectData.getStandardDoodads(); - final WarcraftData standardDestructables = standardObjectData.getStandardDestructables(); - final WarcraftData abilities = standardObjectData.getStandardAbilities(); - final WarcraftData standardAbilityBuffs = standardObjectData.getStandardAbilityBuffs(); - final WarcraftData standardUpgrades = standardObjectData.getStandardUpgrades(); - - final DataTable standardUnitMeta = standardObjectData.getStandardUnitMeta(); - final DataTable standardDoodadMeta = standardObjectData.getStandardDoodadMeta(); - final DataTable standardDestructableMeta = standardObjectData.getStandardDestructableMeta(); - final DataTable abilityMeta = standardObjectData.getStandardAbilityMeta(); - final DataTable standardAbilityBuffMeta = standardObjectData.getStandardAbilityBuffMeta(); - final DataTable standardUpgradeMeta = standardObjectData.getStandardUpgradeMeta(); - - final War3ObjectDataChangeset unitChangeset = new War3ObjectDataChangeset('u'); - final War3ObjectDataChangeset itemChangeset = new War3ObjectDataChangeset('t'); - final War3ObjectDataChangeset doodadChangeset = new War3ObjectDataChangeset('d'); - final War3ObjectDataChangeset destructableChangeset = new War3ObjectDataChangeset('b'); - final War3ObjectDataChangeset abilityChangeset = new War3ObjectDataChangeset('a'); - final War3ObjectDataChangeset buffChangeset = new War3ObjectDataChangeset('h'); - final War3ObjectDataChangeset upgradeChangeset = new War3ObjectDataChangeset('q'); - - if (dataSource.has("war3map.w3u")) { - unitChangeset.load(new LittleEndianDataInputStream(dataSource.getResourceAsStream("war3map.w3u")), wts, - inlineWTS); - } - if (dataSource.has("war3map.w3t")) { - itemChangeset.load(new LittleEndianDataInputStream(dataSource.getResourceAsStream("war3map.w3t")), wts, - inlineWTS); - } - if (dataSource.has("war3map.w3d")) { - doodadChangeset.load(new LittleEndianDataInputStream(dataSource.getResourceAsStream("war3map.w3d")), wts, - inlineWTS); - } - if (dataSource.has("war3map.w3b")) { - destructableChangeset.load(new LittleEndianDataInputStream(dataSource.getResourceAsStream("war3map.w3b")), - wts, inlineWTS); - } - if (dataSource.has("war3map.w3a")) { - abilityChangeset.load(new LittleEndianDataInputStream(dataSource.getResourceAsStream("war3map.w3a")), wts, - inlineWTS); - } - if (dataSource.has("war3map.w3h")) { - buffChangeset.load(new LittleEndianDataInputStream(dataSource.getResourceAsStream("war3map.w3h")), wts, - inlineWTS); - } - if (dataSource.has("war3map.w3q")) { - upgradeChangeset.load(new LittleEndianDataInputStream(dataSource.getResourceAsStream("war3map.w3q")), wts, - inlineWTS); - } - - final WorldEditStrings worldEditStrings = standardObjectData.getWorldEditStrings(); - final MutableObjectData unitData = new MutableObjectData(worldEditStrings, WorldEditorDataType.UNITS, - standardUnits, standardUnitMeta, unitChangeset); - final MutableObjectData itemData = new MutableObjectData(worldEditStrings, WorldEditorDataType.ITEM, - standardItems, standardUnitMeta, itemChangeset); - final MutableObjectData doodadData = new MutableObjectData(worldEditStrings, WorldEditorDataType.DOODADS, - standardDoodads, standardDoodadMeta, doodadChangeset); - final MutableObjectData destructableData = new MutableObjectData(worldEditStrings, - WorldEditorDataType.DESTRUCTIBLES, standardDestructables, standardDestructableMeta, - destructableChangeset); - final MutableObjectData abilityData = new MutableObjectData(worldEditStrings, WorldEditorDataType.ABILITIES, - abilities, abilityMeta, abilityChangeset); - final MutableObjectData buffData = new MutableObjectData(worldEditStrings, WorldEditorDataType.BUFFS_EFFECTS, - standardAbilityBuffs, standardAbilityBuffMeta, buffChangeset); - final MutableObjectData upgradeData = new MutableObjectData(worldEditStrings, WorldEditorDataType.UPGRADES, - standardUpgrades, standardUpgradeMeta, upgradeChangeset); - - return new Warcraft3MapObjectData(unitData, itemData, destructableData, doodadData, abilityData, buffData, - upgradeData, wts); - } -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/DroppedItem.java b/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/DroppedItem.java deleted file mode 100644 index 28dfa43e..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/DroppedItem.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.unitsdoo; - -import java.io.IOException; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -/** - * A dropped item. - */ -public class DroppedItem { - private War3ID id; - private int chance; - - public void load(final LittleEndianDataInputStream stream) throws IOException { - this.id = ParseUtils.readWar3ID(stream); - this.chance = stream.readInt(); - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - ParseUtils.writeWar3ID(stream, this.id); - stream.writeInt(this.chance); - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/DroppedItemSet.java b/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/DroppedItemSet.java deleted file mode 100644 index d70b57fb..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/DroppedItemSet.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.unitsdoo; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.ParseUtils; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -/** - * A dropped item set. - */ -public class DroppedItemSet { - private final List items = new ArrayList<>(); - - public void load(final LittleEndianDataInputStream stream) throws IOException { - for (long i = 0, l = ParseUtils.readUInt32(stream); i < l; i++) { - final DroppedItem item = new DroppedItem(); - - item.load(stream); - - this.items.add(item); - } - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - ParseUtils.writeUInt32(stream, this.items.size()); - - for (final DroppedItem item : this.items) { - item.save(stream); - } - } - - public int getByteLength() { - return 4 + (this.items.size() * 8); - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/InventoryItem.java b/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/InventoryItem.java deleted file mode 100644 index 7912c254..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/InventoryItem.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.unitsdoo; - -import java.io.IOException; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -/** - * An inventory item. - */ -public class InventoryItem { - private int slot; - private War3ID id; - - public void load(final LittleEndianDataInputStream stream) throws IOException { - this.slot = stream.readInt(); - this.id = ParseUtils.readWar3ID(stream); - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - stream.writeInt(this.slot); - ParseUtils.writeWar3ID(stream, this.id); - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/ModifiedAbility.java b/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/ModifiedAbility.java deleted file mode 100644 index 1a89ca5d..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/ModifiedAbility.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.unitsdoo; - -import java.io.IOException; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class ModifiedAbility { - private War3ID id; - private int activeForAutocast = 0; - private int heroLevel = 1; - - public void load(final LittleEndianDataInputStream stream) throws IOException { - this.id = ParseUtils.readWar3ID(stream); - this.activeForAutocast = stream.readInt(); - this.heroLevel = stream.readInt(); - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - ParseUtils.writeWar3ID(stream, this.id); - stream.writeInt(this.activeForAutocast); - stream.writeInt(this.heroLevel); - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/RandomUnit.java b/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/RandomUnit.java deleted file mode 100644 index ef0852e3..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/RandomUnit.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.unitsdoo; - -import java.io.IOException; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class RandomUnit { - private War3ID id; - private int chance; - - public void load(final LittleEndianDataInputStream stream) throws IOException { - this.id = ParseUtils.readWar3ID(stream); - this.chance = stream.readInt(); - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - ParseUtils.writeWar3ID(stream, this.id); - stream.writeInt(this.chance); - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/Unit.java b/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/Unit.java deleted file mode 100644 index 1ce7c1bb..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/Unit.java +++ /dev/null @@ -1,428 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.unitsdoo; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class Unit { - private War3ID id; - private int variation; - private final float[] location = new float[3]; - private float angle; - private final float[] scale = new float[3]; - private short flags; - private int player; - private int unknown; - private int hitpoints = -1; - private int mana = -1; - /** - * @since 8 - */ - private int droppedItemTable = 0; - private final List droppedItemSets = new ArrayList<>(); - private int goldAmount; - private float targetAcquisition; - private int heroLevel; - /** - * @since 8 - */ - private int heroStrength; - /** - * @since 8 - */ - private int heroAgility; - /** - * @since 8 - */ - private int heroIntelligence; - private final List itemsInInventory = new ArrayList<>(); - private final List modifiedAbilities = new ArrayList<>(); - private int randomFlag; - private final short[] level = new short[3]; - private short itemClass; - private long unitGroup; - private long positionInGroup; - private final List randomUnitTables = new ArrayList<>(); - private int customTeamColor; - private int waygate; - private int creationNumber; - - public void load(final LittleEndianDataInputStream stream, final int version) throws IOException { - this.id = ParseUtils.readWar3ID(stream); - this.variation = stream.readInt(); - ParseUtils.readFloatArray(stream, this.location); - this.angle = stream.readFloat(); - ParseUtils.readFloatArray(stream, this.scale); - this.flags = ParseUtils.readUInt8(stream); - this.player = stream.readInt(); - this.unknown = ParseUtils.readUInt16(stream); - this.hitpoints = stream.readInt(); - this.mana = stream.readInt(); - - if (version > 7) { - this.droppedItemTable = stream.readInt(); - } - - for (int i = 0, l = stream.readInt(); i < l; i++) { - final DroppedItemSet set = new DroppedItemSet(); - - set.load(stream); - - this.droppedItemSets.add(set); - } - - this.goldAmount = stream.readInt(); - this.targetAcquisition = stream.readFloat(); - this.heroLevel = stream.readInt(); - - if (version > 7) { - this.heroStrength = stream.readInt(); - this.heroAgility = stream.readInt(); - this.heroIntelligence = stream.readInt(); - } - - for (int i = 0, l = stream.readInt(); i < l; i++) { - final InventoryItem item = new InventoryItem(); - - item.load(stream); - - this.itemsInInventory.add(item); - } - - for (int i = 0, l = stream.readInt(); i < l; i++) { - final ModifiedAbility modifiedAbility = new ModifiedAbility(); - - modifiedAbility.load(stream); - - this.modifiedAbilities.add(modifiedAbility); - } - - this.randomFlag = stream.readInt(); - - if (this.randomFlag == 0) { - ParseUtils.readUInt8Array(stream, this.level); - this.itemClass = ParseUtils.readUInt8(stream); - } - else if (this.randomFlag == 1) { - this.unitGroup = ParseUtils.readUInt32(stream); - this.positionInGroup = ParseUtils.readUInt32(stream); - } - else if (this.randomFlag == 2) { - for (int i = 0, l = stream.readInt(); i < l; i++) { - final RandomUnit randomUnit = new RandomUnit(); - - randomUnit.load(stream); - - this.randomUnitTables.add(randomUnit); - } - } - - this.customTeamColor = stream.readInt(); - this.waygate = stream.readInt(); - this.creationNumber = stream.readInt(); - } - - public void save(final LittleEndianDataOutputStream stream, final int version) throws IOException { - ParseUtils.writeWar3ID(stream, this.id); - stream.writeInt(this.variation); - ParseUtils.writeFloatArray(stream, this.location); - stream.writeFloat(this.angle); - ParseUtils.writeFloatArray(stream, this.scale); - ParseUtils.writeUInt8(stream, this.flags); - stream.writeInt(this.player); - ParseUtils.writeUInt16(stream, this.unknown); - stream.writeInt(this.hitpoints); - stream.writeInt(this.mana); - - if (version > 7) { - stream.writeInt(this.droppedItemTable); - } - - stream.writeInt(this.droppedItemSets.size()); - - for (final DroppedItemSet droppedItemSet : this.droppedItemSets) { - droppedItemSet.save(stream); - } - - stream.writeInt(this.goldAmount); - stream.writeFloat(this.targetAcquisition); - stream.writeInt(this.heroLevel); - - if (version > 7) { - stream.writeInt(this.heroStrength); - stream.writeInt(this.heroAgility); - stream.writeInt(this.heroIntelligence); - } - - stream.writeInt(this.itemsInInventory.size()); - - for (final InventoryItem itemInInventory : this.itemsInInventory) { - itemInInventory.save(stream); - } - - stream.writeInt(this.modifiedAbilities.size()); - - for (final ModifiedAbility modifiedAbility : this.modifiedAbilities) { - modifiedAbility.save(stream); - } - - stream.writeInt(this.randomFlag); - - if (this.randomFlag == 0) { - ParseUtils.writeUInt8Array(stream, this.level); - ParseUtils.writeUInt8(stream, this.itemClass); - } - else if (this.randomFlag == 1) { - ParseUtils.writeUInt32(stream, this.unitGroup); - ParseUtils.writeUInt32(stream, this.positionInGroup); - } - else if (this.randomFlag == 2) { - stream.writeInt(this.randomUnitTables.size()); - - for (final RandomUnit randomUnitTable : this.randomUnitTables) { - randomUnitTable.save(stream); - } - } - - stream.writeInt(this.customTeamColor); - stream.writeInt(this.waygate); - stream.writeInt(this.creationNumber); - } - - public int getByteLength(final int version) { - int size = 91; - - if (version > 7) { - size += 16; - } - - for (final DroppedItemSet droppedItemSet : this.droppedItemSets) { - size += droppedItemSet.getByteLength(); - } - - size += this.itemsInInventory.size() * 8; - - size += this.modifiedAbilities.size() * 12; - - if (this.randomFlag == 0) { - size += 4; - } - else if (this.randomFlag == 1) { - size += 8; - } - else if (this.randomFlag == 2) { - size += 4 + (this.randomUnitTables.size() * 8); - } - - return size; - } - - public War3ID getId() { - return this.id; - } - - public int getVariation() { - return this.variation; - } - - public float[] getLocation() { - return this.location; - } - - public float getAngle() { - return this.angle; - } - - public float[] getScale() { - return this.scale; - } - - public short getFlags() { - return this.flags; - } - - public int getPlayer() { - return this.player; - } - - public int getUnknown() { - return this.unknown; - } - - public int getHitpoints() { - return this.hitpoints; - } - - public int getMana() { - return this.mana; - } - - public int getDroppedItemTable() { - return this.droppedItemTable; - } - - public List getDroppedItemSets() { - return this.droppedItemSets; - } - - public int getGoldAmount() { - return this.goldAmount; - } - - public float getTargetAcquisition() { - return this.targetAcquisition; - } - - public int getHeroLevel() { - return this.heroLevel; - } - - public int getHeroStrength() { - return this.heroStrength; - } - - public int getHeroAgility() { - return this.heroAgility; - } - - public int getHeroIntelligence() { - return this.heroIntelligence; - } - - public List getItemsInInventory() { - return this.itemsInInventory; - } - - public List getModifiedAbilities() { - return this.modifiedAbilities; - } - - public int getRandomFlag() { - return this.randomFlag; - } - - public short[] getLevel() { - return this.level; - } - - public short getItemClass() { - return this.itemClass; - } - - public long getUnitGroup() { - return this.unitGroup; - } - - public long getPositionInGroup() { - return this.positionInGroup; - } - - public List getRandomUnitTables() { - return this.randomUnitTables; - } - - public int getCustomTeamColor() { - return this.customTeamColor; - } - - public int getWaygate() { - return this.waygate; - } - - public int getCreationNumber() { - return this.creationNumber; - } - - public void setId(final War3ID id) { - this.id = id; - } - - public void setVariation(final int variation) { - this.variation = variation; - } - - public void setAngle(final float angle) { - this.angle = angle; - } - - public void setFlags(final short flags) { - this.flags = flags; - } - - public void setPlayer(final int player) { - this.player = player; - } - - public void setUnknown(final int unknown) { - this.unknown = unknown; - } - - public void setHitpoints(final int hitpoints) { - this.hitpoints = hitpoints; - } - - public void setMana(final int mana) { - this.mana = mana; - } - - public void setDroppedItemTable(final int droppedItemTable) { - this.droppedItemTable = droppedItemTable; - } - - public void setGoldAmount(final int goldAmount) { - this.goldAmount = goldAmount; - } - - public void setTargetAcquisition(final float targetAcquisition) { - this.targetAcquisition = targetAcquisition; - } - - public void setHeroLevel(final int heroLevel) { - this.heroLevel = heroLevel; - } - - public void setHeroStrength(final int heroStrength) { - this.heroStrength = heroStrength; - } - - public void setHeroAgility(final int heroAgility) { - this.heroAgility = heroAgility; - } - - public void setHeroIntelligence(final int heroIntelligence) { - this.heroIntelligence = heroIntelligence; - } - - public void setRandomFlag(final int randomFlag) { - this.randomFlag = randomFlag; - } - - public void setItemClass(final short itemClass) { - this.itemClass = itemClass; - } - - public void setUnitGroup(final long unitGroup) { - this.unitGroup = unitGroup; - } - - public void setPositionInGroup(final long positionInGroup) { - this.positionInGroup = positionInGroup; - } - - public void setCustomTeamColor(final int customTeamColor) { - this.customTeamColor = customTeamColor; - } - - public void setWaygate(final int waygate) { - this.waygate = waygate; - } - - public void setCreationNumber(final int creationNumber) { - this.creationNumber = creationNumber; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/War3MapUnitsDoo.java b/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/War3MapUnitsDoo.java deleted file mode 100644 index d8f6bfee..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/unitsdoo/War3MapUnitsDoo.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.unitsdoo; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class War3MapUnitsDoo { - private static final War3ID MAGIC_NUMBER = War3ID.fromString("W3do"); - private int version = 8; - private long unknown = 11; - private final List units = new ArrayList<>(); - - public War3MapUnitsDoo(final LittleEndianDataInputStream stream) throws IOException { - if (stream != null) { - this.load(stream); - } - } - - private boolean load(final LittleEndianDataInputStream stream) throws IOException { - final War3ID firstId = ParseUtils.readWar3ID(stream); - if (!MAGIC_NUMBER.equals(firstId)) { - return false; - } - - this.version = stream.readInt(); - this.unknown = ParseUtils.readUInt32(stream); - - for (int i = 0, l = stream.readInt(); i < l; i++) { - final Unit unit = new Unit(); - - unit.load(stream, this.version); - - this.units.add(unit); - } - - return true; - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - ParseUtils.writeWar3ID(stream, MAGIC_NUMBER); - stream.writeInt(this.version); - ParseUtils.writeUInt32(stream, this.unknown); - stream.writeInt(this.units.size()); - - for (final Unit unit : this.units) { - unit.save(stream, this.version); - } - } - - public int getByteLength() { - int size = 16; - - for (final Unit unit : this.units) { - size += unit.getByteLength(this.version); - } - - return size; - } - - public List getUnits() { - return this.units; - } - - public int getVersion() { - return this.version; - } - - public void setVersion(final int version) { - this.version = version; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/w3e/Corner.java b/core/src/com/etheller/warsmash/parsers/w3x/w3e/Corner.java deleted file mode 100644 index ff64e7c0..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/w3e/Corner.java +++ /dev/null @@ -1,149 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.w3e; - -import java.io.IOException; - -import com.etheller.warsmash.util.ParseUtils; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -/** - * A tile corner. - */ -public class Corner { - private float groundHeight; - private float waterHeight; - private int mapEdge; - private int ramp; - private int blight; - private int water; - private int boundary; - private int groundTexture; - private int cliffVariation; - private int groundVariation; - private int cliffTexture; - private int layerHeight; - - public Corner() { - // TODO Auto-generated constructor stub - } - - public Corner(final Corner other) { - this.groundHeight = other.groundHeight; - this.waterHeight = other.waterHeight; - this.mapEdge = other.mapEdge; - this.ramp = other.ramp; - this.blight = other.blight; - this.water = other.water; - this.boundary = other.boundary; - this.groundTexture = other.groundTexture; - this.cliffVariation = other.cliffVariation; - this.groundVariation = other.groundVariation; - this.cliffTexture = other.cliffTexture; - this.layerHeight = other.layerHeight; - } - - public void load(final LittleEndianDataInputStream stream) throws IOException { - this.groundHeight = (stream.readShort() - 8192) / (float) 512; - - final short waterAndEdge = stream.readShort(); - this.waterHeight = ((waterAndEdge & 0x3FFF) - 8192) / (float) 512; - this.mapEdge = waterAndEdge & 0x4000; - - final short textureAndFlags = ParseUtils.readUInt8(stream); - - this.ramp = textureAndFlags & 0b00010000; - this.blight = textureAndFlags & 0b00100000; - this.water = textureAndFlags & 0b01000000; - this.boundary = textureAndFlags & 0b10000000; - - this.groundTexture = textureAndFlags & 0b00001111; - - final short variation = ParseUtils.readUInt8(stream); - - this.cliffVariation = (variation & 0b11100000) >>> 5; - this.groundVariation = variation & 0b00011111; - - final short cliffTextureAndLayer = ParseUtils.readUInt8(stream); - - this.cliffTexture = (cliffTextureAndLayer & 0b11110000) >>> 4; - this.layerHeight = cliffTextureAndLayer & 0b00001111; - - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - stream.writeShort((short) ((this.groundHeight * 512f) + 8192f)); - stream.writeShort((short) ((this.waterHeight * 512f) + 8192f + (this.mapEdge << 14))); - ParseUtils.writeUInt8(stream, (short) ((this.ramp << 4) | (this.blight << 5) | (this.water << 6) - | (this.boundary << 7) | this.groundTexture)); - ParseUtils.writeUInt8(stream, (short) ((this.cliffVariation << 5) | this.groundVariation)); - ParseUtils.writeUInt8(stream, (short) ((this.cliffTexture << 4) + this.layerHeight)); - } - - public float getGroundHeight() { - return this.groundHeight; - } - - public float getWaterHeight() { - return this.waterHeight; - } - - public int getMapEdge() { - return this.mapEdge; - } - - public int getRamp() { - return this.ramp; - } - - public boolean isRamp() { - return this.ramp != 0; - } - - public void setRamp(final int ramp) { - this.ramp = ramp; - } - - public int getBlight() { - return this.blight; - } - - public int getWater() { - return this.water; - } - - public int getBoundary() { - return this.boundary; - } - - public int getGroundTexture() { - return this.groundTexture; - } - - public int getCliffVariation() { - return this.cliffVariation; - } - - public int getGroundVariation() { - return this.groundVariation; - } - - public int getCliffTexture() { - return this.cliffTexture; - } - - public void setCliffTexture(final int cliffTexture) { - this.cliffTexture = cliffTexture; - } - - public int getLayerHeight() { - return this.layerHeight; - } - - public float computeFinalGroundHeight() { - return (this.groundHeight + this.layerHeight) - 2.0f; - } - - public float computeFinalWaterHeight(final float waterOffset) { - return this.waterHeight + waterOffset; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/w3e/War3MapW3e.java b/core/src/com/etheller/warsmash/parsers/w3x/w3e/War3MapW3e.java deleted file mode 100644 index 8494df75..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/w3e/War3MapW3e.java +++ /dev/null @@ -1,148 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.w3e; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -/** - * war3map.w3e - the environment file. - */ -public class War3MapW3e { - private static final War3ID MAGIC_NUMBER = War3ID.fromString("W3E!"); - private int version; - private char tileset = 'A'; - private int hasCustomTileset; - private final List groundTiles = new ArrayList<>(); - private final List cliffTiles = new ArrayList<>(); - private final int[] mapSize = new int[2]; - private final float[] centerOffset = new float[2]; - private Corner[][] corners; - - public War3MapW3e(final LittleEndianDataInputStream stream) throws IOException { - if (stream != null) { - this.load(stream); - } - } - - private boolean load(final LittleEndianDataInputStream stream) throws IOException { - final War3ID firstId = ParseUtils.readWar3ID(stream); - if (!MAGIC_NUMBER.equals(firstId)) { - return false; - } - - this.version = stream.readInt(); - this.tileset = (char) stream.read(); - this.hasCustomTileset = stream.readInt(); - - for (int i = 0, l = stream.readInt(); i < l; i++) { - this.groundTiles.add(ParseUtils.readWar3ID(stream)); - } - - for (int i = 0, l = stream.readInt(); i < l; i++) { - this.cliffTiles.add(ParseUtils.readWar3ID(stream)); - } - - ParseUtils.readInt32Array(stream, this.mapSize); - ParseUtils.readFloatArray(stream, this.centerOffset); - - this.corners = new Corner[this.mapSize[1]][]; - for (int row = 0, rows = this.mapSize[1]; row < rows; row++) { - this.corners[row] = new Corner[this.mapSize[0]]; - - for (int column = 0, columns = this.mapSize[0]; column < columns; column++) { - final Corner corner = new Corner(); - - corner.load(stream); - - this.corners[row][column] = corner; - } - } - - return true; - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - ParseUtils.writeWar3ID(stream, MAGIC_NUMBER); - stream.writeInt(this.version); - stream.write(this.tileset); - stream.writeInt(this.hasCustomTileset); - ParseUtils.writeUInt32(stream, this.groundTiles.size()); - - for (final War3ID groundTile : this.groundTiles) { - ParseUtils.writeWar3ID(stream, groundTile); - } - - ParseUtils.writeUInt32(stream, this.cliffTiles.size()); - - for (final War3ID cliffTile : this.cliffTiles) { - ParseUtils.writeWar3ID(stream, cliffTile); - } - - ParseUtils.writeInt32Array(stream, this.mapSize); - ParseUtils.writeFloatArray(stream, this.centerOffset); - - for (final Corner[] row : this.corners) { - for (final Corner corner : row) { - corner.save(stream); - } - } - } - - public int getByteLength() { - return 37 + (this.groundTiles.size() * 4) + (this.cliffTiles.size() * 4) - + (this.mapSize[0] * this.mapSize[1] * 7); - } - - public int getVersion() { - return this.version; - } - - public char getTileset() { - return this.tileset; - } - - public int getHasCustomTileset() { - return this.hasCustomTileset; - } - - public List getGroundTiles() { - return this.groundTiles; - } - - public List getCliffTiles() { - return this.cliffTiles; - } - - public int[] getMapSize() { - return this.mapSize; - } - - public float[] getCenterOffset() { - return this.centerOffset; - } - - public Corner[][] getCorners() { - return this.corners; - } - - public void setVersion(final int version) { - this.version = version; - } - - public void setTileset(final char tileset) { - this.tileset = tileset; - } - - public void setHasCustomTileset(final int hasCustomTileset) { - this.hasCustomTileset = hasCustomTileset; - } - - public void setCorners(final Corner[][] corners) { - this.corners = corners; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/w3i/Force.java b/core/src/com/etheller/warsmash/parsers/w3x/w3i/Force.java deleted file mode 100644 index 0d3f8dd9..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/w3i/Force.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.w3i; - -import java.io.IOException; - -import com.etheller.warsmash.util.ParseUtils; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class Force { - private long flags; - private long playerMasks; - private String name; - - public void load(final LittleEndianDataInputStream stream) throws IOException { - this.flags = ParseUtils.readUInt32(stream); - this.playerMasks = ParseUtils.readUInt32(stream); - this.name = ParseUtils.readUntilNull(stream); - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - ParseUtils.writeUInt32(stream, this.flags); - ParseUtils.writeUInt32(stream, this.playerMasks); - ParseUtils.writeWithNullTerminator(stream, this.name); - } - - public int getByteLength() { - return 9 + this.name.length(); - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/w3i/Player.java b/core/src/com/etheller/warsmash/parsers/w3x/w3i/Player.java deleted file mode 100644 index 5ab3d0af..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/w3i/Player.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.w3i; - -import java.io.IOException; - -import com.etheller.warsmash.util.ParseUtils; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -/** - * A player. - */ -public class Player { - private int id; - private int type; - private int race; - private int isFixedStartPosition; - private String name; - private final float[] startLocation = new float[2]; - private long allyLowPriorities; - private long allyHighPriorities; - private long enemyLowPrioritiesFlags; - private long enemyHighPrioritiesFlags; - - public void load(final LittleEndianDataInputStream stream, final int version) throws IOException { - this.id = (int) ParseUtils.readUInt32(stream); - this.type = stream.readInt(); - this.race = stream.readInt(); - this.isFixedStartPosition = stream.readInt(); - this.name = ParseUtils.readUntilNull(stream); - ParseUtils.readFloatArray(stream, this.startLocation); - this.allyLowPriorities = ParseUtils.readUInt32(stream); - this.allyHighPriorities = ParseUtils.readUInt32(stream); - if (version > 30) { - this.enemyLowPrioritiesFlags = ParseUtils.readUInt32(stream); - this.enemyHighPrioritiesFlags = ParseUtils.readUInt32(stream); - } - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - ParseUtils.writeUInt32(stream, this.id); - stream.writeInt(this.type); - stream.writeInt(this.race); - stream.writeInt(this.isFixedStartPosition); - ParseUtils.writeWithNullTerminator(stream, this.name); - ParseUtils.writeFloatArray(stream, this.startLocation); - ParseUtils.writeUInt32(stream, this.allyLowPriorities); - ParseUtils.writeUInt32(stream, this.allyHighPriorities); - } - - public int getByteLength() { - return 33 + this.name.length(); - } - - public int getId() { - return this.id; - } - - public int getType() { - return this.type; - } - - public int getRace() { - return this.race; - } - - public int getIsFixedStartPosition() { - return this.isFixedStartPosition; - } - - public String getName() { - return this.name; - } - - public float[] getStartLocation() { - return this.startLocation; - } - - public long getAllyLowPriorities() { - return this.allyLowPriorities; - } - - public long getAllyHighPriorities() { - return this.allyHighPriorities; - } - - public long getEnemyLowPrioritiesFlags() { - return this.enemyLowPrioritiesFlags; - } - - public long getEnemyHighPrioritiesFlags() { - return this.enemyHighPrioritiesFlags; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomItem.java b/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomItem.java deleted file mode 100644 index cd332efd..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomItem.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.w3i; - -import java.io.IOException; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class RandomItem { - private int chance; - private War3ID id; - - public void load(final LittleEndianDataInputStream stream) throws IOException { - this.chance = stream.readInt(); - this.id = ParseUtils.readWar3ID(stream); - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - stream.writeInt(this.chance); - ParseUtils.writeWar3ID(stream, this.id); - } - - public int getChance() { - return this.chance; - } - - public War3ID getId() { - return this.id; - } - - public void setChance(final int chance) { - this.chance = chance; - } - - public void setId(final War3ID id) { - this.id = id; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomItemSet.java b/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomItemSet.java deleted file mode 100644 index 4b3e2ea1..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomItemSet.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.w3i; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.ParseUtils; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class RandomItemSet { - private final List items = new ArrayList<>(); - - public void load(final LittleEndianDataInputStream stream) throws IOException { - for (long i = 0, l = ParseUtils.readUInt32(stream); i < l; i++) { - final RandomItem item = new RandomItem(); - - item.load(stream); - - this.items.add(item); - } - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - ParseUtils.writeUInt32(stream, this.items.size()); - - for (final RandomItem item : this.items) { - item.save(stream); - } - } - - public int getByteLength() { - return 4 + (this.items.size() * 8); - } - - public List getItems() { - return this.items; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomItemTable.java b/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomItemTable.java deleted file mode 100644 index 634ff0c5..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomItemTable.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.w3i; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class RandomItemTable { - private War3ID id; - private String name; - private final List sets = new ArrayList<>(); - - public void load(final LittleEndianDataInputStream stream) throws IOException { - this.id = ParseUtils.readWar3ID(stream); - this.name = ParseUtils.readUntilNull(stream); - - for (long i = 0, l = ParseUtils.readUInt32(stream); i < l; i++) { - final RandomItemSet set = new RandomItemSet(); - - set.load(stream); - - this.sets.add(set); - } - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - ParseUtils.writeWar3ID(stream, this.id); - ParseUtils.writeWithNullTerminator(stream, this.name); - ParseUtils.writeUInt32(stream, this.sets.size()); - - for (final RandomItemSet set : this.sets) { - set.save(stream); - } - } - - public int getByteLength() { - int size = 9 + this.name.length(); - - for (final RandomItemSet set : this.sets) { - size += set.getByteLength(); - } - - return size; - } - - public War3ID getId() { - return this.id; - } - - public String getName() { - return this.name; - } - - public List getSets() { - return this.sets; - } - - public void setId(final War3ID id) { - this.id = id; - } - - public void setName(final String name) { - this.name = name; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomUnit.java b/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomUnit.java deleted file mode 100644 index 5ad694d4..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomUnit.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.w3i; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class RandomUnit { - private int chance; - private final List ids = new ArrayList<>(); - - public void load(final LittleEndianDataInputStream stream, final int positions) throws IOException { - this.chance = stream.readInt(); - - for (int i = 0; i < positions; i++) { - this.ids.add(ParseUtils.readWar3ID(stream)); - } - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - stream.writeInt(this.chance); - - for (final War3ID id : this.ids) { - ParseUtils.writeWar3ID(stream, id); - } - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomUnitTable.java b/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomUnitTable.java deleted file mode 100644 index 3295681d..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/w3i/RandomUnitTable.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.w3i; - -import java.io.IOException; -import java.util.List; - -import com.etheller.warsmash.util.ParseUtils; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class RandomUnitTable { - private int id; - private String name; - private int positions; - private int[] columnTypes; - private List units; - - public void load(final LittleEndianDataInputStream stream) throws IOException { - this.id = stream.readInt(); // TODO is this a War3ID? - this.name = ParseUtils.readUntilNull(stream); - this.positions = stream.readInt(); - this.columnTypes = ParseUtils.readInt32Array(stream, this.positions); - - for (long i = 0, l = ParseUtils.readUInt32(stream); i < l; i++) { - final RandomUnit unit = new RandomUnit(); - - unit.load(stream, this.positions); - - this.units.add(unit); - } - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - stream.writeInt(this.id); - ParseUtils.writeWithNullTerminator(stream, this.name); - stream.writeInt(this.positions); - ParseUtils.writeInt32Array(stream, this.columnTypes); - ParseUtils.writeUInt32(stream, this.units.size()); - - for (final RandomUnit unit : this.units) { - unit.save(stream); - } - } - - public int getByteLength() { - return 13 + this.name.length() + (this.columnTypes.length * 4) - + (this.units.size() * (4 + (4 * this.positions))); - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/w3i/TechAvailabilityChange.java b/core/src/com/etheller/warsmash/parsers/w3x/w3i/TechAvailabilityChange.java deleted file mode 100644 index 9c37f84f..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/w3i/TechAvailabilityChange.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.w3i; - -import java.io.IOException; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class TechAvailabilityChange { - private long playerFlags; - private War3ID id; - - public void load(final LittleEndianDataInputStream stream) throws IOException { - this.playerFlags = ParseUtils.readUInt32(stream); - this.id = ParseUtils.readWar3ID(stream); - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - ParseUtils.writeUInt32(stream, this.playerFlags); - ParseUtils.writeWar3ID(stream, this.id); - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/w3i/UpgradeAvailabilityChange.java b/core/src/com/etheller/warsmash/parsers/w3x/w3i/UpgradeAvailabilityChange.java deleted file mode 100644 index ed922c73..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/w3i/UpgradeAvailabilityChange.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.w3i; - -import java.io.IOException; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class UpgradeAvailabilityChange { - private long playerFlags; - private War3ID id; - private int levelAffected; - private int availability; - - public void load(final LittleEndianDataInputStream stream) throws IOException { - this.playerFlags = ParseUtils.readUInt32(stream); - this.id = ParseUtils.readWar3ID(stream); - this.levelAffected = stream.readInt(); - this.availability = stream.readInt(); - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - ParseUtils.writeUInt32(stream, this.playerFlags); - ParseUtils.writeWar3ID(stream, this.id); - stream.writeInt(this.levelAffected); - stream.writeInt(this.availability); - } - -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/w3i/War3MapW3i.java b/core/src/com/etheller/warsmash/parsers/w3x/w3i/War3MapW3i.java deleted file mode 100644 index 32c6df73..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/w3i/War3MapW3i.java +++ /dev/null @@ -1,456 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.w3i; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.ParseUtils; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -/** - * war3map.w3i - the general map information file. - */ -public class War3MapW3i { - private int version; - private int saves; - private int editorVersion; - private final short[] unknown1 = new short[16]; - private String name; - private String author; - private String description; - private String recommendedPlayers; - private final float[] cameraBounds = new float[8]; - private final int[] cameraBoundsComplements = new int[4]; - private final int[] playableSize = new int[2]; - private long flags; - private char tileset = 'A'; - private int campaignBackground; - private String loadingScreenModel; - private String loadingScreenText; - private String loadingScreenTitle; - private String loadingScreenSubtitle; - private int loadingScreen; - private String prologueScreenModel; - private String prologueScreenText; - private String prologueScreenTitle; - private String prologueScreenSubtitle; - private int useTerrainFog; - private final float[] fogHeight = new float[2]; - private float fogDensity; - private final short[] fogColor = new short[4]; - private int globalWeather; - private String soundEnvironment; - private char lightEnvironmentTileset; - private final short[] waterVertexColor = new short[4]; - private final short[] unknown2ProbablyLua = new short[4]; - private final List players = new ArrayList<>(); - private final List forces = new ArrayList<>(); - private final List upgradeAvailabilityChanges = new ArrayList<>(); - private final List techAvailabilityChanges = new ArrayList<>(); - private final List randomUnitTables = new ArrayList<>(); - private final List randomItemTables = new ArrayList<>(); - - public War3MapW3i(final LittleEndianDataInputStream stream) throws IOException { - if (stream != null) { - load(stream); - } - } - - private void load(final LittleEndianDataInputStream stream) throws IOException { - this.version = stream.readInt(); - this.saves = stream.readInt(); - this.editorVersion = stream.readInt(); - - if (this.version > 27) { - ParseUtils.readUInt8Array(stream, this.unknown1); - } - - this.name = ParseUtils.readUntilNull(stream); - this.author = ParseUtils.readUntilNull(stream); - this.description = ParseUtils.readUntilNull(stream); - this.recommendedPlayers = ParseUtils.readUntilNull(stream); - ParseUtils.readFloatArray(stream, this.cameraBounds); - ParseUtils.readInt32Array(stream, this.cameraBoundsComplements); - ParseUtils.readInt32Array(stream, this.playableSize); - this.flags = ParseUtils.readUInt32(stream); - this.tileset = (char) stream.read(); - this.campaignBackground = stream.readInt(); - - if (this.version > 24) { - this.loadingScreenModel = ParseUtils.readUntilNull(stream); - } - - this.loadingScreenText = ParseUtils.readUntilNull(stream); - this.loadingScreenTitle = ParseUtils.readUntilNull(stream); - this.loadingScreenSubtitle = ParseUtils.readUntilNull(stream); - this.loadingScreen = stream.readInt(); - - if (this.version > 24) { - this.prologueScreenModel = ParseUtils.readUntilNull(stream); - } - - this.prologueScreenText = ParseUtils.readUntilNull(stream); - this.prologueScreenTitle = ParseUtils.readUntilNull(stream); - this.prologueScreenSubtitle = ParseUtils.readUntilNull(stream); - - if (this.version > 24) { - this.useTerrainFog = stream.readInt(); - ParseUtils.readFloatArray(stream, this.fogHeight); - this.fogDensity = stream.readFloat(); - ParseUtils.readUInt8Array(stream, this.fogColor); - this.globalWeather = stream.readInt(); // TODO probably war3id, right? - this.soundEnvironment = ParseUtils.readUntilNull(stream); - this.lightEnvironmentTileset = (char) stream.read(); - ParseUtils.readUInt8Array(stream, this.waterVertexColor); - } - - if (this.version > 27) { - ParseUtils.readUInt8Array(stream, this.unknown2ProbablyLua); - } - if (this.version > 30) { - final long supportedModes = ParseUtils.readUInt32(stream); - final long gameDataVersion = ParseUtils.readUInt32(stream); - } - - for (int i = 0, l = stream.readInt(); i < l; i++) { - final Player player = new Player(); - - player.load(stream, this.version); - - this.players.add(player); - } - - for (int i = 0, l = stream.readInt(); i < l; i++) { - final Force force = new Force(); - - force.load(stream); - - this.forces.add(force); - } - - if (stream.available() == 1) { - // some kind of really stupid protected map??? - return; - } - if (stream.available() > 0) { - for (int i = 0, l = stream.readInt(); i < l; i++) { - final UpgradeAvailabilityChange upgradeAvailabilityChange = new UpgradeAvailabilityChange(); - - upgradeAvailabilityChange.load(stream); - - this.upgradeAvailabilityChanges.add(upgradeAvailabilityChange); - } - } - - if (stream.available() > 0) { - for (int i = 0, l = stream.readInt(); i < l; i++) { - final TechAvailabilityChange techAvailabilityChange = new TechAvailabilityChange(); - - techAvailabilityChange.load(stream); - - this.techAvailabilityChanges.add(techAvailabilityChange); - } - } - - if (stream.available() > 0) { - for (int i = 0, l = stream.readInt(); i < l; i++) { - final RandomUnitTable randomUnitTable = new RandomUnitTable(); - - randomUnitTable.load(stream); - - this.randomUnitTables.add(randomUnitTable); - } - } - - if (this.version > 24) { - if (stream.available() > 0) { - for (int i = 0, l = stream.readInt(); i < l; i++) { - final RandomItemTable randomItemTable = new RandomItemTable(); - - randomItemTable.load(stream); - - this.randomItemTables.add(randomItemTable); - } - } - } - } - - public void save(final LittleEndianDataOutputStream stream) throws IOException { - stream.writeInt(this.version); - stream.writeInt(this.saves); - stream.writeInt(this.editorVersion); - - if (this.version > 27) { - ParseUtils.writeUInt8Array(stream, this.unknown1); - } - - ParseUtils.writeWithNullTerminator(stream, this.name); - ParseUtils.writeWithNullTerminator(stream, this.author); - ParseUtils.writeWithNullTerminator(stream, this.description); - ParseUtils.writeWithNullTerminator(stream, this.recommendedPlayers); - ParseUtils.writeFloatArray(stream, this.cameraBounds); - ParseUtils.writeInt32Array(stream, this.cameraBoundsComplements); - ParseUtils.writeInt32Array(stream, this.playableSize); - ParseUtils.writeUInt32(stream, this.flags); - stream.write((byte) this.tileset); - stream.writeInt(this.campaignBackground); - - if (this.version > 24) { - ParseUtils.writeWithNullTerminator(stream, this.loadingScreenModel); - } - - ParseUtils.writeWithNullTerminator(stream, this.loadingScreenText); - ParseUtils.writeWithNullTerminator(stream, this.loadingScreenTitle); - ParseUtils.writeWithNullTerminator(stream, this.loadingScreenSubtitle); - stream.writeInt(this.loadingScreen); - - if (this.version > 24) { - ParseUtils.writeWithNullTerminator(stream, this.prologueScreenModel); - } - - ParseUtils.writeWithNullTerminator(stream, this.prologueScreenText); - ParseUtils.writeWithNullTerminator(stream, this.prologueScreenTitle); - ParseUtils.writeWithNullTerminator(stream, this.prologueScreenSubtitle); - - if (this.version > 24) { - stream.writeInt(this.useTerrainFog); - ParseUtils.writeFloatArray(stream, this.fogHeight); - stream.writeFloat(this.fogDensity); - ParseUtils.writeUInt8Array(stream, this.fogColor); - stream.writeInt(this.globalWeather); // TODO War3ID??? - ParseUtils.writeWithNullTerminator(stream, this.soundEnvironment); - stream.write((byte) this.lightEnvironmentTileset); - ParseUtils.writeUInt8Array(stream, this.waterVertexColor); - } - - if (this.version > 27) { - ParseUtils.writeUInt8Array(stream, this.unknown2ProbablyLua); - } - - ParseUtils.writeUInt32(stream, this.players.size()); - - for (final Player player : this.players) { - player.save(stream); - } - - ParseUtils.writeUInt32(stream, this.forces.size()); - - for (final Force force : this.forces) { - force.save(stream); - } - - ParseUtils.writeUInt32(stream, this.upgradeAvailabilityChanges.size()); - - for (final UpgradeAvailabilityChange change : this.upgradeAvailabilityChanges) { - change.save(stream); - } - - ParseUtils.writeUInt32(stream, this.techAvailabilityChanges.size()); - - for (final TechAvailabilityChange change : this.techAvailabilityChanges) { - change.save(stream); - } - - ParseUtils.writeUInt32(stream, this.randomUnitTables.size()); - - for (final RandomUnitTable table : this.randomUnitTables) { - table.save(stream); - } - - if (this.version > 24) { - ParseUtils.writeUInt32(stream, this.randomItemTables.size()); - - for (final RandomItemTable table : this.randomItemTables) { - table.save(stream); - } - } - - } - - public int getByteLength() { - int size = 111 + this.name.length() + this.author.length() + this.description.length() - + this.recommendedPlayers.length() + this.loadingScreenText.length() + this.loadingScreenTitle.length() - + this.loadingScreenSubtitle.length() + this.prologueScreenText.length() - + this.prologueScreenTitle.length() + this.prologueScreenSubtitle.length(); - - for (final Player player : this.players) { - size += player.getByteLength(); - } - - for (final Force force : this.forces) { - size += force.getByteLength(); - } - - size += this.upgradeAvailabilityChanges.size() * 16; - - size += this.techAvailabilityChanges.size() * 8; - - for (final RandomUnitTable table : this.randomUnitTables) { - size += table.getByteLength(); - } - - if (this.version > 24) { - size += 36 + this.loadingScreenModel.length() + this.prologueScreenModel.length() - + this.soundEnvironment.length(); - - for (final RandomItemTable table : this.randomItemTables) { - size += table.getByteLength(); - } - } - - return size; - } - - public int getVersion() { - return this.version; - } - - public int getSaves() { - return this.saves; - } - - public int getEditorVersion() { - return this.editorVersion; - } - - public short[] getUnknown1() { - return this.unknown1; - } - - public String getName() { - return this.name; - } - - public String getAuthor() { - return this.author; - } - - public String getDescription() { - return this.description; - } - - public String getRecommendedPlayers() { - return this.recommendedPlayers; - } - - public float[] getCameraBounds() { - return this.cameraBounds; - } - - public int[] getCameraBoundsComplements() { - return this.cameraBoundsComplements; - } - - public int[] getPlayableSize() { - return this.playableSize; - } - - public long getFlags() { - return this.flags; - } - - public char getTileset() { - return this.tileset; - } - - public int getCampaignBackground() { - return this.campaignBackground; - } - - public String getLoadingScreenModel() { - return this.loadingScreenModel; - } - - public String getLoadingScreenText() { - return this.loadingScreenText; - } - - public String getLoadingScreenTitle() { - return this.loadingScreenTitle; - } - - public String getLoadingScreenSubtitle() { - return this.loadingScreenSubtitle; - } - - public int getLoadingScreen() { - return this.loadingScreen; - } - - public String getPrologueScreenModel() { - return this.prologueScreenModel; - } - - public String getPrologueScreenText() { - return this.prologueScreenText; - } - - public String getPrologueScreenTitle() { - return this.prologueScreenTitle; - } - - public String getPrologueScreenSubtitle() { - return this.prologueScreenSubtitle; - } - - public int getUseTerrainFog() { - return this.useTerrainFog; - } - - public float[] getFogHeight() { - return this.fogHeight; - } - - public float getFogDensity() { - return this.fogDensity; - } - - public short[] getFogColor() { - return this.fogColor; - } - - public int getGlobalWeather() { - return this.globalWeather; - } - - public String getSoundEnvironment() { - return this.soundEnvironment; - } - - public char getLightEnvironmentTileset() { - return this.lightEnvironmentTileset; - } - - public short[] getWaterVertexColor() { - return this.waterVertexColor; - } - - public short[] getUnknown2() { - return this.unknown2ProbablyLua; - } - - public List getPlayers() { - return this.players; - } - - public List getForces() { - return this.forces; - } - - public List getUpgradeAvailabilityChanges() { - return this.upgradeAvailabilityChanges; - } - - public List getTechAvailabilityChanges() { - return this.techAvailabilityChanges; - } - - public List getRandomUnitTables() { - return this.randomUnitTables; - } - - public List getRandomItemTables() { - return this.randomItemTables; - } -} diff --git a/core/src/com/etheller/warsmash/parsers/w3x/wpm/War3MapWpm.java b/core/src/com/etheller/warsmash/parsers/w3x/wpm/War3MapWpm.java deleted file mode 100644 index 78b436f0..00000000 --- a/core/src/com/etheller/warsmash/parsers/w3x/wpm/War3MapWpm.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.etheller.warsmash.parsers.w3x.wpm; - -import java.io.IOException; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; - -public class War3MapWpm { - private static final War3ID MAGIC_NUMBER = War3ID.fromString("MP3W"); - private int version; - private final int[] size = new int[2]; - private short[] pathing; - - public War3MapWpm(final LittleEndianDataInputStream stream) throws IOException { - if (stream != null) { - this.load(stream); - } - } - - private boolean load(final LittleEndianDataInputStream stream) throws IOException { - final War3ID firstId = ParseUtils.readWar3ID(stream); - if (!MAGIC_NUMBER.equals(firstId)) { - return false; - } - - this.version = stream.readInt(); - ParseUtils.readInt32Array(stream, this.size); - this.pathing = ParseUtils.readUInt8Array(stream, this.size[0] * this.size[1]); - - return true; - } - - public int getVersion() { - return this.version; - } - - public int[] getSize() { - return this.size; - } - - public short[] getPathing() { - return this.pathing; - } - - public void setVersion(final int version) { - this.version = version; - } - - public void setPathing(final short[] pathing) { - this.pathing = pathing; - } - -} diff --git a/core/src/com/etheller/warsmash/units/DataTable.java b/core/src/com/etheller/warsmash/units/DataTable.java deleted file mode 100644 index d9c33e3c..00000000 --- a/core/src/com/etheller/warsmash/units/DataTable.java +++ /dev/null @@ -1,326 +0,0 @@ -package com.etheller.warsmash.units; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.etheller.warsmash.util.StringBundle; - -public class DataTable implements ObjectData { - public static boolean DEBUG = false; - - Map dataTable = new LinkedHashMap<>(); - - private final StringBundle worldEditStrings; - - public DataTable(final StringBundle worldEditStrings) { - this.worldEditStrings = worldEditStrings; - } - - @Override - public String getLocalizedString(final String key) { - return this.worldEditStrings.getString(key); - } - - @Override - public Set keySet() { - final Set outputKeySet = new HashSet<>(); - final Set internalKeySet = this.dataTable.keySet(); - for (final StringKey key : internalKeySet) { - outputKeySet.add(key.getString()); - } - return outputKeySet; - } - - public void readTXT(final InputStream inputStream) { - try { - readTXT(inputStream, false); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - public void readTXT(final File f) { - readTXT(f, false); - } - - public void readTXT(final File f, final boolean canProduce) { - try { - readTXT(new FileInputStream(f), canProduce); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - public void readSLK(final File f) { - try { - readSLK(new FileInputStream(f)); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - public void readTXT(final InputStream txt, final boolean canProduce) throws IOException { - if (txt == null) { - return; - } - final BufferedReader reader = new BufferedReader(new InputStreamReader(txt, "utf-8")); - // BOM marker will only appear on the very beginning - reader.mark(4); - if ('\ufeff' != reader.read()) { - reader.reset(); // not the BOM marker - } - - String input = ""; - Element currentUnit = null; - final boolean first = true; - while ((input = reader.readLine()) != null) { - if (DEBUG) { - System.out.println(input); - } - if (input.startsWith("//")) { - continue; - } - if (input.startsWith("[") && input.contains("]")) { - final int start = input.indexOf("[") + 1; - final int end = input.indexOf("]"); - final String newKey = input.substring(start, end); - final String newKeyBase = newKey; - currentUnit = this.dataTable.get(new StringKey(newKey)); - if (currentUnit == null) { - currentUnit = new Element(newKey, this); - if (canProduce) { - currentUnit = new LMUnit(newKey, this); - this.dataTable.put(new StringKey(newKey), currentUnit); - } - } - } - else if (input.contains("=")) { - final int eIndex = input.indexOf("="); - final String fieldValue = input.substring(eIndex + 1); - final StringBuilder builder = new StringBuilder(); - boolean withinQuotedString = false; - final String fieldName = input.substring(0, eIndex); - boolean wasSlash = false; - final List values = new ArrayList<>(); - for (int i = 0; i < fieldValue.length(); i++) { - final char c = fieldValue.charAt(i); - final boolean isSlash = c == '/'; - if (isSlash && wasSlash && !withinQuotedString) { - builder.setLength(builder.length() - 1); - break; // comment starts here - } - if (c == '\"') { - withinQuotedString = !withinQuotedString; - } - else if (!withinQuotedString && (c == ',')) { - values.add(builder.toString().trim()); - builder.setLength(0); // empty buffer - } - else { - builder.append(c); - } - wasSlash = isSlash; - } - if (builder.length() > 0) { - if (currentUnit == null) { - System.out.println("null for " + input); - } - values.add(builder.toString().trim()); - } - currentUnit.setField(fieldName, values); - } - } - - reader.close(); - } - - public void readSLK(final InputStream txt) throws IOException { - if (txt == null) { - return; - } - final BufferedReader reader = new BufferedReader(new InputStreamReader(txt, "utf-8")); - - String input = ""; - Element currentUnit = null; - input = reader.readLine(); - if (!input.contains("ID")) { - System.err.println("Formatting of SLK is unusual."); - } - input = reader.readLine(); - while (input.startsWith("P;") || input.startsWith("F;")) { - input = reader.readLine(); - } - final int yIndex = input.indexOf("Y") + 1; - final int xIndex = input.indexOf("X") + 1; - int colCount = 0; - int rowCount = 0; - boolean flipMode = false; - if (xIndex > yIndex) { - colCount = Integer.parseInt(input.substring(xIndex, input.lastIndexOf(";"))); - rowCount = Integer.parseInt(input.substring(yIndex, xIndex - 2)); - } - else { - rowCount = Integer.parseInt(input.substring(yIndex, input.lastIndexOf(";"))); - colCount = Integer.parseInt(input.substring(xIndex, yIndex - 2)); - flipMode = true; - } - int rowStartCount = 0; - String[] dataNames = new String[colCount]; - int col = 0; - int lastFieldId = 0; - while ((input = reader.readLine()) != null) { - if (DEBUG) { - System.out.println(input); - } - if (input.startsWith("E")) { - break; - } - if (input.startsWith("O;")) { - continue; - } - if (input.contains("X1;") || input.endsWith(";X1")) { - rowStartCount++; - col = 0; - } - else { - col++; - } - String kInput; - if (input.startsWith("F;")) { - kInput = reader.readLine(); - if (DEBUG) { - System.out.println(kInput); - } - } - else { - kInput = input; - } - if (rowStartCount <= 1) { - final int subXIndex = input.indexOf("X"); - final int subYIndex = input.indexOf("Y"); - if ((subYIndex >= 0) && (subYIndex < subXIndex)) { - final int eIndex = kInput.indexOf("K"); - final int fieldIdEndIndex = kInput != input ? input.length() : eIndex - 1; - if ((eIndex == -1) || (kInput.charAt(eIndex - 1) != ';')) { - continue; - } - final int fieldId; - if (subXIndex < 0) { - if (lastFieldId == 0) { - rowStartCount++; - } - fieldId = lastFieldId + 1; - } - else { - fieldId = Integer.parseInt(input.substring(subXIndex + 1, fieldIdEndIndex)); - } - - final int quotationIndex = kInput.indexOf("\""); - if ((fieldId - 1) >= dataNames.length) { - dataNames = Arrays.copyOf(dataNames, fieldId); - } - if (quotationIndex == -1) { - dataNames[fieldId - 1] = kInput.substring(eIndex + 1); - } - else { - dataNames[fieldId - 1] = kInput.substring(quotationIndex + 1, kInput.lastIndexOf("\"")); - } - lastFieldId = fieldId; - continue; - } - else { - int eIndex = kInput.indexOf("K"); - if ((eIndex == -1) || (kInput.charAt(eIndex - 1) != ';')) { - continue; - } - final int fieldId; - if (subXIndex < 0) { - if (lastFieldId == 0) { - rowStartCount++; - } - fieldId = lastFieldId + 1; - } - else { - if (flipMode && input.contains("Y") && (input == kInput)) { - eIndex = Math.min(subYIndex, eIndex); - } - final int fieldIdEndIndex = kInput != input ? input.length() : eIndex - 1; - fieldId = Integer.parseInt(input.substring(subXIndex + 1, fieldIdEndIndex)); - } - - final int quotationIndex = kInput.indexOf("\""); - if ((fieldId - 1) >= dataNames.length) { - dataNames = Arrays.copyOf(dataNames, fieldId); - } - if (quotationIndex == -1) { - dataNames[fieldId - 1] = kInput.substring(eIndex + 1, kInput.length()); - } - else { - dataNames[fieldId - 1] = kInput.substring(quotationIndex + 1, kInput.lastIndexOf("\"")); - } - lastFieldId = fieldId; - continue; - } - } - if (input.contains("X1;") || ((input != kInput) && input.endsWith("X1"))) { - final int start = kInput.indexOf("\"") + 1; - final int end = kInput.lastIndexOf("\""); - if ((start - 1) != end) { - final String newKey = kInput.substring(start, end); - currentUnit = this.dataTable.get(new StringKey(newKey)); - if (currentUnit == null) { - currentUnit = new Element(newKey, this); - this.dataTable.put(new StringKey(newKey), currentUnit); - } - } - } - else if (kInput.contains("K")) { - final int subXIndex = input.indexOf("X"); - int eIndex = kInput.indexOf("K"); - if (flipMode && kInput.contains("Y")) { - eIndex = Math.min(kInput.indexOf("Y"), eIndex); - } - final int fieldIdEndIndex = kInput != input ? input.length() : eIndex - 1; - final int fieldId = (subXIndex == -1) || (subXIndex > fieldIdEndIndex) ? 1 - : Integer.parseInt(input.substring(subXIndex + 1, fieldIdEndIndex)); - String fieldValue = kInput.substring(eIndex + 1); - if ((fieldValue.length() > 1) && fieldValue.startsWith("\"") && fieldValue.endsWith("\"")) { - fieldValue = fieldValue.substring(1, fieldValue.length() - 1); - } - if (dataNames[fieldId - 1] != null) { - currentUnit.setField(dataNames[fieldId - 1], fieldValue); - } - } - } - - reader.close(); - } - - @Override - public Element get(final String id) { - return this.dataTable.get(new StringKey(id)); - } - - @Override - public void setValue(final String id, final String field, final String value) { - get(id).setField(field, value); - } - - public void put(final String id, final Element e) { - this.dataTable.put(new StringKey(id), e); - } -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/units/Element.java b/core/src/com/etheller/warsmash/units/Element.java deleted file mode 100644 index 15de6fd0..00000000 --- a/core/src/com/etheller/warsmash/units/Element.java +++ /dev/null @@ -1,217 +0,0 @@ -package com.etheller.warsmash.units; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; - -public class Element extends HashedGameObject { - - public Element(final String id, final DataTable table) { - super(id, table); - } - - public List builds() { - return getFieldAsList("Builds", this.parentTable); - } - - public List requires() { - final List requirements = getFieldAsList("Requires", this.parentTable); - final List reqLvls = requiresLevels(); - return requirements; - } - - public List requiresLevels() { - final String stringList = getField("Requiresamount"); - final String[] listAsArray = stringList.split(","); - final LinkedList output = new LinkedList<>(); - if ((listAsArray != null) && (listAsArray.length > 0) && !listAsArray[0].equals("")) { - for (final String levelString : listAsArray) { - final Integer level = Integer.parseInt(levelString); - if (level != null) { - output.add(level); - } - } - } - return output; - } - - public List parents() { - return getFieldAsList("Parents", this.parentTable); - } - - public List children() { - return getFieldAsList("Children", this.parentTable); - } - - public List requiredBy() { - return getFieldAsList("RequiredBy", this.parentTable); - } - - public List trains() { - return getFieldAsList("Trains", this.parentTable); - } - - public List upgrades() { - return getFieldAsList("Upgrade", this.parentTable); - } - - public List researches() { - return getFieldAsList("Researches", this.parentTable); - } - - public List dependencyOr() { - return getFieldAsList("DependencyOr", this.parentTable); - } - - public List abilities() { - return getFieldAsList("abilList", this.parentTable); - } - - HashMap> hashedLists = new HashMap<>(); - - @Override - public String toString() { - return getField("Name"); - } - - public int getTechTier() { - final String tier = getField("Custom Field: TechTier"); - if (tier == null) { - return -1; - } - return Integer.parseInt(tier); - } - - public void setTechTier(final int i) { - setField("Custom Field: TechTier", i + ""); - } - - public int getTechDepth() { - final String tier = getField("Custom Field: TechDepth"); - if (tier == null) { - return -1; - } - return Integer.parseInt(tier); - } - - public void setTechDepth(final int i) { - setField("Custom Field: TechDepth", i + ""); - } - - public String getIconPath() { - String artField = getField("Art"); - if (artField.indexOf(',') != -1) { - artField = artField.substring(0, artField.indexOf(',')); - } - return artField; - } - - public String getUnitId() { - return this.id; - } - - @Override - public String getName() { - String name = getField("Name"); - boolean nameKnown = name.length() >= 1; - if (!nameKnown && !getField("code").equals(this.id) && (getField("code").length() >= 4)) { - final Element other = (Element) this.parentTable.get(getField("code").substring(0, 4)); - if (other != null) { - name = other.getName(); - nameKnown = true; - } - } - if (!nameKnown && (getField("EditorName").length() > 1)) { - name = getField("EditorName"); - nameKnown = true; - } - if (!nameKnown && (getField("Editorname").length() > 1)) { - name = getField("Editorname"); - nameKnown = true; - } - if (!nameKnown && (getField("BuffTip").length() > 1)) { - name = getField("BuffTip"); - nameKnown = true; - } - if (!nameKnown && (getField("Bufftip").length() > 1)) { - name = getField("Bufftip"); - nameKnown = true; - } - if (nameKnown && name.startsWith("WESTRING")) { - if (!name.contains(" ")) { - name = this.parentTable.getLocalizedString(name); - } - else { - final String[] names = name.split(" "); - name = ""; - for (final String subName : names) { - if (name.length() > 0) { - name += " "; - } - if (subName.startsWith("WESTRING")) { - name += this.parentTable.getLocalizedString(subName); - } - else { - name += subName; - } - } - } - if (name.startsWith("\"") && name.endsWith("\"")) { - name = name.substring(1, name.length() - 1); - } - setField("Name", name); - } - if (!nameKnown) { - name = this.parentTable.getLocalizedString("WESTRING_UNKNOWN") + " '" + getUnitId() + "'"; - } - if (getField("campaign").startsWith("1") && Character.isUpperCase(getUnitId().charAt(0))) { - name = getField("Propernames"); - if (name.contains(",")) { - name = name.split(",")[0]; - } - } - String suf = getField("EditorSuffix"); - if ((suf.length() > 0) && !suf.equals("_")) { - if (suf.startsWith("WESTRING")) { - suf = this.parentTable.getLocalizedString(suf); - } - if (!suf.startsWith(" ")) { - name += " "; - } - name += suf; - } - return name; - } - - public void addParent(final String parentId) { - String parentField = getField("Parents"); - if (!parentField.contains(parentId)) { - parentField = parentField + "," + parentId; - setField("Parents", parentField); - } - } - - public void addChild(final String parentId) { - String parentField = getField("Children"); - if (!parentField.contains(parentId)) { - parentField = parentField + "," + parentId; - setField("Children", parentField); - } - } - - public void addRequiredBy(final String parentId) { - String parentField = getField("RequiredBy"); - if (!parentField.contains(parentId)) { - parentField = parentField + "," + parentId; - setField("RequiredBy", parentField); - } - } - - public void addResearches(final String parentId) { - String parentField = getField("Researches"); - if (!parentField.contains(parentId)) { - parentField = parentField + "," + parentId; - setField("Researches", parentField); - } - } -} diff --git a/core/src/com/etheller/warsmash/units/GameObject.java b/core/src/com/etheller/warsmash/units/GameObject.java deleted file mode 100644 index bc5f5d07..00000000 --- a/core/src/com/etheller/warsmash/units/GameObject.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.etheller.warsmash.units; - -import java.util.Collections; -import java.util.List; -import java.util.Set; - -public interface GameObject { - - public void setField(String field, String value); - - public void setField(String field, String value, int index); - - public String getField(String field); - - public String getField(String field, int index); - - public int getFieldValue(String field); - - public int getFieldValue(String field, int index); - - public float getFieldFloatValue(String field); - - public float getFieldFloatValue(String field, int index); - - public List getFieldAsList(String field, ObjectData objectData); - - public String getId(); - - public ObjectData getTable(); - - public String getName(); - - public Set keySet(); - - GameObject EMPTY = new GameObject() { - - @Override - public void setField(final String field, final String value, final int index) { - } - - @Override - public void setField(final String field, final String value) { - } - - @Override - public Set keySet() { - return Collections.emptySet(); - } - - @Override - public ObjectData getTable() { - return null; - } - - @Override - public String getName() { - return ""; - } - - @Override - public String getId() { - return "0000"; - } - - @Override - public int getFieldValue(final String field, final int index) { - return 0; - } - - @Override - public int getFieldValue(final String field) { - return 0; - } - - @Override - public float getFieldFloatValue(final String field) { - return 0; - } - - @Override - public float getFieldFloatValue(final String field, final int index) { - return 0; - } - - @Override - public List getFieldAsList(final String field, final ObjectData objectData) { - return Collections.emptyList(); - } - - @Override - public String getField(final String field, final int index) { - return ""; - } - - @Override - public String getField(final String field) { - return ""; - } - }; - -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/units/HashedGameObject.java b/core/src/com/etheller/warsmash/units/HashedGameObject.java deleted file mode 100644 index 0768c934..00000000 --- a/core/src/com/etheller/warsmash/units/HashedGameObject.java +++ /dev/null @@ -1,278 +0,0 @@ -package com.etheller.warsmash.units; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public abstract class HashedGameObject implements GameObject { - HashMap> fields = new HashMap<>(); - String id; - ObjectData parentTable; - - transient HashMap> hashedLists = new HashMap<>(); - - public HashedGameObject(final String id, final ObjectData table) { - this.id = id; - this.parentTable = table; - } - - @Override - public void setField(final String field, final String value) { - final StringKey key = new StringKey(field); - List list = this.fields.get(key); - if (list == null) { - list = new ArrayList<>(); - this.fields.put(key, list); - list.add(value); - } - else { - list.set(0, value); - } - } - - public void setField(final String field, final List value) { - final StringKey key = new StringKey(field); - if (value.isEmpty()) { - this.fields.remove(key); - } - else { - this.fields.put(key, value); - } - } - - @Override - public String getField(final String field) { - final String value = ""; - if (this.fields.get(new StringKey(field)) != null) { - final List list = this.fields.get(new StringKey(field)); - final StringBuilder sb = new StringBuilder(); - if (list != null) { - for (final String str : list) { - if (sb.length() != 0) { - sb.append(','); - } - sb.append(str); - } - return sb.toString(); - } - } - return value; - } - - public boolean hasField(final String field) { - return this.fields.containsKey(new StringKey(field)); - } - - @Override - public int getFieldValue(final String field) { - int i = 0; - try { - i = Integer.parseInt(getField(field).trim()); - } - catch (final NumberFormatException e) { - - } - return i; - } - - @Override - public float getFieldFloatValue(final String field) { - float i = 0; - try { - i = Float.parseFloat(getField(field).trim()); - } - catch (final NumberFormatException e) { - - } - return i; - } - - @Override - public float getFieldFloatValue(final String field, final int index) { - float i = 0; - try { - i = Float.parseFloat(getField(field, index).trim()); - } - catch (final NumberFormatException e) { - - } - return i; - } - - @Override - public void setField(final String field, final String value, final int index) { - final StringKey key = new StringKey(field); - List list = this.fields.get(key); - if (list == null) { - if (index == 0) { - list = new ArrayList<>(); - this.fields.put(key, list); - list.add(value); - } - else { - throw new IndexOutOfBoundsException(); - } - } - else { - if (list.size() == index) { - list.add(value); - } - else { - list.set(index, value); - } - } - } - - @Override - public String getField(final String field, final int index) { - String value = ""; - if (this.fields.get(new StringKey(field)) != null) { - final List list = this.fields.get(new StringKey(field)); - if (list != null) { - if (list.size() > index) { - value = list.get(index); - } - else if (list.size() > 0) { - value = list.get(list.size() - 1); - } - } - } - return value; - } - - @Override - public int getFieldValue(final String field, final int index) { - int i = 0; - try { - i = Integer.parseInt(getField(field, index).trim()); - } - catch (final NumberFormatException e) { - - } - return i; - } - - @Override - public List getFieldAsList(final String field, final ObjectData parentTable) { - List fieldAsList; - fieldAsList = new ArrayList<>(); - final String stringList = getField(field); - final String[] listAsArray = stringList.split(","); - if ((listAsArray != null) && (listAsArray.length > 0)) { - for (final String buildingId : listAsArray) { - final GameObject referencedUnit = parentTable.get(buildingId); - if (referencedUnit != null) { - fieldAsList.add(referencedUnit); - } - } - } - return fieldAsList; - } - - @Override - public String toString() { - return getField("Name"); - } - - @Override - public String getId() { - return this.id; - } - - @Override - public String getName() { - String name = getField("Name"); - boolean nameKnown = name.length() >= 1; - if (!nameKnown && !getField("code").equals(this.id) && (getField("code").length() >= 4)) { - final GameObject other = this.parentTable.get(getField("code").substring(0, 4)); - if (other != null) { - name = other.getName(); - nameKnown = true; - } - } - if (!nameKnown && (getField("EditorName").length() > 1)) { - name = getField("EditorName"); - nameKnown = true; - } - if (!nameKnown && (getField("Editorname").length() > 1)) { - name = getField("Editorname"); - nameKnown = true; - } - if (!nameKnown && (getField("BuffTip").length() > 1)) { - name = getField("BuffTip"); - nameKnown = true; - } - if (!nameKnown && (getField("Bufftip").length() > 1)) { - name = getField("Bufftip"); - nameKnown = true; - } - if (nameKnown && name.startsWith("WESTRING")) { - if (!name.contains(" ")) { - name = this.parentTable.getLocalizedString(name); - } - else { - final String[] names = name.split(" "); - name = ""; - for (final String subName : names) { - if (name.length() > 0) { - name += " "; - } - if (subName.startsWith("WESTRING")) { - name += this.parentTable.getLocalizedString(subName); - } - else { - name += subName; - } - } - } - if (name.startsWith("\"") && name.endsWith("\"")) { - name = name.substring(1, name.length() - 1); - } - setField("Name", name); - } - if (!nameKnown) { - name = this.parentTable.getLocalizedString("WESTRING_UNKNOWN") + " '" + getId() + "'"; - } - if (getField("campaign").startsWith("1") && Character.isUpperCase(getId().charAt(0))) { - name = getField("Propernames"); - if (name.contains(",")) { - name = name.split(",")[0]; - } - } - String suf = getField("EditorSuffix"); - if ((suf.length() > 0) && !suf.equals("_")) { - if (suf.startsWith("WESTRING")) { - suf = this.parentTable.getLocalizedString(suf); - } - if (!suf.startsWith(" ")) { - name += " "; - } - name += suf; - } - return name; - } - - public void addToList(final String parentId, final String list) { - String parentField = getField(list); - if (!parentField.contains(parentId)) { - parentField = parentField + "," + parentId; - setField(list, parentField); - } - } - - @Override - public ObjectData getTable() { - return this.parentTable; - } - - @Override - public Set keySet() { - final Set keySet = new HashSet<>(); - for (final StringKey key : this.fields.keySet()) { - keySet.add(key.getString()); - } - return keySet; - } -} diff --git a/core/src/com/etheller/warsmash/units/LMUnit.java b/core/src/com/etheller/warsmash/units/LMUnit.java deleted file mode 100644 index 39d29a11..00000000 --- a/core/src/com/etheller/warsmash/units/LMUnit.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.etheller.warsmash.units; - -import java.util.LinkedHashMap; - -public class LMUnit extends Element { - - public LMUnit(final String id, final DataTable table) { - super(id, table); - this.fields = new LinkedHashMap<>(); - } - -} diff --git a/core/src/com/etheller/warsmash/units/ObjectData.java b/core/src/com/etheller/warsmash/units/ObjectData.java deleted file mode 100644 index 0ff7c61b..00000000 --- a/core/src/com/etheller/warsmash/units/ObjectData.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.units; - -import java.util.Set; - -public interface ObjectData { - GameObject get(String id); - - void setValue(String id, String field, String value); - - Set keySet(); - - String getLocalizedString(String key); -} diff --git a/core/src/com/etheller/warsmash/units/StandardObjectData.java b/core/src/com/etheller/warsmash/units/StandardObjectData.java deleted file mode 100644 index 6cd2129b..00000000 --- a/core/src/com/etheller/warsmash/units/StandardObjectData.java +++ /dev/null @@ -1,645 +0,0 @@ -package com.etheller.warsmash.units; - -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.util.WorldEditStrings; - -public class StandardObjectData { - private WorldEditStrings worldEditStrings; - private DataSource source; - - public StandardObjectData(final DataSource dataSource) { - this.source = dataSource; - this.worldEditStrings = new WorldEditStrings(dataSource); - } - - public WarcraftData getStandardUnits() { - - final DataTable profile = new DataTable(this.worldEditStrings); - final DataTable unitAbilities = new DataTable(this.worldEditStrings); - final DataTable unitBalance = new DataTable(this.worldEditStrings); - final DataTable unitData = new DataTable(this.worldEditStrings); - final DataTable unitUI = new DataTable(this.worldEditStrings); - final DataTable unitWeapons = new DataTable(this.worldEditStrings); - - try { - profile.readTXT(this.source.getResourceAsStream("Units\\CampaignUnitFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\CampaignUnitStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\HumanUnitFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\HumanUnitStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NeutralUnitFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NeutralUnitStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NightElfUnitFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NightElfUnitStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\OrcUnitFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\OrcUnitStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\UndeadUnitFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\UndeadUnitStrings.txt"), true); - - unitAbilities.readSLK(this.source.getResourceAsStream("Units\\UnitAbilities.slk")); - - unitBalance.readSLK(this.source.getResourceAsStream("Units\\UnitBalance.slk")); - - unitData.readSLK(this.source.getResourceAsStream("Units\\UnitData.slk")); - - unitUI.readSLK(this.source.getResourceAsStream("Units\\UnitUI.slk")); - - unitWeapons.readSLK(this.source.getResourceAsStream("Units\\UnitWeapons.slk")); - final InputStream unitSkin = this.source.getResourceAsStream("Units\\UnitSkin.txt"); - if (unitSkin != null) { - profile.readTXT(unitSkin, true); - } - } - catch (final IOException e) { - throw new RuntimeException(e); - } - - final WarcraftData units = new WarcraftData(); - - units.add(profile, "Profile", false); - units.add(unitAbilities, "UnitAbilities", true); - units.add(unitBalance, "UnitBalance", true); - units.add(unitData, "UnitData", true); - units.add(unitUI, "UnitUI", true); - units.add(unitWeapons, "UnitWeapons", true); - - return units; - } - - public WarcraftData getStandardItems() { - final DataTable profile = new DataTable(this.worldEditStrings); - final DataTable itemData = new DataTable(this.worldEditStrings); - - try { - profile.readTXT(this.source.getResourceAsStream("Units\\ItemFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\ItemStrings.txt"), true); - itemData.readSLK(this.source.getResourceAsStream("Units\\ItemData.slk")); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - - final WarcraftData units = new WarcraftData(); - - units.add(profile, "Profile", false); - units.add(itemData, "ItemData", true); - - return units; - } - - public WarcraftData getStandardDestructables() { - final DataTable destructableData = new DataTable(this.worldEditStrings); - - try { - destructableData.readSLK(this.source.getResourceAsStream("Units\\DestructableData.slk")); - final InputStream unitSkin = this.source.getResourceAsStream("Units\\DestructableSkin.txt"); - if (unitSkin != null) { - destructableData.readTXT(unitSkin, true); - } - } - catch (final IOException e) { - throw new RuntimeException(e); - } - - final WarcraftData units = new WarcraftData(); - - units.add(destructableData, "DestructableData", true); - - return units; - } - - public WarcraftData getStandardDoodads() { - - final DataTable destructableData = new DataTable(this.worldEditStrings); - - try { - destructableData.readSLK(this.source.getResourceAsStream("Doodads\\Doodads.slk")); - final InputStream unitSkin = this.source.getResourceAsStream("Doodads\\DoodadSkins.txt"); - if (unitSkin != null) { - destructableData.readTXT(unitSkin, true); - } - } - catch (final IOException e) { - throw new RuntimeException(e); - } - - final WarcraftData units = new WarcraftData(); - - units.add(destructableData, "DoodadData", true); - - return units; - } - - public DataTable getStandardUnitMeta() { - final DataTable unitMetaData = new DataTable(this.worldEditStrings); - try { - unitMetaData.readSLK(this.source.getResourceAsStream("Units\\UnitMetaData.slk")); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return unitMetaData; - } - - public DataTable getStandardDestructableMeta() { - final DataTable unitMetaData = new DataTable(this.worldEditStrings); - try { - unitMetaData.readSLK(this.source.getResourceAsStream("Units\\DestructableMetaData.slk")); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return unitMetaData; - } - - public DataTable getStandardDoodadMeta() { - final DataTable unitMetaData = new DataTable(this.worldEditStrings); - try { - unitMetaData.readSLK(this.source.getResourceAsStream("Doodads\\DoodadMetaData.slk")); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return unitMetaData; - } - - public WarcraftData getStandardAbilities() { - - final DataTable profile = new DataTable(this.worldEditStrings); - final DataTable abilityData = new DataTable(this.worldEditStrings); - - try { - profile.readTXT(this.source.getResourceAsStream("Units\\CampaignAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\CampaignAbilityStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\CommonAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\CommonAbilityStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\HumanAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\HumanAbilityStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NeutralAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NeutralAbilityStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NightElfAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NightElfAbilityStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\OrcAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\OrcAbilityStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\UndeadAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\UndeadAbilityStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\ItemAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\ItemAbilityStrings.txt"), true); - - final InputStream unitSkin = this.source.getResourceAsStream("Units\\AbilitySkin.txt"); - if (unitSkin != null) { - profile.readTXT(unitSkin, true); - } - - abilityData.readSLK(this.source.getResourceAsStream("Units\\AbilityData.slk")); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - - final WarcraftData abilities = new WarcraftData(); - - abilities.add(profile, "Profile", false); - abilities.add(abilityData, "AbilityData", true); - - return abilities; - } - - public WarcraftData getStandardAbilityBuffs() { - final DataTable profile = new DataTable(this.worldEditStrings); - final DataTable abilityData = new DataTable(this.worldEditStrings); - - try { - profile.readTXT(this.source.getResourceAsStream("Units\\CampaignAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\CampaignAbilityStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\CommonAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\CommonAbilityStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\HumanAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\HumanAbilityStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NeutralAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NeutralAbilityStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NightElfAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NightElfAbilityStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\OrcAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\OrcAbilityStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\UndeadAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\UndeadAbilityStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\ItemAbilityFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\ItemAbilityStrings.txt"), true); - - abilityData.readSLK(this.source.getResourceAsStream("Units\\AbilityBuffData.slk")); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - - final WarcraftData abilities = new WarcraftData(); - - abilities.add(profile, "Profile", false); - abilities.add(abilityData, "AbilityData", true); - - return abilities; - } - - public WarcraftData getStandardUpgrades() { - final DataTable profile = new DataTable(this.worldEditStrings); - final DataTable upgradeData = new DataTable(this.worldEditStrings); - - try { - profile.readTXT(this.source.getResourceAsStream("Units\\CampaignUpgradeFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\CampaignUpgradeStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\HumanUpgradeFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\HumanUpgradeStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NeutralUpgradeFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NeutralUpgradeStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NightElfUpgradeFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\NightElfUpgradeStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\OrcUpgradeFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\OrcUpgradeStrings.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\UndeadUpgradeFunc.txt"), true); - profile.readTXT(this.source.getResourceAsStream("Units\\UndeadUpgradeStrings.txt"), true); - - upgradeData.readSLK(this.source.getResourceAsStream("Units\\UpgradeData.slk")); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - - final WarcraftData units = new WarcraftData(); - - units.add(profile, "Profile", false); - units.add(upgradeData, "UpgradeData", true); - - return units; - } - - public DataTable getStandardUpgradeMeta() { - final DataTable unitMetaData = new DataTable(this.worldEditStrings); - try { - unitMetaData.readSLK(this.source.getResourceAsStream("Units\\UpgradeMetaData.slk")); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return unitMetaData; - } - - public DataTable getStandardUpgradeEffectMeta() { - final DataTable unitMetaData = new DataTable(this.worldEditStrings); - try { - unitMetaData.readSLK(this.source.getResourceAsStream("Units\\UpgradeEffectMetaData.slk")); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return unitMetaData; - } - - public DataTable getStandardAbilityMeta() { - final DataTable unitMetaData = new DataTable(this.worldEditStrings); - try { - unitMetaData.readSLK(this.source.getResourceAsStream("Units\\AbilityMetaData.slk")); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return unitMetaData; - } - - public DataTable getStandardAbilityBuffMeta() { - final DataTable unitMetaData = new DataTable(this.worldEditStrings); - try { - unitMetaData.readSLK(this.source.getResourceAsStream("Units\\AbilityBuffMetaData.slk")); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return unitMetaData; - } - - public DataTable getUnitEditorData() { - final DataTable unitMetaData = new DataTable(this.worldEditStrings); - try { - unitMetaData.readTXT(this.source.getResourceAsStream("UI\\UnitEditorData.txt"), true); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return unitMetaData; - } - - public DataTable getWorldEditData() { - final DataTable unitMetaData = new DataTable(this.worldEditStrings); - try { - unitMetaData.readTXT(this.source.getResourceAsStream("UI\\WorldEditData.txt"), true); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return unitMetaData; - } - - public WorldEditStrings getWorldEditStrings() { - return this.worldEditStrings; - } - - public static class WarcraftData implements ObjectData { - WorldEditStrings worldEditStrings; - List tables = new ArrayList<>(); - Map tableMap = new HashMap<>(); - Map units = new HashMap<>(); - - public WarcraftData(final WorldEditStrings worldEditStrings) { - this.worldEditStrings = worldEditStrings; - } - - @Override - public String getLocalizedString(final String key) { - return this.worldEditStrings.getString(key); - } - - public void add(final DataTable data, final String name, final boolean canMake) { - this.tableMap.put(new StringKey(name), data); - this.tables.add(data); - if (canMake) { - for (final String id : data.keySet()) { - if (!this.units.containsKey(new StringKey(id))) { - this.units.put(new StringKey(id), new WarcraftObject(data.get(id).getId(), this)); - } - } - } - } - - public WarcraftData() { - } - - public List getTables() { - return this.tables; - } - - public void setTables(final List tables) { - this.tables = tables; - } - - public DataTable getTable(final String tableName) { - return this.tableMap.get(new StringKey(tableName)); - } - - @Override - public GameObject get(final String id) { - return this.units.get(new StringKey(id)); - } - - @Override - public void setValue(final String id, final String field, final String value) { - get(id).setField(field, value); - } - - @Override - public Set keySet() { - final Set keySet = new HashSet<>(); - for (final StringKey key : this.units.keySet()) { - keySet.add(key.getString()); - } - return keySet; - } - - public void cloneUnit(final String parentId, final String cloneId) { - for (final DataTable table : this.tables) { - final Element parentEntry = table.get(parentId); - final LMUnit cloneUnit = new LMUnit(cloneId, table); - for (final String key : parentEntry.keySet()) { - cloneUnit.setField(key, parentEntry.getField(key)); - } - table.put(cloneId, cloneUnit); - } - this.units.put(new StringKey(cloneId), new WarcraftObject(cloneId, this)); - } - } - - public static class WarcraftObject implements GameObject { - String id; - WarcraftData dataSource; - - public WarcraftObject(final String id, final WarcraftData dataSource) { - this.id = id; - this.dataSource = dataSource; - } - - @Override - public void setField(final String field, final String value, final int index) { - for (final DataTable table : this.dataSource.getTables()) { - final Element element = table.get(this.id); - if ((element != null) && element.hasField(field)) { - element.setField(field, value, index); - return; - } - } - } - - @Override - public String getField(final String field, final int index) { - for (final DataTable table : this.dataSource.getTables()) { - final Element element = table.get(this.id); - if ((element != null) && element.hasField(field)) { - return element.getField(field, index); - } - } - return ""; - } - - @Override - public int getFieldValue(final String field, final int index) { - for (final DataTable table : this.dataSource.getTables()) { - final Element element = table.get(this.id); - if ((element != null) && element.hasField(field)) { - return element.getFieldValue(field, index); - } - } - return 0; - } - - @Override - public void setField(final String field, final String value) { - for (final DataTable table : this.dataSource.getTables()) { - final Element element = table.get(this.id); - if ((element != null) && element.hasField(field)) { - element.setField(field, value); - return; - } - } - throw new IllegalArgumentException("no field"); - } - - @Override - public String getField(final String field) { - for (final DataTable table : this.dataSource.getTables()) { - final Element element = table.get(this.id); - if ((element != null) && element.hasField(field)) { - return element.getField(field); - } - } - return ""; - } - - @Override - public int getFieldValue(final String field) { - for (final DataTable table : this.dataSource.getTables()) { - final Element element = table.get(this.id); - if ((element != null) && element.hasField(field)) { - return element.getFieldValue(field); - } - } - return 0; - } - - @Override - public float getFieldFloatValue(final String field) { - for (final DataTable table : this.dataSource.getTables()) { - final Element element = table.get(this.id); - if ((element != null) && element.hasField(field)) { - return element.getFieldFloatValue(field); - } - } - return 0f; - } - - @Override - public float getFieldFloatValue(final String field, final int index) { - for (final DataTable table : this.dataSource.getTables()) { - final Element element = table.get(this.id); - if ((element != null) && element.hasField(field)) { - return element.getFieldFloatValue(field, index); - } - } - return 0f; - } - - /* - * (non-Javadoc) I'm not entirely sure this is still safe to use - * - * @see com.hiveworkshop.wc3.units.GameObject#getFieldAsList(java.lang. String) - */ - @Override - public List getFieldAsList(final String field, final ObjectData objectData) { - for (final DataTable table : this.dataSource.getTables()) { - final Element element = table.get(this.id); - if ((element != null) && element.hasField(field)) { - return element.getFieldAsList(field, objectData); - } - } - return new ArrayList<>();// empty list if not found - } - - @Override - public String getId() { - return this.id; - } - - @Override - public ObjectData getTable() { - return this.dataSource; - } - - // @Override - // public String getName() { - // return dataSource.profile.get(id).getName(); - // } - @Override - public String getName() { - String name = getField("Name"); - boolean nameKnown = name.length() >= 1; - if (!nameKnown && !getField("code").equals(this.id) && (getField("code").length() >= 4)) { - final WarcraftObject other = (WarcraftObject) this.dataSource.get(getField("code").substring(0, 4)); - if (other != null) { - name = other.getName(); - nameKnown = true; - } - } - if (!nameKnown && (getField("EditorName").length() > 1)) { - name = getField("EditorName"); - nameKnown = true; - } - if (!nameKnown && (getField("Editorname").length() > 1)) { - name = getField("Editorname"); - nameKnown = true; - } - if (!nameKnown && (getField("BuffTip").length() > 1)) { - name = getField("BuffTip"); - nameKnown = true; - } - if (!nameKnown && (getField("Bufftip").length() > 1)) { - name = getField("Bufftip"); - nameKnown = true; - } - if (nameKnown && name.startsWith("WESTRING")) { - if (!name.contains(" ")) { - name = this.dataSource.getLocalizedString(name); - } - else { - final String[] names = name.split(" "); - name = ""; - for (final String subName : names) { - if (name.length() > 0) { - name += " "; - } - if (subName.startsWith("WESTRING")) { - name += this.dataSource.getLocalizedString(subName); - } - else { - name += subName; - } - } - } - if (name.startsWith("\"") && name.endsWith("\"")) { - name = name.substring(1, name.length() - 1); - } - setField("Name", name); - } - if (!nameKnown) { - name = this.dataSource.getLocalizedString("WESTRING_UNKNOWN") + " '" + getId() + "'"; - } - if (getField("campaign").startsWith("1") && Character.isUpperCase(getId().charAt(0))) { - name = getField("Propernames"); - if (name.contains(",")) { - name = name.split(",")[0]; - } - } - String suf = getField("EditorSuffix"); - if ((suf.length() > 0) && !suf.equals("_")) { - if (suf.startsWith("WESTRING")) { - suf = this.dataSource.getLocalizedString(suf); - } - if (!suf.startsWith(" ")) { - name += " "; - } - name += suf; - } - return name; - } - - BufferedImage storedImage = null; - String storedImagePath = null; - - @Override - public Set keySet() { - final Set keySet = new HashSet<>(); - for (final DataTable table : this.dataSource.tables) { - keySet.addAll(table.get(this.id).keySet()); - } - return keySet; - } - } - - private StandardObjectData() { - } -} diff --git a/core/src/com/etheller/warsmash/units/StringKey.java b/core/src/com/etheller/warsmash/units/StringKey.java deleted file mode 100644 index c78e16e9..00000000 --- a/core/src/com/etheller/warsmash/units/StringKey.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.etheller.warsmash.units; - -/** - * A hashable wrapper object for a String that can be used as the key in a - * hashtable, but which disregards case as a key -- except that it will remember - * case if directly asked for its value. The game needs this to be able to show - * the original case of a string to the user in the editor, while still doing - * map lookups in a case insensitive way. - * - * @author Eric - * - */ -public final class StringKey { - private final String string; - - public StringKey(final String string) { - this.string = string; - } - - public String getString() { - return this.string; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + ((this.string.toLowerCase() == null) ? 0 : this.string.toLowerCase().hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final StringKey other = (StringKey) obj; - if (this.string == null) { - if (other.string != null) { - return false; - } - } - else if (!this.string.equalsIgnoreCase(other.string)) { - return false; - } - return true; - } -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/units/custom/Change.java b/core/src/com/etheller/warsmash/units/custom/Change.java deleted file mode 100644 index e185128c..00000000 --- a/core/src/com/etheller/warsmash/units/custom/Change.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.etheller.warsmash.units.custom; - -import com.etheller.warsmash.util.War3ID; - -public final class Change { - private War3ID id; - private int vartype, level, dataptr; - private int longval; - private float realval; - private String strval; - - private boolean boolval; - private War3ID junkDNA; - - public War3ID getId() { - return this.id; - } - - public void setId(final War3ID id) { - this.id = id; - } - - public int getVartype() { - return this.vartype; - } - - public void setVartype(final int vartype) { - this.vartype = vartype; - } - - public int getLevel() { - return this.level; - } - - public void setLevel(final int level) { - this.level = level; - } - - public int getDataptr() { - return this.dataptr; - } - - public void setDataptr(final int dataptr) { - this.dataptr = dataptr; - } - - public int getLongval() { - return this.longval; - } - - public void setLongval(final int longval) { - this.longval = longval; - } - - public float getRealval() { - return this.realval; - } - - public void setRealval(final float realval) { - this.realval = realval; - } - - public String getStrval() { - return this.strval; - } - - public void setStrval(final String strval) { - this.strval = strval; - } - - public boolean isBoolval() { - return this.boolval; - } - - public void setBoolval(final boolean boolval) { - this.boolval = boolval; - } - - public void setJunkDNA(final War3ID junkDNA) { - this.junkDNA = junkDNA; - } - - public War3ID getJunkDNA() { - return this.junkDNA; - } - - public void copyFrom(final Change other) { - this.id = other.id; - this.level = other.level; - this.dataptr = other.dataptr; - this.vartype = other.vartype; - this.longval = other.longval; - this.realval = other.realval; - this.strval = other.strval; - this.boolval = other.boolval; - this.junkDNA = other.junkDNA; - } - - @Override - public Change clone() { - final Change copy = new Change(); - copy.copyFrom(this); - return copy; - } -} diff --git a/core/src/com/etheller/warsmash/units/custom/ChangeMap.java b/core/src/com/etheller/warsmash/units/custom/ChangeMap.java deleted file mode 100644 index 54424217..00000000 --- a/core/src/com/etheller/warsmash/units/custom/ChangeMap.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.etheller.warsmash.units.custom; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import com.etheller.warsmash.util.War3ID; - -public final class ChangeMap implements Iterable>> { - private final Map> idToChanges = new LinkedHashMap<>(); - - public void add(final War3ID war3Id, final Change change) { - List list = this.idToChanges.get(war3Id); - if (list == null) { - list = new ArrayList<>(); - this.idToChanges.put(war3Id, list); - } - list.add(change); - } - - public void add(final War3ID war3Id, final List changes) { - for (final Change change : changes) { - add(war3Id, change); - } - } - - public List get(final War3ID war3ID) { - return this.idToChanges.get(war3ID); - } - - public void delete(final War3ID war3ID, final Change change) { - if (this.idToChanges.containsKey(war3ID)) { - final List changeList = this.idToChanges.get(war3ID); - changeList.remove(change); - if (changeList.isEmpty()) { - this.idToChanges.remove(war3ID); - } - } - } - - @Override - public Iterator>> iterator() { - return this.idToChanges.entrySet().iterator(); - } - - public int size() { - return this.idToChanges.size(); - } - - public void clear() { - this.idToChanges.clear(); - } -} diff --git a/core/src/com/etheller/warsmash/units/custom/ObjectDataChangeEntry.java b/core/src/com/etheller/warsmash/units/custom/ObjectDataChangeEntry.java deleted file mode 100644 index 1acda995..00000000 --- a/core/src/com/etheller/warsmash/units/custom/ObjectDataChangeEntry.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.etheller.warsmash.units.custom; - -import java.util.List; -import java.util.Map; - -import com.etheller.warsmash.util.War3ID; - -public final class ObjectDataChangeEntry { - private War3ID oldId; - private War3ID newId; - private final ChangeMap changes; - - public ObjectDataChangeEntry(final War3ID oldId, final War3ID newId) { - this.oldId = oldId; - this.newId = newId; - this.changes = new ChangeMap(); - } - - @Override - public ObjectDataChangeEntry clone() { - final ObjectDataChangeEntry objectDataChangeEntry = new ObjectDataChangeEntry(this.oldId, this.newId); - for (final Map.Entry> entry : this.changes) { - objectDataChangeEntry.getChanges().add(entry.getKey(), entry.getValue()); - } - return objectDataChangeEntry; - } - - public ChangeMap getChanges() { - return this.changes; - } - - public War3ID getOldId() { - return this.oldId; - } - - public void setOldId(final War3ID oldId) { - this.oldId = oldId; - } - - public War3ID getNewId() { - return this.newId; - } - - public void setNewId(final War3ID newId) { - this.newId = newId; - } -} diff --git a/core/src/com/etheller/warsmash/units/custom/ObjectMap.java b/core/src/com/etheller/warsmash/units/custom/ObjectMap.java deleted file mode 100644 index bbece539..00000000 --- a/core/src/com/etheller/warsmash/units/custom/ObjectMap.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.etheller.warsmash.units.custom; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; -import java.util.function.BiConsumer; - -import com.etheller.warsmash.util.War3ID; - -public final class ObjectMap implements Iterable> { - private final Map idToDataChangeEntry; - private final Set lowerCaseKeySet; - - public ObjectMap() { - this.idToDataChangeEntry = new LinkedHashMap<>(); - this.lowerCaseKeySet = new HashSet<>(); - } - - public void clear() { - this.idToDataChangeEntry.clear(); - this.lowerCaseKeySet.clear(); - } - - public ObjectDataChangeEntry remove(final War3ID key) { - this.lowerCaseKeySet.remove(War3ID.fromString(key.toString().toLowerCase())); - return this.idToDataChangeEntry.remove(key); - } - - public Set keySet() { - return this.idToDataChangeEntry.keySet(); - } - - public ObjectDataChangeEntry put(final War3ID key, final ObjectDataChangeEntry value) { - this.lowerCaseKeySet.add(War3ID.fromString(key.toString().toLowerCase())); - return this.idToDataChangeEntry.put(key, value); - } - - public Set> entrySet() { - return this.idToDataChangeEntry.entrySet(); - } - - public ObjectDataChangeEntry get(final War3ID key) { - return this.idToDataChangeEntry.get(key); - } - - public boolean containsKey(final War3ID key) { - return this.idToDataChangeEntry.containsKey(key); - } - - public boolean containsKeyCaseInsensitive(final War3ID key) { - return this.lowerCaseKeySet.contains(War3ID.fromString(key.toString().toLowerCase())); - } - - public boolean containsValue(final ObjectDataChangeEntry value) { - return this.idToDataChangeEntry.containsValue(value); - } - - public Collection values() { - return this.idToDataChangeEntry.values(); - } - - public int size() { - return this.idToDataChangeEntry.size(); - } - - public void forEach(final BiConsumer forEach) { - this.idToDataChangeEntry.forEach(forEach); - } - - @Override - public Iterator> iterator() { - return this.idToDataChangeEntry.entrySet().iterator(); - } - - @Override - public ObjectMap clone() { - final ObjectMap clone = new ObjectMap(); - forEach(new BiConsumer() { - @Override - public void accept(final War3ID key, final ObjectDataChangeEntry value) { - clone.put(key, value); - } - }); - return clone; - } -} diff --git a/core/src/com/etheller/warsmash/units/custom/WTS.java b/core/src/com/etheller/warsmash/units/custom/WTS.java deleted file mode 100644 index 52cc2c0f..00000000 --- a/core/src/com/etheller/warsmash/units/custom/WTS.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.etheller.warsmash.units.custom; - -public interface WTS { - String get(int key); - - WTS DO_NOTHING = new WTS() { - @Override - public String get(final int key) { - return "TRIGSTR_" + key; - } - }; -} diff --git a/core/src/com/etheller/warsmash/units/custom/WTSFile.java b/core/src/com/etheller/warsmash/units/custom/WTSFile.java deleted file mode 100644 index 99b7ab3d..00000000 --- a/core/src/com/etheller/warsmash/units/custom/WTSFile.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.etheller.warsmash.units.custom; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Hashtable; -import java.util.Map; - -/** - * - * @author Deaod - * - */ -public class WTSFile implements WTS { - private final InputStream source; - private final Map trigStrings = new Hashtable<>(); - - private static enum ParseState { - NEXT_TRIGSTR, - START_OF_DATA, - END_OF_DATA; - } - - private void parse() throws IOException { - final BufferedReader sourceReader = new BufferedReader( - new InputStreamReader(this.source, Charset.forName("utf-8"))); - ParseState state = ParseState.NEXT_TRIGSTR; - - // WTS files may start with a Byte Order Mark, which we will have to skip. - sourceReader.mark(4); - if (sourceReader.read() != 0xFEFF) { - // first character not a BOM, unread the character. - sourceReader.reset(); - } - - String currentLine = sourceReader.readLine(); - int id = 0; - StringBuffer data = new StringBuffer(); - - while (currentLine != null) { - switch (state) { - case NEXT_TRIGSTR: - if (currentLine.startsWith("STRING ")) { - id = Integer.parseInt(currentLine.substring(7)); - state = ParseState.START_OF_DATA; - } - break; - - case START_OF_DATA: - if (currentLine.startsWith("{")) { - state = ParseState.END_OF_DATA; - } - break; - - case END_OF_DATA: - if (currentLine.startsWith("}")) { - this.trigStrings.put(id, data.toString()); - data = new StringBuffer(); - state = ParseState.NEXT_TRIGSTR; - } - else { - data.append(currentLine); - } - break; - } - currentLine = sourceReader.readLine(); - } - sourceReader.close(); - } - - public WTSFile(final InputStream inputStream) throws IOException { - this.source = inputStream; - parse(); - } - - public WTSFile(final Path source) throws IOException { - this(Files.newInputStream(source)); - } - - public WTSFile(final String sourcePath) throws IOException { - this(Paths.get(sourcePath)); - } - - @Override - public String get(final int index) { - return this.trigStrings.get(index); - } - -} diff --git a/core/src/com/etheller/warsmash/units/custom/War3ObjectDataChangeset.java b/core/src/com/etheller/warsmash/units/custom/War3ObjectDataChangeset.java deleted file mode 100644 index 1f215dda..00000000 --- a/core/src/com/etheller/warsmash/units/custom/War3ObjectDataChangeset.java +++ /dev/null @@ -1,802 +0,0 @@ -package com.etheller.warsmash.units.custom; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; -import java.nio.charset.CodingErrorAction; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.etheller.warsmash.util.ParseUtils; -import com.etheller.warsmash.util.War3ID; -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -/** - * Inspired by PitzerMike's obj.h, without a lot of immediate focus on Java - * conventions. I will probably get it converted over to Java conventions once I - * have a working replica of his obj.h code. - * - * @author Eric - * - */ -public final class War3ObjectDataChangeset { - public static final int VAR_TYPE_INT = 0; - public static final int VAR_TYPE_REAL = 1; - public static final int VAR_TYPE_UNREAL = 2; - public static final int VAR_TYPE_STRING = 3; - public static final int VAR_TYPE_BOOLEAN = 4; - public static final int MAX_STR_LEN = 1024; - private static final Set UNIT_ID_SET; - private static final Set ABILITY_ID_SET; - static { - final HashSet unitHashSet = new HashSet<>(); - unitHashSet.add(War3ID.fromString("ubpx")); - unitHashSet.add(War3ID.fromString("ubpy")); - unitHashSet.add(War3ID.fromString("ides")); - unitHashSet.add(War3ID.fromString("uhot")); - unitHashSet.add(War3ID.fromString("unam")); - unitHashSet.add(War3ID.fromString("ureq")); - unitHashSet.add(War3ID.fromString("urqa")); - unitHashSet.add(War3ID.fromString("utip")); - unitHashSet.add(War3ID.fromString("utub")); - UNIT_ID_SET = unitHashSet; - final HashSet abilHashSet = new HashSet<>(); - abilHashSet.add(War3ID.fromString("irc2")); - abilHashSet.add(War3ID.fromString("irc3")); - abilHashSet.add(War3ID.fromString("bsk1")); - abilHashSet.add(War3ID.fromString("bsk2")); - abilHashSet.add(War3ID.fromString("bsk3")); - abilHashSet.add(War3ID.fromString("coau")); - abilHashSet.add(War3ID.fromString("coa1")); - abilHashSet.add(War3ID.fromString("coa2")); - abilHashSet.add(War3ID.fromString("cyc1")); - abilHashSet.add(War3ID.fromString("dcp1")); - abilHashSet.add(War3ID.fromString("dcp2")); - abilHashSet.add(War3ID.fromString("dvm1")); - abilHashSet.add(War3ID.fromString("dvm2")); - abilHashSet.add(War3ID.fromString("dvm3")); - abilHashSet.add(War3ID.fromString("dvm4")); - abilHashSet.add(War3ID.fromString("dvm5")); - abilHashSet.add(War3ID.fromString("exh1")); - abilHashSet.add(War3ID.fromString("exhu")); - abilHashSet.add(War3ID.fromString("fak1")); - abilHashSet.add(War3ID.fromString("fak2")); - abilHashSet.add(War3ID.fromString("fak3")); - abilHashSet.add(War3ID.fromString("hwdu")); - abilHashSet.add(War3ID.fromString("inv1")); - abilHashSet.add(War3ID.fromString("inv2")); - abilHashSet.add(War3ID.fromString("inv3")); - abilHashSet.add(War3ID.fromString("inv4")); - abilHashSet.add(War3ID.fromString("inv5")); - abilHashSet.add(War3ID.fromString("liq1")); - abilHashSet.add(War3ID.fromString("liq2")); - abilHashSet.add(War3ID.fromString("liq3")); - abilHashSet.add(War3ID.fromString("liq4")); - abilHashSet.add(War3ID.fromString("mim1")); - abilHashSet.add(War3ID.fromString("mfl1")); - abilHashSet.add(War3ID.fromString("mfl2")); - abilHashSet.add(War3ID.fromString("mfl3")); - abilHashSet.add(War3ID.fromString("mfl4")); - abilHashSet.add(War3ID.fromString("mfl5")); - abilHashSet.add(War3ID.fromString("tpi1")); - abilHashSet.add(War3ID.fromString("tpi2")); - abilHashSet.add(War3ID.fromString("spl1")); - abilHashSet.add(War3ID.fromString("spl2")); - abilHashSet.add(War3ID.fromString("irl1")); - abilHashSet.add(War3ID.fromString("irl2")); - abilHashSet.add(War3ID.fromString("irl3")); - abilHashSet.add(War3ID.fromString("irl4")); - abilHashSet.add(War3ID.fromString("irl5")); - abilHashSet.add(War3ID.fromString("idc1")); - abilHashSet.add(War3ID.fromString("idc2")); - abilHashSet.add(War3ID.fromString("idc3")); - abilHashSet.add(War3ID.fromString("imo1")); - abilHashSet.add(War3ID.fromString("imo2")); - abilHashSet.add(War3ID.fromString("imo3")); - abilHashSet.add(War3ID.fromString("imou")); - abilHashSet.add(War3ID.fromString("ict1")); - abilHashSet.add(War3ID.fromString("ict2")); - abilHashSet.add(War3ID.fromString("isr1")); - abilHashSet.add(War3ID.fromString("isr2")); - abilHashSet.add(War3ID.fromString("ipv1")); - abilHashSet.add(War3ID.fromString("ipv2")); - abilHashSet.add(War3ID.fromString("ipv3")); - abilHashSet.add(War3ID.fromString("mec1")); - abilHashSet.add(War3ID.fromString("spb1")); - abilHashSet.add(War3ID.fromString("spb2")); - abilHashSet.add(War3ID.fromString("spb3")); - abilHashSet.add(War3ID.fromString("spb4")); - abilHashSet.add(War3ID.fromString("spb5")); - abilHashSet.add(War3ID.fromString("gra1")); - abilHashSet.add(War3ID.fromString("gra2")); - abilHashSet.add(War3ID.fromString("gra3")); - abilHashSet.add(War3ID.fromString("gra4")); - abilHashSet.add(War3ID.fromString("gra5")); - abilHashSet.add(War3ID.fromString("ipmu")); - abilHashSet.add(War3ID.fromString("flk1")); - abilHashSet.add(War3ID.fromString("flk2")); - abilHashSet.add(War3ID.fromString("flk3")); - abilHashSet.add(War3ID.fromString("flk4")); - abilHashSet.add(War3ID.fromString("flk5")); - abilHashSet.add(War3ID.fromString("fbk1")); - abilHashSet.add(War3ID.fromString("fbk2")); - abilHashSet.add(War3ID.fromString("fbk3")); - abilHashSet.add(War3ID.fromString("fbk4")); - abilHashSet.add(War3ID.fromString("nca1")); - abilHashSet.add(War3ID.fromString("pxf1")); - abilHashSet.add(War3ID.fromString("pxf2")); - abilHashSet.add(War3ID.fromString("mls1")); - abilHashSet.add(War3ID.fromString("sla1")); - abilHashSet.add(War3ID.fromString("sla2")); - ABILITY_ID_SET = abilHashSet; - } - - private int version; - private ObjectMap original = new ObjectMap(); - private final ObjectMap custom = new ObjectMap(); - private char expected; - private War3ID lastused; - - public char kind; - public boolean detected; - - public War3ID nameField; - - public War3ObjectDataChangeset() { - this.version = 2; - this.kind = 'u'; - this.expected = 'u'; - this.detected = false; - this.lastused = War3ID.fromString("u~~~"); - } - - public War3ObjectDataChangeset(final char expectedkind) { - this.version = 2; - this.kind = 'u'; - this.expected = expectedkind; - this.detected = false; - this.lastused = War3ID.fromString("u~~~"); - } - - public boolean detectKind(final War3ID chid) { - if (UNIT_ID_SET.contains(chid)) { - this.kind = 'u'; - return false; - } - else if (ABILITY_ID_SET.contains(chid)) { - this.kind = 'a'; - } - else { - switch (chid.asStringValue().charAt(0)) { - case 'f': - this.kind = 'h'; - break; - case 'i': - this.kind = 't'; - break; - case 'g': - this.kind = 'q'; - break; - case 'a': - case 'u': - case 'b': - case 'd': - this.kind = chid.asStringValue().charAt(0); - break; - default: - this.kind = 'a'; - } - } - return true; - } - - public char getExpectedKind() { - return this.expected; - } - - public War3ID getNameField() { - final War3ID field = War3ID.fromString("unam"); - char cmp = this.kind; - if (!this.detected) { - cmp = this.expected; - } - switch (cmp) { - case 'h': - this.nameField = field.set(0, 'f'); - break; - case 't': - this.nameField = field.set(0, 'u'); - break; - case 'q': - this.nameField = field.set(0, 'g'); - break; - default: - this.nameField = field.set(0, cmp); - break; - } - return this.nameField; - } - - public boolean extended() { - char cmp = this.kind; - if (!this.detected) { - cmp = this.expected; - } - switch (cmp) { - case 'u': - case 'h': - case 'b': - case 't': - return false; - } - return true; - } - - public void renameids(final ObjectMap map, final boolean isOriginal) { - final War3ID nameId = getNameField(); - final List idsToRemoveFromMap = new ArrayList<>(); - final Map idsToObjectsForAddingToMap = new HashMap<>(); - for (final Iterator> iterator = map.iterator(); iterator.hasNext();) { - final Map.Entry entry = iterator.next(); - final ObjectDataChangeEntry current = entry.getValue(); - final List nameEntry = current.getChanges().get(nameId); - if ((nameEntry != null) && !nameEntry.isEmpty()) { - final Change firstNameChange = nameEntry.get(0); - int pos = firstNameChange.getStrval().lastIndexOf("::"); - if ((pos != -1) && (firstNameChange.getStrval().length() > (pos + 2))) { - String rest = firstNameChange.getStrval().substring(pos + 2); - if (rest.length() == 4) { - final War3ID newId = War3ID.fromString(rest); - final ObjectDataChangeEntry existingObjectWithMatchingId = map.get(newId); - if (isOriginal) {// obj.cpp: update id and name - current.setOldId(newId); - } - else { - current.setNewId(newId); - } - firstNameChange.setStrval(firstNameChange.getStrval().substring(0, pos)); - if (existingObjectWithMatchingId != null) { - // obj.cpp: carry over all changes - final Iterator>> changeIterator = current.getChanges() - .iterator(); - while (changeIterator.hasNext()) { - final Map.Entry> changeIteratorNext = changeIterator.next(); - final War3ID copiedChangeId = changeIteratorNext.getKey(); - List changeListForFieldToOverwrite = existingObjectWithMatchingId.getChanges() - .get(copiedChangeId); - if (changeListForFieldToOverwrite == null) { - changeListForFieldToOverwrite = new ArrayList<>(); - } - for (final Change changeToCopy : changeIteratorNext.getValue()) { - final Iterator replaceIterator = changeListForFieldToOverwrite.iterator(); - boolean didOverwrite = false; - while (replaceIterator.hasNext()) { - final Change changeToOverwrite = replaceIterator.next(); - if (changeToOverwrite.getLevel() != changeToCopy.getLevel()) { - // obj.cpp: we can only replace - // changes with the same - // level/variation - continue; - } - if (copiedChangeId.equals(nameId)) { - // obj.cpp: carry over further - // references - pos = changeToOverwrite.getStrval().lastIndexOf("::"); - if ((pos != -1) && (changeToOverwrite.getStrval().length() > (pos + 2))) { - rest = changeToOverwrite.getStrval().substring(pos + 2); - if ((rest.length() == 4) || "REMOVE".equals(rest)) { - changeToCopy.setStrval(changeToCopy.getStrval() + "::" + rest); - // so if this is a peasant, whose name was "Peasant::hfoo" - // and when we copied his data onto the footman, we found - // that the footman was named "Footman::hkni", then at that - // point we set the peasant's name to be "Peasant::hkni" - // because we are about to copy it onto the footman. - // And, we already set it to just "Peasant", so - // appending the "::" and the 'rest' variable is enough. - // Then, on a further loop iteration, in theory - // we will copoy the footman who is named Peasant - // onto the knight. - // - // TODO but what if we already copied the footman onto the knight? - // did PitzerMike consider this in obj.cpp? - } - } - } - changeToOverwrite.copyFrom(changeToCopy); - didOverwrite = true; - break; - } - if (!didOverwrite) { - changeListForFieldToOverwrite.add(changeToCopy); - if (changeListForFieldToOverwrite.size() == 1) { - existingObjectWithMatchingId.getChanges().add(copiedChangeId, - changeListForFieldToOverwrite); - } - } - } - } - } - else { // obj.cpp: an object with that id didn't exist - idsToRemoveFromMap.add(entry.getKey()); - idsToObjectsForAddingToMap.put(newId, current.clone()); - } - } - else if ("REMOVE".equals(rest)) { // obj.cpp: want to remove the object - idsToRemoveFromMap.add(entry.getKey()); - } // obj.cpp: in all other cases keep it untouched - } - } - - } - for (final War3ID id : idsToRemoveFromMap) { - map.remove(id); - } - for (final Map.Entry entry : idsToObjectsForAddingToMap.entrySet()) { - map.put(entry.getKey(), entry.getValue()); - } - } - - public void renameIds() { - renameids(this.original, true); - renameids(this.custom, false); - } - - // ' ' - '/' - // ':' - '@' - // '[' - '`' - // '{' - '~' - public char nextchar(final char cur) { - switch (cur) { - case '&': // skip ' because often jass parsers don't handle escaped rawcodes like '\'' - return '('; - case '/': // skip digits - return ':'; - case '@': // skip capital letters - return '['; // skip \ for the sam reason like ' ('\\') - case '[': - return ']'; - case '_': // skip � and lower case letters (� can't be seen very well) - return '{'; - case '~': // close circle and restart at ! - return '!'; - default: - return (char) ((short) cur + 1); - } - } - - // we use only special characters to avoid collisions with existing objects - // the first character must remain unchanged though because it can have a - // special meaning - public War3ID getunusedid(final War3ID substitutefor) { - this.lastused = this.lastused.set(0, substitutefor.charAt(0)); - this.lastused = this.lastused.set(3, nextchar(substitutefor.charAt(3))); - if (this.lastused.charAt(3) == '!') { - this.lastused = this.lastused.set(2, nextchar(substitutefor.charAt(2))); - if (this.lastused.charAt(2) == '!') { - this.lastused = this.lastused.set(1, nextchar(substitutefor.charAt(1))); - } - } - return this.lastused; - } - - public void mergetable(final ObjectMap target, final ObjectMap targetCustom, final ObjectMap source, - final CollisionHandling collisionHandling) { - final Iterator> sourceObjectIterator = source.iterator(); - while (sourceObjectIterator.hasNext()) { - final Map.Entry sourceObject = sourceObjectIterator.next(); - if (target.containsKey(sourceObject.getKey())) { - // obj.cpp: we have a collision - War3ID oldId; - War3ID replacementId; - - switch (collisionHandling) { - case CREATE_NEW_ID: - oldId = sourceObject.getKey(); - // obj.cpp: get new id until we finally have one that isn't used yet, or we're - // out of ids - replacementId = getunusedid(oldId); - while (!((oldId.charAt(1) == '~') && (oldId.charAt(2) == '~') && (oldId.charAt(3) == '~')) - && targetCustom.containsKey(replacementId)) { - oldId = replacementId; - replacementId = getunusedid(oldId); - } - if (!((oldId.charAt(1) == '~') && (oldId.charAt(2) == '~') && (oldId.charAt(3) == '~'))) { - sourceObject.getValue().setNewId(replacementId); - targetCustom.put(replacementId, sourceObject.getValue().clone()); - } - break; - case REPLACE: - // final ObjectDataChangeEntry deleteObject = target.get(sourceObject.getKey()); - target.put(sourceObject.getKey(), sourceObject.getValue().clone()); - break; - default:// merge - final ObjectDataChangeEntry targetObject = target.get(sourceObject.getKey()); - for (final Map.Entry> sourceUnitField : sourceObject.getValue().getChanges()) { - for (final Change sourceChange : sourceUnitField.getValue()) { - List targetChanges = targetObject.getChanges().get(sourceUnitField.getKey()); - if (targetChanges == null) { - targetChanges = new ArrayList<>(); - } - Change bestTargetChange = null; - for (final Change targetChange : targetChanges) { - if (targetChange.getLevel() == sourceChange.getLevel()) { - bestTargetChange = targetChange; - break; - } - } - if (bestTargetChange != null) { - bestTargetChange.copyFrom(sourceChange); - } - else { - targetChanges.add(sourceChange.clone()); - if (targetChanges.size() == 1) { - targetObject.getChanges().add(sourceUnitField.getKey(), targetChanges); - } - } - } - } - break; - } - } - else { - targetCustom.put(sourceObject.getKey(), sourceObject.getValue().clone()); - } - } - } - - public static enum CollisionHandling { - CREATE_NEW_ID, - REPLACE, - MERGE; - } - - public void merge(final War3ObjectDataChangeset obj, final CollisionHandling collisionHandling) { - mergetable(this.original, this.custom, obj.original, collisionHandling); - mergetable(this.original, this.custom, obj.custom, collisionHandling); - } - - public int getvartype(final String name) { - if ("int".equals(name) || "bool".equals(name)) { - return 0; - } - else if ("real".equals(name)) { - return 1; - } - else if ("unreal".equals(name)) { - return 2; - } - return 3; // string - } - - public boolean loadtable(final LittleEndianDataInputStream stream, final ObjectMap map, final boolean isOriginal, - final WTS wts, final boolean inlineWTS) throws IOException { - final War3ID noid = new War3ID(0); - final ByteBuffer stringByteBuffer = ByteBuffer.allocate(1024); // TODO check max len? - final CharsetDecoder decoder = Charset.forName("utf-8").newDecoder().onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE); - int ptr; - final int count = stream.readInt(); - for (int i = 0; i < count; i++) { - final long nanoTime = System.nanoTime(); - War3ID origid; - War3ID newid = null; - origid = readWar3ID(stream); - ObjectDataChangeEntry existingObject; - if (isOriginal) { - if (noid.equals(origid)) { - throw new IOException("the input stream might be screwed"); - } - existingObject = map.get(origid); - if (existingObject == null) { - existingObject = new ObjectDataChangeEntry(origid, noid); - } - existingObject.setNewId(readWar3ID(stream)); - } - else { - newid = readWar3ID(stream); - if (noid.equals(origid) || noid.equals(newid)) { - throw new IOException("the input stream might be screwed"); - } - existingObject = map.get(newid); - if (existingObject == null) { - existingObject = new ObjectDataChangeEntry(origid, newid); - } - } - final int ccount = stream.readInt();// Retera: I assume this is change count? - if ((ccount == 0) && isOriginal) { - // throw new IOException("we seem to have reached the end of the stream and get - // zeroes"); - System.err.println("we seem to have reached the end of the stream and get zeroes"); - } - if (isOriginal) { - debugprint("StandardUnit \"" + origid + "\" " + ccount + " {"); - } - else { - debugprint("CustomUnit \"" + origid + ":" + newid + "\" " + ccount + " {"); - } - for (int j = 0; j < ccount; j++) { - final War3ID chid = readWar3ID(stream); - if (noid.equals(chid)) { - throw new IOException("the input stream might be screwed"); - } - if (!this.detected) { - this.detected = detectKind(chid); - } - - final Change newlyReadChange = new Change(); - newlyReadChange.setId(chid); - newlyReadChange.setVartype(stream.readInt()); - debugprint("\t\"" + chid + "\" {"); - debugprint("\t\tType " + newlyReadChange.getVartype() + ","); - if (extended()) { - newlyReadChange.setLevel(stream.readInt()); - newlyReadChange.setDataptr(stream.readInt()); - debugprint("\t\tLevel " + newlyReadChange.getLevel() + ","); - debugprint("\t\tData " + newlyReadChange.getDataptr() + ","); - } - - switch (newlyReadChange.getVartype()) { - case 0: - newlyReadChange.setLongval(stream.readInt()); - debugprint("\t\tValue " + newlyReadChange.getLongval() + ","); - break; - case 3: - ptr = 0; - stringByteBuffer.clear(); - byte charRead; - while ((charRead = (byte) stream.read()) != 0) { - stringByteBuffer.put(charRead); - } - stringByteBuffer.flip(); - newlyReadChange.setStrval(decoder.decode(stringByteBuffer).toString()); - if (inlineWTS && (newlyReadChange.getStrval().length() > 8) - && "TRIGSTR_".equals(newlyReadChange.getStrval().substring(0, 8))) { - final int key = getWTSValue(newlyReadChange); - newlyReadChange.setStrval(wts.get(key)); - if ((newlyReadChange.getStrval() != null) - && (newlyReadChange.getStrval().length() > MAX_STR_LEN)) { - newlyReadChange.setStrval(newlyReadChange.getStrval().substring(0, MAX_STR_LEN - 1)); - } - } - debugprint("\t\tValue \"" + newlyReadChange.getStrval() + "\","); - break; - case 4: - newlyReadChange.setBoolval(stream.readInt() == 1); - debugprint("\t\tValue " + newlyReadChange.isBoolval() + ","); - break; - default: - newlyReadChange.setRealval(stream.readFloat()); - debugprint("\t\tValue " + newlyReadChange.getRealval() + ","); - break; - } - final War3ID crap = readWar3ID(stream); - debugprint("\t\tExtra \"" + crap + "\","); - newlyReadChange.setJunkDNA(crap); - List existingChanges = existingObject.getChanges().get(chid); - if (existingChanges == null) { - existingChanges = new ArrayList<>(); - } - Change bestTargetChange = null; - for (final Change targetChange : existingChanges) { - if (targetChange.getLevel() == newlyReadChange.getLevel()) { - bestTargetChange = targetChange; - break; - } - } - if (bestTargetChange != null) { - bestTargetChange.copyFrom(newlyReadChange); - } - else { - existingChanges.add(newlyReadChange.clone()); - if (existingChanges.size() == 1) { - existingObject.getChanges().add(chid, existingChanges); - } - } - if (!crap.equals(existingObject.getOldId()) && !crap.equals(existingObject.getNewId()) - && !crap.equals(noid)) { - for (int charIndex = 0; charIndex < 4; charIndex++) { - if ((crap.charAt(charIndex) < 32) || (crap.charAt(charIndex) > 126)) { - return false; - } - } - } - debugprint("\t}"); - } - debugprint("}"); - if ((newid == null) && !isOriginal) { - throw new IllegalStateException("custom unit has no ID!"); - } - map.put(isOriginal ? origid : newid, existingObject); - final long endNanoTime = System.nanoTime(); - final long deltaNanoTime = endNanoTime - nanoTime; - } - return true; - } - - private War3ID readWar3ID(final LittleEndianDataInputStream stream) throws IOException { - return new War3ID(Integer.reverseBytes(stream.readInt())); - } - - private static int getWTSValue(final Change change) { - String numberAsText = change.getStrval().substring(8); - while ((numberAsText.length() > 0) && (numberAsText.charAt(0) == '0')) { - numberAsText = numberAsText.substring(1); - } - if (numberAsText.length() == 0) { - return 0; - } - while (!Character.isDigit(numberAsText.charAt(numberAsText.length() - 1))) { - numberAsText = numberAsText.substring(0, numberAsText.length() - 1); - } - return Integer.parseInt(numberAsText); - } - - public boolean load(final LittleEndianDataInputStream stream, final WTS wts, final boolean inlineWTS) - throws IOException { - this.detected = false; - this.version = stream.readInt(); - if ((this.version != 1) && (this.version != 2)) { - return false; - } - ObjectMap backup = this.original.clone(); - if (!loadtable(stream, this.original, true, wts, inlineWTS)) { - this.original = backup; - return false; - } - backup = this.custom.clone(); - if (!loadtable(stream, this.custom, false, wts, inlineWTS)) { - this.original = backup; - return false; - } - return true; - } - - public boolean load(final File file, final WTS wts, final boolean inlineWTS) throws IOException { - try (LittleEndianDataInputStream inputStream = new LittleEndianDataInputStream(new FileInputStream(file))) { - final boolean result = load(inputStream, wts, inlineWTS); - return result; - } - } - - public static void inlineWTSTable(final ObjectMap map, final WTS wts) { - for (final Map.Entry entry : map.entrySet()) { - for (final Map.Entry> changes : entry.getValue().getChanges()) { - for (final Change change : changes.getValue()) { - if ((change.getStrval().length() > 8) && "TRIGSTR_".equals(change.getStrval().substring(0, 8))) { - final int key = getWTSValue(change); - change.setStrval(wts.get(key)); - if (change.getStrval().length() > MAX_STR_LEN) { - change.setStrval(change.getStrval().substring(0, MAX_STR_LEN - 1)); - } - } - } - } - } - } - - public void inlineWTS(final WTS wts) { - inlineWTSTable(this.original, wts); - inlineWTSTable(this.custom, wts); - } - - public void reset() { - reset('u'); - } - - public void reset(final char expectedkind) { - this.detected = false; - this.kind = 'u'; - this.lastused = War3ID.fromString("u~~~"); - this.expected = expectedkind; - this.original.clear(); - this.custom.clear(); - } - - public boolean saveTable(final LittleEndianDataOutputStream outputStream, final ObjectMap map, - final boolean isOriginal) throws IOException { - final CharsetEncoder encoder = Charset.forName("utf-8").newEncoder().onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE); - final CharBuffer charBuffer = CharBuffer.allocate(1024); - final ByteBuffer byteBuffer = ByteBuffer.allocate(1024); - final War3ID noid = new War3ID(0); - int count; - count = map.size(); - outputStream.writeInt(count); - for (final Map.Entry entry : map) { - final ObjectDataChangeEntry cl = entry.getValue(); - int totalSize = 0; - for (final Map.Entry> changeEntry : cl.getChanges()) { - totalSize += changeEntry.getValue().size(); - } - if ((totalSize > 0) || !isOriginal) { - ParseUtils.writeWar3ID(outputStream, cl.getOldId()); - ParseUtils.writeWar3ID(outputStream, cl.getNewId()); - count = totalSize;// cl.getChanges().size(); - outputStream.writeInt(count); - for (final Map.Entry> changes : entry.getValue().getChanges()) { - for (final Change change : changes.getValue()) { - ParseUtils.writeWar3ID(outputStream, change.getId()); - outputStream.writeInt(change.getVartype()); - if (extended()) { - outputStream.writeInt(change.getLevel()); - outputStream.writeInt(change.getDataptr()); - } - switch (change.getVartype()) { - case 0: - outputStream.writeInt(change.getLongval()); - break; - case 3: - charBuffer.clear(); - byteBuffer.clear(); - charBuffer.put(change.getStrval()); - charBuffer.flip(); - encoder.encode(charBuffer, byteBuffer, false); - byteBuffer.flip(); - final byte[] stringBytes = new byte[byteBuffer.remaining() + 1]; - int i = 0; - while (byteBuffer.hasRemaining()) { - stringBytes[i++] = byteBuffer.get(); - } - stringBytes[i] = 0; - outputStream.write(stringBytes); - break; - case 4: - outputStream.writeInt(change.isBoolval() ? 1 : 0); - break; - default: - outputStream.writeFloat(change.getRealval()); - break; - } - // if (change.getJunkDNA() == null) { - // saveWriteChars(outputStream, cl.getNewId().asStringValue().toCharArray()); - // } else { - // saveWriteChars(outputStream, - // change.getJunkDNA().asStringValue().toCharArray()); - // } - // saveWriteChars(outputStream, cl.getNewId().asStringValue().toCharArray()); - ParseUtils.writeWar3ID(outputStream, noid); - } - } - } - } - return true; - } - - public boolean save(final LittleEndianDataOutputStream outputStream, final boolean generateWTS) throws IOException { - if (generateWTS) { - throw new UnsupportedOperationException("FAIL cannot generate WTS, needs more code"); - } - this.version = 2; - outputStream.writeInt(this.version); - if (!saveTable(outputStream, this.original, true)) { - throw new RuntimeException("Failed to save standard unit custom data"); - } - if (!saveTable(outputStream, this.custom, false)) { - throw new RuntimeException("Failed to save custom unit custom data"); - } - return true; - } - - public ObjectMap getOriginal() { - return this.original; - } - - public ObjectMap getCustom() { - return this.custom; - } - - private static void debugprint(final String s) { - - } -} diff --git a/core/src/com/etheller/warsmash/units/manager/MutableObjectData.java b/core/src/com/etheller/warsmash/units/manager/MutableObjectData.java deleted file mode 100644 index 808d40e7..00000000 --- a/core/src/com/etheller/warsmash/units/manager/MutableObjectData.java +++ /dev/null @@ -1,958 +0,0 @@ -package com.etheller.warsmash.units.manager; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.etheller.warsmash.units.GameObject; -import com.etheller.warsmash.units.ObjectData; -import com.etheller.warsmash.units.custom.Change; -import com.etheller.warsmash.units.custom.ChangeMap; -import com.etheller.warsmash.units.custom.ObjectDataChangeEntry; -import com.etheller.warsmash.units.custom.War3ObjectDataChangeset; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.util.WorldEditStrings; - -public final class MutableObjectData { - private static final War3ID ROC_SUPPORT_URAC = War3ID.fromString("urac"); - private static final War3ID ROC_SUPPORT_UCAM = War3ID.fromString("ucam"); - private static final War3ID ROC_SUPPORT_USPE = War3ID.fromString("uspe"); - private static final War3ID ROC_SUPPORT_UBDG = War3ID.fromString("ubdg"); - - private final WorldEditorDataType worldEditorDataType; - private final ObjectData sourceSLKData; - private final ObjectData sourceSLKMetaData; - private final War3ObjectDataChangeset editorData; - private Set cachedKeySet; - private final Map metaNameToMetaId; - private final Map cachedKeyToGameObject; - private final MutableObjectDataChangeNotifier changeNotifier; - private final WorldEditStrings worldEditStrings; - - public MutableObjectData(final WorldEditStrings worldEditStrings, final WorldEditorDataType worldEditorDataType, - final ObjectData sourceSLKData, final ObjectData sourceSLKMetaData, - final War3ObjectDataChangeset editorData) { - this.worldEditStrings = worldEditStrings; - this.worldEditorDataType = worldEditorDataType; - resolveStringReferencesInNames(sourceSLKData); - this.sourceSLKData = sourceSLKData; - this.sourceSLKMetaData = sourceSLKMetaData; - this.editorData = editorData; - this.metaNameToMetaId = new HashMap<>(); - for (final String metaKeyString : sourceSLKMetaData.keySet()) { - final War3ID metaKey = War3ID.fromString(metaKeyString); - this.metaNameToMetaId.put(sourceSLKMetaData.get(metaKeyString).getField("field"), metaKey); - } - this.cachedKeyToGameObject = new HashMap<>(); - this.changeNotifier = new MutableObjectDataChangeNotifier(); - } - - // TODO remove this hack - public War3ObjectDataChangeset getEditorData() { - return this.editorData; - } - - private void resolveStringReferencesInNames(final ObjectData sourceSLKData) { - for (final String key : sourceSLKData.keySet()) { - final GameObject gameObject = sourceSLKData.get(key); - String name = gameObject.getField("Name"); - final String suffix = gameObject.getField("EditorSuffix"); - if (name.startsWith("WESTRING")) { - if (!name.contains(" ")) { - name = this.worldEditStrings.getString(name); - } - else { - final String[] names = name.split(" "); - name = ""; - for (final String subName : names) { - if (name.length() > 0) { - name += " "; - } - if (subName.startsWith("WESTRING")) { - name += this.worldEditStrings.getString(subName); - } - else { - name += subName; - } - } - } - if (name.startsWith("\"") && name.endsWith("\"")) { - name = name.substring(1, name.length() - 1); - } - gameObject.setField("Name", name); - } - if (suffix.startsWith("WESTRING")) { - gameObject.setField("EditorSuffix", this.worldEditStrings.getString(suffix)); - } - } - } - - public void mergeChangset(final War3ObjectDataChangeset changeset) { - final List newObjects = new ArrayList<>(); - final Map previousAliasToNewAlias = new HashMap<>(); - for (final Map.Entry entry : changeset.getCustom()) { - -// final String newId = JOptionPane.showInputDialog("Choose UNIT ID"); - final War3ID nextDefaultEditorId = /* War3ID.fromString(newId); */getNextDefaultEditorId( - War3ID.fromString(entry.getKey().charAt(0) + "000")); - ; - System.out.println("Merging " + nextDefaultEditorId + " for " + entry.getKey()); - // createNew API will notifier the changeNotifier - final MutableGameObject newObject = createNew(nextDefaultEditorId, entry.getValue().getOldId(), false); - for (final Map.Entry> changeList : entry.getValue().getChanges()) { - newObject.customUnitData.getChanges().add(changeList.getKey(), changeList.getValue()); - } - newObjects.add(nextDefaultEditorId); - previousAliasToNewAlias.put(entry.getKey(), nextDefaultEditorId); - } - final War3ID[] fieldsToCheck = this.worldEditorDataType == WorldEditorDataType.UNITS - ? new War3ID[] { War3ID.fromString("utra"), War3ID.fromString("uupt"), War3ID.fromString("ubui") } - : new War3ID[] {}; - for (final War3ID unitId : newObjects) { - final MutableGameObject unit = get(unitId); - for (final War3ID field : fieldsToCheck) { - final String techtreeString = unit.getFieldAsString(field, 0); - final java.util.List techList = Arrays.asList(techtreeString.split(",")); - final ArrayList resultingTechList = new ArrayList<>(); - for (final String tech : techList) { - if (tech.length() == 4) { - final War3ID newTechId = previousAliasToNewAlias.get(War3ID.fromString(tech)); - if (newTechId != null) { - resultingTechList.add(newTechId.toString()); - } - else { - resultingTechList.add(tech); - } - } - else { - resultingTechList.add(tech); - } - } - final StringBuilder sb = new StringBuilder(); - for (final String tech : resultingTechList) { - if (sb.length() > 0) { - sb.append(","); - } - sb.append(tech); - } - unit.setField(field, 0, sb.toString()); - } - } - this.changeNotifier.objectsCreated(newObjects.toArray(new War3ID[newObjects.size()])); - } - - public War3ObjectDataChangeset copySelectedObjects(final List objectsToCopy) { - final War3ObjectDataChangeset changeset = new War3ObjectDataChangeset(this.editorData.getExpectedKind()); - final War3ID[] fieldsToCheck = this.worldEditorDataType == WorldEditorDataType.UNITS - ? new War3ID[] { War3ID.fromString("utra"), War3ID.fromString("uupt"), War3ID.fromString("ubui") } - : new War3ID[] {}; - final Map previousAliasToNewAlias = new HashMap<>(); - for (final MutableGameObject gameObject : objectsToCopy) { - final ObjectDataChangeEntry gameObjectUserDataToCopy; - final ObjectDataChangeEntry gameObjectUserData; - final War3ID alias = gameObject.getAlias(); - if (this.editorData.getOriginal().containsKey(alias)) { - gameObjectUserDataToCopy = this.editorData.getOriginal().get(alias); - final War3ID newAlias = getNextDefaultEditorId( - War3ID.fromString(gameObject.getCode().charAt(0) + "000"), changeset, this.sourceSLKData); - gameObjectUserData = new ObjectDataChangeEntry(gameObjectUserDataToCopy.getOldId(), newAlias); - } - else if (this.editorData.getCustom().containsKey(alias)) { - gameObjectUserDataToCopy = this.editorData.getCustom().get(alias); - gameObjectUserData = new ObjectDataChangeEntry(gameObjectUserDataToCopy.getOldId(), - gameObjectUserDataToCopy.getNewId()); - } - else { - gameObjectUserDataToCopy = null; - final War3ID newAlias = getNextDefaultEditorId( - War3ID.fromString(gameObject.getCode().charAt(0) + "000"), changeset, this.sourceSLKData); - gameObjectUserData = new ObjectDataChangeEntry( - gameObject.isCustom() ? gameObject.getCode() : gameObject.getAlias(), newAlias); - } - if (gameObjectUserDataToCopy != null) { - for (final Map.Entry> changeEntry : gameObjectUserDataToCopy.getChanges()) { - for (final Change change : changeEntry.getValue()) { - final Change newChange = new Change(); - newChange.copyFrom(change); - gameObjectUserData.getChanges().add(change.getId(), newChange); - } - } - } - previousAliasToNewAlias.put(gameObject.getAlias(), gameObjectUserData.getNewId()); - changeset.getCustom().put(gameObjectUserData.getNewId(), gameObjectUserData); - } - final MutableObjectData changeEditManager = new MutableObjectData(this.worldEditStrings, - this.worldEditorDataType, this.sourceSLKData, this.sourceSLKMetaData, changeset); - for (final War3ID unitId : changeEditManager.keySet()) { - final MutableGameObject unit = changeEditManager.get(unitId); - for (final War3ID field : fieldsToCheck) { - final String techtreeString = unit.getFieldAsString(field, 0); - final java.util.List techList = Arrays.asList(techtreeString.split(",")); - final ArrayList resultingTechList = new ArrayList<>(); - for (final String tech : techList) { - if (tech.length() == 4) { - final War3ID newTechId = previousAliasToNewAlias.get(War3ID.fromString(tech)); - if (newTechId != null) { - resultingTechList.add(newTechId.toString()); - } - else { - resultingTechList.add(tech); - } - } - else { - resultingTechList.add(tech); - } - } - final StringBuilder sb = new StringBuilder(); - for (final String tech : resultingTechList) { - if (sb.length() > 0) { - sb.append(","); - } - sb.append(tech); - } - unit.setField(field, 0, sb.toString()); - } - } - return changeset; - - } - - public WorldEditorDataType getWorldEditorDataType() { - return this.worldEditorDataType; - } - - public ObjectData getSourceSLKMetaData() { - return this.sourceSLKMetaData; - } - - public void addChangeListener(final MutableObjectDataChangeListener listener) { - this.changeNotifier.subscribe(listener); - } - - public void removeChangeListener(final MutableObjectDataChangeListener listener) { - this.changeNotifier.unsubscribe(listener); - } - - /** - * Returns the set of all Unit IDs in the map, at the cost of a lot of time to - * go find them all. - * - * @return - */ - - public Set keySet() { - if (this.cachedKeySet == null) { - final Set customUnitKeys = this.editorData.getCustom().keySet(); - final Set customKeys = new HashSet<>(customUnitKeys); - for (final String standardUnitKey : this.sourceSLKData.keySet()) { - customKeys.add(War3ID.fromString(standardUnitKey)); - } - this.cachedKeySet = customKeys; - } - return this.cachedKeySet; - } - - public void dropCachesHack() { - this.cachedKeySet = null; - this.cachedKeyToGameObject.clear(); - } - - public MutableGameObject get(final War3ID id) { - MutableGameObject mutableGameObject = this.cachedKeyToGameObject.get(id); - if (mutableGameObject == null) { - if (this.editorData.getCustom().containsKey(id)) { - final ObjectDataChangeEntry customUnitData = this.editorData.getCustom().get(id); - GameObject parentWC3Object = this.sourceSLKData.get(customUnitData.getOldId().asStringValue()); - if (parentWC3Object == null) { - System.err.println("Error parsing unit data: custom unit inherits from unknown id '" - + customUnitData.getOldId().asStringValue() + "'"); - parentWC3Object = GameObject.EMPTY; - } - mutableGameObject = new MutableGameObject(parentWC3Object, customUnitData); - this.cachedKeyToGameObject.put(id, mutableGameObject); - } - else if (this.editorData.getOriginal().containsKey(id)) { - final ObjectDataChangeEntry customUnitData = this.editorData.getOriginal().get(id); - GameObject parentWC3Object = this.sourceSLKData.get(customUnitData.getOldId().asStringValue()); - if (parentWC3Object == null) { - System.err.println("Error parsing unit data: standard unit modifies unknown id '" - + customUnitData.getOldId().asStringValue() + "'"); - parentWC3Object = GameObject.EMPTY; - } - mutableGameObject = new MutableGameObject(parentWC3Object, this.editorData.getOriginal().get(id)); - this.cachedKeyToGameObject.put(id, mutableGameObject); - } - else if (this.sourceSLKData.get(id.asStringValue()) != null) { - GameObject parentWC3Object = this.sourceSLKData.get(id.asStringValue()); - if (parentWC3Object == null) { - System.err.println("Error parsing unit data: id does not exist: '" + id.asStringValue() + "'"); - parentWC3Object = GameObject.EMPTY; - } - mutableGameObject = new MutableGameObject(parentWC3Object, null); - this.cachedKeyToGameObject.put(id, mutableGameObject); - } - } - return mutableGameObject; - } - - public MutableGameObject createNew(final War3ID id, final War3ID parent) { - return createNew(id, parent, true); - } - - private MutableGameObject createNew(final War3ID id, final War3ID parent, final boolean fireListeners) { - this.editorData.getCustom().put(id, new ObjectDataChangeEntry(parent, id)); - if (this.cachedKeySet != null) { - this.cachedKeySet.add(id); - } - if (fireListeners) { - this.changeNotifier.objectCreated(id); - } - return get(id); - } - - public void remove(final War3ID id) { - remove(id, true); - } - - public void remove(final List objects) { - final List removedIds = new ArrayList<>(); - for (final MutableGameObject object : objects) { - if (object.isCustom()) { - remove(object.getAlias(), false); - removedIds.add(object.getAlias()); - } - } - this.changeNotifier.objectsRemoved(removedIds.toArray(new War3ID[removedIds.size()])); - } - - private MutableGameObject remove(final War3ID id, final boolean fireListeners) { - final ObjectDataChangeEntry removedObject = this.editorData.getCustom().remove(id); - final MutableGameObject removedMutableObj = this.cachedKeyToGameObject.remove(id); - if (this.cachedKeySet != null) { - this.cachedKeySet.remove(id); - } - if (fireListeners) { - this.changeNotifier.objectRemoved(id); - } - return removedMutableObj /* might be null based on cache, don't use */; - } - - private static boolean goodForId(final char c) { - return Character.isDigit(c) || ((c >= 'A') && (c <= 'Z')); - } - - public War3ID getNextDefaultEditorId(final War3ID startingId) { - War3ID newId = startingId; - while (this.editorData.getCustom().containsKeyCaseInsensitive(newId) - || (this.sourceSLKData.get(newId.toString()) != null) || !goodForId(newId.charAt(1)) - || !goodForId(newId.charAt(2)) || !goodForId(newId.charAt(3))) { - // TODO good code general solution - if (newId.charAt(3) == 'Z') { - if (newId.charAt(2) == 'Z') { - if (newId.charAt(1) == 'Z') { - newId = new War3ID(((newId.getValue() / (256 * 256 * 256)) * 256 * 256 * 256) - + (256 * 256 * 256) + '0' + ('0' * 256) + ('0' * 256 * 256)); - } - else { - newId = new War3ID( - ((newId.getValue() / (256 * 256)) * 256 * 256) + (256 * 256) + '0' + ('0' * 256)); - } - } - else { - newId = new War3ID(((newId.getValue() / 256) * 256) + 256 + '0'); - } - } - else { - newId = new War3ID(newId.getValue() + 1); - } - } - return newId; - } - - public static War3ID getNextDefaultEditorId(final War3ID startingId, final War3ObjectDataChangeset editorData, - final ObjectData sourceSLKData) { - War3ID newId = startingId; - while (editorData.getCustom().containsKeyCaseInsensitive(newId) || (sourceSLKData.get(newId.toString()) != null) - || !goodForId(newId.charAt(1)) || !goodForId(newId.charAt(2)) || !goodForId(newId.charAt(3))) { - newId = new War3ID(newId.getValue() + 1); - } - return newId; - } - - private static final War3ID BUFF_EDITOR_NAME = War3ID.fromString("fnam"); - private static final War3ID BUFF_BUFFTIP = War3ID.fromString("ftip"); - private static final War3ID UNIT_CAMPAIGN = War3ID.fromString("ucam"); - private static final War3ID UNIT_EDITOR_SUFFIX = War3ID.fromString("unsf"); - private static final War3ID ABIL_EDITOR_SUFFIX = War3ID.fromString("ansf"); - private static final War3ID DESTRUCTABLE_EDITOR_SUFFIX = War3ID.fromString("bsuf"); - private static final War3ID BUFF_EDITOR_SUFFIX = War3ID.fromString("fnsf"); - private static final War3ID UPGRADE_EDITOR_SUFFIX = War3ID.fromString("gnsf"); - private static final War3ID HERO_PROPER_NAMES = War3ID.fromString("upro"); - - private static final Set CATEGORY_FIELDS = new HashSet<>(); - private static final Set TEXT_FIELDS = new HashSet<>(); - private static final Set ICON_FIELDS = new HashSet<>(); - private static final Set FIELD_SETTINGS_FIELDS = new HashSet<>(); - - static { - // categorizing - I thought these would be changeFlags value "c", but no luck - CATEGORY_FIELDS.add(War3ID.fromString("ubdg")); // is a building - CATEGORY_FIELDS.add(War3ID.fromString("uspe")); // categorize special - CATEGORY_FIELDS.add(War3ID.fromString("ucam")); // categorize campaign - CATEGORY_FIELDS.add(War3ID.fromString("urac")); // race - CATEGORY_FIELDS.add(War3ID.fromString("uine")); // in editor - CATEGORY_FIELDS.add(War3ID.fromString("ucls")); // sort string (not a real field, fanmade) - - CATEGORY_FIELDS.add(War3ID.fromString("icla")); // item class - - CATEGORY_FIELDS.add(War3ID.fromString("bcat")); // destructible category - - CATEGORY_FIELDS.add(War3ID.fromString("dcat")); // doodad category - - CATEGORY_FIELDS.add(War3ID.fromString("aher")); // hero ability - CATEGORY_FIELDS.add(War3ID.fromString("aite")); // item ability - CATEGORY_FIELDS.add(War3ID.fromString("arac")); // ability race - - CATEGORY_FIELDS.add(War3ID.fromString("frac")); // buff race - CATEGORY_FIELDS.add(War3ID.fromString("feff")); // is effect - - CATEGORY_FIELDS.add(War3ID.fromString("grac")); // upgrade race - // field structure fields - doesn't seem to be changeFlags 's' like you might - // hope - FIELD_SETTINGS_FIELDS.add(War3ID.fromString("ubdg")); // unit is a builder - FIELD_SETTINGS_FIELDS.add(War3ID.fromString("dvar")); // doodad variations - FIELD_SETTINGS_FIELDS.add(War3ID.fromString("alev")); // ability level - FIELD_SETTINGS_FIELDS.add(War3ID.fromString("glvl")); // upgrade max level - } - - public final class MutableGameObject { - private final GameObject parentWC3Object; - private ObjectDataChangeEntry customUnitData; - - private void fireChangedEvent(final War3ID field, final int level) { - final String changeFlags = MutableObjectData.this.sourceSLKMetaData.get(field.toString()) - .getField("changeFlags"); - if (CATEGORY_FIELDS.contains(field)) { - MutableObjectData.this.changeNotifier.categoriesChanged(getAlias()); - } - else if (changeFlags.contains("t")) { - MutableObjectData.this.changeNotifier.textChanged(getAlias()); - } - else if (changeFlags.contains("m")) { - MutableObjectData.this.changeNotifier.modelChanged(getAlias()); - } - else if (changeFlags.contains("i")) { - MutableObjectData.this.changeNotifier.iconsChanged(getAlias()); - } - else if (FIELD_SETTINGS_FIELDS.contains(field)) { - MutableObjectData.this.changeNotifier.fieldsChanged(getAlias()); - } - } - - public MutableGameObject(final GameObject parentWC3Object, final ObjectDataChangeEntry customUnitData) { - this.parentWC3Object = parentWC3Object; - if (parentWC3Object == null) { - System.err.println( - "Parent object is null for " + customUnitData.getNewId() + ":" + customUnitData.getOldId()); - throw new AssertionError("parentWC3Object cannot be null"); -// this.parentWC3Object = new Element("", new DataTable()); - } - this.customUnitData = customUnitData; - } - - public boolean hasCustomField(final War3ID field, final int level) { - return getMatchingChange(field, level) != null; - } - - public boolean hasEditorData() { - return (this.customUnitData != null) && (this.customUnitData.getChanges().size() > 0); - } - - public boolean isCustom() { - return MutableObjectData.this.editorData.getCustom().containsKey(getAlias()); - } - - public void setField(final War3ID field, final int level, final String value) { - if (value.equals(getFieldStringFromSLKs(field, level))) { - if (!value.equals(getFieldAsString(field, level))) { - fireChangedEvent(field, level); - } - else { - } - resetFieldToDefaults(field, level); - return; - } - final Change matchingChange = getOrCreateMatchingChange(field, level); - matchingChange.setStrval(value); - matchingChange.setVartype(War3ObjectDataChangeset.VAR_TYPE_STRING); - fireChangedEvent(field, level); - } - - public void setField(final War3ID field, final int level, final boolean value) { - if (value == (asInt(getFieldStringFromSLKs(field, level).trim()) == 1)) { - if (value != getFieldAsBoolean(field, level)) { - fireChangedEvent(field, level); - } - resetFieldToDefaults(field, level); - return; - } - final Change matchingChange = getOrCreateMatchingChange(field, level); - matchingChange.setBoolval(value); - matchingChange.setVartype(War3ObjectDataChangeset.VAR_TYPE_BOOLEAN); - fireChangedEvent(field, level); - } - - public void setField(final War3ID field, final int level, final int value) { - if (value == asInt(getFieldStringFromSLKs(field, level).trim())) { - if (value != getFieldAsInteger(field, level)) { - fireChangedEvent(field, level); - } - resetFieldToDefaults(field, level); - return; - } - final Change matchingChange = getOrCreateMatchingChange(field, level); - matchingChange.setLongval(value); - matchingChange.setVartype(War3ObjectDataChangeset.VAR_TYPE_INT); - fireChangedEvent(field, level); - } - - public void resetFieldToDefaults(final War3ID field, final int level) { - final Change existingChange = getMatchingChange(field, level); - if ((existingChange != null) && (this.customUnitData != null)) { - this.customUnitData.getChanges().delete(field, existingChange); - fireChangedEvent(field, level); - } - return; - } - - public void setField(final War3ID field, final int level, final float value) { - if (Math.abs(value - asFloat(getFieldStringFromSLKs(field, level).trim())) < 0.00001f) { - if (Math.abs(value - getFieldAsFloat(field, level)) > 0.00001f) { - fireChangedEvent(field, level); - } - resetFieldToDefaults(field, level); - return; - } - final Change matchingChange = getOrCreateMatchingChange(field, level); - matchingChange.setRealval(value); - final boolean unsigned = MutableObjectData.this.sourceSLKMetaData.get(field.asStringValue()) - .getField("type").equals("unreal"); - matchingChange.setVartype( - unsigned ? War3ObjectDataChangeset.VAR_TYPE_UNREAL : War3ObjectDataChangeset.VAR_TYPE_REAL); - fireChangedEvent(field, level); - } - - private Change getOrCreateMatchingChange(final War3ID field, final int level) { - if (this.customUnitData == null) { - final War3ID war3Id = War3ID.fromString(this.parentWC3Object.getId()); - final ObjectDataChangeEntry newCustomUnitData = new ObjectDataChangeEntry(war3Id, War3ID.NONE); - MutableObjectData.this.editorData.getOriginal().put(war3Id, newCustomUnitData); - this.customUnitData = newCustomUnitData; - } - Change matchingChange = getMatchingChange(field, level); - if (matchingChange == null) { - final ChangeMap changeMap = this.customUnitData.getChanges(); - final List changeList = changeMap.get(field); - matchingChange = new Change(); - matchingChange.setId(field); - matchingChange.setLevel(level); - if (MutableObjectData.this.editorData.extended()) { - // dunno why, but Blizzard sure likes those dataptrs in the ability data - // my code should grab 0 when the metadata lacks this field - matchingChange.setDataptr( - MutableObjectData.this.sourceSLKMetaData.get(field.asStringValue()).getFieldValue("data")); - } - if (changeList == null) { - changeMap.add(field, matchingChange); - } - else { - boolean insertedChange = false; - for (int i = 0; i < changeList.size(); i++) { - if (changeList.get(i).getLevel() > level) { - insertedChange = true; - changeList.add(i, matchingChange); - break; - } - } - if (!insertedChange) { - changeList.add(changeList.size(), matchingChange); - } - } - } - return matchingChange; - } - - public String getFieldAsString(final War3ID field, final int level) { - final Change matchingChange = getMatchingChange(field, level); - if (matchingChange != null) { - if (matchingChange.getVartype() == War3ObjectDataChangeset.VAR_TYPE_INT) { - return Integer.toString(matchingChange.getLongval()); - } - if (matchingChange.getVartype() != War3ObjectDataChangeset.VAR_TYPE_STRING) { - throw new IllegalStateException( - "Requested string value of '" + field + "' from '" + this.parentWC3Object.getId() - + "', but this field was not a string! vartype=" + matchingChange.getVartype()); - } - return matchingChange.getStrval(); - } - // no luck with custom data, look at the standard data - int slkLevel = level; - if ((MutableObjectData.this.worldEditorDataType == WorldEditorDataType.UPGRADES) && false) { - slkLevel -= 1; - } - return getFieldStringFromSLKs(field, slkLevel); - } - - private Change getMatchingChange(final War3ID field, final int level) { - Change matchingChange = null; - if (this.customUnitData == null) { - return null; - } - final List changeList = this.customUnitData.getChanges().get(field); - if (changeList != null) { - for (final Change change : changeList) { - if (change.getLevel() == level) { - matchingChange = change; - break; - } - } - } - return matchingChange; - } - - public String readSLKTag(final String key) { - if (MutableObjectData.this.metaNameToMetaId.containsKey(key)) { - return getFieldAsString(MutableObjectData.this.metaNameToMetaId.get(key), 0); - } - return this.parentWC3Object.getField(key); - } - - public boolean readSLKTagBoolean(final String key) { - if (MutableObjectData.this.metaNameToMetaId.containsKey(key)) { - return getFieldAsBoolean(MutableObjectData.this.metaNameToMetaId.get(key), 0); - } - return this.parentWC3Object.getFieldValue(key) == 1; - } - - public int readSLKTagInt(final String key) { - if (MutableObjectData.this.metaNameToMetaId.containsKey(key)) { - return getFieldAsInteger(MutableObjectData.this.metaNameToMetaId.get(key), 0); - } - return this.parentWC3Object.getFieldValue(key); - } - - public float readSLKTagFloat(final String key) { - if (MutableObjectData.this.metaNameToMetaId.containsKey(key)) { - return getFieldAsFloat(MutableObjectData.this.metaNameToMetaId.get(key), 0); - } - try { - return Float.parseFloat(this.parentWC3Object.getField(key)); - } - catch (final NumberFormatException exc) { - return Float.NaN; - } - } - - public String getName() { - String name = getFieldAsString(MutableObjectData.this.editorData.getNameField(), - MutableObjectData.this.worldEditorDataType == WorldEditorDataType.UPGRADES ? 1 : 0); - boolean nameKnown = name.length() >= 1; - if (!nameKnown && !readSLKTag("code").equals(getAlias().toString()) && (readSLKTag("code").length() >= 4) - && !isCustom()) { - final MutableGameObject codeObject = get(War3ID.fromString(readSLKTag("code").substring(0, 4))); - if (codeObject != null) { - name = codeObject.getName(); - nameKnown = true; - } - } - String suf = ""; - switch (MutableObjectData.this.worldEditorDataType) { - case ABILITIES: - suf = getFieldAsString(ABIL_EDITOR_SUFFIX, 0); - break; - case BUFFS_EFFECTS: - final String editorName = getFieldAsString(BUFF_EDITOR_NAME, 0); - if (!nameKnown && (editorName.length() > 1)) { - name = editorName; - nameKnown = true; - } - final String buffTip = getFieldAsString(BUFF_BUFFTIP, 0); - if (!nameKnown && (buffTip.length() > 1)) { - name = buffTip; - nameKnown = true; - } - suf = getFieldAsString(BUFF_EDITOR_SUFFIX, 0); - break; - case DESTRUCTIBLES: - suf = getFieldAsString(DESTRUCTABLE_EDITOR_SUFFIX, 0); - break; - case DOODADS: - break; - case ITEM: - break; - case UNITS: - if (getFieldAsBoolean(UNIT_CAMPAIGN, 0) && Character.isUpperCase(getAlias().charAt(0))) { - name = getFieldAsString(HERO_PROPER_NAMES, 0); - if (name.contains(",")) { - name = name.split(",")[0]; - } - } - suf = getFieldAsString(UNIT_EDITOR_SUFFIX, 0); - break; - case UPGRADES: - suf = getFieldAsString(UPGRADE_EDITOR_SUFFIX, 1); - break; - } - if (nameKnown/* && name.startsWith("WESTRING") */) { - if (!name.contains(" ")) { - // name = WEString.getString(name); - } - else { - final String[] names = name.split(" "); - name = ""; - for (final String subName : names) { - if (name.length() > 0) { - name += " "; - } - // if (subName.startsWith("WESTRING")) { - // name += WEString.getString(subName); - // } else { - name += subName; - // } - } - } - if (name.startsWith("\"") && name.endsWith("\"")) { - name = name.substring(1, name.length() - 1); - } - } - if (!nameKnown) { - name = MutableObjectData.this.worldEditStrings.getString("WESTRING_UNKNOWN") + " '" - + getAlias().toString() + "'"; - } - if ((suf.length() > 0) && !suf.equals("_")) { - // if (suf.startsWith("WESTRING")) { - // suf = WEString.getString(suf); - // } - if (!suf.startsWith(" ")) { - name += " "; - } - name += suf; - } - return name; - } - - private String getFieldStringFromSLKs(final War3ID field, final int level) { - final GameObject metaData = MutableObjectData.this.sourceSLKMetaData.get(field.asStringValue()); - if (metaData == null) { - if (MutableObjectData.this.worldEditorDataType == WorldEditorDataType.UNITS) { - if (ROC_SUPPORT_URAC.equals(field)) { - return this.parentWC3Object.getField("race"); - } - else if (ROC_SUPPORT_UCAM.equals(field)) { - return "0"; - } - else if (ROC_SUPPORT_USPE.equals(field)) { - return this.parentWC3Object.getField("special"); - } - else if (ROC_SUPPORT_UBDG.equals(field)) { - return this.parentWC3Object.getField("isbldg"); - } - } - throw new IllegalStateException("Program requested " + field.toString() + " from " - + MutableObjectData.this.worldEditorDataType); - } - if (this.parentWC3Object == null) { - throw new IllegalStateException("corrupted unit, no parent unit id"); - } - int index = metaData.getFieldValue("index"); - final String upgradeHack = metaData.getField("appendIndex"); - if ("0".equals(upgradeHack)) { - // Engage magic upgrade hack to replace index with level - if (!field.toString().equals("gbpx") && !field.toString().equals("gbpy")) { - index = level; - } - } - else if ((index != -1) && (level > 0)) { - index = level - 1; - } - if (index != -1) { - final String fieldStringValue = this.parentWC3Object - .getField(getEditorMetaDataDisplayKey(level, metaData), index); - return fieldStringValue; - } - final String fieldStringValue = this.parentWC3Object.getField(getEditorMetaDataDisplayKey(level, metaData)); - return fieldStringValue; - } - - public int getFieldAsInteger(final War3ID field, final int level) { - final Change matchingChange = getMatchingChange(field, level); - if (matchingChange != null) { - if (matchingChange.getVartype() != War3ObjectDataChangeset.VAR_TYPE_INT) { - throw new IllegalStateException( - "Requested integer value of '" + field + "' from '" + this.parentWC3Object.getId() - + "', but this field was not an int! vartype=" + matchingChange.getVartype()); - } - return matchingChange.getLongval(); - } - // no luck with custom data, look at the standard data - try { - return Integer.parseInt(getFieldStringFromSLKs(field, level)); - } - catch (final NumberFormatException e) { - return 0; - } - } - - public boolean getFieldAsBoolean(final War3ID field, final int level) { - final Change matchingChange = getMatchingChange(field, level); - if (matchingChange != null) { - if (matchingChange.getVartype() != War3ObjectDataChangeset.VAR_TYPE_BOOLEAN) { - if (matchingChange.getVartype() == War3ObjectDataChangeset.VAR_TYPE_INT) { - return matchingChange.getLongval() == 1; - } - else { - throw new IllegalStateException( - "Requested boolean value of '" + field + "' from '" + this.parentWC3Object.getId() - + "', but this field was not a bool! vartype=" + matchingChange.getVartype()); - } - } - return matchingChange.isBoolval(); - } - // no luck with custom data, look at the standard data - try { - return Integer.parseInt(getFieldStringFromSLKs(field, level)) == 1; - } - catch (final NumberFormatException e) { - return false; - } - } - - public float getFieldAsFloat(final War3ID field, final int level) { - final Change matchingChange = getMatchingChange(field, level); - if (matchingChange != null) { - if ((matchingChange.getVartype() != War3ObjectDataChangeset.VAR_TYPE_REAL) - && (matchingChange.getVartype() != War3ObjectDataChangeset.VAR_TYPE_UNREAL)) { - throw new IllegalStateException( - "Requested float value of '" + field + "' from '" + this.parentWC3Object.getId() - + "', but this field was not a float! vartype=" + matchingChange.getVartype()); - } - return matchingChange.getRealval(); - } - // no luck with custom data, look at the standard data - try { - return Float.parseFloat(getFieldStringFromSLKs(field, level)); - } - catch (final NumberFormatException e) { - return 0; - } - } - - public War3ID getAlias() { - if (this.customUnitData == null) { - return War3ID.fromString(this.parentWC3Object.getId()); - } - if (War3ID.NONE.equals(this.customUnitData.getNewId())) { - return this.customUnitData.getOldId(); - } - return this.customUnitData.getNewId(); - } - - public War3ID getCode() { - if (this.customUnitData == null) { - if ((MutableObjectData.this.worldEditorDataType == WorldEditorDataType.ABILITIES) - || (MutableObjectData.this.worldEditorDataType == WorldEditorDataType.BUFFS_EFFECTS)) { - return War3ID.fromString(this.parentWC3Object.getField("code")); - } - else { - return War3ID.fromString(this.parentWC3Object.getId()); - } - } - if (War3ID.NONE.equals(this.customUnitData.getNewId())) { - if ((MutableObjectData.this.worldEditorDataType == WorldEditorDataType.ABILITIES) - || (MutableObjectData.this.worldEditorDataType == WorldEditorDataType.BUFFS_EFFECTS)) { - return War3ID.fromString(this.parentWC3Object.getField("code")); - } - else { - return this.customUnitData.getOldId(); - } - } - return this.customUnitData.getOldId(); - } - - } - - private static int asInt(final String text) { - if ("#VALUE!".equals(text)) { - return 0; - } - return text == null ? 0 - : "".equals(text) ? 0 : "-".equals(text) ? 0 : "_".equals(text) ? 0 : Integer.parseInt(text); - } - - private static float asFloat(final String text) { - return text == null ? 0 - : "".equals(text) ? 0 : "-".equals(text) ? 0 : "_".equals(text) ? 0 : Float.parseFloat(text); - } - - public enum WorldEditorDataType { - UNITS("w3u"), - ITEM("w3t"), - DESTRUCTIBLES("w3b"), - DOODADS("w3d"), - ABILITIES("w3a"), - BUFFS_EFFECTS("w3h"), - UPGRADES("w3q"); - - private String extension; - - private WorldEditorDataType(final String extension) { - this.extension = extension; - } - - public String getExtension() { - return this.extension; - } - } - - public static String getEditorMetaDataDisplayKey(int level, final GameObject metaData) { - final int index = metaData.getFieldValue("index"); - String metaDataName = metaData.getField("field"); - final int repeatCount = metaData.getFieldValue("repeat"); - final String upgradeHack = metaData.getField("appendIndex"); - final boolean repeats = (repeatCount > 0) && !"0".equals(upgradeHack); - final int data = metaData.getFieldValue("data"); - if (data > 0) { - metaDataName += (char) ('A' + (data - 1)); - } - if ("1".equals(upgradeHack)) { - final int upgradeExtensionLevel = level - 1; - if (upgradeExtensionLevel > 0) { - metaDataName += Integer.toString(upgradeExtensionLevel); - } - } - else if (repeats && (index == -1)) { - if (level == 0) { - level = 1; - } - if (repeatCount >= 10) { - metaDataName += String.format("%2d", level).replace(' ', '0'); - } - else { - metaDataName += Integer.toString(level); - } - } - return metaDataName; - } - - public static String getDisplayAsRawDataName(final MutableGameObject gameObject) { - String aliasString = gameObject.getAlias().toString(); - if (!gameObject.getAlias().equals(gameObject.getCode())) { - aliasString += ":" + gameObject.getCode().toString(); - } - return aliasString + " (" + gameObject.getName() + ")"; - } -} diff --git a/core/src/com/etheller/warsmash/units/manager/MutableObjectDataChangeListener.java b/core/src/com/etheller/warsmash/units/manager/MutableObjectDataChangeListener.java deleted file mode 100644 index 359863a4..00000000 --- a/core/src/com/etheller/warsmash/units/manager/MutableObjectDataChangeListener.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.etheller.warsmash.units.manager; - -import com.etheller.warsmash.util.War3ID; - -public interface MutableObjectDataChangeListener { - void textChanged(War3ID changedObject); - - void iconsChanged(War3ID changedObject); - - void categoriesChanged(War3ID changedObject); - - void fieldsChanged(War3ID changedObject); - - void modelChanged(War3ID changedObject); - - void objectCreated(War3ID newObject); - - void objectsCreated(War3ID[] newObject); - - void objectRemoved(War3ID removedObject); - - void objectsRemoved(War3ID[] removedObject); -} diff --git a/core/src/com/etheller/warsmash/units/manager/MutableObjectDataChangeNotifier.java b/core/src/com/etheller/warsmash/units/manager/MutableObjectDataChangeNotifier.java deleted file mode 100644 index 1ea3ddea..00000000 --- a/core/src/com/etheller/warsmash/units/manager/MutableObjectDataChangeNotifier.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.etheller.warsmash.units.manager; - -import com.etheller.warsmash.util.SubscriberSetNotifier; -import com.etheller.warsmash.util.War3ID; - -public final class MutableObjectDataChangeNotifier extends SubscriberSetNotifier - implements MutableObjectDataChangeListener { - - @Override - public void textChanged(final War3ID changedObject) { - for (final MutableObjectDataChangeListener listener : this.set) { - listener.textChanged(changedObject); - } - } - - @Override - public void categoriesChanged(final War3ID changedObject) { - for (final MutableObjectDataChangeListener listener : this.set) { - listener.categoriesChanged(changedObject); - } - } - - @Override - public void iconsChanged(final War3ID changedObject) { - for (final MutableObjectDataChangeListener listener : this.set) { - listener.iconsChanged(changedObject); - } - } - - @Override - public void fieldsChanged(final War3ID changedObject) { - for (final MutableObjectDataChangeListener listener : this.set) { - listener.fieldsChanged(changedObject); - } - } - - @Override - public void modelChanged(final War3ID changedObject) { - for (final MutableObjectDataChangeListener listener : this.set) { - listener.modelChanged(changedObject); - } - } - - @Override - public void objectCreated(final War3ID newObject) { - for (final MutableObjectDataChangeListener listener : this.set) { - listener.objectCreated(newObject); - } - } - - @Override - public void objectsCreated(final War3ID[] newObject) { - for (final MutableObjectDataChangeListener listener : this.set) { - listener.objectsCreated(newObject); - } - } - - @Override - public void objectRemoved(final War3ID newObject) { - for (final MutableObjectDataChangeListener listener : this.set) { - listener.objectRemoved(newObject); - } - } - - @Override - public void objectsRemoved(final War3ID[] newObject) { - for (final MutableObjectDataChangeListener listener : this.set) { - listener.objectsRemoved(newObject); - } - } - -} diff --git a/core/src/com/etheller/warsmash/util/DataSourceFileHandle.java b/core/src/com/etheller/warsmash/util/DataSourceFileHandle.java deleted file mode 100644 index 4bc4a5d6..00000000 --- a/core/src/com/etheller/warsmash/util/DataSourceFileHandle.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.etheller.warsmash.util; - -import java.io.IOException; -import java.io.InputStream; - -import com.badlogic.gdx.files.FileHandle; -import com.etheller.warsmash.datasources.DataSource; - -public class DataSourceFileHandle extends FileHandle { - private final DataSource dataSource; - - public DataSourceFileHandle(final DataSource dataSource, final String path) { - super(fixPath(dataSource, path)); - this.dataSource = dataSource; - } - - @Override - public String path() { - return file().getPath(); - } - - @Override - public InputStream read() { - try { - return this.dataSource.getResourceAsStream(path()); - } - catch (final IOException e) { - throw new RuntimeException("Failed to load FileHandle from DataSource: " + path()); - } - } - - private static String fixPath(final DataSource dataSource, String path) { - if (!dataSource.has(path) && (path.toLowerCase().endsWith(".wav") || path.toLowerCase().endsWith(".mp3"))) { - final String otherPossiblePath = path.substring(0, path.lastIndexOf('.')) + ".flac"; - if (dataSource.has(otherPossiblePath)) { - path = otherPossiblePath; - } - } - return path; - } -} diff --git a/core/src/com/etheller/warsmash/util/Descriptor.java b/core/src/com/etheller/warsmash/util/Descriptor.java deleted file mode 100644 index ff608feb..00000000 --- a/core/src/com/etheller/warsmash/util/Descriptor.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.etheller.warsmash.util; - -public interface Descriptor { - E create(); - -} diff --git a/core/src/com/etheller/warsmash/util/FastNumberFormat.java b/core/src/com/etheller/warsmash/util/FastNumberFormat.java deleted file mode 100644 index 8741b4d8..00000000 --- a/core/src/com/etheller/warsmash/util/FastNumberFormat.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.util; - -public class FastNumberFormat { - private static final StringBuilder RECYCLE_STRING_BUILDER = new StringBuilder(); - - public static String formatWholeNumber(final float value) { - int intValue = (int) value; - RECYCLE_STRING_BUILDER.setLength(0); - do { - RECYCLE_STRING_BUILDER.append(intValue % 10); - intValue /= 10; - } - while (intValue > 0); - final int len = RECYCLE_STRING_BUILDER.length(); - final int halfLength = len / 2; - for (int i = 0; i < halfLength; i++) { - final char swapCharA = RECYCLE_STRING_BUILDER.charAt(i); - final char swapCharB = RECYCLE_STRING_BUILDER.charAt(len - 1 - i); - RECYCLE_STRING_BUILDER.setCharAt(len - 1 - i, swapCharA); - RECYCLE_STRING_BUILDER.setCharAt(i, swapCharB); - } - return RECYCLE_STRING_BUILDER.toString(); - } -} diff --git a/core/src/com/etheller/warsmash/util/FixedIntersector.java b/core/src/com/etheller/warsmash/util/FixedIntersector.java deleted file mode 100644 index 0ecbcd86..00000000 --- a/core/src/com/etheller/warsmash/util/FixedIntersector.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.etheller.warsmash.util; - -import com.badlogic.gdx.math.Intersector; -import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.math.Plane; -import com.badlogic.gdx.math.Plane.PlaneSide; -import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.math.collision.Ray; - -public class FixedIntersector { - - private final static Vector3 v0 = new Vector3(); - private final static Vector3 v1 = new Vector3(); - private final static Vector3 v2 = new Vector3(); - - private static final Plane p = new Plane(new Vector3(), 0); - private static final Vector3 i = new Vector3(); - - /** - * Intersect a {@link Ray} and a triangle, returning the intersection point in - * intersection. - * - * @param ray The ray - * @param t1 The first vertex of the triangle - * @param t2 The second vertex of the triangle - * @param t3 The third vertex of the triangle - * @param intersection The intersection point (optional) - * @return True in case an intersection is present. - */ - public static boolean intersectRayTriangle(final Ray ray, final Vector3 t1, final Vector3 t2, final Vector3 t3, - final Vector3 intersection) { - if (t2.epsilonEquals(t3)) { - return false; - } - final Vector3 edge1 = v0.set(t2).sub(t1); - final Vector3 edge2 = v1.set(t3).sub(t1); - - final Vector3 pvec = v2.set(ray.direction).crs(edge2); - float det = edge1.dot(pvec); - if (MathUtils.isZero(det)) { - p.set(t1, t2, t3); - if ((p.testPoint(ray.origin) == PlaneSide.OnPlane) - && Intersector.isPointInTriangle(ray.origin, t1, t2, t3)) { - if (intersection != null) { - intersection.set(ray.origin); - } - return true; - } - return false; - } - - det = 1.0f / det; - - final Vector3 tvec = i.set(ray.origin).sub(t1); - final float u = tvec.dot(pvec) * det; - if ((u < 0.0f) || (u > 1.0f)) { - return false; - } - - final Vector3 qvec = tvec.crs(edge1); - final float v = ray.direction.dot(qvec) * det; - if ((v < 0.0f) || ((u + v) > 1.0f)) { - return false; - } - - final float t = edge2.dot(qvec) * det; - if (t < 0) { - return false; - } - - if (intersection != null) { - if (t <= MathUtils.FLOAT_ROUNDING_ERROR) { - intersection.set(ray.origin); - } - else { - ray.getEndPoint(intersection, t); - } - } - - return true; - } -} diff --git a/core/src/com/etheller/warsmash/util/ImageUtils.java b/core/src/com/etheller/warsmash/util/ImageUtils.java deleted file mode 100644 index 80358b1a..00000000 --- a/core/src/com/etheller/warsmash/util/ImageUtils.java +++ /dev/null @@ -1,255 +0,0 @@ -package com.etheller.warsmash.util; - -import java.awt.Transparency; -import java.awt.color.ColorSpace; -import java.awt.image.BufferedImage; -import java.awt.image.ColorModel; -import java.awt.image.ComponentColorModel; -import java.awt.image.DataBuffer; -import java.io.IOException; -import java.io.InputStream; -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import javax.imageio.ImageIO; - -import com.badlogic.gdx.graphics.GL30; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Pixmap.Format; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.Texture.TextureFilter; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.viewer5.handlers.tga.TgaFile; - -/** - * Uses AWT stuff - * - */ -public final class ImageUtils { - private static final int BYTES_PER_PIXEL = 4; - public static final String DEFAULT_ICON_PATH = "ReplaceableTextures\\CommandButtons\\BTNTemp.blp"; - - public static Texture getAnyExtensionTexture(final DataSource dataSource, final String path) { - BufferedImage image; - try { - final AnyExtensionImage imageInfo = getAnyExtensionImageFixRGB(dataSource, path, "texture"); - image = imageInfo.getImageData(); - if (image != null) { - return ImageUtils.getTexture(image, imageInfo.isNeedsSRGBFix()); - } - } - catch (final IOException e) { - return null; - } - return null; - } - - public static AnyExtensionImage getAnyExtensionImageFixRGB(final DataSource dataSource, final String path, - final String errorType) throws IOException { - if (path.toLowerCase().endsWith(".blp")) { - try (InputStream stream = dataSource.getResourceAsStream(path)) { - if (stream == null) { - final String tgaPath = path.substring(0, path.length() - 4) + ".tga"; - try (final InputStream tgaStream = dataSource.getResourceAsStream(tgaPath)) { - if (tgaStream != null) { - final BufferedImage tgaData = TgaFile.readTGA(tgaPath, tgaStream); - return new AnyExtensionImage(false, tgaData); - } - else { - final String ddsPath = path.substring(0, path.length() - 4) + ".dds"; - try (final InputStream ddsStream = dataSource.getResourceAsStream(ddsPath)) { - if (ddsStream != null) { - final BufferedImage image = ImageIO.read(ddsStream); - return new AnyExtensionImage(false, image); - } - else { - throw new IllegalStateException("Missing " + errorType + ": " + path); - } - } - } - } - } - else { - final BufferedImage image = ImageIO.read(stream); - return new AnyExtensionImage(true, image); - } - } - } - else { - throw new IllegalStateException("Missing " + errorType + ": " + path); - } - } - - public static final class AnyExtensionImage { - private final boolean needsSRGBFix; - private final BufferedImage imageData; - - public AnyExtensionImage(final boolean needsSRGBFix, final BufferedImage imageData) { - this.needsSRGBFix = needsSRGBFix; - this.imageData = imageData; - } - - public BufferedImage getImageData() { - return this.imageData; - } - - public BufferedImage getRGBCorrectImageData() { - return this.needsSRGBFix ? forceBufferedImagesRGB(this.imageData) : this.imageData; - } - - public boolean isNeedsSRGBFix() { - return this.needsSRGBFix; - } - } - - public static BufferedImage getBLPImage(final DataSource dataSource, final String path) { - try { - try (final InputStream resourceAsStream = dataSource.getResourceAsStream(path)) { - if ((resourceAsStream == null) || path.endsWith(".tga")) { - final String tgaPath = path.substring(0, path.length() - 4) + ".tga"; - try (final InputStream tgaStream = dataSource.getResourceAsStream(tgaPath)) { - if (tgaStream == null) { - throw new IllegalStateException("missing resource: " + path); - } - else { - return TgaFile.readTGA(tgaPath, tgaStream); - } - } - } - final BufferedImage image = ImageIO.read(resourceAsStream); - if (image == null) { - throw new IllegalStateException("corrupt resource: " + path); - } - return image; - } - - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - public static Texture getTexture(final BufferedImage image, final boolean sRGBFix) { - final int[] pixels = new int[image.getWidth() * image.getHeight()]; - image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()); - - // 4 - // for - // RGBA, - // 3 - // for - // RGB - - final Pixmap pixmap = sRGBFix ? new Pixmap(image.getWidth(), image.getHeight(), Format.RGBA8888) { - @Override - public int getGLInternalFormat() { - return GL30.GL_SRGB8_ALPHA8; - } - } : new Pixmap(image.getWidth(), image.getHeight(), Format.RGBA8888); - for (int y = 0; y < image.getHeight(); y++) { - for (int x = 0; x < image.getWidth(); x++) { - final int pixel = pixels[(y * image.getWidth()) + x]; - pixmap.drawPixel(x, y, (pixel << 8) | (pixel >>> 24)); - } - } - final Texture texture = new Texture(pixmap); - texture.setFilter(TextureFilter.Linear, TextureFilter.Linear); - return texture; - } - - public static Texture getTextureNoColorCorrection(final BufferedImage image) { - final int[] pixels = new int[image.getWidth() * image.getHeight()]; - image.getRGB(0, 0, image.getWidth(), image.getHeight(), pixels, 0, image.getWidth()); - - // 4 - // for - // RGBA, - // 3 - // for - // RGB - - final Pixmap pixmap = new Pixmap(image.getWidth(), image.getHeight(), Format.RGBA8888); - for (int y = 0; y < image.getHeight(); y++) { - for (int x = 0; x < image.getWidth(); x++) { - final int pixel = pixels[(y * image.getWidth()) + x]; - pixmap.drawPixel(x, y, (pixel << 8) | (pixel >>> 24)); - } - } - final Texture texture = new Texture(pixmap); - texture.setFilter(TextureFilter.Linear, TextureFilter.Linear); - return texture; - } - - public static Buffer getTextureBuffer(final BufferedImage image) { - - final int imageWidth = image.getWidth(); - final int imageHeight = image.getHeight(); - final int[] pixels = new int[imageWidth * imageHeight]; - image.getRGB(0, 0, imageWidth, imageHeight, pixels, 0, imageWidth); - - final ByteBuffer buffer = ByteBuffer.allocateDirect(imageWidth * imageHeight * BYTES_PER_PIXEL) - .order(ByteOrder.nativeOrder()); - // 4 - // for - // RGBA, - // 3 - // for - // RGB - - for (int y = 0; y < imageHeight; y++) { - for (int x = 0; x < imageWidth; x++) { - final int pixel = pixels[(y * imageWidth) + x]; - buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component - buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component - buffer.put((byte) (pixel & 0xFF)); // Blue component - buffer.put((byte) ((pixel >> 24) & 0xFF)); // Alpha component. - // Only for RGBA - } - } - - buffer.flip(); - return buffer; - } - - /** - * Convert an input buffered image into sRGB color space using component values - * directly instead of performing a color space conversion. - * - * @param in Input image to be converted. - * @return Resulting sRGB image. - */ - public static BufferedImage forceBufferedImagesRGB(final BufferedImage in) { - // Resolve input ColorSpace. - final ColorSpace inCS = in.getColorModel().getColorSpace(); - final ColorSpace sRGBCS = ColorSpace.getInstance(ColorSpace.CS_sRGB); - if (inCS == sRGBCS) { - // Already is sRGB. - return in; - } - if (inCS.getNumComponents() != sRGBCS.getNumComponents()) { - throw new IllegalArgumentException("Input color space has different number of components from sRGB."); - } - - // Draw input. - final ColorModel lRGBModel = new ComponentColorModel(inCS, true, false, Transparency.TRANSLUCENT, - DataBuffer.TYPE_BYTE); - final ColorModel sRGBModel = new ComponentColorModel(sRGBCS, true, false, Transparency.TRANSLUCENT, - DataBuffer.TYPE_BYTE); - final BufferedImage lRGB = new BufferedImage(lRGBModel, - lRGBModel.createCompatibleWritableRaster(in.getWidth(), in.getHeight()), false, null); - for (int i = 0; i < in.getWidth(); i++) { - for (int j = 0; j < in.getHeight(); j++) { - lRGB.setRGB(i, j, in.getRGB(i, j)); - } - } - - // Convert to sRGB. - final BufferedImage sRGB = new BufferedImage(sRGBModel, lRGB.getRaster(), false, null); - - return sRGB; - } - - private ImageUtils() { - } -} diff --git a/core/src/com/etheller/warsmash/util/IniFile.java b/core/src/com/etheller/warsmash/util/IniFile.java deleted file mode 100644 index 5c6fcffb..00000000 --- a/core/src/com/etheller/warsmash/util/IniFile.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.etheller.warsmash.util; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class IniFile { - private static final Pattern NAME_PATTERN = Pattern.compile("^\\[(.+?)\\].*"); - private static final Pattern DATA_PATTERN = Pattern.compile("^(.+?)=(.*?)$"); - public final Map properties = new HashMap<>(); - public final Map> sections = new HashMap<>(); - - public IniFile(final String buffer) { - if (buffer != null) { - this.load(buffer); - } - } - - public void load(final String buffer) { - // All properties added until a section is reached are added to the properties - // map. - // Once a section is reached, any further properties will be added to it until - // matching another section, etc. - Map section = this.properties; - - // Below: using \n instead of \r\n because its not reading directly from the - // actual file, but instead from a Java translated thing - for (final String line : buffer.split("\n")) { - // INI defines comments as starting with a semicolon ';'. - // However, Warcraft 3 INI files use normal C comments '//'. - // In addition, Warcraft 3 files have empty lines. - // Therefore, ignore any line matching any of these conditions. - - if ((line.length() != 0) && !line.startsWith("//") && !line.startsWith(";")) { - final Matcher matcher = NAME_PATTERN.matcher(line); - - if (matcher.matches()) { - final String name = matcher.group(1).trim().toLowerCase(); - - section = this.sections.get(name); - - if (section == null) { - section = new HashMap<>(); - - this.sections.put(name, section); - } - } - else { - final Matcher dataMatcher = DATA_PATTERN.matcher(line); - if (dataMatcher.matches()) { - section.put(dataMatcher.group(1).toLowerCase(), dataMatcher.group(2)); - } - } - } - - } - - } - - public String save() { - final List lines = new ArrayList<>(); - - for (final Map.Entry entry : this.properties.entrySet()) { - lines.add(entry.getKey() + "=" + entry.getValue()); - } - - for (final Map.Entry> sectionData : this.sections.entrySet()) { - lines.add("[" + sectionData.getKey() + "]"); - - for (final Map.Entry entry : sectionData.getValue().entrySet()) { - lines.add(entry.getKey() + "=" + entry.getValue()); - } - } - - return String.join("\r\n", lines); - } - - public Map getSection(final String name) { - return this.sections.get(name.toLowerCase()); - } -} diff --git a/core/src/com/etheller/warsmash/util/Interpolator.java b/core/src/com/etheller/warsmash/util/Interpolator.java deleted file mode 100644 index ab6dd42c..00000000 --- a/core/src/com/etheller/warsmash/util/Interpolator.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.etheller.warsmash.util; - -public class Interpolator { - public static void interpolateScalar(final float[] out, final float[] a, final float[] b, final float[] c, - final float[] d, final float t, final int type) { - switch (type) { - case 0: { - out[0] = a[0]; - break; - } - case 1: { - out[0] = RenderMathUtils.lerp(a[0], d[0], t); - break; - } - case 2: { - out[0] = RenderMathUtils.hermite(a[0], b[0], c[0], d[0], t); - break; - } - case 3: { - out[0] = RenderMathUtils.bezier(a[0], b[0], c[0], d[0], t); - break; - } - } - } - - public static void interpolateVector(final float[] out, final float[] a, final float[] b, final float[] c, - final float[] d, final float t, final int type) { - switch (type) { - case 0: { - System.arraycopy(a, 0, out, 0, a.length); - break; - } - case 1: { - out[0] = RenderMathUtils.lerp(a[0], d[0], t); - out[1] = RenderMathUtils.lerp(a[1], d[1], t); - out[2] = RenderMathUtils.lerp(a[2], d[2], t); - break; - } - case 2: { - out[0] = RenderMathUtils.hermite(a[0], b[0], c[0], d[0], t); - out[1] = RenderMathUtils.hermite(a[1], b[1], c[1], d[1], t); - out[2] = RenderMathUtils.hermite(a[2], b[2], c[2], d[2], t); - break; - } - case 3: { - out[0] = RenderMathUtils.bezier(a[0], b[0], c[0], d[0], t); - out[1] = RenderMathUtils.bezier(a[1], b[1], c[1], d[1], t); - out[2] = RenderMathUtils.bezier(a[2], b[2], c[2], d[2], t); - break; - } - } - } - - public static void interpolateQuaternion(final float[] out, final float[] a, final float[] b, final float[] c, - final float[] d, final float t, final int type) { - switch (type) { - case 0: { - System.arraycopy(a, 0, out, 0, a.length); - break; - } - case 1: { - RenderMathUtils.slerp(out, a, d, t); - break; - } - case 2: - case 3: { - RenderMathUtils.sqlerp(out, a, b, c, d, t); - break; - } - } - } -} diff --git a/core/src/com/etheller/warsmash/util/MappedData.java b/core/src/com/etheller/warsmash/util/MappedData.java deleted file mode 100644 index ed927697..00000000 --- a/core/src/com/etheller/warsmash/util/MappedData.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.etheller.warsmash.util; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * A structure that holds mapped data from INI and SLK files. - * - * In the case of SLK files, the first row is expected to hold the names of the - * columns. - */ -public class MappedData { - private final Map map = new HashMap<>(); - - public MappedData() { - this(null); - } - - public MappedData(final String buffer) { - if (buffer != null) { - this.load(buffer); - } - } - - /** - * Load data from an SLK file or an INI file. - * - * Note that this may override previous properties! - */ - public void load(final String buffer) { - if (buffer.startsWith("ID;")) { - final SlkFile file = new SlkFile(buffer); - final List> rows = file.rows; - final List header = rows.get(0); - - for (int i = 1, l = rows.size(); i < l; i++) { - final List row = rows.get(i); - if (row != null) { - String name = (String) row.get(0); - - if (name != null) { - name = name.toLowerCase(); - - if (!this.map.containsKey(name)) { - this.map.put(name, new MappedDataRow()); - } - - final MappedDataRow mapped = this.map.get(name); - - for (int j = 0, k = header.size(); j < k; j++) { - final Object headerObj = header.get(j); - String key = headerObj == null ? null : headerObj.toString(); - - // UnitBalance.slk doesn't define the name of one row. - if (key == null) { - key = "column" + j; - } - - mapped.put(key, j < row.size() ? row.get(j) : null); - } - } - } - } - } - else { - final IniFile file = new IniFile(buffer); - final Map> sections = file.sections; - - for (final Map.Entry> rowAndProperties : sections.entrySet()) { - final String row = rowAndProperties.getKey(); - - if (!this.map.containsKey(row)) { - this.map.put(row, new MappedDataRow()); - } - - final MappedDataRow mapped = this.map.get(row); - - for (final Map.Entry nameAndProperty : rowAndProperties.getValue().entrySet()) { - mapped.put(nameAndProperty.getKey(), nameAndProperty.getValue()); - } - } - } - } - - public MappedDataRow getRow(final String key) { - return this.map.get(key.toLowerCase()); - } - - public Object getProperty(final String key, final String name) { - return this.map.get(key.toLowerCase()).get(name); - } - - public void setRow(final String key, final MappedDataRow values) { - this.map.put(key.toLowerCase(), values); - } -} diff --git a/core/src/com/etheller/warsmash/util/MappedDataRow.java b/core/src/com/etheller/warsmash/util/MappedDataRow.java deleted file mode 100644 index f22a20ff..00000000 --- a/core/src/com/etheller/warsmash/util/MappedDataRow.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.etheller.warsmash.util; - -import java.util.HashMap; - -public class MappedDataRow extends HashMap { - -} diff --git a/core/src/com/etheller/warsmash/util/MdlUtils.java b/core/src/com/etheller/warsmash/util/MdlUtils.java deleted file mode 100644 index 3e3623f1..00000000 --- a/core/src/com/etheller/warsmash/util/MdlUtils.java +++ /dev/null @@ -1,198 +0,0 @@ -package com.etheller.warsmash.util; - -/** - * Constants for the tokens were used to prevent typos in token literals. It - * would be very easy for me to type "Interval" in one place and "Intreval" in - * another by mistake. With this paradigm, that mistake causes a compile error, - * since TOKEN_INTREVAL does not exist. - */ -public class MdlUtils { - public static final String TOKEN_VERSION = "Version"; - - public static final String TOKEN_MODEL = "Model"; - - public static final String TOKEN_SEQUENCES = "Sequences"; - - public static final String TOKEN_GLOBAL_SEQUENCES = "GlobalSequences"; - - public static final String TOKEN_INTERVAL = "Interval"; - public static final String TOKEN_NONLOOPING = "NonLooping"; - public static final String TOKEN_MOVESPEED = "MoveSpeed"; - public static final String TOKEN_RARITY = "Rarity"; - - public static final String TOKEN_FORMAT_VERSION = "FormatVersion"; - public static final String TOKEN_BLEND_TIME = "BlendTime"; - public static final String TOKEN_DURATION = "Duration"; - - public static final String TOKEN_IMAGE = "Image"; - public static final String TOKEN_WRAP_WIDTH = "WrapWidth"; - public static final String TOKEN_WRAP_HEIGHT = "WrapHeight"; - public static final String TOKEN_BITMAP = "Bitmap"; - - public static final String TOKEN_TVERTEX_ANIM_SPACE = "TVertexAnim "; - public static final String TOKEN_TVERTEX_ANIM = "TVertexAnim"; - - public static final String TOKEN_DONT_INTERP = "DontInterp"; - public static final String TOKEN_LINEAR = "Linear"; - public static final String TOKEN_HERMITE = "Hermite"; - public static final String TOKEN_BEZIER = "Bezier"; - public static final String TOKEN_GLOBAL_SEQ_ID = "GlobalSeqId"; - - public static final String TOKEN_PLANE = "Plane"; - public static final String TOKEN_BOX = "Box"; - public static final String TOKEN_SPHERE = "Sphere"; - public static final String TOKEN_CYLINDER = "Cylinder"; - - public static final String TOKEN_GEOSETID = "GeosetId"; - public static final String TOKEN_MULTIPLE = "Multiple"; - public static final String TOKEN_GEOSETANIMID = "GeosetAnimId"; - public static final String TOKEN_NONE = "None"; - public static final String TOKEN_OBJECTID = "ObjectId"; - public static final String TOKEN_PARENT = "Parent"; - public static final String TOKEN_BILLBOARDED_LOCK_Z = "BillboardedLockZ"; - public static final String TOKEN_BILLBOARDED_LOCK_Y = "BillboardedLockY"; - public static final String TOKEN_BILLBOARDED_LOCK_X = "BillboardedLockX"; - public static final String TOKEN_BILLBOARDED = "Billboarded"; - public static final String TOKEN_CAMERA_ANCHORED = "CameraAnchored"; - public static final String TOKEN_DONT_INHERIT = "DontInherit"; - public static final String TOKEN_ROTATION = "Rotation"; - public static final String TOKEN_TRANSLATION = "Translation"; - public static final String TOKEN_SCALING = "Scaling"; - public static final String TOKEN_STATIC = "static"; - public static final String TOKEN_ATTACHMENT_ID = "AttachmentID"; - public static final String TOKEN_PATH = "Path"; - public static final String TOKEN_VISIBILITY = "Visibility"; - public static final String TOKEN_POSITION = "Position"; - public static final String TOKEN_FIELDOFVIEW = "FieldOfView"; - public static final String TOKEN_FARCLIP = "FarClip"; - public static final String TOKEN_NEARCLIP = "NearClip"; - public static final String TOKEN_TARGET = "Target"; - public static final String TOKEN_VERTICES = "Vertices"; - public static final String TOKEN_BOUNDSRADIUS = "BoundsRadius"; - public static final String TOKEN_EVENT_TRACK = "EventTrack"; - public static final String TOKEN_MAXIMUM_EXTENT = "MaximumExtent"; - public static final String TOKEN_MINIMUM_EXTENT = "MinimumExtent"; - public static final String TOKEN_NORMALS = "Normals"; - public static final String TOKEN_TVERTICES = "TVertices"; - public static final String TOKEN_VERTEX_GROUP = "VertexGroup"; - public static final String TOKEN_FACES = "Faces"; - public static final String TOKEN_GROUPS = "Groups"; - public static final String TOKEN_ANIM = "Anim"; - public static final String TOKEN_MATERIAL_ID = "MaterialID"; - public static final String TOKEN_SELECTION_GROUP = "SelectionGroup"; - public static final String TOKEN_UNSELECTABLE = "Unselectable"; - public static final String TOKEN_TRIANGLES = "Triangles"; - public static final String TOKEN_MATRICES = "Matrices"; - public static final String TOKEN_DROP_SHADOW = "DropShadow"; - public static final String TOKEN_ALPHA = "Alpha"; - public static final String TOKEN_COLOR = "Color"; - public static final String TOKEN_STATIC_ALPHA = TOKEN_STATIC + " " + TOKEN_ALPHA; - public static final String TOKEN_STATIC_COLOR = TOKEN_STATIC + " " + TOKEN_COLOR; - public static final String TOKEN_FILTER_MODE = "FilterMode"; - public static final String TOKEN_UNSHADED = "Unshaded"; - public static final String TOKEN_SPHERE_ENV_MAP = "SphereEnvMap"; - public static final String TOKEN_TWO_SIDED = "TwoSided"; - public static final String TOKEN_UNFOGGED = "Unfogged"; - public static final String TOKEN_NO_DEPTH_TEST = "NoDepthTest"; - public static final String TOKEN_NO_DEPTH_SET = "NoDepthSet"; - public static final String TOKEN_TEXTURE_ID = "TextureID"; - public static final String TOKEN_STATIC_TEXTURE_ID = TOKEN_STATIC + " " + TOKEN_TEXTURE_ID; - public static final String TOKEN_TVERTEX_ANIM_ID = "TVertexAnimId"; - public static final String TOKEN_COORD_ID = "CoordId"; - - public static final String TOKEN_OMNIDIRECTIONAL = "Omnidirectional"; - public static final String TOKEN_DIRECTIONAL = "Directional"; - public static final String TOKEN_AMBIENT = "Ambient"; - public static final String TOKEN_ATTENUATION_START = "AttenuationStart"; - public static final String TOKEN_STATIC_ATTENUATION_START = TOKEN_STATIC + " " + TOKEN_ATTENUATION_START; - public static final String TOKEN_ATTENUATION_END = "AttenuationEnd"; - public static final String TOKEN_STATIC_ATTENUATION_END = TOKEN_STATIC + " " + TOKEN_ATTENUATION_END; - public static final String TOKEN_INTENSITY = "Intensity"; - public static final String TOKEN_STATIC_INTENSITY = TOKEN_STATIC + " " + TOKEN_INTENSITY; - public static final String TOKEN_AMB_INTENSITY = "AmbIntensity"; - public static final String TOKEN_STATIC_AMB_INTENSITY = TOKEN_STATIC + " " + TOKEN_AMB_INTENSITY; - public static final String TOKEN_AMB_COLOR = "AmbColor"; - public static final String TOKEN_STATIC_AMB_COLOR = TOKEN_STATIC + " " + TOKEN_AMB_COLOR; - - public static final String TOKEN_CONSTANT_COLOR = "ConstantColor"; - public static final String TOKEN_SORT_PRIMS_NEAR_Z = "SortPrimsNearZ"; - public static final String TOKEN_SORT_PRIMS_FAR_Z = "SortPrimsFarZ"; - public static final String TOKEN_FULL_RESOLUTION = "FullResolution"; - public static final String TOKEN_PRIORITY_PLANE = "PriorityPlane"; - - public static final String TOKEN_EMITTER_USES_MDL = "EmitterUsesMDL"; - public static final String TOKEN_EMITTER_USES_TGA = "EmitterUsesTGA"; - public static final String TOKEN_EMISSION_RATE = "EmissionRate"; - public static final String TOKEN_STATIC_EMISSION_RATE = TOKEN_STATIC + " " + TOKEN_EMISSION_RATE; - public static final String TOKEN_GRAVITY = "Gravity"; - public static final String TOKEN_STATIC_GRAVITY = TOKEN_STATIC + " " + TOKEN_GRAVITY; - public static final String TOKEN_LONGITUDE = "Longitude"; - public static final String TOKEN_STATIC_LONGITUDE = TOKEN_STATIC + " " + TOKEN_LONGITUDE; - public static final String TOKEN_LATITUDE = "Latitude"; - public static final String TOKEN_STATIC_LATITUDE = TOKEN_STATIC + " " + TOKEN_LATITUDE; - public static final String TOKEN_PARTICLE = "Particle"; - public static final String TOKEN_LIFE_SPAN = "LifeSpan"; - public static final String TOKEN_STATIC_LIFE_SPAN = TOKEN_STATIC + " " + TOKEN_LIFE_SPAN; - public static final String TOKEN_INIT_VELOCITY = "InitVelocity"; - public static final String TOKEN_STATIC_INIT_VELOCITY = TOKEN_STATIC + " " + TOKEN_INIT_VELOCITY; - - public static final String TOKEN_LINE_EMITTER = "LineEmitter"; - public static final String TOKEN_MODEL_SPACE = "ModelSpace"; - public static final String TOKEN_XY_QUAD = "XYQuad"; - public static final String TOKEN_SPEED = "Speed"; - public static final String TOKEN_STATIC_SPEED = TOKEN_STATIC + " " + TOKEN_SPEED; - public static final String TOKEN_VARIATION = "Variation"; - public static final String TOKEN_STATIC_VARIATION = TOKEN_STATIC + " " + TOKEN_VARIATION; - public static final String TOKEN_SQUIRT = "Squirt"; - public static final String TOKEN_WIDTH = "Width"; - public static final String TOKEN_STATIC_WIDTH = TOKEN_STATIC + " " + TOKEN_WIDTH; - public static final String TOKEN_LENGTH = "Length"; - public static final String TOKEN_STATIC_LENGTH = TOKEN_STATIC + " " + TOKEN_LENGTH; - public static final String TOKEN_ROWS = "Rows"; - public static final String TOKEN_COLUMNS = "Columns"; - public static final String TOKEN_HEAD = "Head"; - public static final String TOKEN_TAIL = "Tail"; - public static final String TOKEN_BOTH = "Both"; - public static final String TOKEN_TAIL_LENGTH = "TailLength"; - public static final String TOKEN_TIME = "Time"; - public static final String TOKEN_SEGMENT_COLOR = "SegmentColor"; - public static final String TOKEN_PARTICLE_SCALING = "ParticleScaling"; - public static final String TOKEN_LIFE_SPAN_UV_ANIM = "LifeSpanUVAnim"; - public static final String TOKEN_DECAY_UV_ANIM = "DecayUVAnim"; - public static final String TOKEN_TAIL_UV_ANIM = "TailUVAnim"; - public static final String TOKEN_TAIL_DECAY_UV_ANIM = "TailDecayUVAnim"; - public static final String TOKEN_REPLACEABLE_ID = "ReplaceableId"; - public static final String TOKEN_BLEND = "Blend";// ParticleEmitter2.FilterMode.BLEND.getMdlText(); - public static final String TOKEN_ADDITIVE = "Additive";// ParticleEmitter2.FilterMode.ADDITIVE.getMdlText(); - public static final String TOKEN_MODULATE = "Modulate";// ParticleEmitter2.FilterMode.MODULATE.getMdlText(); - public static final String TOKEN_MODULATE2X = "Modulate2x";// ParticleEmitter2.FilterMode.MODULATE2X.getMdlText(); - public static final String TOKEN_ALPHAKEY = "AlphaKey";// ParticleEmitter2.FilterMode.ALPHAKEY.getMdlText(); - - public static final String TOKEN_HEIGHT_ABOVE = "HeightAbove"; - public static final String TOKEN_STATIC_HEIGHT_ABOVE = TOKEN_STATIC + " " + TOKEN_HEIGHT_ABOVE; - public static final String TOKEN_HEIGHT_BELOW = "HeightBelow"; - public static final String TOKEN_STATIC_HEIGHT_BELOW = TOKEN_STATIC + " " + TOKEN_HEIGHT_BELOW; - public static final String TOKEN_TEXTURE_SLOT = "TextureSlot"; - public static final String TOKEN_STATIC_TEXTURE_SLOT = TOKEN_STATIC + " " + TOKEN_TEXTURE_SLOT; - - public static final String TOKEN_TEXTURES = "Textures"; - public static final String TOKEN_MATERIALS = "Materials"; - public static final String TOKEN_TEXTURE_ANIMS = "TextureAnims"; - public static final String TOKEN_PIVOT_POINTS = "PivotPoints"; - - public static final String TOKEN_ATTACHMENT = "Attachment"; - public static final String TOKEN_BONE = "Bone"; - public static final String TOKEN_CAMERA = "Camera"; - public static final String TOKEN_COLLISION_SHAPE = "CollisionShape"; - public static final String TOKEN_EVENT_OBJECT = "EventObject"; - public static final String TOKEN_GEOSET = "Geoset"; - public static final String TOKEN_GEOSETANIM = "GeosetAnim"; - public static final String TOKEN_HELPER = "Helper"; - public static final String TOKEN_LAYER = "Layer"; - public static final String TOKEN_LIGHT = "Light"; - public static final String TOKEN_MATERIAL = "Material"; - public static final String TOKEN_PARTICLE_EMITTER = "ParticleEmitter"; - public static final String TOKEN_PARTICLE_EMITTER2 = "ParticleEmitter2"; - public static final String TOKEN_RIBBON_EMITTER = "RibbonEmitter"; - -} diff --git a/core/src/com/etheller/warsmash/util/ParseUtils.java b/core/src/com/etheller/warsmash/util/ParseUtils.java deleted file mode 100644 index 89737fd1..00000000 --- a/core/src/com/etheller/warsmash/util/ParseUtils.java +++ /dev/null @@ -1,189 +0,0 @@ -package com.etheller.warsmash.util; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.charset.Charset; - -import com.google.common.io.LittleEndianDataInputStream; -import com.google.common.io.LittleEndianDataOutputStream; - -public class ParseUtils { - public static final Charset UTF8 = Charset.forName("utf-8"); - - public static long readUInt32(final LittleEndianDataInputStream stream) throws IOException { - return stream.readInt() & 0xFFFFFFFFL; - } - - public static int readUInt16(final LittleEndianDataInputStream stream) throws IOException { - return stream.readShort() & 0xFFFF; - } - - public static short readUInt8(final LittleEndianDataInputStream stream) throws IOException { - return (short) (stream.readByte() & (short) 0xFF); - } - - public static void readFloatArray(final LittleEndianDataInputStream stream, final float[] array) - throws IOException { - for (int i = 0; i < array.length; i++) { - array[i] = stream.readFloat(); - } - } - - public static float[] readFloatArray(final LittleEndianDataInputStream stream, final int length) - throws IOException { - final float[] array = new float[length]; - readFloatArray(stream, array); - return array; - } - - public static void readUInt32Array(final LittleEndianDataInputStream stream, final long[] array) - throws IOException { - for (int i = 0; i < array.length; i++) { - array[i] = readUInt32(stream); - } - } - - public static long[] readUInt32Array(final LittleEndianDataInputStream stream, final int length) - throws IOException { - final long[] array = new long[length]; - readUInt32Array(stream, array); - return array; - } - - public static void readInt32Array(final LittleEndianDataInputStream stream, final int[] array) throws IOException { - for (int i = 0; i < array.length; i++) { - array[i] = stream.readInt(); - } - } - - public static int[] readInt32Array(final LittleEndianDataInputStream stream, final int length) throws IOException { - final int[] array = new int[length]; - readInt32Array(stream, array); - return array; - } - - public static void readUInt16Array(final LittleEndianDataInputStream stream, final int[] array) throws IOException { - for (int i = 0; i < array.length; i++) { - array[i] = readUInt16(stream); - } - } - - public static int[] readUInt16Array(final LittleEndianDataInputStream stream, final int length) throws IOException { - final int[] array = new int[length]; - readUInt16Array(stream, array); - return array; - } - - public static void readUInt8Array(final LittleEndianDataInputStream stream, final short[] array) - throws IOException { - for (int i = 0; i < array.length; i++) { - array[i] = readUInt8(stream); - } - } - - public static short[] readUInt8Array(final LittleEndianDataInputStream stream, final int length) - throws IOException { - final short[] array = new short[length]; - readUInt8Array(stream, array); - return array; - } - - public static War3ID readWar3ID(final LittleEndianDataInputStream stream) throws IOException { -// final int value = stream.readInt(); -// return new War3ID(((value & 0xFF000000) >>> 24) | ((value & 0x00FF0000) >>> 8) | ((value & 0x0000FF00) << 8) -// | ((value & 0x000000FF) << 24)); - return new War3ID(Integer.reverseBytes(stream.readInt())); - } - - public static void writeWar3ID(final LittleEndianDataOutputStream stream, final War3ID id) throws IOException { -// final int value = id.getValue(); -// stream.writeInt(((value & 0xFF000000) >>> 24) | ((value & 0x00FF0000) >>> 8) | ((value & 0x0000FF00) << 8) -// | ((value & 0x000000FF) << 24)); - stream.writeInt(Integer.reverseBytes(id.getValue())); - } - - public static void writeFloatArray(final LittleEndianDataOutputStream stream, final float[] array) - throws IOException { - for (int i = 0; i < array.length; i++) { - stream.writeFloat(array[i]); - } - } - - public static void writeUInt32(final LittleEndianDataOutputStream stream, final long uInt) throws IOException { - stream.writeInt((int) (uInt & 0xFFFFFFFF)); - } - - public static void writeUInt16(final LittleEndianDataOutputStream stream, final int uInt) throws IOException { - stream.writeShort((short) (uInt & 0xFFFF)); - } - - public static void writeUInt8(final LittleEndianDataOutputStream stream, final short uInt) throws IOException { - stream.writeByte((byte) (uInt & 0xFF)); - } - - public static void writeUInt32Array(final LittleEndianDataOutputStream stream, final long[] array) - throws IOException { - for (int i = 0; i < array.length; i++) { - writeUInt32(stream, array[i]); - } - } - - public static void writeInt32Array(final LittleEndianDataOutputStream stream, final int[] array) - throws IOException { - for (int i = 0; i < array.length; i++) { - stream.writeInt(array[i]); - } - } - - public static void writeUInt16Array(final LittleEndianDataOutputStream stream, final int[] array) - throws IOException { - for (int i = 0; i < array.length; i++) { - writeUInt16(stream, array[i]); - } - } - - public static void writeUInt8Array(final LittleEndianDataOutputStream stream, final short[] array) - throws IOException { - for (int i = 0; i < array.length; i++) { - writeUInt8(stream, array[i]); - } - } - - public static String readString(final LittleEndianDataInputStream stream, final byte[] recycleByteArray) - throws IOException { - stream.read(recycleByteArray); - int i; - for (i = 0; (i < recycleByteArray.length) && (recycleByteArray[i] != 0); i++) { - } - final String name = new String(recycleByteArray, 0, i, ParseUtils.UTF8); - return name; - } - - public static String readUntilNull(final LittleEndianDataInputStream stream) throws IOException { - - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int c; - while (((c = stream.read()) != 0) && (c != -1)) { - baos.write(c); - } - return new String(baos.toByteArray(), ParseUtils.UTF8); - } - - public static void writeWithNullTerminator(final LittleEndianDataOutputStream stream, final String name) - throws IOException { - final byte[] nameBytes = name.getBytes(ParseUtils.UTF8); - stream.write(nameBytes); - stream.write(0); - } - - public static float[] flipRGB(final float[] color) { - final float r = color[0]; - color[0] = color[2]; - color[2] = r; - return color; - } - - public static float[] newFlippedRGB(final float[] color) { - return new float[] { color[2], color[1], color[0] }; - } -} diff --git a/core/src/com/etheller/warsmash/util/Quadtree.java b/core/src/com/etheller/warsmash/util/Quadtree.java deleted file mode 100644 index 81a93082..00000000 --- a/core/src/com/etheller/warsmash/util/Quadtree.java +++ /dev/null @@ -1,253 +0,0 @@ -package com.etheller.warsmash.util; - -import java.util.function.Consumer; - -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.utils.Array; - -public class Quadtree { - private static final int MAX_DEPTH = 9; // 2^9 = 512, and 512 is the biggest map size... - private static final int SPLIT_THRESHOLD = 6; - - private final Rectangle bounds; - private Quadtree northeast; - private Quadtree northwest; - private Quadtree southwest; - private Quadtree southeast; - private final Array> nodes = new Array<>(); - private boolean leaf = true; - private final NodeAdder nodeAdder = new NodeAdder(); - private final UniqueNodeAdder uniqueNodeAdder = new UniqueNodeAdder(); - - public Quadtree(final Rectangle bounds) { - this.bounds = bounds; - } - - public void add(final T object, final Rectangle bounds) { - final Node node = new Node(object, bounds); - add(node, 0); - } - - public void remove(final T object, final Rectangle bounds) { - remove(object, bounds, null); - } - - public void translate(final T object, final Rectangle prevBoundsToUpdate, final float xShift, final float yShift) { - final Node node = remove(object, prevBoundsToUpdate, null); - prevBoundsToUpdate.x += xShift; - prevBoundsToUpdate.y += yShift; - add(node, 0); - } - - public boolean intersect(final Rectangle bounds, final QuadtreeIntersector intersector) { - if (this.leaf) { - for (int i = 0; i < this.nodes.size; i++) { - final Node node = this.nodes.get(i); - if (node.bounds.overlaps(bounds)) { - if (intersector.onIntersect(node.object)) { - return true; - } - } - } - return false; - } - else { - if (this.northeast.bounds.overlaps(bounds)) { - if (this.northeast.intersect(bounds, intersector)) { - return true; - } - } - if (this.northwest.bounds.overlaps(bounds)) { - if (this.northwest.intersect(bounds, intersector)) { - return true; - } - } - if (this.southwest.bounds.overlaps(bounds)) { - if (this.southwest.intersect(bounds, intersector)) { - return true; - } - } - if (this.southeast.bounds.overlaps(bounds)) { - if (this.southeast.intersect(bounds, intersector)) { - return true; - } - } - return false; - } - } - - public boolean intersect(final float x, final float y, final QuadtreeIntersector intersector) { - if (this.leaf) { - for (int i = 0; i < this.nodes.size; i++) { - final Node node = this.nodes.get(i); - if (node.bounds.contains(x, y)) { - if (intersector.onIntersect(node.object)) { - return true; - } - } - } - return false; - } - else { - if (this.northeast.bounds.contains(x, y)) { - if (this.northeast.intersect(x, y, intersector)) { - return true; - } - } - if (this.northwest.bounds.contains(x, y)) { - if (this.northwest.intersect(x, y, intersector)) { - return true; - } - } - if (this.southwest.bounds.contains(x, y)) { - if (this.southwest.intersect(x, y, intersector)) { - return true; - } - } - if (this.southeast.bounds.contains(x, y)) { - if (this.southeast.intersect(x, y, intersector)) { - return true; - } - } - return false; - } - } - - private void add(final Node node, final int depth) { - if (this.leaf) { - if ((this.nodes.size >= SPLIT_THRESHOLD) && (depth < MAX_DEPTH)) { - split(depth); - // then dont return and add as a nonleaf - } - else { - this.nodes.add(node); - return; - } - } - boolean overlapsAny = false; - if (this.northeast.bounds.overlaps(node.bounds)) { - this.northeast.add(node, depth + 1); - overlapsAny = true; - } - if (this.northwest.bounds.overlaps(node.bounds)) { - this.northwest.add(node, depth + 1); - overlapsAny = true; - } - if (this.southwest.bounds.overlaps(node.bounds)) { - this.southwest.add(node, depth + 1); - overlapsAny = true; - } - if (this.southeast.bounds.overlaps(node.bounds)) { - this.southeast.add(node, depth + 1); - overlapsAny = true; - } - if (!overlapsAny) { - throw new IllegalStateException("Does not overlap anything!"); - } - } - - private void split(final int depth) { - final int splitDepth = depth + 1; - final float halfWidth = this.bounds.width / 2; - final float x = this.bounds.x; - final float xMidpoint = x + halfWidth; - final float halfHeight = this.bounds.height / 2; - final float y = this.bounds.y; - final float yMidpoint = y + halfHeight; - this.northeast = new Quadtree<>(new Rectangle(xMidpoint, yMidpoint, halfWidth, halfHeight)); - this.northwest = new Quadtree<>(new Rectangle(x, yMidpoint, halfWidth, halfHeight)); - this.southwest = new Quadtree<>(new Rectangle(x, y, halfWidth, halfHeight)); - this.southeast = new Quadtree<>(new Rectangle(xMidpoint, y, halfWidth, halfHeight)); - this.leaf = false; - this.nodes.forEach(this.nodeAdder.reset(splitDepth)); - this.nodes.clear(); - } - - private Node remove(final T object, final Rectangle bounds, final Quadtree parent) { - Node returnValue = null; - if (this.leaf) { - for (int i = 0; i < this.nodes.size; i++) { - if (this.nodes.get(i).object == object) { - returnValue = this.nodes.removeIndex(i); - break; - } - } - } - else { - if (this.northeast.bounds.overlaps(bounds)) { - returnValue = this.northeast.remove(object, bounds, this); - } - if (this.northwest.bounds.overlaps(bounds)) { - returnValue = this.northwest.remove(object, bounds, this); - } - if (this.southwest.bounds.overlaps(bounds)) { - returnValue = this.southwest.remove(object, bounds, this); - } - if (this.southeast.bounds.overlaps(bounds)) { - returnValue = this.southeast.remove(object, bounds, this); - } - mergeIfNecessary(); - } - return returnValue; - } - - private void mergeIfNecessary() { - if (this.northeast.leaf && this.northwest.leaf && this.southwest.leaf && this.southeast.leaf) { - final int children = this.northeast.nodes.size + this.northwest.nodes.size + this.southwest.nodes.size - + this.southeast.nodes.size; // might include duplicates - if (children <= SPLIT_THRESHOLD) { - this.leaf = true; - addAllUnique(this.northeast.nodes); - addAllUnique(this.northwest.nodes); - addAllUnique(this.southwest.nodes); - addAllUnique(this.southeast.nodes); - this.northeast = this.northwest = this.southwest = this.southeast = null; - } - } - } - - private void addAllUnique(final Array> nodes) { - nodes.forEach(this.uniqueNodeAdder); - } - - private static final class Node { - private final T object; - private final Rectangle bounds; - - public Node(final T object, final Rectangle bounds) { - this.object = object; - this.bounds = bounds; - } - } - - private final class NodeAdder implements Consumer> { - private int splitDepth; - - private NodeAdder reset(final int splitDepth) { - this.splitDepth = splitDepth; - return this; - } - - @Override - public void accept(final Node node) { - add(node, this.splitDepth); - } - } - - private final class UniqueNodeAdder implements Consumer> { - - private UniqueNodeAdder reset() { - return this; - } - - @Override - public void accept(final Node node) { - for (int i = 0; i < Quadtree.this.nodes.size; i++) { - if (Quadtree.this.nodes.get(i) == node) { - return; - } - } - Quadtree.this.nodes.add(node); - } - } -} diff --git a/core/src/com/etheller/warsmash/util/QuadtreeIntersector.java b/core/src/com/etheller/warsmash/util/QuadtreeIntersector.java deleted file mode 100644 index fa7a8904..00000000 --- a/core/src/com/etheller/warsmash/util/QuadtreeIntersector.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.util; - -public interface QuadtreeIntersector { - /** - * Handles what to do when the intersector finds an intersecting object, - * returning true if we should stop the intersection test and process no more - * objects. - * - * @param intersectingObject - * @return - */ - boolean onIntersect(T intersectingObject); -} diff --git a/core/src/com/etheller/warsmash/util/RawcodeUtils.java b/core/src/com/etheller/warsmash/util/RawcodeUtils.java deleted file mode 100644 index 4a856385..00000000 --- a/core/src/com/etheller/warsmash/util/RawcodeUtils.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.etheller.warsmash.util; - -import java.nio.charset.StandardCharsets; - -public final class RawcodeUtils { - private RawcodeUtils() { - } - - /** - * Convert a four character string into an integer.
- * Do not use characters outside the ASCII character set. - * - * @param id the string to convert - * @return integer representation of the string. - */ - public final static int toInt(final String id) { - final byte[] bytes = id.getBytes(StandardCharsets.US_ASCII); - int result = 0; - if (bytes.length >= 4) { - result |= (bytes[3] << 0) & 0x000000FF; - result |= (bytes[2] << 8) & 0x0000FF00; - result |= (bytes[1] << 16) & 0x00FF0000; - result |= (bytes[0] << 24) & 0xFF000000; - } - else { - for (int i = 0; i < bytes.length; i++) { - result |= (bytes[i] << (24 - (i << 3))); - } - } - - return result; - } - - /** - * Convert an integer into a four character string. - * - * @param id the integer to convert - * @return four character string representing the integer. - */ - public final static String toString(final int id) { - final StringBuffer result = new StringBuffer(4); - - return toString(id, result); - } - - /** - * Convert an integer into a four character string using an existing - * StringBuffer. - * - * @param id - * @param result - * @return - */ - public static String toString(final int id, final StringBuffer result) { - result.append((char) ((id >> 24) & 0xFF)); - result.append((char) ((id >> 16) & 0xFF)); - result.append((char) ((id >> 8) & 0xFF)); - result.append((char) ((id >> 0) & 0xFF)); - - return result.toString(); - } -} diff --git a/core/src/com/etheller/warsmash/util/RenderMathUtils.java b/core/src/com/etheller/warsmash/util/RenderMathUtils.java deleted file mode 100644 index f5a39412..00000000 --- a/core/src/com/etheller/warsmash/util/RenderMathUtils.java +++ /dev/null @@ -1,699 +0,0 @@ -package com.etheller.warsmash.util; - -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.nio.ShortBuffer; -import java.util.List; - -import com.badlogic.gdx.math.Intersector; -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Quaternion; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.math.collision.Ray; - -public enum RenderMathUtils { - ; - public static final float[] EMPTY_FLOAT_ARRAY = new float[0]; - public static final long[] EMPTY_LONG_ARRAY = new long[0]; - public static final Quaternion QUAT_DEFAULT = new Quaternion(0, 0, 0, 1); - public static final Vector3 VEC3_ONE = new Vector3(1, 1, 1); - public static final Vector3 VEC3_UNIT_X = new Vector3(1, 0, 0); - public static final Vector3 VEC3_UNIT_Y = new Vector3(0, 1, 0); - public static final Vector3 VEC3_UNIT_Z = new Vector3(0, 0, 1); - public static final float[] FLOAT_VEC3_ZERO = new float[] { 0, 0, 0 }; - public static final float[] FLOAT_QUAT_DEFAULT = new float[] { 0, 0, 0, 1 }; - public static final float[] FLOAT_VEC3_ONE = new float[] { 1, 1, 1 }; - public static final float HALF_PI = (float) (Math.PI / 2.0); - - // copied from ghostwolf and - // https://www.blend4web.com/api_doc/libs_gl-matrix2.js.html - public static void fromRotationTranslationScaleOrigin(final Quaternion q, final Vector3 v, final Vector3 s, - final Matrix4 out, final Vector3 pivot) { - final float x = q.x; - final float y = q.y; - final float z = q.z; - final float w = q.w; - final float x2 = x + x; - final float y2 = y + y; - final float z2 = z + z; - final float xx = x * x2; - final float xy = x * y2; - final float xz = x * z2; - final float yy = y * y2; - final float yz = y * z2; - final float zz = z * z2; - final float wx = w * x2; - final float wy = w * y2; - final float wz = w * z2; - final float sx = s.x; - final float sy = s.y; - final float sz = s.z; - out.val[Matrix4.M00] = (1 - (yy + zz)) * sx; - out.val[Matrix4.M10] = (xy + wz) * sx; - out.val[Matrix4.M20] = (xz - wy) * sx; - out.val[Matrix4.M30] = 0; - out.val[Matrix4.M01] = (xy - wz) * sy; - out.val[Matrix4.M11] = (1 - (xx + zz)) * sy; - out.val[Matrix4.M21] = (yz + wx) * sy; - out.val[Matrix4.M31] = 0; - out.val[Matrix4.M02] = (xz + wy) * sz; - out.val[Matrix4.M12] = (yz - wx) * sz; - out.val[Matrix4.M22] = (1 - (xx + yy)) * sz; - out.val[Matrix4.M32] = 0; - out.val[Matrix4.M03] = (v.x + pivot.x) - ((out.val[Matrix4.M00] * pivot.x) + (out.val[Matrix4.M01] * pivot.y) - + (out.val[Matrix4.M02] * pivot.z)); - out.val[Matrix4.M13] = (v.y + pivot.y) - ((out.val[Matrix4.M10] * pivot.x) + (out.val[Matrix4.M11] * pivot.y) - + (out.val[Matrix4.M12] * pivot.z)); - out.val[Matrix4.M23] = (v.z + pivot.z) - ((out.val[Matrix4.M20] * pivot.x) + (out.val[Matrix4.M21] * pivot.y) - + (out.val[Matrix4.M22] * pivot.z)); - out.val[Matrix4.M33] = 1; - } - - // copied from - // https://www.blend4web.com/api_doc/libs_gl-matrix2.js.html - public static void fromRotationTranslationScale(final Quaternion q, final Vector3 v, final Vector3 s, - final Matrix4 out) { - final float x = q.x; - final float y = q.y; - final float z = q.z; - final float w = q.w; - final float x2 = x + x; - final float y2 = y + y; - final float z2 = z + z; - final float xx = x * x2; - final float xy = x * y2; - final float xz = x * z2; - final float yy = y * y2; - final float yz = y * z2; - final float zz = z * z2; - final float wx = w * x2; - final float wy = w * y2; - final float wz = w * z2; - final float sx = s.x; - final float sy = s.y; - final float sz = s.z; - out.val[Matrix4.M00] = (1 - (yy + zz)) * sx; - out.val[Matrix4.M10] = (xy + wz) * sx; - out.val[Matrix4.M20] = (xz - wy) * sx; - out.val[Matrix4.M30] = 0; - out.val[Matrix4.M01] = (xy - wz) * sy; - out.val[Matrix4.M11] = (1 - (xx + zz)) * sy; - out.val[Matrix4.M21] = (yz + wx) * sy; - out.val[Matrix4.M31] = 0; - out.val[Matrix4.M02] = (xz + wy) * sz; - out.val[Matrix4.M12] = (yz - wx) * sz; - out.val[Matrix4.M22] = (1 - (xx + yy)) * sz; - out.val[Matrix4.M32] = 0; - out.val[Matrix4.M03] = v.x; - out.val[Matrix4.M13] = v.y; - out.val[Matrix4.M23] = v.z; - out.val[Matrix4.M33] = 1; - } - - public static void mul(final Matrix4 dest, final Matrix4 left, final Matrix4 right) { - dest.set(left); // TODO better performance here, remove the extra - // copying - dest.mul(right); - } - - public static void mul(final Quaternion dest, final Quaternion left, final Quaternion right) { - dest.set(left); // TODO better performance here, remove the extra - // copying - dest.mul(right); - } - - public static Quaternion rotateX(final Quaternion out, final Quaternion a, float rad) { - rad *= 0.5; - - final float ax = a.x, ay = a.y, az = a.z, aw = a.w; - final float bx = (float) Math.sin(rad), bw = (float) Math.cos(rad); - - out.x = (ax * bw) + (aw * bx); - out.y = (ay * bw) + (az * bx); - out.z = (az * bw) - (ay * bx); - out.w = (aw * bw) - (ax * bx); - return out; - } - - public static Quaternion rotateY(final Quaternion out, final Quaternion a, float rad) { - rad *= 0.5; - - final float ax = a.x, ay = a.y, az = a.z, aw = a.w; - final float by = (float) Math.sin(rad), bw = (float) Math.cos(rad); - - out.x = (ax * bw) - (az * by); - out.y = (ay * bw) + (aw * by); - out.z = (az * bw) + (ax * by); - out.w = (aw * bw) - (ay * by); - return out; - } - - public static Quaternion rotateZ(final Quaternion out, final Quaternion a, float rad) { - rad *= 0.5; - - final float ax = a.x, ay = a.y, az = a.z, aw = a.w; - final float bz = (float) Math.sin(rad), bw = (float) Math.cos(rad); - - out.x = (ax * bw) + (ay * bz); - out.y = (ay * bw) - (ax * bz); - out.z = (az * bw) + (aw * bz); - out.w = (aw * bw) - (az * bz); - return out; - } - - public static Matrix4 perspective(final Matrix4 out, final float fovy, final float aspect, final float near, - final float far) { - final float f = 1.0f / (float) Math.tan(fovy / 2), nf; - out.val[Matrix4.M00] = f / aspect; - out.val[Matrix4.M10] = 0; - out.val[Matrix4.M20] = 0; - out.val[Matrix4.M30] = 0; - out.val[Matrix4.M01] = 0; - out.val[Matrix4.M11] = f; - out.val[Matrix4.M21] = 0; - out.val[Matrix4.M31] = 0; - out.val[Matrix4.M02] = 0; - out.val[Matrix4.M12] = 0; - out.val[Matrix4.M32] = -1; - out.val[Matrix4.M03] = 0; - out.val[Matrix4.M13] = 0; - out.val[Matrix4.M33] = 0; - if (!Double.isNaN(far) && !Double.isInfinite(far)) { - nf = 1 / (near - far); - out.val[Matrix4.M22] = (far + near) * nf; - out.val[Matrix4.M23] = (2 * far * near) * nf; - } - else { - out.val[Matrix4.M22] = -1; - out.val[Matrix4.M23] = -2 * near; - } - return out; - } - - public static Matrix4 ortho(final Matrix4 out, final float left, final float right, final float bottom, - final float top, final float near, final float far) { - final float lr = 1 / (left - right); - final float bt = 1 / (bottom - top); - final float nf = 1 / (near - far); - out.val[Matrix4.M00] = -2 * lr; - out.val[Matrix4.M10] = 0; - out.val[Matrix4.M20] = 0; - out.val[Matrix4.M30] = 0; - - out.val[Matrix4.M01] = 0; - out.val[Matrix4.M11] = -2 * bt; - out.val[Matrix4.M21] = 0; - out.val[Matrix4.M31] = 0; - - out.val[Matrix4.M02] = 0; - out.val[Matrix4.M12] = 0; - out.val[Matrix4.M22] = 2 * nf; - out.val[Matrix4.M32] = 0; - - out.val[Matrix4.M03] = (left + right) * lr; - out.val[Matrix4.M13] = (top + bottom) * bt; - out.val[Matrix4.M23] = (far + near) * nf; - out.val[Matrix4.M33] = 1; - return out; - } - - public static void unpackPlanes(final Vector4[] planes, final Matrix4 m) { - final float a00 = m.val[Matrix4.M00], a01 = m.val[Matrix4.M01], a02 = m.val[Matrix4.M02], - a03 = m.val[Matrix4.M03], a10 = m.val[Matrix4.M10], a11 = m.val[Matrix4.M11], a12 = m.val[Matrix4.M12], - a13 = m.val[Matrix4.M13], a20 = m.val[Matrix4.M20], a21 = m.val[Matrix4.M21], a22 = m.val[Matrix4.M22], - a23 = m.val[Matrix4.M23], a30 = m.val[Matrix4.M30], a31 = m.val[Matrix4.M31], a32 = m.val[Matrix4.M32], - a33 = m.val[Matrix4.M33]; - - // Left clipping plane - Vector4 plane = planes[0]; - plane.x = a30 + a00; - plane.y = a31 + a01; - plane.z = a32 + a02; - plane.w = a33 + a03; - - // Right clipping plane - plane = planes[1]; - plane.x = a30 - a00; - plane.y = a31 - a01; - plane.z = a32 - a02; - plane.w = a33 - a03; - - // Top clipping plane - plane = planes[2]; - plane.x = a30 - a10; - plane.y = a31 - a11; - plane.z = a32 - a12; - plane.w = a33 - a13; - - // Bottom clipping plane - plane = planes[3]; - plane.x = a30 + a10; - plane.y = a31 + a11; - plane.z = a32 + a12; - plane.w = a33 + a13; - - // Near clipping plane - plane = planes[4]; - plane.x = a30 + a20; - plane.y = a31 + a21; - plane.z = a32 + a22; - plane.w = a33 + a23; - - // Far clipping plane - plane = planes[5]; - plane.x = a30 - a20; - plane.y = a31 - a21; - plane.z = a32 - a22; - plane.w = a33 - a23; - - normalizePlane(planes[0], planes[0]); - normalizePlane(planes[1], planes[1]); - normalizePlane(planes[2], planes[2]); - normalizePlane(planes[3], planes[3]); - normalizePlane(planes[4], planes[4]); - normalizePlane(planes[5], planes[5]); - } - - public static void normalizePlane(final Vector4 out, final Vector4 plane) { - final float len = Vector3.len(plane.x, plane.y, plane.z); - - out.x = plane.x / len; - out.y = plane.y / len; - out.z = plane.z / len; - out.w = plane.w / len; - } - - public static float distanceToPlane(final Vector4 plane, final Vector3 point) { - return (plane.x * point.x) + (plane.y * point.y) + (plane.z * point.z) + plane.w; - } - - private static final Vector4 heap = new Vector4(); - - public static Vector3 unproject(final Vector3 out, final Vector3 v, final Matrix4 inverseMatrix, - final Rectangle viewport) { - final float x = ((2 * (v.x - viewport.x)) / viewport.width) - 1; - final float y = ((2 * (v.y - viewport.y)) / viewport.height) - 1; - final float z = (2 * v.z) - 1; - - heap.set(x, y, z, 1); - Vector4.transformMat4(heap, heap, inverseMatrix); - out.set(heap.x / heap.w, heap.y / heap.w, heap.z / heap.w); - - return out; - } - - public static int testCell(final List planes, final int left, final int right, final int bottom, - final int top, int first) { - if (first == -1) { - first = 0; - } - - for (int i = 0; i < 6; i++) { - final int index = (first + i) % 6; - final Vector4 plane = planes.get(index); - - if ((distance2Plane2(plane, left, bottom) < 0) && (distance2Plane2(plane, left, top) < 0) - && (distance2Plane2(plane, right, top) < 0) && (distance2Plane2(plane, right, bottom) < 0)) { - return index; - } - } - - return -1; - } - - public static int testCell(final Vector4[] planes, final float left, final float right, final float bottom, - final float top, int first) { - if (first == -1) { - first = 0; - } - - for (int i = 0; i < 6; i++) { - final int index = (first + i) % 6; - final Vector4 plane = planes[index]; - - if ((distance2Plane2(plane, left, bottom) < 0) && (distance2Plane2(plane, left, top) < 0) - && (distance2Plane2(plane, right, top) < 0) && (distance2Plane2(plane, right, bottom) < 0)) { - return index; - } - } - - return -1; - } - - public static float distance2Plane2(final Vector4 plane, final float px, final float py) { - return (plane.x * px) + (plane.y * py) + plane.w; - } - - public static int testSphere(final Vector4[] planes, final float x, final float y, final float z, final float r, - int first) { - if (first == -1) { - first = 0; - } - - for (int i = 0; i < 6; i++) { - final int index = (first + i) % 6; - - if (distanceToPlane3(planes[index], x, y, z) < -r) { - return index; - } - } - - return -1; - } - - public static float distanceToPlane3(final Vector4 plane, final float px, final float py, final float pz) { - return (plane.x * px) + (plane.y * py) + (plane.z * pz) + plane.w; - } - - public static float randomInRange(final float a, final float b) { - return (float) (a + (Math.random() * (b - a))); - } - - public static float clamp(final float x, final float minVal, final float maxVal) { - return Math.min(Math.max(x, minVal), maxVal); - } - - public static float lerp(final float a, final float b, final float t) { - return a + (t * (b - a)); - } - - public static float hermite(final float a, final float b, final float c, final float d, final float t) { - final float factorTimes2 = t * t; - final float factor1 = (factorTimes2 * ((2 * t) - 3)) + 1; - final float factor2 = (factorTimes2 * (t - 2)) + t; - final float factor3 = factorTimes2 * (t - 1); - final float factor4 = factorTimes2 * (3 - (2 * t)); - return (a * factor1) + (b * factor2) + (c * factor3) + (d * factor4); - } - - public static float bezier(final float a, final float b, final float c, final float d, final float t) { - final float invt = 1 - t; - final float factorTimes2 = t * t; - final float inverseFactorTimesTwo = invt * invt; - final float factor1 = inverseFactorTimesTwo * invt; - final float factor2 = 3 * t * inverseFactorTimesTwo; - final float factor3 = 3 * factorTimes2 * invt; - final float factor4 = factorTimes2 * t; - - return (a * factor1) + (b * factor2) + (c * factor3) + (d * factor4); - } - - public static final float EPSILON = 0.000001f; - - public static float[] slerp(final float[] out, final float[] a, final float[] b, final float t) { - final float ax = a[0], ay = a[1], az = a[2], aw = a[3]; - float bx = b[0], by = b[1], bz = b[2], bw = b[3]; - - float omega, cosom, sinom, scale0, scale1; - - // calc cosine - cosom = (ax * bx) + (ay * by) + (az * bz) + (aw * bw); - // adjust signs (if necessary) - if (cosom < 0.0) { - cosom = -cosom; - bx = -bx; - by = -by; - bz = -bz; - bw = -bw; - } - // calculate coefficients - if ((1.0 - cosom) > EPSILON) { - // standard case (slerp) - omega = (float) Math.acos(cosom); - sinom = (float) Math.sin(omega); - scale0 = (float) (Math.sin((1.0 - t) * omega) / sinom); - scale1 = (float) (Math.sin(t * omega) / sinom); - } - else { - // "from" and "to" quaternions are very close - // ... so we can do a linear interpolation - scale0 = 1.0f - t; - scale1 = t; - } - // calculate final values - out[0] = (scale0 * ax) + (scale1 * bx); - out[1] = (scale0 * ay) + (scale1 * by); - out[2] = (scale0 * az) + (scale1 * bz); - out[3] = (scale0 * aw) + (scale1 * bw); - - return out; - } - - private static final float[] sqlerpHeap1 = new float[4]; - private static final float[] sqlerpHeap2 = new float[4]; - - public static float[] sqlerp(final float[] out, final float[] a, final float[] b, final float[] c, final float[] d, - final float t) { - slerp(sqlerpHeap1, a, d, t); - slerp(sqlerpHeap2, b, c, t); - slerp(out, sqlerpHeap1, sqlerpHeap2, 2 * t * (1 - t)); - return out; - } - - static Vector3 best = new Vector3(); - static Vector3 tmp = new Vector3(); - static Vector3 tmp1 = new Vector3(); - static Vector3 tmp2 = new Vector3(); - static Vector3 tmp3 = new Vector3(); - - /** - * Intersects the given ray with list of triangles. Returns the nearest - * intersection point in intersection - * - * @param ray The ray - * @param vertices the vertices - * @param indices the indices, each successive 3 shorts index the 3 - * vertices of a triangle - * @param vertexSize the size of a vertex in floats - * @param intersection The nearest intersection point (optional) - * @return Whether the ray and the triangles intersect. - */ - public static boolean intersectRayTriangles(final Ray ray, final float[] vertices, final int[] indices, - final int vertexSize, final Vector3 intersection) { - float min_dist = Float.MAX_VALUE; - boolean hit = false; - - if ((indices.length % 3) != 0) { - throw new RuntimeException("triangle list size is not a multiple of 3"); - } - - for (int i = 0; i < indices.length; i += 3) { - final int i1 = indices[i] * vertexSize; - final int i2 = indices[i + 1] * vertexSize; - final int i3 = indices[i + 2] * vertexSize; - - final boolean result = FixedIntersector.intersectRayTriangle(ray, - tmp1.set(vertices[i1], vertices[i1 + 1], vertices[i1 + 2]), - tmp2.set(vertices[i2], vertices[i2 + 1], vertices[i2 + 2]), - tmp3.set(vertices[i3], vertices[i3 + 1], vertices[i3 + 2]), tmp); - - if (result == true) { - final float dist = ray.origin.dst2(tmp); - if (dist < min_dist) { - min_dist = dist; - best.set(tmp); - hit = true; - } - } - } - - if (hit == false) { - return false; - } - else { - if (intersection != null) { - intersection.set(best); - } - return true; - } - } - - /** - * Intersects the given ray with list of triangles. Returns the nearest - * intersection point in intersection - * - * @param ray The ray - * @param vertices the vertices - * @param indices the indices, each successive 3 shorts index the 3 - * vertices of a triangle - * @param vertexSize the size of a vertex in floats - * @param intersection The nearest intersection point (optional) - * @return Whether the ray and the triangles intersect. - */ - public static boolean intersectRayTriangles(final Ray ray, final float[] vertices, final int[] indices, - final int vertexSize, final Vector3 worldLocation, final float facingRadians, final Vector3 intersection) { - float min_dist = Float.MAX_VALUE; - boolean hit = false; - - if ((indices.length % 3) != 0) { - throw new RuntimeException("triangle list size is not a multiple of 3"); - } - - final float facingX_X = (float) Math.cos(facingRadians); - final float facingX_Y = (float) Math.sin(facingRadians); - final double halfPi = Math.PI / 2; - final float facingY_X = (float) Math.cos(facingRadians + halfPi); - final float facingY_Y = (float) Math.sin(facingRadians + halfPi); - for (int i = 0; i < indices.length; i += 3) { - final int i1 = indices[i] * vertexSize; - final int i2 = indices[i + 1] * vertexSize; - final int i3 = indices[i + 2] * vertexSize; - - final boolean result = Intersector.intersectRayTriangle(ray, - tmp1.set((vertices[i1] * facingX_X) + (vertices[i1 + 1] * facingY_X) + worldLocation.x, - (vertices[i1] * facingX_Y) + (vertices[i1 + 1] * facingY_Y) + worldLocation.y, - vertices[i1 + 2] + worldLocation.z), - tmp2.set((vertices[i2] * facingX_X) + (vertices[i2 + 1] * facingY_X) + worldLocation.x, - (vertices[i2] * facingX_Y) + (vertices[i2 + 1] * facingY_Y) + worldLocation.y, - vertices[i2 + 2] + worldLocation.z), - tmp3.set((vertices[i3] * facingX_X) + (vertices[i3 + 1] * facingY_X) + worldLocation.x, - (vertices[i3] * facingX_Y) + (vertices[i3 + 1] * facingY_Y) + worldLocation.y, - vertices[i3 + 2] + worldLocation.z), - tmp); - - if (result == true) { - final float dist = ray.origin.dst2(tmp); - if (dist < min_dist) { - min_dist = dist; - best.set(tmp); - hit = true; - } - } - } - - if (hit == false) { - return false; - } - else { - if (intersection != null) { - intersection.set(best); - } - return true; - } - } - - // ==== All of the following "wrap" calls are horribly inefficient. Eventually - // they should be removed entirely with better design. - // Until that happens, be sure to only call them during setup and not while the - // simulation is live. Otherwise you'll probably get some - // bad lag (and memory leaks?). - public static ShortBuffer wrapFaces(final int[] faces) { - final ShortBuffer wrapper = ByteBuffer.allocateDirect(faces.length * 2).order(ByteOrder.nativeOrder()) - .asShortBuffer(); - for (final int face : faces) { - wrapper.put((short) face); - } - wrapper.clear(); - return wrapper; - } - - public static ByteBuffer wrap(final byte[] skin) { - final ByteBuffer wrapper = ByteBuffer.allocateDirect(skin.length).order(ByteOrder.nativeOrder()); - wrapper.put(skin); - wrapper.clear(); - return wrapper; - } - - public static FloatBuffer wrap(final float[] positions) { - final FloatBuffer wrapper = ByteBuffer.allocateDirect(positions.length * 4).order(ByteOrder.nativeOrder()) - .asFloatBuffer(); - wrapper.put(positions); - wrapper.clear(); - return wrapper; - } - - public static IntBuffer wrap(final int[] positions) { - final IntBuffer wrapper = ByteBuffer.allocateDirect(positions.length * 4).order(ByteOrder.nativeOrder()) - .asIntBuffer(); - wrapper.put(positions); - wrapper.clear(); - return wrapper; - } - - public static ByteBuffer wrapAsBytes(final int[] positions) { - final ByteBuffer wrapper = ByteBuffer.allocateDirect(positions.length).order(ByteOrder.nativeOrder()); - for (final int face : positions) { - wrapper.put((byte) face); - } - wrapper.clear(); - return wrapper; - } - - public static Buffer wrap(final short[] cornerTextures) { - final ByteBuffer wrapper = ByteBuffer.allocateDirect(cornerTextures.length).order(ByteOrder.nativeOrder()); - for (final short face : cornerTextures) { - wrapper.put((byte) face); - } - wrapper.clear(); - return wrapper; - } - - public static Buffer wrapShort(final short[] cornerTextures) { - final ByteBuffer wrapper = ByteBuffer.allocateDirect(cornerTextures.length * 2).order(ByteOrder.nativeOrder()); - for (final short face : cornerTextures) { - wrapper.putShort(face); - } - wrapper.clear(); - return wrapper; - } - - public static Buffer wrapPairs(final float[][] quadVertices) { - final FloatBuffer wrapper = ByteBuffer.allocateDirect(quadVertices.length * 8).order(ByteOrder.nativeOrder()) - .asFloatBuffer(); - for (int i = 0; i < quadVertices.length; i++) { - for (int j = 0; j < 2; j++) { - wrapper.put(quadVertices[i][j]); - } - } - wrapper.clear(); - return wrapper; - } - - public static Buffer wrap(final int[][] quadIndices) { - final IntBuffer wrapper = ByteBuffer.allocateDirect(quadIndices.length * 3 * 4).order(ByteOrder.nativeOrder()) - .asIntBuffer(); - for (int i = 0; i < quadIndices.length; i++) { - for (int j = 0; j < 3; j++) { - wrapper.put(quadIndices[i][j]); - } - } - wrapper.clear(); - return wrapper; - } - - public static Buffer wrap(final List vertices) { - if (vertices.isEmpty()) { - return null; - } - final int expectedNumberOfFloats = vertices.get(0).length; - final FloatBuffer wrapper = ByteBuffer.allocateDirect(vertices.size() * expectedNumberOfFloats * 4) - .order(ByteOrder.nativeOrder()).asFloatBuffer(); - for (final float[] subArray : vertices) { - for (final float f : subArray) { - wrapper.put(f); - } - } - wrapper.clear(); - return wrapper; - } - - public static Buffer wrapFaces(final List indices) { - if (indices.isEmpty()) { - return null; - } - final int expectedNumberOfValues = indices.get(0).length; - final ShortBuffer wrapper = ByteBuffer.allocateDirect(indices.size() * expectedNumberOfValues * 2) - .order(ByteOrder.nativeOrder()).asShortBuffer(); - for (final int[] subArray : indices) { - for (final int value : subArray) { - wrapper.put((short) value); - } - } - wrapper.clear(); - return wrapper; - } -} diff --git a/core/src/com/etheller/warsmash/util/SlkFile.java b/core/src/com/etheller/warsmash/util/SlkFile.java deleted file mode 100644 index bebac997..00000000 --- a/core/src/com/etheller/warsmash/util/SlkFile.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.etheller.warsmash.util; - -import java.util.ArrayList; -import java.util.List; - -public class SlkFile { - public List> rows = new ArrayList<>(); - - public SlkFile(final String buffer) { - if (buffer != null) { - this.load(buffer); - } - } - - public void load(final String buffer) { - if (!buffer.startsWith("ID")) { - throw new RuntimeException("WrongMagicNumber"); - } - - int x = 0; - int y = 0; - for (final String line : buffer.split("\n")) { - // The B command is supposed to define the total number of columns and rows, - // however in UbetSplatData.slk it gives wrong information - // Therefore, just ignore it, since JavaScript arrays grow as they want either - // way - if (line.charAt(0) != 'B') { - for (final String token : line.split(";")) { - if (token.isEmpty()) { - continue; - } - final char op = token.charAt(0); - final String valueString = token.substring(1).trim(); - final Object value; - - if (op == 'X') { - x = Integer.parseInt(valueString, 10) - 1; - } - else if (op == 'Y') { - y = Integer.parseInt(valueString, 10) - 1; - } - else if (op == 'K') { - while (y >= this.rows.size()) { - this.rows.add(null); - } - if (this.rows.get(y) == null) { - this.rows.set(y, new ArrayList<>()); - } - - if (valueString.charAt(0) == '"') { - value = valueString.substring(1, valueString.length() - 1); - } - else if ("TRUE".equals(valueString)) { - value = true; - } - else if ("FALSE".equals(valueString)) { - value = false; - } - else { - value = Float.parseFloat(valueString); - } - - final List row = this.rows.get(y); - while (x >= row.size()) { - row.add(null); - } - row.set(x, value); - } - } - } - } - } -} diff --git a/core/src/com/etheller/warsmash/util/StringBundle.java b/core/src/com/etheller/warsmash/util/StringBundle.java deleted file mode 100644 index d9d1150b..00000000 --- a/core/src/com/etheller/warsmash/util/StringBundle.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.etheller.warsmash.util; - -public interface StringBundle { - String getString(String string); - - String getStringCaseSensitive(final String key); - - StringBundle EMPTY = new StringBundle() { - @Override - public String getStringCaseSensitive(final String key) { - return key; - } - - @Override - public String getString(final String string) { - return string; - } - }; -} diff --git a/core/src/com/etheller/warsmash/util/SubscriberSetNotifier.java b/core/src/com/etheller/warsmash/util/SubscriberSetNotifier.java deleted file mode 100644 index a8da4735..00000000 --- a/core/src/com/etheller/warsmash/util/SubscriberSetNotifier.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.etheller.warsmash.util; - -import java.util.HashSet; -import java.util.Set; - -public abstract class SubscriberSetNotifier { - protected final Set set; // bad for iteration but there - // should never be a dude subscribed - // 2x - - public SubscriberSetNotifier() { - this.set = new HashSet<>(); - } - - public final void subscribe(final LISTENER_TYPE listener) { - this.set.add(listener); - } - - public final void unsubscribe(final LISTENER_TYPE listener) { - this.set.remove(listener); - } - -} diff --git a/core/src/com/etheller/warsmash/util/Test.java b/core/src/com/etheller/warsmash/util/Test.java deleted file mode 100644 index 6cac3aa0..00000000 --- a/core/src/com/etheller/warsmash/util/Test.java +++ /dev/null @@ -1,206 +0,0 @@ -package com.etheller.warsmash.util; - -import java.io.File; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.google.common.io.Files; -import com.hiveworkshop.rms.parsers.mdlx.MdlxAttachment; -import com.hiveworkshop.rms.parsers.mdlx.MdlxBone; -import com.hiveworkshop.rms.parsers.mdlx.MdlxExtent; -import com.hiveworkshop.rms.parsers.mdlx.MdlxGeoset; -import com.hiveworkshop.rms.parsers.mdlx.MdlxLayer; -import com.hiveworkshop.rms.parsers.mdlx.MdlxLayer.FilterMode; -import com.hiveworkshop.rms.parsers.mdlx.MdlxLight; -import com.hiveworkshop.rms.parsers.mdlx.MdlxLight.Type; -import com.hiveworkshop.rms.parsers.mdlx.MdlxMaterial; -import com.hiveworkshop.rms.parsers.mdlx.MdlxModel; -import com.hiveworkshop.rms.parsers.mdlx.MdlxParticleEmitter; -import com.hiveworkshop.rms.parsers.mdlx.MdlxSequence; -import com.hiveworkshop.rms.parsers.mdlx.MdlxTexture; - -public class Test { - - public static void main(final String[] args) { - final Pattern pattern = Pattern.compile("^\\[(.+?)\\]"); - final Matcher matcher = pattern.matcher("[boat] // ocean"); - if (matcher.matches()) { - final String name = matcher.group(1).trim().toLowerCase(); - System.out.println(name); - } - else { - System.out.println("no match"); - } - -// Quadtree myQT = new Quadtree<>(new Rectangle(-, y, width, height)) - - final MdlxModel model = new MdlxModel(); - upExtent(model.extent); - MdlxSequence sequence = new MdlxSequence(); - sequence.name = "Stand"; - sequence.interval = new long[] { 333, 332 }; - upExtent(sequence.extent); - model.sequences.add(sequence); - sequence = new MdlxSequence(); - sequence.name = "Stand"; - sequence.interval = new long[] { 333, 332 }; - upExtent(sequence.extent); - model.sequences.add(sequence); - sequence.name = "Stand"; - sequence.interval = new long[] { 334, 333 }; - upExtent(sequence.extent); - model.sequences.add(sequence); - sequence.name = "Stand"; - sequence.interval = new long[] { 331, 330 }; - upExtent(sequence.extent); - model.sequences.add(sequence); - - MdlxGeoset mdlxGeoset = new MdlxGeoset(); - upExtent(mdlxGeoset.extent); - mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent); - mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent); - mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent); - mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent); - mdlxGeoset.vertices = new float[] { -128f, -128f, 0f, 128f, -128f, 0f, 128f, 128f, 0f, -128f, 128f, 0f }; - mdlxGeoset.vertexGroups = new short[] { 0, 0, 0, 0 }; - mdlxGeoset.normals = new float[] { 0, 0, 1, 0, 128f, 1, 0, 0, Float.NaN, 0, 0, 1 }; - mdlxGeoset.faceTypeGroups = new long[] { 1, 0 }; - mdlxGeoset.faces = new int[] { 0, 1, 2, 3 }; - mdlxGeoset.faceGroups = new long[] { 2, 2 }; - mdlxGeoset.materialId = 0; - mdlxGeoset.matrixGroups = new long[] { 3 }; - mdlxGeoset.matrixIndices = new long[] { 0, 1, 2 }; - mdlxGeoset.uvSets = new float[][] { { 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f } }; - model.geosets.add(mdlxGeoset); - - final int n = 3600; - mdlxGeoset = new MdlxGeoset(); - upExtent(mdlxGeoset.extent); - mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent); - mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent); - mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent); - mdlxGeoset.sequenceExtents.add(mdlxGeoset.extent); - mdlxGeoset.vertices = new float[(n + 1) * 3]; - for (int i = 1; i <= n; i++) { - final float distance = 4000; - final float down = (float) ((((((i / 360) % 10) + 1) / 10f) * Math.PI) / 2); - final float around = (float) (((i % 360) / 360f) * Math.PI * 2); - final float xyRad = (float) (Math.sin(down) * distance); - final float z = (float) (Math.cos(down) * distance); - mdlxGeoset.vertices[i * 3] = (float) (Math.cos(around) * xyRad); - mdlxGeoset.vertices[(i * 3) + 1] = (float) (Math.sin(around) * xyRad); - mdlxGeoset.vertices[(i * 3) + 2] = z; - } - mdlxGeoset.vertexGroups = new short[(n + 1)]; - mdlxGeoset.normals = new float[(n + 1) * 3]; - mdlxGeoset.faceTypeGroups = new long[n]; - Arrays.fill(mdlxGeoset.faceTypeGroups, 1); - mdlxGeoset.faces = new int[n * 2]; - for (int i = 0; i < n; i++) { - mdlxGeoset.faces[(i * 2) + 1] = i + 1; - } - mdlxGeoset.faceGroups = new long[n]; - Arrays.fill(mdlxGeoset.faceGroups, 2); - mdlxGeoset.materialId = 0; - mdlxGeoset.matrixGroups = new long[] { 3 }; - mdlxGeoset.matrixIndices = new long[] { 0, 1, 2 }; - mdlxGeoset.uvSets = new float[][] { { 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f } }; - model.geosets.add(mdlxGeoset); - - final MdlxTexture texture = new MdlxTexture(); - texture.setPath("Textures\\white.blp"); - model.textures.add(texture); - - final MdlxMaterial material = new MdlxMaterial(); - final MdlxLayer layer = new MdlxLayer(); - layer.alpha = 1.0f; - layer.textureId = 0; - layer.filterMode = FilterMode.NONE; - material.layers.add(layer); - model.materials.add(material); - - final MdlxBone stupid1 = makeStupidBone("Bone_A"); - stupid1.setObjectId(0); - stupid1.setParentId(-1); - model.bones.add(stupid1); - final MdlxBone stupid2 = makeStupidBone("Bone_B"); - stupid2.setObjectId(1); - stupid1.setParentId(-1); - model.bones.add(stupid2); - final MdlxBone stupid3 = makeStupidBone("Bone_C"); - stupid2.setObjectId(2); - stupid1.setParentId(-1); - model.bones.add(stupid3); - - final MdlxLight light = new MdlxLight(); - light.ambientColor[0] = -5; - light.ambientColor[1] = 0; - light.ambientColor[2] = Float.MAX_VALUE; - light.ambientIntensity = Float.MAX_VALUE; - light.intensity = Float.MAX_VALUE; - light.attenuation[0] = Float.MAX_VALUE; - light.attenuation[1] = Float.MAX_VALUE; - light.color[0] = -5; - light.color[1] = -5; - light.color[2] = Float.MAX_VALUE; - light.type = Type.OMNIDIRECTIONAL; - light.name = "#!@$!@#$"; - light.objectId = 3; - light.parentId = -1; - model.lights.add(light); - - final MdlxAttachment attachment = new MdlxAttachment(); - attachment.setObjectId(4); - attachment.setParentId(-1); - attachment.setName("!@#$"); -// attachment.setPath("war3mapImport\\stupidFan.mdl"); - model.attachments.add(attachment); - - final MdlxParticleEmitter mdlxParticleEmitter = new MdlxParticleEmitter(); - mdlxParticleEmitter.emissionRate = 99999; - mdlxParticleEmitter.flags |= 0x8000; - mdlxParticleEmitter.lifeSpan = 99999; - mdlxParticleEmitter.name = "ATCH"; - mdlxParticleEmitter.objectId = 5; - mdlxParticleEmitter.parentId = -1; - mdlxParticleEmitter.path = "Doodads\\Cinematic\\ArthasIllidanFight\\ArthasIllidanFight.mdl"; - model.particleEmitters.add(mdlxParticleEmitter); - - model.pivotPoints.add(new float[] { 0, 0, 0 }); - model.pivotPoints.add(new float[] { 0, 0, 0 }); - model.pivotPoints.add(new float[] { 0, 0, 0 }); - model.pivotPoints.add(new float[] { 0, 0, 0 }); - model.pivotPoints.add(new float[] { 0, 0, 0 }); - model.pivotPoints.add(new float[] { 0, 0, 0 }); - - final ByteBuffer mdxBuffer = model.saveMdx(); - try { - Files.write(mdxBuffer.array(), new File("C:\\Temp\\doomball.mdx")); - } - catch (final IOException e) { - e.printStackTrace(); - } - } - - private static void upExtent(final MdlxExtent extent) { - extent.boundsRadius = Float.MAX_VALUE; - extent.max[0] = Float.MAX_VALUE; - extent.max[1] = Float.MAX_VALUE; - extent.max[2] = Float.MAX_VALUE; - extent.min[0] = -Float.MAX_VALUE; - extent.min[1] = -Float.MAX_VALUE; - extent.min[2] = -Float.MAX_VALUE; - } - - private static MdlxBone makeStupidBone(final String name) { - final MdlxBone stupid1 = new MdlxBone(); - stupid1.setName(name); - stupid1.setGeosetId(-1); - stupid1.setGeosetAnimationId(-1); - return stupid1; - } - -} diff --git a/core/src/com/etheller/warsmash/util/Vector4.java b/core/src/com/etheller/warsmash/util/Vector4.java deleted file mode 100644 index e6f42c18..00000000 --- a/core/src/com/etheller/warsmash/util/Vector4.java +++ /dev/null @@ -1,573 +0,0 @@ -package com.etheller.warsmash.util; - -import java.io.Serializable; - -import com.badlogic.gdx.math.Interpolation; -import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Vector; -import com.badlogic.gdx.utils.NumberUtils; - -/** - * Encapsulates a 4D vector. Allows chaining operations by returning a reference - * to itself in all modification methods. - * - * @author intrigus - */ -public class Vector4 implements Serializable, Vector { - - /** the x-component of this vector **/ - public float x; - /** the y-component of this vector **/ - public float y; - /** the z-component of this vector **/ - public float z; - /** the w-component of this vector **/ - public float w; - - public final static Vector4 X = new Vector4(1, 0, 0, 0); - public final static Vector4 Y = new Vector4(0, 1, 0, 0); - public final static Vector4 Z = new Vector4(0, 0, 1, 0); - public final static Vector4 W = new Vector4(0, 0, 0, 1); - public final static Vector4 Zero = new Vector4(0, 0, 0, 0); - - private final static Matrix4 tmpMat = new Matrix4(); - - /** Constructs a vector at (0,0,0,0) */ - public Vector4() { - } - - /** - * Creates a vector with the given components - * - * @param x The x-component - * @param y The y-component - * @param z The z-component - * @param w The w-component - */ - public Vector4(final float x, final float y, final float z, final float w) { - this.set(x, y, z, w); - } - - /** - * Creates a vector from the given vector - * - * @param vector The vector - */ - public Vector4(final Vector4 vector) { - this.set(vector); - } - - /** - * Creates a vector from the given array. The array must have at least 4 - * elements. - * - * @param values The array - */ - public Vector4(final float[] values) { - this.set(values[0], values[1], values[2], values[3]); - } - - /** - * Sets the vector to the given components - * - * @param x The x-component - * @param y The y-component - * @param z The z-component - * @param w The w-component - * @return this vector for chaining - */ - public Vector4 set(final float x, final float y, final float z, final float w) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - return this; - } - - @Override - public Vector4 set(final Vector4 vector) { - return this.set(vector.x, vector.y, vector.z, vector.w); - } - - /** - * Sets the components from the array. The array must have at least 4 elements - * - * @param values The array - * @return this vector for chaining - */ - public Vector4 set(final float[] values) { - return this.set(values[0], values[1], values[2], values[3]); - } - - @Override - public Vector4 cpy() { - return new Vector4(this); - } - - @Override - public Vector4 add(final Vector4 vector) { - return this.add(vector.x, vector.y, vector.z, vector.w); - } - - /** - * Adds the given vector to this component - * - * @param x The x-component of the other vector - * @param y The y-component of the other vector - * @param z The z-component of the other vector - * @param w The w-component of the other vector - * @return This vector for chaining. - */ - public Vector4 add(final float x, final float y, final float z, final float w) { - return this.set(this.x + x, this.y + y, this.z + z, this.w + w); - } - - /** - * Adds the given value to all four components of the vector. - * - * @param values The value - * @return This vector for chaining - */ - public Vector4 add(final float values) { - return this.set(this.x + values, this.y + values, this.z + values, this.w + values); - } - - @Override - public Vector4 sub(final Vector4 a_vec) { - return this.sub(a_vec.x, a_vec.y, a_vec.z, a_vec.w); - } - - /** - * Subtracts the other vector from this vector. - * - * @param x The x-component of the other vector - * @param y The y-component of the other vector - * @param z The z-component of the other vector - * @param w The w-component of the other vector - * @return This vector for chaining - */ - public Vector4 sub(final float x, final float y, final float z, final float w) { - return this.set(this.x - x, this.y - y, this.z - z, this.w - w); - } - - /** - * Subtracts the given value from all components of this vector - * - * @param value The value - * @return This vector for chaining - */ - public Vector4 sub(final float value) { - return this.set(this.x - value, this.y - value, this.z - value, this.w - value); - } - - @Override - public Vector4 scl(final float scalar) { - return this.set(this.x * scalar, this.y * scalar, this.z * scalar, this.w * scalar); - } - - @Override - public Vector4 scl(final Vector4 other) { - return this.set(this.x * other.x, this.y * other.y, this.z * other.z, this.w * other.w); - } - - /** - * Scales this vector by the given values - * - * @param vx X value - * @param vy Y value - * @param vz Z value - * @param vw W value - * @return This vector for chaining - */ - public Vector4 scl(final float vx, final float vy, final float vz, final float vw) { - return this.set(this.x * vx, this.y * vy, this.z * vz, this.z * vw); - } - - @Override - public Vector4 mulAdd(final Vector4 vec, final float scalar) { - this.x += vec.x * scalar; - this.y += vec.y * scalar; - this.z += vec.z * scalar; - this.w += vec.w * scalar; - return this; - } - - @Override - public Vector4 mulAdd(final Vector4 vec, final Vector4 mulVec) { - this.x += vec.x * mulVec.x; - this.y += vec.y * mulVec.y; - this.z += vec.z * mulVec.z; - this.w += vec.w * mulVec.w; - return this; - } - - /** @return The euclidian length */ - public static float len(final float x, final float y, final float z, final float w) { - return (float) Math.sqrt((x * x) + (y * y) + (z * z) + (w * w)); - } - - @Override - public float len() { - return (float) Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z) + (this.w * this.w)); - } - - /** @return The squared euclidian length */ - public static float len2(final float x, final float y, final float z, final float w) { - return (x * x) + (y * y) + (z * z) + (w * w); - } - - @Override - public float len2() { - return (this.x * this.x) + (this.y * this.y) + (this.z * this.z) + (this.w * this.w); - } - - /** - * @param vector The other vector - * @return Whether this and the other vector are equal - */ - public boolean idt(final Vector4 vector) { - return (this.x == vector.x) && (this.y == vector.y) && (this.z == vector.z) && (this.w == vector.w); - } - - /** @return The euclidian distance between the two specified vectors */ - public static float dst(final float x1, final float y1, final float z1, final float w1, final float x2, - final float y2, final float z2, final float w2) { - final float a = x2 - x1; - final float b = y2 - y1; - final float c = z2 - z1; - final float d = w2 - w1; - return (float) Math.sqrt((a * a) + (b * b) + (c * c) + (d * d)); - } - - @Override - public float dst(final Vector4 vector) { - final float a = vector.x - this.x; - final float b = vector.y - this.y; - final float c = vector.z - this.z; - final float d = vector.w - this.w; - return (float) Math.sqrt((a * a) + (b * b) + (c * c) + (d * d)); - } - - /** @return the distance between this point and the given point */ - public float dst(final float x, final float y, final float z, final float w) { - final float a = x - this.x; - final float b = y - this.y; - final float c = z - this.z; - final float d = w - this.w; - return (float) Math.sqrt((a * a) + (b * b) + (c * c) + (d * d)); - } - - /** @return the squared distance between the given points */ - public static float dst2(final float x1, final float y1, final float z1, final float w1, final float x2, - final float y2, final float z2, final float w2) { - final float a = x2 - x1; - final float b = y2 - y1; - final float c = z2 - z1; - final float d = w2 - w1; - return (a * a) + (b * b) + (c * c) + (d * d); - } - - @Override - public float dst2(final Vector4 point) { - final float a = point.x - this.x; - final float b = point.y - this.y; - final float c = point.z - this.z; - final float d = point.w - this.w; - return (a * a) + (b * b) + (c * c) + (d * d); - } - - /** - * Returns the squared distance between this point and the given point - * - * @param x The x-component of the other point - * @param y The y-component of the other point - * @param z The z-component of the other point - * @param w The w-component of the other point - * @return The squared distance - */ - public float dst2(final float x, final float y, final float z, final float w) { - final float a = x - this.x; - final float b = y - this.y; - final float c = z - this.z; - final float d = w - this.w; - return (a * a) + (b * b) + (c * c) + (d * d); - } - - @Override - public Vector4 nor() { - final float len2 = this.len2(); - if ((len2 == 0f) || (len2 == 1f)) { - return this; - } - return this.scl(1f / (float) Math.sqrt(len2)); - } - - /** @return The dot product between the two vectors */ - public static float dot(final float x1, final float y1, final float z1, final float w1, final float x2, - final float y2, final float z2, final float w2) { - return (x1 * x2) + (y1 * y2) + (z1 * z2) + (w1 * w2); - } - - @Override - public float dot(final Vector4 vector) { - return (this.x * vector.x) + (this.y * vector.y) + (this.z * vector.z) + (this.w * vector.w); - } - - /** - * Returns the dot product between this and the given vector. - * - * @param x The x-component of the other vector - * @param y The y-component of the other vector - * @param z The z-component of the other vector - * @param w The w-component of the other vector - * @return The dot product - */ - public float dot(final float x, final float y, final float z, final float w) { - return (this.x * x) + (this.y * y) + (this.z * z) + (this.w * w); - } - - @Override - public boolean isUnit() { - return isUnit(0.000000001f); - } - - @Override - public boolean isUnit(final float margin) { - return Math.abs(len2() - 1f) < margin; - } - - @Override - public boolean isZero() { - return (this.x == 0) && (this.y == 0) && (this.z == 0); - } - - @Override - public boolean isZero(final float margin) { - return len2() < margin; - } - - @Override - public boolean isOnLine(final Vector4 other, final float epsilon) { - throw new UnsupportedOperationException(); - // TODO -// return len2((this.y * other.z) - (this.z * other.y), (this.z * other.x) - (this.x * other.z), -// (this.x * other.y) - (this.y * other.x)) <= epsilon; - } - - @Override - public boolean isOnLine(final Vector4 other) { - throw new UnsupportedOperationException(); - // TODO -// return len2((this.y * other.z) - (this.z * other.y), (this.z * other.x) - (this.x * other.z), -// (this.x * other.y) - (this.y * other.x)) <= MathUtils.FLOAT_ROUNDING_ERROR; - } - - @Override - public boolean isCollinear(final Vector4 other, final float epsilon) { - return isOnLine(other, epsilon) && hasSameDirection(other); - } - - @Override - public boolean isCollinear(final Vector4 other) { - return isOnLine(other) && hasSameDirection(other); - } - - @Override - public boolean isCollinearOpposite(final Vector4 other, final float epsilon) { - return isOnLine(other, epsilon) && hasOppositeDirection(other); - } - - @Override - public boolean isCollinearOpposite(final Vector4 other) { - return isOnLine(other) && hasOppositeDirection(other); - } - - @Override - public boolean isPerpendicular(final Vector4 vector) { - return MathUtils.isZero(dot(vector)); - } - - @Override - public boolean isPerpendicular(final Vector4 vector, final float epsilon) { - return MathUtils.isZero(dot(vector), epsilon); - } - - @Override - public boolean hasSameDirection(final Vector4 vector) { - return dot(vector) > 0; - } - - @Override - public boolean hasOppositeDirection(final Vector4 vector) { - return dot(vector) < 0; - } - - @Override - public Vector4 lerp(final Vector4 target, final float alpha) { - // TODO - this.x += alpha * (target.x - this.x); - this.y += alpha * (target.y - this.y); - this.z += alpha * (target.z - this.z); - return this; - } - - @Override - public Vector4 interpolate(final Vector4 target, final float alpha, final Interpolation interpolator) { - // TODO - return lerp(target, interpolator.apply(0f, 1f, alpha)); - } - - @Override - public String toString() { - return "[" + this.x + ", " + this.y + ", " + this.z + ", " + this.w + "]"; - } - - @Override - public Vector4 limit(final float limit) { -// TODO - return limit2(limit * limit); - } - - @Override - public Vector4 limit2(final float limit2) { - // TODO - final float len2 = len2(); - if (len2 > limit2) { - scl((float) Math.sqrt(limit2 / len2)); - } - return this; - } - - @Override - public Vector4 setLength(final float len) { - return setLength2(len * len); - } - - @Override - public Vector4 setLength2(final float len2) { - final float oldLen2 = len2(); - return ((oldLen2 == 0) || (oldLen2 == len2)) ? this : scl((float) Math.sqrt(len2 / oldLen2)); - } - - @Override - public Vector4 clamp(final float min, final float max) { - final float len2 = len2(); - if (len2 == 0f) { - return this; - } - final float max2 = max * max; - if (len2 > max2) { - return scl((float) Math.sqrt(max2 / len2)); - } - final float min2 = min * min; - if (len2 < min2) { - return scl((float) Math.sqrt(min2 / len2)); - } - return this; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + NumberUtils.floatToIntBits(this.x); - result = (prime * result) + NumberUtils.floatToIntBits(this.y); - result = (prime * result) + NumberUtils.floatToIntBits(this.z); - result = (prime * result) + NumberUtils.floatToIntBits(this.w); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final Vector4 other = (Vector4) obj; - if (NumberUtils.floatToIntBits(this.x) != NumberUtils.floatToIntBits(other.x)) { - return false; - } - if (NumberUtils.floatToIntBits(this.y) != NumberUtils.floatToIntBits(other.y)) { - return false; - } - if (NumberUtils.floatToIntBits(this.z) != NumberUtils.floatToIntBits(other.z)) { - return false; - } - if (NumberUtils.floatToIntBits(this.w) != NumberUtils.floatToIntBits(other.w)) { - return false; - } - return true; - } - - @Override - public boolean epsilonEquals(final Vector4 other, final float epsilon) { - if (other == null) { - return false; - } - if (Math.abs(other.x - this.x) > epsilon) { - return false; - } - if (Math.abs(other.y - this.y) > epsilon) { - return false; - } - if (Math.abs(other.z - this.z) > epsilon) { - return false; - } - if (Math.abs(other.w - this.w) > epsilon) { - return false; - } - return true; - } - - /** - * Compares this vector with the other vector, using the supplied epsilon for - * fuzzy equality testing. - * - * @return whether the vectors are the same. - */ - public boolean epsilonEquals(final float x, final float y, final float z, final float w, final float epsilon) { - if (Math.abs(x - this.x) > epsilon) { - return false; - } - if (Math.abs(y - this.y) > epsilon) { - return false; - } - if (Math.abs(z - this.z) > epsilon) { - return false; - } - if (Math.abs(w - this.w) > epsilon) { - return false; - } - return true; - } - - @Override - public Vector4 setZero() { - this.x = 0; - this.y = 0; - this.z = 0; - this.w = 0; - return this; - } - - @Override - public Vector4 setToRandomDirection() { - throw new UnsupportedOperationException(); - } - - public static Vector4 transformMat4(final Vector4 out, final Vector4 a, final Matrix4 matrix) { - final float x = a.x, y = a.y, z = a.z, w = a.w; - final float[] m = matrix.val; - out.x = (m[Matrix4.M00] * x) + (m[Matrix4.M01] * y) + (m[Matrix4.M02] * z) + (m[Matrix4.M03] * w); - out.y = (m[Matrix4.M10] * x) + (m[Matrix4.M11] * y) + (m[Matrix4.M12] * z) + (m[Matrix4.M13] * w); - out.z = (m[Matrix4.M20] * x) + (m[Matrix4.M21] * y) + (m[Matrix4.M22] * z) + (m[Matrix4.M23] * w); - out.w = (m[Matrix4.M30] * x) + (m[Matrix4.M31] * y) + (m[Matrix4.M32] * z) + (m[Matrix4.M33] * w); - return out; - } -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/util/War3ID.java b/core/src/com/etheller/warsmash/util/War3ID.java deleted file mode 100644 index e42e3cbf..00000000 --- a/core/src/com/etheller/warsmash/util/War3ID.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.etheller.warsmash.util; - -public final class War3ID implements Comparable { - public static final War3ID NONE = new War3ID(0); - private final int value; - - public War3ID(final int value) { - this.value = value; - } - - public int getValue() { - return this.value; - } - - public static War3ID fromString(String idString) { - if (idString.length() == 3) { - System.err.println( - "Loaded custom data for the ability CURSE whose MetaData field, 'Crs', is the only 3 letter War3ID in the game. This might cause unexpected errors, so watch your % chance to miss in custom curse abilities carefully."); - idString += '\0'; - } - if (idString.length() != 4) { - throw new IllegalArgumentException( - "A War3ID must be 4 ascii characters in length (got " + idString.length() + ") '" + idString + "'"); - } - return new War3ID(RawcodeUtils.toInt(idString)); - } - - public String asStringValue() { - String string = RawcodeUtils.toString(this.value); - if (((string.charAt(3) == '\0') || (string.charAt(3) == ' ')) && (string.charAt(2) != '\0')) { - string = string.substring(0, 3); - } - return string; - } - - public War3ID set(final int index, final char c) { - final String asStringValue = asStringValue(); - String result = asStringValue.substring(0, index); - result += c; - result += asStringValue.substring(index + 1, asStringValue.length()); - return War3ID.fromString(result); - } - - public char charAt(final int index) { - return (char) ((this.value >>> ((3 - index) * 8)) & 0xFF); - } - - @Override - public String toString() { - return asStringValue(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + this.value; - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final War3ID other = (War3ID) obj; - if (this.value != other.value) { - return false; - } - return true; - } - - @Override - public int compareTo(final War3ID o) { - return Integer.compare(this.value, o.value); - } -} diff --git a/core/src/com/etheller/warsmash/util/WarsmashConstants.java b/core/src/com/etheller/warsmash/util/WarsmashConstants.java deleted file mode 100644 index 8fea2806..00000000 --- a/core/src/com/etheller/warsmash/util/WarsmashConstants.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.etheller.warsmash.util; - -public class WarsmashConstants { - public static final int MAX_PLAYERS = 16; - /* - * With version, we use 0 for RoC, 1 for TFT emulation, and probably 2+ or - * whatever for custom mods and other stuff - */ - public static int GAME_VERSION = 1; - public static final int REPLACEABLE_TEXTURE_LIMIT = 64; - public static final float SIMULATION_STEP_TIME = 1 / 20f; - public static final int PORT_NUMBER = 6115; - public static final float BUILDING_CONSTRUCT_START_LIFE = 0.1f; - public static final int BUILD_QUEUE_SIZE = 7; - public static final int MAX_SELECTION_SIZE = 12; - // It looks like in Patch 1.22, "Particle" in video settings will change this - // factor: - // Low - unknown ? - // Medium - 1.0f - // High - 1.5f - public static final float MODEL_DETAIL_PARTICLE_FACTOR = 1.5f; - public static final float MODEL_DETAIL_PARTICLE_FACTOR_INVERSE = 1f / MODEL_DETAIL_PARTICLE_FACTOR; - - // I know this default string is from somewhere, maybe a language file? Didn't - // find it yet so I used this - public static final String DEFAULT_STRING = "Default string"; - - public static final boolean CATCH_CURSOR = false; - public static final boolean VERBOSE_LOGGING = true; - public static final boolean ENABLE_DEBUG = false; - public static final char SPECIAL_ESCAPE_KEYCODE = 0x7E; - - // My tileset loader is "always on top", even for local files. This is different - // from some MPQ loader engines that would use - // load index as a numeric value and could be changed. For now, I have this - // workaround to fix it if you need the local files - // to take priority over built-ins for tilesets. - public static final boolean FIX_FLAT_FILES_TILESET_LOADING = false; -} diff --git a/core/src/com/etheller/warsmash/util/WorldEditStrings.java b/core/src/com/etheller/warsmash/util/WorldEditStrings.java deleted file mode 100644 index 40c746e8..00000000 --- a/core/src/com/etheller/warsmash/util/WorldEditStrings.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.etheller.warsmash.util; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.MissingResourceException; -import java.util.PropertyResourceBundle; -import java.util.ResourceBundle; - -import com.etheller.warsmash.datasources.DataSource; - -public class WorldEditStrings implements StringBundle { - private ResourceBundle bundle; - private ResourceBundle bundlegs; - - public WorldEditStrings(final DataSource dataSource) { - if (dataSource.has("UI\\WorldEditStrings.txt")) { - try (InputStream fis = dataSource.getResourceAsStream("UI\\WorldEditStrings.txt"); - InputStreamReader reader = new InputStreamReader(fis, "utf-8")) { - this.bundle = new PropertyResourceBundle(reader); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - try (InputStream fis = dataSource.getResourceAsStream("UI\\WorldEditGameStrings.txt"); - InputStreamReader reader = new InputStreamReader(fis, "utf-8")) { - this.bundlegs = new PropertyResourceBundle(reader); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public String getString(String string) { - try { - while (string.toUpperCase().startsWith("WESTRING")) { - string = internalGetString(string); - } - return string; - } - catch (final MissingResourceException exc) { - try { - return this.bundlegs.getString(string.toUpperCase()); - } - catch (final MissingResourceException exc2) { - return string; - } - } - } - - private String internalGetString(final String key) { - if (this.bundle == null) { - return this.bundlegs.getString(key.toUpperCase()); - } - try { - String string = this.bundle.getString(key.toUpperCase()); - if ((string.charAt(0) == '"') && (string.length() >= 2) && (string.charAt(string.length() - 1) == '"')) { - string = string.substring(1, string.length() - 1); - } - return string; - } - catch (final MissingResourceException exc) { - return this.bundlegs.getString(key.toUpperCase()); - } - } - - @Override - public String getStringCaseSensitive(final String key) { - if (this.bundle == null) { - return this.bundlegs.getString(key); - } - try { - return this.bundle.getString(key); - } - catch (final MissingResourceException exc) { - return this.bundlegs.getString(key); - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/AudioBufferSource.java b/core/src/com/etheller/warsmash/viewer5/AudioBufferSource.java deleted file mode 100644 index 245b8441..00000000 --- a/core/src/com/etheller/warsmash/viewer5/AudioBufferSource.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import com.badlogic.gdx.audio.Sound; -import com.etheller.warsmash.viewer5.gl.Extensions; - -public class AudioBufferSource { - public Sound buffer; - private AudioPanner panner; - - public void connect(final AudioPanner panner) { - this.panner = panner; - } - - public void start(final int value, final float volume, final float pitch, final boolean looping) { - if (this.buffer != null) { - if (!this.panner.listener.is3DSupported() || this.panner.isWithinListenerDistance()) { - Extensions.audio.play(this.buffer, volume, pitch, this.panner.x, this.panner.y, this.panner.z, - this.panner.listener.is3DSupported(), this.panner.maxDistance, this.panner.refDistance, - looping); - } - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/AudioContext.java b/core/src/com/etheller/warsmash/viewer5/AudioContext.java deleted file mode 100644 index 68383f2f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/AudioContext.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.etheller.warsmash.viewer5; - -public class AudioContext { - private boolean running = false; - public Listener listener; - public AudioDestination destination; - - public AudioContext(final Listener listener, final AudioDestination destination) { - this.listener = listener; - this.destination = destination; - } - - public void suspend() { - this.running = false; - } - - public boolean isRunning() { - return this.running; - } - - public void resume() { - this.running = true; - } - - public static interface Listener { - - float getX(); - - float getY(); - - float getZ(); - - public void setPosition(final float x, final float y, final float z); - - public void setOrientation(final float forwardX, final float forwardY, final float forwardZ, final float upX, - final float upY, final float upZ); - - boolean is3DSupported(); - - Listener DO_NOTHING = new Listener() { - private float x; - private float y; - private float z; - - @Override - public void setPosition(final float x, final float y, final float z) { - this.x = x; - this.y = y; - this.z = z; - } - - @Override - public float getX() { - return x; - } - - @Override - public float getY() { - return y; - } - - @Override - public float getZ() { - return z; - } - - @Override - public void setOrientation(final float forwardX, final float forwardY, final float forwardZ, - final float upX, final float upY, final float upZ) { - - } - - @Override - public boolean is3DSupported() { - return false; - } - }; - } - - public AudioPanner createPanner() { - return new AudioPanner(this.listener) { - @Override - public void connect(final AudioDestination destination) { - } - }; - } - - public AudioBufferSource createBufferSource() { - return new AudioBufferSource(); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/AudioDestination.java b/core/src/com/etheller/warsmash/viewer5/AudioDestination.java deleted file mode 100644 index d028de95..00000000 --- a/core/src/com/etheller/warsmash/viewer5/AudioDestination.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.viewer5; - -public interface AudioDestination { - -} diff --git a/core/src/com/etheller/warsmash/viewer5/AudioPanner.java b/core/src/com/etheller/warsmash/viewer5/AudioPanner.java deleted file mode 100644 index a83b3657..00000000 --- a/core/src/com/etheller/warsmash/viewer5/AudioPanner.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import com.etheller.warsmash.viewer5.AudioContext.Listener; - -public abstract class AudioPanner { - public Listener listener; - public float x; - public float y; - public float z; - - public AudioPanner(final Listener listener) { - this.listener = listener; - } - - public void setPosition(final float x, final float y, final float z) { - this.x = x; - this.y = y; - this.z = z; - } - - public void setDistances(final float maxDistance, final float refDistance) { - this.maxDistance = maxDistance; - this.refDistance = refDistance; - this.maxDistanceSq = maxDistance * maxDistance; - } - - public float maxDistance; - public float refDistance; - public float maxDistanceSq; - - public abstract void connect(AudioDestination destination); - - public boolean isWithinListenerDistance() { - final float dx = this.listener.getX() - this.x; - final float dy = this.listener.getY() - this.y; - final float dz = this.listener.getZ() - this.z; - return ((dx * dx) + (dy * dy) + (dz * dz)) <= this.maxDistanceSq; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/BatchedInstance.java b/core/src/com/etheller/warsmash/viewer5/BatchedInstance.java deleted file mode 100644 index dca32141..00000000 --- a/core/src/com/etheller/warsmash/viewer5/BatchedInstance.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.etheller.warsmash.viewer5; - -/** - * A batched model instance. - */ -public abstract class BatchedInstance extends ModelInstance { - - public BatchedInstance(final Model model) { - super(model); - } - - @Override - public boolean isBatched() { - return true; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/Bounds.java b/core/src/com/etheller/warsmash/viewer5/Bounds.java deleted file mode 100644 index 1349ea9b..00000000 --- a/core/src/com/etheller/warsmash/viewer5/Bounds.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import com.badlogic.gdx.math.Intersector; -import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.math.collision.BoundingBox; -import com.badlogic.gdx.math.collision.Ray; - -public class Bounds { - public float x, y, z, r; - private BoundingBox boundingBox; - - public void fromExtents(final float[] min, final float[] max, final float boundsRadius) { - final float x = min[0]; - final float y = min[1]; - final float z = min[2]; - final float w = max[0] - x; - final float d = max[1] - y; - final float h = max[2] - z; - - this.x = x + (w / 2f); - this.y = y + (d / 2f); - this.z = z + (h / 2f); - this.r = boundsRadius > 0 ? boundsRadius : (float) (Math.max(Math.max(w, d), h) / 2.); - this.boundingBox = new BoundingBox(new Vector3(min), new Vector3(max)); - } - - public boolean intersectRay(final Ray ray, final Vector3 intersection) { - if (this.boundingBox == null) { - return false; - } - return Intersector.intersectRayBounds(ray, this.boundingBox, intersection); - } - - public boolean intersectRayFast(final Ray ray) { - return Intersector.intersectRayBoundsFast(ray, this.boundingBox); - } - - public BoundingBox getBoundingBox() { - return this.boundingBox; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/Camera.java b/core/src/com/etheller/warsmash/viewer5/Camera.java deleted file mode 100644 index 1a97cd6b..00000000 --- a/core/src/com/etheller/warsmash/viewer5/Camera.java +++ /dev/null @@ -1,346 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Quaternion; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.util.Vector4; - -public class Camera { - private static final Vector3 vectorHeap = new Vector3(); - private static final Vector3 vectorHeap2 = new Vector3(); - private static final Vector3 vectorHeap3 = new Vector3(); - private static final Quaternion quatHeap = new Quaternion(); - private static final Matrix4 matHeap = new Matrix4(); - - public final Rectangle rect; - - private boolean isPerspective; - private float fov; - private float aspect; - - public boolean isOrtho; - private float leftClipPlane; - private float rightClipPlane; - private float bottomClipPlane; - private float topClipPlane; - - private float nearClipPlane; - private float farClipPlane; - - public final Vector3 location; - public final Quaternion rotation; - - public Quaternion inverseRotation; - /** - * World -> View. - */ - private final Matrix4 viewMatrix; - /** - * View -> Clip. - */ - private final Matrix4 projectionMatrix; - /** - * World -> Clip. - */ - public final Matrix4 viewProjectionMatrix; - /** - * View -> World. - */ - private final Matrix4 inverseViewMatrix; - /** - * Clip -> World. - */ - private final Matrix4 inverseViewProjectionMatrix; - public final Vector3 directionX; - public final Vector3 directionY; - public final Vector3 directionZ; - public final Vector3[] vectors; - public final Vector3[] billboardedVectors; - - public final Vector4[] planes; - private boolean dirty; - - public Camera() { - // rencered viewport - this.rect = new Rectangle(); - - // perspective values - this.isPerspective = true; - this.fov = 0; - this.aspect = 0; - - // Orthogonal values - this.isOrtho = false; - this.leftClipPlane = 0f; - this.rightClipPlane = 0f; - this.bottomClipPlane = 0f; - this.topClipPlane = 0f; - - // Shared values - this.nearClipPlane = 0f; - this.farClipPlane = 0f; - - // World values - this.location = new Vector3(); - this.rotation = new Quaternion(); - - // Derived values. - this.inverseRotation = new Quaternion(); - this.viewMatrix = new Matrix4(); - this.projectionMatrix = new Matrix4(); - this.viewProjectionMatrix = new Matrix4(); - this.inverseViewMatrix = new Matrix4(); - this.inverseViewProjectionMatrix = new Matrix4(); - this.directionX = new Vector3(); - this.directionY = new Vector3(); - this.directionZ = new Vector3(); - - // First four vectors are the corners of a 2x2 rectangle, the last three vectors - // are the unit axes - this.vectors = new Vector3[] { new Vector3(-1, -1, 0), new Vector3(-1, 1, 0), new Vector3(1, 1, 0), - new Vector3(1, -1, 0), new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1) }; - - // First four vectors are the corners of a 2x2 rectangle billboarded to the - // camera, the last three vectors are the unit axes billboarded - this.billboardedVectors = new Vector3[] { new Vector3(), new Vector3(), new Vector3(), new Vector3(), - new Vector3(), new Vector3(), new Vector3() }; - - // Left, right, top, bottom, near, far - this.planes = new Vector4[] { new Vector4(), new Vector4(), new Vector4(), new Vector4(), new Vector4(), - new Vector4() }; - - this.dirty = true; - } - - public void perspective(final float fov, final float aspect, final float near, final float far) { - this.isPerspective = true; - this.isOrtho = false; - this.fov = fov; - this.aspect = aspect; - this.nearClipPlane = near; - this.farClipPlane = far; - - this.dirty = true; - } - - public void ortho(final float left, final float right, final float bottom, final float top, final float near, - final float far) { - this.isPerspective = false; - this.isOrtho = true; - this.leftClipPlane = left; - this.rightClipPlane = right; - this.bottomClipPlane = bottom; - this.topClipPlane = top; - this.nearClipPlane = near; - this.farClipPlane = far; - - this.dirty = true; - } - - public void viewport(final Rectangle viewport) { - this.rect.set(viewport); - - this.aspect = viewport.width / viewport.height; - - this.dirty = true; - } - - public float getAspect() { - return this.aspect; - } - - public void setLocation(final Vector3 location) { - this.location.set(location); - - this.dirty = true; - } - - public void move(final Vector3 offset) { - this.location.add(offset); - - this.dirty = true; - } - - public void setRotation(final Quaternion rotation) { - this.rotation.set(rotation); - - this.dirty = true; - } - - public void rotate(final Quaternion rotation) { - this.rotation.mul(rotation); - - this.dirty = true; - } - - public void setRotationAngles(final float horizontalAngle, final float verticalAngle) { - this.rotation.idt(); -// this.rotateAngles(horizontalAngle, verticalAngle); - throw new UnsupportedOperationException( - "Ghostwolf called a function that does not exist, so I did not know what to do here"); - } - - public void rotateAround(final Quaternion rotation, final Vector3 point) { - this.rotate(rotation); - - quatHeap.conjugate(); // TODO ????????? - vectorHeap.set(this.location); - vectorHeap.sub(point); - rotation.transform(vectorHeap); - vectorHeap.add(point); - this.location.set(vectorHeap); - } - - public void setRotationAround(final Quaternion rotation, final Vector3 point) { - this.setRotation(rotation); - ; - - final float length = vectorHeap.set(this.location).sub(point).len(); - - quatHeap.conjugate(); // TODO ????????? - vectorHeap.set(RenderMathUtils.VEC3_UNIT_Z); - quatHeap.transform(vectorHeap); - vectorHeap.scl(length); - this.location.set(vectorHeap.add(point)); - } - - public void setRotationAroundAngles(final float horizontalAngle, final float verticalAngle, final Vector3 point) { - quatHeap.idt(); - RenderMathUtils.rotateX(quatHeap, quatHeap, verticalAngle); - RenderMathUtils.rotateY(quatHeap, quatHeap, horizontalAngle); - - this.setRotationAround(quatHeap, point); - } - - public void face(final Vector3 point, final Vector3 worldUp) { - matHeap.setToLookAt(this.location, point, worldUp); - matHeap.getRotation(this.rotation); - - this.dirty = true; - } - - public void moveToAndFace(final Vector3 location, final Vector3 target, final Vector3 worldUp) { - this.location.set(location); - this.face(target, worldUp); - } - - public void reset() { - this.location.set(0, 0, 0); - this.rotation.idt(); - - this.dirty = true; - } - - public void update() { - if (this.dirty) { - final Vector3 location = this.location; - final Quaternion rotation = this.rotation; - final Quaternion inverseRotation = this.inverseRotation; - final Matrix4 viewMatrix = this.viewMatrix; - final Matrix4 projectionMatrix = this.projectionMatrix; - final Matrix4 viewProjectionMatrix = this.viewProjectionMatrix; - final Vector3[] vectors = this.vectors; - final Vector3[] billboardedVectors = this.billboardedVectors; - - if (this.isPerspective) { - RenderMathUtils.perspective(projectionMatrix, this.fov, this.aspect, this.nearClipPlane, - this.farClipPlane); - } - else { - RenderMathUtils.ortho(projectionMatrix, this.leftClipPlane, this.rightClipPlane, this.bottomClipPlane, - this.topClipPlane, this.nearClipPlane, this.farClipPlane); - } - - rotation.toMatrix(viewMatrix.val); - viewMatrix.translate(vectorHeap.set(location).scl(-1)); - inverseRotation.set(rotation).conjugate(); - - // World projection matrix - // World space -> NDC space - viewProjectionMatrix.set(projectionMatrix).mul(viewMatrix); - - // Recalculate the camera's frustum planes - RenderMathUtils.unpackPlanes(this.planes, viewProjectionMatrix); - - // Inverse world matrix - // Camera space -> world space - this.inverseViewMatrix.set(viewMatrix).inv(); - - this.directionX.set(RenderMathUtils.VEC3_UNIT_X); - inverseRotation.transform(this.directionX); - this.directionY.set(RenderMathUtils.VEC3_UNIT_Y); - inverseRotation.transform(this.directionY); - this.directionZ.set(RenderMathUtils.VEC3_UNIT_Z); - inverseRotation.transform(this.directionZ); - - // Inverse world projection matrix - // NDC space -> World space - this.inverseViewProjectionMatrix.set(viewProjectionMatrix); - this.inverseViewProjectionMatrix.inv(); - - for (int i = 0; i < 7; i++) { - billboardedVectors[i].set(vectors[i]); - inverseRotation.transform(billboardedVectors[i]); - } - this.dirty = false; - } - } - - public boolean testSphere(final Vector3 center, final float radius) { - for (final Vector4 plane : this.planes) { - if (RenderMathUtils.distanceToPlane(plane, center) <= -radius) { - return false; - } - } - return true; - } - - public Vector3 cameraToWorld(final Vector3 out, final Vector3 v) { - return out.set(v).prj(this.inverseViewMatrix); - } - - public Vector3 worldToCamera(final Vector3 out, final Vector3 v) { - return out.set(v).prj(this.viewMatrix); - } - - public Vector2 worldToScreen(final Vector2 out, final Vector3 v) { - final Rectangle viewport = this.rect; - - vectorHeap.set(v); - vectorHeap.prj(this.viewProjectionMatrix); - - out.x = Math.round(((vectorHeap.x + 1) / 2) * viewport.width); - out.y = ((Gdx.graphics.getHeight() - viewport.y - viewport.height) + (viewport.height)) - - Math.round(((vectorHeap.y + 1) / 2) * viewport.height); - - return out; - } - - public float[] screenToWorldRay(final float[] out, final Vector2 v) { - final Vector3 a = vectorHeap; - final Vector3 b = vectorHeap2; - final Vector3 c = vectorHeap3; - final float x = v.x; - final float y = v.y; - final Rectangle viewport = this.rect; - - // Intersection on the near-plane - RenderMathUtils.unproject(a, c.set(x, y, 0), this.inverseViewProjectionMatrix, viewport); - - // Intersection on the far-plane - RenderMathUtils.unproject(b, c.set(x, y, 1), this.inverseViewProjectionMatrix, viewport); - - out[0] = a.x; - out[1] = a.y; - out[2] = a.z; - out[3] = b.x; - out[4] = b.y; - out[5] = b.z; - - return out; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/CanvasProvider.java b/core/src/com/etheller/warsmash/viewer5/CanvasProvider.java deleted file mode 100644 index 7d0aaabd..00000000 --- a/core/src/com/etheller/warsmash/viewer5/CanvasProvider.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.etheller.warsmash.viewer5; - -public interface CanvasProvider { - float getWidth(); - - float getHeight(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/EmittedObject.java b/core/src/com/etheller/warsmash/viewer5/EmittedObject.java deleted file mode 100644 index 24eec9d0..00000000 --- a/core/src/com/etheller/warsmash/viewer5/EmittedObject.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.etheller.warsmash.viewer5; - -public abstract class EmittedObject>> { - public abstract void update(float dt); - - public float health; - public EMITTER emitter; - public int index; - - public EmittedObject(final EMITTER emitter) { - this.emitter = emitter; - } - - protected abstract void bind(int flags); -} diff --git a/core/src/com/etheller/warsmash/viewer5/EmittedObjectUpdater.java b/core/src/com/etheller/warsmash/viewer5/EmittedObjectUpdater.java deleted file mode 100644 index e99816d7..00000000 --- a/core/src/com/etheller/warsmash/viewer5/EmittedObjectUpdater.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.util.ArrayList; -import java.util.List; - -public class EmittedObjectUpdater { - final List objects; - private int alive; - - public EmittedObjectUpdater() { - this.objects = new ArrayList<>(); - this.alive = 0; - } - - public void add(final EmittedObject object) { - this.objects.add(object); - this.alive++; - } - - public void update(final float dt) { - for (int i = 0; i < this.alive; i++) { - final EmittedObject object = this.objects.get(i); - - object.update(dt); - - if (object.health <= 0) { - this.alive -= 1; - - object.emitter.kill(object); - - // Swap between this object and the last living object. - // Decrement the iterator so the swapped object is updated this frame. - if (i != this.alive) { - this.objects.set(i, this.objects.remove(this.alive)); - i -= 1; - } - else { - this.objects.remove(this.alive); - } - } - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/Emitter.java b/core/src/com/etheller/warsmash/viewer5/Emitter.java deleted file mode 100644 index 690dc634..00000000 --- a/core/src/com/etheller/warsmash/viewer5/Emitter.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.util.ArrayList; -import java.util.List; - -public abstract class Emitter>> - implements UpdatableObject { - - public final MODEL_INSTANCE instance; - public final List objects; - public int alive; - protected float currentEmission; - - public Emitter(final MODEL_INSTANCE instance) { - this.instance = instance; - this.objects = new ArrayList<>(); - this.alive = 0; - this.currentEmission = 0; - } - - public final EMITTED_OBJECT emitObject(final int flags) { - if (this.alive == this.objects.size()) { - this.objects.add(this.createObject()); - } - - final EMITTED_OBJECT object = this.objects.get(this.alive); - - object.index = this.alive; - - object.bind(flags); - - this.alive += 1; - this.currentEmission -= 1; - - this.instance.scene.emitterObjectUpdater.add(object); - - return object; - } - - @Override - public void update(final float dt, final boolean objectVisible) { - if (!objectVisible) { - return; - } - this.updateEmission(dt); - - final float currentEmission = this.currentEmission; - - if (currentEmission >= 1) { - for (int i = 0; i < currentEmission; i += 1) { - this.emit(); - } - } - } - - public void kill(final EMITTED_OBJECT object) { - this.alive -= 1; - - final EMITTED_OBJECT otherObject = this.objects.get(this.alive); - if (object.index == -1) { - System.err.println("bad"); - } - this.objects.set(object.index, otherObject); - this.objects.set(this.alive, object); - - otherObject.index = object.index; - object.index = -1; - } - - public final void clear() { - for (int i = 0; i < this.alive; i++) { - this.objects.get(i).health = 0; - } - this.currentEmission = 0; - } - - protected abstract void updateEmission(float dt); - - protected abstract void emit(); - - protected abstract EMITTED_OBJECT createObject(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/GdxTextureResource.java b/core/src/com/etheller/warsmash/viewer5/GdxTextureResource.java deleted file mode 100644 index aff666b2..00000000 --- a/core/src/com/etheller/warsmash/viewer5/GdxTextureResource.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import com.badlogic.gdx.graphics.Texture.TextureWrap; -import com.etheller.warsmash.viewer5.handlers.ResourceHandler; - -public abstract class GdxTextureResource extends Texture { - private com.badlogic.gdx.graphics.Texture gdxTexture; - - public GdxTextureResource(final ModelViewer viewer, final ResourceHandler handler, final String extension, - final PathSolver pathSolver, final String fetchUrl) { - super(viewer, extension, pathSolver, fetchUrl, handler); - } - - public void setGdxTexture(final com.badlogic.gdx.graphics.Texture gdxTexture) { - this.gdxTexture = gdxTexture; - } - - @Override - protected void error(final Exception e) { - e.printStackTrace(); - } - - @Override - public void bind(final int unit) { - this.viewer.webGL.bindTexture(this, unit); - } - - @Override - public void internalBind() { - this.gdxTexture.bind(); - } - - @Override - public int getWidth() { - return this.gdxTexture.getWidth(); - } - - @Override - public int getHeight() { - return this.gdxTexture.getHeight(); - } - - @Override - public int getGlTarget() { - return this.gdxTexture.glTarget; - } - - @Override - public int getGlHandle() { - return this.gdxTexture.getTextureObjectHandle(); - } - - @Override - public void setWrapS(final boolean wrapS) { - this.gdxTexture.setWrap(wrapS ? TextureWrap.Repeat : TextureWrap.ClampToEdge, this.gdxTexture.getVWrap()); - } - - @Override - public void setWrapT(final boolean wrapT) { - this.gdxTexture.setWrap(this.gdxTexture.getUWrap(), wrapT ? TextureWrap.Repeat : TextureWrap.ClampToEdge); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/GenericNode.java b/core/src/com/etheller/warsmash/viewer5/GenericNode.java deleted file mode 100644 index bc4f4f00..00000000 --- a/core/src/com/etheller/warsmash/viewer5/GenericNode.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.util.List; - -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Quaternion; -import com.badlogic.gdx.math.Vector3; - -public abstract class GenericNode { - - public Vector3 pivot; - public Vector3 localLocation; - public Quaternion localRotation; - public Vector3 localScale; - public Vector3 worldLocation; - public Quaternion worldRotation; - public Vector3 worldScale; - public Vector3 inverseWorldLocation; - public Quaternion inverseWorldRotation; - public Vector3 inverseWorldScale; - public Matrix4 localMatrix; - public Matrix4 worldMatrix; - public GenericNode parent; - public List children; - public boolean dontInheritTranslation; - public boolean dontInheritRotation; - public boolean dontInheritScaling; - public boolean visible; - public boolean wasDirty; - public boolean dirty; - - protected abstract void update(float dt, Scene scene); -} diff --git a/core/src/com/etheller/warsmash/viewer5/GenericResource.java b/core/src/com/etheller/warsmash/viewer5/GenericResource.java deleted file mode 100644 index 79ff358f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/GenericResource.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.io.InputStream; - -import com.etheller.warsmash.common.LoadGenericCallback; - -public final class GenericResource extends Resource { - - public Object data; // TODO this likely won't work, just brainstorming until I get to the part of - // using the data - private final LoadGenericCallback callback; - - public GenericResource(final ModelViewer viewer, final String extension, final PathSolver pathSolver, - final String fetchUrl, final LoadGenericCallback callback) { - super(viewer, extension, pathSolver, fetchUrl); - this.callback = callback; - } - - @Override - protected void lateLoad() { - - } - - @Override - protected void load(final InputStream src, final Object options) { - this.data = this.callback.call(src); - - } - - @Override - protected void error(final Exception e) { - e.printStackTrace(); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/Grid.java b/core/src/com/etheller/warsmash/viewer5/Grid.java deleted file mode 100644 index ee2b4276..00000000 --- a/core/src/com/etheller/warsmash/viewer5/Grid.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import com.badlogic.gdx.math.Vector3; - -public class Grid { - private final float x; - private final float y; - private final int width; - private final int depth; - private final int cellWidth; - private final int cellDepth; - private final int columns; - private final int rows; - final GridCell[] cells; - - public Grid(final float x, final float y, final int width, final int depth, final int cellWidth, - final int cellDepth) { - final int columns = width / cellWidth; - final int rows = depth / cellDepth; - - this.x = x; - this.y = y; - this.width = width; - this.depth = depth; - this.cellWidth = cellWidth; - this.cellDepth = cellDepth; - this.columns = columns; - this.rows = rows; - this.cells = new GridCell[rows * columns]; - - for (int row = 0; row < rows; row++) { - for (int column = 0; column < columns; column++) { - final float left = x + (column * cellWidth); - final float right = left + cellWidth; - final float bottom = y + (row * cellDepth); - final float top = bottom + cellDepth; - - this.cells[(row * columns) + column] = new GridCell(left, right, bottom, top); - } - } - } - - public void add(final ModelInstance instance) { - final int left = instance.left; - final int right = instance.right + 1; - final int bottom = instance.bottom; - final int top = instance.top + 1; - - if (left != -1) { - for (int y = bottom; y < top; y++) { - for (int x = left; x < right; x++) { - this.cells[(y * this.columns) + x].add(instance); - } - } - } - } - - public void remove(final ModelInstance instance) { - final int left = instance.left; - final int right = instance.right + 1; - final int bottom = instance.bottom; - final int top = instance.top + 1; - - if (left != -1) { - instance.left = -1; - - for (int y = bottom; y < top; y++) { - for (int x = left; x < right; x++) { - this.cells[(y * this.columns) + x].remove(instance); - } - } - } - } - - public void moved(final ModelInstance instance, final float upcomingX, final float upcomingY) { - final Bounds bounds = instance.model.bounds; - final float x = (upcomingX + bounds.x) - this.x; - final float y = (upcomingY + bounds.y) - this.y; - final float r = bounds.r; - final Vector3 s = instance.worldScale; - int left = (int) (Math.floor((x - (r * s.x)) / this.cellWidth)); - int right = (int) (Math.floor((x + (r * s.x)) / this.cellWidth)); - int bottom = (int) (Math.floor((y - (r * s.y)) / this.cellDepth)); - int top = (int) (Math.floor((y + (r * s.y)) / this.cellDepth)); - - if ((right < 0) || (left > (this.columns - 1)) || (top < 0) || (bottom > (this.rows - 1))) { - // The instance is outside of the grid, so remove it. - this.remove(instance); - } - else { - // Clamp the values so they are in the grid. - left = Math.max(left, 0); - right = Math.min(right, this.columns - 1); - bottom = Math.max(bottom, 0); - top = Math.min(top, this.rows - 1); - - // If the values actually changed, update the cells. - if ((left != instance.left) || (right != instance.right) || (bottom != instance.bottom) - || (top != instance.top)) { - /// TODO: This can be optimized by checking if there are shared cells. - /// That can be done in precisely the same way as done a few lines above, i.e. - /// simple rectangle intersection. - this.remove(instance); - - instance.left = left; - instance.right = right; - instance.bottom = bottom; - instance.top = top; - - this.add(instance); - } - } - } - - public void clear() { - for (final GridCell cell : this.cells) { - cell.clear(); - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/GridCell.java b/core/src/com/etheller/warsmash/viewer5/GridCell.java deleted file mode 100644 index a3c035d2..00000000 --- a/core/src/com/etheller/warsmash/viewer5/GridCell.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.RenderMathUtils; - -public class GridCell { - public final float left; - public final float right; - public final float bottom; - public final float top; - public int plane; - final List instances; - public final boolean visible; - - public GridCell(final float left, final float right, final float bottom, final float top) { - this.left = left; - this.right = right; - this.bottom = bottom; - this.top = top; - this.plane = -1; - this.instances = new ArrayList(); - this.visible = false; - } - - public void add(final ModelInstance instance) { - this.instances.add(instance); - } - - public void remove(final ModelInstance instance) { - this.instances.remove(instance); - } - - public void clear() { - this.instances.clear(); - } - - public boolean isVisible(final Camera camera) { - this.plane = RenderMathUtils.testCell(camera.planes, this.left, this.right, this.bottom, this.top, this.plane); - - return this.plane == -1; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/HandlerResource.java b/core/src/com/etheller/warsmash/viewer5/HandlerResource.java deleted file mode 100644 index fac3d88c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/HandlerResource.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import com.etheller.warsmash.viewer5.handlers.ResourceHandler; - -public abstract class HandlerResource extends Resource { - public final HANDLER handler; - - public HandlerResource(final ModelViewer viewer, final String extension, final PathSolver pathSolver, - final String fetchUrl, final HANDLER handler) { - super(viewer, extension, pathSolver, fetchUrl); - this.handler = handler; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/Model.java b/core/src/com/etheller/warsmash/viewer5/Model.java deleted file mode 100644 index fbedd8f8..00000000 --- a/core/src/com/etheller/warsmash/viewer5/Model.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.viewer5.handlers.ModelHandler; - -public abstract class Model extends HandlerResource { - public final Bounds bounds; - public List preloadedInstances; - - public Model(final HANDLER handler, final ModelViewer viewer, final String extension, final PathSolver pathSolver, - final String fetchUrl) { - super(viewer, extension, pathSolver, fetchUrl, handler); - this.bounds = new Bounds(); - this.preloadedInstances = new ArrayList<>(); - } - - protected abstract ModelInstance createInstance(int type); - - public ModelInstance addInstance() { - return addInstance(0); - } - - public ModelInstance addInstance(final int type) { - final ModelInstance instance = createInstance(type); - - if (this.ok) { - instance.load(); - } - else { - this.preloadedInstances.add(instance); - } - - return instance; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/ModelInstance.java b/core/src/com/etheller/warsmash/viewer5/ModelInstance.java deleted file mode 100644 index c145516d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/ModelInstance.java +++ /dev/null @@ -1,229 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.util.Vector4; - -public abstract class ModelInstance extends Node { - - public int left; - public int right; - public int bottom; - public int top; - public int plane; - public float depth; - public int updateFrame; - public int cullFrame; - public Model model; - public TextureMapper textureMapper; - public boolean paused; - public boolean rendered; - - public Scene scene; - - public ModelInstance(final Model model) { - this.scene = null; - this.left = -1; - this.right = -1; - this.bottom = -1; - this.top = -1; - this.plane = -1; - this.depth = 0; - this.updateFrame = 0; - this.cullFrame = 0; - this.model = model; - this.textureMapper = model.viewer.baseTextureMapper(this); - this.paused = false; - this.rendered = true; - } - - public void setTexture(final int index, final Texture texture) { - this.textureMapper = this.model.viewer.changeTextureMapper(this, index, texture); - } - - public void show() { - this.rendered = true; - } - - public void hide() { - this.rendered = false; - } - - public boolean shown() { - return this.rendered; - } - - public boolean hidden() { - return !this.rendered; - } - - public boolean detach() { - if (this.scene != null) { - return this.scene.removeInstance(this); - } - - return false; - } - - public abstract void updateAnimations(float dt); - - public abstract void clearEmittedObjects(); - - @Override - protected final void updateObject(final float dt, final Scene scene) { - if (this.updateFrame < this.model.viewer.frame) { - if (this.rendered && !this.paused) { - this.updateAnimations(dt); - } - } - - this.updateLights(scene); - - this.updateFrame = this.model.viewer.frame; - } - - protected abstract void updateLights(Scene scene2); - - public boolean setScene(final Scene scene) { - return scene.addInstance(this); - } - - @Override - public Node move(final float[] offset) { - final Node result = super.move(offset); - updateSceneGridLocationInfo(); - return result; - } - - @Override - public Node moveTo(final float[] offset) { - final Node result = super.moveTo(offset); - updateSceneGridLocationInfo(); - return result; - } - - @Override - public Node setLocation(final float x, final float y, final float z) { - final Node result = super.setLocation(x, y, z); - updateSceneGridLocationInfo(); - return result; - } - - @Override - public Node setLocation(final float[] location) { - final Node result = super.setLocation(location); - updateSceneGridLocationInfo(); - return result; - } - - @Override - public Node setLocation(final Vector3 location) { - final Node result = super.setLocation(location); - updateSceneGridLocationInfo(); - return result; - } - - private void updateSceneGridLocationInfo() { - if (this.scene != null) { - // can't just use world location if it moves - float x, y; - if (this.dirty) { - // TODO this is an incorrect, predicted location for dirty case - if ((this.parent != null) && !this.dontInheritTranslation) { - x = this.parent.localLocation.x + this.localLocation.x; - y = this.parent.localLocation.y + this.localLocation.y; - } - else { - x = this.localLocation.x; - y = this.localLocation.y; - } - } - else { - x = this.worldLocation.x; - y = this.worldLocation.y; - } - this.scene.instanceMoved(this, x, y); - } - } - - @Override - public void recalculateTransformation() { - super.recalculateTransformation(); - - if (this.scene != null) { - this.scene.instanceMoved(this, this.worldLocation.x, this.worldLocation.y); - } - } - - public boolean isVisible(final Camera camera) { - // can't just use world location if it moves - float x, y, z; - float sx, sy, sz; - if (this.dirty) { - // TODO this is an incorrect, predicted location for dirty case - if ((this.parent != null) && !this.dontInheritTranslation) { - x = this.parent.localLocation.x + this.localLocation.x; - y = this.parent.localLocation.y + this.localLocation.y; - z = this.parent.localLocation.z + this.localLocation.z; - sx = this.parent.localScale.x * this.localScale.x; - sy = this.parent.localScale.y * this.localScale.y; - sz = this.parent.localScale.z * this.localScale.z; - } - else { - x = this.localLocation.x; - y = this.localLocation.y; - z = this.localLocation.z; - sx = this.localScale.x; - sy = this.localScale.y; - sz = this.localScale.z; - } - } - else { - x = this.worldLocation.x; - y = this.worldLocation.y; - z = this.worldLocation.z; - sx = this.worldScale.x; - sy = this.worldScale.y; - sz = this.worldScale.z; - } - // Get the biggest scaling dimension. - if (sy > sx) { - sx = sy; - } - - if (sz > sx) { - sx = sz; - } - - final Bounds bounds = this.model.bounds; - final Vector4[] planes = camera.planes; - - this.plane = RenderMathUtils.testSphere(planes, x + bounds.x, y + bounds.y, z + bounds.z, bounds.r * sx, - this.plane); - - if (this.plane == -1) { - this.depth = RenderMathUtils.distanceToPlane3(planes[4], x, y, z); - - return true; - } - - return false; - } - - public boolean isBatched() { - return false; - } - - public abstract void renderOpaque(Matrix4 mvp); - - public abstract void renderTranslucent(); - - public abstract void load(); - - protected abstract RenderBatch getBatch(TextureMapper textureMapper2); - - public abstract void setReplaceableTexture(int replaceableTextureId, String replaceableTextureFile); - - protected abstract void removeLights(Scene scene2); -} diff --git a/core/src/com/etheller/warsmash/viewer5/ModelViewer.java b/core/src/com/etheller/warsmash/viewer5/ModelViewer.java deleted file mode 100644 index 730d2423..00000000 --- a/core/src/com/etheller/warsmash/viewer5/ModelViewer.java +++ /dev/null @@ -1,380 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.etheller.warsmash.common.FetchDataTypeName; -import com.etheller.warsmash.common.LoadGenericCallback; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.viewer5.gl.ClientBuffer; -import com.etheller.warsmash.viewer5.gl.WebGL; -import com.etheller.warsmash.viewer5.handlers.ResourceHandler; -import com.etheller.warsmash.viewer5.handlers.ResourceHandlerConstructionParams; - -public abstract class ModelViewer { - public DataSource dataSource; - public final CanvasProvider canvas; - public List resources; - public Map fetchCache; - public int frameTime; - public GL20 gl; - public WebGL webGL; - public List scenes; - private int visibleCells; - private int visibleInstances; - private int updatedParticles; - public int frame; - public final int rectBuffer; - public ClientBuffer buffer; - public boolean audioEnabled; - private final Map> textureMappers; - private final Set handlers; - - public ModelViewer(final DataSource dataSource, final CanvasProvider canvas) { - this.dataSource = dataSource; - this.canvas = canvas; - this.resources = new ArrayList<>(); - this.fetchCache = new HashMap<>(); - this.handlers = new HashSet(); - this.frameTime = 1000 / 60; - this.gl = Gdx.gl; - this.webGL = new WebGL(this.gl); - this.scenes = new ArrayList<>(); - this.visibleCells = 0; - this.visibleInstances = 0; - this.updatedParticles = 0; - - this.frame = 0; - - this.rectBuffer = this.gl.glGenBuffer(); - this.buffer = new ClientBuffer(this.gl); - this.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.rectBuffer); - final ByteBuffer temp = ByteBuffer.allocateDirect(6).order(ByteOrder.nativeOrder()); - temp.put((byte) 0); - temp.put((byte) 1); - temp.put((byte) 2); - temp.put((byte) 0); - temp.put((byte) 2); - temp.put((byte) 3); - temp.clear(); - this.gl.glBufferData(GL20.GL_ARRAY_BUFFER, temp.capacity(), temp, GL20.GL_STATIC_DRAW); - this.audioEnabled = false; - this.textureMappers = new HashMap>(); - } - - public void setDataSource(final DataSource dataSource) { - this.dataSource = dataSource; - } - - public boolean enableAudio() { - this.audioEnabled = true; - return this.audioEnabled; - } - - public boolean addHandler(ResourceHandler handler) { - if (handler != null) { - - // Allow to pass also the handler's module for convenience. - if (handler.handler != null) { - handler = handler.handler; - } - - if (!this.handlers.contains(handler)) { - // Check if the handler has a loader, and if so load it. - if (handler.load && !handler.load(this)) { - onResourceLoadError(); - return false; - } - - this.handlers.add(handler); - - return true; - } - } - return false; - } - - public Scene addSimpleScene() { - final Scene scene = new SimpleScene(this, createLightManager(true)); - - this.scenes.add(scene); - - return scene; - } - - public WorldScene addWorldScene() { - final WorldScene scene = new WorldScene(this, createLightManager(false)); - - this.scenes.add(scene); - - return scene; - } - - public boolean removeScene(final Scene scene) { - return this.scenes.remove(scene); - } - - public void clear() { - this.scenes.clear(); - } - - public Object[] findHandler(final String ext) { - for (final ResourceHandler handler : this.handlers) { - for (final String[] extension : handler.extensions) { - if (extension[0].equals(ext)) { - return new Object[] { handler, extension[1] }; - } - } - } - return null; - } - - public Resource load(final String src, final PathSolver pathSolver, final Object solverParams) { - String finalSrc = src; - String extension = ""; - boolean isFetch = false; - - // If a given path solver, resolve. - if (pathSolver != null) { - final SolvedPath solved = pathSolver.solve(src, solverParams); - - finalSrc = solved.getFinalSrc(); - if (!this.dataSource.has(finalSrc)) { - final String ddsPath = finalSrc.substring(0, finalSrc.lastIndexOf('.')) + ".dds"; - if (this.dataSource.has(ddsPath)) { - finalSrc = ddsPath; - } - else { - System.err.println("Attempting to load non-existant file: " + finalSrc); - } - } - extension = solved.getExtension(); - isFetch = solved.isFetch(); - - if (!(extension instanceof String)) { - throw new IllegalStateException("The path solver did not return an extension!"); - } - - if (extension.charAt(0) != '.') { - extension = '.' + extension; - } - // Built-in texture sources - // ---- TODO not using JS code here - - final Object[] handlerAndDataType = this.findHandler(extension.toLowerCase()); - - // Is there a handler for this file type? - if (handlerAndDataType != null) { - if (isFetch) { - final Resource resource = this.fetchCache.get(finalSrc); - - if (resource != null) { - return resource; - } - } - - final ResourceHandler handler = (ResourceHandler) handlerAndDataType[0]; - final Resource resource = handler.construct(new ResourceHandlerConstructionParams(this, handler, - extension, pathSolver, isFetch ? finalSrc : "")); - - this.resources.add(resource); - -// if (isFetch) { - this.fetchCache.put(finalSrc, resource); -// } - - // TODO this is a synchronous hack, skipped some Ghostwolf code - try { - resource.loadData(this.dataSource.getResourceAsStream(finalSrc), null); - } - catch (final IOException e) { - throw new IllegalStateException("Unable to load data: " + finalSrc); - } - - return resource; - } - else { - throw new IllegalStateException("Missing handler for: " + finalSrc); - } - } - else { - throw new IllegalStateException( - "Could not resolve " + finalSrc + ". Did you forget to pass a path solver?"); - } - - } - - public boolean has(final String key) { - return this.fetchCache.containsKey(key); - } - - public Resource get(final String key) { - return this.fetchCache.get(key); - } - - public GenericResource loadGeneric(final String path, final FetchDataTypeName dataType, - final LoadGenericCallback callback) { - return loadGeneric(path, dataType, callback, this.dataSource); - } - - /** - * Load something generic. - * - * Unlike load(), this does not use handlers or construct any internal objects. - * - * `dataType` can be one of: `"image"`, `"string"`, `"arrayBuffer"`, `"blob"`. - * - * If `callback` isn't given, the resource's `data` is the fetch data, according - * to `dataType`. - * - * If `callback` is given, the resource's `data` is the value returned by it - * when called with the fetch data. - * - * If `callback` returns a promise, the resource's `data` will be whatever the - * promise resolved to. - */ - public GenericResource loadGeneric(final String path, final FetchDataTypeName dataType, - final LoadGenericCallback callback, final DataSource dataSource) { - final Resource cachedResource = this.fetchCache.get(path); - - if (cachedResource != null) { - // Technically also non-generic resources can be returned here, since the fetch - // cache is shared. - // That being said, this should be used for generic resources, and it makes the - // typing a lot easier. - return (GenericResource) cachedResource; - } - - final GenericResource resource = new GenericResource(this, null, null, path, callback); - - this.resources.add(resource); - this.fetchCache.put(path, resource); - - // TODO this is a synchronous hack, skipped some Ghostwolf code - try { - resource.loadData(dataSource.getResourceAsStream(path), null); - } - catch (final IOException e) { - throw new IllegalStateException("Unable to load data: " + path); - } - - return resource; - - } - - public void updateAndRender() { - this.update(); - this.startFrame(); - this.render(); - } - -// public Resource loadGeneric(String path, String dataType, ) - - public boolean unload(final Resource resource) { - // TODO Auto-generated method stub - final String fetchUrl = resource.fetchUrl; - if (!"".equals(fetchUrl)) { - this.fetchCache.remove(fetchUrl); - } - return this.resources.remove(resource); - } - - public void update() { - final float dt = Gdx.graphics.getRawDeltaTime();// this.frameTime * 0.001f; - - this.frame += 1; - - this.visibleCells = 0; - this.visibleInstances = 0; - this.updatedParticles = 0; - - for (final Scene scene : this.scenes) { - scene.update(dt); - - this.visibleCells += scene.visibleCells; - this.visibleInstances += scene.visibleInstances; - this.updatedParticles += scene.updatedParticles; - } - } - - public void startFrame() { - Gdx.gl.glScissor(0, 0, (int) this.canvas.getWidth(), (int) this.canvas.getHeight()); - this.gl.glDepthMask(true); - this.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); -// WarsmashGdxGame.bindDefaultVertexArray(); - } - - public void render() { - for (final Scene scene : this.scenes) { - scene.startFrame(); - } - this.renderOpaque(); - this.renderTranslucent(); - } - - private void renderOpaque() { - for (final Scene scene : this.scenes) { - scene.renderOpaque(); - } - } - - private void renderTranslucent() { - for (final Scene scene : this.scenes) { - scene.renderTranslucent(); - } - } - - public TextureMapper baseTextureMapper(final ModelInstance instance) { - final Model model = instance.model; - List mappers = this.textureMappers.get(model); - if (mappers == null) { - mappers = new ArrayList<>(); - this.textureMappers.put(model, mappers); - } - if (mappers.isEmpty()) { - mappers.add(new TextureMapper(model)); - } - return mappers.get(0); - } - - public TextureMapper changeTextureMapper(final ModelInstance instance, final Object key, final Texture texture) { - final Map map = new HashMap<>(instance.textureMapper.textures); - - if (texture instanceof Texture) { // not null? - map.put(key, texture); - } - else { - map.remove(key); - } - - final Model model = instance.model; - final List mappers = this.textureMappers.get(model); - - for (final TextureMapper mapper : mappers) { - if (mapper.textures.equals(map)) { - return mapper; - } - } - - final TextureMapper mapper = new TextureMapper(model, map); - - mappers.add(mapper); - - return mapper; - } - - private void onResourceLoadError() { - System.err.println("error, this, InvalidHandler, FailedToLoad"); - } - - public abstract SceneLightManager createLightManager(boolean simple); -} diff --git a/core/src/com/etheller/warsmash/viewer5/Node.java b/core/src/com/etheller/warsmash/viewer5/Node.java deleted file mode 100644 index e17d1e9f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/Node.java +++ /dev/null @@ -1,328 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Quaternion; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.util.Descriptor; -import com.etheller.warsmash.util.RenderMathUtils; - -public abstract class Node extends GenericNode { - protected static final Vector3 locationHeap = new Vector3(); - protected static final Quaternion rotationHeap = new Quaternion(); - protected static final Vector3 scalingHeap = new Vector3(); - - public Node() { - this.pivot = new Vector3(); - this.localLocation = new Vector3(); - this.localRotation = new Quaternion(); - this.localScale = new Vector3(1, 1, 1); - this.worldLocation = new Vector3(); - this.worldRotation = new Quaternion(); - this.worldScale = new Vector3(1, 1, 1); - this.inverseWorldLocation = new Vector3(); - this.inverseWorldRotation = new Quaternion(); - this.inverseWorldScale = new Vector3(); - this.localMatrix = new Matrix4(); -// this.localMatrix.val[0] = 1; -// this.localMatrix.val[5] = 1; -// this.localMatrix.val[10] = 1; -// this.localMatrix.val[15] = 1; - this.worldMatrix = new Matrix4(); - this.parent = null; - this.children = new ArrayList<>(); - this.dontInheritTranslation = false; - this.dontInheritRotation = false; - this.dontInheritScaling = false; - - this.visible = true; - this.wasDirty = false; - this.dirty = true; - } - - public Node setPivot(final float[] pivot) { - this.pivot.set(pivot); - this.dirty = true; - return this; - } - - public Node setLocation(final float x, final float y, final float z) { - this.localLocation.set(x, y, z); - this.dirty = true; - return this; - } - - public Node setLocation(final float[] location) { - this.localLocation.set(location); - this.dirty = true; - return this; - } - - public Node setLocation(final Vector3 location) { - this.localLocation.set(location); - this.dirty = true; - return this; - } - - public Node setRotation(final float[] rotation) { - this.localRotation.set(rotation[0], rotation[1], rotation[2], rotation[3]); - this.dirty = true; - return this; - } - - public Node setScale(final float[] varying) { - this.localScale.set(varying); - this.dirty = true; - return this; - } - - public Node setUniformScale(final float uniform) { - this.localScale.set(uniform, uniform, uniform); - this.dirty = true; - return this; - } - - public Node setTransformation(final Vector3 location, final Quaternion rotation, final Vector3 scale) { - // TODO for performance, Ghostwolf did a direct field write on everything here. - // I'm hoping we can get Java's JIT to just figure it out and do it on its own - this.localLocation.set(location); - this.localRotation.set(rotation); - this.localScale.set(scale); - this.dirty = true; - return this; - } - - public Node resetTransformation() { - this.pivot.set(Vector3.Zero); - this.localLocation.set(Vector3.Zero); - this.localRotation.set(RenderMathUtils.QUAT_DEFAULT); - this.localScale.set(RenderMathUtils.VEC3_ONE); - - this.dirty = true; - return this; - } - - public Node movePivot(final float[] offset) { - this.pivot.add(offset[0], offset[1], offset[2]); - - this.dirty = true; - - return this; - } - - public Node move(final float[] offset) { - this.localLocation.add(offset[0], offset[1], offset[2]); - - this.dirty = true; - - return this; - } - - public Node moveTo(final float[] offset) { - this.localLocation.set(offset[0], offset[1], offset[2]); - - this.dirty = true; - - return this; - } - - public Node rotate(final Quaternion rotation) { - RenderMathUtils.mul(this.localRotation, this.localRotation, rotation); - - this.dirty = true; - - return this; - } - - public Node setLocalRotation(final Quaternion rotation) { - this.localRotation.set(rotation); - - this.dirty = true; - - return this; - } - - public Node rotateLocal(final Quaternion rotation) { - RenderMathUtils.mul(this.localRotation, rotation, this.localRotation); - - this.dirty = true; - - return this; - } - - public Node scale(final float[] scale) { - this.localScale.x *= scale[0]; - this.localScale.y *= scale[1]; - this.localScale.z *= scale[2]; - - this.dirty = true; - - return this; - } - - public Node uniformScale(final float scale) { - this.localScale.x *= scale; - this.localScale.y *= scale; - this.localScale.z *= scale; - - this.dirty = true; - - return this; - } - - public Node setParent(final GenericNode parent) { - if (this.parent != null) { - this.parent.children.remove(this); - } - - this.parent = parent; - - if (parent != null) { - parent.children.add(this); - } - - this.dirty = true; - - return this; - } - - public void recalculateTransformation() { - boolean dirty = this.dirty; - final GenericNode parent = this.parent; - - this.wasDirty = this.dirty; - - if (parent != null) { - dirty = dirty || parent.wasDirty; - } - - this.wasDirty = dirty; - - if (dirty) { - this.dirty = false; - - if (parent != null) { - Vector3 computedLocation; - Quaternion computedRotation; - Vector3 computedScaling; - - final Vector3 parentPivot = parent.pivot; - - computedLocation = locationHeap; - computedLocation.x = this.localLocation.x + parentPivot.x; - computedLocation.y = this.localLocation.y + parentPivot.y; - computedLocation.z = this.localLocation.z + parentPivot.z; - - if (this.dontInheritRotation) { - computedRotation = rotationHeap; - - computedRotation.set(this.localRotation); - computedRotation.mul(parent.inverseWorldRotation); - } - else { - computedRotation = this.localRotation; - } - - if (this.dontInheritScaling) { - computedScaling = scalingHeap; - - final Vector3 parentInverseScale = parent.inverseWorldScale; - computedScaling.x = parentInverseScale.x * this.localScale.x; - computedScaling.y = parentInverseScale.y * this.localScale.y; - computedScaling.z = parentInverseScale.z * this.localScale.z; - - this.worldScale.x = this.localScale.x; - this.worldScale.y = this.localScale.y; - this.worldScale.z = this.localScale.z; - } - else { - computedScaling = this.localScale; - - final Vector3 parentScale = parent.worldScale; - this.worldScale.x = parentScale.x * this.localScale.x; - this.worldScale.y = parentScale.y * this.localScale.y; - this.worldScale.z = parentScale.z * this.localScale.z; - } - - RenderMathUtils.fromRotationTranslationScale(computedRotation, computedLocation, computedScaling, - this.localMatrix); - - RenderMathUtils.mul(this.worldMatrix, parent.worldMatrix, this.localMatrix); - - RenderMathUtils.mul(this.worldRotation, parent.worldRotation, computedRotation); - } - else { - RenderMathUtils.fromRotationTranslationScale(this.localRotation, this.localLocation, this.localScale, - this.localMatrix); - - this.worldMatrix.set(this.localMatrix); - - this.worldRotation.set(this.localRotation); - - this.worldScale.set(this.localScale); - } - } - - // Inverse world rotation - this.inverseWorldRotation.x = -this.worldRotation.x; - this.inverseWorldRotation.y = -this.worldRotation.y; - this.inverseWorldRotation.z = -this.worldRotation.z; - this.inverseWorldRotation.w = this.worldRotation.w; - - // Inverse world scale - this.inverseWorldScale.x = 1 / this.worldScale.x; - this.inverseWorldScale.y = 1 / this.worldScale.y; - this.inverseWorldScale.z = 1 / this.worldScale.z; - - // World location - this.worldLocation.x = this.worldMatrix.val[Matrix4.M03]; - this.worldLocation.y = this.worldMatrix.val[Matrix4.M13]; - this.worldLocation.z = this.worldMatrix.val[Matrix4.M23]; - - // Inverse world location - this.inverseWorldLocation.x = -this.worldLocation.x; - this.inverseWorldLocation.y = -this.worldLocation.y; - this.inverseWorldLocation.z = -this.worldLocation.z; - - } - - @Override - public void update(final float dt, final Scene scene) { - if (this.dirty || ((this.parent != null) && this.parent.wasDirty)) { - this.dirty = true; // in case this node isn't dirty, but the parent was - this.wasDirty = true; - this.recalculateTransformation(); - } - else { - this.wasDirty = false; - } - - - this.updateObject(dt, scene); - this.updateChildren(dt, scene); - } - - protected abstract void updateObject(float dt, Scene scene); - - private void updateChildren(final float dt, final Scene scene) { - final int childrenSize = this.children.size(); - for (int i = 0; i < childrenSize; i++) { - this.children.get(i).update(dt, scene); - } - } - - public static Object[] createSkeletalNodes(final int count, - final Descriptor nodeDescriptor) { - final List nodes = new ArrayList<>(); - final List worldMatrices = new ArrayList<>(); - for (int i = 0; i < count; i++) { - final NODE node = nodeDescriptor.create(); - nodes.add(node); - worldMatrices.add(node.worldMatrix); - } - final Object[] data = { nodes, worldMatrices }; - return data; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/PathSolver.java b/core/src/com/etheller/warsmash/viewer5/PathSolver.java deleted file mode 100644 index 159e0973..00000000 --- a/core/src/com/etheller/warsmash/viewer5/PathSolver.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.etheller.warsmash.viewer5; - -public interface PathSolver { - SolvedPath solve(String src, Object solverParams); - - // We generally just use the default path solver. - // These things were apparently meant to work as the Ghostwolf's JavaScript's - // equivalent of the DataSource interface you will find in this Java repo. - // But I did not know that and wasn't sure what it was for, so I kept it in the - // port of his code. Eventually it should be removed. - public static final PathSolver DEFAULT = new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - final int dotIndex = src.lastIndexOf('.'); - if ((dotIndex == -1)) { - throw new IllegalStateException("unable to resolve: " + src); - } - return new SolvedPath(src, src.substring(dotIndex), true); - } - }; - public static final PathSolver NOFETCH = new PathSolver() { - @Override - public SolvedPath solve(final String src, final Object solverParams) { - final int dotIndex = src.lastIndexOf('.'); - if ((dotIndex == -1)) { - throw new IllegalStateException("unable to resolve: " + src); - } - return new SolvedPath(src, src.substring(dotIndex), false); - } - }; -} diff --git a/core/src/com/etheller/warsmash/viewer5/RawOpenGLTextureResource.java b/core/src/com/etheller/warsmash/viewer5/RawOpenGLTextureResource.java deleted file mode 100644 index 0d099156..00000000 --- a/core/src/com/etheller/warsmash/viewer5/RawOpenGLTextureResource.java +++ /dev/null @@ -1,157 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.awt.image.BufferedImage; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.GL30; -import com.etheller.warsmash.viewer5.handlers.ResourceHandler; - -/** - * Similar to GdxTextureResource, but now I'm probably replacing use of that one - * with this one. I'm trying to fight the system here and avoid porting - * Ghostwolf's BLP parser to java, and just use the Java BLP parser that I - * already had, but the libraries are not playing nicely with each other, so - * this class is written to be a lower level solution (OpenGL calls instead of - * LibGDX api) that will work. - * - * My theory is that because doing it THIS way works on Retera Model Studio, - * therefore it should work here as well. - */ -public abstract class RawOpenGLTextureResource extends Texture { - private static final int BYTES_PER_PIXEL = 4; - private final int target; - protected int handle; - private int width; - private int height; - private int wrapS = GL20.GL_CLAMP_TO_EDGE; - private int wrapT = GL20.GL_CLAMP_TO_EDGE; - private final int magFilter = GL20.GL_LINEAR; - private final int minFilter = GL20.GL_LINEAR; - private ByteBuffer data; - - public RawOpenGLTextureResource(final ModelViewer viewer, final String extension, final PathSolver pathSolver, - final String fetchUrl, final ResourceHandler handler) { - super(viewer, extension, pathSolver, fetchUrl, handler); - final GL20 gl = this.viewer.gl; - this.handle = gl.glGenTexture(); - this.target = GL20.GL_TEXTURE_2D; - gl.glBindTexture(this.target, this.handle); - gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER, this.minFilter); - gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER, this.magFilter); - } - - @Override - protected void error(final Exception e) { - e.printStackTrace(); - } - - @Override - public void bind(final int unit) { - this.viewer.webGL.bindTexture(this, unit); - } - - @Override - public void internalBind() { - this.viewer.gl.glBindTexture(this.target, this.handle); - this.viewer.gl.glTexParameteri(this.target, GL20.GL_TEXTURE_WRAP_S, this.wrapS); - this.viewer.gl.glTexParameteri(this.target, GL20.GL_TEXTURE_WRAP_T, this.wrapT); - } - - @Override - public int getWidth() { - return this.width; - } - - @Override - public int getHeight() { - return this.height; - } - - @Override - public int getGlTarget() { - return this.target; - } - - @Override - public int getGlHandle() { - return this.handle; - } - - @Override - public void setWrapS(final boolean wrapS) { - this.wrapS = wrapS ? GL20.GL_REPEAT : GL20.GL_CLAMP_TO_EDGE; - final GL20 gl = this.viewer.gl; - } - - @Override - public void setWrapT(final boolean wrapT) { - this.wrapT = wrapT ? GL20.GL_REPEAT : GL20.GL_CLAMP_TO_EDGE; - final GL20 gl = this.viewer.gl; - } - - public void update(final BufferedImage image, final boolean sRGBFix) { - final GL20 gl = this.viewer.gl; - - final int imageWidth = image.getWidth(); - final int imageHeight = image.getHeight(); - final int[] pixels = new int[imageWidth * imageHeight]; - image.getRGB(0, 0, imageWidth, imageHeight, pixels, 0, imageWidth); - - final ByteBuffer buffer = ByteBuffer.allocateDirect(imageWidth * imageHeight * BYTES_PER_PIXEL) - .order(ByteOrder.nativeOrder()); - // 4 - // for - // RGBA, - // 3 - // for - // RGB - - for (int y = 0; y < imageHeight; y++) { - for (int x = 0; x < imageWidth; x++) { - final int pixel = pixels[(y * imageWidth) + x]; - buffer.put((byte) ((pixel >> 16) & 0xFF)); // Red component - buffer.put((byte) ((pixel >> 8) & 0xFF)); // Green component - buffer.put((byte) (pixel & 0xFF)); // Blue component - buffer.put((byte) ((pixel >> 24) & 0xFF)); // Alpha component. - // Only for RGBA - } - } - - buffer.flip(); - this.data = buffer; - - gl.glBindTexture(GL20.GL_TEXTURE_2D, this.handle); - -// if ((this.width == imageWidth) && (this.height == imageHeight)) { -// gl.glTexSubImage2D(GL20.GL_TEXTURE_2D, 0, 0, 0, imageWidth, imageHeight, GL20.GL_RGBA, -// GL20.GL_UNSIGNED_BYTE, buffer); -// } -// else { - gl.glTexImage2D(GL20.GL_TEXTURE_2D, 0, sRGBFix ? GL30.GL_SRGB8_ALPHA8 : GL30.GL_RGBA8, imageWidth, imageHeight, - 0, GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, buffer); - - this.width = imageWidth; - this.height = imageHeight; -// } - } - - /** - * I really don't like holding the reference to the original buffer like this. - * Seems wasteful. It's already on the GPU. However, while porting some code for - * shadow maps I hit a point where I really finally felt obligated to add this - * (there is some code in the Terrain stuff that should've had this, but - * doesn't, and does its own texture management as a result). - * - * So, as a note to future authors, please reinvent the system such that this - * cached buffer data is only stored for shadow maps and terrain textures or - * whatever. Right now, this holds a reference to these guys on every texture, - * on every unit, on every doodad, etc. Java will not be able to garbage collect - * them because we hold on to the buffer in "update()". - */ - public ByteBuffer getData() { - return this.data; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/RenderBatch.java b/core/src/com/etheller/warsmash/viewer5/RenderBatch.java deleted file mode 100644 index 83dbb4d2..00000000 --- a/core/src/com/etheller/warsmash/viewer5/RenderBatch.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.util.ArrayList; -import java.util.List; - -/** - * A render batch. - */ -public abstract class RenderBatch { - public Scene scene; - public Model model; - public TextureMapper textureMapper; - public List instances = new ArrayList<>(); - public int count = 0; - - public abstract void render(); - - public RenderBatch(final Scene scene, final Model model, final TextureMapper textureMapper) { - this.scene = scene; - this.model = model; - this.textureMapper = textureMapper; - } - - public void clear() { - this.count = 0; - } - - public void add(final ModelInstance instance) { - if (this.count == this.instances.size()) { - this.instances.add(instance); - } - else if (this.count > this.instances.size()) { - throw new IllegalStateException("count > size"); - } - else { - this.instances.set(this.count, instance); - } - this.count++; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/Resource.java b/core/src/com/etheller/warsmash/viewer5/Resource.java deleted file mode 100644 index cc9f619a..00000000 --- a/core/src/com/etheller/warsmash/viewer5/Resource.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.io.InputStream; - -public abstract class Resource { - public final ModelViewer viewer; - public final String extension; - public final String fetchUrl; - public boolean ok; - public boolean loaded; - public final PathSolver pathSolver; - public final Object solverParams = null; - - public Resource(final ModelViewer viewer, final String extension, final PathSolver pathSolver, - final String fetchUrl) { - this.viewer = viewer; - this.extension = extension; - this.pathSolver = pathSolver; - this.fetchUrl = fetchUrl; - this.ok = false; - this.loaded = false; - } - - public void loadData(final InputStream src, final Object options) { - this.loaded = true; - - try { - this.load(src, options); - this.ok = true; - this.lateLoad(); - } - catch (final Exception e) { - this.error(e); - } - } - - public boolean detach() { - return this.viewer.unload(this); - } - - protected abstract void lateLoad(); - - protected abstract void load(InputStream src, Object options); - - protected abstract void error(Exception e); -} diff --git a/core/src/com/etheller/warsmash/viewer5/ResourceLoader.java b/core/src/com/etheller/warsmash/viewer5/ResourceLoader.java deleted file mode 100644 index ce56cf85..00000000 --- a/core/src/com/etheller/warsmash/viewer5/ResourceLoader.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.etheller.warsmash.viewer5; - -public interface ResourceLoader { -} diff --git a/core/src/com/etheller/warsmash/viewer5/Scene.java b/core/src/com/etheller/warsmash/viewer5/Scene.java deleted file mode 100644 index 3b3b5934..00000000 --- a/core/src/com/etheller/warsmash/viewer5/Scene.java +++ /dev/null @@ -1,328 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.GL30; -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Rectangle; -import com.etheller.warsmash.viewer5.gl.Extensions; -import com.etheller.warsmash.viewer5.gl.WebGL; -import com.etheller.warsmash.viewer5.handlers.w3x.DynamicShadowManager; - -/** - * A scene. - * - * Every scene has its own list of model instances, and its own camera and - * viewport. - * - * In addition, in Ghostwolf's original code every scene may have its own - * AudioContext if enableAudio() is called. If audo is enabled, the - * AudioContext's listener's location will be updated automatically. Note that - * due to browser policies, this may be done only after user interaction with - * the web page. - * - * In "Warsmash", we are starting from an attempt to replicate Ghostwolf, but - * audio is always on in LibGDX generally. So we will probably simplify or skip - * over those behaviors other than a boolean on/off toggle for audio. - */ -public abstract class Scene { - - public final ModelViewer viewer; - public int visibleCells; - public int visibleInstances; - public final Camera camera; - public int updatedParticles; - public boolean audioEnabled; - public AudioContext audioContext; - - public final List instances; - public int currentInstance; - public final List batchedInstances; - public int currentBatchedInstance; - public final EmittedObjectUpdater emitterObjectUpdater; - public final Map batches; - public final Comparator instanceDepthComparator; - public DynamicShadowManager shadowManager; - /** - * Similar to WebGL's own `alpha` parameter. - * - * If false, the scene will be cleared before rendering, meaning that scenes - * behind it won't be visible through it. - * - * If true, alpha works as usual. - */ - public boolean alpha = false; - private final SceneLightManager lightManager; - - public Scene(final ModelViewer viewer, final SceneLightManager lightManager) { - final CanvasProvider canvas = viewer.canvas; - this.viewer = viewer; - this.camera = new Camera(); - - this.updatedParticles = 0; - - this.audioEnabled = false; - this.audioContext = null; - - // Use the whole canvas, and standard perspective projection values. - this.camera.viewport(new Rectangle(0, 0, canvas.getWidth(), canvas.getHeight())); - this.camera.perspective((float) (Math.PI / 4), canvas.getWidth() / canvas.getHeight(), 8, 10000); - - this.instances = new ArrayList<>(); - this.currentInstance = 0; - - this.batchedInstances = new ArrayList<>(); - this.currentBatchedInstance = 0; - - this.emitterObjectUpdater = new EmittedObjectUpdater(); - - this.batches = new HashMap<>(); - this.instanceDepthComparator = new InstanceDepthComparator(); - this.visibleCells = 0; - this.visibleInstances = 0; - - this.lightManager = lightManager; - } - - public boolean enableAudio() { - if (this.audioContext == null) { - this.audioContext = Extensions.audio.createContext(this instanceof WorldScene); - } - if (!this.audioContext.isRunning()) { - this.audioContext.resume(); - } - this.audioEnabled = this.audioContext.isRunning(); - return this.audioEnabled; - } - - public void disableAudio() { - if (this.audioContext != null) { - this.audioContext.suspend(); - } - this.audioEnabled = false; - } - - public boolean addInstance(final ModelInstance instance) { - if (instance.scene != this) { - if (instance.scene != null) { - instance.scene.removeInstance(instance); - } - - instance.scene = this; - - // Only allow instances that are actually ok to be added the scene. - if (instance.model.ok) { - // predict x and y of model - float x, y; - if (instance.dirty) { - // TODO this is an incorrect, predicted location for dirty case - if ((instance.parent != null) && !instance.dontInheritTranslation) { - x = instance.parent.localLocation.x + instance.localLocation.x; - y = instance.parent.localLocation.y + instance.localLocation.y; - } - else { - x = instance.localLocation.x; - y = instance.localLocation.y; - } - } - else { - x = instance.worldLocation.x; - y = instance.worldLocation.y; - } - instanceMoved(instance, x, y); - return true; - } - } - - return false; - } - - public abstract void instanceMoved(ModelInstance instance, float x, float y); - - public boolean removeInstance(final ModelInstance instance) { - if (instance.scene == this) { - instance.removeLights(this); - innerRemove(instance); - - instance.scene = null; - this.instances.remove(instance); - - return true; - } - return false; - } - - protected abstract void innerRemove(ModelInstance instance); - - public abstract void clear(); - - public boolean detach() { - if (this.viewer != null) { - return this.viewer.removeScene(this); - } - return false; - } - - public void addToBatch(final ModelInstance instance) { - final TextureMapper textureMapper = instance.textureMapper; - RenderBatch batch = this.batches.get(textureMapper); - - if (batch == null) { - batch = instance.getBatch(textureMapper); - - this.batches.put(textureMapper, batch); - } - - batch.add(instance); - } - - public void update(final float dt) { - this.camera.update(); - - if (this.audioEnabled) { - final float x = this.camera.location.x; - final float y = this.camera.location.y; - final float z = this.camera.location.z; - final float forwardX = this.camera.directionY.x; - final float forwardY = this.camera.directionY.y; - final float forwardZ = this.camera.directionY.z; - final float upX = this.camera.directionZ.x; - final float upY = this.camera.directionZ.y; - final float upZ = this.camera.directionZ.z; - final AudioContext.Listener listener = this.audioContext.listener; - - listener.setPosition(x, y, z); - listener.setOrientation(forwardX, forwardY, forwardZ, upX, upY, upZ); - } - - final int frame = this.viewer.frame; - - this.currentInstance = 0; - this.currentBatchedInstance = 0; - - innerUpdate(dt, frame); - - for (int i = this.batchedInstances.size() - 1; i >= this.currentBatchedInstance; i--) { - this.batchedInstances.remove(i); - } - - for (int i = this.instances.size() - 1; i >= this.currentInstance; i--) { - this.instances.remove(i); - } - Collections.sort(this.instances, this.instanceDepthComparator); - - this.emitterObjectUpdater.update(dt); - this.updatedParticles = this.emitterObjectUpdater.objects.size(); - - } - - protected abstract void innerUpdate(float dt, int frame); - - public void startFrame() { - final GL20 gl = this.viewer.gl; - final Rectangle viewport = this.camera.rect; - - // Set the viewport - gl.glViewport((int) viewport.x, (int) viewport.y, (int) viewport.width, (int) viewport.height); - - // Allow to render only in the viewport - gl.glScissor((int) viewport.x, (int) viewport.y, (int) viewport.width, (int) viewport.height); - - // If this scene doesn't want alpha, clear it. - if (!this.alpha) { - gl.glDepthMask(true); - gl.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT); - } - this.lightManager.update(); - } - - public void renderOpaque() { - final Rectangle viewport = this.camera.rect; - this.viewer.gl.glViewport((int) viewport.x, (int) viewport.y, (int) viewport.width, (int) viewport.height); - - // Clear all of the batches. - for (final RenderBatch batch : this.batches.values()) { - batch.clear(); - } - - // Add all of the batched instances to batches. - for (final ModelInstance instance : this.batchedInstances) { - this.addToBatch(instance); - } - - // Render all of the batches. - for (final RenderBatch batch : this.batches.values()) { - batch.render(); - } - - // Render all of the opaque things of non-batched instances. - for (final ModelInstance instance : this.instances) { - instance.renderOpaque(this.camera.viewProjectionMatrix); - } - } - - public void renderOpaque(final DynamicShadowManager dynamicShadowManager, final WebGL webGL) { - final Matrix4 depthMatrix = dynamicShadowManager.prepareShadowMatrix(); - dynamicShadowManager.beginShadowMap(webGL); - Gdx.gl30.glDepthMask(true); - Gdx.gl30.glClear(GL20.GL_DEPTH_BUFFER_BIT | GL20.GL_COLOR_BUFFER_BIT); - Gdx.gl30.glDisable(GL30.GL_SCISSOR_TEST); - - // Render all of the opaque things of non-batched instances. -// for (final ModelInstance instance : this.instances) { -// instance.renderOpaque(depthMatrix); -// } - - dynamicShadowManager.endShadowMap(); - final Rectangle viewport = this.camera.rect; - this.viewer.gl.glViewport((int) viewport.x, (int) viewport.y, (int) viewport.width, (int) viewport.height); - Gdx.gl30.glEnable(GL30.GL_SCISSOR_TEST); - } - - /** - * Renders all translucent things in this scene. Automatically applies the - * camera's viewport. - */ - public void renderTranslucent() { - final Rectangle viewport = this.camera.rect; - - this.viewer.gl.glViewport((int) viewport.x, (int) viewport.y, (int) viewport.width, (int) viewport.height); - - for (final ModelInstance instance : this.instances) { - instance.renderTranslucent(); - } - - } - - public void clearEmitterObjects() { - for (final EmittedObject object : this.emitterObjectUpdater.objects) { - object.health = 0; - } - } - - public void addLight(final SceneLightInstance lightInstance) { - this.lightManager.add(lightInstance); - } - - public void removeLight(final SceneLightInstance lightInstance) { - this.lightManager.remove(lightInstance); - } - - private static final class InstanceDepthComparator implements Comparator { - @Override - public int compare(final ModelInstance o1, final ModelInstance o2) { - return -Float.compare(o2.depth, o1.depth); - } - } - - public SceneLightManager getLightManager() { - return this.lightManager; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/SceneLightInstance.java b/core/src/com/etheller/warsmash/viewer5/SceneLightInstance.java deleted file mode 100644 index 8a949220..00000000 --- a/core/src/com/etheller/warsmash/viewer5/SceneLightInstance.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.viewer5; - -public interface SceneLightInstance { - -} diff --git a/core/src/com/etheller/warsmash/viewer5/SceneLightManager.java b/core/src/com/etheller/warsmash/viewer5/SceneLightManager.java deleted file mode 100644 index efd69f4f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/SceneLightManager.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.viewer5; - -public interface SceneLightManager { - public void add(final SceneLightInstance lightInstance); - - public void remove(final SceneLightInstance lightInstance); - - public void update(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/Shaders.java b/core/src/com/etheller/warsmash/viewer5/Shaders.java deleted file mode 100644 index a4798c3d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/Shaders.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler.ShaderEnvironmentType; - -public class Shaders { - public static final String boneTexture = ""// - + " uniform sampler2D u_boneMap;\r\n" + // - " uniform float u_vectorSize;\r\n" + // - " uniform float u_rowSize;\r\n" + // - " mat4 fetchMatrix(float column, float row) {\r\n" + // - " column *= u_vectorSize * 4.0;\r\n" + // - " row *= u_rowSize;\r\n" + // - " // Add in half texel to sample in the middle of the texel.\r\n" + // - " // Otherwise, since the sample is directly on the boundry, small floating point errors can cause the sample to get the wrong pixel.\r\n" - + // - " // This is mostly noticable with NPOT textures, which the bone maps are.\r\n" + // - " column += 0.5 * u_vectorSize;\r\n" + // - " row += 0.5 * u_rowSize;\r\n" + // - " return mat4(texture2D(u_boneMap, vec2(column, row)),\r\n" + // - " texture2D(u_boneMap, vec2(column + u_vectorSize, row)),\r\n" + // - " texture2D(u_boneMap, vec2(column + u_vectorSize * 2.0, row)),\r\n" + // - " texture2D(u_boneMap, vec2(column + u_vectorSize * 3.0, row)));\r\n" + // - " }"; - - public static final String decodeFloat = "\r\n" + // - " vec2 decodeFloat2(float f) {\r\n" + // - " vec2 v;\r\n" + // - " v[1] = floor(f / 256.0);\r\n" + // - " v[0] = floor(f - v[1] * 256.0);\r\n" + // - " return v;\r\n" + // - " }\r\n" + // - " vec3 decodeFloat3(float f) {\r\n" + // - " vec3 v;\r\n" + // - " v[2] = floor(f / 65536.0);\r\n" + // - " v[1] = floor((f - v[2] * 65536.0) / 256.0);\r\n" + // - " v[0] = floor(f - v[2] * 65536.0 - v[1] * 256.0);\r\n" + // - " return v;\r\n" + // - " }\r\n" + // - " vec4 decodeFloat4(float v) {\r\n" + // - " vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;\r\n" + // - " enc = fract(enc);\r\n" + // - " enc -= enc.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);\r\n" + // - " return enc;\r\n" + // - " }"; - - public static final String quatTransform = "\r\n" + // - " // A 2D quaternion*vector.\r\n" + // - " // q is the zw components of the original quaternion.\r\n" + // - " vec2 quat_transform(vec2 q, vec2 v) {\r\n" + // - " vec2 uv = vec2(-q.x * v.y, q.x * v.x);\r\n" + // - " vec2 uuv = vec2(-q.x * uv.y, q.x * uv.x);\r\n" + // - " return v + 2.0 * (uv * q.y + uuv);\r\n" + // - " }\r\n" + // - " // A 2D quaternion*vector.\r\n" + // - " // q is the zw components of the original quaternion.\r\n" + // - " vec3 quat_transform(vec2 q, vec3 v) {\r\n" + // - " return vec3(quat_transform(q, v.xy), v.z);\r\n" + // - " }\r\n" + // - " "; - - public static String lightSystem(final String normalName, final String positionName, final String lightTexture, - final String lightTextureHeight, final String lightCount, final boolean terrain) { - return " vec3 lightFactor = vec3(0.0,0.0,0.0);\r\n" + // - " for(float lightIndex = 0.5; lightIndex < " + lightCount + "; lightIndex += 1.0) {\r\n" + // - " float rowPos = (lightIndex) / " + lightTextureHeight + ";\r\n" + // - " vec4 lightPosition = texture2D(" + lightTexture + ", vec2(0.125, rowPos));\r\n" + // - " vec3 lightExtra = texture2D(" + lightTexture + ", vec2(0.375, rowPos)).xyz;\r\n" + // - " vec4 lightColor = texture2D(" + lightTexture + ", vec2(0.625, rowPos));\r\n" + // - " vec4 lightAmbColor = texture2D(" + lightTexture + ", vec2(0.875, rowPos));\r\n" + // - " if(lightExtra.x > 1.5) {\r\n" + // - " // Ambient light;\r\n" + // - " float dist = length(" + positionName + " - vec3(lightPosition." + (terrain ? "xyw" : "xyz") - + "));\r\n" + // - " float attenuationStart = lightExtra.y;\r\n" + // - " float attenuationEnd = lightExtra.z;\r\n" + // - " if( dist <= attenuationEnd ) {\r\n" + // - " float attenuationDist = clamp((dist-attenuationStart), 0.001, (attenuationEnd-attenuationStart));\r\n" - + // - " float attenuationFactor = 1.0/(attenuationDist);\r\n" + // - " lightFactor += attenuationFactor * lightAmbColor.a * lightAmbColor.rgb;\r\n" + // - " \r\n" + // - " }\r\n" + // - " } else if(lightExtra.x > 0.5) {\r\n" + // - " // Directional (sun) light;\r\n" + // - " vec3 lightDirection = vec3(lightPosition.xyz);\r\n" + // - " vec3 lightFactorContribution = lightColor.a * lightColor.rgb * clamp(dot(" + normalName - + ", lightDirection), 0.0, 1.0);\r\n" + // - " if(lightFactorContribution.r > 1.0 || lightFactorContribution.g > 1.0 || lightFactorContribution.b > 1.0) {\r\n" - + // - " lightFactorContribution = clamp(lightFactorContribution, 0.0, 1.0);\r\n" + // - " }\r\n" + // - " lightFactor += lightFactorContribution + lightAmbColor.a * lightAmbColor.rgb;\r\n" + // - " } else {\r\n" + // - " // Omnidirectional light;\r\n" + // - " vec3 deltaBtwn = " + positionName + " - lightPosition.xyz;\r\n" + // - " float dist = length(" + positionName + " - vec3(lightPosition." + (terrain ? "xyz" : "xyz") - + ")) / 64.0 + 1.0;\r\n" + // - " vec3 lightDirection = normalize(-deltaBtwn);\r\n" + // - " vec3 lightFactorContribution = (lightColor.a/(pow(dist, 2.0))) * lightColor.rgb * clamp(dot(" - + normalName + ", lightDirection), 0.0, 1.0);\r\n" + // - " if(lightFactorContribution.r > 1.0 || lightFactorContribution.g > 1.0 || lightFactorContribution.b > 1.0) {\r\n" - + // - " lightFactorContribution = clamp(lightFactorContribution, 0.0, 1.0);\r\n" + // - " }\r\n" + // - " lightFactor += lightFactorContribution + (lightAmbColor.a/(pow(dist, 2.0))) * lightAmbColor.rgb;\r\n" - + // - " }\r\n" + // - " }\r\n" + // - (MdxHandler.CURRENT_SHADER_TYPE == ShaderEnvironmentType.MENU - ? " vec4 sRGB = vec4(lightFactor, 1.0);" + // - " bvec4 cutoff = lessThan(sRGB, vec4(0.04045));" + // - " vec4 higher = pow((sRGB + vec4(0.055))/vec4(1.055), vec4(2.4));" + // - " vec4 lower = sRGB/vec4(12.92);" + // - "" + // - " lightFactor = (higher * (vec4(1.0) - vec4(cutoff)) + lower * vec4(cutoff)).xyz;" - : ""); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/SimpleScene.java b/core/src/com/etheller/warsmash/viewer5/SimpleScene.java deleted file mode 100644 index f68a8ff8..00000000 --- a/core/src/com/etheller/warsmash/viewer5/SimpleScene.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.util.ArrayList; -import java.util.List; - -public class SimpleScene extends Scene { - private final List allInstances = new ArrayList<>(); - - public SimpleScene(final ModelViewer viewer, final SceneLightManager lightManager) { - super(viewer, lightManager); - this.visibleCells = 1; - this.visibleInstances = 0; - } - - @Override - public void instanceMoved(final ModelInstance instance, final float x, final float y) { - if (instance.left == -1) { - instance.left = 0; - this.allInstances.add(instance); - } - } - - @Override - protected void innerRemove(final ModelInstance instance) { - this.allInstances.remove(instance); - instance.left = -1; - } - - @Override - public void clear() { - for (final ModelInstance instance : this.allInstances) { - instance.scene = null; - } - this.allInstances.clear(); - } - - @Override - protected void innerUpdate(final float dt, final int frame) { - - // Update and collect all of the visible instances. - for (final ModelInstance instance : new ArrayList<>(this.allInstances)) { - // Below: current SimpleScene is not checking instance visibility. - // It's meant to be simple. Low number of models. Render everything, - // dont check visible. Then I had to add a call to isVisible() because it - // assigns depth, which is crazy. - instance.isVisible(this.camera); - if (instance.rendered && (instance.cullFrame < frame)) { - instance.cullFrame = frame; - - if (instance.updateFrame < frame) { - instance.update(dt, this); - if (!instance.rendered) { - // it became hidden while it updated - continue; - } - } - - if (instance.isBatched()) { - if (this.currentBatchedInstance < this.batchedInstances.size()) { - this.batchedInstances.set(this.currentBatchedInstance++, instance); - } - else { - this.batchedInstances.add(instance); - this.currentBatchedInstance++; - } - } - else { - if (this.currentInstance < this.instances.size()) { - this.instances.set(this.currentInstance++, instance); - } - else { - this.instances.add(instance); - this.currentInstance++; - } - } - - } - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/SkeletalNode.java b/core/src/com/etheller/warsmash/viewer5/SkeletalNode.java deleted file mode 100644 index d27b0ec1..00000000 --- a/core/src/com/etheller/warsmash/viewer5/SkeletalNode.java +++ /dev/null @@ -1,254 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.util.ArrayList; - -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Quaternion; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.util.RenderMathUtils; - -public abstract class SkeletalNode extends GenericNode { - protected static final Vector3 cameraRayHeap = new Vector3(); - protected static final Vector3 billboardAxisHeap = new Vector3(); - protected static final Quaternion rotationHeap = new Quaternion(); - protected static final Quaternion rotationHeap2 = new Quaternion(); - protected static final Vector3 scalingHeap = new Vector3(); - protected static final Vector3 blendLocationHeap = new Vector3(); - protected static final Vector3 blendHeap = new Vector3(); - protected static final Vector3 blendScaleHeap = new Vector3(); - - public UpdatableObject object; - - public boolean billboarded; - public boolean billboardedX; - public boolean billboardedY; - public boolean billboardedZ; - - public Vector3 localBlendLocation; - public Quaternion localBlendRotation; - public Vector3 localBlendScale; - - public SkeletalNode() { - this.pivot = new Vector3(); - this.localLocation = new Vector3(); - this.localRotation = new Quaternion(0, 0, 0, 1); - this.localScale = new Vector3(1, 1, 1); - this.worldLocation = new Vector3(); - this.worldRotation = new Quaternion(); - this.worldScale = new Vector3(1, 1, 1); - this.inverseWorldLocation = new Vector3(); - this.inverseWorldRotation = new Quaternion(); - this.inverseWorldScale = new Vector3(); - this.localMatrix = new Matrix4(); - this.localBlendLocation = new Vector3(); - this.localBlendRotation = new Quaternion(0, 0, 0, 1); - this.localBlendScale = new Vector3(1, 1, 1); - this.worldMatrix = new Matrix4(); - this.dontInheritTranslation = false; - this.dontInheritRotation = false; - this.dontInheritScaling = false; - this.children = new ArrayList<>(); - - this.visible = true; - this.wasDirty = false; - - /** - * The object associated with this node, if there is any. - * - * @member {?} - */ - this.object = null; - - this.localRotation.w = 1; - - this.localScale.set(1, 1, 1); - - this.localMatrix.val[0] = 1; - this.localMatrix.val[5] = 1; - this.localMatrix.val[10] = 1; - this.localMatrix.val[15] = 1; - - this.dirty = true; - - this.billboarded = false; - this.billboardedX = false; - this.billboardedY = false; - this.billboardedZ = false; - } - - public void recalculateTransformation(final Scene scene, final float blendTimeRatio) { - final float inverseBlendRatio = 1 - blendTimeRatio; - final Quaternion computedRotation; - Vector3 computedScaling; - Vector3 computedLocation; - - if (this.dontInheritScaling) { - computedScaling = scalingHeap; - - final Vector3 parentInverseScale = this.parent.inverseWorldScale; - computedScaling.x = parentInverseScale.x * this.localScale.x; - computedScaling.y = parentInverseScale.y * this.localScale.y; - computedScaling.z = parentInverseScale.z * this.localScale.z; - - this.worldScale.x = this.localScale.x; - this.worldScale.y = this.localScale.y; - this.worldScale.z = this.localScale.z; - } - else { - if (!Float.isNaN(blendTimeRatio) && (blendTimeRatio > 0)) { - blendScaleHeap.set(this.localScale).scl(inverseBlendRatio) - .add(blendHeap.set(this.localBlendScale).scl(blendTimeRatio)); - computedScaling = blendScaleHeap; - } - else { - computedScaling = this.localScale; - } - - final Vector3 parentScale = this.parent.worldScale; - this.worldScale.x = parentScale.x * this.localScale.x; - this.worldScale.y = parentScale.y * this.localScale.y; - this.worldScale.z = parentScale.z * this.localScale.z; - } - - if (this.billboarded) { - computedRotation = rotationHeap; - - computedRotation.set(this.parent.inverseWorldRotation); - if(scene!=null) { - // TODO null scene is stupid, and happens rarely - computedRotation.mul(scene.camera.inverseRotation); - } - - this.convertBasis(computedRotation); - } - else { - computedRotation = rotationHeap.set(this.localRotation); - if (!Float.isNaN(blendTimeRatio) && (blendTimeRatio > 0)) { - computedRotation.slerp(this.localBlendRotation, blendTimeRatio); - } - - if (this.billboardedX) { - if (computedScaling == this.localScale) { - computedScaling = scalingHeap.set(computedScaling); - } - // It took me many hours to deduce from playing around that this negative one - // multiplier should be here. I suggest a lot of testing before you remove it. - computedScaling.z *= -1; - - final Camera camera = scene.camera; - cameraRayHeap.set(camera.billboardedVectors[6]); - - rotationHeap2.set(computedRotation); - // Inverse that local rotation - rotationHeap2.x = -rotationHeap2.x; - rotationHeap2.y = -rotationHeap2.y; - rotationHeap2.z = -rotationHeap2.z; - - rotationHeap2.mul(this.parent.inverseWorldRotation); - - rotationHeap2.transform(cameraRayHeap); - - billboardAxisHeap.set(1, 0, 0); - final float angle = (float) Math.atan2(cameraRayHeap.z, cameraRayHeap.y); - rotationHeap2.setFromAxisRad(billboardAxisHeap, angle); - - RenderMathUtils.mul(computedRotation, computedRotation, rotationHeap2); - } - else if (this.billboardedY) { - final Camera camera = scene.camera; - cameraRayHeap.set(camera.billboardedVectors[6]); - - rotationHeap2.set(computedRotation); - // Inverse that local rotation - rotationHeap2.x = -rotationHeap2.x; - rotationHeap2.y = -rotationHeap2.y; - rotationHeap2.z = -rotationHeap2.z; - - rotationHeap2.mul(this.parent.inverseWorldRotation); - - rotationHeap2.transform(cameraRayHeap); - - billboardAxisHeap.set(0, 1, 0); - final float angle = (float) Math.atan2(-cameraRayHeap.z, cameraRayHeap.x); - rotationHeap2.setFromAxisRad(billboardAxisHeap, angle); - - RenderMathUtils.mul(computedRotation, computedRotation, rotationHeap2); - } - else if (this.billboardedZ) { - final Camera camera = scene.camera; - cameraRayHeap.set(camera.billboardedVectors[6]); - - rotationHeap2.set(computedRotation); - // Inverse that local rotation - rotationHeap2.x = -rotationHeap2.x; - rotationHeap2.y = -rotationHeap2.y; - rotationHeap2.z = -rotationHeap2.z; - - rotationHeap2.mul(this.parent.inverseWorldRotation); - - rotationHeap2.transform(cameraRayHeap); - - billboardAxisHeap.set(0, 0, 1); - final float angle = (float) Math.atan2(cameraRayHeap.y, cameraRayHeap.x); - rotationHeap2.setFromAxisRad(billboardAxisHeap, angle); - - RenderMathUtils.mul(computedRotation, computedRotation, rotationHeap2); - } - } - - if (!Float.isNaN(blendTimeRatio) && (blendTimeRatio > 0)) { - computedLocation = blendLocationHeap.set(this.localLocation).scl(inverseBlendRatio) - .add(blendHeap.set(this.localBlendLocation).scl(blendTimeRatio)); - } - else { - computedLocation = this.localLocation; - } - RenderMathUtils.fromRotationTranslationScaleOrigin(computedRotation, computedLocation, computedScaling, - this.localMatrix, this.pivot); - - RenderMathUtils.mul(this.worldMatrix, this.parent.worldMatrix, this.localMatrix); - - RenderMathUtils.mul(this.worldRotation, this.parent.worldRotation, computedRotation); - - // Inverse world rotation - this.inverseWorldRotation.x = -this.worldRotation.x; - this.inverseWorldRotation.y = -this.worldRotation.y; - this.inverseWorldRotation.z = -this.worldRotation.z; - this.inverseWorldRotation.w = this.worldRotation.w; - - // Inverse world scale - this.inverseWorldScale.x = 1 / this.worldScale.x; - this.inverseWorldScale.y = 1 / this.worldScale.y; - this.inverseWorldScale.z = 1 / this.worldScale.z; - - // World location - final float x = this.pivot.x; - final float y = this.pivot.y; - final float z = this.pivot.z; - this.worldLocation.x = (this.worldMatrix.val[Matrix4.M00] * x) + (this.worldMatrix.val[Matrix4.M01] * y) - + (this.worldMatrix.val[Matrix4.M02] * z) + this.worldMatrix.val[Matrix4.M03]; - this.worldLocation.y = (this.worldMatrix.val[Matrix4.M10] * x) + (this.worldMatrix.val[Matrix4.M11] * y) - + (this.worldMatrix.val[Matrix4.M12] * z) + this.worldMatrix.val[Matrix4.M13]; - this.worldLocation.z = (this.worldMatrix.val[Matrix4.M20] * x) + (this.worldMatrix.val[Matrix4.M21] * y) - + (this.worldMatrix.val[Matrix4.M22] * z) + this.worldMatrix.val[Matrix4.M23]; - - // Inverse world location - this.inverseWorldLocation.x = -this.worldLocation.x; - this.inverseWorldLocation.y = -this.worldLocation.y; - this.inverseWorldLocation.z = -this.worldLocation.z; - } - - public void beginBlending() { - this.localBlendLocation.set(this.localLocation); - this.localBlendRotation.set(this.localRotation); - this.localBlendScale.set(this.localScale); - } - - public void updateChildren(final float dt, final Scene scene) { - for (int i = 0, l = this.children.size(); i < l; i++) { - this.children.get(i).update(dt, scene); - } - } - - protected abstract void convertBasis(Quaternion computedRotation); -} diff --git a/core/src/com/etheller/warsmash/viewer5/SolvedPath.java b/core/src/com/etheller/warsmash/viewer5/SolvedPath.java deleted file mode 100644 index 537e89ec..00000000 --- a/core/src/com/etheller/warsmash/viewer5/SolvedPath.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.etheller.warsmash.viewer5; - -public class SolvedPath { - public String finalSrc; - public String extension; - public boolean fetch; - - public SolvedPath(final String finalSrc, final String extension, final boolean fetch) { - this.finalSrc = finalSrc; - this.extension = extension; - this.fetch = fetch; - } - - public String getFinalSrc() { - return this.finalSrc; - } - - public String getExtension() { - return this.extension; - } - - public boolean isFetch() { - return this.fetch; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/Texture.java b/core/src/com/etheller/warsmash/viewer5/Texture.java deleted file mode 100644 index d55596f5..00000000 --- a/core/src/com/etheller/warsmash/viewer5/Texture.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import com.etheller.warsmash.viewer5.handlers.ResourceHandler; - -public abstract class Texture extends HandlerResource implements ViewerTextureRenderable { - - public Texture(final ModelViewer viewer, final String extension, final PathSolver pathSolver, final String fetchUrl, - final ResourceHandler handler) { - super(viewer, extension, pathSolver, fetchUrl, handler); - } - - public abstract void bind(final int unit); - - public abstract void internalBind(); - - public abstract int getWidth(); - - public abstract int getHeight(); - - @Override - public abstract int getGlTarget(); - - @Override - public abstract int getGlHandle(); - - public abstract void setWrapS(final boolean wrapS); - - public abstract void setWrapT(final boolean wrapT); - -} diff --git a/core/src/com/etheller/warsmash/viewer5/TextureMapper.java b/core/src/com/etheller/warsmash/viewer5/TextureMapper.java deleted file mode 100644 index 5f9eeade..00000000 --- a/core/src/com/etheller/warsmash/viewer5/TextureMapper.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.util.HashMap; -import java.util.Map; - -public class TextureMapper { - public final Model model; - public final Map textures; - - public TextureMapper(final Model model) { - this.model = model; - this.textures = new HashMap<>(); - } - - public TextureMapper(final Model model, final Map textures) { - this.model = model; - this.textures = new HashMap<>(textures); - } - - public Texture get(final Object key) { - return this.textures.get(key); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/UpdatableObject.java b/core/src/com/etheller/warsmash/viewer5/UpdatableObject.java deleted file mode 100644 index 7534f54f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/UpdatableObject.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.viewer5; - -public interface UpdatableObject { - void update(float dt, boolean visible); -} diff --git a/core/src/com/etheller/warsmash/viewer5/ViewerTextureRenderable.java b/core/src/com/etheller/warsmash/viewer5/ViewerTextureRenderable.java deleted file mode 100644 index 7f29f0e6..00000000 --- a/core/src/com/etheller/warsmash/viewer5/ViewerTextureRenderable.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import com.badlogic.gdx.graphics.Texture; - -public interface ViewerTextureRenderable { - // TODO bind method makes more sense here - - int getGlTarget(); - - int getGlHandle(); - - class GdxViewerTextureRenderable implements ViewerTextureRenderable { - private final com.badlogic.gdx.graphics.Texture gdxTexture; - - public GdxViewerTextureRenderable(final Texture texture) { - this.gdxTexture = texture; - } - - @Override - public int getGlTarget() { - return this.gdxTexture.glTarget; - } - - @Override - public int getGlHandle() { - return this.gdxTexture.getTextureObjectHandle(); - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/WorldScene.java b/core/src/com/etheller/warsmash/viewer5/WorldScene.java deleted file mode 100644 index f05a5507..00000000 --- a/core/src/com/etheller/warsmash/viewer5/WorldScene.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.etheller.warsmash.viewer5; - -import java.util.ArrayList; - -/** - * A scene. - * - * Every scene has its own list of model instances, and its own camera and - * viewport. - * - * In addition, in Ghostwolf's original code every scene may have its own - * AudioContext if enableAudio() is called. If audo is enabled, the - * AudioContext's listener's location will be updated automatically. Note that - * due to browser policies, this may be done only after user interaction with - * the web page. - * - * In "Warsmash", we are starting from an attempt to replicate Ghostwolf, but - * audio is always on in LibGDX generally. So we will probably simplify or skip - * over those behaviors other than a boolean on/off toggle for audio. - */ -public class WorldScene extends Scene { - - public Grid grid; - - public WorldScene(final ModelViewer viewer, final SceneLightManager lightManager) { - super(viewer, lightManager); - this.grid = new Grid(-100000, -100000, 200000, 200000, 200000, 200000); - } - - @Override - public void instanceMoved(final ModelInstance instance, final float x, final float y) { - this.grid.moved(instance, x, y); - } - - @Override - protected void innerRemove(final ModelInstance instance) { - this.grid.remove(instance); - } - - @Override - public void clear() { - // First remove references to this scene stored in the instances. - for (final GridCell cell : this.grid.cells) { - for (final ModelInstance instance : cell.instances) { - instance.scene = null; - } - } - - // Then remove references to the instances. - this.grid.clear(); - } - - @Override - protected void innerUpdate(final float dt, final int frame) { - this.visibleCells = 0; - this.visibleInstances = 0; - - // Update and collect all of the visible instances. - for (final GridCell cell : this.grid.cells) { - if (cell.isVisible(this.camera) || true) { - this.visibleCells += 1; - - for (final ModelInstance instance : new ArrayList<>(cell.instances)) { -// final ModelInstance instance = cell.instances.get(i); - if (instance.rendered && (instance.cullFrame < frame) && instance.isVisible(this.camera)) { - instance.cullFrame = frame; - - if (instance.updateFrame < frame) { - instance.update(dt, this); - if (!instance.rendered) { - // it became hidden while it updated - continue; - } - } - - if (instance.isBatched()) { - if (this.currentBatchedInstance < this.batchedInstances.size()) { - this.batchedInstances.set(this.currentBatchedInstance++, instance); - } - else { - this.batchedInstances.add(instance); - this.currentBatchedInstance++; - } - } - else { - if (this.currentInstance < this.instances.size()) { - this.instances.set(this.currentInstance++, instance); - } - else { - this.instances.add(instance); - this.currentInstance++; - } - } - - this.visibleInstances += 1; - } - } - } - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/deprecated/ShaderProgram.java b/core/src/com/etheller/warsmash/viewer5/deprecated/ShaderProgram.java deleted file mode 100644 index 51117e55..00000000 --- a/core/src/com/etheller/warsmash/viewer5/deprecated/ShaderProgram.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.etheller.warsmash.viewer5.deprecated; - -import com.etheller.warsmash.viewer5.gl.WebGL; - -public class ShaderProgram { - - public boolean ok; - public int attribsCount; - public int webglResource; - - public ShaderProgram(final WebGL webGL, final ShaderUnitDeprecated vertexShader, final ShaderUnitDeprecated fragmentShader) { - // TODO Auto-generated constructor stub - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/deprecated/ShaderUnitDeprecated.java b/core/src/com/etheller/warsmash/viewer5/deprecated/ShaderUnitDeprecated.java deleted file mode 100644 index 75897cda..00000000 --- a/core/src/com/etheller/warsmash/viewer5/deprecated/ShaderUnitDeprecated.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.etheller.warsmash.viewer5.deprecated; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.IntBuffer; - -import com.badlogic.gdx.graphics.GL20; - -public class ShaderUnitDeprecated { - - public boolean ok; - private final int webglResource; - private final String src; - private final int shaderType; - - public ShaderUnitDeprecated(final GL20 gl, final String src, final int type) { - final int id = gl.glCreateShader(type); - this.ok = false; - this.webglResource = id; - this.src = src; - this.shaderType = type; - - gl.glShaderSource(id, src); - gl.glCompileShader(id); - - final IntBuffer success = ByteBuffer.allocateDirect(8).order(ByteOrder.nativeOrder()).asIntBuffer(); - gl.glGetShaderiv(id, GL20.GL_COMPILE_STATUS, success); - throw new UnsupportedOperationException("Not yet implemented, probably using library instead"); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/gl/ANGLEInstancedArrays.java b/core/src/com/etheller/warsmash/viewer5/gl/ANGLEInstancedArrays.java deleted file mode 100644 index c1219af0..00000000 --- a/core/src/com/etheller/warsmash/viewer5/gl/ANGLEInstancedArrays.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.viewer5.gl; - -/** - * TODO what is this? - */ -public interface ANGLEInstancedArrays { - - void glVertexAttribDivisorANGLE(int index, int divisor); - - void glDrawArraysInstancedANGLE(int mode, int first, int count, int instanceCount); - - void glDrawElementsInstancedANGLE(int mode, int count, int type, int indicesOffset, int instanceCount); -} diff --git a/core/src/com/etheller/warsmash/viewer5/gl/AudioExtension.java b/core/src/com/etheller/warsmash/viewer5/gl/AudioExtension.java deleted file mode 100644 index 8af22f03..00000000 --- a/core/src/com/etheller/warsmash/viewer5/gl/AudioExtension.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.viewer5.gl; - -import com.badlogic.gdx.audio.Sound; -import com.etheller.warsmash.viewer5.AudioContext; - -public interface AudioExtension { - AudioContext createContext(boolean world); - - float getDuration(Sound sound); - - void play(Sound buffer, final float volume, final float pitch, final float x, final float y, final float z, - final boolean is3DSound, float maxDistance, float refDistance, boolean looping); -} diff --git a/core/src/com/etheller/warsmash/viewer5/gl/ClientBuffer.java b/core/src/com/etheller/warsmash/viewer5/gl/ClientBuffer.java deleted file mode 100644 index 0c513f63..00000000 --- a/core/src/com/etheller/warsmash/viewer5/gl/ClientBuffer.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.etheller.warsmash.viewer5.gl; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; - -import com.badlogic.gdx.graphics.GL20; - -public class ClientBuffer { - private final GL20 gl; - private final int buffer; - private int size; - private ByteBuffer arrayBuffer; - public ByteBuffer byteView; - public FloatBuffer floatView; - - public ClientBuffer(final GL20 gl) { - this(gl, 4); - } - - public ClientBuffer(final GL20 gl, final int size) { - this.gl = gl; - this.buffer = gl.glGenBuffer(); - this.arrayBuffer = null; - - this.reserve(size); - } - - public void reserve(final int size) { - if (this.size < size) { - - // Ensure the size is on a 4 byte boundary. - this.size = (int) Math.ceil(size / 4.) * 4; - - this.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.buffer); - - this.arrayBuffer = ByteBuffer.allocateDirect(this.size).order(ByteOrder.nativeOrder()); - this.gl.glBufferData(GL20.GL_ARRAY_BUFFER, this.size, this.arrayBuffer, GL20.GL_DYNAMIC_DRAW); - this.byteView = this.arrayBuffer; - this.floatView = this.arrayBuffer.asFloatBuffer(); - - } - } - - public void bindAndUpdate() { - bindAndUpdate(this.size); - } - - public void bindAndUpdate(final int size) { - final GL20 gl = this.gl; - - gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.buffer); - gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, 0, size, this.byteView); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/gl/DataTexture.java b/core/src/com/etheller/warsmash/viewer5/gl/DataTexture.java deleted file mode 100644 index f19e50c1..00000000 --- a/core/src/com/etheller/warsmash/viewer5/gl/DataTexture.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.etheller.warsmash.viewer5.gl; - -import java.nio.Buffer; - -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.GL30; - -public class DataTexture { - public GL20 gl; - public int texture; - public int format; - public int internalFormat; - public int width = 0; - public int height = 0; - - public DataTexture(final GL20 gl, final int channels, final int width, final int height) { - this.gl = gl; - this.texture = gl.glGenTexture(); - this.format = (channels == 3 ? GL20.GL_RGB : GL20.GL_RGBA); - this.internalFormat = (channels == 3 ? GL20.GL_RGB : GL30.GL_RGBA32F); - - gl.glBindTexture(GL20.GL_TEXTURE_2D, this.texture); - gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_S, GL20.GL_CLAMP_TO_EDGE); - gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_T, GL20.GL_CLAMP_TO_EDGE); - gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER, GL20.GL_NEAREST); - gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER, GL20.GL_NEAREST); - - this.reserve(width, height); - } - - public void reserve(final int width, final int height) { - if ((this.width < width) || (this.height < height)) { - final GL20 gl = this.gl; - - this.width = Math.max(this.width, width); - this.height = Math.max(this.height, height); - - gl.glBindTexture(GL20.GL_TEXTURE_2D, this.texture); - gl.glTexImage2D(GL20.GL_TEXTURE_2D, 0, this.internalFormat, this.width, this.height, 0, this.format, - GL20.GL_FLOAT, null); - } - - } - - public void bindAndUpdate(final Buffer buffer) { - bindAndUpdate(buffer, this.width, this.height); - } - - public void bindAndUpdate(final Buffer buffer, final int width, final int height) { - final GL20 gl = this.gl; - - gl.glBindTexture(GL20.GL_TEXTURE_2D, this.texture); - gl.glTexSubImage2D(GL20.GL_TEXTURE_2D, 0, 0, 0, width, height, this.format, GL20.GL_FLOAT, buffer); - } - - public void bind(final int unit) { - final GL20 gl = this.gl; - - gl.glActiveTexture(GL20.GL_TEXTURE0 + unit); - gl.glBindTexture(GL20.GL_TEXTURE_2D, this.texture); - } - - public int getWidth() { - return this.width; - } - - public int getHeight() { - return this.height; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/gl/DynamicShadowExtension.java b/core/src/com/etheller/warsmash/viewer5/gl/DynamicShadowExtension.java deleted file mode 100644 index aeae3c13..00000000 --- a/core/src/com/etheller/warsmash/viewer5/gl/DynamicShadowExtension.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.etheller.warsmash.viewer5.gl; - -public interface DynamicShadowExtension { - void glFramebufferTexture(int target, int attachment, int texture, int level); - - void glDrawBuffer(int mode); -} diff --git a/core/src/com/etheller/warsmash/viewer5/gl/Extensions.java b/core/src/com/etheller/warsmash/viewer5/gl/Extensions.java deleted file mode 100644 index 3bc06994..00000000 --- a/core/src/com/etheller/warsmash/viewer5/gl/Extensions.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.etheller.warsmash.viewer5.gl; - -public class Extensions { - public static ANGLEInstancedArrays angleInstancedArrays; - - public static DynamicShadowExtension dynamicShadowExtension; - - public static WireframeExtension wireframeExtension; - - public static AudioExtension audio; - - public static int GL_LINE = 0; - public static int GL_FILL = 0; -} diff --git a/core/src/com/etheller/warsmash/viewer5/gl/WebGL.java b/core/src/com/etheller/warsmash/viewer5/gl/WebGL.java deleted file mode 100644 index 6235a95b..00000000 --- a/core/src/com/etheller/warsmash/viewer5/gl/WebGL.java +++ /dev/null @@ -1,168 +0,0 @@ -package com.etheller.warsmash.viewer5.gl; - -import java.util.HashMap; -import java.util.Map; - -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.etheller.warsmash.viewer5.Texture; -import com.etheller.warsmash.viewer5.deprecated.ShaderUnitDeprecated; - -/** - * This needs a rename. Just a ripoff of ghostwolf's wrapper utility class, it's - * a utility, not a webgl - */ -public class WebGL { - public GL20 gl; - public Map shaderUnits; - public Map shaderPrograms; - public ShaderProgram currentShaderProgram; - public String floatPrecision; - public final com.badlogic.gdx.graphics.Texture emptyTexture; - public ANGLEInstancedArrays instancedArrays; - - public WebGL(final GL20 gl) { - gl.glDepthFunc(GL20.GL_LEQUAL); - gl.glEnable(GL20.GL_DEPTH_TEST); - - // TODO here ghostwolf throws exceptions for unsupported versions of opengl - - this.gl = gl; - - this.shaderUnits = new HashMap<>(); - - this.shaderPrograms = new HashMap<>(); - - this.currentShaderProgram = null; - this.floatPrecision = "precision mediump float;\n"; - - final Pixmap imageData = new Pixmap(2, 2, Pixmap.Format.RGBA8888); - for (int i = 0; i < 2; i++) { - for (int j = 0; j < 2; j++) { - imageData.drawPixel(i, j, 0x000000FF); - } - } - this.emptyTexture = new com.badlogic.gdx.graphics.Texture(imageData); - this.instancedArrays = Extensions.angleInstancedArrays; - } - - public ShaderUnitDeprecated createShaderUnit(final String src, final int type) { - final int hash = stringHash(src); // TODO: why on earth are we doing this, what about hash collisions? - if (!this.shaderUnits.containsKey(hash)) { - this.shaderUnits.put(hash, new ShaderUnitDeprecated(this.gl, src, type)); - } - return this.shaderUnits.get(hash); - } - - public ShaderProgram createShaderProgram(String vertexSrc, String fragmentSrc) { - vertexSrc = vertexSrc.replace("mediump", ""); - fragmentSrc = fragmentSrc.replace("mediump", ""); - final Map shaderPrograms = this.shaderPrograms; - - final int hash = stringHash(vertexSrc + fragmentSrc); - ShaderProgram.pedantic = false; - if (!shaderPrograms.containsKey(hash)) { - shaderPrograms.put(hash, new ShaderProgram(vertexSrc, fragmentSrc)); - } - - final ShaderProgram shaderProgram = shaderPrograms.get(hash); - - if (shaderProgram.isCompiled()) { - return shaderProgram; - } - else { - System.err.println(shaderProgram.getLog()); - if (true) { - throw new IllegalStateException("Bad shader"); - } - } - return null; - } - - public void enableVertexAttribs(final int start, final int end) { - final GL20 gl = this.gl; - - for (int i = start; i < end; i++) { - gl.glEnableVertexAttribArray(i); - } - } - - public void disableVertexAttribs(final int start, final int end) { - final GL20 gl = this.gl; - - for (int i = start; i < end; i++) { - gl.glDisableVertexAttribArray(i); - } - } - - public void useShaderProgram(final ShaderProgram shaderProgram) { - final ShaderProgram currentShaderProgram = this.currentShaderProgram; - - if ((shaderProgram != null) && shaderProgram.isCompiled() && (shaderProgram != currentShaderProgram)) { - int oldAttribs = 0; - final int newAttribs = shaderProgram.getAttributes().length; - - if (currentShaderProgram != null) { - oldAttribs = currentShaderProgram.getAttributes().length; - } - - shaderProgram.begin(); - - if (newAttribs > oldAttribs) { - this.enableVertexAttribs(oldAttribs, newAttribs); - } - else if (newAttribs < oldAttribs) { - this.disableVertexAttribs(newAttribs, oldAttribs); - } - - this.currentShaderProgram = shaderProgram; - } - else if (shaderProgram == null) { - int oldAttribs = 0; - final int newAttribs = 0; - - if (currentShaderProgram != null) { - oldAttribs = currentShaderProgram.getAttributes().length; - currentShaderProgram.end(); - } - - if (newAttribs > oldAttribs) { - this.enableVertexAttribs(oldAttribs, newAttribs); - } - else if (newAttribs < oldAttribs) { - this.disableVertexAttribs(newAttribs, oldAttribs); - } - - this.currentShaderProgram = shaderProgram; - } - } - - public void bindTexture(final Texture texture, final int unit) { - final GL20 gl = this.gl; - - gl.glActiveTexture(GL20.GL_TEXTURE0 + unit); - - if (texture != null /* && texture.ok */) { - texture.internalBind(); - } - else { - this.emptyTexture.bind(); - } - } - - public void setTextureMode(final int wrapS, final int wrapT, final int magFilter, final int minFilter) { - final GL20 gl = this.gl; - - // TODO make sure we dont assign this parameter doubly if we're already using - // libgdx texture, which does do some wrapS and wrapT stuff already - gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_S, wrapS); - gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_T, wrapT); - gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER, magFilter); - gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER, minFilter); - } - - private int stringHash(final String src) { - return src.hashCode(); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/gl/WireframeExtension.java b/core/src/com/etheller/warsmash/viewer5/gl/WireframeExtension.java deleted file mode 100644 index 1041bc6c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/gl/WireframeExtension.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.viewer5.gl; - -public interface WireframeExtension { - void glPolygonMode(int face, int mode); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/AbstractMdxModelViewer.java b/core/src/com/etheller/warsmash/viewer5/handlers/AbstractMdxModelViewer.java deleted file mode 100644 index 012b055a..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/AbstractMdxModelViewer.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers; - -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.util.StringBundle; -import com.etheller.warsmash.viewer5.CanvasProvider; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer.SolverParams; - -public abstract class AbstractMdxModelViewer extends ModelViewer { - public PathSolver wc3PathSolver = PathSolver.DEFAULT; - public PathSolver mapPathSolver = PathSolver.DEFAULT; - public SolverParams solverParams = new SolverParams(); - - public AbstractMdxModelViewer(final DataSource dataSource, final CanvasProvider canvas) { - super(dataSource, canvas); - } - - public abstract StringBundle getWorldEditStrings(); - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/EmitterObject.java b/core/src/com/etheller/warsmash/viewer5/handlers/EmitterObject.java deleted file mode 100644 index e9300b73..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/EmitterObject.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers; - -public interface EmitterObject { - boolean ok(); - - int getGeometryEmitterType(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/ModelHandler.java b/core/src/com/etheller/warsmash/viewer5/handlers/ModelHandler.java deleted file mode 100644 index 6598bdc3..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/ModelHandler.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers; - -public abstract class ModelHandler extends ResourceHandler { - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/ModelInstanceDescriptor.java b/core/src/com/etheller/warsmash/viewer5/handlers/ModelInstanceDescriptor.java deleted file mode 100644 index 336e9ed4..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/ModelInstanceDescriptor.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers; - -import com.etheller.warsmash.viewer5.Model; -import com.etheller.warsmash.viewer5.ModelInstance; - -public interface ModelInstanceDescriptor { - ModelInstance create(Model model); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/ResourceHandler.java b/core/src/com/etheller/warsmash/viewer5/handlers/ResourceHandler.java deleted file mode 100644 index 25717361..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/ResourceHandler.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers; - -import java.util.List; - -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.HandlerResource; - -public abstract class ResourceHandler { - public ResourceHandler handler; - public boolean load; - public List extensions; - - public abstract boolean load(ModelViewer modelViewer); - - public abstract HandlerResource construct(ResourceHandlerConstructionParams params); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/ResourceHandlerConstructionParams.java b/core/src/com/etheller/warsmash/viewer5/handlers/ResourceHandlerConstructionParams.java deleted file mode 100644 index 1eb95b38..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/ResourceHandlerConstructionParams.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers; - -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.PathSolver; - -public class ResourceHandlerConstructionParams { - public final ModelViewer viewer; - public final ResourceHandler handler; - public final String extension; - public final PathSolver pathSolver; - public final String fetchUrl; - - public ResourceHandlerConstructionParams(final ModelViewer viewer, final ResourceHandler handler, - final String extension, final PathSolver pathSolver, final String fetchUrl) { - this.viewer = viewer; - this.handler = handler; - this.extension = extension; - this.pathSolver = pathSolver; - this.fetchUrl = fetchUrl; - } - - public ModelViewer getViewer() { - return this.viewer; - } - - public ResourceHandler getHandler() { - return this.handler; - } - - public String getExtension() { - return this.extension; - } - - public PathSolver getPathSolver() { - return this.pathSolver; - } - - public String getFetchUrl() { - return this.fetchUrl; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/blp/BlpGdxTexture.java b/core/src/com/etheller/warsmash/viewer5/handlers/blp/BlpGdxTexture.java deleted file mode 100644 index a29e6d68..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/blp/BlpGdxTexture.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.blp; - -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.InputStream; - -import javax.imageio.ImageIO; - -import com.etheller.warsmash.util.ImageUtils; -import com.etheller.warsmash.viewer5.GdxTextureResource; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.handlers.ResourceHandler; - -public class BlpGdxTexture extends GdxTextureResource { - - public BlpGdxTexture(final ModelViewer viewer, final ResourceHandler handler, final String extension, - final PathSolver pathSolver, final String fetchUrl) { - super(viewer, handler, extension, pathSolver, fetchUrl); - } - - @Override - protected void lateLoad() { - - } - - @Override - protected void load(final InputStream src, final Object options) { - BufferedImage img; - try { - img = ImageIO.read(src); - setGdxTexture(ImageUtils.getTexture(img, true)); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/blp/BlpHandler.java b/core/src/com/etheller/warsmash/viewer5/handlers/blp/BlpHandler.java deleted file mode 100644 index 372ad6a7..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/blp/BlpHandler.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.blp; - -import java.util.ArrayList; - -import com.etheller.warsmash.viewer5.HandlerResource; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.handlers.ResourceHandler; -import com.etheller.warsmash.viewer5.handlers.ResourceHandlerConstructionParams; - -public class BlpHandler extends ResourceHandler { - - public BlpHandler() { - this.extensions = new ArrayList<>(); - this.extensions.add(new String[] { ".blp", "arrayBuffer" }); - } - - @Override - public boolean load(final ModelViewer modelViewer) { - return true; - } - - @Override - public HandlerResource construct(final ResourceHandlerConstructionParams params) { - return new BlpTexture(params.getViewer(), params.getHandler(), params.getExtension(), params.getPathSolver(), - params.getFetchUrl()); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/blp/BlpTexture.java b/core/src/com/etheller/warsmash/viewer5/handlers/blp/BlpTexture.java deleted file mode 100644 index 7ba89682..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/blp/BlpTexture.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.blp; - -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.InputStream; - -import javax.imageio.ImageIO; - -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.RawOpenGLTextureResource; -import com.etheller.warsmash.viewer5.handlers.ResourceHandler; - -public class BlpTexture extends RawOpenGLTextureResource { - - public BlpTexture(final ModelViewer viewer, final ResourceHandler handler, final String extension, - final PathSolver pathSolver, final String fetchUrl) { - super(viewer, extension, pathSolver, fetchUrl, handler); - } - - @Override - protected void lateLoad() { - - } - - @Override - protected void load(final InputStream src, final Object options) { - BufferedImage img; - try { - img = ImageIO.read(src); - update(img, true); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/blp/DdsHandler.java b/core/src/com/etheller/warsmash/viewer5/handlers/blp/DdsHandler.java deleted file mode 100644 index 69f5f78d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/blp/DdsHandler.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.blp; - -import java.util.ArrayList; - -import com.etheller.warsmash.viewer5.HandlerResource; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.handlers.ResourceHandler; -import com.etheller.warsmash.viewer5.handlers.ResourceHandlerConstructionParams; - -public class DdsHandler extends ResourceHandler { - - public DdsHandler() { - this.extensions = new ArrayList<>(); - this.extensions.add(new String[] { ".dds", "arrayBuffer" }); - } - - @Override - public boolean load(final ModelViewer modelViewer) { - return true; - } - - @Override - public HandlerResource construct(final ResourceHandlerConstructionParams params) { - return new DdsTexture(params.getViewer(), params.getHandler(), params.getExtension(), params.getPathSolver(), - params.getFetchUrl()); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/blp/DdsTexture.java b/core/src/com/etheller/warsmash/viewer5/handlers/blp/DdsTexture.java deleted file mode 100644 index f33529e9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/blp/DdsTexture.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.blp; - -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.InputStream; - -import javax.imageio.ImageIO; - -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.RawOpenGLTextureResource; -import com.etheller.warsmash.viewer5.handlers.ResourceHandler; - -public class DdsTexture extends RawOpenGLTextureResource { - - public DdsTexture(final ModelViewer viewer, final ResourceHandler handler, final String extension, - final PathSolver pathSolver, final String fetchUrl) { - super(viewer, extension, pathSolver, fetchUrl, handler); - } - - @Override - protected void lateLoad() { - - } - - @Override - protected void load(final InputStream src, final Object options) { - BufferedImage img; - try { - img = ImageIO.read(src); - update(img, false); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/AnimatedObject.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/AnimatedObject.java deleted file mode 100644 index 96576b96..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/AnimatedObject.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.HashMap; -import java.util.Map; - -import com.etheller.warsmash.util.War3ID; -import com.hiveworkshop.rms.parsers.mdlx.MdlxAnimatedObject; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxFloatArrayTimeline; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxFloatTimeline; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxTimeline; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxUInt32Timeline; - -public class AnimatedObject { - public MdxModel model; - public Map> timelines; - public Map variants; - - public AnimatedObject(final MdxModel model, final MdlxAnimatedObject object) { - this.model = model; - this.timelines = new HashMap<>(); - this.variants = new HashMap<>(); - - for (final MdlxTimeline timeline : object.getTimelines()) { - this.timelines.put(timeline.getName(), createTypedSd(model, timeline)); - } - } - - public int getScalarValue(final float[] out, final War3ID name, final int sequence, final int frame, - final int counter, final float defaultValue) { - if (sequence != -1) { - final Sd animation = this.timelines.get(name); - - if (animation instanceof ScalarSd) { - return ((ScalarSd) animation).getValue(out, sequence, frame, counter); - } - } - - out[0] = defaultValue; - - return -1; - } - - public int getScalarValue(final long[] out, final War3ID name, final int sequence, final int frame, - final int counter, final long defaultValue) { - if (sequence != -1) { - final Sd animation = this.timelines.get(name); - - if (animation instanceof UInt32Sd) { - return ((UInt32Sd) animation).getValue(out, sequence, frame, counter); - } - } - - out[0] = defaultValue; - - return -1; - } - - public int getVectorValue(final float[] out, final War3ID name, final int sequence, final int frame, - final int counter, final float[] defaultValue) { - if (sequence != -1) { - final Sd animation = this.timelines.get(name); - - if (animation instanceof VectorSd) { - return ((VectorSd) animation).getValue(out, sequence, frame, counter); - } - } - - System.arraycopy(defaultValue, 0, out, 0, 3); - - return -1; - } - - public int getQuatValue(final float[] out, final War3ID name, final int sequence, final int frame, - final int counter, final float[] defaultValue) { - if (sequence != -1) { - final Sd animation = this.timelines.get(name); - - if (animation instanceof QuaternionSd) { - return ((QuaternionSd) animation).getValue(out, sequence, frame, counter); - } - } - - System.arraycopy(defaultValue, 0, out, 0, 4); - - return -1; - } - - public void addVariants(final War3ID name, final String variantName) { - final Sd timeline = this.timelines.get(name); - final int sequences = this.model.getSequences().size(); - final byte[] variants = new byte[sequences]; - - if (timeline != null) { - for (int i = 0; i < sequences; i++) { - if (timeline.isVariant(i)) { - variants[i] = 1; - } - } - } - - this.variants.put(variantName, variants); - } - - public void addVariantIntersection(final String[] names, final String variantName) { - final int sequences = this.model.getSequences().size(); - final byte[] variants = new byte[sequences]; - - for (int i = 0; i < sequences; i++) { - for (final String name : names) { - final byte[] variantsAtName = this.variants.get(name); - if ((variantsAtName != null) && (variantsAtName[i] != 0)) { - variants[i] = 1; - } - } - } - - this.variants.put(variantName, variants); - } - - public boolean isVariant(final War3ID name, final int sequence) { - final Sd timeline = this.timelines.get(name); - - if (timeline != null) { - return timeline.isVariant(sequence); - } - - return false; - } - - private Sd createTypedSd(final MdxModel model, final MdlxTimeline timeline) { - if (timeline instanceof MdlxUInt32Timeline) { - return new UInt32Sd(model, (MdlxUInt32Timeline) timeline); - } - else if (timeline instanceof MdlxFloatTimeline) { - return new ScalarSd(model, (MdlxFloatTimeline) timeline); - } - else if (timeline instanceof MdlxFloatArrayTimeline) { - final MdlxFloatArrayTimeline faTimeline = (MdlxFloatArrayTimeline) timeline; - final int arraySize = faTimeline.getArraySize(); - if (arraySize == 3) { - return new VectorSd(model, faTimeline); - } - else if (arraySize == 4) { - return new QuaternionSd(model, faTimeline); - } - else { - throw new IllegalStateException("Unsupported arraySize = " + arraySize); - } - } - throw new IllegalStateException("Unsupported timeline type " + timeline.getClass()); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Attachment.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Attachment.java deleted file mode 100644 index 96f05b46..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Attachment.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.hiveworkshop.rms.parsers.mdlx.AnimationMap; -import com.hiveworkshop.rms.parsers.mdlx.MdlxAttachment; - -public class Attachment extends GenericObject { - protected String name; - protected final String path; - protected final int attachmentId; - protected MdxModel internalModel; - - public Attachment(final MdxModel model, final MdlxAttachment attachment, final int index) { - super(model, attachment, index); - - final String path = attachment.getPath().toLowerCase().replace(".mdl", ".mdx"); - - this.name = attachment.getName().toLowerCase(); - this.path = path; - this.attachmentId = attachment.getAttachmentId(); - this.internalModel = null; - - // Second condition is against custom resources using arbitrary paths - if (!path.equals("") && (path.indexOf(".mdx") != -1)) { - this.internalModel = (MdxModel) model.viewer.load(path, model.pathSolver, model.solverParams); - } - } - - @Override - public int getVisibility(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KATV.getWar3id(), sequence, frame, counter, 1); - } - - public String getName() { - return this.name; - } - - public int getAttachmentId() { - return this.attachmentId; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/AttachmentInstance.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/AttachmentInstance.java deleted file mode 100644 index c8982233..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/AttachmentInstance.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.viewer5.UpdatableObject; - -public class AttachmentInstance implements UpdatableObject { - private static final float[] visbilityHeap = new float[1]; - - private final MdxComplexInstance instance; - private final Attachment attachment; - public final MdxComplexInstance internalInstance; - - public AttachmentInstance(final MdxComplexInstance instance, final Attachment attachment) { - final MdxModel internalModel = attachment.internalModel; - final MdxComplexInstance internalInstance = (MdxComplexInstance) internalModel.addInstance(); - - internalInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - internalInstance.dontInheritScaling = false; - internalInstance.hide(); - internalInstance.setParent(instance.nodes[attachment.objectId]); - internalInstance.setAnimationSpeed(instance.getAnimationSpeed()); - - this.instance = instance; - this.attachment = attachment; - this.internalInstance = internalInstance; - } - - @Override - public void update(final float dt, final boolean objectVisible) { - final MdxComplexInstance internalInstance = this.internalInstance; - if (internalInstance.model.ok) { - if (!objectVisible) { - internalInstance.hide(); - } - else { - this.attachment.getVisibility(visbilityHeap, this.instance.sequence, this.instance.frame, - this.instance.counter); - - if (visbilityHeap[0] > 0.1) { - // The parent instance might not actually be in a scene. - // This happens if loading a local model, where loading is instant and adding to - // a scene always comes afterwards. - // Therefore, do it here dynamically. - this.instance.scene.addInstance(internalInstance); - - if (internalInstance.hidden()) { - internalInstance.show(); - - // Every time the attachment becomes visible again, restart its first sequence. - internalInstance.setSequence(0); - } - } - else { - internalInstance.hide(); - } - } - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Batch.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Batch.java deleted file mode 100644 index 02dc3b18..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Batch.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -public class Batch implements GenericIndexed { - public int index; - public Geoset geoset; - public Layer layer; - public boolean isExtended; - - public Batch(final int index, final Geoset geoset, final Layer layer, final boolean isExtended) { - this.index = index; - this.geoset = geoset; - this.layer = layer; - this.isExtended = isExtended; - } - - @Override - public int getIndex() { - return this.index; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/BatchGroup.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/BatchGroup.java deleted file mode 100644 index 74aa9565..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/BatchGroup.java +++ /dev/null @@ -1,159 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.List; - -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.badlogic.gdx.math.Matrix4; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.Texture; -import com.etheller.warsmash.viewer5.gl.DataTexture; -import com.etheller.warsmash.viewer5.gl.WebGL; -import com.etheller.warsmash.viewer5.handlers.w3x.DynamicShadowManager; -import com.etheller.warsmash.viewer5.handlers.w3x.W3xSceneLightManager; - -public class BatchGroup extends GenericGroup { - - private final MdxModel model; - public final boolean isExtended; - - public BatchGroup(final MdxModel model, final boolean isExtended) { - this.model = model; - this.isExtended = isExtended; - } - - @Override - public void render(final MdxComplexInstance instance, final Matrix4 mvp) { - final Scene scene = instance.scene; - final MdxModel model = this.model; - final List textures = model.getTextures(); - final MdxHandler handler = model.handler; - final List batches = model.batches; - final List replaceables = model.replaceables; - final ModelViewer viewer = model.viewer; - final GL20 gl = viewer.gl; - final WebGL webGL = viewer.webGL; - final boolean isExtended = this.isExtended; - final ShaderProgram shader; - final W3xSceneLightManager lightManager = (W3xSceneLightManager) scene.getLightManager(); - - if (isExtended) { - if (DynamicShadowManager.IS_SHADOW_MAPPING) { - shader = handler.shaders.extendedShadowMap; - } - else { - shader = handler.shaders.extended; - } - } - else { - if (DynamicShadowManager.IS_SHADOW_MAPPING) { - shader = handler.shaders.complexShadowMap; - } - else { - shader = handler.shaders.complex; - } - } - - webGL.useShaderProgram(shader); - - shader.setUniformMatrix("u_mvp", mvp); - - final DataTexture boneTexture = instance.boneTexture; - final DataTexture unitLightsTexture = lightManager.getUnitLightsTexture(); - - unitLightsTexture.bind(14); - shader.setUniformi("u_lightTexture", 14); - shader.setUniformf("u_lightCount", lightManager.getUnitLightCount()); - shader.setUniformf("u_lightTextureHeight", unitLightsTexture.getHeight()); - - // Instances of models with no bones don't have a bone texture. - if (boneTexture != null) { - boneTexture.bind(15); - - shader.setUniformf("u_hasBones", 1); - shader.setUniformi("u_boneMap", 15); - shader.setUniformf("u_vectorSize", 1f / boneTexture.getWidth()); - shader.setUniformf("u_rowSize", 1); - } - else { - shader.setUniformf("u_hasBones", 0); - } - - shader.setUniformi("u_texture", 0); - - gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, model.arrayBuffer); - gl.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, model.elementBuffer); - - shader.setUniform4fv("u_vertexColor", instance.vertexColor, 0, instance.vertexColor.length); - - for (final int index : this.objects) { - final Batch batch = batches.get(index); - final Geoset geoset = batch.geoset; - final Layer layer = batch.layer; - final int geosetIndex = geoset.index; - final int layerIndex = layer.index; - final float[] geosetColor = instance.geosetColors[geosetIndex]; - final float layerAlpha = instance.layerAlphas[layerIndex]; - - if ((geosetColor[3] > 0.01) && (layerAlpha > 0.01)) { - // BELOW: I updated it to "Math.max(0," because MDL and MDX parser for PRSCMOD - // menu screen behaved differently, - // the MDL case was getting "no data" for default value when unanimated, and "no - // data" resolved to -1, - // whereas MDX binary contained an "unused" 0 value. - final int layerTexture = Math.max(0, instance.layerTextures[layerIndex]); - final float[] uvAnim = instance.uvAnims[layerIndex]; - - shader.setUniform4fv("u_geosetColor", geosetColor, 0, geosetColor.length); - - shader.setUniformf("u_layerAlpha", layerAlpha); - shader.setUniformf("u_unshaded", layer.unshaded); - - shader.setUniform2fv("u_uvTrans", uvAnim, 0, 2); - shader.setUniform2fv("u_uvRot", uvAnim, 2, 2); - shader.setUniform1fv("u_uvScale", uvAnim, 4, 1); - - if (instance.additiveOverrideMeshMode) { - layer.bindBlended(shader); - gl.glBlendFunc(FilterMode.ADDITIVE_ALPHA[0], FilterMode.ADDITIVE_ALPHA[1]); - } - else if (instance.vertexColor[3] < 1.0f) { - layer.bindBlended(shader); - } - else { - layer.bind(shader); - } - - final Integer replaceable = replaceables.get(layerTexture); // TODO is this OK? - Texture texture; - - if ((replaceable > 0) && (replaceable < WarsmashConstants.REPLACEABLE_TEXTURE_LIMIT) - && (instance.replaceableTextures[replaceable] != null)) { - texture = instance.replaceableTextures[replaceable]; - } - else { - texture = textures.get(layerTexture); - - Texture textureLookup = instance.textureMapper.get(texture); - if (textureLookup == null) { - textureLookup = texture; - } - texture = textureLookup; - } - - viewer.webGL.bindTexture(texture, 0); - - if (isExtended) { - geoset.bindExtended(shader, layer.coordId); - } - else { - geoset.bind(shader, layer.coordId); - } - - geoset.render(); - } - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Bone.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Bone.java deleted file mode 100644 index eab052c1..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Bone.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.hiveworkshop.rms.parsers.mdlx.MdlxBone; - -public class Bone extends GenericObject { - - private final GeosetAnimation geosetAnimation; - - public Bone(final MdxModel model, final MdlxBone bone, final int index) { - super(model, bone, index); - - GeosetAnimation geosetAnimation = null; - final int geosetId = bone.getGeosetId(); - if (geosetId != -1) { - final Geoset geoset = model.getGeosets().get(geosetId); - if (geoset.geosetAnimation != null) { - geosetAnimation = geoset.geosetAnimation; - } - else { - final int geosetAnimationId = bone.getGeosetAnimationId(); - if (geosetAnimationId != -1) { - geosetAnimation = model.getGeosetAnimations().get(geosetAnimationId); - } - } - } - this.geosetAnimation = geosetAnimation; - } - - @Override - public int getVisibility(final float[] out, final int sequence, final int frame, final int counter) { - if (this.geosetAnimation != null) { - return this.geosetAnimation.getAlpha(out, sequence, frame, counter); - } - - out[0] = 1; - - return -1; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Camera.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Camera.java deleted file mode 100644 index cfcc6afe..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Camera.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.util.RenderMathUtils; -import com.hiveworkshop.rms.parsers.mdlx.AnimationMap; -import com.hiveworkshop.rms.parsers.mdlx.MdlxCamera; - -public class Camera extends AnimatedObject { - - public final String name; - public final float[] position; - public final float fieldOfView; - public final float farClippingPlane; - public final float nearClippingPlane; - public final float[] targetPosition; - - public Camera(final MdxModel model, final MdlxCamera camera) { - super(model, camera); - - this.name = camera.getName(); - this.position = camera.getPosition(); - this.fieldOfView = camera.getFieldOfView(); - this.farClippingPlane = camera.getFarClippingPlane(); - this.nearClippingPlane = camera.getNearClippingPlane(); - this.targetPosition = camera.getTargetPosition(); - } - - public int getPositionTranslation(final float[] out, final int sequence, final int frame, final int counter) { - return this.getVectorValue(out, AnimationMap.KCTR.getWar3id(), sequence, frame, counter, - RenderMathUtils.FLOAT_VEC3_ZERO); - } - - public int getTargetTranslation(final float[] out, final int sequence, final int frame, final int counter) { - return this.getVectorValue(out, AnimationMap.KTTR.getWar3id(), sequence, frame, counter, - RenderMathUtils.FLOAT_VEC3_ZERO); - } - - public int getRotation(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KCRL.getWar3id(), sequence, frame, counter, 0); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/CollisionShape.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/CollisionShape.java deleted file mode 100644 index 7d1635ba..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/CollisionShape.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.badlogic.gdx.math.Intersector; -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.math.collision.BoundingBox; -import com.badlogic.gdx.math.collision.Ray; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.viewer5.Bounds; -import com.etheller.warsmash.viewer5.GenericNode; -import com.hiveworkshop.rms.parsers.mdlx.MdlxCollisionShape; - -public class CollisionShape extends GenericObject { - private static Vector3 intersectHeap = new Vector3(); - private static Vector3 intersectHeap2 = new Vector3(); - private static Matrix4 intersectMatrixHeap = new Matrix4(); - private static Ray intersectRayHeap = new Ray(); - private Intersectable intersectable; - - public CollisionShape(final MdxModel model, final MdlxCollisionShape object, final int index) { - super(model, object, index); - final float[][] vertices = object.getVertices(); - - switch (object.getType()) { - case BOX: - this.intersectable = new IntersectableBox(vertices[0], vertices[1]); - break; - case CYLINDER: - this.intersectable = null; // TODO - break; - case PLANE: - this.intersectable = null; // TODO - break; - case SPHERE: - this.intersectable = new IntersectableSphere(vertices[0], object.getBoundsRadius()); - break; - } - } - - public boolean checkIntersect(final Ray ray, final MdxNode mdxNode, final Vector3 intersection) { - if (this.intersectable != null) { - return this.intersectable.checkIntersect(ray, mdxNode, intersection); - } - return false; - } - - private static interface Intersectable { - boolean checkIntersect(final Ray ray, final MdxNode mdxNode, final Vector3 intersection); - } - - private static final class IntersectableBox implements Intersectable { - private final BoundingBox boundingBox; - - public IntersectableBox(final float[] vertex1, final float[] vertex2) { - this.boundingBox = new BoundingBox(new Vector3(vertex1), new Vector3(vertex2)); - } - - @Override - public boolean checkIntersect(final Ray ray, final MdxNode mdxNode, final Vector3 intersection) { - intersectMatrixHeap.set(mdxNode.worldMatrix); - Matrix4.inv(intersectMatrixHeap.val); - intersectHeap.set(ray.origin); - intersectHeap2.set(ray.direction); - intersectHeap2.add(ray.origin); - intersectHeap.prj(intersectMatrixHeap); - intersectHeap2.prj(intersectMatrixHeap); - intersectHeap2.sub(intersectHeap); - intersectRayHeap.set(intersectHeap, intersectHeap2); - if (Intersector.intersectRayBounds(intersectRayHeap, this.boundingBox, intersection)) { - intersection.prj(mdxNode.worldMatrix); - return true; - } - return false; - } - } - - private static final class IntersectableSphere implements Intersectable { - private final Vector3 center; - private final float radius; - - public IntersectableSphere(final float[] center, final float radius) { - this.center = new Vector3(center); - this.radius = radius; - } - - @Override - public boolean checkIntersect(final Ray ray, final MdxNode mdxNode, final Vector3 intersection) { - intersectHeap.set(this.center); - intersectHeap.prj(mdxNode.worldMatrix); - if (Intersector.intersectRaySphere(ray, intersectHeap, this.radius, intersection)) { - return true; - } - return false; - } - } - - public static boolean intersectRayTriangles(final Ray ray, final GenericNode mdxNode, final float[] vertices, - final int[] indices, final int vertexSize, final Vector3 intersection) { - intersectMatrixHeap.set(mdxNode.worldMatrix); - Matrix4.inv(intersectMatrixHeap.val); - intersectHeap.set(ray.origin); - intersectHeap2.set(ray.direction); - intersectHeap2.add(ray.origin); - intersectHeap.prj(intersectMatrixHeap); - intersectHeap2.prj(intersectMatrixHeap); - intersectHeap2.sub(intersectHeap); - intersectRayHeap.set(intersectHeap, intersectHeap2); - if (RenderMathUtils.intersectRayTriangles(intersectRayHeap, vertices, indices, vertexSize, intersection)) { - intersection.prj(mdxNode.worldMatrix); - return true; - } - return false; - } - - public static boolean intersectRayBounds(final Bounds bounds, final Matrix4 worldMatrix, final Ray ray, - final Vector3 intersection) { - intersectMatrixHeap.set(worldMatrix); - Matrix4.inv(intersectMatrixHeap.val); - intersectHeap.set(ray.origin); - intersectHeap2.set(ray.direction); - intersectHeap2.add(ray.origin); - intersectHeap.prj(intersectMatrixHeap); - intersectHeap2.prj(intersectMatrixHeap); - intersectHeap2.sub(intersectHeap); - intersectRayHeap.set(intersectHeap, intersectHeap2); - if (bounds.intersectRay(intersectRayHeap, intersection)) { - intersection.prj(worldMatrix); - return true; - } - return false; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EmitterGroup.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EmitterGroup.java deleted file mode 100644 index 0586672d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EmitterGroup.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.badlogic.gdx.math.Matrix4; -import com.etheller.warsmash.viewer5.Model; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.SkeletalNode; -import com.etheller.warsmash.viewer5.gl.ANGLEInstancedArrays; -import com.etheller.warsmash.viewer5.handlers.w3x.DynamicShadowManager; - -public class EmitterGroup extends GenericGroup { - private final MdxModel model; - - public EmitterGroup(final MdxModel model) { - this.model = model; - } - - @Override - public void render(final MdxComplexInstance instance, final Matrix4 mvp) { - if (DynamicShadowManager.IS_SHADOW_MAPPING) { - return; - } - - final Scene scene = instance.scene; - final SkeletalNode[] nodes = instance.nodes; - final Model model = instance.model; - final ModelViewer viewer = model.viewer; - final GL20 gl = viewer.gl; - final ANGLEInstancedArrays instancedArrays = viewer.webGL.instancedArrays; - final ShaderProgram shader = ((MdxModel) model).handler.shaders.particles; - - gl.glDepthMask(false); - gl.glEnable(GL20.GL_BLEND); - gl.glDisable(GL20.GL_CULL_FACE); - gl.glEnable(GL20.GL_DEPTH_TEST); - - viewer.webGL.useShaderProgram(shader); - - shader.setUniformMatrix("u_mvp", mvp); - shader.setUniformi("u_texture", 0); - - final int a_position = shader.getAttributeLocation("a_position"); - instancedArrays.glVertexAttribDivisorANGLE(a_position, 0); - - gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, viewer.rectBuffer); - gl.glVertexAttribPointer(a_position, 1, GL20.GL_UNSIGNED_BYTE, false, 0, 0); - - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_p0"), 1); - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_p1"), 1); - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_p2"), 1); - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_p3"), 1); - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_health"), 1); - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_color"), 1); - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_tail"), 1); - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_leftRightTop"), 1); - - for (final int index : this.objects) { - GeometryEmitterFuncs.renderEmitter((MdxEmitter) nodes[index].object, shader); - } - - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_leftRightTop"), 0); - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_tail"), 0); - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_color"), 0); - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_health"), 0); - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_p3"), 0); - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_p2"), 0); - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_p1"), 0); - instancedArrays.glVertexAttribDivisorANGLE(shader.getAttributeLocation("a_p0"), 0); - - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectEmitter.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectEmitter.java deleted file mode 100644 index 9c5a2256..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectEmitter.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.viewer5.EmittedObject; - -public abstract class EventObjectEmitter>> - extends MdxEmitter { - private static final long[] valueHeap = { 0L }; - - private int lastEmissionKey; - - public EventObjectEmitter(final MdxComplexInstance instance, final EMITTER_OBJECT emitterObject) { - super(instance, emitterObject); - this.lastEmissionKey = -1; - } - - @Override - protected void updateEmission(final float dt) { - final MdxComplexInstance instance = this.instance; - - if (instance.allowParticleSpawn) { - final EMITTER_OBJECT emitterObject = this.emitterObject; - - final int keyframe = emitterObject.getValue(valueHeap, instance); - - if (keyframe != this.lastEmissionKey) { - this.currentEmission += 1; - this.lastEmissionKey = keyframe; - } - } - - } - - public void reset() { - this.lastEmissionKey = -1; - } - - @Override - protected void emit() { - this.emitObject(0); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectEmitterObject.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectEmitterObject.java deleted file mode 100644 index 0b470930..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectEmitterObject.java +++ /dev/null @@ -1,369 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.audio.Sound; -import com.badlogic.gdx.files.FileHandle; -import com.etheller.warsmash.common.FetchDataTypeName; -import com.etheller.warsmash.common.LoadGenericCallback; -import com.etheller.warsmash.util.MappedData; -import com.etheller.warsmash.util.MappedDataRow; -import com.etheller.warsmash.viewer5.GenericResource; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.Texture; -import com.etheller.warsmash.viewer5.handlers.EmitterObject; -import com.hiveworkshop.rms.parsers.mdlx.MdlxEventObject; -import com.hiveworkshop.rms.parsers.mdlx.MdlxParticleEmitter2; - -public class EventObjectEmitterObject extends GenericObject implements EmitterObject { - private static final class LoadGenericSoundCallback implements LoadGenericCallback { - private final String filename; - - public LoadGenericSoundCallback(final String filename) { - this.filename = filename; - } - - @Override - public Object call(final InputStream data) { - final FileHandle temp = new FileHandle(this.filename) { - @Override - public InputStream read() { - return data; - } - - ; - }; - if (data != null) { - return Gdx.audio.newSound(temp); - } - else { - System.err.println("Warning: missing sound file: " + this.filename); - return null; - } - } - } - - private static final LoadGenericCallback mappedDataCallback = new LoadGenericCallback() { - - @Override - public Object call(final InputStream data) { - final StringBuilder stringBuilder = new StringBuilder(); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(data, "utf-8"))) { - String line; - while ((line = reader.readLine()) != null) { - stringBuilder.append(line); - stringBuilder.append("\n"); - } - } - catch (final UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return new MappedData(stringBuilder.toString()); - } - }; - - private int geometryEmitterType = -1; - public final String type; - private final String id; - public final long[] keyFrames; - private long globalSequence = -1; - private final long[] defval = { 1 }; - public MdxModel internalModel; - public Texture internalTexture; - public float[][] colors; - public float[] intervalTimes; - public float scale; - public int columns; - public int rows; - public float lifeSpan; - public int blendSrc; - public int blendDst; - public float[][] intervals; - public float distanceCutoff; - private float maxDistance; - public float minDistance; - public float pitch; - public float pitchVariance; - public float volume; - public List decodedBuffers = new ArrayList<>(); - /** - * If this is an SPL/UBR emitter object, ok will be set to true if the tables - * are loaded. - *

- * This is because, like the other geometry emitters, it is fine to use them - * even if the textures don't load. - *

- * The particles will simply be black. - */ - private boolean ok = false; - - public EventObjectEmitterObject(final MdxModel model, final MdlxEventObject eventObject, final int index) { - super(model, eventObject, index); - - final ModelViewer viewer = model.viewer; - final String name = eventObject.getName(); - String type = name.substring(0, 3); - final String id = name.substring(4); - - // Same thing - if ("FPT".equals(type)) { - type = "SPL"; - } - - if ("SPL".equals(type)) { - this.geometryEmitterType = GeometryEmitterFuncs.EMITTER_SPLAT; - } - else if ("UBR".equals(type)) { - this.geometryEmitterType = GeometryEmitterFuncs.EMITTER_UBERSPLAT; - } - else if ("SPN".equals(type)) { - this.geometryEmitterType = GeometryEmitterFuncs.EMITTER_SPN; - } - - this.type = type; - this.id = id; - this.keyFrames = eventObject.getKeyFrames(); - - final int globalSequenceId = eventObject.getGlobalSequenceId(); - if (globalSequenceId != -1) { - this.globalSequence = model.getGlobalSequences().get(globalSequenceId); - } - - final List tables = new ArrayList<>(); - final PathSolver pathSolver = model.pathSolver; - final Object solverParams = model.solverParams; - - if ("SPN".equals(type)) { - tables.add(viewer.loadGeneric(pathSolver.solve("Splats\\SpawnData.slk", solverParams).finalSrc, - FetchDataTypeName.SLK, mappedDataCallback)); - } - else if ("SPL".equals(type)) { - tables.add(viewer.loadGeneric(pathSolver.solve("Splats\\SplatData.slk", solverParams).finalSrc, - FetchDataTypeName.SLK, mappedDataCallback)); - } - else if ("UBR".equals(type)) { - tables.add(viewer.loadGeneric(pathSolver.solve("Splats\\UberSplatData.slk", solverParams).finalSrc, - FetchDataTypeName.SLK, mappedDataCallback)); - } - else if ("SND".equals(type)) { - if (!model.reforged) { - tables.add(viewer.loadGeneric(pathSolver.solve("UI\\SoundInfo\\AnimLookups.slk", solverParams).finalSrc, - FetchDataTypeName.SLK, mappedDataCallback)); - } - tables.add(viewer.loadGeneric(pathSolver.solve("UI\\SoundInfo\\AnimSounds.slk", solverParams).finalSrc, - FetchDataTypeName.SLK, mappedDataCallback)); - } - else { - // Units\Critters\BlackStagMale\BlackStagMale.mdx has an event object named - // "Point01". - return; - } - - // TODO I am scrapping some async stuff with promises here from the JS and - // calling load - this.load(tables); - } - - private float getFloat(final MappedDataRow row, final String name) { - final Float x = (Float) row.get(name); - if (x == null) { - return Float.NaN; - } - else { - return x.floatValue(); - } - } - - private int getInt(final MappedDataRow row, final String name) { - return getInt(row, name, Integer.MIN_VALUE); - } - - private int getInt(final MappedDataRow row, final String name, final int defaultValue) { - final Number x = (Number) row.get(name); - if (x == null) { - return defaultValue; - } - else { - return x.intValue(); - } - } - - private void load(final List tables) { - final MappedData firstTable = (MappedData) tables.get(0).data; - if (firstTable == null) { - return; - } - final MappedDataRow row = firstTable.getRow(this.id.trim()); - - if (row != null) { - final MdxModel model = this.model; - final ModelViewer viewer = model.viewer; - final PathSolver pathSolver = model.pathSolver; - - if ("SPN".equals(this.type)) { - this.internalModel = (MdxModel) viewer.load(((String) row.get("Model")).replace(".mdl", ".mdx"), - pathSolver, model.solverParams); - - if (this.internalModel != null) { - // TODO javascript async code removed here -// this.internalModel.whenLoaded((model) => this.ok = model.ok) - this.ok = this.internalModel.ok; - } - } - else if ("SPL".equals(this.type) || "UBR".equals(this.type)) { - final String texturesExt = model.reforged ? ".dds" : ".blp"; - - this.internalTexture = (Texture) viewer.load( - "ReplaceableTextures\\Splats\\" + row.get("file") + texturesExt, pathSolver, - model.solverParams); - - this.scale = getFloat(row, "Scale"); - this.colors = new float[][] { - { getFloat(row, "StartR"), getFloat(row, "StartG"), getFloat(row, "StartB"), - getFloat(row, "StartA") }, - { getFloat(row, "MiddleR"), getFloat(row, "MiddleG"), getFloat(row, "MiddleB"), - getFloat(row, "MiddleA") }, - { getFloat(row, "EndR"), getFloat(row, "EndG"), getFloat(row, "EndB"), - getFloat(row, "EndA") } }; - - if ("SPL".equals(this.type)) { - this.columns = getInt(row, "Columns"); - this.rows = getInt(row, "Rows"); - this.lifeSpan = getFloat(row, "Lifespan") + getFloat(row, "Decay"); - this.intervalTimes = new float[] { getFloat(row, "Lifespan"), getFloat(row, "Decay") }; - this.intervals = new float[][] { - { getFloat(row, "UVLifespanStart"), getFloat(row, "UVLifespanEnd"), - getFloat(row, "LifespanRepeat") }, - { getFloat(row, "UVDecayStart"), getFloat(row, "UVDecayEnd"), - getFloat(row, "DecayRepeat") }, }; - } - else { - this.columns = 1; - this.rows = 1; - this.lifeSpan = getFloat(row, "BirthTime") + getFloat(row, "PauseTime") + getFloat(row, "Decay"); - this.intervalTimes = new float[] { getFloat(row, "BirthTime"), getFloat(row, "PauseTime"), - getFloat(row, "Decay") }; - } - - final int[] blendModes = FilterMode - .emitterFilterMode(MdlxParticleEmitter2.FilterMode.fromId(getInt(row, "BlendMode"))); - - this.blendSrc = blendModes[0]; - this.blendDst = blendModes[1]; - - this.ok = true; - } - else if ("SND".equals(this.type)) { - // Only load sounds if audio is enabled. - // This is mostly to save on bandwidth and loading time, especially when loading - // full maps. - if (viewer.audioEnabled) { - final MappedData animSounds = (MappedData) tables.get(1).data; - - final MappedDataRow animSoundsRow = animSounds.getRow((String) row.get("SoundLabel")); - - if (animSoundsRow != null) { - this.distanceCutoff = getFloat(animSoundsRow, "DistanceCutoff"); - this.maxDistance = getFloat(animSoundsRow, "MaxDistance"); - this.minDistance = getFloat(animSoundsRow, "MinDistance"); - this.pitch = getFloat(animSoundsRow, "Pitch"); - this.pitchVariance = getFloat(animSoundsRow, "PitchVariance"); - this.volume = getFloat(animSoundsRow, "Volume") / 127f; - - final String[] fileNames = ((String) animSoundsRow.get("FileNames")).split(","); - final GenericResource[] resources = new GenericResource[fileNames.length]; - for (int i = 0; i < fileNames.length; i++) { - final String path = ((String) animSoundsRow.get("DirectoryBase")) + fileNames[i]; - try { - final String pathString = pathSolver.solve(path, model.solverParams).finalSrc; - final GenericResource genericResource = viewer.loadGeneric(pathString, - FetchDataTypeName.ARRAY_BUFFER, new LoadGenericSoundCallback(pathString)); - if (genericResource == null) { - System.err.println("Null sound: " + fileNames[i]); - } - resources[i] = genericResource; - } - catch (final Exception exc) { - System.err.println("Failed to load sound: " + path); - exc.printStackTrace(); - } - } - - // TODO JS async removed - for (final GenericResource resource : resources) { - if (resource != null) { - this.decodedBuffers.add((Sound) resource.data); - } - } - this.ok = true; - } - } - } - else { - System.err.println("Unknown event object type: " + this.type + this.id); - } - } - else { - System.err.println("Unknown event object ID: " + this.type + this.id); - } - } - - public int getValue(final long[] out, final MdxComplexInstance instance) { - if (this.globalSequence != -1) { - - return this.getValueAtTime(out, instance.counter % this.globalSequence, 0, this.globalSequence); - } - else if (instance.sequence != -1) { - final long[] interval = this.model.getSequences().get(instance.sequence).getInterval(); - - return this.getValueAtTime(out, instance.frame, interval[0], interval[1]); - } - else { - out[0] = this.defval[0]; - - return -1; - } - } - - public int getValueAtTime(final long[] out, final long frame, final long start, final long end) { - if ((frame >= start) && (frame <= end)) { - for (int i = this.keyFrames.length - 1; i > -1; i--) { - if (this.keyFrames[i] < start) { - out[0] = 0; - - return -1; - } - else if (this.keyFrames[i] <= frame) { - out[0] = 1; - - return i; - } - } - } - - out[0] = 0; - - return -1; - } - - @Override - public boolean ok() { - return this.ok; - } - - @Override - public int getGeometryEmitterType() { - return this.geometryEmitterType; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSnd.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSnd.java deleted file mode 100644 index 4afebca5..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSnd.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.List; - -import com.badlogic.gdx.audio.Sound; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.viewer5.AudioBufferSource; -import com.etheller.warsmash.viewer5.AudioContext; -import com.etheller.warsmash.viewer5.AudioPanner; -import com.etheller.warsmash.viewer5.EmittedObject; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.Scene; - -public class EventObjectSnd extends EmittedObject { - public EventObjectSnd(final EventObjectSndEmitter emitter) { - super(emitter); - } - - @Override - protected void bind(final int flags) { - final EventObjectSndEmitter emitter = this.emitter; - final MdxComplexInstance instance = emitter.instance; - final ModelViewer viewer = instance.model.viewer; - final Scene scene = instance.scene; - - // Is audio enabled both viewer-wide and in this scene? - if (viewer.audioEnabled && scene.audioEnabled) { - final EventObjectEmitterObject emitterObject = emitter.emitterObject; - final MdxNode node = instance.nodes[emitterObject.index]; - final AudioContext audioContext = scene.audioContext; - final List decodedBuffers = emitterObject.decodedBuffers; - if (decodedBuffers.isEmpty()) { - return; - } - final AudioPanner panner = audioContext.createPanner(); - final AudioBufferSource source = audioContext.createBufferSource(); - final Vector3 location = node.worldLocation; - - // Panner settings - panner.setPosition(location.x, location.y, location.z); - panner.setDistances(emitterObject.distanceCutoff, emitterObject.minDistance); - panner.connect(audioContext.destination); - - // Source. - source.buffer = decodedBuffers.get((int) (Math.random() * decodedBuffers.size())); - source.connect(panner); - - // Make a sound. - source.start(0, emitterObject.volume, - (emitterObject.pitch + ((float) Math.random() * emitterObject.pitchVariance * 2)) - - emitterObject.pitchVariance, - false); - } - } - - @Override - public void update(final float dt) { - - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSndEmitter.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSndEmitter.java deleted file mode 100644 index 6eba3619..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSndEmitter.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -public class EventObjectSndEmitter extends EventObjectEmitter { - - public EventObjectSndEmitter(final MdxComplexInstance instance, final EventObjectEmitterObject emitterObject) { - super(instance, emitterObject); - } - - @Override - protected EventObjectSnd createObject() { - return new EventObjectSnd(this); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSplEmitter.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSplEmitter.java deleted file mode 100644 index e1120233..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSplEmitter.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -public class EventObjectSplEmitter extends EventObjectEmitter { - public EventObjectSplEmitter(final MdxComplexInstance instance, final EventObjectEmitterObject emitterObject) { - super(instance, emitterObject); - } - - @Override - protected EventObjectSplUbr createObject() { - return new EventObjectSplUbr(this); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSplUbr.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSplUbr.java deleted file mode 100644 index ac7b8d7d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSplUbr.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.viewer5.EmittedObject; - -public class EventObjectSplUbr - extends EmittedObject> { - private static final Vector3 vertexHeap = new Vector3(); - - public final float[] vertices = new float[12]; - - public EventObjectSplUbr(final EventObjectEmitter emitter) { - super(emitter); - } - - @Override - protected void bind(final int flags) { - final EventObjectEmitter emitter = this.emitter; - final MdxComplexInstance instance = emitter.instance; - final EventObjectEmitterObject emitterObject = emitter.emitterObject; - final float[] vertices = this.vertices; - final float scale = emitterObject.scale; - final MdxNode node = instance.nodes[emitterObject.index]; - final Matrix4 worldMatrix = node.worldMatrix; - - this.health = emitterObject.lifeSpan; - - vertexHeap.x = scale; - vertexHeap.y = scale; - vertexHeap.prj(worldMatrix); - vertices[0] = vertexHeap.x; - vertices[1] = vertexHeap.y; - vertices[2] = vertexHeap.z; - - vertexHeap.x = -scale; - vertexHeap.y = scale; - vertexHeap.prj(worldMatrix); - vertices[3] = vertexHeap.x; - vertices[4] = vertexHeap.y; - vertices[5] = vertexHeap.z; - - vertexHeap.x = -scale; - vertexHeap.y = -scale; - vertexHeap.prj(worldMatrix); - vertices[6] = vertexHeap.x; - vertices[7] = vertexHeap.y; - vertices[8] = vertexHeap.z; - - vertexHeap.x = scale; - vertexHeap.y = -scale; - vertexHeap.prj(worldMatrix); - vertices[9] = vertexHeap.x; - vertices[10] = vertexHeap.y; - vertices[11] = vertexHeap.z; - - } - - @Override - public void update(final float dt) { - this.health -= dt; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSpn.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSpn.java deleted file mode 100644 index 9c58ef8e..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSpn.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.viewer5.EmittedObject; -import com.etheller.warsmash.viewer5.Scene; - -public class EventObjectSpn extends EmittedObject { - private final MdxComplexInstance internalInstance; - - public EventObjectSpn(final EventObjectSpnEmitter emitter) { - super(emitter); - - final EventObjectEmitterObject emitterObject = emitter.emitterObject; - final MdxModel internalModel = emitterObject.internalModel; - - this.internalInstance = (MdxComplexInstance) internalModel.addInstance(); - } - - @Override - protected void bind(final int flags) { - final EventObjectSpnEmitter emitter = this.emitter; - final MdxComplexInstance instance = emitter.instance; - final Scene scene = instance.scene; - final MdxNode node = instance.nodes[emitter.emitterObject.index]; - final MdxComplexInstance internalInstance = this.internalInstance; - - internalInstance.setSequence(0); - internalInstance.setTransformation(node.worldLocation, node.worldRotation, node.worldScale); - internalInstance.show(); - - scene.addInstance(internalInstance); - - this.health = 1; - } - - @Override - public void update(final float dt) { - final MdxComplexInstance instance = this.internalInstance; - final MdxModel model = (MdxModel) instance.model; - - // Once the sequence finishes, this event object dies - if (model.getSequences().isEmpty()) { - System.err.println("NO SEQ FOR " + model.name); - } - if (instance.frame >= model.getSequences().get(0).getInterval()[1]) { - this.health = 0; - - instance.hide(); - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSpnEmitter.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSpnEmitter.java deleted file mode 100644 index 786e5ba4..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectSpnEmitter.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -public class EventObjectSpnEmitter extends EventObjectEmitter { - - public EventObjectSpnEmitter(final MdxComplexInstance instance, final EventObjectEmitterObject emitterObject) { - super(instance, emitterObject); - } - - @Override - protected EventObjectSpn createObject() { - return new EventObjectSpn(this); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectUbrEmitter.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectUbrEmitter.java deleted file mode 100644 index 7589e78a..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/EventObjectUbrEmitter.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -public class EventObjectUbrEmitter extends EventObjectEmitter { - public EventObjectUbrEmitter(final MdxComplexInstance instance, final EventObjectEmitterObject emitterObject) { - super(instance, emitterObject); - } - - @Override - protected EventObjectSplUbr createObject() { - return new EventObjectSplUbr(this); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/FilterMode.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/FilterMode.java deleted file mode 100644 index d610cff0..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/FilterMode.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.badlogic.gdx.graphics.GL20; -import com.hiveworkshop.rms.parsers.mdlx.MdlxLayer; -import com.hiveworkshop.rms.parsers.mdlx.MdlxParticleEmitter2; - -public class FilterMode { - private static final int[] ERROR_DEFAULT = new int[] { 0, 0 }; - private static final int[] MODULATE_2X = new int[] { GL20.GL_DST_COLOR, GL20.GL_SRC_COLOR }; - private static final int[] MODULATE = new int[] { GL20.GL_ZERO, GL20.GL_SRC_COLOR }; - public static final int[] ADDITIVE_ALPHA = new int[] { GL20.GL_SRC_ALPHA, GL20.GL_ONE }; - private static final int[] BLEND = new int[] { GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA }; - - public static int[] layerFilterMode(final MdlxLayer.FilterMode filterMode) { - switch (filterMode) { - case BLEND: - return BLEND; // Blend - case ADDITIVE: - return ADDITIVE_ALPHA; // Additive - case ADDALPHA: - return ADDITIVE_ALPHA; // Add alpha - case MODULATE: - return MODULATE; // Modulate - case MODULATE2X: - return MODULATE_2X; // Modulate 2x - default: - return ERROR_DEFAULT; - } - } - - public static int[] emitterFilterMode(final MdlxParticleEmitter2.FilterMode filterMode) { - switch (filterMode) { - case BLEND: - return BLEND; // Blend - case ADDITIVE: - return ADDITIVE_ALPHA; // Add alpha - case MODULATE: - return MODULATE; // Modulate - case MODULATE2X: - return MODULATE_2X; // Modulate 2x - case ALPHAKEY: - return BLEND; // Add alpha - default: - return ERROR_DEFAULT; - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GenericGroup.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GenericGroup.java deleted file mode 100644 index f4b27e55..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GenericGroup.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.math.Matrix4; - -public abstract class GenericGroup { - public final List objects; - - public abstract void render(MdxComplexInstance instance, Matrix4 mvp); - - public GenericGroup() { - this.objects = new ArrayList<>(); // TODO IntArrayList - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GenericIndexed.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GenericIndexed.java deleted file mode 100644 index f5151a5d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GenericIndexed.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -public interface GenericIndexed { - public int getIndex(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GenericObject.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GenericObject.java deleted file mode 100644 index f71ac28d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GenericObject.java +++ /dev/null @@ -1,171 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.util.RenderMathUtils; -import com.hiveworkshop.rms.parsers.mdlx.AnimationMap; -import com.hiveworkshop.rms.parsers.mdlx.MdlxGenericObject; - -public class GenericObject extends AnimatedObject implements GenericIndexed { - - public final int index; - public final String name; - public final int objectId; - public final int parentId; - public final float[] pivot; - public final int dontInheritTranslation; - public final int dontInheritRotation; - public final int dontInheritScaling; - public final int billboarded; - public final int billboardedX; - public final int billboardedY; - public final int billboardedZ; - public final int cameraAnchored; - public final int bone; - public final int light; - public final int eventObject; - public final int attachment; - public final int particleEmitter; - public final int collisionShape; - public final int ribbonEmitter; - public final int emitterUsesMdlOrUnshaded; - public final int emitterUsesTgaOrSortPrimitivesFarZ; - public final int lineEmitter; - public final int unfogged; - public final int modelSpace; - public final int xYQuad; - public final boolean anyBillboarding; - public final Variants variants; - public final boolean hasTranslationAnim; - public final boolean hasRotationAnim; - public final boolean hasScaleAnim; - public final boolean hasGenericAnim; - - public GenericObject(final MdxModel model, final MdlxGenericObject object, final int index) { - super(model, object); - - this.index = index; - this.name = object.getName(); - int objectId = object.getObjectId(); - if (objectId == -1) { - objectId = index; - } - this.objectId = objectId; - int parentId = object.getParentId(); - this.pivot = ((this.objectId < model.getPivotPoints().size())) ? model.getPivotPoints().get(this.objectId) - : new float[] { 0, 0, 0 }; - - final int flags = object.getFlags(); - - this.dontInheritTranslation = flags & 0x1; - this.dontInheritRotation = flags & 0x2; - this.dontInheritScaling = flags & 0x4; - this.billboarded = flags & 0x8; - this.billboardedX = flags & 0x10; - this.billboardedY = flags & 0x20; - this.billboardedZ = flags & 0x40; - this.cameraAnchored = flags & 0x80; - this.bone = flags & 0x100; - this.light = flags & 0x200; - this.eventObject = flags & 0x400; - this.attachment = flags & 0x800; - this.particleEmitter = flags & 0x1000; - this.collisionShape = flags & 0x2000; - this.ribbonEmitter = flags & 0x4000; - this.emitterUsesMdlOrUnshaded = flags & 0x8000; - this.emitterUsesTgaOrSortPrimitivesFarZ = flags & 0x10000; - this.lineEmitter = flags & 0x20000; - this.unfogged = flags & 0x40000; - this.modelSpace = flags & 0x80000; - this.xYQuad = flags & 0x100000; - - this.anyBillboarding = (this.billboarded != 0) || (this.billboardedX != 0) || (this.billboardedY != 0) - || (this.billboardedZ != 0); - - if (object.getObjectId() == object.getParentId()) { - parentId = -1; // - } - this.parentId = parentId; - - final Variants variants = new Variants(model.getSequences().size()); - - boolean hasTranslationAnim = false; - boolean hasRotationAnim = false; - boolean hasScaleAnim = false; - - for (int i = 0; i < model.getSequences().size(); i++) { - final boolean translation = this.isTranslationVariant(i); - final boolean rotation = this.isRotationVariant(i); - final boolean scale = this.isScaleVariant(i); - - variants.translation[i] = translation; - variants.rotation[i] = rotation; - variants.scale[i] = scale; - variants.generic[i] = translation || rotation || scale; - - hasTranslationAnim = hasTranslationAnim || translation; - hasRotationAnim = hasRotationAnim || rotation; - hasScaleAnim = hasScaleAnim || scale; - } - - this.variants = variants; - this.hasTranslationAnim = hasTranslationAnim; - this.hasRotationAnim = hasRotationAnim; - this.hasScaleAnim = hasScaleAnim; - this.hasGenericAnim = hasTranslationAnim || hasRotationAnim || hasScaleAnim; - } - - /** - * Many of the generic objects have animated visibilities. This is a generic - * getter to allow the code to be consistent. - */ - public int getVisibility(final float[] out, final int sequence, final int frame, final int counter) { - out[0] = 1; - return -1; - } - - public int getTranslation(final float[] out, final int sequence, final int frame, final int counter) { - return this.getVectorValue(out, AnimationMap.KGTR.getWar3id(), sequence, frame, counter, - RenderMathUtils.FLOAT_VEC3_ZERO); - } - - public int getRotation(final float[] out, final int sequence, final int frame, final int counter) { - return this.getQuatValue(out, AnimationMap.KGRT.getWar3id(), sequence, frame, counter, - RenderMathUtils.FLOAT_QUAT_DEFAULT); - } - - public int getScale(final float[] out, final int sequence, final int frame, final int counter) { - return this.getVectorValue(out, AnimationMap.KGSC.getWar3id(), sequence, frame, counter, - RenderMathUtils.FLOAT_VEC3_ONE); - } - - public boolean isTranslationVariant(final int sequence) { - return this.isVariant(AnimationMap.KGTR.getWar3id(), sequence); - } - - public boolean isRotationVariant(final int sequence) { - return this.isVariant(AnimationMap.KGRT.getWar3id(), sequence); - } - - public boolean isScaleVariant(final int sequence) { - return this.isVariant(AnimationMap.KGSC.getWar3id(), sequence); - } - - public static final class Variants { - boolean[] translation; - boolean[] rotation; - boolean[] scale; - boolean[] generic; - - public Variants(final int sequencesCount) { - this.translation = new boolean[sequencesCount]; - this.rotation = new boolean[sequencesCount]; - this.scale = new boolean[sequencesCount]; - this.generic = new boolean[sequencesCount]; - } - } - - @Override - public int getIndex() { - return this.index; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GeometryEmitterFuncs.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GeometryEmitterFuncs.java deleted file mode 100644 index 978b2a60..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GeometryEmitterFuncs.java +++ /dev/null @@ -1,468 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; -import java.util.List; - -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.Camera; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.Texture; -import com.etheller.warsmash.viewer5.TextureMapper; -import com.etheller.warsmash.viewer5.gl.ANGLEInstancedArrays; -import com.etheller.warsmash.viewer5.gl.ClientBuffer; -import com.etheller.warsmash.viewer5.gl.DataTexture; -import com.etheller.warsmash.viewer5.handlers.EmitterObject; -import com.etheller.warsmash.viewer5.handlers.w3x.W3xSceneLightManager; - -//The total storage that emitted objects can use. -//This is enough to support all of the MDX geometry emitters. -//The memory layout is the same as this C struct: -// -//struct { -// float p0[3] -// float p1[3] -// float p2[3] -// float p3[3] -// float health -// byte color[4] -// byte tail -// byte leftRightTop[3] -//} -// -public class GeometryEmitterFuncs { - public static final int BYTES_PER_OBJECT = 60; - public static final int FLOATS_PER_OBJECT = BYTES_PER_OBJECT >> 2; - - // Offsets into the emitted object structure - public static final int BYTE_OFFSET_P0 = 0; - public static final int BYTE_OFFSET_P1 = 12; - public static final int BYTE_OFFSET_P2 = 24; - public static final int BYTE_OFFSET_P3 = 36; - public static final int BYTE_OFFSET_HEALTH = 48; - public static final int BYTE_OFFSET_COLOR = 52; - public static final int BYTE_OFFSET_TAIL = 56; - public static final int BYTE_OFFSET_LEFT_RIGHT_TOP = 57; - - // Offset aliases - public static final int FLOAT_OFFSET_P0 = BYTE_OFFSET_P0 >> 2; - public static final int FLOAT_OFFSET_P1 = BYTE_OFFSET_P1 >> 2; - public static final int FLOAT_OFFSET_P2 = BYTE_OFFSET_P2 >> 2; - public static final int FLOAT_OFFSET_P3 = BYTE_OFFSET_P3 >> 2; - public static final int FLOAT_OFFSET_HEALTH = BYTE_OFFSET_HEALTH >> 2; - public static final int BYTE_OFFSET_TEAM_COLOR = BYTE_OFFSET_LEFT_RIGHT_TOP; - - // Head or tail. - public static final int HEAD = 0; - public static final int TAIL = 1; - - // Emitter types - public static final int EMITTER_PARTICLE2 = 0; - public static final int EMITTER_RIBBON = 1; - public static final int EMITTER_SPLAT = 2; - public static final int EMITTER_UBERSPLAT = 3; - public static final int EMITTER_SPN = 4; // added by Retera because reasons - - private static final Vector3 locationHeap = new Vector3(); - private static final Vector3 startHeap = new Vector3(); - private static final Vector3 endHeap = new Vector3(); - private static final float[] vectorTemp = new float[3]; - private static final Vector3[] vector3Heap = { new Vector3(), new Vector3(), new Vector3(), new Vector3(), - new Vector3(), new Vector3() }; - - public static void bindParticleEmitter2Buffer(final ParticleEmitter2 emitter, final ClientBuffer buffer) { - final MdxComplexInstance instance = emitter.instance; - final List objects = emitter.objects; - final ByteBuffer byteView = buffer.byteView; - final FloatBuffer floatView = buffer.floatView; - final ParticleEmitter2Object emitterObject = emitter.emitterObject; - final int modelSpace = emitterObject.modelSpace; - final float tailLength = emitterObject.tailLength; - int offset = 0; - - for (int objectIndex = 0; objectIndex < emitter.alive; objectIndex++) { - final Particle2 object = objects.get(objectIndex); - final int byteOffset = offset * BYTES_PER_OBJECT; - final int floatOffset = offset * FLOATS_PER_OBJECT; - final int p0Offset = floatOffset + FLOAT_OFFSET_P0; - Vector3 location = object.location; - final Vector3 scale = object.scale; - final int tail = object.tail; - - if (tail == HEAD) { - // If this is a model space emitter, the location is in local space, so convert - // it to world space. - if (modelSpace != 0) { - location = locationHeap.set(location).prj(emitter.node.worldMatrix); - } - - floatView.put(p0Offset + 0, location.x); - floatView.put(p0Offset + 1, location.y); - floatView.put(p0Offset + 2, location.z); - if (emitterObject.xYQuad != 0) { - final Vector3 velocity = object.velocity; - floatView.put(p0Offset + 3, velocity.x); - floatView.put(p0Offset + 4, velocity.y); - floatView.put(p0Offset + 5, velocity.z); - } - else { - floatView.put(p0Offset + 3, 0); - floatView.put(p0Offset + 4, 0); - } - } - else { - final Vector3 velocity = object.velocity; - final Vector3 start = startHeap; - Vector3 end = location; - - start.x = end.x - (tailLength * velocity.x); - start.y = end.y - (tailLength * velocity.y); - start.z = end.z - (tailLength * velocity.z); - - // If this is a model space emitter, the start and end are in local space, so - // convert them to world space. - if (modelSpace != 0) { - start.prj(emitter.node.worldMatrix); - end = endHeap.set(end).prj(emitter.node.worldMatrix); - } - - floatView.put(p0Offset + 0, start.x); - floatView.put(p0Offset + 1, start.y); - floatView.put(p0Offset + 2, start.z); - floatView.put(p0Offset + 3, end.x); - floatView.put(p0Offset + 4, end.y); - floatView.put(p0Offset + 5, end.z); - } - - floatView.put(p0Offset + 6, scale.x); - floatView.put(p0Offset + 7, scale.y); - floatView.put(p0Offset + 8, scale.z); - - floatView.put(floatOffset + FLOAT_OFFSET_HEALTH, object.health); - - byteView.put(byteOffset + BYTE_OFFSET_TAIL, (byte) tail); - byteView.put(byteOffset + BYTE_OFFSET_TEAM_COLOR, (byte) 0); - - offset += 1; - } - - } - - public static void bindParticleEmitter2Shader(final ParticleEmitter2 emitter, final ShaderProgram shader) { - final MdxComplexInstance instance = emitter.instance; - final Scene scene = instance.scene; - final Camera camera = scene.camera; - final ParticleEmitter2Object emitterObject = emitter.emitterObject; - final MdxModel model = emitterObject.model; - final ModelViewer viewer = model.viewer; - final GL20 gl = viewer.gl; - final float[][] colors = emitterObject.colors; - final float[][] intervals = emitterObject.intervals; - final long replaceableId = emitterObject.replaceableId; - Vector3[] vectors; - Texture texture; - - gl.glBlendFunc(emitterObject.blendSrc, emitterObject.blendDst); - - if ((replaceableId > 0) && (replaceableId < WarsmashConstants.REPLACEABLE_TEXTURE_LIMIT) - && (instance.replaceableTextures[(int) replaceableId] != null)) { - texture = instance.replaceableTextures[(int) replaceableId]; - } - else { - texture = emitterObject.internalTexture; - } - - viewer.webGL.bindTexture(texture, 0); - - // Choose between a default rectangle and a billboarded one - if (emitterObject.xYQuad != 0) { - vectors = camera.vectors; - } - else { - vectors = camera.billboardedVectors; - } - - shader.setUniformf("u_emitter", EMITTER_PARTICLE2); - - shader.setUniformf("u_lifeSpan", emitterObject.lifeSpan); - shader.setUniformf("u_timeMiddle", emitterObject.timeMiddle); - shader.setUniformf("u_columns", emitterObject.columns); - shader.setUniformf("u_rows", emitterObject.rows); - shader.setUniformf("u_teamColored", emitterObject.teamColored); - shader.setUniformi("u_unshaded", emitterObject.emitterUsesMdlOrUnshaded != 0 ? 1 : 0); - - final W3xSceneLightManager lightManager = (W3xSceneLightManager) scene.getLightManager(); - final DataTexture unitLightsTexture = lightManager.getUnitLightsTexture(); - - unitLightsTexture.bind(14); - shader.setUniformi("u_lightTexture", 14); - shader.setUniformf("u_lightCount", lightManager.getUnitLightCount()); - shader.setUniformf("u_lightTextureHeight", unitLightsTexture.getHeight()); - - shader.setUniform3fv("u_intervals[0]", intervals[0], 0, 3); - shader.setUniform3fv("u_intervals[1]", intervals[1], 0, 3); - shader.setUniform3fv("u_intervals[2]", intervals[2], 0, 3); - shader.setUniform3fv("u_intervals[3]", intervals[3], 0, 3); - - shader.setUniform4fv("u_colors[0]", colors[0], 0, 4); - shader.setUniform4fv("u_colors[1]", colors[1], 0, 4); - shader.setUniform4fv("u_colors[2]", colors[2], 0, 4); - - shader.setUniform3fv("u_scaling", emitterObject.scaling, 0, 3); - - if (emitterObject.head) { - shader.setUniform3fv("u_vertices[0]", asFloatArray(vectors[0]), 0, 3); - shader.setUniform3fv("u_vertices[1]", asFloatArray(vectors[1]), 0, 3); - shader.setUniform3fv("u_vertices[2]", asFloatArray(vectors[2]), 0, 3); - shader.setUniform3fv("u_vertices[3]", asFloatArray(vectors[3]), 0, 3); - } - - shader.setUniform3fv("u_cameraZ", asFloatArray(camera.billboardedVectors[6]), 0, 3); - } - - public static void bindRibbonEmitterBuffer(final RibbonEmitter emitter, final ClientBuffer buffer) { - Ribbon object = emitter.first; - final ByteBuffer byteView = buffer.byteView; - final FloatBuffer floatView = buffer.floatView; - final RibbonEmitterObject emitterObject = emitter.emitterObject; - final long columns = emitterObject.columns; - final int alive = emitter.alive; - final float chainLengthFactor = 1 / (float) (alive - 1); - int offset = 0; - - while (object.next != null) { - final float[] next = object.next.vertices; - final int byteOffset = offset * BYTES_PER_OBJECT; - final int floatOffset = offset * FLOATS_PER_OBJECT; - final int p0Offset = floatOffset + FLOAT_OFFSET_P0; - final int colorOffset = byteOffset + BYTE_OFFSET_COLOR; - final int leftRightTopOffset = byteOffset + BYTE_OFFSET_LEFT_RIGHT_TOP; - final float left = ((object.slot % columns) + (1 - (offset * chainLengthFactor) - chainLengthFactor)) - / columns; - final float top = object.slot / (float) columns; - final float right = left + chainLengthFactor; - final float[] vertices = object.vertices; - final byte[] color = object.color; - - floatView.put(p0Offset + 0, vertices[0]); - floatView.put(p0Offset + 1, vertices[1]); - floatView.put(p0Offset + 2, vertices[2]); - floatView.put(p0Offset + 3, vertices[3]); - floatView.put(p0Offset + 4, vertices[4]); - floatView.put(p0Offset + 5, vertices[5]); - floatView.put(p0Offset + 6, next[3]); - floatView.put(p0Offset + 7, next[4]); - floatView.put(p0Offset + 8, next[5]); - floatView.put(p0Offset + 9, next[0]); - floatView.put(p0Offset + 10, next[1]); - floatView.put(p0Offset + 11, next[2]); - - byteView.put(colorOffset + 0, color[0]); - byteView.put(colorOffset + 1, color[1]); - byteView.put(colorOffset + 2, color[2]); - byteView.put(colorOffset + 3, color[3]); - - byteView.put(leftRightTopOffset + 0, (byte) (left * 255)); - byteView.put(leftRightTopOffset + 1, (byte) (right * 255)); - byteView.put(leftRightTopOffset + 2, (byte) (top * 255)); - - object = object.next; - offset += 1; - - } - } - - public static void bindRibbonEmitterShader(final RibbonEmitter emitter, final ShaderProgram shader) { - final TextureMapper textureMapper = emitter.instance.textureMapper; - final RibbonEmitterObject emitterObject = emitter.emitterObject; - final Layer layer = emitterObject.layer; - final MdxModel model = emitterObject.model; - final GL20 gl = model.viewer.gl; - final Texture texture = model.getTextures().get(layer.textureId); - - layer.bind(shader); - - Texture mappedTexture = textureMapper.get(texture); - if (mappedTexture == null) { - mappedTexture = texture; - } - model.viewer.webGL.bindTexture(mappedTexture, 0); - - shader.setUniformf("u_emitter", EMITTER_RIBBON); - - shader.setUniformf("u_columns", emitterObject.columns); - shader.setUniformf("u_rows", emitterObject.rows); - } - - public static void bindEventObjectEmitterBuffer( - final EventObjectEmitter emitter, final ClientBuffer buffer) { - final List objects = emitter.objects; - final FloatBuffer floatView = buffer.floatView; - int offset = 0; - - for (final EventObjectSplUbr object : objects) { - final int floatOffset = offset * FLOATS_PER_OBJECT; - final int p0Offset = floatOffset + FLOAT_OFFSET_P0; - final float[] vertices = object.vertices; - - floatView.put(p0Offset + 0, vertices[0]); - floatView.put(p0Offset + 1, vertices[1]); - floatView.put(p0Offset + 2, vertices[2]); - floatView.put(p0Offset + 3, vertices[3]); - floatView.put(p0Offset + 4, vertices[4]); - floatView.put(p0Offset + 5, vertices[5]); - floatView.put(p0Offset + 6, vertices[6]); - floatView.put(p0Offset + 7, vertices[7]); - floatView.put(p0Offset + 8, vertices[8]); - floatView.put(p0Offset + 9, vertices[9]); - floatView.put(p0Offset + 10, vertices[10]); - floatView.put(p0Offset + 11, vertices[11]); - - floatView.put(floatOffset + FLOAT_OFFSET_HEALTH, object.health); - - offset += 1; - } - } - - public static void bindEventObjectSplEmitterShader(final EventObjectSplEmitter emitter, - final ShaderProgram shader) { - final TextureMapper textureMapper = emitter.instance.textureMapper; - final EventObjectEmitterObject emitterObject = emitter.emitterObject; - final float[] intervalTimes = emitterObject.intervalTimes; - final float[][] intervals = emitterObject.intervals; - final float[][] colors = emitterObject.colors; - final MdxModel model = emitterObject.model; - final GL20 gl = model.viewer.gl; - final Texture texture = emitterObject.internalTexture; - - gl.glBlendFunc(emitterObject.blendSrc, emitterObject.blendDst); - - Texture finalTexture = textureMapper.get(texture); - if (finalTexture == null) { - finalTexture = texture; - } - model.viewer.webGL.bindTexture(finalTexture, 0); - - shader.setUniformf("u_lifeSpan", emitterObject.lifeSpan); - shader.setUniformf("u_columns", emitterObject.columns); - shader.setUniformf("rows", emitterObject.rows); - - // 3 because the uniform is shared with UBR, which has 3 values. - vectorTemp[0] = intervalTimes[0]; - vectorTemp[1] = intervalTimes[1]; - vectorTemp[2] = 0; - shader.setUniform3fv("u_intervalTimes", vectorTemp, 0, 3); - - shader.setUniform3fv("u_intervals[0]", intervals[0], 0, 3); - shader.setUniform3fv("u_intervals[1]", intervals[1], 0, 3); - - shader.setUniform3fv("u_colors[0]", colors[0], 0, 3); - shader.setUniform3fv("u_colors[1]", colors[1], 0, 3); - shader.setUniform3fv("u_colors[2]", colors[2], 0, 3); - } - - public static void bindEventObjectUbrEmitterShader(final EventObjectUbrEmitter emitter, - final ShaderProgram shader) { - final TextureMapper textureMapper = emitter.instance.textureMapper; - final EventObjectEmitterObject emitterObject = emitter.emitterObject; - final float[] intervalTimes = emitterObject.intervalTimes; - final float[][] colors = emitterObject.colors; - final MdxModel model = emitterObject.model; - final GL20 gl = model.viewer.gl; - final Texture texture = emitterObject.internalTexture; - - gl.glBlendFunc(emitterObject.blendSrc, emitterObject.blendDst); - - Texture finalTexture = textureMapper.get(texture); - if (finalTexture == null) { - finalTexture = texture; - } - model.viewer.webGL.bindTexture(finalTexture, 0); - - shader.setUniformf("u_lifeSpan", emitterObject.lifeSpan); - shader.setUniformf("u_columns", emitterObject.columns); - shader.setUniformf("rows", emitterObject.rows); - - shader.setUniform3fv("u_intervalTimes", intervalTimes, 0, 3); - - shader.setUniform3fv("u_colors[0]", colors[0], 0, 3); - shader.setUniform3fv("u_colors[1]", colors[1], 0, 3); - shader.setUniform3fv("u_colors[2]", colors[2], 0, 3); - } - - public static void renderEmitter(final MdxEmitter emitter, final ShaderProgram shader) { - int alive = emitter.alive; - final EmitterObject emitterObject = emitter.emitterObject; - final int emitterType = emitterObject.getGeometryEmitterType(); - - if (emitterType == EMITTER_RIBBON) { - alive -= 1; - } - else if (emitterType == EMITTER_SPN) { - return; - } - - if (alive > 0) { - final ModelViewer viewer = emitter.instance.model.viewer; - final ANGLEInstancedArrays instancedArrays = viewer.webGL.instancedArrays; - final ClientBuffer buffer = viewer.buffer; - final GL20 gl = viewer.gl; - final int size = alive * BYTES_PER_OBJECT; - - buffer.reserve(size); - - switch (emitterType) { - case EMITTER_PARTICLE2: - bindParticleEmitter2Buffer((ParticleEmitter2) emitter, buffer); - bindParticleEmitter2Shader((ParticleEmitter2) emitter, shader); - break; - case EMITTER_RIBBON: - bindRibbonEmitterBuffer((RibbonEmitter) emitter, buffer); - bindRibbonEmitterShader((RibbonEmitter) emitter, shader); - break; - case EMITTER_SPLAT: - if (true) { - return; - } - bindEventObjectEmitterBuffer((EventObjectSplEmitter) emitter, buffer); - bindEventObjectSplEmitterShader((EventObjectSplEmitter) emitter, shader); - break; - default: - if (true) { - return; - } - bindEventObjectEmitterBuffer((EventObjectUbrEmitter) emitter, buffer); - bindEventObjectUbrEmitterShader((EventObjectUbrEmitter) emitter, shader); - break; - } - - buffer.bindAndUpdate(size); - - shader.setUniformf("u_emitter", emitterType); - - shader.setVertexAttribute("a_p0", 3, GL20.GL_FLOAT, false, BYTES_PER_OBJECT, BYTE_OFFSET_P0); - shader.setVertexAttribute("a_p1", 3, GL20.GL_FLOAT, false, BYTES_PER_OBJECT, BYTE_OFFSET_P1); - shader.setVertexAttribute("a_p2", 3, GL20.GL_FLOAT, false, BYTES_PER_OBJECT, BYTE_OFFSET_P2); - shader.setVertexAttribute("a_p3", 3, GL20.GL_FLOAT, false, BYTES_PER_OBJECT, BYTE_OFFSET_P3); - shader.setVertexAttribute("a_health", 1, GL20.GL_FLOAT, false, BYTES_PER_OBJECT, BYTE_OFFSET_HEALTH); - shader.setVertexAttribute("a_color", 4, GL20.GL_UNSIGNED_BYTE, true, BYTES_PER_OBJECT, BYTE_OFFSET_COLOR); - shader.setVertexAttribute("a_tail", 1, GL20.GL_UNSIGNED_BYTE, false, BYTES_PER_OBJECT, BYTE_OFFSET_TAIL); - shader.setVertexAttribute("a_leftRightTop", 3, GL20.GL_UNSIGNED_BYTE, false, BYTES_PER_OBJECT, - BYTE_OFFSET_LEFT_RIGHT_TOP); - - instancedArrays.glDrawArraysInstancedANGLE(GL20.GL_TRIANGLES, 0, 6, alive); - } - } - - private static final float[] asFloatArray(final Vector3 vec) { - vectorTemp[0] = vec.x; - vectorTemp[1] = vec.y; - vectorTemp[2] = vec.z; - return vectorTemp; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Geoset.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Geoset.java deleted file mode 100644 index 9e8bdd8e..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Geoset.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.Arrays; - -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.etheller.warsmash.viewer5.gl.ANGLEInstancedArrays; -import com.hiveworkshop.rms.parsers.mdlx.MdlxGeoset; - -public class Geoset { - public MdxModel model; - public int index; - public int positionOffset; - public int normalOffset; - public int uvOffset; - public int skinOffset; - public int faceOffset; - public int vertices; - public int elements; - public GeosetAnimation geosetAnimation; - public Variants variants; - public boolean hasAlphaAnim; - public boolean hasColorAnim; - public boolean hasObjectAnim; - private final int openGLSkinType; - private final int skinStride; - private final int boneCountOffsetBytes; - public final boolean unselectable; - public final MdlxGeoset mdlxGeoset; - - public Geoset(final MdxModel model, final int index, final int positionOffset, final int normalOffset, - final int uvOffset, final int skinOffset, final int faceOffset, final int vertices, final int elements, - final int openGLSkinType, final int skinStride, final int boneCountOffsetBytes, final boolean unselectable, - final MdlxGeoset mdlxGeoset) { - this.model = model; - this.index = index; - this.positionOffset = positionOffset; - this.normalOffset = normalOffset; - this.uvOffset = uvOffset; - this.skinOffset = skinOffset; - this.faceOffset = faceOffset; - this.vertices = vertices; - this.elements = elements; - this.openGLSkinType = openGLSkinType; - this.skinStride = skinStride; - this.boneCountOffsetBytes = boneCountOffsetBytes; - this.unselectable = unselectable; - this.mdlxGeoset = mdlxGeoset; - - for (final GeosetAnimation geosetAnimation : model.getGeosetAnimations()) { - if (geosetAnimation.geosetId == index) { - this.geosetAnimation = geosetAnimation; - } - } - - final Variants variants = new Variants(model.getSequences().size()); - - final GeosetAnimation geosetAnimation = this.geosetAnimation; - boolean hasAlphaAnim = false; - boolean hasColorAnim = false; - - if (geosetAnimation != null) { - for (int i = 0, l = model.getSequences().size(); i < l; i++) { - final boolean alpha = geosetAnimation.isAlphaVariant(i); - final boolean color = geosetAnimation.isColorVariant(i); - - variants.alpha[i] = alpha; - variants.color[i] = color; - variants.object[i] = alpha || color; - - hasAlphaAnim = hasAlphaAnim || alpha; - hasColorAnim = hasColorAnim || color; - } - } - else { - for (int i = 0, l = model.getSequences().size(); i < l; i++) { - variants.alpha[i] = false; - variants.color[i] = false; - variants.object[i] = false; - } - } - - this.variants = variants; - this.hasAlphaAnim = hasAlphaAnim; - this.hasColorAnim = hasColorAnim; - this.hasObjectAnim = hasAlphaAnim || hasColorAnim; - } - - public int getAlpha(final float[] out, final int sequence, final int frame, final int counter) { - if (this.geosetAnimation != null) { - return this.geosetAnimation.getAlpha(out, sequence, frame, counter); - } - - out[0] = 1; - return -1; - } - - public int getColor(final float[] out, final int sequence, final int frame, final int counter) { - if (this.geosetAnimation != null) { - return this.geosetAnimation.getAlpha(out, sequence, frame, counter); - } - - Arrays.fill(out, 1); - return -1; - } - - public void bind(final ShaderProgram shader, final int coordId) { - // TODO use indices instead of strings for attributes - shader.setVertexAttribute("a_position", 3, GL20.GL_FLOAT, false, 0, this.positionOffset); - shader.setVertexAttribute("a_normal", 3, GL20.GL_FLOAT, false, 0, this.normalOffset); - shader.setVertexAttribute("a_uv", 2, GL20.GL_FLOAT, false, 0, this.uvOffset + (coordId * this.vertices * 8)); - shader.setVertexAttribute("a_bones", 4, this.openGLSkinType, false, this.skinStride, this.skinOffset); - shader.setVertexAttribute("a_boneNumber", 1, this.openGLSkinType, false, this.skinStride, - this.skinOffset + this.boneCountOffsetBytes); - } - - public void bindExtended(final ShaderProgram shader, final int coordId) { - // TODO use indices instead of strings for attributes - shader.setVertexAttribute("a_position", 3, GL20.GL_FLOAT, false, 0, this.positionOffset); - shader.setVertexAttribute("a_normal", 3, GL20.GL_FLOAT, false, 0, this.normalOffset); - shader.setVertexAttribute("a_uv", 2, GL20.GL_FLOAT, false, 0, this.uvOffset + (coordId * this.vertices * 8)); - shader.setVertexAttribute("a_bones", 4, this.openGLSkinType, false, this.skinStride, this.skinOffset); - shader.setVertexAttribute("a_extendedBones", 4, this.openGLSkinType, false, this.skinStride, - this.skinOffset + (this.boneCountOffsetBytes / 2)); - shader.setVertexAttribute("a_boneNumber", 1, this.openGLSkinType, false, this.skinStride, - this.skinOffset + this.boneCountOffsetBytes); - } - - public void render() { - final GL20 gl = this.model.viewer.gl; - - gl.glDrawElements(GL20.GL_TRIANGLES, this.elements, GL20.GL_UNSIGNED_SHORT, this.faceOffset); - } - - public void bindSimple(final ShaderProgram shader) { - shader.setVertexAttribute("a_position", 3, GL20.GL_FLOAT, false, 0, this.positionOffset); - shader.setVertexAttribute("a_uv", 2, GL20.GL_FLOAT, false, 0, this.uvOffset); - } - - public void renderSimple(final int instances) { - final ANGLEInstancedArrays instancedArrays = this.model.viewer.webGL.instancedArrays; - instancedArrays.glDrawElementsInstancedANGLE(GL20.GL_TRIANGLES, this.elements, GL20.GL_UNSIGNED_SHORT, - this.faceOffset, instances); - } - - public void bindHd(final ShaderProgram shader, final int coordId) { - shader.setVertexAttribute("a_position", 3, GL20.GL_FLOAT, false, 0, this.positionOffset); - shader.setVertexAttribute("a_normal", 3, GL20.GL_FLOAT, false, 0, this.positionOffset); - shader.setVertexAttribute("a_uv", 2, GL20.GL_FLOAT, false, 0, this.uvOffset + (coordId * this.vertices * 8)); - shader.setVertexAttribute("a_bones", 4, GL20.GL_UNSIGNED_BYTE, false, 8, this.skinOffset); - shader.setVertexAttribute("a_weights", 4, GL20.GL_UNSIGNED_BYTE, false, 8, this.skinOffset + 4); - } - - private static final class Variants { - private final boolean[] alpha; - private final boolean[] color; - private final boolean[] object; - - public Variants(final int size) { - this.alpha = new boolean[size]; - this.color = new boolean[size]; - this.object = new boolean[size]; - } - - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GeosetAnimation.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GeosetAnimation.java deleted file mode 100644 index 4e8a2566..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/GeosetAnimation.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.hiveworkshop.rms.parsers.mdlx.AnimationMap; -import com.hiveworkshop.rms.parsers.mdlx.MdlxGeosetAnimation; - -public class GeosetAnimation extends AnimatedObject { - - private final float alpha; - private final float[] color; - public final int geosetId; - - public GeosetAnimation(final MdxModel model, final MdlxGeosetAnimation geosetAnimation) { - super(model, geosetAnimation); - - final float[] color = geosetAnimation.getColor(); - - this.alpha = geosetAnimation.getAlpha(); - this.color = new float[] { color[2], color[1], color[0] }; // Stored as RGB, but animated colors are stored as - // BGR, so sizzle. - this.geosetId = geosetAnimation.getGeosetId(); - - this.addVariants(AnimationMap.KGAO.getWar3id(), "alpha"); - this.addVariants(AnimationMap.KGAC.getWar3id(), "color"); - } - - public int getAlpha(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KGAO.getWar3id(), sequence, frame, counter, this.alpha); - } - - public int getColor(final float[] out, final int sequence, final int frame, final int counter) { - return this.getVectorValue(out, AnimationMap.KGAC.getWar3id(), sequence, frame, counter, this.color); - } - - public boolean isAlphaVariant(final int sequence) { - return this.isVariant(AnimationMap.KGAO.getWar3id(), sequence); - } - - public boolean isColorVariant(final int sequence) { - return this.isVariant(AnimationMap.KGAC.getWar3id(), sequence); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Helper.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Helper.java deleted file mode 100644 index ba0133b2..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Helper.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.hiveworkshop.rms.parsers.mdlx.MdlxGenericObject; - -/** - * An MDX helper. - */ -public class Helper extends GenericObject { - public Helper(final MdxModel model, final MdlxGenericObject object, final int index) { - super(model, object, index); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Layer.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Layer.java deleted file mode 100644 index 72dfbc81..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Layer.java +++ /dev/null @@ -1,157 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.hiveworkshop.rms.parsers.mdlx.AnimationMap; -import com.hiveworkshop.rms.parsers.mdlx.MdlxLayer; - -/** - * An MDX layer. - */ -public class Layer extends AnimatedObject { - public int index; - public int priorityPlane; - public int filterMode; - public int textureId; - public int coordId; - public float alpha; - public int unshaded; - public int sphereEnvironmentMap; - public int twoSided; - public int unfogged; - public int noDepthTest; - public int noDepthSet; - public boolean depthMaskValue; - public int blendSrc; - public int blendDst; - public boolean blended; - public TextureAnimation textureAnimation; - - public Layer(final MdxModel model, final MdlxLayer layer, final int layerId, final int priorityPlane) { - super(model, layer); - - final MdlxLayer.FilterMode filterMode = layer.getFilterMode(); - final int textureAnimationId = layer.getTextureAnimationId(); - final GL20 gl = model.viewer.gl; - - this.index = layerId; - this.priorityPlane = priorityPlane; - this.filterMode = filterMode.ordinal(); - this.textureId = layer.getTextureId(); - this.coordId = (int) layer.getCoordId(); - this.alpha = layer.getAlpha(); - - final int flags = layer.getFlags(); - - this.unshaded = flags & 0x1; - this.sphereEnvironmentMap = flags & 0x2; - this.twoSided = flags & 0x10; - this.unfogged = flags & 0x20; - this.noDepthTest = flags & 0x40; - this.noDepthSet = flags & 0x80; - - this.depthMaskValue = ((filterMode == MdlxLayer.FilterMode.NONE) - || (filterMode == MdlxLayer.FilterMode.TRANSPARENT)); - - this.blendSrc = 0; - this.blendDst = 0; - this.blended = (filterMode.ordinal() > 1); - - if (this.blended) { - final int[] result = FilterMode.layerFilterMode(filterMode); - this.blendSrc = result[0]; - this.blendDst = result[1]; - } - - if (textureAnimationId != -1) { - final TextureAnimation textureAnimation = model.getTextureAnimations().get(textureAnimationId); - - if (textureAnimation != null) { - this.textureAnimation = textureAnimation; - } - } - - this.addVariants(AnimationMap.KMTA.getWar3id(), "alpha"); - this.addVariants(AnimationMap.KMTF.getWar3id(), "textureId"); - } - - public void bind(final ShaderProgram shader) { - final GL20 gl = this.model.viewer.gl; - - // gl.uniform1f(shader.uniforms.u_unshaded, this.unshaded); - shader.setUniformf("u_filterMode", this.filterMode); - - if (this.blended) { - gl.glEnable(GL20.GL_BLEND); - gl.glBlendFunc(this.blendSrc, this.blendDst); - } - else { - gl.glDisable(GL20.GL_BLEND); - } - - if (this.twoSided != 0) { - gl.glDisable(GL20.GL_CULL_FACE); - } - else { - gl.glEnable(GL20.GL_CULL_FACE); - } - - if (this.noDepthTest != 0) { - gl.glDisable(GL20.GL_DEPTH_TEST); - } - else { - gl.glEnable(GL20.GL_DEPTH_TEST); - } - - if (this.noDepthSet != 0) { - gl.glDepthMask(false); - } - else { - gl.glDepthMask(this.depthMaskValue); - } - } - - public void bindBlended(final ShaderProgram shader) { - final GL20 gl = this.model.viewer.gl; - - // gl.uniform1f(shader.uniforms.u_unshaded, this.unshaded); - shader.setUniformf("u_filterMode", this.filterMode); - - gl.glEnable(GL20.GL_BLEND); - if ((this.blendSrc == 0) && (this.blendDst == 0)) { - gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); - } - else { - gl.glBlendFunc(this.blendSrc, this.blendDst); - } - - if (this.twoSided != 0) { - gl.glDisable(GL20.GL_CULL_FACE); - } - else { - gl.glEnable(GL20.GL_CULL_FACE); - } - - if (this.noDepthTest != 0) { - gl.glDisable(GL20.GL_DEPTH_TEST); - } - else { - gl.glEnable(GL20.GL_DEPTH_TEST); - } - - if (this.noDepthSet != 0) { - gl.glDepthMask(false); - } - else { - gl.glDepthMask(this.depthMaskValue); - } - } - - public int getAlpha(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KMTA.getWar3id(), sequence, frame, counter, this.alpha); - } - - public int getTextureId(final long[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KMTF.getWar3id(), sequence, frame, counter, this.textureId); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Light.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Light.java deleted file mode 100644 index 2aaeef88..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Light.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.hiveworkshop.rms.parsers.mdlx.AnimationMap; -import com.hiveworkshop.rms.parsers.mdlx.MdlxLight; - -public class Light extends GenericObject { - - private final Type type; - private final float[] attenuation; - private final float[] color; - private final float intensity; - private final float[] ambientColor; - private final float ambientIntensity; - - public Light(final MdxModel model, final MdlxLight light, final int index) { - super(model, light, index); - - switch (light.getType()) { - case OMNIDIRECTIONAL: - this.type = Type.OMNIDIRECTIONAL; - break; - case DIRECTIONAL: - this.type = Type.DIRECTIONAL; - break; - case AMBIENT: - this.type = Type.AMBIENT; - break; - default: - this.type = Type.DIRECTIONAL; - break; - } - this.attenuation = light.getAttenuation(); - this.color = light.getColor(); - this.intensity = light.getIntensity(); - this.ambientColor = light.getAmbientColor(); - this.ambientIntensity = light.getAmbientIntensity(); - } - - public Type getType() { - return this.type; - } - - public int getAttenuationStart(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KLAS.getWar3id(), sequence, frame, counter, this.attenuation[0]); - } - - public int getAttenuationEnd(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KLAE.getWar3id(), sequence, frame, counter, this.attenuation[1]); - } - - public int getIntensity(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KLAI.getWar3id(), sequence, frame, counter, this.intensity); - } - - public int getColor(final float[] out, final int sequence, final int frame, final int counter) { - return this.getVectorValue(out, AnimationMap.KLAC.getWar3id(), sequence, frame, counter, this.color); - } - - public int getAmbientIntensity(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KLBI.getWar3id(), sequence, frame, counter, this.ambientIntensity); - } - - public int getAmbientColor(final float[] out, final int sequence, final int frame, final int counter) { - return this.getVectorValue(out, AnimationMap.KLBC.getWar3id(), sequence, frame, counter, this.ambientColor); - } - - @Override - public int getVisibility(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KLAV.getWar3id(), sequence, frame, counter, 1); - } - - public static enum Type { - // Omnidirectional light used for in-game sun - OMNIDIRECTIONAL, - // Directional light used for torches in the game world, and similar objects - // that "glow" - DIRECTIONAL, - // Directional ambient light used for torches in the game world, and similar - // objects that "glow" - AMBIENT; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/LightInstance.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/LightInstance.java deleted file mode 100644 index 4e5a26f7..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/LightInstance.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.nio.FloatBuffer; - -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.SceneLightInstance; -import com.etheller.warsmash.viewer5.UpdatableObject; - -public class LightInstance implements UpdatableObject, SceneLightInstance { - private static final Matrix4 matrix4Heap = new Matrix4(); - private static final Vector3 vector3Heap = new Vector3(); - private static final float[] vectorHeap = new float[3]; - private static final float[] scalarHeap = new float[1]; - protected final MdxNode node; - protected final Light light; - private boolean visible; - private boolean loadedInScene; - private final MdxComplexInstance instance; - - public LightInstance(final MdxComplexInstance instance, final Light light) { - this.instance = instance; - this.node = instance.nodes[light.index]; - this.light = light; - } - - public void bind(final int offset, final FloatBuffer floatBuffer) { - final int sequence = this.instance.sequence; - final int frame = this.instance.frame; - final int counter = this.instance.counter; - this.light.getAttenuationStart(scalarHeap, sequence, frame, counter); - final float attenuationStart = scalarHeap[0]; - this.light.getAttenuationEnd(scalarHeap, sequence, frame, counter); - final float attenuationEnd = scalarHeap[0]; - this.light.getIntensity(scalarHeap, sequence, frame, counter); - final float intensity = scalarHeap[0]; - this.light.getColor(vectorHeap, sequence, frame, counter); - final float colorRed = vectorHeap[0]; - final float colorGreen = vectorHeap[1]; - final float colorBlue = vectorHeap[2]; - this.light.getAmbientIntensity(scalarHeap, sequence, frame, counter); - final float ambientIntensity = scalarHeap[0]; - this.light.getAmbientColor(vectorHeap, sequence, frame, counter); - final float ambientColorRed = vectorHeap[0]; - final float ambientColorGreen = vectorHeap[1]; - final float ambientColorBlue = vectorHeap[2]; - switch (this.light.getType()) { - case AMBIENT: - case OMNIDIRECTIONAL: - floatBuffer.put(offset, this.node.worldLocation.x); - floatBuffer.put(offset + 1, this.node.worldLocation.y); - floatBuffer.put(offset + 2, this.node.worldLocation.z); - break; - case DIRECTIONAL: - vector3Heap.set(0, 0, 1); - this.node.localRotation.transform(vector3Heap); - vector3Heap.nor(); - floatBuffer.put(offset, vector3Heap.x); - floatBuffer.put(offset + 1, vector3Heap.y); - floatBuffer.put(offset + 2, vector3Heap.z); - break; - } - // I use some padding to make the memory structure of the light be a 4x4 float - // grid, when somebody who actually has experience with this stuff comes along - // to change this to something smart, maybe they'll remove the padding if it's - // not necessary. I'm basing how I implement this on how Ghostwolf did - // BoneTexture - floatBuffer.put(offset + 3, this.instance.worldLocation.z); - floatBuffer.put(offset + 4, this.light.getType().ordinal()); - floatBuffer.put(offset + 5, attenuationStart); - floatBuffer.put(offset + 6, attenuationEnd); - floatBuffer.put(offset + 7, 0); - floatBuffer.put(offset + 8, colorRed); - floatBuffer.put(offset + 9, colorGreen); - floatBuffer.put(offset + 10, colorBlue); - floatBuffer.put(offset + 11, intensity); - floatBuffer.put(offset + 12, ambientColorRed); - floatBuffer.put(offset + 13, ambientColorGreen); - floatBuffer.put(offset + 14, ambientColorBlue); - floatBuffer.put(offset + 15, ambientIntensity); - } - - @Override - public void update(final float dt, final boolean visible) { - } - - public void update(final Scene scene) { - this.light.getVisibility(scalarHeap, this.instance.sequence, this.instance.frame, this.instance.counter); - this.visible = scalarHeap[0] > 0; - updateVisibility(scene, this.visible); - } - - public void remove(final Scene scene) { - updateVisibility(scene, false); - } - - private void updateVisibility(final Scene scene, final boolean visible) { - if (scene != null) { - if (this.loadedInScene != visible) { - if (visible) { - scene.addLight(this); - } - else { - scene.removeLight(this); - } - this.loadedInScene = visible; - } - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Material.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Material.java deleted file mode 100644 index a07ca084..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Material.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.List; - -public class Material { - public final MdxModel model; - public final String shader; - public final List layers; - - public Material(final MdxModel model, final String shader, final List layers) { - this.model = model; - this.shader = shader; - this.layers = layers; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxComplexInstance.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxComplexInstance.java deleted file mode 100644 index 460b9819..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxComplexInstance.java +++ /dev/null @@ -1,939 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Quaternion; -import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.math.collision.Ray; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.Bounds; -import com.etheller.warsmash.viewer5.GenericNode; -import com.etheller.warsmash.viewer5.ModelInstance; -import com.etheller.warsmash.viewer5.Node; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.RenderBatch; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.SkeletalNode; -import com.etheller.warsmash.viewer5.Texture; -import com.etheller.warsmash.viewer5.TextureMapper; -import com.etheller.warsmash.viewer5.UpdatableObject; -import com.etheller.warsmash.viewer5.gl.DataTexture; -import com.etheller.warsmash.viewer5.handlers.w3x.DynamicShadowManager; -import com.hiveworkshop.rms.parsers.mdlx.MdlxGeoset; - -public class MdxComplexInstance extends ModelInstance { - private static final float[] visibilityHeap = new float[1]; - private static final float[] translationHeap = new float[3]; - private static final float[] rotationHeap = new float[4]; - private static final float[] scaleHeap = new float[3]; - private static final float[] colorHeap = new float[3]; - private static final float[] alphaHeap = new float[1]; - private static final long[] textureIdHeap = new long[1]; - private static final Vector3 intersectionHeap = new Vector3(); - - public List lights = new ArrayList<>(); - public List attachments = new ArrayList<>(); - public List particleEmitters = new ArrayList<>(); - public List particleEmitters2 = new ArrayList<>(); - public List ribbonEmitters = new ArrayList<>(); - public List> eventObjectEmitters = new ArrayList<>(); - public MdxNode[] nodes; - public SkeletalNode[] sortedNodes; - public int frame = 0; - public float floatingFrame = 0; - // Global sequences - public int counter = 0; - public int sequence = -1; - public SequenceLoopMode sequenceLoopMode = SequenceLoopMode.NEVER_LOOP; - public boolean sequenceEnded = false; - public float[] vertexColor = { 1, 1, 1, 1 }; - // Particles do not spawn when the sequence is -1, or when the sequence finished - // and it's not repeating - public boolean allowParticleSpawn = false; - // If forced is true, everything will update regardless of variancy. - // Any later non-forced update can then use variancy to skip updating things. - // It is set to true every time the sequence is set with setSequence(). - public boolean forced = true; - public float[][] geosetColors; - public float[] layerAlphas; - public int[] layerTextures; - public float[][] uvAnims; - public Matrix4[] worldMatrices; - public FloatBuffer worldMatricesCopyHeap; - public DataTexture boneTexture; - public Texture[] replaceableTextures = new Texture[WarsmashConstants.REPLACEABLE_TEXTURE_LIMIT]; - private float animationSpeed = 1.0f; - private float blendTime; - private float blendTimeRemaining; - public boolean additiveOverrideMeshMode = false; - - public MdxComplexInstance(final MdxModel model) { - super(model); - } - - @Override - public void load() { - final MdxModel model = (MdxModel) this.model; - - this.geosetColors = new float[model.geosets.size()][]; - for (int i = 0, l = model.geosets.size(); i < l; i++) { - this.geosetColors[i] = new float[4]; - } - - this.layerAlphas = new float[model.layers.size()]; - this.layerTextures = new int[model.layers.size()]; - this.uvAnims = new float[model.layers.size()][]; - for (int i = 0, l = model.layers.size(); i < l; i++) { - this.layerAlphas[i] = 0; - this.layerTextures[i] = 0; - this.uvAnims[i] = new float[5]; - } - - // Create the needed amount of shared nodes. - final Object[] sharedNodeData = Node.createSkeletalNodes(model.genericObjects.size(), - MdxNodeDescriptor.INSTANCE); - final List nodes = (List) sharedNodeData[0]; - int nodeIndex = 0; - this.nodes = nodes.toArray(new MdxNode[nodes.size()]); - - // A shared typed array for all world matrices of the internal nodes. - this.worldMatrices = ((List) sharedNodeData[1]).toArray(new Matrix4[0]); - this.worldMatricesCopyHeap = ByteBuffer.allocateDirect(16 * this.worldMatrices.length * 4) - .order(ByteOrder.nativeOrder()).asFloatBuffer(); - - // And now initialize all of the nodes and objects - for (final Bone bone : model.bones) { - this.initNode(this.nodes, this.nodes[nodeIndex++], bone); - } - - for (final Light light : model.lights) { - final LightInstance lightInstance = new LightInstance(this, light); - this.lights.add(lightInstance); - this.initNode(this.nodes, this.nodes[nodeIndex++], light, lightInstance); - } - - for (final Helper helper : model.helpers) { - this.initNode(this.nodes, this.nodes[nodeIndex++], helper); - } - - for (final Attachment attachment : model.attachments) { - AttachmentInstance attachmentInstance = null; - - // Attachments may have game models attached to them, such as Undead and - // Nightelf building animations. - if (attachment.internalModel != null) { - attachmentInstance = new AttachmentInstance(this, attachment); - - this.attachments.add(attachmentInstance); - } - - this.initNode(this.nodes, this.nodes[nodeIndex++], attachment, attachmentInstance); - } - - for (final ParticleEmitterObject emitterObject : model.particleEmitters) { - final ParticleEmitter emitter = new ParticleEmitter(this, emitterObject); - - this.particleEmitters.add(emitter); - - this.initNode(this.nodes, this.nodes[nodeIndex++], emitterObject, emitter); - } - - for (final ParticleEmitter2Object emitterObject : model.particleEmitters2) { - final ParticleEmitter2 emitter = new ParticleEmitter2(this, emitterObject); - - this.particleEmitters2.add(emitter); - - this.initNode(this.nodes, this.nodes[nodeIndex++], emitterObject, emitter); - } - - for (final RibbonEmitterObject emitterObject : model.ribbonEmitters) { - final RibbonEmitter emitter = new RibbonEmitter(this, emitterObject); - - this.ribbonEmitters.add(emitter); - - this.initNode(this.nodes, this.nodes[nodeIndex++], emitterObject, emitter); - } - - for (final EventObjectEmitterObject emitterObject : model.eventObjects) { - final String type = emitterObject.type; - EventObjectEmitter emitter; - - if ("SPN".equals(type)) { - emitter = new EventObjectSpnEmitter(this, emitterObject); - } - else if ("SPL".equals(type)) { - emitter = new EventObjectSplEmitter(this, emitterObject); - } - else if ("UBR".equals(type)) { - emitter = new EventObjectUbrEmitter(this, emitterObject); - } - else { - emitter = new EventObjectSndEmitter(this, emitterObject); - } - - this.eventObjectEmitters.add(emitter); - - this.initNode(this.nodes, this.nodes[nodeIndex++], emitterObject, emitter); - } - - for (final CollisionShape collisionShape : model.collisionShapes) { - this.initNode(this.nodes, this.nodes[nodeIndex++], collisionShape); - } - - // Save a sorted array of all of the nodes, such that every child node comes - // after its parent. - // This allows for flat iteration when updating. - final List hierarchy = model.hierarchy; - - this.sortedNodes = new SkeletalNode[nodes.size()]; - for (int i = 0, l = nodes.size(); i < l; i++) { - this.sortedNodes[i] = this.nodes[hierarchy.get(i)]; - } - - // If the sequence was changed before the model was loaded, reset it now that - // the model loaded. - this.setSequence(this.sequence); - - if (model.bones.size() != 0) { - this.boneTexture = new DataTexture(model.viewer.gl, 4, model.bones.size() * 4, 1); - } - } - - /* - * Clear all of the emitted objects that belong to this instance. - */ - @Override - public void clearEmittedObjects() { - for (final ParticleEmitter emitter : this.particleEmitters) { - emitter.clear(); - } - - for (final ParticleEmitter2 emitter : this.particleEmitters2) { - emitter.clear(); - } - - for (final RibbonEmitter emitter : this.ribbonEmitters) { - emitter.clear(); - } - - for (final EventObjectEmitter emitter : this.eventObjectEmitters) { - emitter.clear(); - } - } - - private void initNode(final MdxNode[] nodes, final SkeletalNode node, final GenericObject genericObject) { - initNode(nodes, node, genericObject, null); - } - - /** - * Initialize a skeletal node. - */ - private void initNode(final MdxNode[] nodes, final SkeletalNode node, final GenericObject genericObject, - final UpdatableObject object) { - node.pivot.set(genericObject.pivot); - - if (genericObject.parentId == -1) { - node.parent = this; - } - else { - node.parent = nodes[genericObject.parentId]; - } - - /// TODO: single-axis billboarding - if (genericObject.billboarded != 0) { - node.billboarded = true; - } - else if (genericObject.billboardedX != 0) { - node.billboardedX = true; - } - else if (genericObject.billboardedY != 0) { - node.billboardedY = true; - } - else if (genericObject.billboardedZ != 0) { - node.billboardedZ = true; - } - - if (object != null) { - node.object = object; - } - - } - - /* - * Overriden to hide also attachment models. - */ - @Override - public void hide() { - super.hide(); - - for (final AttachmentInstance attachment : this.attachments) { - attachment.internalInstance.hide(); - } - } - - /** - * Updates all of this instance internal nodes and objects. Nodes that are - * determined to not be visible will not be updated, nor will any of their - * children down the hierarchy. - */ - public void updateNodes(final float dt, final boolean forced) { - if (!this.model.ok) { - return; - } - final int sequence = this.sequence; - final int frame = this.frame; - final int counter = this.counter; - final SkeletalNode[] sortedNodes = this.sortedNodes; - final MdxModel model = (MdxModel) this.model; - final List sortedGenericObjects = model.sortedGenericObjects; - final Scene scene = this.scene; - - // Update the nodes - for (int i = 0, l = sortedNodes.length; i < l; i++) { - final GenericObject genericObject = sortedGenericObjects.get(i); - final SkeletalNode node = sortedNodes[i]; - final GenericNode parent = node.parent; - - genericObject.getVisibility(visibilityHeap, sequence, frame, counter); - - final boolean objectVisible = visibilityHeap[0] > 0; - final boolean nodeVisible = forced || (parent.visible && objectVisible); - - node.visible = nodeVisible; - - // Every node only needs to be updated if this is a forced update, or if both - // the parent node and the generic object corresponding to this node are - // visible. - // Incoming messy code for optimizations! - if (nodeVisible) { - boolean wasDirty = false; - final GenericObject.Variants variants = genericObject.variants; - final Vector3 localLocation = node.localLocation; - final Quaternion localRotation = node.localRotation; - final Vector3 localScale = node.localScale; - - // Only update the local node data if there is a need to - if (forced || variants.generic[sequence]) { - wasDirty = true; - - // Translation - if (forced || variants.translation[sequence]) { - genericObject.getTranslation(translationHeap, sequence, frame, counter); - - localLocation.x = translationHeap[0]; - localLocation.y = translationHeap[1]; - localLocation.z = translationHeap[2]; - } - - // Rotation - if (forced || variants.rotation[sequence]) { - genericObject.getRotation(rotationHeap, sequence, frame, counter); - - localRotation.x = rotationHeap[0]; - localRotation.y = rotationHeap[1]; - localRotation.z = rotationHeap[2]; - localRotation.w = rotationHeap[3]; - } - - // Scale - if (forced || variants.scale[sequence]) { - genericObject.getScale(scaleHeap, sequence, frame, counter); - - localScale.x = scaleHeap[0]; - localScale.y = scaleHeap[1]; - localScale.z = scaleHeap[2]; - } - } - - final boolean wasReallyDirty = forced || wasDirty || parent.wasDirty || genericObject.anyBillboarding; - - node.wasDirty = wasReallyDirty; - - // If this is a forced update, or this node's local data was updated, or the - // parent node was updated, do a full world update. - if (wasReallyDirty) { - node.recalculateTransformation(scene, this.blendTimeRemaining / this.blendTime); - } - - // If there is an instance object associated with this node, and the node is - // visible (which might not be the case for a forced update!), update the - // object. - // This includes attachments and emitters. - final UpdatableObject object = node.object; - - if (object != null) { - object.update(dt, objectVisible); - } - - // Update all of the node's non-skeletal children, which will update their - // children, and so on. - node.updateChildren(dt, scene); - } - } - } - - /** - * Update the batch data. - */ - public void updateBatches(final boolean forced) { - final int sequence = this.sequence; - final int frame = this.frame; - final int counter = this.counter; - final MdxModel model = (MdxModel) this.model; - if (!model.ok) { - return; - } - final List geosets = model.geosets; - final List layers = model.layers; - final float[][] geosetColors = this.geosetColors; - final float[] layerAlphas = this.layerAlphas; - final int[] layerTextures = this.layerTextures; - final float[][] uvAnims = this.uvAnims; - - // Geoset - for (int i = 0, l = geosets.size(); i < l; i++) { - final Geoset geoset = geosets.get(i); - final GeosetAnimation geosetAnimation = geoset.geosetAnimation; - final float[] geosetColor = geosetColors[i]; - - if (geosetAnimation != null) { - // Color - if (forced || (geosetAnimation.variants.get("color")[sequence] != 0)) { - geosetAnimation.getColor(colorHeap, sequence, frame, counter); - - geosetColor[0] = colorHeap[0]; - geosetColor[1] = colorHeap[1]; - geosetColor[2] = colorHeap[2]; - } - - // Alpha - if (forced || (geosetAnimation.variants.get("alpha")[sequence] != 0)) { - geosetAnimation.getAlpha(alphaHeap, sequence, frame, counter); - - geosetColor[3] = alphaHeap[0]; - } - } - else if (forced) { - geosetColor[0] = 1; - geosetColor[1] = 1; - geosetColor[2] = 1; - geosetColor[3] = 1; - } - } - - // Layers - for (int i = 0, l = layers.size(); i < l; i++) { - final Layer layer = layers.get(i); - final TextureAnimation textureAnimation = layer.textureAnimation; - final float[] uvAnim = uvAnims[i]; - - // Alpha - if (forced || (layer.variants.get("alpha")[sequence] != 0)) { - layer.getAlpha(alphaHeap, sequence, frame, counter); - - layerAlphas[i] = alphaHeap[0]; - } - - // Sprite animation - if (forced || (layer.variants.get("textureId")[sequence] != 0)) { - layer.getTextureId(textureIdHeap, sequence, frame, counter); - - layerTextures[i] = (int) textureIdHeap[0]; - } - - if (textureAnimation != null) { - // UV translation animation - if (forced || (textureAnimation.variants.get("translation")[sequence] != 0)) { - textureAnimation.getTranslation(translationHeap, sequence, frame, counter); - - uvAnim[0] = translationHeap[0]; - uvAnim[1] = translationHeap[1]; - } - - // UV rotation animation - if (forced || (textureAnimation.variants.get("rotation")[sequence] != 0)) { - textureAnimation.getRotation(rotationHeap, sequence, frame, counter); - - uvAnim[2] = rotationHeap[2]; - uvAnim[3] = rotationHeap[3]; - } - - // UV scale animation - if (forced || (textureAnimation.variants.get("scale")[sequence] != 0)) { - textureAnimation.getScale(scaleHeap, sequence, frame, counter); - - uvAnim[4] = scaleHeap[0]; - } - } - else if (forced) { - uvAnim[0] = 0; - uvAnim[1] = 0; - uvAnim[2] = 0; - uvAnim[3] = 1; - uvAnim[4] = 1; - } - } - } - - public void updateBoneTexture() { - if (this.boneTexture != null) { - this.worldMatricesCopyHeap.clear(); - for (int i = 0, l = this.worldMatrices.length; i < l; i++) { - final Matrix4 worldMatrix = this.worldMatrices[i]; - this.worldMatricesCopyHeap.put((i * 16) + 0, worldMatrix.val[Matrix4.M00]); - this.worldMatricesCopyHeap.put((i * 16) + 1, worldMatrix.val[Matrix4.M10]); - this.worldMatricesCopyHeap.put((i * 16) + 2, worldMatrix.val[Matrix4.M20]); - this.worldMatricesCopyHeap.put((i * 16) + 3, worldMatrix.val[Matrix4.M30]); - this.worldMatricesCopyHeap.put((i * 16) + 4, worldMatrix.val[Matrix4.M01]); - this.worldMatricesCopyHeap.put((i * 16) + 5, worldMatrix.val[Matrix4.M11]); - this.worldMatricesCopyHeap.put((i * 16) + 6, worldMatrix.val[Matrix4.M21]); - this.worldMatricesCopyHeap.put((i * 16) + 7, worldMatrix.val[Matrix4.M31]); - this.worldMatricesCopyHeap.put((i * 16) + 8, worldMatrix.val[Matrix4.M02]); - this.worldMatricesCopyHeap.put((i * 16) + 9, worldMatrix.val[Matrix4.M12]); - this.worldMatricesCopyHeap.put((i * 16) + 10, worldMatrix.val[Matrix4.M22]); - this.worldMatricesCopyHeap.put((i * 16) + 11, worldMatrix.val[Matrix4.M32]); - this.worldMatricesCopyHeap.put((i * 16) + 12, worldMatrix.val[Matrix4.M03]); - this.worldMatricesCopyHeap.put((i * 16) + 13, worldMatrix.val[Matrix4.M13]); - this.worldMatricesCopyHeap.put((i * 16) + 14, worldMatrix.val[Matrix4.M23]); - this.worldMatricesCopyHeap.put((i * 16) + 15, worldMatrix.val[Matrix4.M33]); - } - this.boneTexture.bindAndUpdate(this.worldMatricesCopyHeap); - } - } - - @Override - public void renderOpaque(final Matrix4 mvp) { - final MdxModel model = (MdxModel) this.model; - - if (!this.additiveOverrideMeshMode) { - for (final GenericGroup group : model.opaqueGroups) { - group.render(this, mvp); - } - } - - final int glGetError = Gdx.gl.glGetError(); - if ((glGetError != GL20.GL_NO_ERROR) && WarsmashConstants.ENABLE_DEBUG) { - throw new IllegalStateException("GL ERROR: " + glGetError + " ON " + model.name + " (Opaque)"); - } - } - - @Override - public void renderTranslucent() { - if (DynamicShadowManager.IS_SHADOW_MAPPING) { - return; - } - final MdxModel model = (MdxModel) this.model; - - for (final GenericGroup group : model.opaqueGroups) { - group.render(this, this.scene.camera.viewProjectionMatrix); - } - for (final GenericGroup group : model.translucentGroups) { - group.render(this, this.scene.camera.viewProjectionMatrix); - - final int glGetError = Gdx.gl.glGetError(); - if ((glGetError != GL20.GL_NO_ERROR) && WarsmashConstants.ENABLE_DEBUG) { - throw new IllegalStateException("GL ERROR: " + glGetError + " ON " + model.name + " (Translucent)"); - } - } - } - - @Override - public void updateAnimations(final float dt) { - final MdxModel model = (MdxModel) this.model; - final int sequenceId = this.sequence; - - if ((sequenceId != -1) && (model.sequences.size() != 0)) { - final Sequence sequence = model.sequences.get(sequenceId); - final long[] interval = sequence.getInterval(); - final float frameTime = (dt * 1000 * this.animationSpeed); - - final int lastIntegerFrame = this.frame; - this.floatingFrame += frameTime; - this.blendTimeRemaining -= frameTime; - this.frame = (int) this.floatingFrame; - final int integerFrameTime = this.frame - lastIntegerFrame; - this.counter += integerFrameTime; - this.allowParticleSpawn = true; - if (this.additiveOverrideMeshMode) { - this.vertexColor[3] = Math.max(0, - this.vertexColor[3] - (integerFrameTime / (float) (interval[1] - interval[0]))); - } - - final long animEnd = interval[1] - 1; - if (this.floatingFrame >= animEnd) { - if ((this.sequenceLoopMode == SequenceLoopMode.ALWAYS_LOOP) - || ((this.sequenceLoopMode == SequenceLoopMode.MODEL_LOOP) && (sequence.getFlags() == 0))) { - this.floatingFrame = this.frame = (int) interval[0]; // TODO not cast - - this.resetEventEmitters(); - } - else if (this.sequenceLoopMode == SequenceLoopMode.LOOP_TO_NEXT_ANIMATION) { // faux queued animation - // mode - final float framesPast = this.floatingFrame - animEnd; - - final List sequences = model.sequences; - this.sequence = (this.sequence + 1) % sequences.size(); - this.floatingFrame = sequences.get(this.sequence).getInterval()[0] + framesPast; // TODO not cast - this.frame = (int) this.floatingFrame; - this.sequenceEnded = false; - this.resetEventEmitters(); - this.forced = true; - } - else { - this.floatingFrame = this.frame = (int) animEnd; // TODO not cast - this.counter -= integerFrameTime; - this.allowParticleSpawn = false; - } - if (this.sequenceLoopMode == SequenceLoopMode.NEVER_LOOP_AND_HIDE_WHEN_DONE) { - hide(); - } - - this.sequenceEnded = true; - } - else { - this.sequenceEnded = false; - } - } - - final boolean forced = this.forced; - - if (sequenceId == -1) { - if (forced) { - // Update the nodes - this.updateNodes(dt, forced); - - this.updateBoneTexture(); - - // Update the batches - this.updateBatches(forced); - } - } - else { - // let variants = model.variants; - - // if (forced || variants.nodes[sequenceId]) { - // Update the nodes - this.updateNodes(dt, forced); - - this.updateBoneTexture(); - // } - - // if (forced || variants.batches[sequenceId]) { - // Update the batches - this.updateBatches(forced); - // } - } - - this.forced = false; - - } - - @Override - protected void updateLights(final Scene scene) { - for (final LightInstance light : this.lights) { - light.update(scene); - } - } - - @Override - protected void removeLights(final Scene scene2) { - for (final LightInstance light : this.lights) { - light.remove(this.scene); - } - } - - /** - * Set the team color of this instance. - */ - public MdxComplexInstance setTeamColor(final int id) { - this.replaceableTextures[1] = (Texture) this.model.viewer.load( - "ReplaceableTextures\\" + ReplaceableIds.getPathString(1) + ReplaceableIds.getIdString(id) + ".blp", - PathSolver.DEFAULT, null); - this.replaceableTextures[2] = (Texture) this.model.viewer.load( - "ReplaceableTextures\\" + ReplaceableIds.getPathString(2) + ReplaceableIds.getIdString(id) + ".blp", - PathSolver.DEFAULT, null); - return this; - } - - @Override - public void setReplaceableTexture(final int replaceableTextureId, final String replaceableTextureFile) { - this.replaceableTextures[replaceableTextureId] = (Texture) this.model.viewer.load(replaceableTextureFile, - PathSolver.DEFAULT, null); - } - - /** - * Set the vertex color of this instance. - */ - public MdxComplexInstance setVertexColor(final float[] color) { - System.arraycopy(color, 0, this.vertexColor, 0, color.length); - - return this; - } - - public MdxComplexInstance setVertexAlpha(final float alpha) { - this.vertexColor[3] = alpha; - - return this; - } - - /** - * Set the sequence of this instance. - */ - public MdxComplexInstance setSequence(final int id) { - final MdxModel model = (MdxModel) this.model; - - final int lastSequence = this.sequence; - this.sequence = id; - - if (model.ok) { - final List sequences = model.sequences; - - if ((id < 0) || (id > (sequences.size() - 1))) { - this.sequence = -1; - this.frame = 0; - this.floatingFrame = 0; - this.allowParticleSpawn = false; - } - else { - if ((this.blendTime > 0) && (lastSequence != -1)) { - if ((this.blendTimeRemaining <= 0) && (this.counter > 0)) { - this.blendTimeRemaining = this.blendTime; - for (int i = 0, l = this.sortedNodes.length; i < l; i++) { - final SkeletalNode node = this.sortedNodes[i]; - node.beginBlending(); - } - } - } - - this.frame = (int) sequences.get(id).getInterval()[0]; // TODO not cast - this.floatingFrame = this.frame; - this.sequenceEnded = false; - } - - this.resetEventEmitters(); - - this.forced = true; - } - - return this; - } - - /** - * Set the seuqnece loop mode. 0 to never loop, 1 to loop based on the model, - * and 2 to always loop. 3 was added by Retera as "hide after done" for gameplay - * spawned effects - */ - public MdxComplexInstance setSequenceLoopMode(final SequenceLoopMode mode) { - this.sequenceLoopMode = mode; - - return this; - } - - /** - * Get an attachment node. - */ - public MdxNode getAttachment(final int id) { - final MdxModel model = (MdxModel) this.model; - final Attachment attachment = model.attachments.get(id); - - if (attachment != null) { - return this.nodes[attachment.index]; - } - - return null; - } - - /** - * Event emitters depend on keyframe index changes to emit, rather than only - * values. To work, they need to check what the last keyframe was, and only if - * it's a different one, do something. When changing sequences, these states - * need to be reset, so they can immediately emit things if needed. - */ - private void resetEventEmitters() { - /// TODO: Update this. Said Ghostwolf. - for (final EventObjectEmitter eventObjectEmitter : this.eventObjectEmitters) { - eventObjectEmitter.reset(); - } - } - - @Override - protected RenderBatch getBatch(final TextureMapper textureMapper2) { - throw new UnsupportedOperationException("NOT API"); - } - - public Bounds getBounds() { - if (this.sequence == -1) { - return this.model.bounds; - } - else { - final Bounds sequenceBounds = ((MdxModel) this.model).sequences.get(this.sequence).getBounds(); - if (sequenceBounds.r == 0) { - return this.model.bounds; - } - else { - return sequenceBounds; - } - } - } - - public boolean intersectRayBounds(final Ray ray, final Vector3 intersection) { - return CollisionShape.intersectRayBounds(getBounds(), this.worldMatrix, ray, intersection); - } - - /** - * Intersects a world ray with the model's CollisionShapes. Only ever call this - * function on the Gdx thread because it uses static variables to hold state - * while processing. - * - * @param ray - */ - public boolean intersectRayWithCollisionSimple(final Ray ray, final Vector3 intersection) { - final MdxModel mdxModel = (MdxModel) this.model; - final List collisionShapes = mdxModel.collisionShapes; - boolean intersected = false; - ray.getEndPoint(intersection, 99999); - for (final CollisionShape collisionShape : collisionShapes) { - final MdxNode mdxNode = this.nodes[collisionShape.index]; - if (collisionShape.checkIntersect(ray, mdxNode, intersectionHeap)) { - if (intersectionHeap.dst2(ray.origin) < intersection.dst2(ray.origin)) { - intersection.set(intersectionHeap); - } - intersected = true; - } - } - return intersected || intersectRayBounds(ray, intersection); - } - - /** - * Intersects a world ray with the model's geosets. Only ever call this function - * on the Gdx thread because it uses static variables to hold state while - * processing. - * - * @param ray - */ - public boolean intersectRayWithMeshSlow(final Ray ray, final Vector3 intersection) { - final MdxModel mdxModel = (MdxModel) this.model; - boolean intersected = false; - ray.getEndPoint(intersection, 99999); - for (final Geoset geoset : mdxModel.geosets) { - if (!geoset.unselectable) { - geoset.getAlpha(alphaHeap, this.sequence, this.frame, this.counter); - if (alphaHeap[0] > 0) { - final MdlxGeoset mdlxGeoset = geoset.mdlxGeoset; - if (CollisionShape.intersectRayTriangles(ray, this, mdlxGeoset.getVertices(), mdlxGeoset.getFaces(), - 3, intersectionHeap)) { - if (intersectionHeap.dst2(ray.origin) < intersection.dst2(ray.origin)) { - intersection.set(intersectionHeap); - } - intersected = true; - } - } - } - } - return intersected; - } - - /** - * Intersects a world ray with the model's CollisionShapes. Only ever call this - * function on the Gdx thread because it uses static variables to hold state - * while processing. - * - * @param ray - */ - public boolean intersectRayWithCollision(final Ray ray, final Vector3 intersection, final boolean alwaysUseMesh, - final boolean onlyUseMesh) { - final MdxModel mdxModel = (MdxModel) this.model; - final List collisionShapes = mdxModel.collisionShapes; - if (!onlyUseMesh) { - for (final CollisionShape collisionShape : collisionShapes) { - final MdxNode mdxNode = this.nodes[collisionShape.index]; - if (collisionShape.checkIntersect(ray, mdxNode, intersection)) { - return true; - } - } - } - if (collisionShapes.isEmpty() || alwaysUseMesh) { - for (final Geoset geoset : mdxModel.geosets) { - if (!geoset.unselectable) { - geoset.getAlpha(alphaHeap, this.sequence, this.frame, this.counter); - if (alphaHeap[0] > 0) { - final MdlxGeoset mdlxGeoset = geoset.mdlxGeoset; - if (CollisionShape.intersectRayTriangles(ray, this, mdlxGeoset.getVertices(), - mdlxGeoset.getFaces(), 3, intersection)) { - return true; - } - } - } - } - } - return false; - } - - public void setAnimationSpeed(final float speedRatio) { - this.animationSpeed = speedRatio; - for (final AttachmentInstance attachmentInstance : this.attachments) { - if (attachmentInstance.internalInstance != null) { - attachmentInstance.internalInstance.setAnimationSpeed(speedRatio); - } - } - } - - public float getAnimationSpeed() { - return this.animationSpeed; - } - - public void setBlendTime(final float blendTime) { - this.blendTime = blendTime; - } - - public void setFrame(final int frame) { - this.frame = frame; - this.floatingFrame = frame; - } - - public void setFrameByRatio(final float ratioOfAnimationCompleted) { - if (this.sequence != -1) { - final Sequence currentlyPlayingSequence = ((MdxModel) this.model).sequences.get(this.sequence); - final long start = currentlyPlayingSequence.getInterval()[0]; - final int lastIntegerFrame = this.frame; - final float lastFloatingFrame = this.floatingFrame; - final long sequenceLength = currentlyPlayingSequence.getInterval()[1] - start; - final float newFloatingFrame = start + (sequenceLength * ratioOfAnimationCompleted); - float frameTime = newFloatingFrame - lastFloatingFrame; - if (frameTime < 0) { - frameTime += sequenceLength; - } - this.floatingFrame = newFloatingFrame; - this.frame = (int) this.floatingFrame; - this.blendTimeRemaining -= frameTime; - int integerFrameTime = this.frame - lastIntegerFrame; - if (integerFrameTime < 0) { - integerFrameTime += sequenceLength; - } - this.counter += integerFrameTime; - for (final AttachmentInstance attachmentInstance : this.attachments) { - if (attachmentInstance.internalInstance != null) { - attachmentInstance.internalInstance.setFrameByRatio(ratioOfAnimationCompleted); - } - } - } - } - - public int clampFrame(final int frameToClamp) { - final MdxModel model = (MdxModel) this.model; - final int sequenceId = this.sequence; - if ((sequenceId >= 0) && (sequenceId < model.sequences.size())) { - final Sequence sequence = model.sequences.get(sequenceId); - final long[] interval = sequence.getInterval(); - return (int) Math.max(interval[0], Math.min(interval[1], frameToClamp)); - } - return frameToClamp; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxEmitter.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxEmitter.java deleted file mode 100644 index f6a0feed..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxEmitter.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.viewer5.EmittedObject; -import com.etheller.warsmash.viewer5.Emitter; -import com.etheller.warsmash.viewer5.ModelInstance; -import com.etheller.warsmash.viewer5.handlers.EmitterObject; - -public abstract class MdxEmitter>> - extends Emitter { - - protected final EMITTER_OBJECT emitterObject; - - public MdxEmitter(final MODEL_INSTANCE instance, final EMITTER_OBJECT emitterObject) { - super(instance); - - this.emitterObject = emitterObject; - } - - @Override - public void update(final float dt, final boolean objectVisible) { - if (!objectVisible) { - return; - } - if (this.emitterObject.ok()) { - super.update(dt, objectVisible); - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxHandler.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxHandler.java deleted file mode 100644 index 9d4d6e4f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxHandler.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.ArrayList; - -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.etheller.warsmash.viewer5.HandlerResource; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.handlers.ModelHandler; -import com.etheller.warsmash.viewer5.handlers.ResourceHandlerConstructionParams; -import com.etheller.warsmash.viewer5.handlers.blp.BlpHandler; -import com.etheller.warsmash.viewer5.handlers.blp.DdsHandler; -import com.etheller.warsmash.viewer5.handlers.tga.TgaHandler; - -public class MdxHandler extends ModelHandler { - public final Shaders shaders = new Shaders(); - - public static enum ShaderEnvironmentType { - MENU, - GAME - }; - - public static ShaderEnvironmentType CURRENT_SHADER_TYPE; - - public MdxHandler() { - this.extensions = new ArrayList<>(); - this.extensions.add(new String[] { ".mdx", "arrayBuffer" }); - this.extensions.add(new String[] { ".mdl", "text" }); - this.load = true; - } - - @Override - public boolean load(final ModelViewer viewer) { - viewer.addHandler(new BlpHandler()); - viewer.addHandler(new DdsHandler()); - viewer.addHandler(new TgaHandler()); - - this.shaders.complex = viewer.webGL.createShaderProgram(MdxShaders.vsComplex(), MdxShaders.fsComplex); - this.shaders.extended = viewer.webGL.createShaderProgram("#define EXTENDED_BONES\r\n" + MdxShaders.vsComplex(), - MdxShaders.fsComplex); - this.shaders.complexShadowMap = viewer.webGL.createShaderProgram(MdxShaders.vsComplex(), - MdxShaders.fsComplexShadowMap); - this.shaders.extendedShadowMap = viewer.webGL.createShaderProgram( - "#define EXTENDED_BONES\r\n" + MdxShaders.vsComplex(), MdxShaders.fsComplexShadowMap); - this.shaders.particles = viewer.webGL.createShaderProgram(MdxShaders.vsParticles(), MdxShaders.fsParticles); - // Shaders.simple = viewer.webGL.createShaderProgram(MdxShaders.vsSimple, - // MdxShaders.fsSimple); -// Shaders.hd = viewer.webGL.createShaderProgram(MdxShaders.vsHd, MdxShaders.fsHd); - // TODO HD reforged - - // If a shader failed to compile, don't allow the handler to be registered, and - // send an error instead. - return this.shaders.complex.isCompiled() && this.shaders.extended.isCompiled() - && this.shaders.particles.isCompiled() - /* && Shaders.simple.isCompiled() && Shaders.hd.isCompiled() */; - } - - @Override - public HandlerResource construct(final ResourceHandlerConstructionParams params) { - return new MdxModel((MdxHandler) params.getHandler(), params.getViewer(), params.getExtension(), - params.getPathSolver(), params.getFetchUrl()); - } - - public static final class Shaders { - private Shaders() { - - } - - public ShaderProgram complex; - public ShaderProgram complexShadowMap; - public ShaderProgram extended; - public ShaderProgram extendedShadowMap; - public ShaderProgram simple; - public ShaderProgram particles; - public ShaderProgram hd; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxModel.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxModel.java deleted file mode 100644 index f5b88e83..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxModel.java +++ /dev/null @@ -1,378 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.compress.utils.IOUtils; - -import com.badlogic.gdx.graphics.GL20; -import com.etheller.warsmash.viewer5.ModelInstance; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.Texture; -import com.hiveworkshop.rms.parsers.mdlx.MdlxAttachment; -import com.hiveworkshop.rms.parsers.mdlx.MdlxBone; -import com.hiveworkshop.rms.parsers.mdlx.MdlxCamera; -import com.hiveworkshop.rms.parsers.mdlx.MdlxCollisionShape; -import com.hiveworkshop.rms.parsers.mdlx.MdlxEventObject; -import com.hiveworkshop.rms.parsers.mdlx.MdlxExtent; -import com.hiveworkshop.rms.parsers.mdlx.MdlxGeosetAnimation; -import com.hiveworkshop.rms.parsers.mdlx.MdlxHelper; -import com.hiveworkshop.rms.parsers.mdlx.MdlxLayer; -import com.hiveworkshop.rms.parsers.mdlx.MdlxLight; -import com.hiveworkshop.rms.parsers.mdlx.MdlxMaterial; -import com.hiveworkshop.rms.parsers.mdlx.MdlxModel; -import com.hiveworkshop.rms.parsers.mdlx.MdlxParticleEmitter; -import com.hiveworkshop.rms.parsers.mdlx.MdlxParticleEmitter2; -import com.hiveworkshop.rms.parsers.mdlx.MdlxRibbonEmitter; -import com.hiveworkshop.rms.parsers.mdlx.MdlxSequence; -import com.hiveworkshop.rms.parsers.mdlx.MdlxTexture; -import com.hiveworkshop.rms.parsers.mdlx.MdlxTexture.WrapMode; -import com.hiveworkshop.rms.parsers.mdlx.MdlxTextureAnimation; - -public class MdxModel extends com.etheller.warsmash.viewer5.Model { - public boolean reforged = false; - public boolean hd = false; - public SolverParams solverParams = new SolverParams(); - public String name = ""; - public long blendTime; - public List sequences = new ArrayList<>(); - public List globalSequences = new ArrayList<>(); - public List materials = new ArrayList<>(); - public List layers = new ArrayList<>(); - public List replaceables = new ArrayList<>(); - public List textures = new ArrayList<>(); - public List textureAnimations = new ArrayList<>(); - public List geosets = new ArrayList<>(); - public List geosetAnimations = new ArrayList<>(); - public List bones = new ArrayList<>(); - public List lights = new ArrayList<>(); - public List helpers = new ArrayList<>(); - public List attachments = new ArrayList<>(); - public List pivotPoints = new ArrayList<>(); - public List particleEmitters = new ArrayList<>(); - public List particleEmitters2 = new ArrayList<>(); - public List ribbonEmitters = new ArrayList<>(); - public List cameras = new ArrayList<>(); - public List eventObjects = new ArrayList<>(); - public List collisionShapes = new ArrayList<>(); - public boolean hasLayerAnims = false; - public boolean hasGeosetAnims = false; - public List batches = new ArrayList<>(); - public List genericObjects = new ArrayList<>(); - public List sortedGenericObjects = new ArrayList<>(); - public List hierarchy = new ArrayList<>(); - public List opaqueGroups = new ArrayList<>(); - public List translucentGroups = new ArrayList<>(); - public List simpleGroups = new ArrayList<>(); - public int arrayBuffer; - public int elementBuffer; - - public MdxModel(final MdxHandler handler, final ModelViewer viewer, final String extension, - final PathSolver pathSolver, final String fetchUrl) { - super(handler, viewer, extension, pathSolver, fetchUrl); - } - - @Override - public ModelInstance createInstance(final int type) { - if (type == 1) { - return new MdxSimpleInstance(this); - } - else { - return new MdxComplexInstance(this); - } - } - - public void load(final Object bufferOrParser) throws IOException { - MdlxModel parser; - - if (bufferOrParser instanceof MdlxModel) { - parser = (MdlxModel) bufferOrParser; - } - else { - System.err.println("Wasting memory with conversion from InputStream to buffer in MdxModel"); - parser = new MdlxModel(ByteBuffer.wrap(IOUtils.toByteArray((InputStream) bufferOrParser))); - } - - final ModelViewer viewer = this.viewer; - final PathSolver pathSolver = this.pathSolver; - final SolverParams solverParams = this.solverParams; - final boolean reforged = parser.getVersion() > 800; - final String texturesExt = reforged ? ".dds" : ".blp"; - - this.reforged = reforged; - this.name = parser.getName(); - this.blendTime = parser.getBlendTime(); - - // Initialize the bounds. - final MdlxExtent extent = parser.getExtent(); - final float[] min = extent.getMin(); - final float[] max = extent.getMax(); - for (int i = 0; i < 3; i++) { - if (min[i] > max[i]) { - min[i] = max[i] = 0; - } - } - this.bounds.fromExtents(min, max, extent.getBoundsRadius()); - - // Sequences - for (final MdlxSequence sequence : parser.getSequences()) { - this.sequences.add(new Sequence(sequence)); - } - - // Global sequences - this.globalSequences.addAll(parser.getGlobalSequences()); - - // Texture animations - for (final MdlxTextureAnimation textureAnimation : parser.getTextureAnimations()) { - this.textureAnimations.add(new TextureAnimation(this, textureAnimation)); - } - - // Materials - int layerId = 0; - for (final MdlxMaterial material : parser.getMaterials()) { - final List layers = new ArrayList<>(); - - for (final MdlxLayer layer : material.getLayers()) { - final Layer vLayer = new Layer(this, layer, layerId++, material.getPriorityPlane()); - - layers.add(vLayer); - - this.layers.add(vLayer); - } - - this.materials.add(new Material(this, "" /* material.shader */, layers)); - - if (false /* !"".equals(material.shader) */) { - this.hd = true; - } - } - - if (reforged) { - solverParams.reforged = true; - } - - if (this.hd) { - solverParams.hd = true; - } - - final GL20 gl = viewer.gl; - - // Textures. - for (final MdlxTexture texture : parser.getTextures()) { - String path = texture.getPath(); - final int replaceableId = texture.getReplaceableId(); - final WrapMode wrapMode = texture.getWrapMode(); - - if (replaceableId != 0) { - // TODO This uses dumb, stupid, terrible, no-good hardcoded replaceable IDs - // instead of the real system, because currently MdxSimpleInstance is not - // supporting it correctly. - final String idString = ((replaceableId == 1) || (replaceableId == 2)) ? ReplaceableIds.getIdString(0) - : ""; - path = "ReplaceableTextures\\" + ReplaceableIds.getPathString(replaceableId) + idString + ".blp"; - } - - if (reforged && !path.endsWith(".dds")) { - path = path.substring(0, path.length() - 4) + ".dds"; - } - else if ("".equals(path)) { - path = "Textures\\white.blp"; - } - - final Texture viewerTexture = (Texture) viewer.load(path, pathSolver, solverParams); - - // When the texture will load, it will apply its wrap modes. - if (wrapMode.isWrapWidth()) { - viewerTexture.setWrapS(true); - } - - if (wrapMode.isWrapHeight()) { - viewerTexture.setWrapT(true); - } - - this.replaceables.add(replaceableId); - this.textures.add(viewerTexture); - } - - // Geoset animations - for (final MdlxGeosetAnimation geosetAnimation : parser.getGeosetAnimations()) { - this.geosetAnimations.add(new GeosetAnimation(this, geosetAnimation)); - } - - // Geosets - SetupGeosets.setupGeosets(this, parser.getGeosets(), parser.getBones().size() >= 256); - - this.pivotPoints = parser.getPivotPoints(); - - // Tracks the IDs of all generic objects - int objectId = 0; - - // Bones - for (final MdlxBone bone : parser.getBones()) { - this.bones.add(new Bone(this, bone, objectId++)); - } - - // Lights - for (final MdlxLight light : parser.getLights()) { - this.lights.add(new Light(this, light, objectId++)); - } - - // Helpers - for (final MdlxHelper helper : parser.getHelpers()) { - this.helpers.add(new Helper(this, helper, objectId++)); - } - - // Attachments - for (final MdlxAttachment attachment : parser.getAttachments()) { - this.attachments.add(new Attachment(this, attachment, objectId++)); - } - - // Particle Emitters - for (final MdlxParticleEmitter particleEmitter : parser.getParticleEmitters()) { - this.particleEmitters.add(new ParticleEmitterObject(this, particleEmitter, objectId++)); - } - - // Particle Emitters 2 - for (final MdlxParticleEmitter2 particleEmitter2 : parser.getParticleEmitters2()) { - this.particleEmitters2.add(new ParticleEmitter2Object(this, particleEmitter2, objectId++)); - } - - // Ribbon emitters - for (final MdlxRibbonEmitter ribbonEmitter : parser.getRibbonEmitters()) { - this.ribbonEmitters.add(new RibbonEmitterObject(this, ribbonEmitter, objectId++)); - } - - // Camera - for (final MdlxCamera camera : parser.getCameras()) { - this.cameras.add(new Camera(this, camera)); - } - - // Event objects - for (final MdlxEventObject eventObject : parser.getEventObjects()) { - this.eventObjects.add(new EventObjectEmitterObject(this, eventObject, objectId++)); - } - - // Collision shapes - for (final MdlxCollisionShape collisionShape : parser.getCollisionShapes()) { - this.collisionShapes.add(new CollisionShape(this, collisionShape, objectId++)); - } - - // One array for all generic objects. - this.genericObjects.addAll(this.bones); - this.genericObjects.addAll(this.lights); - this.genericObjects.addAll(this.helpers); - this.genericObjects.addAll(this.attachments); - this.genericObjects.addAll(this.particleEmitters); - this.genericObjects.addAll(this.particleEmitters2); - this.genericObjects.addAll(this.ribbonEmitters); - this.genericObjects.addAll(this.eventObjects); - this.genericObjects.addAll(this.collisionShapes); - - // Render groups. - SetupGroups.setupGroups(this); - - // SimpleInstance render group. - SetupSimpleGroups.setupSimpleGroups(this); - - // Creates the sorted indices array of the generic objects - try { - this.setupHierarchy(-1); - } - catch (final StackOverflowError e) { - System.out.println("bah"); - } - - // Keep a sorted array. - for (int i = 0, l = this.genericObjects.size(); i < l; i++) { - this.sortedGenericObjects.add(this.genericObjects.get(this.hierarchy.get(i))); - } - - } - - private void setupHierarchy(final int parent) { - for (int i = 0, l = this.genericObjects.size(); i < l; i++) { - final GenericObject object = this.genericObjects.get(i); - - if (object.parentId == parent) { - this.hierarchy.add(i); - - this.setupHierarchy(object.objectId); - } - } - } - - @Override - protected void lateLoad() { - } - - @Override - protected void load(final InputStream src, final Object options) { - try { - this.load(src); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - @Override - protected void error(final Exception e) { - e.printStackTrace(); - } - - // TODO typing - public List getGlobalSequences() { - return this.globalSequences; - } - - public List getSequences() { - return this.sequences; - } - - public List getPivotPoints() { - return this.pivotPoints; - } - - public List getGeosetAnimations() { - return this.geosetAnimations; - } - - public List getTextures() { - return this.textures; - } - - public List getMaterials() { - return this.materials; - } - - public List getTextureAnimations() { - return this.textureAnimations; - } - - public List getGeosets() { - return this.geosets; - } - - private static final class SolverParams { - public boolean reforged; - public boolean hd; - - } - - public List getCameras() { - return this.cameras; - } - - public List getEventObjects() { - return this.eventObjects; - } - - public List getBones() { - return this.bones; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxNode.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxNode.java deleted file mode 100644 index cafc3a27..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxNode.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.badlogic.gdx.math.Quaternion; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.SkeletalNode; - -public class MdxNode extends SkeletalNode { - private static final Quaternion HALF_PI_X = new Quaternion().setFromAxisRad(1, 0, 0, (float) (-Math.PI / 2)); - private static final Quaternion HALF_PI_Y = new Quaternion().setFromAxisRad(0, 1, 0, (float) (-Math.PI / 2)); - - @Override - protected void convertBasis(final Quaternion computedRotation) { - computedRotation.mul(HALF_PI_Y); - computedRotation.mul(HALF_PI_X); - } - - @Override - protected void update(final float dt, final Scene scene) { - - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxNodeDescriptor.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxNodeDescriptor.java deleted file mode 100644 index 72c36654..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxNodeDescriptor.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.util.Descriptor; - -public class MdxNodeDescriptor implements Descriptor { - public static final MdxNodeDescriptor INSTANCE = new MdxNodeDescriptor(); - - @Override - public MdxNode create() { - return new MdxNode(); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxRenderBatch.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxRenderBatch.java deleted file mode 100644 index 66203c9a..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxRenderBatch.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.nio.FloatBuffer; -import java.util.List; - -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.badlogic.gdx.math.Matrix4; -import com.etheller.warsmash.viewer5.Model; -import com.etheller.warsmash.viewer5.ModelInstance; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.RenderBatch; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.Texture; -import com.etheller.warsmash.viewer5.TextureMapper; -import com.etheller.warsmash.viewer5.gl.ANGLEInstancedArrays; -import com.etheller.warsmash.viewer5.gl.ClientBuffer; -import com.etheller.warsmash.viewer5.gl.WebGL; -import com.etheller.warsmash.viewer5.handlers.w3x.DynamicShadowManager; - -public class MdxRenderBatch extends RenderBatch { - private static final Matrix4 transposeHeap = new Matrix4(); - - public MdxRenderBatch(final Scene scene, final Model model, final TextureMapper textureMapper) { - super(scene, model, textureMapper); - } - - private void bindAndUpdateBuffer(final ClientBuffer buffer) { - final int count = this.count; - final List instances = this.instances; - - // Ensure there is enough memory for all of the instances data. - buffer.reserve(count * 48); - - final FloatBuffer floatView = buffer.floatView; - - // "Copy" the instances into the buffer - for (int i = 0; i < count; i++) { - final ModelInstance instance = instances.get(i); - final Matrix4 worldMatrix = instance.worldMatrix; - final int offset = i * 12; - - floatView.put(offset + 0, worldMatrix.val[Matrix4.M00]); - floatView.put(offset + 1, worldMatrix.val[Matrix4.M10]); - floatView.put(offset + 2, worldMatrix.val[Matrix4.M20]); - floatView.put(offset + 3, worldMatrix.val[Matrix4.M01]); - floatView.put(offset + 4, worldMatrix.val[Matrix4.M11]); - floatView.put(offset + 5, worldMatrix.val[Matrix4.M21]); - floatView.put(offset + 6, worldMatrix.val[Matrix4.M02]); - floatView.put(offset + 7, worldMatrix.val[Matrix4.M12]); - floatView.put(offset + 8, worldMatrix.val[Matrix4.M22]); - floatView.put(offset + 9, worldMatrix.val[Matrix4.M03]); - floatView.put(offset + 10, worldMatrix.val[Matrix4.M13]); - floatView.put(offset + 11, worldMatrix.val[Matrix4.M23]); - } - - // Update the buffer. - buffer.bindAndUpdate(count * 48); - } - - @Override - public void render() { - if (DynamicShadowManager.IS_SHADOW_MAPPING) { - return; - } - final int count = this.count; - - if (count != 0) { - final MdxModel model = (MdxModel) this.model; - final List batches = model.batches; - final List textures = model.textures; - final ModelViewer viewer = model.viewer; - final GL20 gl = viewer.gl; - final WebGL webGL = viewer.webGL; - final ANGLEInstancedArrays instancedArrays = webGL.instancedArrays; - final ShaderProgram shader = model.handler.shaders.simple; - final int m0 = shader.getAttributeLocation("a_m0"); - final int m1 = shader.getAttributeLocation("a_m1"); - final int m2 = shader.getAttributeLocation("a_m2"); - final int m3 = shader.getAttributeLocation("a_m3"); - final ClientBuffer buffer = viewer.buffer; - final TextureMapper textureMapper = this.textureMapper; - - webGL.useShaderProgram(shader); - - this.bindAndUpdateBuffer(buffer); - - shader.setVertexAttribute(m0, 3, GL20.GL_FLOAT, false, 48, 0); - shader.setVertexAttribute(m1, 3, GL20.GL_FLOAT, false, 48, 12); - shader.setVertexAttribute(m2, 3, GL20.GL_FLOAT, false, 48, 24); - shader.setVertexAttribute(m3, 3, GL20.GL_FLOAT, false, 48, 36); - - transposeHeap.set(this.scene.camera.viewProjectionMatrix); - transposeHeap.tra(); - shader.setUniformMatrix4fv("u_VP", this.scene.camera.viewProjectionMatrix.val, 0, - this.scene.camera.viewProjectionMatrix.val.length); - - gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, model.arrayBuffer); - gl.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, model.elementBuffer); - - instancedArrays.glVertexAttribDivisorANGLE(m0, 1); - instancedArrays.glVertexAttribDivisorANGLE(m1, 1); - instancedArrays.glVertexAttribDivisorANGLE(m2, 1); - instancedArrays.glVertexAttribDivisorANGLE(m3, 1); - - for (final GenericGroup group : model.simpleGroups) { - for (final Integer object : group.objects) { - final Batch batch = batches.get(object); - final Geoset geoset = batch.geoset; - final Layer layer = batch.layer; - final Texture texture = textures.get(layer.textureId); - - shader.setUniformi("u_texture", 0); - - Texture mappedTexture = textureMapper.get(texture); - if (mappedTexture == null) { - mappedTexture = texture; - } - viewer.webGL.bindTexture(mappedTexture, 0); - - layer.bind(shader); - - geoset.bindSimple(shader); - geoset.renderSimple(count); - } - } - - instancedArrays.glVertexAttribDivisorANGLE(m3, 0); - instancedArrays.glVertexAttribDivisorANGLE(m2, 0); - instancedArrays.glVertexAttribDivisorANGLE(m1, 0); - instancedArrays.glVertexAttribDivisorANGLE(m0, 0); - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxShaders.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxShaders.java deleted file mode 100644 index 194d0129..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxShaders.java +++ /dev/null @@ -1,492 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.viewer5.Shaders; - -public class MdxShaders { - public static final String vsHd = Shaders.boneTexture + "\r\n" + // - " uniform mat4 u_mvp;\r\n" + // - " uniform float u_layerAlpha;\r\n" + // - " attribute vec3 a_position;\r\n" + // - " attribute vec3 a_normal;\r\n" + // - " attribute vec2 a_uv;\r\n" + // - " attribute vec4 a_bones;\r\n" + // - " attribute vec4 a_weights;\r\n" + // - " varying vec3 v_normal;\r\n" + // - " varying vec2 v_uv;\r\n" + // - " varying float v_layerAlpha;\r\n" + // - " void transform(inout vec3 position, inout vec3 normal) {\r\n" + // - " mat4 bone;\r\n" + // - " bone += fetchMatrix(a_bones[0], 0.0) * a_weights[0];\r\n" + // - " bone += fetchMatrix(a_bones[1], 0.0) * a_weights[1];\r\n" + // - " bone += fetchMatrix(a_bones[2], 0.0) * a_weights[2];\r\n" + // - " bone += fetchMatrix(a_bones[3], 0.0) * a_weights[3];\r\n" + // - " position = vec3(bone * vec4(position, 1.0));\r\n" + // - " normal = mat3(bone) * normal;\r\n" + // - " }\r\n" + // - " void main() {\r\n" + // - " vec3 position = a_position;\r\n" + // - " vec3 normal = a_normal;\r\n" + // - " transform(position, normal);\r\n" + // - " v_normal = normal;\r\n" + // - " v_uv = a_uv;\r\n" + // - " v_layerAlpha = u_layerAlpha;\r\n" + // - " gl_Position = u_mvp * vec4(position, 1.0);\r\n" + // - " }"; - - public static final String fsHd = "\r\n" + // - " uniform sampler2D u_diffuseMap;\r\n" + // - " uniform sampler2D u_ormMap;\r\n" + // - " uniform sampler2D u_teamColorMap;\r\n" + // - " uniform float u_filterMode;\r\n" + // - " varying vec3 v_normal;\r\n" + // - " varying vec2 v_uv;\r\n" + // - " varying float v_layerAlpha;\r\n" + // - " void main() {\r\n" + // - " vec4 texel = texture2D(u_diffuseMap, v_uv);\r\n" + // - " vec4 color = vec4(texel.rgb, texel.a * v_layerAlpha);\r\n" + // - " vec4 orma = texture2D(u_ormMap, v_uv);\r\n" + // - " if (orma.a > 0.1) {\r\n" + // - " color *= texture2D(u_teamColorMap, v_uv) * orma.a;\r\n" + // - " }\r\n" + // - " // 1bit Alpha\r\n" + // - " if (u_filterMode == 1.0 && color.a < 0.75) {\r\n" + // - " discard;\r\n" + // - " }\r\n" + // - " gl_FragColor = color;\r\n" + // - " }"; - - public static final String vsSimple = "\r\n" + // - " uniform mat4 u_VP;\r\n" + // - " attribute vec3 a_m0;\r\n" + // - " attribute vec3 a_m1;\r\n" + // - " attribute vec3 a_m2;\r\n" + // - " attribute vec3 a_m3;\r\n" + // - " attribute vec3 a_position;\r\n" + // - " attribute vec2 a_uv;\r\n" + // - " varying vec2 v_uv;\r\n" + // - " void main() {\r\n" + // - " v_uv = a_uv;\r\n" + // - " gl_Position = u_VP * mat4(a_m0, 0.0, a_m1, 0.0, a_m2, 0.0, a_m3, 1.0) * vec4(a_position, 1.0);\r\n" + // - " }\r\n"; - - public static final String fsSimple = "\r\n" + // - " precision mediump float;\r\n" + // - " uniform sampler2D u_texture;\r\n" + // - " uniform float u_filterMode;\r\n" + // - " varying vec2 v_uv;\r\n" + // - " void main() {\r\n" + // - " vec4 color = texture2D(u_texture, v_uv);\r\n" + // - " // 1bit Alpha\r\n" + // - " if (u_filterMode == 1.0 && color.a < 0.75) {\r\n" + // - " discard;\r\n" + // - " }\r\n" + // - " gl_FragColor = color;\r\n" + // - " }\r\n"; - - public static final String vsComplex() { - return "\r\n" + // - "\r\n" + // - " uniform mat4 u_mvp;\r\n" + // - " uniform vec4 u_vertexColor;\r\n" + // - " uniform vec4 u_geosetColor;\r\n" + // - " uniform float u_layerAlpha;\r\n" + // - " uniform vec2 u_uvTrans;\r\n" + // - " uniform vec2 u_uvRot;\r\n" + // - " uniform float u_uvScale;\r\n" + // - " uniform bool u_hasBones;\r\n" + // - " uniform bool u_unshaded;\r\n" + // - " attribute vec3 a_position;\r\n" + // - " attribute vec3 a_normal;\r\n" + // - " attribute vec2 a_uv;\r\n" + // - " attribute vec4 a_bones;\r\n" + // - " #ifdef EXTENDED_BONES\r\n" + // - " attribute vec4 a_extendedBones;\r\n" + // - " #endif\r\n" + // - " attribute float a_boneNumber;\r\n" + // - " varying vec2 v_uv;\r\n" + // - " varying vec4 v_color;\r\n" + // - " varying vec4 v_uvTransRot;\r\n" + // - " varying float v_uvScale;\r\n" + // - " uniform sampler2D u_lightTexture;\r\n" + // - " uniform float u_lightCount;\r\n" + // - " uniform float u_lightTextureHeight;\r\n" + // - Shaders.boneTexture + "\r\n" + // - " void transform(inout vec3 position, inout vec3 normal) {\r\n" + // - " // For the broken models out there, since the game supports this.\r\n" + // - " if (a_boneNumber > 0.0) {\r\n" + // - " vec4 position4 = vec4(position, 1.0);\r\n" + // - " vec4 normal4 = vec4(normal, 0.0);\r\n" + // - " mat4 bone;\r\n" + // - " vec4 p = vec4(0.0,0.0,0.0,0.0);\r\n" + // - " vec4 n = vec4(0.0,0.0,0.0,0.0);\r\n" + // - " for (int i = 0; i < 4; i++) {\r\n" + // - " if (a_bones[i] > 0.0) {\r\n" + // - " bone = fetchMatrix(a_bones[i] - 1.0, 0.0);\r\n" + // - " p += bone * position4;\r\n" + // - " n += bone * normal4;\r\n" + // - " }\r\n" + // - " }\r\n" + // - " #ifdef EXTENDED_BONES\r\n" + // - " for (int i = 0; i < 4; i++) {\r\n" + // - " if (a_extendedBones[i] > 0.0) {\r\n" + // - " bone = fetchMatrix(a_extendedBones[i] - 1.0, 0.0);\r\n" + // - " p += bone * position4;\r\n" + // - " n += bone * normal4;\r\n" + // - " }\r\n" + // - " }\r\n" + // - " #endif\r\n" + // - " position = p.xyz / a_boneNumber;\r\n" + // - " normal = normalize(n.xyz);\r\n" + // - " } else {\r\n" + // - " position.x += 100.0;\r\n" + // - " }\r\n" + // - "\r\n" + // - " }\r\n" + // - " void main() {\r\n" + // - " vec3 position = a_position;\r\n" + // - " vec3 normal = a_normal;\r\n" + // - " if (u_hasBones) {\r\n" + // - " transform(position, normal);\r\n" + // - " }\r\n" + // - " v_uv = a_uv;\r\n" + // - " v_color = u_vertexColor * u_geosetColor.bgra * vec4(1.0, 1.0, 1.0, u_layerAlpha);\r\n" + // - " v_uvTransRot = vec4(u_uvTrans, u_uvRot);\r\n" + // - " v_uvScale = u_uvScale;\r\n" + // - " gl_Position = u_mvp * vec4(position, 1.0);\r\n" + // - " if(!u_unshaded) {\r\n" + // - Shaders.lightSystem("normal", "position", "u_lightTexture", "u_lightTextureHeight", "u_lightCount", - false) - + "\r\n" + // - " v_color.xyz *= clamp(lightFactor, 0.0, 1.0);\r\n" + // - " }\r\n" + // - " }"; - } - - public static final String fsComplex = Shaders.quatTransform + "\r\n\r\n" + // - " uniform sampler2D u_texture;\r\n" + // - " uniform vec4 u_vertexColor;\r\n" + // - " uniform float u_filterMode;\r\n" + // - " varying vec2 v_uv;\r\n" + // - " varying vec4 v_color;\r\n" + // - " varying vec4 v_uvTransRot;\r\n" + // - " varying float v_uvScale;\r\n" + // - " void main() {\r\n" + // - " vec2 uv = v_uv;\r\n" + // - " // Translation animation\r\n" + // - " uv += v_uvTransRot.xy;\r\n" + // - " // Rotation animation\r\n" + // - " uv = quat_transform(v_uvTransRot.zw, uv - 0.5) + 0.5;\r\n" + // - " // Scale animation\r\n" + // - " uv = v_uvScale * (uv - 0.5) + 0.5;\r\n" + // - " vec4 texel = texture2D(u_texture, uv);\r\n" + // - " vec4 color = texel * v_color;\r\n" + // - " // 1bit Alpha\r\n" + // - " if (u_vertexColor.a == 1.0 && u_filterMode == 1.0 && color.a < 0.75) {\r\n" + // - " discard;\r\n" + // - " }\r\n" + // - " // \"Close to 0 alpha\"\r\n" + // - " if (u_filterMode >= 5.0 && color.a < 0.02) {\r\n" + // - " discard;\r\n" + // - " }\r\n" + // - " gl_FragColor = color;\r\n" + // - " }"; - - public static final String fsComplexShadowMap = "\r\n\r\n" + // - Shaders.quatTransform + "\r\n\r\n" + // - " uniform sampler2D u_texture;\r\n" + // - " uniform float u_filterMode;\r\n" + // - " varying vec2 v_uv;\r\n" + // - " varying vec4 v_color;\r\n" + // - " varying vec4 v_uvTransRot;\r\n" + // - " varying float v_uvScale;\r\n" + // - " varying vec3 v_normal;\r\n" + // -// " layout(location = 0) out float fragmentdepth;\r\n" + // - " void main() {\r\n" + // - " vec2 uv = v_uv;\r\n" + // - " // Translation animation\r\n" + // - " uv += v_uvTransRot.xy;\r\n" + // - " // Rotation animation\r\n" + // - " uv = quat_transform(v_uvTransRot.zw, uv - 0.5) + 0.5;\r\n" + // - " // Scale animation\r\n" + // - " uv = v_uvScale * (uv - 0.5) + 0.5;\r\n" + // - " vec4 texel = texture2D(u_texture, uv);\r\n" + // - " vec4 color = texel * v_color;\r\n" + // - " // 1bit Alpha\r\n" + // - " if (u_filterMode == 1.0 && color.a < 0.75) {\r\n" + // - " discard;\r\n" + // - " }\r\n" + // - " // \"Close to 0 alpha\"\r\n" + // - " if (u_filterMode >= 5.0 && color.a < 0.02) {\r\n" + // - " discard;\r\n" + // - " }\r\n" + // - " gl_FragColor = vec4(0.0, 0, 0, 1.0);//gl_FragCoord.z;\r\n" + // - " }"; - - public static final String vsParticles() { - return "\r\n" + // - " #define EMITTER_PARTICLE2 0.0\r\n" + // - " #define EMITTER_RIBBON 1.0\r\n" + // - " #define EMITTER_SPLAT 2.0\r\n" + // - " #define EMITTER_UBERSPLAT 3.0\r\n" + // - " #define HEAD 0.0\r\n" + // - " uniform mat4 u_mvp;\r\n" + // - " uniform mediump float u_emitter;\r\n" + // - " // Shared\r\n" + // - " uniform vec4 u_colors[3];\r\n" + // - " uniform vec3 u_vertices[4];\r\n" + // - " uniform vec3 u_intervals[4];\r\n" + // - " uniform float u_lifeSpan;\r\n" + // - " uniform float u_columns;\r\n" + // - " uniform float u_rows;\r\n" + // - " // Particle2\r\n" + // - " uniform vec3 u_scaling;\r\n" + // - " uniform vec3 u_cameraZ;\r\n" + // - " uniform float u_timeMiddle;\r\n" + // - " uniform bool u_teamColored;\r\n" + // - " uniform bool u_unshaded;\r\n" + // - " uniform sampler2D u_lightTexture;\r\n" + // - " uniform float u_lightCount;\r\n" + // - " uniform float u_lightTextureHeight;\r\n" + // - " // Splat and Uber.\r\n" + // - " uniform vec3 u_intervalTimes;\r\n" + // - " // Vertices\r\n" + // - " attribute float a_position;\r\n" + // - " // Instances\r\n" + // - " attribute vec3 a_p0;\r\n" + // - " attribute vec3 a_p1;\r\n" + // - " attribute vec3 a_p2;\r\n" + // - " attribute vec3 a_p3;\r\n" + // - " attribute float a_health;\r\n" + // - " attribute vec4 a_color;\r\n" + // - " attribute float a_tail;\r\n" + // - " attribute vec3 a_leftRightTop;\r\n" + // - " varying vec2 v_texcoord;\r\n" + // - " varying vec4 v_color;\r\n" + // - " float getCell(vec3 interval, float factor) {\r\n" + // - " float start = interval[0];\r\n" + // - " float end = interval[1];\r\n" + // - " float repeat = interval[2];\r\n" + // - " float spriteCount = end - start;\r\n" + // - " if (spriteCount > 0.0) {\r\n" + // - " // Repeating speeds up the sprite animation, which makes it effectively run N times in its interval.\r\n" - + // - " // E.g. if repeat is 4, the sprite animation will be seen 4 times, and thus also run 4 times as fast.\r\n" - + // - " // The sprite index is limited to the number of actual sprites.\r\n" + // - " return min(start + mod(floor(spriteCount * repeat * factor), spriteCount), u_columns * u_rows - 1.0);\r\n" - + // - " }\r\n" + // - " return 0.0;\r\n" + // - " }\r\n" + // - " void particle2() {\r\n" + // - " float factor = (u_lifeSpan - a_health) / u_lifeSpan;\r\n" + // - " int index = 0;\r\n" + // - " if (factor < u_timeMiddle) {\r\n" + // - " factor = factor / u_timeMiddle;\r\n" + // - " index = 0;\r\n" + // - " } else {\r\n" + // - " factor = (factor - u_timeMiddle) / (1.0 - u_timeMiddle);\r\n" + // - " index = 1;\r\n" + // - " }\r\n" + // - " factor = min(factor, 1.0);\r\n" + // - " float scale = mix(u_scaling[index], u_scaling[index + 1], factor);\r\n" + // - " vec4 color = mix(u_colors[index], u_colors[index + 1], factor);\r\n" + // - " float cell = 0.0;\r\n" + // - " if (u_teamColored) {\r\n" + // - " cell = a_leftRightTop[0];\r\n" + // - " } else {\r\n" + // - " vec3 interval;\r\n" + // - " if (a_tail == HEAD) {\r\n" + // - " interval = u_intervals[index];\r\n" + // - " } else {\r\n" + // - " interval = u_intervals[index + 2];\r\n" + // - " }\r\n" + // - " cell = getCell(interval, factor);\r\n" + // - " }\r\n" + // - " float left = floor(mod(cell, u_columns));\r\n" + // - " float top = floor(cell / u_columns);\r\n" + // - " float right = left + 1.0;\r\n" + // - " float bottom = top + 1.0;\r\n" + // - " left /= u_columns;\r\n" + // - " right /= u_columns;\r\n" + // - " top /= u_rows;\r\n" + // - " bottom /= u_rows;\r\n" + // - " if (a_position == 0.0) {\r\n" + // - " v_texcoord = vec2(right, top);\r\n" + // - " } else if (a_position == 1.0) {\r\n" + // - " v_texcoord = vec2(left, top);\r\n" + // - " } else if (a_position == 2.0) {\r\n" + // - " v_texcoord = vec2(left, bottom);\r\n" + // - " } else if (a_position == 3.0) {\r\n" + // - " v_texcoord = vec2(right, bottom);\r\n" + // - " }\r\n" + // - " v_color = color;\r\n" + // - " \r\n" + // - " vec3 lightingNormal;\r\n" + // - " vec3 position;\r\n" + // - " if (a_tail == HEAD) {\r\n" + // - " vec3 vertices[4];\r\n" + // - " if(a_p1[0] != 0.0 || a_p1[1] != 0.0) {\r\n" + // - " lightingNormal = vec3(0.0, 0.0, 1.0);\r\n" + // - " vec3 vx;\r\n" + // - " vx[0] = a_p1[0];\r\n" + // - " vx[1] = a_p1[1];\r\n" + // - " vx[2] = 0.0;\r\n" + // - " vx = normalize(vx);\r\n" + // - " vec3 vy;\r\n" + // - " vy[0] = -vx[1];\r\n" + // - " vy[1] = vx[0];\r\n" + // - " vy[2] = 0.0;\r\n" + // - " vertices[2] = - vx - vy;\r\n" + // - " vertices[1] = vx - vy;\r\n" + // - " vertices[0] = -vertices[2];\r\n" + // - " vertices[3] = -vertices[1];\r\n" + // - " } else {\r\n" + // - " lightingNormal = normalize(u_cameraZ);\r\n" + // - " vertices[0] = u_vertices[0];\r\n" + // - " vertices[1] = u_vertices[1];\r\n" + // - " vertices[2] = u_vertices[2];\r\n" + // - " vertices[3] = u_vertices[3];\r\n" + // - " }\r\n" + // - " position = a_p0 + (vertices[int(a_position)] * scale);\r\n" + // - " gl_Position = u_mvp * vec4(position, 1.0);\r\n" + // - " } else {\r\n" + // - " // Get the normal to the tail in camera space.\r\n" + // - " // This allows to build a 2D rectangle around the 3D tail.\r\n" + // - " vec3 normal = cross(u_cameraZ, normalize(a_p1 - a_p0));\r\n" + // - " vec3 boundary = normal * scale * a_p2[0];\r\n" + // - " if (a_position == 0.0) {\r\n" + // - " position = a_p0 - boundary;\r\n" + // - " } else if (a_position == 1.0) {\r\n" + // - " position = a_p1 - boundary;\r\n" + // - " } else if (a_position == 2.0) {\r\n" + // - " position = a_p1 + boundary;\r\n" + // - " } else if (a_position == 3.0) {\r\n" + // - " position = a_p0 + boundary;\r\n" + // - " }\r\n" + // - " gl_Position = u_mvp * vec4(position, 1.0);\r\n" + // - " lightingNormal = normalize(u_cameraZ);\r\n" + // - " }\r\n" + // - " if(!u_unshaded) {\r\n" + // - Shaders.lightSystem("lightingNormal", "position", "u_lightTexture", "u_lightTextureHeight", - "u_lightCount", false) - + "\r\n" + // - " v_color.xyz *= clamp(lightFactor, 0.0, 1.0);\r\n" + // - " }\r\n" + // - " }\r\n" + // - " void ribbon() {\r\n" + // - " vec3 position;\r\n" + // - " float left = a_leftRightTop[0] / 255.0;\r\n" + // - " float right = a_leftRightTop[1] / 255.0;\r\n" + // - " float top = a_leftRightTop[2] / 255.0;\r\n" + // - " float bottom = top + 1.0;\r\n" + // - " if (a_position == 0.0) {\r\n" + // - " v_texcoord = vec2(right, top);\r\n" + // - " position = a_p0;\r\n" + // - " } else if (a_position == 1.0) {\r\n" + // - " v_texcoord = vec2(right, bottom);\r\n" + // - " position = a_p1;\r\n" + // - " } else if (a_position == 2.0) {\r\n" + // - " v_texcoord = vec2(left, bottom);\r\n" + // - " position = a_p2;\r\n" + // - " } else if (a_position == 3.0) {\r\n" + // - " v_texcoord = vec2(left, top);\r\n" + // - " position = a_p3;\r\n" + // - " }\r\n" + // - " v_texcoord[0] /= u_columns;\r\n" + // - " v_texcoord[1] /= u_rows;\r\n" + // - " v_color = a_color;\r\n" + // - " gl_Position = u_mvp * vec4(position, 1.0);\r\n" + // - " }\r\n" + // - " void splat() {\r\n" + // - " float factor = u_lifeSpan - a_health;\r\n" + // - " int index;\r\n" + // - " if (factor < u_intervalTimes[0]) {\r\n" + // - " factor = factor / u_intervalTimes[0];\r\n" + // - " index = 0;\r\n" + // - " } else {\r\n" + // - " factor = (factor - u_intervalTimes[0]) / u_intervalTimes[1];\r\n" + // - " index = 1;\r\n" + // - " }\r\n" + // - " float cell = getCell(u_intervals[index], factor);\r\n" + // - " float left = floor(mod(cell, u_columns));\r\n" + // - " float top = floor(cell / u_columns);\r\n" + // - " float right = left + 1.0;\r\n" + // - " float bottom = top + 1.0;\r\n" + // - " vec3 position;\r\n" + // - " if (a_position == 0.0) {\r\n" + // - " v_texcoord = vec2(left, top);\r\n" + // - " position = a_p0;\r\n" + // - " } else if (a_position == 1.0) {\r\n" + // - " v_texcoord = vec2(left, bottom);\r\n" + // - " position = a_p1;\r\n" + // - " } else if (a_position == 2.0) {\r\n" + // - " v_texcoord = vec2(right, bottom);\r\n" + // - " position = a_p2;\r\n" + // - " } else if (a_position == 3.0) {\r\n" + // - " v_texcoord = vec2(right, top);\r\n" + // - " position = a_p3;\r\n" + // - " }\r\n" + // - " v_texcoord[0] /= u_columns;\r\n" + // - " v_texcoord[1] /= u_rows;\r\n" + // - " v_color = mix(u_colors[index], u_colors[index + 1], factor) / 255.0;\r\n" + // - " gl_Position = u_mvp * vec4(position, 1.0);\r\n" + // - " }\r\n" + // - " void ubersplat() {\r\n" + // - " float factor = u_lifeSpan - a_health;\r\n" + // - " vec4 color;\r\n" + // - " if (factor < u_intervalTimes[0]) {\r\n" + // - " color = mix(u_colors[0], u_colors[1], factor / u_intervalTimes[0]);\r\n" + // - " } else if (factor < u_intervalTimes[0] + u_intervalTimes[1]) {\r\n" + // - " color = u_colors[1];\r\n" + // - " } else {\r\n" + // - " color = mix(u_colors[1], u_colors[2], (factor - u_intervalTimes[0] - u_intervalTimes[1]) / u_intervalTimes[2]);\r\n" - + // - " }\r\n" + // - " vec3 position;\r\n" + // - " if (a_position == 0.0) {\r\n" + // - " v_texcoord = vec2(0.0, 0.0);\r\n" + // - " position = a_p0;\r\n" + // - " } else if (a_position == 1.0) {\r\n" + // - " v_texcoord = vec2(0.0, 1.0);\r\n" + // - " position = a_p1;\r\n" + // - " } else if (a_position == 2.0) {\r\n" + // - " v_texcoord = vec2(1.0, 1.0);\r\n" + // - " position = a_p2;\r\n" + // - " } else if (a_position == 3.0) {\r\n" + // - " v_texcoord = vec2(1.0, 0.0);\r\n" + // - " position = a_p3;\r\n" + // - " }\r\n" + // - " v_color = color / 255.0;\r\n" + // - " gl_Position = u_mvp * vec4(position, 1.0);\r\n" + // - " }\r\n" + // - " void main() {\r\n" + // - " if (u_emitter == EMITTER_PARTICLE2) {\r\n" + // - " particle2();\r\n" + // - " } else if (u_emitter == EMITTER_RIBBON) {\r\n" + // - " ribbon();\r\n" + // - " } else if (u_emitter == EMITTER_SPLAT) {\r\n" + // - " splat();\r\n" + // - " } else if (u_emitter == EMITTER_UBERSPLAT) {\r\n" + // - " ubersplat();\r\n" + // - " }\r\n" + // - " }"; - } - - public static final String fsParticles = "\r\n" + // - " #define EMITTER_RIBBON 1.0\r\n" + // - " uniform sampler2D u_texture;\r\n" + // - " uniform mediump float u_emitter;\r\n" + // - " uniform float u_filterMode;\r\n" + // - " varying vec2 v_texcoord;\r\n" + // - " varying vec4 v_color;\r\n" + // - " void main() {\r\n" + // - " vec4 texel = texture2D(u_texture, v_texcoord);\r\n" + // - " vec4 color = texel * v_color;\r\n" + // - " // 1bit Alpha, used by ribbon emitters.\r\n" + // - " if (u_emitter == EMITTER_RIBBON && u_filterMode == 1.0 && color.a < 0.75) {\r\n" + // - " discard;\r\n" + // - " }\r\n" + // - " gl_FragColor = color;\r\n" + // - " }"; -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxSimpleInstance.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxSimpleInstance.java deleted file mode 100644 index f56d4760..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxSimpleInstance.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.badlogic.gdx.math.Matrix4; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.BatchedInstance; -import com.etheller.warsmash.viewer5.Model; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.RenderBatch; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.Texture; -import com.etheller.warsmash.viewer5.TextureMapper; - -public class MdxSimpleInstance extends BatchedInstance { - public Texture[] replaceableTextures = new Texture[WarsmashConstants.REPLACEABLE_TEXTURE_LIMIT]; - - public MdxSimpleInstance(final Model model) { - super(model); - } - - @Override - public void updateAnimations(final float dt) { - } - - @Override - public void clearEmittedObjects() { - } - - @Override - public void renderOpaque(final Matrix4 mvp) { - } - - @Override - public void renderTranslucent() { - } - - @Override - protected void updateLights(final Scene scene2) { - } - - @Override - protected void removeLights(final Scene scene2) { - } - - @Override - public void load() { - } - - @Override - public RenderBatch getBatch(final TextureMapper textureMapper) { - return new MdxRenderBatch(this.scene, this.model, textureMapper); - } - - @Override - public void setReplaceableTexture(final int replaceableTextureId, final String replaceableTextureFile) { - this.replaceableTextures[replaceableTextureId] = (Texture) this.model.viewer.load(replaceableTextureFile, - PathSolver.DEFAULT, null); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxViewer.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxViewer.java deleted file mode 100644 index 6911611b..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/MdxViewer.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.util.StringBundle; -import com.etheller.warsmash.util.WorldEditStrings; -import com.etheller.warsmash.viewer5.CanvasProvider; -import com.etheller.warsmash.viewer5.SceneLightManager; -import com.etheller.warsmash.viewer5.handlers.AbstractMdxModelViewer; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler.ShaderEnvironmentType; -import com.etheller.warsmash.viewer5.handlers.w3x.W3xScenePortraitLightManager; - -public class MdxViewer extends AbstractMdxModelViewer { - - private final WorldEditStrings worldEditStrings; - private final Vector3 defaultLighting; - - public MdxViewer(final DataSource dataSource, final CanvasProvider canvas, final Vector3 defaultLighting) { - super(dataSource, canvas); - MdxHandler.CURRENT_SHADER_TYPE = ShaderEnvironmentType.MENU; - this.defaultLighting = defaultLighting; - this.worldEditStrings = new WorldEditStrings(this.dataSource); - } - - @Override - public SceneLightManager createLightManager(final boolean simple) { - return new W3xScenePortraitLightManager(this, this.defaultLighting); - } - - @Override - public StringBundle getWorldEditStrings() { - return this.worldEditStrings; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Particle.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Particle.java deleted file mode 100644 index f146e7c2..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Particle.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.badlogic.gdx.math.Quaternion; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.viewer5.EmittedObject; -import com.etheller.warsmash.viewer5.Scene; - -/** - * A spawned model particle. - */ -public class Particle extends EmittedObject { - private static final Quaternion rotationHeap = new Quaternion(); - private static final Quaternion rotationHeap2 = new Quaternion(); - private static final Vector3 velocityHeap = new Vector3(); - private static final float[] latitudeHeap = new float[1]; -// private static final float[] longitudeHeap = new float[1]; - private static final float[] lifeSpanHeap = new float[1]; - private static final float[] gravityHeap = new float[1]; - private static final float[] speedHeap = new float[1]; - private static final float[] tempVector = new float[3]; - - private final MdxComplexInstance internalInstance; - private final Vector3 velocity = new Vector3(); - private float gravity; - - public Particle(final ParticleEmitter emitter) { - super(emitter); - - final ParticleEmitterObject emitterObject = emitter.emitterObject; - - this.internalInstance = (MdxComplexInstance) emitterObject.internalModel.addInstance(); - } - - @Override - protected void bind(final int flags) { - final ParticleEmitter emitter = this.emitter; - final MdxComplexInstance instance = emitter.instance; - final int sequence = instance.sequence; - final int frame = instance.frame; - final int counter = instance.counter; - final Scene scene = instance.scene; - final ParticleEmitterObject emitterObject = emitter.emitterObject; - final MdxNode node = instance.nodes[emitterObject.index]; - final MdxComplexInstance internalInstance = this.internalInstance; - final Vector3 scale = node.worldScale; - final Vector3 velocity = this.velocity; - - emitterObject.getLatitude(latitudeHeap, sequence, frame, counter); - // longitude?? commented in ghostwolf JS - emitterObject.getLifeSpan(lifeSpanHeap, sequence, frame, counter); - emitterObject.getGravity(gravityHeap, sequence, frame, counter); - emitterObject.getSpeed(speedHeap, sequence, frame, counter); - - this.health = lifeSpanHeap[0]; - this.gravity = gravityHeap[0] * scale.z; - - // Local rotation - rotationHeap.idt(); - rotationHeap.mul(rotationHeap2.setFromAxisRad(0, 0, 1, - RenderMathUtils.randomInRange((float) -Math.PI, (float) Math.PI))); - rotationHeap.mul(rotationHeap2.setFromAxisRad(0, 1, 0, - RenderMathUtils.randomInRange(-latitudeHeap[0], latitudeHeap[0]))); - velocity.set(RenderMathUtils.VEC3_UNIT_Z); - rotationHeap.transform(velocity); - - // World rotation - node.worldRotation.transform(velocity); - - // Apply speed - velocity.scl(speedHeap[0]); - - // Apply the parent's scale - velocity.scl(scale); - - scene.addInstance(internalInstance); - - internalInstance.setTransformation(node.worldLocation, rotationHeap.setFromAxisRad(RenderMathUtils.VEC3_UNIT_Z, - RenderMathUtils.randomInRange(0, (float) Math.PI * 2)), node.worldScale); - internalInstance.setSequence(0); - internalInstance.show(); - } - - @Override - public void update(final float dt) { - final MdxComplexInstance internalInstance = this.internalInstance; - - internalInstance.paused = false; /// Why is this here? - - this.health -= dt; - - if (this.health > 0) { - final Vector3 velocity = this.velocity; - - velocity.z -= this.gravity * dt; - - tempVector[0] = velocity.x * dt; - tempVector[1] = velocity.y * dt; - tempVector[2] = velocity.z * dt; - internalInstance.move(tempVector); - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Particle2.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Particle2.java deleted file mode 100644 index 91f5e6fc..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Particle2.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.badlogic.gdx.math.Quaternion; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.viewer5.EmittedObject; - -public class Particle2 extends EmittedObject { - private static final Quaternion HALF_PI_Z = new Quaternion().setFromAxisRad(0, 0, 1, (float) (Math.PI / 2)); - public int tail = 0; - private float gravity = 0; - public final Vector3 location = new Vector3(); - public final Vector3 velocity = new Vector3(); - public final Vector3 scale = new Vector3(1, 1, 1); - - private static final Quaternion rotationHeap = new Quaternion(); - private static final Quaternion rotationHeap2 = new Quaternion(); - private static final float[] widthHeap = new float[1]; - private static final float[] lengthHeap = new float[1]; - private static final float[] latitudeHeap = new float[1]; - private static final float[] variationHeap = new float[1]; - private static final float[] speedHeap = new float[1]; - private static final float[] gravityHeap = new float[1]; - - public Particle2(final ParticleEmitter2 emitter) { - super(emitter); - } - - @Override - protected void bind(final int flags) { - final MdxComplexInstance instance = this.emitter.instance; - final ParticleEmitter2Object emitterObject = this.emitter.emitterObject; - - emitterObject.getWidth(widthHeap, instance.sequence, instance.frame, instance.counter); - emitterObject.getLength(lengthHeap, instance.sequence, instance.frame, instance.counter); - emitterObject.getLatitude(latitudeHeap, instance.sequence, instance.frame, instance.counter); - emitterObject.getVariation(variationHeap, instance.sequence, instance.frame, instance.counter); - emitterObject.getSpeed(speedHeap, instance.sequence, instance.frame, instance.counter); - emitterObject.getGravity(gravityHeap, instance.sequence, instance.frame, instance.counter); - - final MdxNode node = this.emitter.node; - final Vector3 pivot = node.pivot; - final Vector3 scale = node.worldScale; - final float width = widthHeap[0] * 0.5f; - final float length = lengthHeap[0] * 0.5f; - final float latitude = (float) Math.toRadians(latitudeHeap[0]); - final float variation = variationHeap[0]; - final float speed = speedHeap[0]; - final Vector3 location = this.location; - final Vector3 velocity = this.velocity; - - this.health = emitterObject.lifeSpan; - this.tail = flags; - this.gravity = gravityHeap[0] * scale.z; - - this.scale.set(scale); - - // Local location - location.x = pivot.x + RenderMathUtils.randomInRange(-width, width); - location.y = pivot.y + RenderMathUtils.randomInRange(-length, length); - location.z = pivot.z; - - // World location - if (emitterObject.modelSpace == 0) { - location.prj(node.worldMatrix); - } - - // Local rotation - rotationHeap.idt(); - rotationHeap.mul(HALF_PI_Z); - rotationHeap.mul(rotationHeap2.setFromAxisRad(0, 1, 0, RenderMathUtils.randomInRange(-latitude, latitude))); - - // If this is not a line emitter, emit in a sphere rather than a circle - if (emitterObject.lineEmitter == 0) { - rotationHeap.mul(rotationHeap2.setFromAxisRad(1, 0, 0, RenderMathUtils.randomInRange(-latitude, latitude))); - } - - // World rotation - if (emitterObject.modelSpace == 0) { - rotationHeap.mulLeft(node.worldRotation); - } - - // Apply the rotation - velocity.set(RenderMathUtils.VEC3_UNIT_Z); - rotationHeap.transform(velocity); - - // Apply speed - velocity.scl(speed + RenderMathUtils.randomInRange(-variation, variation)); - - // Apply the parent's scale - if (emitterObject.modelSpace == 0) { - velocity.scl(scale); - } - } - - @Override - public void update(final float dt) { - this.health -= dt; - - if (this.health > 0) { - this.velocity.z -= this.gravity * dt; - - this.location.x += this.velocity.x * dt; - this.location.y += this.velocity.y * dt; - this.location.z += this.velocity.z * dt; - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitter.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitter.java deleted file mode 100644 index 7b9f8eba..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitter.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -public class ParticleEmitter extends MdxEmitter { - - private static final float[] emissionRateHeap = new float[1]; - - public ParticleEmitter(final MdxComplexInstance instance, final ParticleEmitterObject emitterObject) { - super(instance, emitterObject); - } - - @Override - protected void updateEmission(final float dt) { - final MdxComplexInstance instance = this.instance; - - if (instance.allowParticleSpawn) { - final ParticleEmitterObject emitterObject = this.emitterObject; - - emitterObject.getEmissionRate(emissionRateHeap, instance.sequence, instance.frame, instance.counter); - - this.currentEmission += emissionRateHeap[0] * dt; - } - } - - @Override - protected void emit() { - this.emitObject(0); - } - - @Override - protected Particle createObject() { - return new Particle(this); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitter2.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitter2.java deleted file mode 100644 index 77b2a306..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitter2.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.util.WarsmashConstants; - -public class ParticleEmitter2 extends MdxEmitter { - private static final float[] emissionRateHeap = new float[1]; - - protected final MdxNode node; - private int lastEmissionKey; - - public ParticleEmitter2(final MdxComplexInstance instance, final ParticleEmitter2Object emitterObject) { - super(instance, emitterObject); - - this.node = instance.nodes[emitterObject.index]; - this.lastEmissionKey = -1; - } - - @Override - protected void updateEmission(final float dt) { - final MdxComplexInstance instance = this.instance; - - if (instance.allowParticleSpawn) { - final ParticleEmitter2Object emitterObject = this.emitterObject; - final int keyframe = emitterObject.getEmissionRate(emissionRateHeap, instance.sequence, instance.frame, - instance.counter); - - if (emitterObject.squirt != 0) { - if (keyframe != this.lastEmissionKey) { - this.currentEmission += emissionRateHeap[0]; - } - - this.lastEmissionKey = keyframe; - } - else { - this.currentEmission += emissionRateHeap[0] * dt * WarsmashConstants.MODEL_DETAIL_PARTICLE_FACTOR; - } - } - } - - @Override - protected void emit() { - if (this.emitterObject.head) { - this.emitObject(0); - } - - if (this.emitterObject.tail) { - this.emitObject(1); - } - - } - - @Override - protected Particle2 createObject() { - return new Particle2(this); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitter2Object.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitter2Object.java deleted file mode 100644 index a7718362..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitter2Object.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.Texture; -import com.etheller.warsmash.viewer5.handlers.EmitterObject; -import com.hiveworkshop.rms.parsers.mdlx.AnimationMap; -import com.hiveworkshop.rms.parsers.mdlx.MdlxParticleEmitter2; -import com.hiveworkshop.rms.parsers.mdlx.MdlxParticleEmitter2.HeadOrTail; - -public class ParticleEmitter2Object extends GenericObject implements EmitterObject { - public float width; - public float length; - public float speed; - public float latitude; - public float gravity; - public float emissionRate; - public long squirt; - public float lifeSpan; - public float variation; - public float tailLength; - public float timeMiddle; - public long columns; - public long rows; - public int teamColored = 0; - public Texture internalTexture; - public long replaceableId; - public boolean head; - public boolean tail; - public float cellWidth; - public float cellHeight; - public float[][] colors; - public float[] scaling; - public float[][] intervals; - public int blendSrc; - public int blendDst; - public int priorityPlane; - - public ParticleEmitter2Object(final MdxModel model, final MdlxParticleEmitter2 emitter, final int index) { - super(model, emitter, index); - - this.width = emitter.getWidth(); - this.length = emitter.getLength(); - this.speed = emitter.getSpeed(); - this.latitude = emitter.getLatitude(); - this.gravity = emitter.getGravity(); - this.emissionRate = emitter.getEmissionRate(); - this.squirt = emitter.getSquirt(); - this.lifeSpan = emitter.getLifeSpan(); - this.variation = emitter.getVariation(); - this.tailLength = emitter.getTailLength(); - this.timeMiddle = emitter.getTimeMiddle(); - - final long replaceableId = emitter.getReplaceableId(); - - this.columns = emitter.getColumns(); - this.rows = emitter.getRows(); - - if (replaceableId == 0) { - this.internalTexture = model.getTextures().get(emitter.getTextureId()); - } - else if ((replaceableId == 1) || (replaceableId == 2)) { - this.teamColored = 1; - } - else { - this.internalTexture = (Texture) model.viewer.load( - "ReplaceableTextures\\" + ReplaceableIds.getPathString(replaceableId) + ".blp", model.pathSolver, - model.solverParams); - } - - this.replaceableId = emitter.getReplaceableId(); - - final HeadOrTail headOrTail = emitter.getHeadOrTail(); - - this.head = headOrTail.isIncludesHead(); - this.tail = headOrTail.isIncludesTail(); - - this.cellWidth = 1f / emitter.getColumns(); - this.cellHeight = 1f / emitter.getRows(); - this.colors = new float[3][0]; - - final float[][] colors = emitter.getSegmentColors(); - final short[] alpha = emitter.getSegmentAlphas(); - - for (int i = 0; i < 3; i++) { - final float[] color = colors[i]; - - this.colors[i] = new float[] { color[0], color[1], color[2], - (alpha[i] / 255f) * WarsmashConstants.MODEL_DETAIL_PARTICLE_FACTOR_INVERSE }; - } - - this.scaling = emitter.getSegmentScaling(); - - final long[][] headIntervals = emitter.getHeadIntervals(); - final long[][] tailIntervals = emitter.getTailIntervals(); - - // Change to Float32Array instead of Uint32Array to be able to pass the - // intervals directly using uniform3fv(). - this.intervals = new float[][] { { headIntervals[0][0], headIntervals[0][1], headIntervals[0][2] }, - { headIntervals[1][0], headIntervals[1][1], headIntervals[1][2] }, - { tailIntervals[0][0], tailIntervals[0][1], tailIntervals[0][2] }, - { tailIntervals[1][0], tailIntervals[1][1], tailIntervals[1][2] }, }; - - final int[] blendModes = FilterMode.emitterFilterMode(emitter.getFilterMode()); - - this.blendSrc = blendModes[0]; - this.blendDst = blendModes[1]; - - this.priorityPlane = emitter.getPriorityPlane(); - } - - public int getWidth(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KP2N.getWar3id(), sequence, frame, counter, this.length); - } - - public int getLength(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KP2W.getWar3id(), sequence, frame, counter, this.width); - } - - public int getSpeed(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KP2S.getWar3id(), sequence, frame, counter, this.speed); - } - - public int getLatitude(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KP2L.getWar3id(), sequence, frame, counter, this.latitude); - } - - public int getGravity(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KP2G.getWar3id(), sequence, frame, counter, this.gravity); - } - - public int getEmissionRate(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KP2E.getWar3id(), sequence, frame, counter, this.emissionRate); - } - - @Override - public int getVisibility(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KP2V.getWar3id(), sequence, frame, counter, 1); - } - - public int getVariation(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KP2R.getWar3id(), sequence, frame, counter, this.variation); - } - - @Override - public boolean ok() { - return true; - } - - @Override - public int getGeometryEmitterType() { - return GeometryEmitterFuncs.EMITTER_PARTICLE2; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitterObject.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitterObject.java deleted file mode 100644 index 66822c18..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ParticleEmitterObject.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.Locale; - -import com.etheller.warsmash.viewer5.handlers.EmitterObject; -import com.hiveworkshop.rms.parsers.mdlx.AnimationMap; -import com.hiveworkshop.rms.parsers.mdlx.MdlxParticleEmitter; - -public class ParticleEmitterObject extends GenericObject implements EmitterObject { - public MdxModel internalModel; - public float speed; - public float latitude; - public float longitude; - public float lifeSpan; - public float gravity; - public float emissionRate; - - /** - * No need to create instances of the internal model if it didn't load. - * - * Such instances won't actually render, and who knows if the model will ever - * load? - */ - public boolean ok = false; - - public ParticleEmitterObject(final MdxModel model, final MdlxParticleEmitter emitter, final int index) { - super(model, emitter, index); - - this.internalModel = (MdxModel) model.viewer.load( - emitter.getPath().replace("\\", "/").toLowerCase(Locale.US).replace(".mdl", ".mdx"), model.pathSolver, - model.solverParams); - this.speed = emitter.getSpeed(); - this.latitude = emitter.getLatitude(); - this.longitude = emitter.getLongitude(); - this.lifeSpan = emitter.getLifeSpan(); - this.gravity = emitter.getGravity(); - this.emissionRate = emitter.getEmissionRate(); - - // Activate emitters based on this emitter object only when and if the internal - // model loads successfully. - // TODO async removed here - this.ok = this.internalModel.ok; - } - - public int getSpeed(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KPES.getWar3id(), sequence, frame, counter, this.speed); - } - - public int getLatitude(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KPLT.getWar3id(), sequence, frame, counter, this.latitude); - } - - public int getLongitude(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KPLN.getWar3id(), sequence, frame, counter, this.longitude); - } - - public int getLifeSpan(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KPEL.getWar3id(), sequence, frame, counter, this.lifeSpan); - } - - public int getGravity(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KPEG.getWar3id(), sequence, frame, counter, this.gravity); - } - - public int getEmissionRate(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KPEE.getWar3id(), sequence, frame, counter, this.emissionRate); - } - - @Override - public int getVisibility(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KPEV.getWar3id(), sequence, frame, counter, 1); - } - - @Override - public int getGeometryEmitterType() { - throw new UnsupportedOperationException("ghostwolf doesnt have this in the JS"); - } - - @Override - public boolean ok() { - return this.ok; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/QuaternionSd.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/QuaternionSd.java deleted file mode 100644 index a50cf961..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/QuaternionSd.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.util.Interpolator; -import com.etheller.warsmash.util.RenderMathUtils; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxTimeline; - -public class QuaternionSd extends Sd { - - public QuaternionSd(final MdxModel model, final MdlxTimeline timeline) { - super(model, timeline, SdArrayDescriptor.FLOAT_ARRAY); - } - - @Override - protected float[] convertDefaultValue(final float[] defaultValue) { - return defaultValue; - } - - @Override - protected void copy(final float[] out, final float[] value) { - System.arraycopy(value, 0, out, 0, value.length); - } - - @Override - protected void interpolate(final float[] out, final float[][] values, final float[][] inTans, - final float[][] outTans, final int start, final int end, final float t) { - Interpolator.interpolateQuaternion(out, values[start], - (start < outTans.length) ? outTans[start] : RenderMathUtils.EMPTY_FLOAT_ARRAY, - (start < inTans.length) ? inTans[end] : RenderMathUtils.EMPTY_FLOAT_ARRAY, values[end], t, - this.interpolationType); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ReplaceableIds.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ReplaceableIds.java deleted file mode 100644 index f62fc99e..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ReplaceableIds.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.HashMap; -import java.util.Map; - -import com.etheller.warsmash.util.WarsmashConstants; - -public class ReplaceableIds { - private static final Map ID_TO_STR = new HashMap<>(); - private static final Map REPLACEABLE_ID_TO_STR = new HashMap<>(); - - static { - for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) { - ID_TO_STR.put(Long.valueOf(i), String.format("%2d", i).replace(' ', '0')); - } - REPLACEABLE_ID_TO_STR.put(Long.valueOf(1), "TeamColor\\TeamColor"); - REPLACEABLE_ID_TO_STR.put(Long.valueOf(2), "TeamGlow\\TeamGlow"); - REPLACEABLE_ID_TO_STR.put(Long.valueOf(11), "Cliff\\Cliff0"); - REPLACEABLE_ID_TO_STR.put(Long.valueOf(21), ""); // Used by all cursor models (HumanCursor, OrcCursor, - // UndeadCursor, NightElfCursor) - REPLACEABLE_ID_TO_STR.put(Long.valueOf(31), "LordaeronTree\\LordaeronSummerTree"); - REPLACEABLE_ID_TO_STR.put(Long.valueOf(32), "AshenvaleTree\\AshenTree"); - REPLACEABLE_ID_TO_STR.put(Long.valueOf(33), "BarrensTree\\BarrensTree"); - REPLACEABLE_ID_TO_STR.put(Long.valueOf(34), "NorthrendTree\\NorthTree"); - REPLACEABLE_ID_TO_STR.put(Long.valueOf(35), "Mushroom\\MushroomTree"); - REPLACEABLE_ID_TO_STR.put(Long.valueOf(36), "RuinsTree\\RuinsTree"); - REPLACEABLE_ID_TO_STR.put(Long.valueOf(37), "OutlandMushroomTree\\MushroomTree"); - } - - public static void main(final String[] args) { - System.out.println(ID_TO_STR); - } - - public static String getIdString(final long replaceableId) { - return ID_TO_STR.get(replaceableId); - } - - public static String getPathString(final long replaceableId) { - return REPLACEABLE_ID_TO_STR.get(replaceableId); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Ribbon.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Ribbon.java deleted file mode 100644 index b05f55d7..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Ribbon.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.viewer5.EmittedObject; - -public class Ribbon extends EmittedObject { - private static final float[] vectorHeap = new float[3]; - private static final Vector3 belowHeap = new Vector3(); - private static final Vector3 aboveHeap = new Vector3(); - private static final float[] colorHeap = new float[3]; - private static final float[] alphaHeap = new float[1]; - private static final long[] slotHeap = new long[1]; - - public float[] vertices = new float[6]; - public byte[] color = new byte[4]; - public int slot; - public Ribbon prev; - public Ribbon next; - - public Ribbon(final RibbonEmitter emitter) { - super(emitter); - } - - @Override - protected void bind(final int flags) { - final RibbonEmitter emitter = this.emitter; - final MdxComplexInstance instance = emitter.instance; - final RibbonEmitterObject emitterObject = emitter.emitterObject; - final MdxNode node = instance.nodes[emitterObject.index]; - final Vector3 pivot = node.pivot; - final float x = pivot.x, y = pivot.y, z = pivot.z; - final Matrix4 worldMatrix = node.worldMatrix; - final float[] vertices = this.vertices; - - this.health = emitter.emitterObject.lifeSpan; - - emitterObject.getHeightBelow(vectorHeap, instance.sequence, instance.frame, instance.counter); - belowHeap.set(vectorHeap); - emitterObject.getHeightAbove(vectorHeap, instance.sequence, instance.frame, instance.counter); - aboveHeap.set(vectorHeap); - - belowHeap.y = y - belowHeap.x; - belowHeap.x = x; - belowHeap.z = z; - - aboveHeap.y = y + aboveHeap.x; - aboveHeap.x = x; - aboveHeap.z = z; - - belowHeap.prj(worldMatrix); - aboveHeap.prj(worldMatrix); - - vertices[0] = aboveHeap.x; - vertices[1] = aboveHeap.y; - vertices[2] = aboveHeap.z; - vertices[3] = belowHeap.x; - vertices[4] = belowHeap.y; - vertices[5] = belowHeap.z; - } - - @Override - public void update(final float dt) { - this.health -= dt; - - if (this.health > 0) { - final RibbonEmitter emitter = this.emitter; - final MdxComplexInstance instance = emitter.instance; - final RibbonEmitterObject emitterObject = emitter.emitterObject; - final byte[] color = this.color; - final float[] vertices = this.vertices; - final float gravity = emitterObject.gravity * dt * dt; - - emitterObject.getColor(colorHeap, instance.sequence, instance.frame, instance.counter); - emitterObject.getAlpha(alphaHeap, instance.sequence, instance.frame, instance.counter); - emitterObject.getTextureSlot(slotHeap, instance.sequence, instance.frame, instance.counter); - - vertices[1] -= gravity; - vertices[4] -= gravity; - - color[0] = (byte) (colorHeap[0] * 255); - color[1] = (byte) (colorHeap[1] * 255); - color[2] = (byte) (colorHeap[2] * 255); - color[3] = (byte) (alphaHeap[0] * 255); - - this.slot = (int) slotHeap[0]; - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/RibbonEmitter.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/RibbonEmitter.java deleted file mode 100644 index e815f218..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/RibbonEmitter.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -public class RibbonEmitter extends MdxEmitter { - public Ribbon first; - public Ribbon last; - - public RibbonEmitter(final MdxComplexInstance instance, final RibbonEmitterObject emitterObject) { - super(instance, emitterObject); - } - - @Override - protected void updateEmission(final float dt) { - final MdxComplexInstance instance = this.instance; - - if (instance.allowParticleSpawn) { - final RibbonEmitterObject emitterObject = this.emitterObject; - - // It doesn't make sense to emit more than 1 ribbon at the same time. - this.currentEmission = Math.min(this.currentEmission + (emitterObject.emissionRate * dt), 1); - } - - } - - @Override - protected void emit() { - final Ribbon ribbon = this.emitObject(0); - final Ribbon last = this.last; - - if (last != null) { - last.next = ribbon; - ribbon.prev = last; - } - else { - this.first = ribbon; - } - - this.last = ribbon; - } - - @Override - public void kill(final Ribbon object) { - super.kill(object); - - final Ribbon prev = object.prev; - final Ribbon next = object.next; - - if (object == this.first) { - this.first = next; - } - - if (object == this.last) { - this.first = null; - this.last = null; - } - - if (prev != null) { - prev.next = next; - } - - if (next != null) { - next.prev = prev; - } - - object.prev = null; - object.next = null; - } - - @Override - protected Ribbon createObject() { - return new Ribbon(this); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/RibbonEmitterObject.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/RibbonEmitterObject.java deleted file mode 100644 index ef18c469..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/RibbonEmitterObject.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.viewer5.handlers.EmitterObject; -import com.hiveworkshop.rms.parsers.mdlx.AnimationMap; -import com.hiveworkshop.rms.parsers.mdlx.MdlxRibbonEmitter; - -public class RibbonEmitterObject extends GenericObject implements EmitterObject { - public Layer layer; - public float heightAbove; - public float heightBelow; - public float alpha; - public float[] color; - public float lifeSpan; - public long textureSlot; - public long emissionRate; - public float gravity; - public long columns; - public long rows; - /** - * Even if the internal texture isn't loaded, it's fine to run emitters based on - * this emitter object. - * - * The ribbons will simply be black. - */ - public boolean ok = true; - - public RibbonEmitterObject(final MdxModel model, final MdlxRibbonEmitter emitter, final int index) { - super(model, emitter, index); - - this.layer = model.getMaterials().get(emitter.getMaterialId()).layers.get(0); - this.heightAbove = emitter.getHeightAbove(); - this.heightBelow = emitter.getHeightBelow(); - this.alpha = emitter.getAlpha(); - this.color = emitter.getColor(); - this.lifeSpan = emitter.getLifeSpan(); - this.textureSlot = emitter.getTextureSlot(); - this.emissionRate = emitter.getEmissionRate(); - this.gravity = emitter.getGravity(); - this.columns = emitter.getColumns(); - this.rows = emitter.getRows(); - } - - public int getHeightBelow(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KRHB.getWar3id(), sequence, frame, counter, this.heightBelow); - } - - public int getHeightAbove(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KRHA.getWar3id(), sequence, frame, counter, this.heightAbove); - } - - public int getTextureSlot(final long[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KRTX.getWar3id(), sequence, frame, counter, 0); - } - - public int getColor(final float[] out, final int sequence, final int frame, final int counter) { - return this.getVectorValue(out, AnimationMap.KRCO.getWar3id(), sequence, frame, counter, this.color); - } - - public int getAlpha(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KRAL.getWar3id(), sequence, frame, counter, this.alpha); - } - - @Override - public int getVisibility(final float[] out, final int sequence, final int frame, final int counter) { - return this.getScalarValue(out, AnimationMap.KRVS.getWar3id(), sequence, frame, counter, 1f); - } - - @Override - public int getGeometryEmitterType() { - return GeometryEmitterFuncs.EMITTER_RIBBON; - } - - @Override - public boolean ok() { - return this.ok; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ScalarSd.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ScalarSd.java deleted file mode 100644 index 5ea50364..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/ScalarSd.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.util.RenderMathUtils; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxTimeline; - -public class ScalarSd extends Sd { - - public ScalarSd(final MdxModel model, final MdlxTimeline timeline) { - super(model, timeline, SdArrayDescriptor.FLOAT_ARRAY); - } - - @Override - protected float[] convertDefaultValue(final float[] defaultValue) { - return defaultValue; - } - - @Override - protected void copy(final float[] out, final float[] value) { - out[0] = value[0]; - } - - @Override - protected void interpolate(final float[] out, final float[][] values, final float[][] inTans, - final float[][] outTans, final int start, final int end, final float t) { - final float startValue = values[start][0]; - - switch (this.interpolationType) { - case 0: - out[0] = startValue; - break; - case 1: - out[0] = RenderMathUtils.lerp(startValue, values[end][0], t); - break; - case 2: - out[0] = RenderMathUtils.hermite(startValue, (start < outTans.length) ? outTans[start][0] : 0f, - (start < inTans.length) ? inTans[end][0] : 0f, values[end][0], t); - break; - case 3: - out[0] = RenderMathUtils.bezier(startValue, (start < outTans.length) ? outTans[start][0] : 0f, - (start < inTans.length) ? inTans[end][0] : 0f, values[end][0], t); - break; - } - - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Sd.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Sd.java deleted file mode 100644 index baf09f64..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Sd.java +++ /dev/null @@ -1,149 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.etheller.warsmash.util.War3ID; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxTimeline; - -public abstract class Sd { - public MdxModel model; - public int interpolationType; - public War3ID name; - public TYPE defval; - public SdSequence globalSequence; - public List> sequences; - - public static Map forcedInterpMap = new HashMap<>(); - - static { - forcedInterpMap.put(War3ID.fromString("KLAV"), 0); - forcedInterpMap.put(War3ID.fromString("KATV"), 0); - forcedInterpMap.put(War3ID.fromString("KPEV"), 0); - forcedInterpMap.put(War3ID.fromString("KP2V"), 0); - forcedInterpMap.put(War3ID.fromString("KRVS"), 0); - } - - public static Map defVals = new HashMap<>(); - - static { - // LAYS - defVals.put(War3ID.fromString("KMTF"), new float[] { 0 }); - defVals.put(War3ID.fromString("KMTA"), new float[] { 1 }); - // TXAN - defVals.put(War3ID.fromString("KTAT"), new float[] { 0, 0, 0 }); - defVals.put(War3ID.fromString("KTAR"), new float[] { 0, 0, 0, 1 }); - defVals.put(War3ID.fromString("KTAS"), new float[] { 1, 1, 1 }); - // GEOA - defVals.put(War3ID.fromString("KGAO"), new float[] { 1 }); - defVals.put(War3ID.fromString("KGAC"), new float[] { 0, 0, 0 }); - // LITE - defVals.put(War3ID.fromString("KLAS"), new float[] { 0 }); - defVals.put(War3ID.fromString("KLAE"), new float[] { 0 }); - defVals.put(War3ID.fromString("KLAC"), new float[] { 0, 0, 0 }); - defVals.put(War3ID.fromString("KLAI"), new float[] { 0 }); - defVals.put(War3ID.fromString("KLBI"), new float[] { 0 }); - defVals.put(War3ID.fromString("KLBC"), new float[] { 0, 0, 0 }); - defVals.put(War3ID.fromString("KLAV"), new float[] { 1 }); - // ATCH - defVals.put(War3ID.fromString("KATV"), new float[] { 1 }); - // PREM - defVals.put(War3ID.fromString("KPEE"), new float[] { 0 }); - defVals.put(War3ID.fromString("KPEG"), new float[] { 0 }); - defVals.put(War3ID.fromString("KPLN"), new float[] { 0 }); - defVals.put(War3ID.fromString("KPLT"), new float[] { 0 }); - defVals.put(War3ID.fromString("KPEL"), new float[] { 0 }); - defVals.put(War3ID.fromString("KPES"), new float[] { 0 }); - defVals.put(War3ID.fromString("KPEV"), new float[] { 1 }); - // PRE2 - defVals.put(War3ID.fromString("KP2S"), new float[] { 0 }); - defVals.put(War3ID.fromString("KP2R"), new float[] { 0 }); - defVals.put(War3ID.fromString("KP2L"), new float[] { 0 }); - defVals.put(War3ID.fromString("KP2G"), new float[] { 0 }); - defVals.put(War3ID.fromString("KP2E"), new float[] { 0 }); - defVals.put(War3ID.fromString("KP2N"), new float[] { 0 }); - defVals.put(War3ID.fromString("KP2W"), new float[] { 0 }); - defVals.put(War3ID.fromString("KP2V"), new float[] { 1 }); - // RIBB - defVals.put(War3ID.fromString("KRHA"), new float[] { 0 }); - defVals.put(War3ID.fromString("KRHB"), new float[] { 0 }); - defVals.put(War3ID.fromString("KRAL"), new float[] { 1 }); - defVals.put(War3ID.fromString("KRCO"), new float[] { 0, 0, 0 }); - defVals.put(War3ID.fromString("KRTX"), new float[] { 0 }); - defVals.put(War3ID.fromString("KRVS"), new float[] { 1 }); - // CAMS - defVals.put(War3ID.fromString("KCTR"), new float[] { 0, 0, 0 }); - defVals.put(War3ID.fromString("KTTR"), new float[] { 0, 0, 0 }); - defVals.put(War3ID.fromString("KCRL"), new float[] { 0 }); - // NODE - defVals.put(War3ID.fromString("KGTR"), new float[] { 0, 0, 0 }); - defVals.put(War3ID.fromString("KGRT"), new float[] { 0, 0, 0, 1 }); - defVals.put(War3ID.fromString("KGSC"), new float[] { 1, 1, 1 }); - - } - - public Sd(final MdxModel model, final MdlxTimeline timeline, final SdArrayDescriptor arrayDescriptor) { - final List globalSequences = model.getGlobalSequences(); - final int globalSequenceId = timeline.getGlobalSequenceId(); - final Integer forcedInterp = forcedInterpMap.get(timeline.getName()); - - this.model = model; - this.name = timeline.getName(); - this.defval = convertDefaultValue(defVals.get(timeline.getName())); - this.globalSequence = null; - this.sequences = new ArrayList<>(); - - // Allow to force an interpolation type. - // The game seems to do this with visibility tracks, where the type is - // forced to None. - // It came up as a bug report by a user who used the wrong interpolation - // type. - this.interpolationType = forcedInterp != null ? forcedInterp : timeline.getInterpolationType().ordinal(); - - if ((globalSequenceId != -1) && (globalSequences.size() > 0)) { - this.globalSequence = new SdSequence(this, 0, globalSequences.get(globalSequenceId).longValue(), - timeline, true, arrayDescriptor); - } - else { - for (final Sequence sequence : model.getSequences()) { - final long[] interval = sequence.getInterval(); - - this.sequences - .add(new SdSequence(this, interval[0], interval[1], timeline, false, arrayDescriptor)); - } - } - } - - public int getValue(final TYPE out, final int sequence, final int frame, final int counter) { - if (this.globalSequence != null) { - return this.globalSequence.getValue(out, - this.globalSequence.end == 0 ? 0 : counter % this.globalSequence.end); - } - else if ((sequence != -1) && (this.sequences.size() > sequence)) { - return this.sequences.get(sequence).getValue(out, frame); - } - else { - this.copy(out, this.defval); - - return -1; - } - } - - public boolean isVariant(final int sequence) { - if (this.globalSequence != null) { - return !this.globalSequence.constant; - } - else { - return !this.sequences.get(sequence).constant; - } - } - - protected abstract TYPE convertDefaultValue(float[] defaultValue); - - protected abstract void copy(TYPE out, TYPE value); - - protected abstract void interpolate(TYPE out, TYPE[] values, TYPE[] inTans, TYPE[] outTans, int start, int end, - float t); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SdArrayDescriptor.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SdArrayDescriptor.java deleted file mode 100644 index ff20f4b2..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SdArrayDescriptor.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -public interface SdArrayDescriptor { - SdArrayDescriptor GENERIC = new SdArrayDescriptor() { - @Override - public Object[] create(final int size) { - return new Object[size]; - } - }; - SdArrayDescriptor FLOAT_ARRAY = new SdArrayDescriptor() { - @Override - public float[][] create(final int size) { - return new float[size][]; - } - }; - SdArrayDescriptor LONG_ARRAY = new SdArrayDescriptor() { - @Override - public long[][] create(final int size) { - return new long[size][]; - } - }; - - TYPE[] create(int size); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SdSequence.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SdSequence.java deleted file mode 100644 index 5ec445c0..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SdSequence.java +++ /dev/null @@ -1,224 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.ArrayList; -import java.util.Arrays; - -import com.etheller.warsmash.util.ParseUtils; -import com.hiveworkshop.rms.parsers.mdlx.AnimationMap; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxTimeline; - -public final class SdSequence { - private static boolean INJECT_FRAMES_GHOSTWOLF_STYLE = false; - - private final Sd sd; - public final long start; // UInt32 - public final long end; // UInt32 - public long[] frames; - public TYPE[] values; - public TYPE[] inTans; - public TYPE[] outTans; - public boolean constant; - - public SdSequence(final Sd sd, final long start, final long end, final MdlxTimeline timeline, - final boolean isGlobalSequence, final SdArrayDescriptor arrayDescriptor) { - this.sd = sd; - this.start = start; - this.end = end; - final ArrayList framesBuilder = new ArrayList<>(); - final ArrayList valuesBuilder = new ArrayList<>(); - final ArrayList inTansBuilder = new ArrayList<>(); - final ArrayList outTansBuilder = new ArrayList<>(); - this.constant = false; - - final int interpolationType = sd.interpolationType; - final long[] frames = timeline.getFrames(); - final TYPE[] values = getValues(timeline); - final TYPE[] inTans = getInTans(timeline); - final TYPE[] outTans = getOutTans(timeline); - final TYPE defval = sd.defval; - - // When using a global sequence, where the first key is outside of the - // sequence's length, it becomes its constant value. - // When having one key in the sequence's range, and one key outside of - // it, results seem to be non-deterministic. - // Sometimes the second key is used too, sometimes not. - // It also differs depending where the model is viewed - the WE - // previewer, the WE itself, or the game. - // All three show different results, none of them make sense. - // Therefore, only handle the case where the first key is outside. - // This fixes problems spread over many models, e.g. HeroMountainKing - // (compare in WE and in Magos). - if (isGlobalSequence && (frames.length > 0) && (frames[0] > end)) { - if (start == end) { - framesBuilder.add(start); - } - else { - framesBuilder.add(frames[0]); - } - valuesBuilder.add(values[0]); - } - - // Go over the keyframes, and add all of the ones that are in this - // sequence (start <= frame <= end). - for (int i = 0, l = frames.length; i < l; i++) { - final long frame = frames[i]; - - if ((frame >= start) && (frame <= end)) { - framesBuilder.add(frame); - valuesBuilder.add(values[i]); - - if (interpolationType > 1) { - inTansBuilder.add(inTans[i]); - outTansBuilder.add(outTans[i]); - } - } - } - - final int keyframeCount = framesBuilder.size(); - - if (keyframeCount == 0) { - // if there are no keys, use the default value directly. - this.constant = true; - framesBuilder.add(start); - valuesBuilder.add(defval); - } - else if (keyframeCount == 1) { - // If there's only one key, use it directly - this.constant = true; - } - else { - final TYPE firstValue = valuesBuilder.get(0); - - // If all of the values in this sequence are the same, might as well - // make it constant. - boolean allFramesMatch = true; - for (final TYPE value : valuesBuilder) { - if (!equals(firstValue, value)) { - allFramesMatch = false; - } - } - this.constant = allFramesMatch; - - if (!this.constant && INJECT_FRAMES_GHOSTWOLF_STYLE) { - // If there is no opening keyframe for this sequence, inject one - // with the default value. - final boolean hasStart = framesBuilder.get(0) == start; - if (!hasStart) { - framesBuilder.add(start); - valuesBuilder.add(defval); - - if (interpolationType > 1) { - inTansBuilder.add(defval); - outTansBuilder.add(defval); - } - } - - // If there is no closing keyframe for this sequence, inject one - // with the default value. - if (framesBuilder.get(framesBuilder.size() - 1) != end) { - framesBuilder.add(end); - final int sourceIndex = hasStart ? 0 : (valuesBuilder.size() - 1); - valuesBuilder.add(valuesBuilder.get(sourceIndex)); - - if (interpolationType > 1) { - inTansBuilder.add(inTansBuilder.get(sourceIndex)); - outTansBuilder.add(outTansBuilder.get(sourceIndex)); - } - } - } - } - this.frames = new long[framesBuilder.size()]; - for (int i = 0; i < framesBuilder.size(); i++) { - this.frames[i] = framesBuilder.get(i); - } - this.values = valuesBuilder.toArray(arrayDescriptor.create(valuesBuilder.size())); - this.inTans = inTansBuilder.toArray(arrayDescriptor.create(inTansBuilder.size())); - this.outTans = outTansBuilder.toArray(arrayDescriptor.create(outTansBuilder.size())); - } - - private TYPE[] getValues(final MdlxTimeline timeline) { - final TYPE[] values = timeline.getValues(); - return fixTimelineArray(timeline, values); - } - - private TYPE[] getOutTans(final MdlxTimeline timeline) { - final TYPE[] outTans = timeline.getOutTans(); - return fixTimelineArray(timeline, outTans); - } - - private TYPE[] getInTans(final MdlxTimeline timeline) { - final TYPE[] inTans = timeline.getInTans(); - return fixTimelineArray(timeline, inTans); - } - - private TYPE[] fixTimelineArray(final MdlxTimeline timeline, final TYPE[] values) { - if (values == null) { - return null; - } - if (timeline.getName().equals(AnimationMap.KLAC.getWar3id()) - || timeline.getName().equals(AnimationMap.KLBC.getWar3id())) { - final float[][] flippedColorData = new float[values.length][3]; - for (int i = 0; i < values.length; i++) { - flippedColorData[i] = ParseUtils.newFlippedRGB((float[]) values[i]); - } - return (TYPE[]) flippedColorData; - } - return values; - } - - public int getValue(final TYPE out, final long frame) { - final int length = this.frames.length; - - if (this.constant || (frame < this.start)) { - this.sd.copy(out, this.values[0]); - - return -1; - } - else { - int startFrameIndex = -1; - int endFrameIndex = -1; - final int lengthLessOne = length - 1; - if ((frame < this.frames[0]) || (frame >= this.frames[lengthLessOne])) { - startFrameIndex = lengthLessOne; - endFrameIndex = 0; - } - else { - for (int i = 1; i < length; i++) { - if (this.frames[i] > frame) { - startFrameIndex = i - 1; - endFrameIndex = i; - break; - } - } - } - long startFrame = this.frames[startFrameIndex]; - final long endFrame = this.frames[endFrameIndex]; - long timeBetweenFrames = endFrame - startFrame; - if (timeBetweenFrames < 0) { - timeBetweenFrames += (this.end - this.start); - if (frame < startFrame) { - startFrame = endFrame; - } - } - final float t = ((timeBetweenFrames) == 0 ? 0 : ((frame - startFrame) / (float) (timeBetweenFrames))); - this.sd.interpolate(out, this.values, this.inTans, this.outTans, startFrameIndex, endFrameIndex, t); - return startFrameIndex; - } - } - - protected final boolean equals(final TYPE a, final TYPE b) { - if ((a instanceof Float) && (b instanceof Float)) { - return a.equals(b); - } - else if ((a instanceof Long) && (b instanceof Long)) { - return a.equals(b); - } - else if ((a instanceof float[]) && (b instanceof float[])) { - return Arrays.equals(((float[]) a), (float[]) b); - } - else if ((a instanceof long[]) && (b instanceof long[])) { - return Arrays.equals(((long[]) a), (long[]) b); - } - return false; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Sequence.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Sequence.java deleted file mode 100644 index d3b916a9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/Sequence.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.Bounds; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.SecondaryTag; -import com.hiveworkshop.rms.parsers.mdlx.MdlxExtent; -import com.hiveworkshop.rms.parsers.mdlx.MdlxSequence; - -public class Sequence { - private final MdlxSequence sequence; - private final Bounds bounds; - private final EnumSet primaryTags = EnumSet.noneOf(AnimationTokens.PrimaryTag.class); - private final EnumSet secondaryTags = EnumSet - .noneOf(AnimationTokens.SecondaryTag.class); - - public Sequence(final MdlxSequence sequence) { - this.sequence = sequence; - this.bounds = new Bounds(); - final MdlxExtent sequenceExtent = sequence.getExtent(); - this.bounds.fromExtents(sequenceExtent.getMin(), sequenceExtent.getMax(), sequenceExtent.getBoundsRadius()); - populateTags(); - } - - private void populateTags() { - this.primaryTags.clear(); - this.secondaryTags.clear(); - TokenLoop: for (final String token : this.sequence.name.split("\\s+")) { - final String upperCaseToken = token.toUpperCase(); - for (final PrimaryTag primaryTag : PrimaryTag.values()) { - if (upperCaseToken.equals(primaryTag.name())) { - this.primaryTags.add(primaryTag); - continue TokenLoop; - } - } - for (final SecondaryTag secondaryTag : SecondaryTag.values()) { - if (upperCaseToken.equals(secondaryTag.name())) { - this.secondaryTags.add(secondaryTag); - continue TokenLoop; - } - } - break; - } - } - - public String getName() { - return this.sequence.getName(); - } - - public long[] getInterval() { - return this.sequence.getInterval(); - } - - public float getMoveSpeed() { - return this.sequence.getMoveSpeed(); - } - - public int getFlags() { - return this.sequence.getFlags(); - } - - public float getRarity() { - return this.sequence.getRarity(); - } - - public long getSyncPoint() { - return this.sequence.getSyncPoint(); - } - - public Bounds getBounds() { - return this.bounds; - } - - public MdlxExtent getExtent() { - return this.sequence.getExtent(); - } - - public EnumSet getPrimaryTags() { - return this.primaryTags; - } - - public EnumSet getSecondaryTags() { - return this.secondaryTags; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SequenceLoopMode.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SequenceLoopMode.java deleted file mode 100644 index 16c249a9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SequenceLoopMode.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -public enum SequenceLoopMode { - NEVER_LOOP, - MODEL_LOOP, - ALWAYS_LOOP, - NEVER_LOOP_AND_HIDE_WHEN_DONE, // used by spawned effects - LOOP_TO_NEXT_ANIMATION; // used by the Arthas vs Illidan tech demo -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SetupGeosets.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SetupGeosets.java deleted file mode 100644 index 76485b28..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SetupGeosets.java +++ /dev/null @@ -1,208 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.badlogic.gdx.graphics.GL20; -import com.etheller.warsmash.util.RenderMathUtils; -import com.hiveworkshop.rms.parsers.mdlx.MdlxGeoset; - -public class SetupGeosets { - private static final int NORMAL_BATCH = 0; - private static final int EXTENDED_BATCH = 1; - private static final int REFORGED_BATCH = 2; - - public static void setupGeosets(final MdxModel model, final List geosets, final boolean bigNodeSpace) { - if (geosets.size() > 0) { - final GL20 gl = model.viewer.gl; - int positionBytes = 0; - int normalBytes = 0; - int uvBytes = 0; - int skinBytes = 0; - int faceBytes = 0; - final int[] batchTypes = new int[geosets.size()]; - - final int extendedBatchStride = bigNodeSpace ? 36 : 9; - final int normalBatchStride = bigNodeSpace ? 20 : 5; - final int openGLSkinType = bigNodeSpace ? GL20.GL_UNSIGNED_INT : GL20.GL_UNSIGNED_BYTE; - final int normalBatchBoneCountOffsetBytes = bigNodeSpace ? 16 : 4; - final int extendedBatchBoneCountOffsetBytes = bigNodeSpace ? 32 : 8; - - for (int i = 0, l = geosets.size(); i < l; i++) { - final MdlxGeoset geoset = geosets.get(i); - - if (true /* geoset.getLod() == 0 */) { - final int vertices = geoset.getVertices().length / 3; - - positionBytes += vertices * 12; - normalBytes += vertices * 12; - uvBytes += geoset.getUvSets().length * vertices * 8; - - if (false /* geoset.skin.length */) { - skinBytes += vertices * 8; - - batchTypes[i] = REFORGED_BATCH; - } - else { - long biggestGroup = 0; - - for (final long group : geoset.getMatrixGroups()) { - if (group > biggestGroup) { - biggestGroup = group; - } - } - - if (biggestGroup > 4) { - skinBytes += vertices * extendedBatchStride; - - batchTypes[i] = EXTENDED_BATCH; - } - else { - skinBytes += vertices * normalBatchStride; - - batchTypes[i] = NORMAL_BATCH; - } - } - - faceBytes += geoset.getFaces().length * 2; - } - } - - int positionOffset = 0; - int normalOffset = positionOffset + positionBytes; - int uvOffset = normalOffset + normalBytes; - int skinOffset = uvOffset + uvBytes; - int faceOffset = 0; - - model.arrayBuffer = gl.glGenBuffer(); - gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, model.arrayBuffer); - gl.glBufferData(GL20.GL_ARRAY_BUFFER, skinOffset + skinBytes, null, GL20.GL_STATIC_DRAW); - - model.elementBuffer = gl.glGenBuffer(); - gl.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, model.elementBuffer); - gl.glBufferData(GL20.GL_ELEMENT_ARRAY_BUFFER, faceBytes, null, GL20.GL_STATIC_DRAW); - - for (int i = 0, l = geosets.size(); i < l; i++) { - final MdlxGeoset geoset = geosets.get(i); - - final int batchType = batchTypes[i]; - if (true /* geoset.lod == 0 */) { - final float[] positions = geoset.getVertices(); - final float[] normals = geoset.getNormals(); - final float[][] uvSets = geoset.getUvSets(); - final int[] faces = geoset.getFaces(); - int[] skin = null; - final int vertices = geoset.getVertices().length / 3; - - int maxBones; - int skinStride; - int boneCountOffsetBytes; - if (batchType == EXTENDED_BATCH) { - maxBones = 8; - skinStride = extendedBatchStride; - boneCountOffsetBytes = extendedBatchBoneCountOffsetBytes; - } - else { - maxBones = 4; - skinStride = normalBatchStride; - boneCountOffsetBytes = normalBatchBoneCountOffsetBytes; - } - - if (batchType == REFORGED_BATCH) { - // skin = geoset.skin; // THIS IS NOT IMPLEMENTED - } - else { - final long[] matrixIndices = geoset.getMatrixIndices(); - final short[] vertexGroups = geoset.getVertexGroups(); - final List matrixGroups = new ArrayList<>(); - int offset = 0; - // Normally the shader supports up to 4 bones per vertex. - // This is enough for almost every existing Warcraft 3 model. - // That being said, there are a few models with geosets that need more, for - // example the Water Elemental. - // These geosets use a different shader, which support up to 8 bones per vertex. - - skin = new int[vertices * (maxBones + 1)]; - - // Slice the matrix groups - for (final long size : geoset.getMatrixGroups()) { - matrixGroups.add(Arrays.copyOfRange(matrixIndices, offset, (int) (offset + size))); - offset += size; - } - - // Parse the skinning. - for (int si = 0; si < vertices; si++) { - final short vertexGroup = vertexGroups[si]; - final long[] matrixGroup = (vertexGroup >= matrixGroups.size()) ? null - : matrixGroups.get(vertexGroup); - - offset = si * (maxBones + 1); - - // Somehow in some bad models a vertex group index refers to an invalid matrix - // group. - // Such models are still loaded by the game. - if (matrixGroup != null) { - final int bones = Math.min(matrixGroup.length, maxBones); - - for (int j = 0; j < bones; j++) { - skin[offset + j] = (int) (matrixGroup[j] + 1); // 1 is added to diffrentiate - // between matrix 0, and no matrix. - } - - skin[offset + maxBones] = bones; - } - } - } - - final boolean unselectable = geoset.getSelectionFlags() == 4; - final Geoset vGeoset = new Geoset(model, model.getGeosets().size(), positionOffset, normalOffset, - uvOffset, skinOffset, faceOffset, vertices, faces.length, openGLSkinType, skinStride, - boneCountOffsetBytes, unselectable, geoset); - - model.getGeosets().add(vGeoset); - - if (batchType == REFORGED_BATCH) { - throw new UnsupportedOperationException("NYI"); -// model.batches.add(new Reforged) - } - else { - final boolean isExtended = batchType == EXTENDED_BATCH; - - for (final Layer layer : model.getMaterials().get((int) geoset.getMaterialId()).layers) { - model.batches.add(new Batch(model.batches.size(), vGeoset, layer, isExtended)); - } - } - - // Positions. - gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, positionOffset, positions.length, - RenderMathUtils.wrap(positions)); - positionOffset += positions.length * 4; - - // Normals. - gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, normalOffset, normals.length, - RenderMathUtils.wrap(normals)); - normalOffset += normals.length * 4; - - // Texture coordinates. - for (final float[] uvSet : uvSets) { - gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, uvOffset, uvSet.length, RenderMathUtils.wrap(uvSet)); - uvOffset += uvSet.length * 4; - } - - // Skin. - gl.glBufferSubData(GL20.GL_ARRAY_BUFFER, skinOffset, skin.length, - bigNodeSpace ? RenderMathUtils.wrap(skin) : RenderMathUtils.wrapAsBytes(skin)); - skinOffset += skin.length * (bigNodeSpace ? 4 : 1); - - // Faces. - gl.glBufferSubData(GL20.GL_ELEMENT_ARRAY_BUFFER, faceOffset, faces.length, - RenderMathUtils.wrapFaces(faces)); - faceOffset += faces.length * 2; - } - - } - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SetupGroups.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SetupGroups.java deleted file mode 100644 index 58f0bca9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SetupGroups.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import com.etheller.warsmash.viewer5.handlers.EmitterObject; - -public class SetupGroups { - public static int getPrio(final Batch object) { - return object.layer.priorityPlane; - } - - public static int getPrio(final ParticleEmitter2Object object) { - return object.priorityPlane; - } - - public static int getPrio(final RibbonEmitterObject object) { - return object.layer.priorityPlane; - } - - public static int getPrio(final Object object) { - if (object instanceof Batch) { - return getPrio((Batch) object); - } - else if (object instanceof RibbonEmitterObject) { - return getPrio((RibbonEmitterObject) object); - } - else if (object instanceof ParticleEmitter2Object) { - return getPrio((ParticleEmitter2Object) object); - } - else { - throw new IllegalArgumentException(object.getClass().getName()); - } - } - - public static boolean matchingGroup(final Object group, final Object object) { - if (group instanceof BatchGroup) { - return (object instanceof Batch) && (((Batch) object).isExtended == ((BatchGroup) group).isExtended); -// } else if(group instanceof ReforgedBatch) { TODO -// return (object instanceof ReforgedBatch) && (object.material.shader === group.shader); - } - else { - // All of the emitter objects are generic objects. - return (object instanceof GenericObject); - } - } - - public static GenericGroup createMatchingGroup(final MdxModel model, final Object object) { - if (object instanceof Batch) { - return new BatchGroup(model, ((Batch) object).isExtended); -// } else if(object instanceof ReforgedBatch) { TODO -// return new ReforgedBatchGroup(model, ((ReforgedBatch)object).material.shader); - } - else { - return new EmitterGroup(model); - } - } - - public static void setupGroups(final MdxModel model) { - final List opaqueBatches = new ArrayList<>(); - final List translucentBatches = new ArrayList<>(); - - for (final Batch batch : model.batches) {// TODO reforged - if (/* batch instanceof ReforgedBatch || */batch.layer.filterMode < 2) { - opaqueBatches.add(batch); - } - else { - translucentBatches.add(batch); - } - } - - final List opaqueGroups = model.opaqueGroups; - final List translucentGroups = model.translucentGroups; - GenericGroup currentGroup = null; - - for (final Batch object : opaqueBatches) { - if ((currentGroup == null) || !matchingGroup(currentGroup, object)) { - currentGroup = createMatchingGroup(model, object); - - opaqueGroups.add(currentGroup); - } - - final int index = object.index; - currentGroup.objects.add(index); - } - - // Sort between all of the translucent batches and emitters that have priority - // planes - final List sorted = new ArrayList<>(); - sorted.addAll(translucentBatches); - sorted.addAll(model.particleEmitters2); - sorted.addAll(model.ribbonEmitters); - Collections.sort(sorted, new Comparator() { - @Override - public int compare(final Object o1, final Object o2) { - return getPrio(o1) - getPrio(o2); - } - }); - - // Event objects have no priority planes, so they might as well always be last. - final List objects = new ArrayList<>(); - objects.addAll(sorted); - objects.addAll(model.eventObjects); - - currentGroup = null; - - for (final Object object : objects) { // TODO reforged - if ((object instanceof Batch /* || object instanceof ReforgedBatch */) - || (object instanceof EmitterObject)) { - if ((currentGroup == null) || !matchingGroup(currentGroup, object)) { - currentGroup = createMatchingGroup(model, object); - - translucentGroups.add(currentGroup); - } - - final int index = ((GenericIndexed) object).getIndex(); - currentGroup.objects.add(index); - } - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SetupSimpleGroups.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SetupSimpleGroups.java deleted file mode 100644 index ebb45ce9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/SetupSimpleGroups.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import java.util.List; - -public class SetupSimpleGroups { - private static final float[] alphaHeap = new float[1]; - - public static boolean isBatchSimple(final Batch batch) { - final GeosetAnimation geosetAnimation = batch.geoset.geosetAnimation; - - if (geosetAnimation != null) { - geosetAnimation.getAlpha(alphaHeap, 0, 0, 0); - - if (alphaHeap[0] <= 0.01) { - return false; - } - } - - Layer layer; - - if (batch instanceof Batch) { - layer = batch.layer; - } - else { - throw new IllegalStateException("reforged?"); // TODO -// layer = batch.material.layers[0]; - } - - layer.getAlpha(alphaHeap, 0, 0, 0); - - if (alphaHeap[0] < 0.01) { - return false; - } - - return true; - } - - public static void setupSimpleGroups(final MdxModel model) { - final List batches = model.batches; - final List simpleGroups = model.simpleGroups; - - for (final GenericGroup group : model.opaqueGroups) { - GenericGroup simpleGroup; - - if (group instanceof BatchGroup) { - simpleGroup = new BatchGroup(model, ((BatchGroup) group).isExtended); - } - else { - throw new IllegalStateException("reforged?"); // TODO - // simpleGroup = new ReforgedBatchGroup(model, group.shader); - } - - for (final Integer object : group.objects) { - if (isBatchSimple(batches.get(object))) { - simpleGroup.objects.add(object); - } - } - - simpleGroups.add(simpleGroup); - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/TextureAnimation.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/TextureAnimation.java deleted file mode 100644 index 8e6fb2be..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/TextureAnimation.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.util.RenderMathUtils; -import com.hiveworkshop.rms.parsers.mdlx.AnimationMap; -import com.hiveworkshop.rms.parsers.mdlx.MdlxTextureAnimation; - -public class TextureAnimation extends AnimatedObject { - - public TextureAnimation(final MdxModel model, final MdlxTextureAnimation textureAnimation) { - super(model, textureAnimation); - - this.addVariants(AnimationMap.KTAT.getWar3id(), "translation"); - this.addVariants(AnimationMap.KTAR.getWar3id(), "rotation"); - this.addVariants(AnimationMap.KTAS.getWar3id(), "scale"); - } - - public int getTranslation(final float[] out, final int sequence, final int frame, final int counter) { - return this.getVectorValue(out, AnimationMap.KTAT.getWar3id(), sequence, frame, counter, - RenderMathUtils.FLOAT_VEC3_ZERO); - } - - public int getRotation(final float[] out, final int sequence, final int frame, final int counter) { - return this.getQuatValue(out, AnimationMap.KTAR.getWar3id(), sequence, frame, counter, - RenderMathUtils.FLOAT_QUAT_DEFAULT); - } - - public int getScale(final float[] out, final int sequence, final int frame, final int counter) { - return this.getVectorValue(out, AnimationMap.KTAS.getWar3id(), sequence, frame, counter, - RenderMathUtils.FLOAT_VEC3_ONE); - } - - public boolean isTranslationVariant(final int sequence) { - return this.isVariant(AnimationMap.KTAT.getWar3id(), sequence); - } - - public boolean isRotationVariant(final int sequence) { - return this.isVariant(AnimationMap.KTAR.getWar3id(), sequence); - } - - public boolean isScaleVariant(final int sequence) { - return this.isVariant(AnimationMap.KTAS.getWar3id(), sequence); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/UInt32Sd.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/UInt32Sd.java deleted file mode 100644 index d5025f85..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/UInt32Sd.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.util.RenderMathUtils; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxTimeline; - -public class UInt32Sd extends Sd { - - public UInt32Sd(final MdxModel model, final MdlxTimeline timeline) { - super(model, timeline, SdArrayDescriptor.LONG_ARRAY); - } - - @Override - protected long[] convertDefaultValue(final float[] defaultValue) { - final long[] returnValue = new long[defaultValue.length]; - for (int i = 0; i < defaultValue.length; i++) { - returnValue[i] = (long) defaultValue[i]; - } - return returnValue; - } - - @Override - protected void copy(final long[] out, final long[] value) { - out[0] = value[0]; - } - - @Override - protected void interpolate(final long[] out, final long[][] values, final long[][] inTans, final long[][] outTans, - final int start, final int end, final float t) { - final long startValue = values[start][0]; - - switch (this.interpolationType) { - case 0: - out[0] = startValue; - break; - case 1: - out[0] = (long) RenderMathUtils.lerp(startValue, values[end][0], t); - break; - case 2: - out[0] = (long) RenderMathUtils.hermite(startValue, (start < outTans.length) ? outTans[start][0] : 0, - (start < inTans.length) ? inTans[end][0] : 0, values[end][0], t); - break; - case 3: - out[0] = (long) RenderMathUtils.bezier(startValue, (start < outTans.length) ? outTans[start][0] : 0, - (start < inTans.length) ? inTans[end][0] : 0, values[end][0], t); - break; - } - - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/VectorSd.java b/core/src/com/etheller/warsmash/viewer5/handlers/mdx/VectorSd.java deleted file mode 100644 index 038a25e1..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/mdx/VectorSd.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.mdx; - -import com.etheller.warsmash.util.Interpolator; -import com.etheller.warsmash.util.RenderMathUtils; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxTimeline; - -public class VectorSd extends Sd { - - public VectorSd(final MdxModel model, final MdlxTimeline timeline) { - super(model, timeline, SdArrayDescriptor.FLOAT_ARRAY); - } - - @Override - protected float[] convertDefaultValue(final float[] defaultValue) { - return defaultValue; - } - - @Override - protected void copy(final float[] out, final float[] value) { - System.arraycopy(value, 0, out, 0, value.length); - } - - @Override - protected void interpolate(final float[] out, final float[][] values, final float[][] inTans, - final float[][] outTans, final int start, final int end, final float t) { - Interpolator.interpolateVector(out, values[start], - (start < outTans.length) ? outTans[start] : RenderMathUtils.EMPTY_FLOAT_ARRAY, - (start < outTans.length) ? inTans[end] : RenderMathUtils.EMPTY_FLOAT_ARRAY, values[end], t, - this.interpolationType); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/tga/ImageUtils.java b/core/src/com/etheller/warsmash/viewer5/handlers/tga/ImageUtils.java deleted file mode 100644 index feebac64..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/tga/ImageUtils.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.tga; - -import java.awt.AlphaComposite; -import java.awt.Composite; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.image.BufferedImage; - -public class ImageUtils { - - /** - * Takes an images as input and generates an array containing this image and all - * possible mipmaps - * - * @param input - * @return - */ - public static BufferedImage[] generateMipMaps(final BufferedImage input) { - int num = 0; - int curWidth = input.getWidth(); - int curHeight = input.getHeight(); - int pow; - do { - num++; - pow = (int) Math.pow(2.0D, num - 1); - } - while ((pow < curWidth) || (pow < curHeight)); - final BufferedImage[] result = new BufferedImage[num]; - result[0] = input; - for (int i = 1; i < num; i++) { - curWidth /= 2; - curHeight /= 2; - if (curHeight == 0) { - curHeight = 1; - } - if (curWidth == 0) { - curWidth = 1; - } - result[i] = ImageUtils.getScaledInstance(result[(i - 1)], curWidth, curHeight, - RenderingHints.VALUE_INTERPOLATION_BICUBIC, true); - } - return result; - } - - /** - * Scales an Image - * - * @param img - * @param targetWidth - * @param targetHeight - * @param hint Rendering Hint - * @param higherQuality - * @return - */ - public static BufferedImage getScaledInstance(final BufferedImage img, final int targetWidth, - final int targetHeight, final Object hint, final boolean higherQuality) { - final int type = img.getTransparency() == 1 ? 1 : 2; - BufferedImage ret = img; - int h; - int w; - if (higherQuality) { - w = img.getWidth(); - h = img.getHeight(); - } - else { - w = targetWidth; - h = targetHeight; - } - do { - if ((higherQuality) && (w > targetWidth)) { - w /= 2; - if (w < targetWidth) { - w = targetWidth; - } - } - if ((higherQuality) && (h > targetHeight)) { - h /= 2; - if (h < targetHeight) { - h = targetHeight; - } - } - - BufferedImage tmp; - if (img.getColorModel().hasAlpha() == false) { - tmp = new BufferedImage(w, h, type); - final Graphics2D g2 = tmp.createGraphics(); - g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); - g2.drawImage(ret, 0, 0, w, h, null); - g2.dispose(); - } - else { - // Necessary because otherwise Bilinear resize would couse transparent pixel to - // change color - tmp = resizeWorkAround(ret, w, h, hint); - } - - ret = tmp; - } - while ((w != targetWidth) || (h != targetHeight)); - return ret; - } - - private static BufferedImage resizeWorkAround(final BufferedImage ret, final int w, final int h, - final Object hint) { - - final BufferedImage noAlpha = new BufferedImage(ret.getWidth(), ret.getHeight(), BufferedImage.TYPE_INT_ARGB); - - for (int x = 0; x < ret.getWidth(); x++) { - for (int y = 0; y < ret.getHeight(); y++) { - int color = ret.getRGB(x, y); - color = color | 0xff000000; - noAlpha.setRGB(x, y, color); - } - } - - final BufferedImage noAlphaSmall = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); - Graphics2D g2 = noAlphaSmall.createGraphics(); - g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); - g2.drawImage(noAlpha, 0, 0, w, h, null); - g2.dispose(); - - final BufferedImage tmp = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); - g2 = tmp.createGraphics(); - g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); - g2.drawImage(ret, 0, 0, w, h, null); - g2.dispose(); - - noAlphaSmall.getAlphaRaster().setRect(0, 0, tmp.getAlphaRaster()); - - return noAlphaSmall; - } - - /** - * An alternative way to convert an image to type_byte_indexed (paletted) that - * avoids dithering. - * - * @param src - * @return - */ - public static BufferedImage antiDitherConvert(final BufferedImage src) { - final BufferedImage convertedImage = new BufferedImage(src.getWidth(), src.getHeight(), - BufferedImage.TYPE_BYTE_INDEXED); - for (int x = 0; x < src.getWidth(); x++) { - for (int y = 0; y < src.getHeight(); y++) { - convertedImage.setRGB(x, y, src.getRGB(x, y)); - } - } - return convertedImage; - } - - public static BufferedImage changeImageType(final BufferedImage src, final int type) { - final BufferedImage img = new BufferedImage(src.getWidth(), src.getHeight(), type); - final Graphics2D g = (Graphics2D) img.getGraphics(); - - if (img.getColorModel().hasAlpha()) { - final Composite comp = AlphaComposite.getInstance(AlphaComposite.SRC); - g.setComposite(comp); - } - - g.drawImage(src, 0, 0, null); - g.dispose(); - - return img; - } - - public static BufferedImage convertStandardImageType(final BufferedImage src, final boolean useAlpha) { - - if (useAlpha && (src.getType() == BufferedImage.TYPE_INT_ARGB)) { - return src; - } - - if ((useAlpha == false) && (src.getType() == BufferedImage.TYPE_INT_RGB)) { - return src; - } - - return ImageUtils.changeImageType(src, useAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB); - - } -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/tga/TgaFile.java b/core/src/com/etheller/warsmash/viewer5/handlers/tga/TgaFile.java deleted file mode 100644 index 55528368..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/tga/TgaFile.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ -package com.etheller.warsmash.viewer5.handlers.tga; - -import java.awt.image.BufferedImage; -import java.awt.image.DataBuffer; -import java.awt.image.DataBufferByte; -import java.awt.image.DataBufferInt; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.RandomAccessFile; - -/** - * - * @author Riven, modified by Oger-Lord - */ -public class TgaFile { - - /** - * Read a TGA image from a file - * - * @param file - * @return - * @throws FileNotFoundException - * @throws IOException - */ - public static BufferedImage readTGA(final File file) throws FileNotFoundException, IOException { - return readTGA(file.getName(), new FileInputStream(file)); - - } - - /** - * Read a TGA image from an input stream. - * - * @param name - * @param stream - * @return - * @throws IOException - */ - public static BufferedImage readTGA(final String name, final InputStream stream) throws IOException { - - // Read Header - final byte[] header = new byte[18]; - stream.read(header); - - // Read pixel data - final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - int nRead; - byte[] data = new byte[16384]; - - while ((nRead = stream.read(data, 0, data.length)) != -1) { - buffer.write(data, 0, nRead); - } - buffer.flush(); - data = buffer.toByteArray(); - - // Verify Header - if ((header[0] | header[1]) != 0) { - throw new IllegalStateException("Error " + name); - } - if (header[2] != 2) { - throw new IllegalStateException("Error " + name); - } - int w = 0, h = 0; - w |= (header[12] & 0xFF) << 0; - w |= (header[13] & 0xFF) << 8; - h |= (header[14] & 0xFF) << 0; - h |= (header[15] & 0xFF) << 8; - - boolean alpha; - - if ((header[16] == 24)) { - alpha = false; - } - else if (header[16] == 32) { - alpha = true; - } - else { - throw new IllegalStateException("Error " + name + " invalid pixel depth: " + header[16]); - } - - if ((header[17] & 15) != (alpha ? 8 : 0)) { - throw new IllegalStateException("Error " + name); - } - - final BufferedImage dst = new BufferedImage(w, h, - alpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB); - final int[] pixels = ((DataBufferInt) dst.getRaster().getDataBuffer()).getData(); - if (pixels.length != (w * h)) { - throw new IllegalStateException("Error " + name); - } - if (data.length < (pixels.length * (alpha ? 4 : 3))) { - throw new IllegalStateException("Error " + name + " not enaugh pixel data"); - } - - if (alpha) { - for (int i = 0, p = (pixels.length - 1) * 4; i < pixels.length; i++, p -= 4) { - pixels[i] |= ((data[p + 0]) & 0xFF) << 0; - pixels[i] |= ((data[p + 1]) & 0xFF) << 8; - pixels[i] |= ((data[p + 2]) & 0xFF) << 16; - pixels[i] |= ((data[p + 3]) & 0xFF) << 24; - } - } - else { - for (int i = 0, p = (pixels.length - 1) * 3; i < pixels.length; i++, p -= 3) { - pixels[i] |= ((data[p + 0]) & 0xFF) << 0; - pixels[i] |= ((data[p + 1]) & 0xFF) << 8; - pixels[i] |= ((data[p + 2]) & 0xFF) << 16; - } - } - - if ((header[17] >> 4) == 1) { - // ok - } - else if ((header[17] >> 4) == 0) { - // flip horizontally - - for (int y = 0; y < h; y++) { - final int w2 = w / 2; - for (int x = 0; x < w2; x++) { - final int a = (y * w) + x; - final int b = (y * w) + (w - 1 - x); - final int t = pixels[a]; - pixels[a] = pixels[b]; - pixels[b] = t; - } - } - } - else if ((header[17] >> 4) == 2) { - // flip horizontally and vertically - - for (int y = 0; y < h; y++) { - final int w2 = w / 2; - for (int x = 0; x < w2; x++) { - final int a = (y * w) + x; - final int b = ((h - 1 - y) * w) + (w - 1 - x); - final int t = pixels[a]; - pixels[a] = pixels[b]; - pixels[b] = t; - } - } - } - else { - final int headerval = header[17] >> 4; - throw new UnsupportedOperationException("Error " + name + " (" + headerval + ")"); - } - - return dst; - } - - /** - * Write a BufferedImage to a TGA file BufferedImages should be TYPE_INT_ARGB or - * TYPE_INT_RGB - * - * @param src - * @param file - * @throws IOException - */ - public static void writeTGA(BufferedImage src, final File file) throws IOException { - - final boolean alpha = src.getColorModel().hasAlpha(); - src = ImageUtils.convertStandardImageType(src, alpha); - - final DataBuffer buffer = src.getRaster().getDataBuffer(); - byte[] data; - - if (buffer instanceof DataBufferByte) { - - // Not used anymore because convert to standard image type => Buffer is int - final byte[] pixels = ((DataBufferByte) src.getRaster().getDataBuffer()).getData(); - if (pixels.length != (src.getWidth() * src.getHeight() * (alpha ? 4 : 3))) { - throw new IllegalStateException(); - } - - data = pixels; - - } - else if (buffer instanceof DataBufferInt) { - - final int[] pixels = ((DataBufferInt) src.getRaster().getDataBuffer()).getData(); - if (pixels.length != (src.getWidth() * src.getHeight())) { - throw new IllegalStateException(); - } - - data = new byte[pixels.length * (alpha ? 4 : 3)]; - - if (alpha) { - - for (int p = 0; p < pixels.length; p++) { - final int i = p * 4; - data[i + 0] = (byte) ((pixels[p] >> 0) & 0xFF); - data[i + 1] = (byte) ((pixels[p] >> 8) & 0xFF); - data[i + 2] = (byte) ((pixels[p] >> 16) & 0xFF); - data[i + 3] = (byte) ((pixels[p] >> 24) & 0xFF); - } - } - else { - - for (int p = 0; p < pixels.length; p++) { - final int i = p * 3; - data[i + 0] = (byte) ((pixels[p] >> 0) & 0xFF); - data[i + 1] = (byte) ((pixels[p] >> 8) & 0xFF); - data[i + 2] = (byte) ((pixels[p] >> 16) & 0xFF); - } - } - } - else { - throw new UnsupportedOperationException(); - } - - final byte[] header = new byte[18]; - header[2] = 2; // uncompressed, true-color image - header[12] = (byte) ((src.getWidth() >> 0) & 0xFF); - header[13] = (byte) ((src.getWidth() >> 8) & 0xFF); - header[14] = (byte) ((src.getHeight() >> 0) & 0xFF); - header[15] = (byte) ((src.getHeight() >> 8) & 0xFF); - header[16] = (byte) (alpha ? 32 : 24); // bits per pixel - header[17] = (byte) ((alpha ? 8 : 0) | (2 << 4)); - - final RandomAccessFile raf = new RandomAccessFile(file, "rw"); - raf.write(header); - raf.write(data); - raf.setLength(raf.getFilePointer()); // trim - raf.close(); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/tga/TgaHandler.java b/core/src/com/etheller/warsmash/viewer5/handlers/tga/TgaHandler.java deleted file mode 100644 index 1505f0df..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/tga/TgaHandler.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.tga; - -import java.util.ArrayList; - -import com.etheller.warsmash.viewer5.HandlerResource; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.handlers.ResourceHandler; -import com.etheller.warsmash.viewer5.handlers.ResourceHandlerConstructionParams; - -public class TgaHandler extends ResourceHandler { - - public TgaHandler() { - this.extensions = new ArrayList<>(); - this.extensions.add(new String[] { ".tga", "arrayBuffer" }); - } - - @Override - public boolean load(final ModelViewer modelViewer) { - return true; - } - - @Override - public HandlerResource construct(final ResourceHandlerConstructionParams params) { - return new TgaTexture(params.getViewer(), params.getHandler(), params.getExtension(), params.getPathSolver(), - params.getFetchUrl()); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/tga/TgaTexture.java b/core/src/com/etheller/warsmash/viewer5/handlers/tga/TgaTexture.java deleted file mode 100644 index 5f3bd585..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/tga/TgaTexture.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.tga; - -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.InputStream; - -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.RawOpenGLTextureResource; -import com.etheller.warsmash.viewer5.handlers.ResourceHandler; - -public class TgaTexture extends RawOpenGLTextureResource { - - public TgaTexture(final ModelViewer viewer, final ResourceHandler handler, final String extension, - final PathSolver pathSolver, final String fetchUrl) { - super(viewer, extension, pathSolver, fetchUrl, handler); - } - - @Override - protected void lateLoad() { - - } - - @Override - protected void load(final InputStream src, final Object options) { - BufferedImage img; - try { - img = TgaFile.readTGA(this.fetchUrl, src); - update(img, false); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/AnimationTokens.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/AnimationTokens.java deleted file mode 100644 index 29801ae5..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/AnimationTokens.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -public class AnimationTokens { - public static enum PrimaryTag { - ATTACK, - BIRTH, - CINEMATIC, - DEATH, - DECAY, - DISSIPATE, - MORPH, - PORTRAIT, - SLEEP, -// SPELL, - STAND, - WALK; - } - - public static enum SecondaryTag { - ALTERNATE, - ALTERNATEEX, - BONE, - CHAIN, - CHANNEL, - COMPLETE, - CRITICAL, - DEFEND, - DRAIN, - EATTREE, - FAST, - FILL, - FLAIL, - FLESH, - FIFTH, - FIRE, - FIRST, - FIVE, - FOUR, - FOURTH, - GOLD, - HIT, - LARGE, - LEFT, - LIGHT, - LOOPING, - LUMBER, - MEDIUM, - MODERATE, - OFF, - ONE, - PUKE, - READY, - RIGHT, - SECOND, - SEVERE, - SLAM, - SMALL, - SPIKED, - SPIN, - SPELL, - SWIM, - TALK, - THIRD, - THREE, - THROW, - TWO, - TURN, - VICTORY, - WORK, - WOUNDED, - UPGRADE; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/DynamicShadowManager.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/DynamicShadowManager.java deleted file mode 100644 index 5847c68e..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/DynamicShadowManager.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL30; -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.viewer5.gl.Extensions; -import com.etheller.warsmash.viewer5.gl.WebGL; - -public class DynamicShadowManager { - public static boolean IS_SHADOW_MAPPING = false; - - private final Vector3 shadowVector = new Vector3(); - private final Matrix4 depthProjectionMatrix = new Matrix4(); - private final Matrix4 depthViewMatrix = new Matrix4(); - private final Matrix4 depthModelMatrix = new Matrix4(); - private final Matrix4 depthMVP = new Matrix4(); - private final Matrix4 biasMatrix = new Matrix4(); - private final Matrix4 depthBiasMVP = new Matrix4(); - - public boolean setup(final WebGL webGL) { - // The framebuffer, which regroups 0, 1, or more textures, and 0 or 1 depth - // buffer. - final GL30 gl = Gdx.gl30; - this.framebufferName = 0; - this.framebufferName = gl.glGenFramebuffer(); - gl.glBindFramebuffer(GL30.GL_FRAMEBUFFER, this.framebufferName); - - this.depthTexture = gl.glGenTexture(); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.depthTexture); - gl.glTexImage2D(GL30.GL_TEXTURE_2D, 0, GL30.GL_DEPTH_COMPONENT16, 1024, 1024, 0, GL30.GL_DEPTH_COMPONENT, - GL30.GL_FLOAT, null); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MAG_FILTER, GL30.GL_NEAREST); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MIN_FILTER, GL30.GL_NEAREST); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_WRAP_S, GL30.GL_CLAMP_TO_EDGE); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_WRAP_T, GL30.GL_CLAMP_TO_EDGE); - Extensions.dynamicShadowExtension.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, - this.depthTexture, 0); - - Extensions.dynamicShadowExtension.glDrawBuffer(GL30.GL_NONE); // No color buffer is drawn to. - - // Always check that our framebuffer is ok - if (gl.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) != GL30.GL_FRAMEBUFFER_COMPLETE) { - return false; - } - Gdx.gl30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0); - - return true; - } - - /** - * @return - */ - public Matrix4 prepareShadowMatrix() { - final Vector3 lightInvDir = this.shadowVector; - lightInvDir.set(500f, 2000, 2000); - - // Compute the MVP matrix from the light's point of view - this.depthProjectionMatrix.setToOrtho(-10, 10, -10, 10, -10, 20); - this.depthViewMatrix.set(this.depthProjectionMatrix); - this.depthViewMatrix.setToLookAt(lightInvDir, Vector3.Zero, RenderMathUtils.VEC3_UNIT_Y); - this.depthModelMatrix.idt(); - this.depthMVP.set(this.depthProjectionMatrix).mul(this.depthViewMatrix).mul(this.depthModelMatrix); - -// this.shader.setUniformMatrix("depthMVP", this.depthMVP); - - this.biasMatrix.val[Matrix4.M00] = 0.5f; - this.biasMatrix.val[Matrix4.M10] = 0.0f; - this.biasMatrix.val[Matrix4.M20] = 0.0f; - this.biasMatrix.val[Matrix4.M30] = 0.5f; - this.biasMatrix.val[Matrix4.M01] = 0.0f; - this.biasMatrix.val[Matrix4.M11] = 0.5f; - this.biasMatrix.val[Matrix4.M21] = 0.0f; - this.biasMatrix.val[Matrix4.M31] = 0.5f; - this.biasMatrix.val[Matrix4.M02] = 0.0f; - this.biasMatrix.val[Matrix4.M12] = 0.0f; - this.biasMatrix.val[Matrix4.M22] = 0.5f; - this.biasMatrix.val[Matrix4.M32] = 0.5f; - this.biasMatrix.val[Matrix4.M03] = 0.0f; - this.biasMatrix.val[Matrix4.M13] = 0.0f; - this.biasMatrix.val[Matrix4.M23] = 0.0f; - this.biasMatrix.val[Matrix4.M33] = 1.0f; - this.depthBiasMVP.set(this.biasMatrix).mul(this.depthMVP); - - return this.depthMVP; - } - - public void beginShadowMap(final WebGL webGL) { - IS_SHADOW_MAPPING = true; - - Gdx.gl30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, this.framebufferName); - Extensions.dynamicShadowExtension.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, - this.depthTexture, 0); - - Extensions.dynamicShadowExtension.glDrawBuffer(GL30.GL_NONE); // No color buffer is drawn to. - Gdx.gl30.glViewport(0, 0, 1024, 1024); - - } - - public Matrix4 getDepthBiasMVP() { - return this.depthBiasMVP; - } - - // Don't forget to change viewport back - public void endShadowMap() { - IS_SHADOW_MAPPING = false; - Gdx.gl30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0); - } - - public int getDepthTexture() { - return this.depthTexture; - } - - public static final String vertexShader = "#version 330 core\r\n" + // - "\r\n" + // - "// Input vertex data, different for all executions of this shader.\r\n" + // - "layout(location = 0) in vec3 vertexPosition_modelspace;\r\n" + // - "\r\n" + // - "// Values that stay constant for the whole mesh.\r\n" + // - "uniform mat4 depthMVP;\r\n" + // - "\r\n" + // - "void main(){\r\n" + // - " gl_Position = depthMVP * vec4(vertexPosition_modelspace,1);\r\n" + // - "}"; - - public static final String fragmentShader = "#version 330 core\r\n" + // - "\r\n" + // - "// Ouput data\r\n" + // - "layout(location = 0) out float fragmentdepth;\r\n" + // - "\r\n" + // - "void main(){\r\n" + // - " // Not really needed, OpenGL does it anyway\r\n" + // - " fragmentdepth = gl_FragCoord.z;\r\n" + // - "}"; - private int depthTexture; - private int framebufferName; - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/IndexedSequence.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/IndexedSequence.java deleted file mode 100644 index f1677e8f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/IndexedSequence.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import com.etheller.warsmash.viewer5.handlers.mdx.Sequence; - -public class IndexedSequence { - public final Sequence sequence; - public final int index; - - public IndexedSequence(final Sequence sequence, final int index) { - this.sequence = sequence; - this.index = index; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/SecondaryTagSequenceComparator.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/SecondaryTagSequenceComparator.java deleted file mode 100644 index 1a5ab6bb..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/SecondaryTagSequenceComparator.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import java.util.Comparator; -import java.util.EnumSet; - -public class SecondaryTagSequenceComparator implements Comparator { - private final StandSequenceComparator standSequenceComparator; - private EnumSet ignoredTags; - - public SecondaryTagSequenceComparator(StandSequenceComparator standSequenceComparator) { - this.standSequenceComparator = standSequenceComparator; - } - - public SecondaryTagSequenceComparator reset(EnumSet ignoredTags) { - this.ignoredTags = ignoredTags; - return this; - } - - @Override - public int compare(final IndexedSequence a, final IndexedSequence b) { - EnumSet secondaryTagsA = a.sequence.getSecondaryTags(); - EnumSet secondaryTagsB = b.sequence.getSecondaryTags(); - int secondaryTagsAOrdinal = getTagsOrdinal(secondaryTagsA, ignoredTags); - int secondaryTagsBOrdinal = getTagsOrdinal(secondaryTagsB, ignoredTags); - if (secondaryTagsAOrdinal != secondaryTagsBOrdinal) { - return secondaryTagsBOrdinal - secondaryTagsAOrdinal; - } - return standSequenceComparator.compare(a, b); - } - - public static int getTagsOrdinal(EnumSet secondaryTagsA, EnumSet ignoredTags) { - int secondaryTagsBOrdinal = Integer.MAX_VALUE; - for (AnimationTokens.SecondaryTag secondaryTag : secondaryTagsA) { - if (secondaryTag.ordinal() < secondaryTagsBOrdinal && !ignoredTags.contains(secondaryTag)) { - secondaryTagsBOrdinal = secondaryTag.ordinal(); - } - } - return secondaryTagsBOrdinal; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/SequenceUtils.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/SequenceUtils.java deleted file mode 100644 index 46160b72..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/SequenceUtils.java +++ /dev/null @@ -1,301 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.EnumSet; -import java.util.List; - -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.mdx.Sequence; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.SecondaryTag; - -public class SequenceUtils { - public static final EnumSet EMPTY = EnumSet.noneOf(SecondaryTag.class); - public static final EnumSet READY = EnumSet.of(SecondaryTag.READY); - public static final EnumSet FLESH = EnumSet.of(SecondaryTag.FLESH); - public static final EnumSet TALK = EnumSet.of(SecondaryTag.TALK); - public static final EnumSet BONE = EnumSet.of(SecondaryTag.BONE); - public static final EnumSet HIT = EnumSet.of(SecondaryTag.HIT); - public static final EnumSet SPELL = EnumSet.of(SecondaryTag.SPELL); - public static final EnumSet WORK = EnumSet.of(SecondaryTag.WORK); - public static final EnumSet FAST = EnumSet.of(SecondaryTag.FAST); - - private static final StandSequenceComparator STAND_SEQUENCE_COMPARATOR = new StandSequenceComparator(); - private static final SecondaryTagSequenceComparator SECONDARY_TAG_SEQUENCE_COMPARATOR = new SecondaryTagSequenceComparator( - STAND_SEQUENCE_COMPARATOR); - - public static List filterSequences(final String type, final List sequences) { - final List filtered = new ArrayList<>(); - - for (int i = 0, l = sequences.size(); i < l; i++) { - final Sequence sequence = sequences.get(i); - final String name = sequence.getName().split("-")[0].trim().toLowerCase(); - - if (name.equals(type)) { - filtered.add(new IndexedSequence(sequence, i)); - } - } - - return filtered; - } - - private static List filterSequences(final PrimaryTag type, final EnumSet tags, - final List sequences) { - final List filtered = new ArrayList<>(); - - for (int i = 0, l = sequences.size(); i < l; i++) { - final Sequence sequence = sequences.get(i); - if ((sequence.getPrimaryTags().contains(type) || (type == null)) - && (sequence.getSecondaryTags().containsAll(tags) - && tags.containsAll(sequence.getSecondaryTags()))) { - filtered.add(new IndexedSequence(sequence, i)); - } - } - - return filtered; - } - - public static IndexedSequence selectSequence(final String type, final List sequences) { - final List filtered = filterSequences(type, sequences); - - filtered.sort(STAND_SEQUENCE_COMPARATOR); - - int i = 0; - final double randomRoll = Math.random() * 100; - for (final int l = filtered.size(); i < l; i++) { - final Sequence sequence = filtered.get(i).sequence; - final float rarity = sequence.getRarity(); - - if (rarity == 0) { - break; - } - - if (randomRoll < (10 - rarity)) { - return filtered.get(i); - } - } - - final int sequencesLeft = filtered.size() - i; - final int random = (int) (i + Math.floor(Math.random() * sequencesLeft)); - if (sequencesLeft <= 0) { - return null; // new IndexedSequence(null, 0); - } - final IndexedSequence sequence = filtered.get(random); - - return sequence; - } - - public static int matchCount(final EnumSet goalTagSet, - final EnumSet tagsToTest) { - int matches = 0; - for (final AnimationTokens.SecondaryTag goalTag : goalTagSet) { - if (tagsToTest.contains(goalTag)) { - matches++; - } - } - return matches; - } - - public static IndexedSequence selectSequence(final AnimationTokens.PrimaryTag type, - final EnumSet tags, final List sequences, - final boolean allowRarityVariations) { - List filtered = filterSequences(type, tags, sequences); - final Comparator sequenceComparator = STAND_SEQUENCE_COMPARATOR; - -// if (filtered.isEmpty() && !tags.isEmpty()) { -// filtered = filterSequences(type, EMPTY, sequences); -// } - if (filtered.isEmpty()) { - // find tags - EnumSet fallbackTags = null; - int fallbackTagsMatchCount = 0; - for (int i = 0, l = sequences.size(); i < l; i++) { - final Sequence sequence = sequences.get(i); - if (sequence.getPrimaryTags().contains(type) || (type == null)) { - final int matchCount = matchCount(tags, sequence.getSecondaryTags()); - if (matchCount > fallbackTagsMatchCount) { - fallbackTags = sequence.getSecondaryTags(); - fallbackTagsMatchCount = matchCount; - } - } - } - if (fallbackTags == null) { - for (int i = 0, l = sequences.size(); i < l; i++) { - final Sequence sequence = sequences.get(i); - if (sequence.getPrimaryTags().contains(type) || (type == null)) { - if ((fallbackTags == null) || (sequence.getSecondaryTags().size() < fallbackTags.size()) - || ((sequence.getSecondaryTags().size() == fallbackTags.size()) - && (SecondaryTagSequenceComparator.getTagsOrdinal(sequence.getSecondaryTags(), - tags) > SecondaryTagSequenceComparator.getTagsOrdinal(fallbackTags, - tags)))) { - fallbackTags = sequence.getSecondaryTags(); - } - } - } - } - if (fallbackTags != null) { - filtered = filterSequences(type, fallbackTags, sequences); - } - } - - filtered.sort(sequenceComparator); - - int i = 0; - final double randomRoll = Math.random() * 100; - for (final int l = filtered.size(); i < l; i++) { - final Sequence sequence = filtered.get(i).sequence; - final float rarity = sequence.getRarity(); - - if (rarity == 0) { - break; - } - - if ((randomRoll < (10 - rarity)) && allowRarityVariations) { - return filtered.get(i); - } - } - - final int sequencesLeft = filtered.size() - i; - final int random = (int) (i + Math.floor(Math.random() * sequencesLeft)); - if (sequencesLeft <= 0) { - return null; // new IndexedSequence(null, 0); - } - final IndexedSequence sequence = filtered.get(random); - - return sequence; - } - - public static void randomStandSequence(final MdxComplexInstance target) { - final MdxModel model = (MdxModel) target.model; - final List sequences = model.getSequences(); - final IndexedSequence sequence = selectSequence("stand", sequences); - - if (sequence != null) { - target.setSequence(sequence.index); - } - else { - target.setSequence(0); - } - } - - public static void randomDeathSequence(final MdxComplexInstance target) { - final MdxModel model = (MdxModel) target.model; - final List sequences = model.getSequences(); - final IndexedSequence sequence = selectSequence("death", sequences); - - if (sequence != null) { - target.setSequence(sequence.index); - } - else { - target.setSequence(0); - } - } - - public static void randomWalkSequence(final MdxComplexInstance target) { - final MdxModel model = (MdxModel) target.model; - final List sequences = model.getSequences(); - final IndexedSequence sequence = selectSequence("walk", sequences); - - if (sequence != null) { - target.setSequence(sequence.index); - } - else { - randomStandSequence(target); - } - } - - public static void randomBirthSequence(final MdxComplexInstance target) { - final MdxModel model = (MdxModel) target.model; - final List sequences = model.getSequences(); - final IndexedSequence sequence = selectSequence("birth", sequences); - - if (sequence != null) { - target.setSequence(sequence.index); - } - else { - randomStandSequence(target); - } - } - - public static void randomPortraitSequence(final MdxComplexInstance target) { - final MdxModel model = (MdxModel) target.model; - final List sequences = model.getSequences(); - final IndexedSequence sequence = selectSequence("portrait", sequences); - - if (sequence != null) { - target.setSequence(sequence.index); - } - else { - randomStandSequence(target); - } - } - - public static void randomPortraitTalkSequence(final MdxComplexInstance target) { - final MdxModel model = (MdxModel) target.model; - final List sequences = model.getSequences(); - final IndexedSequence sequence = selectSequence("portrait talk", sequences); - - if (sequence != null) { - target.setSequence(sequence.index); - } - else { - randomPortraitSequence(target); - } - } - - public static void randomSequence(final MdxComplexInstance target, final String sequenceName) { - final MdxModel model = (MdxModel) target.model; - final List sequences = model.getSequences(); - final IndexedSequence sequence = selectSequence(sequenceName, sequences); - - if (sequence != null) { - target.setSequence(sequence.index); - } - else { - randomStandSequence(target); - } - } - - public static Sequence randomSequence(final MdxComplexInstance target, final PrimaryTag animationName, - final boolean allowRarityVariations) { - final MdxModel model = (MdxModel) target.model; - final List sequences = model.getSequences(); - final IndexedSequence sequence = selectSequence(animationName, null, sequences, allowRarityVariations); - - if (sequence != null) { - target.setSequence(sequence.index); - return sequence.sequence; - } - else { - return null; - } - } - - public static Sequence randomSequence(final MdxComplexInstance target, final PrimaryTag animationName, - final EnumSet secondaryAnimationTags, final boolean allowRarityVariations) { - final MdxModel model = (MdxModel) target.model; - final List sequences = model.getSequences(); - final IndexedSequence sequence = selectSequence(animationName, secondaryAnimationTags, sequences, - allowRarityVariations); - - if (sequence != null) { - target.setSequence(sequence.index); - return sequence.sequence; - } - else { - if ((animationName == null) || (secondaryAnimationTags.size() != 1) - || !secondaryAnimationTags.contains(SecondaryTag.SPELL)) { - return null; - } - else { - return randomSequence(target, null, secondaryAnimationTags, allowRarityVariations); - } - } - } - - public static Sequence randomSequence(final MdxComplexInstance target, final PrimaryTag animationName) { - return randomSequence(target, animationName, EMPTY, false); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/SplatModel.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/SplatModel.java deleted file mode 100644 index 334aeb64..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/SplatModel.java +++ /dev/null @@ -1,543 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Consumer; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.GL30; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.viewer5.ViewerTextureRenderable; - -/** - * TODO this is copied from RivSoft stuff. - * https://github.com/d07RiV/wc3data/blob/3435e9728663825d892693318d0a0bb823dfad8c/src/mdx/viewer/handlers/w3x/splatmodel.js - * - * Shouldn't this just be a geomtry shader that takes X/Y/Texture as input and - * renders a splat, so that we can simply change the X/Y attribute values and - * move around the unit selection circles without memory allocations? For now I - * plan to simply port the RivSoft stuff, and come back later. - */ -public class SplatModel implements Comparable { - private static final int MAX_VERTICES = 65000; - private static final float NO_ABS_HEIGHT = -257f; - private final ViewerTextureRenderable texture; - private final List batches; - public final float[] color; - private final List locations; - private final List splatInstances; - private final boolean unshaded; - private final boolean noDepthTest; - private final boolean highPriority; - - public SplatModel(final GL30 gl, final ViewerTextureRenderable texture, final List locations, - final float[] centerOffset, final List> unitMapping, final boolean unshaded, - final boolean noDepthTest, final boolean highPriority) { - this.texture = texture; - this.unshaded = unshaded; - this.noDepthTest = noDepthTest; - this.highPriority = highPriority; - this.batches = new ArrayList<>(); - this.color = new float[] { 1, 1, 1, 1 }; - - this.locations = locations; - if (unitMapping != null) { - this.splatInstances = new ArrayList<>(); - for (int i = 0; i < unitMapping.size(); i++) { - this.splatInstances.add(new SplatMover(this)); - } - } - else { - this.splatInstances = null; - } - loadBatches(gl, centerOffset); - if (unitMapping != null) { - if (this.splatInstances.size() != unitMapping.size()) { - throw new IllegalStateException(); - } - for (int i = 0; i < this.splatInstances.size(); i++) { - unitMapping.get(i).accept(this.splatInstances.get(i)); - } - } - } - - public void compact(final GL30 gl, final float[] centerOffset) { - // delete all the batches - for (final Batch b : this.batches) { - // Vertices - gl.glDeleteBuffer(b.vertexBuffer); - - // Faces. - gl.glDeleteBuffer(b.faceBuffer); - } - this.batches.clear(); - - loadBatches(gl, centerOffset); - } - - private void loadBatches(final GL30 gl, final float[] centerOffset) { - final List vertices = new ArrayList<>(); - final List uvs = new ArrayList<>(); - final List absoluteHeights = new ArrayList<>(); - final List indices = new ArrayList<>(); - final List batchRenderUnits = new ArrayList<>(); - final int instances = this.locations.size(); - for (int idx = 0; idx < instances; ++idx) { - final float[] locs = this.locations.get(idx); - final float x0 = locs[0]; - final float y0 = locs[1]; - final float x1 = locs[2]; - final float y1 = locs[3]; - final float zoffs = locs[4]; - - final float centerOffsetX = centerOffset[0]; - final float centerOffsetY = centerOffset[1]; - final int ix0 = (int) Math.floor((x0 - centerOffsetX) / 128.0); - final int ix1 = (int) Math.ceil((x1 - centerOffsetX) / 128.0); - final int iy0 = (int) Math.floor((y0 - centerOffsetY) / 128.0); - final int iy1 = (int) Math.ceil((y1 - centerOffsetY) / 128.0); - - final int newVerts = ((iy1 - iy0) + 1) * ((ix1 - ix0) + 1); - final int maxPossibleVerts = ((int) Math.ceil((y1 - y0) / 128.0) + 2) - * ((int) Math.ceil((x1 - x0) / 128.0) + 2); - final int maxPossibleFaces = ((int) Math.ceil((y1 - y0) / 128.0) + 1) - * ((int) Math.ceil((x1 - x0) / 128.0) + 1); - - int start = vertices.size(); - final SplatMover splatMover = (this.splatInstances == null) ? null - : this.splatInstances.get(idx).reset(start * 3 * 4, indices.size() * 6 * 2, idx); - - final int numVertsToCrate = splatMover == null ? newVerts : maxPossibleVerts; - if (numVertsToCrate > MAX_VERTICES) { - continue; - } - - final int step = (ix1 - ix0) + 1; - if ((start + numVertsToCrate) > MAX_VERTICES) { - this.addBatch(gl, vertices, uvs, absoluteHeights, indices, batchRenderUnits); - vertices.clear(); - uvs.clear(); - absoluteHeights.clear(); - indices.clear(); - batchRenderUnits.clear(); - start = 0; - } - - final float uvXScale = x1 - x0; - final float uvYScale = y1 - y0; - for (int iy = iy0; iy <= iy1; ++iy) { - final float y = (iy * 128.0f) + centerOffsetY; - for (int ix = ix0; ix <= ix1; ++ix) { - final float x = (ix * 128.0f) + centerOffsetX; - final float[] vertex = new float[] { x, y, zoffs }; - vertices.add(vertex); - final float[] uv = new float[] { (x - x0) / uvXScale, 1.0f - ((y - y0) / uvYScale) }; - uvs.add(uv); - final float[] absHeight = new float[] { NO_ABS_HEIGHT }; - absoluteHeights.add(absHeight); - if (splatMover != null) { - splatMover.vertices.add(vertex); - splatMover.uvs.add(uv); - splatMover.absoluteHeights.add(absHeight); - } - } - } - if (splatMover != null) { - splatMover.uvXScale = uvXScale; - splatMover.uvYScale = uvYScale; - splatMover.locs = locs; - splatMover.ix0 = ix0; - splatMover.iy0 = iy0; - splatMover.ix1 = ix1; - splatMover.iy1 = iy1; - - final float y = (iy1 * 128.0f) + centerOffsetY; - final float x = (ix1 * 128.0f) + centerOffsetX; - while (splatMover.vertices.size() < maxPossibleVerts) { - final float[] vertex = new float[] { x, y, zoffs }; - vertices.add(vertex); - final float[] uv = new float[] { (x - x0) / uvXScale, 1.0f - ((y - y0) / uvYScale) }; - uvs.add(uv); - final float[] absHeight = new float[] { NO_ABS_HEIGHT }; - absoluteHeights.add(absHeight); - splatMover.vertices.add(vertex); - splatMover.uvs.add(uv); - splatMover.absoluteHeights.add(absHeight); - } - } - for (int i = 0; i < (iy1 - iy0); ++i) { - for (int j = 0; j < (ix1 - ix0); ++j) { - final int i0 = start + (i * step) + j; - final int[] indexArray = new int[] { i0, i0 + 1, i0 + step, i0 + 1, i0 + step + 1, i0 + step }; - indices.add(indexArray); - if (splatMover != null) { - splatMover.indices.add(indexArray); - } - } - } - if (this.splatInstances != null) { - batchRenderUnits.add(splatMover); - - while (splatMover.indices.size() < maxPossibleFaces) { - final int i0 = start; - final int[] indexArray = new int[] { i0, i0, i0, i0, i0, i0 }; - indices.add(indexArray); - splatMover.indices.add(indexArray); - } - } - - } - if (indices.size() > 0) { - this.addBatch(gl, vertices, uvs, absoluteHeights, indices, batchRenderUnits); - } - if (this.splatInstances != null) { - for (final SplatMover splatMover : this.splatInstances) { - if (splatMover.hidden) { - splatMover.hide(); - } - } - } - } - - private void addBatch(final GL30 gl, final List vertices, final List uvs, - final List absoluteHeights, final List indices, final List batchRenderUnits) { - final int uvsOffset = vertices.size() * 3 * 4; - final int paramsOffset = uvsOffset + (uvs.size() * 4 * 2); - - final int vertexBuffer = gl.glGenBuffer(); - gl.glBindBuffer(GL30.GL_ARRAY_BUFFER, vertexBuffer); - gl.glBufferData(GL30.GL_ARRAY_BUFFER, uvsOffset + (uvs.size() * 4 * 2) + (absoluteHeights.size() * 4), null, - GL30.GL_STATIC_DRAW); - gl.glBufferSubData(GL30.GL_ARRAY_BUFFER, 0, vertices.size() * 4 * 3, RenderMathUtils.wrap(vertices)); - gl.glBufferSubData(GL30.GL_ARRAY_BUFFER, uvsOffset, uvs.size() * 4 * 2, RenderMathUtils.wrap(uvs)); - gl.glBufferSubData(GL30.GL_ARRAY_BUFFER, paramsOffset, absoluteHeights.size() * 4, - RenderMathUtils.wrap(absoluteHeights)); - - final int faceBuffer = gl.glGenBuffer(); - gl.glBindBuffer(GL30.GL_ELEMENT_ARRAY_BUFFER, faceBuffer); - gl.glBufferData(GL30.GL_ELEMENT_ARRAY_BUFFER, indices.size() * 6 * 2, RenderMathUtils.wrapFaces(indices), - GL30.GL_STATIC_DRAW); - - this.batches.add(new Batch(uvsOffset, vertexBuffer, faceBuffer, indices.size() * 6, paramsOffset)); - for (final SplatMover mover : batchRenderUnits) { - mover.vertexBuffer = vertexBuffer; - mover.uvsOffset = uvsOffset; - mover.faceBuffer = faceBuffer; - mover.absHeightsOffset = paramsOffset; - } - } - - public void render(final GL30 gl, final ShaderProgram shader) { - // Texture - - if (this.noDepthTest) { - gl.glDisable(GL20.GL_DEPTH_TEST); - } - else { - gl.glEnable(GL20.GL_DEPTH_TEST); - } - gl.glActiveTexture(GL30.GL_TEXTURE1); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.texture.getGlHandle()); - shader.setUniformi("u_show_lighting", this.unshaded ? 0 : 1); - shader.setUniform4fv("u_color", this.color, 0, 4); - - for (final Batch b : this.batches) { - // Vertices - gl.glBindBuffer(GL30.GL_ARRAY_BUFFER, b.vertexBuffer); - shader.setVertexAttribute("a_position", 3, GL30.GL_FLOAT, false, 12, 0); - shader.setVertexAttribute("a_uv", 2, GL30.GL_FLOAT, false, 8, b.uvsOffset); - shader.setVertexAttribute("a_absoluteHeight", 1, GL30.GL_FLOAT, false, 4, b.paramsOffset); - - // Faces. - gl.glBindBuffer(GL30.GL_ELEMENT_ARRAY_BUFFER, b.faceBuffer); - - // Draw - gl.glDrawElements(GL30.GL_TRIANGLES, b.elements, GL30.GL_UNSIGNED_SHORT, 0); - } - - } - - public boolean isNoDepthTest() { - return this.noDepthTest; - } - - public boolean isHighPriority() { - return this.highPriority; - } - - public SplatMover add(final float x, final float y, final float x2, final float y2, final float zDepthUpward, - final float[] centerOffset) { - this.locations.add(new float[] { x, y, x2, y2, zDepthUpward }); - final SplatMover splatMover; - if (this.splatInstances != null) { - splatMover = new SplatMover(this); - this.splatInstances.add(splatMover); - } - else { - splatMover = null; - } - compact(Gdx.gl30, centerOffset); - return splatMover; - } - - private static final class Batch { - private final int uvsOffset; - private final int vertexBuffer; - private final int faceBuffer; - private final int elements; - private final int paramsOffset; - - public Batch(final int uvsOffset, final int vertexBuffer, final int faceBuffer, final int elements, - final int paramsOffset) { - this.uvsOffset = uvsOffset; - this.vertexBuffer = vertexBuffer; - this.faceBuffer = faceBuffer; - this.elements = elements; - this.paramsOffset = paramsOffset; - } - } - - public static final class SplatMover { - public int absHeightsOffset; - public int faceBuffer; - public int uvsOffset; - public int iy1; - public int ix1; - public int iy0; - public int ix0; - public float[] locs; - public float uvYScale; - public float uvXScale; - private int vertexBuffer; - private int startOffset; - private int start; - private final List vertices = new ArrayList<>(); - private final List uvs = new ArrayList<>(); - private final List absoluteHeights = new ArrayList<>(); - private final List indices = new ArrayList<>(); - private int indicesStartOffset; - private int index; - private final SplatModel splatModel; - private boolean hidden = false; - private boolean heightIsAbsolute = false; - private float absoluteHeightValue = 0.0f; - - private SplatMover(final SplatModel splatModel) { - this.splatModel = splatModel; - } - - private SplatMover reset(final int i, final int indicesStartOffset, final int index) { - this.startOffset = i; - this.indicesStartOffset = indicesStartOffset; - this.start = i / 12; - this.index = index; - this.vertices.clear(); - this.uvs.clear(); - this.absoluteHeights.clear(); - this.indices.clear(); - return this; - } - - public void move(final float deltaX, final float deltaY, final float[] centerOffset) { - this.locs[0] += deltaX; - this.locs[2] += deltaX; - this.locs[1] += deltaY; - this.locs[3] += deltaY; - updateAfterMove(centerOffset); - } - - public void setLocation(final float x, final float y, final float[] centerOffset) { - final float width = this.locs[2] - this.locs[0]; - final float height = this.locs[3] - this.locs[1]; - this.locs[0] = x - (width / 2); - this.locs[2] = x + (width / 2); - this.locs[1] = y - (height / 2); - this.locs[3] = y + (height / 2); - updateAfterMove(centerOffset); - } - - private void updateAfterMove(final float[] centerOffset) { - final float x0 = this.locs[0]; - final float y0 = this.locs[1]; - final float x1 = this.locs[2]; - final float y1 = this.locs[3]; - - final float centerOffsetX = centerOffset[0]; - final float centerOffsetY = centerOffset[1]; - final int ix0 = (int) Math.floor((x0 - centerOffsetX) / 128.0); - final int ix1 = (int) Math.ceil((x1 - centerOffsetX) / 128.0); - final int iy0 = (int) Math.floor((y0 - centerOffsetY) / 128.0); - final int iy1 = (int) Math.ceil((y1 - centerOffsetY) / 128.0); - - final GL30 gl = Gdx.gl30; - gl.glBindBuffer(GL30.GL_ARRAY_BUFFER, this.vertexBuffer); - if ((ix0 != this.ix0) || (iy0 != this.iy0) || (ix1 != this.ix1) || (iy1 != this.iy1)) { - // splat geometry has moved, difficult case - final float newVerts = ((iy1 - iy0) + 1) * ((ix1 - ix0) + 1); - if (newVerts <= this.uvs.size()) { - } - int vertexIndex = 0; - float y = 0; - float x = 0; - for (int iy = iy0; iy <= iy1; ++iy) { - y = (iy * 128.0f) + centerOffsetY; - for (int ix = ix0; ix <= ix1; ++ix) { - x = (ix * 128.0f) + centerOffsetX; - final float[] vertexToUpdate = this.vertices.get(vertexIndex); - vertexToUpdate[0] = x; - vertexToUpdate[1] = y; - final float[] uvItem = this.uvs.get(vertexIndex); - uvItem[0] = (x - x0) / this.uvXScale; - uvItem[1] = 1.0f - ((y - y0) / this.uvYScale); - vertexIndex++; - } - } - - for (; vertexIndex < this.vertices.size(); vertexIndex++) { - final float[] vertexToUpdate = this.vertices.get(vertexIndex); - vertexToUpdate[0] = x; - vertexToUpdate[1] = y; - final float[] uvItem = this.uvs.get(vertexIndex); - uvItem[0] = (x - x0) / this.uvXScale; - uvItem[1] = 1.0f - ((y - y0) / this.uvYScale); - } - gl.glBufferSubData(GL30.GL_ARRAY_BUFFER, this.startOffset, 4 * 3 * this.vertices.size(), - RenderMathUtils.wrap(this.vertices)); - - final int step = (ix1 - ix0) + 1; - int faceIndicesIndex = 0; - for (int i = 0; i < (iy1 - iy0); ++i) { - for (int j = 0; j < (ix1 - ix0); ++j) { - final int i0 = this.start + (i * step) + j; - final int[] indexArr = this.indices.get(faceIndicesIndex++); - indexArr[0] = i0; - indexArr[1] = i0 + 1; - indexArr[2] = i0 + step; - indexArr[3] = i0 + 1; - indexArr[4] = i0 + step + 1; - indexArr[5] = i0 + step; - } - } - - for (; faceIndicesIndex < this.indices.size(); faceIndicesIndex++) { - final int i0 = this.start; - final int[] indexArr = this.indices.get(faceIndicesIndex); - for (int i = 0; i < indexArr.length; i++) { - indexArr[i] = i0; - } - } - gl.glBindBuffer(GL30.GL_ELEMENT_ARRAY_BUFFER, this.faceBuffer); - gl.glBufferSubData(GL30.GL_ELEMENT_ARRAY_BUFFER, this.indicesStartOffset, 6 * 2 * this.indices.size(), - RenderMathUtils.wrapFaces(this.indices)); - this.ix0 = ix0; - this.iy0 = iy0; - this.ix1 = ix1; - this.iy1 = iy1; - } - else { - // splat will use same geometry, easy case, just update the UVs - - int index = 0; - for (int iy = iy0; iy <= iy1; ++iy) { - final float y = (iy * 128.0f) + centerOffsetY; - for (int ix = ix0; ix <= ix1; ++ix) { - final float x = (ix * 128.0f) + centerOffsetX; - final float[] uvItem = this.uvs.get(index++); - uvItem[0] = (x - x0) / this.uvXScale; - uvItem[1] = 1.0f - ((y - y0) / this.uvYScale); - } - } - } - gl.glBufferSubData(GL30.GL_ARRAY_BUFFER, this.uvsOffset + ((this.startOffset / 3) * 2), - 4 * 2 * this.uvs.size(), RenderMathUtils.wrap(this.uvs)); - if (this.heightIsAbsolute) { - updateAbsoluteHeightParams(); - } - } - - public void destroy(final GL30 gl, final float[] centerOffset) { - this.splatModel.locations.remove(this.index); - this.splatModel.splatInstances.remove(this.index); - this.splatModel.compact(gl, centerOffset); - } - - public void hide() { - // does not remove the shadow, just makes it not show, so it would still be - // using GPU resources - final GL30 gl = Gdx.gl30; - for (final float[] vertex : this.vertices) { - for (int i = 0; i < vertex.length; i++) { - vertex[i] = 0.0f; - } - } - for (final int[] indices : this.indices) { - for (int i = 0; i < indices.length; i++) { - indices[i] = 0; - } - } - for (final float[] uv : this.uvs) { - for (int i = 0; i < uv.length; i++) { - uv[i] = 0; - } - } - gl.glBindBuffer(GL30.GL_ARRAY_BUFFER, this.vertexBuffer); - gl.glBufferSubData(GL30.GL_ARRAY_BUFFER, this.startOffset, 4 * 3 * this.vertices.size(), - RenderMathUtils.wrap(this.vertices)); - gl.glBindBuffer(GL30.GL_ELEMENT_ARRAY_BUFFER, this.faceBuffer); - gl.glBufferSubData(GL30.GL_ELEMENT_ARRAY_BUFFER, this.indicesStartOffset, 6 * 2 * this.indices.size(), - RenderMathUtils.wrapFaces(this.indices)); - gl.glBufferSubData(GL30.GL_ARRAY_BUFFER, this.uvsOffset + ((this.startOffset / 3) * 2), - 4 * 2 * this.uvs.size(), RenderMathUtils.wrap(this.uvs)); - this.hidden = true; - } - - public void show(final float[] centerOffset) { - // It tries to only update if it is located at a new position... but here we are - // forcing it visible again by putting the position outside the map - this.ix0 = this.ix1 = this.iy0 = this.iy1 = Integer.MIN_VALUE; - move(0, 0, centerOffset); - this.hidden = false; - } - - public void setHeightAbsolute(final boolean absolute, final float absoluteHeightValue) { - this.absoluteHeightValue = absoluteHeightValue; - if (absolute != this.heightIsAbsolute) { - this.heightIsAbsolute = absolute; - updateAbsoluteHeightParams(); - } - } - - private void updateAbsoluteHeightParams() { - final GL30 gl = Gdx.gl30; - final float height = this.heightIsAbsolute ? this.absoluteHeightValue : NO_ABS_HEIGHT; - for (final float[] absHeight : this.absoluteHeights) { - absHeight[0] = height; - } - gl.glBindBuffer(GL30.GL_ARRAY_BUFFER, this.vertexBuffer); - gl.glBufferSubData(GL30.GL_ARRAY_BUFFER, this.absHeightsOffset + (this.startOffset / 3), - this.absoluteHeights.size() * 4, RenderMathUtils.wrap(this.absoluteHeights)); - } - } - - @Override - public int compareTo(final SplatModel other) { - if (this.locations.isEmpty()) { - if (other.locations.isEmpty()) { - return 0; - } - else { - return 1; - } - } - else { - if (other.locations.isEmpty()) { - return -1; - } - else { - return Float.compare(this.locations.get(0)[4], other.locations.get(0)[4]); - } - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/StandSequenceComparator.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/StandSequenceComparator.java deleted file mode 100644 index 1aa65af1..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/StandSequenceComparator.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import java.util.Comparator; - -public class StandSequenceComparator implements Comparator { - @Override - public int compare(final IndexedSequence a, final IndexedSequence b) { - return (int) Math.signum(b.sequence.getRarity() - a.sequence.getRarity()); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/TerrainDoodad.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/TerrainDoodad.java deleted file mode 100644 index eda3fc40..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/TerrainDoodad.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import java.awt.image.BufferedImage; - -import com.badlogic.gdx.math.Quaternion; -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; - -public class TerrainDoodad { - private static final float[] locationHeap = new float[3]; - public final MdxComplexInstance instance; - private final MutableGameObject row; - - public TerrainDoodad(final War3MapViewer map, final MdxModel model, final MutableGameObject row, - final com.etheller.warsmash.parsers.w3x.doo.TerrainDoodad doodad, final BufferedImage pathingTextureImage) { - final float[] centerOffset = map.terrain.centerOffset; - final MdxComplexInstance instance = (MdxComplexInstance) model.addInstance(0); - - final int textureWidth = pathingTextureImage.getWidth(); - final int textureHeight = pathingTextureImage.getHeight(); - final int textureWidthTerrainCells = textureWidth / 4; - final int textureHeightTerrainCells = textureHeight / 4; - final int minCellX = ((int) doodad.getLocation()[0]); - final int minCellY = ((int) doodad.getLocation()[1]); - locationHeap[0] = ((minCellX * 128) + (textureWidthTerrainCells * 64) + centerOffset[0]); - locationHeap[1] = ((minCellY * 128) + (textureHeightTerrainCells * 64) + centerOffset[1]); - - instance.move(locationHeap); - instance.rotate(new Quaternion().setFromAxisRad(RenderMathUtils.VEC3_UNIT_Z, - (float) Math.toRadians(row.readSLKTagFloat("fixedRot")))); - instance.setScene(map.worldScene); - - this.instance = instance; - this.row = row; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/TextTag.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/TextTag.java deleted file mode 100644 index 921995b0..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/TextTag.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.math.Vector3; - -public class TextTag { - private final Vector3 position; - private float screenCoordsZHeight; - private final String text; - private final Color color; - private float lifetime = 0; - - public TextTag(final Vector3 position, final String text, final Color color) { - this.position = position; - this.text = text; - this.color = color; - position.z += 64f; - } - - public boolean update(final float deltaTime) { - this.screenCoordsZHeight += 60.0f * deltaTime; - this.lifetime += deltaTime; - return this.lifetime > 2.5f; - } - - public Vector3 getPosition() { - return this.position; - } - - public float getRemainingLife() { - return 2.5f - this.lifetime; - } - - public Color getColor() { - return this.color; - } - - public String getText() { - return this.text; - } - - public float getScreenCoordsZHeight() { - return this.screenCoordsZHeight; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/UnitSound.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/UnitSound.java deleted file mode 100644 index 98b4fc78..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/UnitSound.java +++ /dev/null @@ -1,148 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.audio.Sound; -import com.badlogic.gdx.utils.TimeUtils; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.units.Element; -import com.etheller.warsmash.util.DataSourceFileHandle; -import com.etheller.warsmash.viewer5.AudioBufferSource; -import com.etheller.warsmash.viewer5.AudioContext; -import com.etheller.warsmash.viewer5.AudioPanner; -import com.etheller.warsmash.viewer5.gl.Extensions; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnit; - -public final class UnitSound { - private static final UnitSound SILENT = new UnitSound(0, 0, 0, 0, 0, 0, false); - - private final List sounds = new ArrayList<>(); - private final float volume; - private final float pitch; - private final float pitchVariance; - private final float minDistance; - private final float maxDistance; - private final float distanceCutoff; - private final boolean looping; - - private Sound lastPlayedSound; - - public static UnitSound create(final DataSource dataSource, final DataTable unitAckSounds, final String soundName, - final String soundType) { - final Element row = unitAckSounds.get(soundName + soundType); - if (row == null) { - return SILENT; - } - final String fileNames = row.getField("FileNames"); - String directoryBase = row.getField("DirectoryBase"); - if ((directoryBase.length() > 1) && !directoryBase.endsWith("\\")) { - directoryBase += "\\"; - } - final float volume = row.getFieldFloatValue("Volume") / 127f; - final float pitch = row.getFieldFloatValue("Pitch"); - float pitchVariance = row.getFieldFloatValue("PitchVariance"); - if (pitchVariance == 1.0f) { - pitchVariance = 0.0f; - } - final float minDistance = row.getFieldFloatValue("MinDistance"); - final float maxDistance = row.getFieldFloatValue("MaxDistance"); - final float distanceCutoff = row.getFieldFloatValue("DistanceCutoff"); - final String[] flags = row.getField("Flags").split(","); - boolean looping = false; - for (final String flag : flags) { - if ("LOOPING".equals(flag)) { - looping = true; - } - } - final UnitSound sound = new UnitSound(volume, pitch, pitchVariance, minDistance, maxDistance, distanceCutoff, - looping); - for (final String fileName : fileNames.split(",")) { - String filePath = directoryBase + fileName; - final int lastDotIndex = filePath.lastIndexOf('.'); - if (lastDotIndex != -1) { - filePath = filePath.substring(0, lastDotIndex); - } - if (dataSource.has(filePath + ".wav") || dataSource.has(filePath + ".flac")) { - try { - sound.sounds.add(Gdx.audio.newSound(new DataSourceFileHandle(dataSource, filePath + ".wav"))); - } - catch (final Exception exc) { - exc.printStackTrace(); - } - } - } - return sound; - } - - public UnitSound(final float volume, final float pitch, final float pitchVariation, final float minDistance, - final float maxDistance, final float distanceCutoff, final boolean looping) { - this.volume = volume; - this.pitch = pitch; - this.pitchVariance = pitchVariation; - this.minDistance = minDistance; - this.maxDistance = maxDistance; - this.distanceCutoff = distanceCutoff; - this.looping = looping; - } - - public boolean playUnitResponse(final AudioContext audioContext, final RenderUnit unit) { - return playUnitResponse(audioContext, unit, (int) (Math.random() * this.sounds.size())); - } - - public boolean playUnitResponse(final AudioContext audioContext, final RenderUnit unit, final int index) { - final long millisTime = TimeUtils.millis(); - if (millisTime < unit.lastUnitResponseEndTimeMillis) { - return false; - } - if (play(audioContext, unit.location[0], unit.location[1], unit.location[2])) { - final float duration = Extensions.audio.getDuration(this.lastPlayedSound); - unit.lastUnitResponseEndTimeMillis = millisTime + (long) (1000 * duration); - return true; - } - return false; - } - - public boolean play(final AudioContext audioContext, final float x, final float y, final float z) { - return play(audioContext, x, y, z, (int) (Math.random() * this.sounds.size())); - } - - public boolean play(final AudioContext audioContext, final float x, final float y, final float z, final int index) { - if (this.sounds.isEmpty()) { - return false; - } - - if (audioContext == null) { - return true; - } - final AudioPanner panner = audioContext.createPanner(); - final AudioBufferSource source = audioContext.createBufferSource(); - - // Panner settings - panner.setPosition(x, y, z); - panner.setDistances(this.distanceCutoff, this.minDistance); - panner.connect(audioContext.destination); - - // Source. - source.buffer = this.sounds.get(index); - source.connect(panner); - - // Make a sound. - source.start(0, this.volume, - (this.pitch + ((float) Math.random() * this.pitchVariance * 2)) - this.pitchVariance, this.looping); - this.lastPlayedSound = source.buffer; - return true; - } - - public int getSoundCount() { - return this.sounds.size(); - } - - public void stop() { - for (final Sound sound : this.sounds) { - sound.stop(); - } - } -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/UnitSoundset.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/UnitSoundset.java deleted file mode 100644 index 70553ef6..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/UnitSoundset.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.units.DataTable; - -public class UnitSoundset { - public final UnitSound what; - public final UnitSound pissed; - public final UnitSound yesAttack; - public final UnitSound yes; - public final UnitSound ready; - public final UnitSound warcry; - - public UnitSoundset(final DataSource dataSource, final DataTable unitAckSounds, final String soundName) { - this.what = UnitSound.create(dataSource, unitAckSounds, soundName, "What"); - this.pissed = UnitSound.create(dataSource, unitAckSounds, soundName, "Pissed"); - this.yesAttack = UnitSound.create(dataSource, unitAckSounds, soundName, "YesAttack"); - this.yes = UnitSound.create(dataSource, unitAckSounds, soundName, "Yes"); - this.ready = UnitSound.create(dataSource, unitAckSounds, soundName, "Ready"); - this.warcry = UnitSound.create(dataSource, unitAckSounds, soundName, "Warcry"); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/Variations.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/Variations.java deleted file mode 100644 index d121da58..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/Variations.java +++ /dev/null @@ -1,159 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import java.util.HashMap; -import java.util.Map; - -public class Variations { - public static final Map CLIFF_VARS; - public static final Map CITY_CLIFF_VARS; - - static { - final Map cliffVariations = new HashMap<>(); - cliffVariations.put("AAAB", 1); - cliffVariations.put("AAAC", 1); - cliffVariations.put("AABA", 1); - cliffVariations.put("AABB", 2); - cliffVariations.put("AABC", 0); - cliffVariations.put("AACA", 1); - cliffVariations.put("AACB", 0); - cliffVariations.put("AACC", 1); - cliffVariations.put("ABAA", 1); - cliffVariations.put("ABAB", 1); - cliffVariations.put("ABAC", 0); - cliffVariations.put("ABBA", 2); - cliffVariations.put("ABBB", 1); - cliffVariations.put("ABBC", 0); - cliffVariations.put("ABCA", 0); - cliffVariations.put("ABCB", 0); - cliffVariations.put("ABCC", 0); - cliffVariations.put("ACAA", 1); - cliffVariations.put("ACAB", 0); - cliffVariations.put("ACAC", 1); - cliffVariations.put("ACBA", 0); - cliffVariations.put("ACBB", 0); - cliffVariations.put("ACBC", 0); - cliffVariations.put("ACCA", 1); - cliffVariations.put("ACCB", 0); - cliffVariations.put("ACCC", 1); - cliffVariations.put("BAAA", 1); - cliffVariations.put("BAAB", 1); - cliffVariations.put("BAAC", 0); - cliffVariations.put("BABA", 1); - cliffVariations.put("BABB", 1); - cliffVariations.put("BABC", 0); - cliffVariations.put("BACA", 0); - cliffVariations.put("BACB", 0); - cliffVariations.put("BACC", 0); - cliffVariations.put("BBAA", 1); - cliffVariations.put("BBAB", 1); - cliffVariations.put("BBAC", 0); - cliffVariations.put("BBBA", 1); - cliffVariations.put("BBCA", 0); - cliffVariations.put("BCAA", 0); - cliffVariations.put("BCAB", 0); - cliffVariations.put("BCAC", 0); - cliffVariations.put("BCBA", 0); - cliffVariations.put("BCCA", 0); - cliffVariations.put("CAAA", 1); - cliffVariations.put("CAAB", 0); - cliffVariations.put("CAAC", 1); - cliffVariations.put("CABA", 0); - cliffVariations.put("CABB", 0); - cliffVariations.put("CABC", 0); - cliffVariations.put("CACA", 1); - cliffVariations.put("CACB", 0); - cliffVariations.put("CACC", 1); - cliffVariations.put("CBAA", 0); - cliffVariations.put("CBAB", 0); - cliffVariations.put("CBAC", 0); - cliffVariations.put("CBBA", 0); - cliffVariations.put("CBCA", 0); - cliffVariations.put("CCAA", 1); - cliffVariations.put("CCAB", 0); - cliffVariations.put("CCAC", 1); - cliffVariations.put("CCBA", 0); - cliffVariations.put("CCCA", 1); - CLIFF_VARS = cliffVariations; - - final Map cityCliffVariations = new HashMap<>(); - cityCliffVariations.put("AAAB", 2); - cityCliffVariations.put("AAAC", 1); - cityCliffVariations.put("AABA", 1); - cityCliffVariations.put("AABB", 3); - cityCliffVariations.put("AABC", 0); - cityCliffVariations.put("AACA", 1); - cityCliffVariations.put("AACB", 0); - cityCliffVariations.put("AACC", 3); - cityCliffVariations.put("ABAA", 1); - cityCliffVariations.put("ABAB", 2); - cityCliffVariations.put("ABAC", 0); - cityCliffVariations.put("ABBA", 3); - cityCliffVariations.put("ABBB", 0); - cityCliffVariations.put("ABBC", 0); - cityCliffVariations.put("ABCA", 0); - cityCliffVariations.put("ABCB", 0); - cityCliffVariations.put("ABCC", 0); - cityCliffVariations.put("ACAA", 1); - cityCliffVariations.put("ACAB", 0); - cityCliffVariations.put("ACAC", 2); - cityCliffVariations.put("ACBA", 0); - cityCliffVariations.put("ACBB", 0); - cityCliffVariations.put("ACBC", 0); - cityCliffVariations.put("ACCA", 3); - cityCliffVariations.put("ACCB", 0); - cityCliffVariations.put("ACCC", 1); - cityCliffVariations.put("BAAA", 1); - cityCliffVariations.put("BAAB", 3); - cityCliffVariations.put("BAAC", 0); - cityCliffVariations.put("BABA", 2); - cityCliffVariations.put("BABB", 0); - cityCliffVariations.put("BABC", 0); - cityCliffVariations.put("BACA", 0); - cityCliffVariations.put("BACB", 0); - cityCliffVariations.put("BACC", 0); - cityCliffVariations.put("BBAA", 3); - cityCliffVariations.put("BBAB", 1); - cityCliffVariations.put("BBAC", 0); - cityCliffVariations.put("BBBA", 1); - cityCliffVariations.put("BBCA", 0); - cityCliffVariations.put("BCAA", 0); - cityCliffVariations.put("BCAB", 0); - cityCliffVariations.put("BCAC", 0); - cityCliffVariations.put("BCBA", 0); - cityCliffVariations.put("BCCA", 0); - cityCliffVariations.put("CAAA", 1); - cityCliffVariations.put("CAAB", 0); - cityCliffVariations.put("CAAC", 3); - cityCliffVariations.put("CABA", 0); - cityCliffVariations.put("CABB", 0); - cityCliffVariations.put("CABC", 0); - cityCliffVariations.put("CACA", 2); - cityCliffVariations.put("CACB", 0); - cityCliffVariations.put("CACC", 1); - cityCliffVariations.put("CBAA", 0); - cityCliffVariations.put("CBAB", 0); - cityCliffVariations.put("CBAC", 0); - cityCliffVariations.put("CBBA", 0); - cityCliffVariations.put("CBCA", 0); - cityCliffVariations.put("CCAA", 3); - cityCliffVariations.put("CCAB", 0); - cityCliffVariations.put("CCAC", 1); - cityCliffVariations.put("CCBA", 0); - cityCliffVariations.put("CCCA", 1); - CITY_CLIFF_VARS = cityCliffVariations; - } - - public static int getCliffVariation(final String dir, final String tag, final int variation) { - final Integer vars; - if ("Cliffs".equals(dir)) { - vars = CLIFF_VARS.get(tag); - } - else { - vars = CITY_CLIFF_VARS.get(tag); - } - if (variation < vars) { - return variation; - } - return variation % (vars + 1); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xSceneLight.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xSceneLight.java deleted file mode 100644 index 1bc01c41..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xSceneLight.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -public class W3xSceneLight { - - public static enum Type { - OMNIDIRECTIONAL, - DIRECTIONAL; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xSceneLightManager.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xSceneLightManager.java deleted file mode 100644 index 282d947a..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xSceneLightManager.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import com.etheller.warsmash.viewer5.gl.DataTexture; - -public interface W3xSceneLightManager { - public DataTexture getUnitLightsTexture(); - - public int getUnitLightCount(); - - public DataTexture getTerrainLightsTexture(); - - public int getTerrainLightCount(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xScenePortraitLightManager.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xScenePortraitLightManager.java deleted file mode 100644 index df3f4be8..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xScenePortraitLightManager.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.viewer5.ModelViewer; -import com.etheller.warsmash.viewer5.SceneLightInstance; -import com.etheller.warsmash.viewer5.SceneLightManager; -import com.etheller.warsmash.viewer5.gl.DataTexture; -import com.etheller.warsmash.viewer5.handlers.mdx.Light; -import com.etheller.warsmash.viewer5.handlers.mdx.LightInstance; - -public class W3xScenePortraitLightManager implements SceneLightManager, W3xSceneLightManager { - private final ModelViewer viewer; - private final Vector3 hardcodedLightDirection; - public final List lights; - private FloatBuffer lightDataCopyHeap; - private final DataTexture unitLightsTexture; - private int unitLightCount; - - public W3xScenePortraitLightManager(final ModelViewer viewer, final Vector3 lightDirection) { - this.viewer = viewer; - this.hardcodedLightDirection = lightDirection; - this.lights = new ArrayList<>(); - this.unitLightsTexture = new DataTexture(viewer.gl, 4, 4, 1); - this.lightDataCopyHeap = ByteBuffer.allocateDirect(16 * 1 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); - } - - @Override - public void add(final SceneLightInstance lightInstance) { - // TODO redesign to avoid cast - final LightInstance mdxLight = (LightInstance) lightInstance; - this.lights.add(mdxLight); - } - - @Override - public void remove(final SceneLightInstance lightInstance) { - // TODO redesign to avoid cast - final LightInstance mdxLight = (LightInstance) lightInstance; - this.lights.remove(mdxLight); - } - - @Override - public void update() { - final int numberOfLights = this.lights.size() + 1; - final int bytesNeeded = numberOfLights * 4 * 16; - if (bytesNeeded > (this.lightDataCopyHeap.capacity() * 4)) { - this.lightDataCopyHeap = ByteBuffer.allocateDirect(bytesNeeded).order(ByteOrder.nativeOrder()) - .asFloatBuffer(); - this.unitLightsTexture.reserve(4, numberOfLights); - } - - this.unitLightCount = 0; - this.lightDataCopyHeap.clear(); - int offset = 0; - this.lightDataCopyHeap.put(offset, this.hardcodedLightDirection.y); - this.lightDataCopyHeap.put(offset + 1, -this.hardcodedLightDirection.x); - this.lightDataCopyHeap.put(offset + 2, -this.hardcodedLightDirection.z); - this.lightDataCopyHeap.put(offset + 3, -this.hardcodedLightDirection.z); - this.lightDataCopyHeap.put(offset + 4, Light.Type.DIRECTIONAL.ordinal()); - this.lightDataCopyHeap.put(offset + 5, 1); - this.lightDataCopyHeap.put(offset + 6, 2); - this.lightDataCopyHeap.put(offset + 7, 0); - this.lightDataCopyHeap.put(offset + 8, 1); - this.lightDataCopyHeap.put(offset + 9, 1); - this.lightDataCopyHeap.put(offset + 10, 1); - this.lightDataCopyHeap.put(offset + 11, 1); - this.lightDataCopyHeap.put(offset + 12, 1); - this.lightDataCopyHeap.put(offset + 13, 1); - this.lightDataCopyHeap.put(offset + 14, 1); - this.lightDataCopyHeap.put(offset + 15, 0.3f); - offset += 16; - this.unitLightCount++; - for (final LightInstance light : this.lights) { - light.bind(offset, this.lightDataCopyHeap); - offset += 16; - this.unitLightCount++; - } - this.lightDataCopyHeap.limit(offset); - this.unitLightsTexture.bindAndUpdate(this.lightDataCopyHeap, 4, this.unitLightCount); - } - - @Override - public DataTexture getUnitLightsTexture() { - return this.unitLightsTexture; - } - - @Override - public int getUnitLightCount() { - return this.unitLightCount; - } - - @Override - public DataTexture getTerrainLightsTexture() { - return null; - } - - @Override - public int getTerrainLightCount() { - return 0; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xSceneWorldLightManager.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xSceneWorldLightManager.java deleted file mode 100644 index e8c4ccb9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xSceneWorldLightManager.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.viewer5.SceneLightInstance; -import com.etheller.warsmash.viewer5.SceneLightManager; -import com.etheller.warsmash.viewer5.gl.DataTexture; -import com.etheller.warsmash.viewer5.handlers.mdx.LightInstance; - -public class W3xSceneWorldLightManager implements SceneLightManager, W3xSceneLightManager { - public final List lights; - private FloatBuffer lightDataCopyHeap; - private final DataTexture unitLightsTexture; - private final DataTexture terrainLightsTexture; - private final War3MapViewer viewer; - private int terrainLightCount; - private int unitLightCount; - - public W3xSceneWorldLightManager(final War3MapViewer viewer) { - this.viewer = viewer; - this.lights = new ArrayList<>(); - this.unitLightsTexture = new DataTexture(viewer.gl, 4, 4, 1); - this.terrainLightsTexture = new DataTexture(viewer.gl, 4, 4, 1); - this.lightDataCopyHeap = ByteBuffer.allocateDirect(16 * 1 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); - } - - @Override - public void add(final SceneLightInstance lightInstance) { - // TODO redesign to avoid cast - final LightInstance mdxLight = (LightInstance) lightInstance; - this.lights.add(mdxLight); - } - - @Override - public void remove(final SceneLightInstance lightInstance) { - // TODO redesign to avoid cast - final LightInstance mdxLight = (LightInstance) lightInstance; - this.lights.remove(mdxLight); - } - - @Override - public void update() { - final int numberOfLights = this.lights.size() + 1; - final int bytesNeeded = numberOfLights * 4 * 16; - if (bytesNeeded > (this.lightDataCopyHeap.capacity() * 4)) { - this.lightDataCopyHeap = ByteBuffer.allocateDirect(bytesNeeded).order(ByteOrder.nativeOrder()) - .asFloatBuffer(); - this.unitLightsTexture.reserve(4, numberOfLights); - this.terrainLightsTexture.reserve(4, numberOfLights); - } - - this.unitLightCount = 0; - this.lightDataCopyHeap.clear(); - int offset = 0; - if (this.viewer.dncUnit != null) { - if (!this.viewer.dncUnit.lights.isEmpty()) { - this.viewer.dncUnit.lights.get(0).bind(0, this.lightDataCopyHeap); - offset += 16; - this.unitLightCount++; - } - } - for (final LightInstance light : this.lights) { - light.bind(offset, this.lightDataCopyHeap); - offset += 16; - this.unitLightCount++; - } - this.lightDataCopyHeap.limit(offset); - this.unitLightsTexture.bindAndUpdate(this.lightDataCopyHeap, 4, this.unitLightCount); - - this.terrainLightCount = 0; - this.lightDataCopyHeap.clear(); - offset = 0; - if (this.viewer.dncTerrain != null) { - if (!this.viewer.dncTerrain.lights.isEmpty()) { - this.viewer.dncTerrain.lights.get(0).bind(0, this.lightDataCopyHeap); - offset += 16; - this.terrainLightCount++; - } - } - for (final LightInstance light : this.lights) { - light.bind(offset, this.lightDataCopyHeap); - offset += 16; - this.terrainLightCount++; - } - this.lightDataCopyHeap.limit(offset); - this.terrainLightsTexture.bindAndUpdate(this.lightDataCopyHeap, 4, this.terrainLightCount); - } - - @Override - public DataTexture getUnitLightsTexture() { - return this.unitLightsTexture; - } - - @Override - public int getUnitLightCount() { - return this.unitLightCount; - } - - @Override - public DataTexture getTerrainLightsTexture() { - return this.terrainLightsTexture; - } - - @Override - public int getTerrainLightCount() { - return this.terrainLightCount; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xShaders.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xShaders.java deleted file mode 100644 index 9a397354..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xShaders.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import com.etheller.warsmash.viewer5.Shaders; - -public class W3xShaders { - public static final class UberSplat { - private UberSplat() { - } - - public static final String vert() { - return "\r\n" + // - "\r\n" + // - " uniform mat4 u_mvp;\r\n" + // - " uniform sampler2D u_heightMap;\r\n" + // - " uniform vec2 u_pixel;\r\n" + // - " uniform vec2 u_size;\r\n" + // - " uniform vec2 u_shadowPixel;\r\n" + // - " uniform vec2 u_centerOffset;\r\n" + // - " uniform sampler2D u_lightTexture;\r\n" + // - " uniform float u_lightCount;\r\n" + // - " uniform float u_lightTextureHeight;\r\n" + // - " attribute vec3 a_position;\r\n" + // - " attribute vec2 a_uv;\r\n" + // - " attribute float a_absoluteHeight;\r\n" + // - " varying vec2 v_uv;\r\n" + // - " varying vec2 v_suv;\r\n" + // - " varying vec3 v_normal;\r\n" + // - " varying float a_positionHeight;\r\n" + // - " varying vec3 shadeColor;\r\n" + // - " const float normalDist = 0.25;\r\n" + // - " void main() {\r\n" + // - " vec2 halfPixel = u_pixel * 0.5;\r\n" + // - " vec2 base = (a_position.xy - u_centerOffset) / 128.0;\r\n" + // - " float height;\r\n" + // - " float hL;\r\n" + // - " float hR;\r\n" + // - " float hD;\r\n" + // - " float hU;\r\n" + // - " if (a_absoluteHeight < -256.0) {\r\n" + // - " height = texture2D(u_heightMap, base * u_pixel + halfPixel).r * 128.0;\r\n" + // - " hL = texture2D(u_heightMap, vec2(base - vec2(normalDist, 0.0)) * u_pixel + halfPixel).r;\r\n" - + // - " hR = texture2D(u_heightMap, vec2(base + vec2(normalDist, 0.0)) * u_pixel + halfPixel).r;\r\n" - + // - " hD = texture2D(u_heightMap, vec2(base - vec2(0.0, normalDist)) * u_pixel + halfPixel).r;\r\n" - + // - " hU = texture2D(u_heightMap, vec2(base + vec2(0.0, normalDist)) * u_pixel + halfPixel).r;\r\n" - + // - " } else {\r\n" + // - " height = a_absoluteHeight;\r\n" + // - " hL = a_absoluteHeight;\r\n" + // - " hR = a_absoluteHeight;\r\n" + // - " hD = a_absoluteHeight;\r\n" + // - " hU = a_absoluteHeight;\r\n" + // - " }\r\n" + // - " v_normal = normalize(vec3(hL - hR, hD - hU, normalDist * 2.0));\r\n" + // - " v_uv = a_uv;\r\n" + // - " v_suv = base / u_size;\r\n" + // - " vec3 myposition = vec3(a_position.xy, height + a_position.z);\r\n" + // - " gl_Position = u_mvp * vec4(myposition.xyz, 1.0);\r\n" + // - " a_positionHeight = a_position.z;\r\n" + // - Shaders.lightSystem("v_normal", "myposition", "u_lightTexture", "u_lightTextureHeight", - "u_lightCount", true) - + "\r\n" + // - " shadeColor = clamp(lightFactor, 0.0, 1.0);\r\n" + // - " }\r\n" + // - " "; - } - - public static final String frag = "\r\n" + // - " uniform sampler2D u_texture;\r\n" + // - " uniform sampler2D u_shadowMap;\r\n" + // - " uniform vec4 u_color;\r\n" + // - " uniform bool u_show_lighting;\r\n" + // - " varying vec2 v_uv;\r\n" + // - " varying vec2 v_suv;\r\n" + // - " varying vec3 v_normal;\r\n" + // - " varying float a_positionHeight;\r\n" + // - " varying vec3 shadeColor;\r\n" + // - // " const vec3 lightDirection = normalize(vec3(-0.3, -0.3, 0.25));\r\n" + // - " void main() {\r\n" + // - " if (any(bvec4(lessThan(v_uv, vec2(0.0)), greaterThan(v_uv, vec2(1.0))))) {\r\n" + // - " discard;\r\n" + // - " }\r\n" + // - " vec4 color = texture2D(u_texture, clamp(v_uv, 0.0, 1.0)).rgba * u_color;\r\n" + // - " float shadow = texture2D(u_shadowMap, v_suv).r;\r\n" + // - // " color.xyz *= clamp(dot(v_normal, lightDirection) + 0.45, 0.0, 1.0);\r\n" + - // // - " if (a_positionHeight <= 4.0) {;\r\n" + // - " color.xyz *= 1.0 - shadow;\r\n" + // - " };\r\n" + // - " if (u_show_lighting) {;\r\n" + // - " color.xyz *= shadeColor;\r\n" + // - " };\r\n" + // - " gl_FragColor = color;\r\n" + // - " }\r\n" + // - " "; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xShadersWebGLDeprecated.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xShadersWebGLDeprecated.java deleted file mode 100644 index 1562e360..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/W3xShadersWebGLDeprecated.java +++ /dev/null @@ -1,230 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -public class W3xShadersWebGLDeprecated { - public static final class Cliffs { - private Cliffs() { - } - - public static final String vert = "\r\n" + // - "uniform mat4 u_VP;\r\n" + // - "uniform sampler2D u_heightMap;\r\n" + // - "uniform vec2 u_pixel;\r\n" + // - "uniform vec2 u_centerOffset;\r\n" + // - "attribute vec3 a_position;\r\n" + // - "attribute vec3 a_normal;\r\n" + // - "attribute vec2 a_uv;\r\n" + // - "attribute vec3 a_instancePosition;\r\n" + // - "attribute float a_instanceTexture;\r\n" + // - "varying vec3 v_normal;\r\n" + // - "varying vec2 v_uv;\r\n" + // - "varying float v_texture;\r\n" + // - "varying vec3 v_position;\r\n" + // - "void main() {\r\n" + // - " // Half of a pixel in the cliff height map.\r\n" + // - " vec2 halfPixel = u_pixel * 0.5;\r\n" + // - " // The bottom left corner of the map tile this vertex is on.\r\n" + // - " vec2 corner = floor((a_instancePosition.xy - vec2(1.0, 0.0) - u_centerOffset.xy) / 128.0);\r\n" + // - " // Get the 4 closest heights in the height map.\r\n" + // - " float bottomLeft = texture2D(u_heightMap, corner * u_pixel + halfPixel).a;\r\n" + // - " float bottomRight = texture2D(u_heightMap, (corner + vec2(1.0, 0.0)) * u_pixel + halfPixel).a;\r\n" + // - " float topLeft = texture2D(u_heightMap, (corner + vec2(0.0, 1.0)) * u_pixel + halfPixel).a;\r\n" + // - " float topRight = texture2D(u_heightMap, (corner + vec2(1.0, 1.0)) * u_pixel + halfPixel).a;\r\n" + // - " \r\n" + // - " // Do a bilinear interpolation between the heights to get the final value.\r\n" + // - " float bottom = mix(bottomRight, bottomLeft, -a_position.x / 128.0);\r\n" + // - " float top = mix(topRight, topLeft, -a_position.x / 128.0);\r\n" + // - " float height = mix(bottom, top, a_position.y / 128.0);\r\n" + // - " v_normal = a_normal;\r\n" + // - " v_uv = a_uv;\r\n" + // - " v_texture = a_instanceTexture;\r\n" + // - " v_position = a_position + vec3(a_instancePosition.xy, a_instancePosition.z + height * 128.0);\r\n" + // - " gl_Position = u_VP * vec4(v_position, 1.0);\r\n" + // - "}\r\n" + // - ""; - - public static final String frag = "\r\n" + // - "// #extension GL_OES_standard_derivatives : enable\r\n" + // - "precision mediump float;\r\n" + // - "uniform sampler2D u_texture1;\r\n" + // - "uniform sampler2D u_texture2;\r\n" + // - "varying vec3 v_normal;\r\n" + // - "varying vec2 v_uv;\r\n" + // - "varying float v_texture;\r\n" + // - "varying vec3 v_position;\r\n" + // - "// const vec3 lightDirection = normalize(vec3(-0.3, -0.3, 0.25));\r\n" + // - "vec4 sample(int texture, vec2 uv) {\r\n" + // - " if (texture == 0) {\r\n" + // - " return texture2D(u_texture1, uv);\r\n" + // - " } else {\r\n" + // - " return texture2D(u_texture2, uv);\r\n" + // - " }\r\n" + // - "}\r\n" + // - "void main() {\r\n" + // - " vec4 color = sample(int(v_texture), v_uv);\r\n" + // - " // vec3 faceNormal = cross(dFdx(v_position), dFdy(v_position));\r\n" + // - " // vec3 normal = normalize((faceNormal + v_normal) * 0.5);\r\n" + // - " // color *= clamp(dot(normal, lightDirection) + 0.45, 0.1, 1.0);\r\n" + // - " gl_FragColor = color;\r\n" + // - "}\r\n" + // - ""; - } - - public static final class Ground { - private Ground() { - } - - public static final String frag = "\r\n" + // - "precision mediump float;\r\n" + // - "uniform sampler2D u_tilesets[15];\r\n" + // - "varying vec4 v_tilesets;\r\n" + // - "varying vec2 v_uv[4];\r\n" + // - "varying vec3 v_normal;\r\n" + // - "const vec3 lightDirection = normalize(vec3(-0.3, -0.3, 0.25));\r\n" + // - "vec4 sample(float tileset, vec2 uv) {\r\n" + // - " if (tileset == 0.0) {\r\n" + // - " return texture2D(u_tilesets[0], uv);\r\n" + // - " } else if (tileset == 1.0) {\r\n" + // - " return texture2D(u_tilesets[1], uv);\r\n" + // - " } else if (tileset == 2.0) {\r\n" + // - " return texture2D(u_tilesets[2], uv);\r\n" + // - " } else if (tileset == 3.0) {\r\n" + // - " return texture2D(u_tilesets[3], uv);\r\n" + // - " } else if (tileset == 4.0) {\r\n" + // - " return texture2D(u_tilesets[4], uv);\r\n" + // - " } else if (tileset == 5.0) {\r\n" + // - " return texture2D(u_tilesets[5], uv);\r\n" + // - " } else if (tileset == 6.0) {\r\n" + // - " return texture2D(u_tilesets[6], uv);\r\n" + // - " } else if (tileset == 7.0) {\r\n" + // - " return texture2D(u_tilesets[7], uv);\r\n" + // - " } else if (tileset == 8.0) {\r\n" + // - " return texture2D(u_tilesets[8], uv);\r\n" + // - " } else if (tileset == 9.0) {\r\n" + // - " return texture2D(u_tilesets[9], uv);\r\n" + // - " } else if (tileset == 10.0) {\r\n" + // - " return texture2D(u_tilesets[10], uv);\r\n" + // - " } else if (tileset == 11.0) {\r\n" + // - " return texture2D(u_tilesets[11], uv);\r\n" + // - " } else if (tileset == 12.0) {\r\n" + // - " return texture2D(u_tilesets[12], uv);\r\n" + // - " } else if (tileset == 13.0) {\r\n" + // - " return texture2D(u_tilesets[13], uv);\r\n" + // - " } else if (tileset == 14.0) {\r\n" + // - " return texture2D(u_tilesets[14], uv);\r\n" + // - " }\r\n" + // - "}\r\n" + // - "vec4 blend(vec4 color, float tileset, vec2 uv) {\r\n" + // - " vec4 texel = sample(tileset, uv);\r\n" + // - " return mix(color, texel, texel.a);\r\n" + // - "}\r\n" + // - "void main() {\r\n" + // - " vec4 color = sample(v_tilesets[0] - 1.0, v_uv[0]);\r\n" + // - " if (v_tilesets[1] > 0.5) {\r\n" + // - " color = blend(color, v_tilesets[1] - 1.0, v_uv[1]);\r\n" + // - " }\r\n" + // - " if (v_tilesets[2] > 0.5) {\r\n" + // - " color = blend(color, v_tilesets[2] - 1.0, v_uv[2]);\r\n" + // - " }\r\n" + // - " if (v_tilesets[3] > 0.5) {\r\n" + // - " color = blend(color, v_tilesets[3] - 1.0, v_uv[3]);\r\n" + // - " }\r\n" + // - " // color *= clamp(dot(v_normal, lightDirection) + 0.45, 0.0, 1.0);\r\n" + // - " gl_FragColor = color;\r\n" + // - "}\r\n" + // - ""; - - public static final String vert = "\r\n" + // - "uniform mat4 u_VP;\r\n" + // - "uniform sampler2D u_heightMap;\r\n" + // - "uniform vec2 u_pixel;\r\n" + // - "uniform vec2 u_centerOffset;\r\n" + // - "attribute vec3 a_position;\r\n" + // - "attribute vec3 a_normal;\r\n" + // - "attribute vec2 a_uv;\r\n" + // - "attribute vec3 a_instancePosition;\r\n" + // - "attribute float a_instanceTexture;\r\n" + // - "varying vec3 v_normal;\r\n" + // - "varying vec2 v_uv;\r\n" + // - "varying float v_texture;\r\n" + // - "varying vec3 v_position;\r\n" + // - "void main() {\r\n" + // - " // Half of a pixel in the cliff height map.\r\n" + // - " vec2 halfPixel = u_pixel * 0.5;\r\n" + // - " // The bottom left corner of the map tile this vertex is on.\r\n" + // - " vec2 corner = floor((a_instancePosition.xy - vec2(1.0, 0.0) - u_centerOffset.xy) / 128.0);\r\n" + // - " // Get the 4 closest heights in the height map.\r\n" + // - " float bottomLeft = texture2D(u_heightMap, corner * u_pixel + halfPixel).a;\r\n" + // - " float bottomRight = texture2D(u_heightMap, (corner + vec2(1.0, 0.0)) * u_pixel + halfPixel).a;\r\n" + // - " float topLeft = texture2D(u_heightMap, (corner + vec2(0.0, 1.0)) * u_pixel + halfPixel).a;\r\n" + // - " float topRight = texture2D(u_heightMap, (corner + vec2(1.0, 1.0)) * u_pixel + halfPixel).a;\r\n" + // - " \r\n" + // - " // Do a bilinear interpolation between the heights to get the final value.\r\n" + // - " float bottom = mix(bottomRight, bottomLeft, -a_position.x / 128.0);\r\n" + // - " float top = mix(topRight, topLeft, -a_position.x / 128.0);\r\n" + // - " float height = mix(bottom, top, a_position.y / 128.0);\r\n" + // - " v_normal = a_normal;\r\n" + // - " v_uv = a_uv;\r\n" + // - " v_texture = a_instanceTexture;\r\n" + // - " v_position = a_position + vec3(a_instancePosition.xy, a_instancePosition.z + height * 128.0);\r\n" + // - " gl_Position = u_VP * vec4(v_position, 1.0);\r\n" + // - "}\r\n" + // - ""; - } - - public static final class Water { - private Water() { - } - - public static final String frag = "\r\n" + // - "precision mediump float;\r\n" + // - "uniform sampler2D u_waterTexture;\r\n" + // - "varying vec2 v_uv;\r\n" + // - "varying vec4 v_color;\r\n" + // - "void main() {\r\n" + // - " gl_FragColor = texture2D(u_waterTexture, v_uv) * v_color;\r\n" + // - "}\r\n" + // - ""; - public static final String vert = "\r\n" + // - "uniform mat4 u_VP;\r\n" + // - "uniform sampler2D u_heightMap;\r\n" + // - "uniform sampler2D u_waterHeightMap;\r\n" + // - "uniform vec2 u_size;\r\n" + // - "uniform vec2 u_offset;\r\n" + // - "uniform float u_offsetHeight;\r\n" + // - "uniform vec4 u_minDeepColor;\r\n" + // - "uniform vec4 u_maxDeepColor;\r\n" + // - "uniform vec4 u_minShallowColor;\r\n" + // - "uniform vec4 u_maxShallowColor;\r\n" + // - "attribute vec2 a_position;\r\n" + // - "attribute float a_InstanceID;\r\n" + // - "attribute float a_isWater;\r\n" + // - "varying vec2 v_uv;\r\n" + // - "varying vec4 v_color;\r\n" + // - "const float minDepth = 10.0 / 128.0;\r\n" + // - "const float deepLevel = 64.0 / 128.0;\r\n" + // - "const float maxDepth = 72.0 / 128.0;\r\n" + // - "void main() {\r\n" + // - " if (a_isWater > 0.5) {\r\n" + // - " v_uv = a_position;\r\n" + // - " vec2 corner = vec2(mod(a_InstanceID, u_size.x), floor(a_InstanceID / u_size.x));\r\n" + // - " vec2 base = corner + a_position;\r\n" + // - " float height = texture2D(u_heightMap, base / u_size).a;\r\n" + // - " float waterHeight = texture2D(u_waterHeightMap, base / u_size).a + u_offsetHeight;\r\n" + // - " float value = clamp(waterHeight - height, 0.0, 1.0);\r\n" + // - " if (value <= deepLevel) {\r\n" + // - " value = max(0.0, value - minDepth) / (deepLevel - minDepth);\r\n" + // - " v_color = mix(u_minShallowColor, u_maxShallowColor, value) / 255.0;\r\n" + // - " } else {\r\n" + // - " value = clamp(value - deepLevel, 0.0, maxDepth - deepLevel) / (maxDepth - deepLevel);\r\n" + // - " v_color = mix(u_minDeepColor, u_maxDeepColor, value) / 255.0;\r\n" + // - " }\r\n" + // - " gl_Position = u_VP * vec4(base * 128.0 + u_offset, waterHeight * 128.0, 1.0);\r\n" + // - " } else {\r\n" + // - " v_uv = vec2(0.0);\r\n" + // - " v_color = vec4(0.0);\r\n" + // - " gl_Position = vec4(0.0);\r\n" + // - " }\r\n" + // - "}\r\n" + // - ""; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java deleted file mode 100644 index a6220f82..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/War3MapViewer.java +++ /dev/null @@ -1,2249 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x; - -import java.awt.image.BufferedImage; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.nio.channels.SeekableByteChannel; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.function.Consumer; - -import javax.imageio.ImageIO; - -import org.apache.commons.compress.utils.IOUtils; -import org.apache.commons.compress.utils.SeekableInMemoryByteChannel; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.math.collision.BoundingBox; -import com.badlogic.gdx.math.collision.Ray; -import com.etheller.warsmash.common.FetchDataTypeName; -import com.etheller.warsmash.common.LoadGenericCallback; -import com.etheller.warsmash.datasources.CompoundDataSource; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.datasources.MpqDataSource; -import com.etheller.warsmash.datasources.SubdirDataSource; -import com.etheller.warsmash.networking.GameTurnManager; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.w3x.War3Map; -import com.etheller.warsmash.parsers.w3x.doo.War3MapDoo; -import com.etheller.warsmash.parsers.w3x.objectdata.Warcraft3MapObjectData; -import com.etheller.warsmash.parsers.w3x.unitsdoo.War3MapUnitsDoo; -import com.etheller.warsmash.parsers.w3x.w3e.War3MapW3e; -import com.etheller.warsmash.parsers.w3x.w3i.Player; -import com.etheller.warsmash.parsers.w3x.w3i.War3MapW3i; -import com.etheller.warsmash.parsers.w3x.wpm.War3MapWpm; -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.units.Element; -import com.etheller.warsmash.units.StandardObjectData; -import com.etheller.warsmash.units.custom.WTS; -import com.etheller.warsmash.units.manager.MutableObjectData; -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.units.manager.MutableObjectData.WorldEditorDataType; -import com.etheller.warsmash.util.MappedData; -import com.etheller.warsmash.util.Quadtree; -import com.etheller.warsmash.util.QuadtreeIntersector; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.util.WorldEditStrings; -import com.etheller.warsmash.viewer5.CanvasProvider; -import com.etheller.warsmash.viewer5.GenericResource; -import com.etheller.warsmash.viewer5.Grid; -import com.etheller.warsmash.viewer5.ModelInstance; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.SceneLightManager; -import com.etheller.warsmash.viewer5.Texture; -import com.etheller.warsmash.viewer5.WorldScene; -import com.etheller.warsmash.viewer5.gl.WebGL; -import com.etheller.warsmash.viewer5.handlers.AbstractMdxModelViewer; -import com.etheller.warsmash.viewer5.handlers.mdx.Attachment; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxHandler.ShaderEnvironmentType; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxNode; -import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode; -import com.etheller.warsmash.viewer5.handlers.tga.TgaFile; -import com.etheller.warsmash.viewer5.handlers.w3x.SplatModel.SplatMover; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.BuildingShadow; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.RemovablePathingMapInstance; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.Terrain; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.Terrain.Splat; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderAttackInstant; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderAttackProjectile; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderDoodad; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderEffect; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderItem; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnitTypeData; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.AbilityDataUI; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.AbilityUI; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitClassification; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidgetFilterFunction; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackInstant; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissile; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.projectile.CAttackProjectile; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.CBasePlayer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.War3MapConfig; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapControl; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRacePreference; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.SettableCommandErrorListener; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.sound.KeyedSounds; - -import mpq.MPQArchive; -import mpq.MPQException; - -public class War3MapViewer extends AbstractMdxModelViewer { - public static int DEBUG_DEPTH = 9999; - - private static final War3ID ABILITY_HERO_RAWCODE = War3ID.fromString("AHer"); - private static final War3ID ABILITY_REVIVE_RAWCODE = War3ID.fromString("Arev"); - private static final Color PLACEHOLDER_LUMBER_COLOR = new Color(0.0f, 200f / 255f, 80f / 255f, 1.0f); - private static final Color PLACEHOLDER_GOLD_COLOR = new Color(1.0f, 220f / 255f, 0f, 1.0f); - private static final War3ID UNIT_FILE = War3ID.fromString("umdl"); - private static final War3ID UNIT_SPECIAL = War3ID.fromString("uspa"); - private static final War3ID UBER_SPLAT = War3ID.fromString("uubs"); - private static final War3ID UNIT_SHADOW = War3ID.fromString("ushu"); - private static final War3ID UNIT_SHADOW_X = War3ID.fromString("ushx"); - private static final War3ID UNIT_SHADOW_Y = War3ID.fromString("ushy"); - private static final War3ID UNIT_SHADOW_W = War3ID.fromString("ushw"); - private static final War3ID UNIT_SHADOW_H = War3ID.fromString("ushh"); - private static final War3ID BUILDING_SHADOW = War3ID.fromString("ushb"); - public static final War3ID UNIT_SELECT_SCALE = War3ID.fromString("ussc"); - private static final War3ID UNIT_SOUNDSET = War3ID.fromString("usnd"); - private static final War3ID ITEM_FILE = War3ID.fromString("ifil"); - private static final War3ID UNIT_PATHING = War3ID.fromString("upat"); - private static final War3ID DESTRUCTABLE_PATHING = War3ID.fromString("bptx"); - private static final War3ID DESTRUCTABLE_PATHING_DEATH = War3ID.fromString("bptd"); - private static final War3ID ELEVATION_SAMPLE_RADIUS = War3ID.fromString("uerd"); - private static final War3ID MAX_PITCH = War3ID.fromString("umxp"); - private static final War3ID ALLOW_CUSTOM_TEAM_COLOR = War3ID.fromString("utcc"); - private static final War3ID TEAM_COLOR = War3ID.fromString("utco"); - private static final War3ID MAX_ROLL = War3ID.fromString("umxr"); - private static final War3ID ANIMATION_RUN_SPEED = War3ID.fromString("urun"); - private static final War3ID ANIMATION_WALK_SPEED = War3ID.fromString("uwal"); - private static final War3ID MODEL_SCALE = War3ID.fromString("usca"); - private static final War3ID sloc = War3ID.fromString("sloc"); - private static final LoadGenericCallback stringDataCallback = new StringDataCallbackImplementation(); - private static final float[] rayHeap = new float[6]; - public static final Ray gdxRayHeap = new Ray(); - private static final Vector2 mousePosHeap = new Vector2(); - private static final Vector3 normalHeap = new Vector3(); - public static final Vector3 intersectionHeap = new Vector3(); - public static final Vector3 intersectionHeap2 = new Vector3(); - private static final Rectangle rectangleHeap = new Rectangle(); - public static final StreamDataCallbackImplementation streamDataCallback = new StreamDataCallbackImplementation(); - private static final boolean ENABLE_WORLDEDIT_AS_GAMEPLAY_DATA_HACK = true; - - public WorldScene worldScene; - public boolean anyReady; - public MappedData terrainData = new MappedData(); - public MappedData cliffTypesData = new MappedData(); - public MappedData waterData = new MappedData(); - public boolean terrainReady; - public boolean cliffsReady; - public boolean doodadsAndDestructiblesLoaded; - public MappedData doodadsData = new MappedData(); - public MappedData doodadMetaData = new MappedData(); - public MappedData destructableMetaData = new MappedData(); - public List doodads = new ArrayList<>(); - public List terrainDoodads = new ArrayList<>(); - public boolean doodadsReady; - public boolean unitsAndItemsLoaded; - public MappedData unitsData = new MappedData(); - public MappedData unitMetaData = new MappedData(); - public List widgets = new ArrayList<>(); - public List units = new ArrayList<>(); - public List projectiles = new ArrayList<>(); - public boolean unitsReady; - public War3Map mapMpq; - - private final DataSource gameDataSource; - - public Terrain terrain; - public int renderPathing = 0; - public int renderLighting = 1; - - private final Set selectedSplatModelKeys = new HashSet<>(); - public List selected = new ArrayList<>(); - private final Set mouseHighlightSplatModelKeys = new HashSet<>(); - private final List mouseHighlightWidgets = new ArrayList<>(); - private DataTable unitAckSoundsTable; - private DataTable unitCombatSoundsTable; - public DataTable miscData; - private DataTable unitGlobalStrings; - public DataTable uiSoundsTable; - private MdxComplexInstance confirmationInstance; - public MdxComplexInstance dncUnit; - public MdxComplexInstance dncUnitDay; - public MdxComplexInstance dncTerrain; - public MdxComplexInstance dncTarget; - public CSimulation simulation; - private float updateTime; - - // for World Editor, I think - public Vector2[] startLocations = new Vector2[WarsmashConstants.MAX_PLAYERS]; - - private final DynamicShadowManager dynamicShadowManager = new DynamicShadowManager(); - - private final Random seededRandom = new Random(1337L); - - private final Map filePathToPathingMap = new HashMap<>(); - - private final List selectionCircleSizes = new ArrayList<>(); - - private final Map unitToRenderPeer = new HashMap<>(); - private final Map destructableToRenderPeer = new HashMap<>(); - private final Map itemToRenderPeer = new HashMap<>(); - private final Map unitIdToTypeData = new HashMap<>(); - private GameUI gameUI; - private Vector3 lightDirection; - - private Quadtree walkableObjectsTree; - private final QuadtreeIntersectorFindsWalkableRenderHeight walkablesIntersector = new QuadtreeIntersectorFindsWalkableRenderHeight(); - private final QuadtreeIntersectorFindsHitPoint walkablesIntersectionFinder = new QuadtreeIntersectorFindsHitPoint(); - private final QuadtreeIntersectorFindsHighestWalkable intersectorFindsHighestWalkable = new QuadtreeIntersectorFindsHighestWalkable(); - - private KeyedSounds uiSounds; - private int localPlayerIndex; - private final SettableCommandErrorListener commandErrorListener; - - public final List textTags = new ArrayList<>(); - - private final War3MapConfig mapConfig; - - private GameTurnManager gameTurnManager; - - public War3MapViewer(final DataSource dataSource, final CanvasProvider canvas, final War3MapConfig mapConfig, - final GameTurnManager gameTurnManager) { - super(dataSource, canvas); - this.gameTurnManager = gameTurnManager; - MdxHandler.CURRENT_SHADER_TYPE = ShaderEnvironmentType.GAME; - this.gameDataSource = dataSource; - - final WebGL webGL = this.webGL; - - this.addHandler(new MdxHandler()); - - this.wc3PathSolver = PathSolver.DEFAULT; - - this.worldScene = this.addWorldScene(); - - if (!this.dynamicShadowManager.setup(webGL)) { - throw new IllegalStateException("FrameBuffer setup failed"); - } - - this.commandErrorListener = new SettableCommandErrorListener(); - this.mapConfig = mapConfig; - } - - public void loadSLKs(final WorldEditStrings worldEditStrings) throws IOException { - final GenericResource terrain = this.loadMapGeneric("TerrainArt\\Terrain.slk", FetchDataTypeName.SLK, - stringDataCallback); - final GenericResource cliffTypes = this.loadMapGeneric("TerrainArt\\CliffTypes.slk", FetchDataTypeName.SLK, - stringDataCallback); - final GenericResource water = this.loadMapGeneric("TerrainArt\\Water.slk", FetchDataTypeName.SLK, - stringDataCallback); - - // == when loaded, which is always in our system == - this.terrainData.load(terrain.data.toString()); - this.cliffTypesData.load(cliffTypes.data.toString()); - this.waterData.load(water.data.toString()); - // emit terrain loaded?? - - final GenericResource doodads = this.loadMapGeneric("Doodads\\Doodads.slk", FetchDataTypeName.SLK, - stringDataCallback); - final GenericResource doodadMetaData = this.loadMapGeneric("Doodads\\DoodadMetaData.slk", FetchDataTypeName.SLK, - stringDataCallback); - final GenericResource destructableData = this.loadMapGeneric("Units\\DestructableData.slk", - FetchDataTypeName.SLK, stringDataCallback); - final GenericResource destructableMetaData = this.loadMapGeneric("Units\\DestructableMetaData.slk", - FetchDataTypeName.SLK, stringDataCallback); - - // == when loaded, which is always in our system == - this.doodadsAndDestructiblesLoaded = true; - this.doodadsData.load(doodads.data.toString()); - this.doodadMetaData.load(doodadMetaData.data.toString()); - this.doodadsData.load(destructableData.data.toString()); - this.destructableMetaData.load(destructableData.data.toString()); - // emit doodads loaded - - final GenericResource unitData = this.loadMapGeneric("Units\\UnitData.slk", FetchDataTypeName.SLK, - stringDataCallback); - final GenericResource unitUi = this.loadMapGeneric("Units\\unitUI.slk", FetchDataTypeName.SLK, - stringDataCallback); - final GenericResource itemData = this.loadMapGeneric("Units\\ItemData.slk", FetchDataTypeName.SLK, - stringDataCallback); - final GenericResource unitMetaData = this.loadMapGeneric("Units\\UnitMetaData.slk", FetchDataTypeName.SLK, - stringDataCallback); - - // == when loaded, which is always in our system == - this.unitsAndItemsLoaded = true; - this.unitsData.load(unitData.data.toString()); - this.unitsData.load(unitUi.data.toString()); - this.unitsData.load(itemData.data.toString()); - this.unitMetaData.load(unitMetaData.data.toString()); - // emit loaded - - this.unitAckSoundsTable = new DataTable(worldEditStrings); - try (InputStream terrainSlkStream = this.dataSource.getResourceAsStream("UI\\SoundInfo\\UnitAckSounds.slk")) { - this.unitAckSoundsTable.readSLK(terrainSlkStream); - } - this.unitCombatSoundsTable = new DataTable(worldEditStrings); - try (InputStream terrainSlkStream = this.dataSource - .getResourceAsStream("UI\\SoundInfo\\UnitCombatSounds.slk")) { - this.unitCombatSoundsTable.readSLK(terrainSlkStream); - } - this.miscData = new DataTable(worldEditStrings); - try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("UI\\MiscData.txt")) { - this.miscData.readTXT(miscDataTxtStream, true); - } - try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("Units\\MiscData.txt")) { - this.miscData.readTXT(miscDataTxtStream, true); - } - try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("Units\\MiscGame.txt")) { - this.miscData.readTXT(miscDataTxtStream, true); - } - try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("UI\\MiscUI.txt")) { - this.miscData.readTXT(miscDataTxtStream, true); - } - try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("UI\\SoundInfo\\MiscData.txt")) { - this.miscData.readTXT(miscDataTxtStream, true); - } - if (this.dataSource.has("war3mapMisc.txt")) { - try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("war3mapMisc.txt")) { - this.miscData.readTXT(miscDataTxtStream, true); - } - } - final Element misc = this.miscData.get("Misc"); - // TODO Find the upkeep constants inside the assets files ????? - if (!misc.hasField("UpkeepUsage")) { - misc.setField("UpkeepUsage", "50,80,10000,10000,10000,10000,10000,10000,10000,10000"); - } - if (!misc.hasField("UpkeepGoldTax")) { - misc.setField("UpkeepGoldTax", "0.00,0.30,0.60,0.60,0.60,0.60,0.60,0.60,0.60,0.60"); - } - if (!misc.hasField("UpkeepLumberTax")) { - misc.setField("UpkeepLumberTax", "0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00"); - } - final Element light = this.miscData.get("Light"); - final float lightX = light.getFieldFloatValue("Direction", 0); - final float lightY = light.getFieldFloatValue("Direction", 1); - final float lightZ = light.getFieldFloatValue("Direction", 2); - this.lightDirection = new Vector3(lightX, lightY, lightZ).nor(); - this.unitGlobalStrings = new DataTable(worldEditStrings); - try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("Units\\UnitGlobalStrings.txt")) { - this.unitGlobalStrings.readTXT(miscDataTxtStream, true); - } - final Element categories = this.unitGlobalStrings.get("Categories"); - for (final CUnitClassification unitClassification : CUnitClassification.values()) { - if (unitClassification.getLocaleKey() != null) { - final String displayName = categories.getField(unitClassification.getLocaleKey()); - unitClassification.setDisplayName(displayName); - } - } - this.selectionCircleSizes.clear(); - final Element selectionCircleData = this.miscData.get("SelectionCircle"); - final int selectionCircleNumSizes = selectionCircleData.getFieldValue("NumSizes"); - for (int i = 0; i < selectionCircleNumSizes; i++) { - final String indexString = i < 10 ? "0" + i : Integer.toString(i); - final float size = selectionCircleData.getFieldFloatValue("Size" + indexString); - final String texture = selectionCircleData.getField("Texture" + indexString); - final String textureDotted = selectionCircleData.getField("TextureDotted" + indexString); - this.selectionCircleSizes.add(new SelectionCircleSize(size, texture, textureDotted)); - } - this.selectionCircleScaleFactor = selectionCircleData.getFieldFloatValue("ScaleFactor"); - this.imageWalkableZOffset = selectionCircleData.getFieldValue("ImageWalkableZOffset"); - this.selectionCircleColorFriend = parseColor(selectionCircleData, "ColorFriend"); - this.selectionCircleColorNeutral = parseColor(selectionCircleData, "ColorNeutral"); - this.selectionCircleColorEnemy = parseColor(selectionCircleData, "ColorEnemy"); - - this.uiSoundsTable = new DataTable(worldEditStrings); - try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("UI\\SoundInfo\\UISounds.slk")) { - this.uiSoundsTable.readSLK(miscDataTxtStream); - } - try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("UI\\SoundInfo\\AmbienceSounds.slk")) { - this.uiSoundsTable.readSLK(miscDataTxtStream); - } - try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("UI\\SoundInfo\\AbilitySounds.slk")) { - this.uiSoundsTable.readSLK(miscDataTxtStream); - } - } - - private Color parseColor(final Element selectionCircleData, final String field) { - return new Color(selectionCircleData.getFieldFloatValue(field, 1) / 255f, - selectionCircleData.getFieldFloatValue(field, 2) / 255f, - selectionCircleData.getFieldFloatValue(field, 3) / 255f, - selectionCircleData.getFieldFloatValue(field, 0) / 255f); - } - - public GenericResource loadMapGeneric(final String path, final FetchDataTypeName dataType, - final LoadGenericCallback callback) { - if (this.mapMpq == null) { - return loadGeneric(path, dataType, callback); - } - else { - return loadGeneric(path, dataType, callback, this.dataSource); - } - } - - public War3Map beginLoadingMap(final String mapFilePath) throws IOException { - return new War3Map(this.gameDataSource, mapFilePath); - } - - public DataTable loadWorldEditData(final War3Map map) { - final StandardObjectData standardObjectData = new StandardObjectData(map); - this.worldEditData = standardObjectData.getWorldEditData(); - return this.worldEditData; - } - - public WTS preloadWTS(final War3Map map) { - try { - this.preloadedWTS = Warcraft3MapObjectData.loadWTS(map); - return this.preloadedWTS; - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - public void loadMap(final War3Map war3Map, final War3MapW3i w3iFile, final int localPlayerIndex) - throws IOException { - this.localPlayerIndex = localPlayerIndex; - - this.mapMpq = war3Map; - - final PathSolver wc3PathSolver = this.wc3PathSolver; - - char tileset = 'A'; - - if (ENABLE_WORLDEDIT_AS_GAMEPLAY_DATA_HACK) { - int playerIndex = 0; - for (final Player player : w3iFile.getPlayers()) { - final CBasePlayer cfgPlayer = this.mapConfig.getPlayer(playerIndex); - cfgPlayer.setName(player.getName()); - cfgPlayer.setRacePref(CRacePreference.VALUES[player.getRace()]); - cfgPlayer.setController(CMapControl.VALUES[player.getType()]); - playerIndex++; - } - } - - tileset = w3iFile.getTileset(); - - DataSource tilesetSource; - try { - // Slightly complex. Here's the theory: - // 1.) Copy map into RAM - // 2.) Setup a Data Source that will read assets - // from either the map or the game, giving the map priority. - SeekableByteChannel sbc; - final CompoundDataSource compoundDataSource = war3Map.getCompoundDataSource(); - if (WarsmashConstants.FIX_FLAT_FILES_TILESET_LOADING) { - tilesetSource = new CompoundDataSource( - Arrays.asList(compoundDataSource, new SubdirDataSource(compoundDataSource, tileset + ".mpq/"))); - } - else { - try (InputStream mapStream = compoundDataSource.getResourceAsStream(tileset + ".mpq")) { - if (mapStream == null) { - tilesetSource = new CompoundDataSource(Arrays.asList(compoundDataSource, - new SubdirDataSource(compoundDataSource, tileset + ".mpq/"), - new SubdirDataSource(compoundDataSource, "_tilesets/" + tileset + ".w3mod/"))); - } - else { - final byte[] mapData = IOUtils.toByteArray(mapStream); - sbc = new SeekableInMemoryByteChannel(mapData); - final DataSource internalMpqContentsDataSource = new MpqDataSource(new MPQArchive(sbc), sbc); - tilesetSource = new CompoundDataSource( - Arrays.asList(compoundDataSource, internalMpqContentsDataSource)); - } - } - catch (final IOException exc) { - tilesetSource = new CompoundDataSource(Arrays.asList(compoundDataSource, - new SubdirDataSource(compoundDataSource, tileset + ".mpq/"), - new SubdirDataSource(compoundDataSource, "_tilesets/" + tileset + ".w3mod/"))); - } - } - } - catch (final MPQException e) { - throw new RuntimeException(e); - } - setDataSource(tilesetSource); - this.worldEditStrings = new WorldEditStrings(this.dataSource); - loadSLKs(this.worldEditStrings); - - this.solverParams.tileset = Character.toLowerCase(tileset); - - final War3MapW3e terrainData = this.mapMpq.readEnvironment(); - - final War3MapWpm terrainPathing = this.mapMpq.readPathing(); - - this.terrain = new Terrain(terrainData, terrainPathing, w3iFile, this.webGL, this.dataSource, - this.worldEditStrings, this, this.worldEditData); - - final float[] centerOffset = terrainData.getCenterOffset(); - final int[] mapSize = terrainData.getMapSize(); - - this.terrainReady = true; - this.anyReady = true; - this.cliffsReady = true; - - // Override the grid based on the map. - this.worldScene.grid = new Grid(centerOffset[0], centerOffset[1], (mapSize[0] * 128) - 128, - (mapSize[1] * 128) - 128, 16 * 128, 16 * 128); - - final MdxModel confirmation = (MdxModel) load("UI\\Feedback\\Confirmation\\Confirmation.mdx", - PathSolver.DEFAULT, null); - this.confirmationInstance = (MdxComplexInstance) confirmation.addInstance(); - this.confirmationInstance.setSequenceLoopMode(SequenceLoopMode.NEVER_LOOP_AND_HIDE_WHEN_DONE); - this.confirmationInstance.setSequence(0); - this.confirmationInstance.setScene(this.worldScene); - - if (this.preloadedWTS != null) { - this.allObjectData = this.mapMpq.readModifications(this.preloadedWTS); - } - else { - this.allObjectData = this.mapMpq.readModifications(); - } - this.simulation = new CSimulation(this.mapConfig, this.miscData, this.allObjectData.getUnits(), - this.allObjectData.getItems(), this.allObjectData.getDestructibles(), this.allObjectData.getAbilities(), - new SimulationRenderController() { - private final Map keyToCombatSound = new HashMap<>(); - - @Override - public CAttackProjectile createAttackProjectile(final CSimulation simulation, final float launchX, - final float launchY, final float launchFacing, final CUnit source, - final CUnitAttackMissile unitAttack, final AbilityTarget target, final float damage, - final int bounceIndex, final CUnitAttackListener attackListener) { - final War3ID typeId = source.getTypeId(); - final int projectileSpeed = unitAttack.getProjectileSpeed(); - final float projectileArc = unitAttack.getProjectileArc(); - String missileArt = unitAttack.getProjectileArt(); - final float projectileLaunchX = simulation.getUnitData().getProjectileLaunchX(typeId); - final float projectileLaunchY = simulation.getUnitData().getProjectileLaunchY(typeId); - final float projectileLaunchZ = simulation.getUnitData().getProjectileLaunchZ(typeId); - - missileArt = mdx(missileArt); - final float facing = launchFacing; - final float sinFacing = (float) Math.sin(facing); - final float cosFacing = (float) Math.cos(facing); - final float x = (launchX + (projectileLaunchY * cosFacing)) + (projectileLaunchX * sinFacing); - final float y = (launchY + (projectileLaunchY * sinFacing)) - (projectileLaunchX * cosFacing); - - final float height = War3MapViewer.this.terrain.getGroundHeight(x, y) + source.getFlyHeight() - + projectileLaunchZ; - final CAttackProjectile simulationAttackProjectile = new CAttackProjectile(x, y, - projectileSpeed, target, source, damage, unitAttack, bounceIndex, attackListener); - - final MdxModel model = (MdxModel) load(missileArt, War3MapViewer.this.mapPathSolver, - War3MapViewer.this.solverParams); - final MdxComplexInstance modelInstance = (MdxComplexInstance) model.addInstance(); - modelInstance.setTeamColor(source.getPlayerIndex()); - modelInstance.setScene(War3MapViewer.this.worldScene); - if (bounceIndex == 0) { - SequenceUtils.randomBirthSequence(modelInstance); - } - else { - SequenceUtils.randomStandSequence(modelInstance); - } - modelInstance.setLocation(x, y, height); - final RenderAttackProjectile renderAttackProjectile = new RenderAttackProjectile( - simulationAttackProjectile, modelInstance, height, projectileArc, War3MapViewer.this); - - War3MapViewer.this.projectiles.add(renderAttackProjectile); - - return simulationAttackProjectile; - } - - @Override - public void createInstantAttackEffect(final CSimulation cSimulation, final CUnit source, - final CUnitAttackInstant unitAttack, final CWidget target) { - final War3ID typeId = source.getTypeId(); - - String missileArt = unitAttack.getProjectileArt(); - final float projectileLaunchX = War3MapViewer.this.simulation.getUnitData() - .getProjectileLaunchX(typeId); - final float projectileLaunchY = War3MapViewer.this.simulation.getUnitData() - .getProjectileLaunchY(typeId); - missileArt = mdx(missileArt); - final float facing = (float) Math.toRadians(source.getFacing()); - final float sinFacing = (float) Math.sin(facing); - final float cosFacing = (float) Math.cos(facing); - final float x = (source.getX() + (projectileLaunchY * cosFacing)) - + (projectileLaunchX * sinFacing); - final float y = (source.getY() + (projectileLaunchY * sinFacing)) - - (projectileLaunchX * cosFacing); - - final float targetX = target.getX(); - final float targetY = target.getY(); - final float angleToTarget = (float) Math.atan2(targetY - y, targetX - x); - - final float height = War3MapViewer.this.terrain.getGroundHeight(targetX, targetY) - + target.getFlyHeight() + target.getImpactZ(); - - final MdxModel model = (MdxModel) load(missileArt, War3MapViewer.this.mapPathSolver, - War3MapViewer.this.solverParams); - final MdxComplexInstance modelInstance = (MdxComplexInstance) model.addInstance(); - modelInstance.setTeamColor(source.getPlayerIndex()); - SequenceUtils.randomBirthSequence(modelInstance); - modelInstance.setLocation(targetX, targetY, height); - modelInstance.setScene(War3MapViewer.this.worldScene); - War3MapViewer.this.projectiles - .add(new RenderAttackInstant(modelInstance, War3MapViewer.this, angleToTarget)); - } - - @Override - public void spawnDamageSound(final CWidget damagedDestructable, final String weaponSound, - final String armorType) { - final RenderWidget damagedWidget = getRenderPeer(damagedDestructable); - if (damagedWidget == null) { - return; - } - final String key = weaponSound + armorType; - UnitSound combatSound = this.keyToCombatSound.get(key); - if (combatSound == null) { - combatSound = UnitSound.create(War3MapViewer.this.dataSource, - War3MapViewer.this.unitCombatSoundsTable, weaponSound, armorType); - this.keyToCombatSound.put(key, combatSound); - } - combatSound.play(War3MapViewer.this.worldScene.audioContext, damagedDestructable.getX(), - damagedDestructable.getY(), damagedWidget.getZ()); - } - - @Override - public void spawnUnitConstructionSound(final CUnit constructingUnit, - final CUnit constructedStructure) { - final UnitSound constructingBuilding = War3MapViewer.this.uiSounds - .getSound(War3MapViewer.this.gameUI.getSkinField("ConstructingBuilding")); - if (constructingBuilding != null) { - constructingBuilding.playUnitResponse(War3MapViewer.this.worldScene.audioContext, - War3MapViewer.this.unitToRenderPeer.get(constructedStructure)); - } - } - - @Override - public void removeUnit(final CUnit unit) { - final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.remove(unit); - War3MapViewer.this.widgets.remove(renderUnit); - War3MapViewer.this.units.remove(renderUnit); - War3MapViewer.this.worldScene.removeInstance(renderUnit.instance); - renderUnit.onRemove(War3MapViewer.this); - } - - @Override - public void removeDestructable(final CDestructable dest) { - final RenderDestructable renderPeer = War3MapViewer.this.destructableToRenderPeer.remove(dest); - War3MapViewer.this.worldScene.removeInstance(renderPeer.instance); - if (renderPeer.walkableBounds != null) { - War3MapViewer.this.walkableObjectsTree.remove((MdxComplexInstance) renderPeer.instance, - renderPeer.walkableBounds); - } - } - - @Override - public BufferedImage getBuildingPathingPixelMap(final War3ID rawcode) { - return War3MapViewer.this - .getBuildingPathingPixelMap(War3MapViewer.this.allObjectData.getUnits().get(rawcode)); - } - - @Override - public BufferedImage getDestructablePathingDeathPixelMap(final War3ID rawcode) { - return War3MapViewer.this.getDestructablePathingDeathPixelMap( - War3MapViewer.this.allObjectData.getDestructibles().get(rawcode)); - } - - @Override - public BufferedImage getDestructablePathingPixelMap(final War3ID rawcode) { - return War3MapViewer.this.getDestructablePathingPixelMap( - War3MapViewer.this.allObjectData.getDestructibles().get(rawcode)); - } - - @Override - public void spawnUnitConstructionFinishSound(final CUnit constructedStructure) { - final UnitSound constructingBuilding = War3MapViewer.this.uiSounds - .getSound(War3MapViewer.this.gameUI.getSkinField("JobDoneSound")); - final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(constructedStructure); - if ((constructingBuilding != null) && (renderUnit.getSimulationUnit() - .getPlayerIndex() == War3MapViewer.this.localPlayerIndex)) { - constructingBuilding.play(War3MapViewer.this.worldScene.audioContext, - constructedStructure.getX(), constructedStructure.getY(), renderUnit.getZ()); - } - } - - @Override - public CUnit createUnit(final CSimulation simulation, final War3ID typeId, final int playerIndex, - final float x, final float y, final float facing) { - return createNewUnit(War3MapViewer.this.allObjectData, typeId, x, y, 0f, playerIndex, - playerIndex, (float) Math.toRadians(facing)); - } - - @Override - public void spawnBuildingDeathEffect(final CUnit source) { - final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(source); - if (renderUnit.specialArtModel != null) { - final MdxComplexInstance modelInstance = (MdxComplexInstance) renderUnit.specialArtModel - .addInstance(); - modelInstance.setTeamColor(source.getPlayerIndex()); - modelInstance.setLocation(renderUnit.location); - modelInstance.setScene(War3MapViewer.this.worldScene); - SequenceUtils.randomBirthSequence(modelInstance); - War3MapViewer.this.projectiles - .add(new RenderAttackInstant(modelInstance, War3MapViewer.this, - (float) Math.toRadians(renderUnit.getSimulationUnit().getFacing()))); - } - } - - @Override - public void spawnGainLevelEffect(final CUnit source) { - final AbilityUI heroUI = War3MapViewer.this.abilityDataUI.getUI(ABILITY_HERO_RAWCODE); - final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(source); - final String heroLevelUpArt = heroUI.getCasterArt(0); - spawnFxOnOrigin(renderUnit, heroLevelUpArt); - } - - @Override - public void heroRevived(final CUnit source) { - final AbilityUI reviveUI = War3MapViewer.this.abilityDataUI.getUI(ABILITY_REVIVE_RAWCODE); - final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(source); - renderUnit.instance.additiveOverrideMeshMode = false; - renderUnit.instance.setVertexAlpha(1.0f); - final CPlayer player = War3MapViewer.this.simulation.getPlayer(source.getPlayerIndex()); - final String heroReviveArt = reviveUI.getTargetArt(player.getRace().ordinal()); - spawnFxOnOrigin(renderUnit, heroReviveArt); - final MutableGameObject row = War3MapViewer.this.allObjectData.getUnits() - .get(source.getTypeId()); - - // Recreate unit shadow.... is needed here - - final String unitShadow = row.getFieldAsString(UNIT_SHADOW, 0); - final float unitX = source.getX(); - final float unitY = source.getY(); - if ((unitShadow != null) && !"_".equals(unitShadow)) { - final String texture = "ReplaceableTextures\\Shadows\\" + unitShadow + ".blp"; - final float shadowX = row.getFieldAsFloat(UNIT_SHADOW_X, 0); - final float shadowY = row.getFieldAsFloat(UNIT_SHADOW_Y, 0); - final float shadowWidth = row.getFieldAsFloat(UNIT_SHADOW_W, 0); - final float shadowHeight = row.getFieldAsFloat(UNIT_SHADOW_H, 0); - if (War3MapViewer.this.mapMpq.has(texture)) { - final float x = unitX - shadowX; - final float y = unitY - shadowY; - renderUnit.shadow = War3MapViewer.this.terrain.addUnitShadowSplat(texture, x, y, - x + shadowWidth, y + shadowHeight, 3, 0.5f); - } - } - } - - @Override - public void heroDeathEvent(final CUnit source) { - final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(source); - renderUnit.instance.additiveOverrideMeshMode = true; - } - - @Override - public void spawnEffectOnUnit(final CUnit unit, final String effectPath) { - final RenderUnit renderUnit = War3MapViewer.this.unitToRenderPeer.get(unit); - final MdxModel spawnedEffectModel = (MdxModel) load(mdx(effectPath), PathSolver.DEFAULT, null); - if (spawnedEffectModel != null) { - final MdxComplexInstance modelInstance = (MdxComplexInstance) spawnedEffectModel - .addInstance(); - modelInstance.setTeamColor(unit.getPlayerIndex()); - modelInstance.setLocation(renderUnit.location); - modelInstance.setScene(War3MapViewer.this.worldScene); - SequenceUtils.randomBirthSequence(modelInstance); - War3MapViewer.this.projectiles - .add(new RenderAttackInstant(modelInstance, War3MapViewer.this, - (float) Math.toRadians(renderUnit.getSimulationUnit().getFacing()))); - } - - } - - @Override - public void spawnSpellEffectOnUnit(final CUnit unit, final War3ID alias) { - final AbilityUI abilityUI = War3MapViewer.this.abilityDataUI.getUI(alias); - spawnEffectOnUnit(unit, abilityUI.getTargetArt(0)); - } - - @Override - public void spawnUnitReadySound(final CUnit trainedUnit) { - final RenderUnit renderPeer = War3MapViewer.this.unitToRenderPeer.get(trainedUnit); - renderPeer.soundset.ready.playUnitResponse(War3MapViewer.this.worldScene.audioContext, - renderPeer); - } - - @Override - public void unitRepositioned(final CUnit cUnit) { - final RenderUnit renderPeer = War3MapViewer.this.unitToRenderPeer.get(cUnit); - renderPeer.repositioned(War3MapViewer.this); - } - - @Override - public void spawnGainResourceTextTag(final CUnit gainingUnit, final ResourceType resourceType, - final int amount) { - final RenderUnit renderPeer = War3MapViewer.this.unitToRenderPeer.get(gainingUnit); - switch (resourceType) { - case FOOD: - throw new IllegalArgumentException(); - case GOLD: - War3MapViewer.this.textTags.add(new TextTag(new Vector3(renderPeer.location), "+" + amount, - PLACEHOLDER_GOLD_COLOR)); - break; - case LUMBER: - War3MapViewer.this.textTags.add(new TextTag(new Vector3(renderPeer.location), "+" + amount, - PLACEHOLDER_LUMBER_COLOR)); - break; - } - } - - @Override - public void spawnUIUnitGetItemSound(final CUnit cUnit, final CItem item) { - final RenderUnit renderPeer = War3MapViewer.this.unitToRenderPeer.get(cUnit); - if (localPlayerIndex == renderPeer.getSimulationUnit().getPlayerIndex()) { - War3MapViewer.this.uiSounds.getSound("ItemGet").play( - War3MapViewer.this.worldScene.audioContext, renderPeer.getX(), renderPeer.getY(), - renderPeer.getZ()); - } - } - - @Override - public void spawnUIUnitDropItemSound(final CUnit cUnit, final CItem item) { - final RenderUnit renderPeer = War3MapViewer.this.unitToRenderPeer.get(cUnit); - if (localPlayerIndex == renderPeer.getSimulationUnit().getPlayerIndex()) { - War3MapViewer.this.uiSounds.getSound("ItemDrop").play( - War3MapViewer.this.worldScene.audioContext, renderPeer.getX(), renderPeer.getY(), - renderPeer.getZ()); - } - } - - @Override - public void spawnAbilitySoundEffect(final CUnit caster, final War3ID alias) { - final RenderUnit renderPeer = War3MapViewer.this.unitToRenderPeer.get(caster); - final AbilityUI abilityUi = War3MapViewer.this.abilityDataUI.getUI(alias); - if (abilityUi.getEffectSound() != null) { - War3MapViewer.this.uiSounds.getSound(abilityUi.getEffectSound()).play( - War3MapViewer.this.worldScene.audioContext, renderPeer.getX(), renderPeer.getY(), - renderPeer.getZ()); - } - } - - @Override - public void unitPreferredSelectionReplacement(final CUnit oldUnit, final CUnit newUnit) { - final RenderUnit oldRenderPeer = War3MapViewer.this.unitToRenderPeer.get(oldUnit); - final RenderUnit newRenderPeer = War3MapViewer.this.unitToRenderPeer.get(newUnit); - oldRenderPeer.setPreferredSelectionReplacement(newRenderPeer); - - } - }, this.terrain.pathingGrid, this.terrain.getEntireMap(), this.seededRandom, this.commandErrorListener); - - this.walkableObjectsTree = new Quadtree<>(this.terrain.getEntireMap()); - if (this.doodadsAndDestructiblesLoaded) { - this.loadDoodadsAndDestructibles(this.allObjectData); - } - else { - throw new IllegalStateException("transcription of JS has not loaded a map and has no JS async promises"); - } - - loadSounds(); - - this.terrain.createWaves(); - - loadLightsAndShading(tileset); - } - - public void spawnFxOnOrigin(final RenderUnit renderUnit, final String heroLevelUpArt) { - final MdxModel heroLevelUpModel = loadModel(heroLevelUpArt); - if (heroLevelUpModel != null) { - final MdxComplexInstance modelInstance = (MdxComplexInstance) heroLevelUpModel.addInstance(); - modelInstance.setTeamColor(renderUnit.playerIndex); - - final MdxModel model = (MdxModel) renderUnit.instance.model; - int index = -1; - for (int i = 0; i < model.attachments.size(); i++) { - final Attachment attachment = model.attachments.get(i); - if (attachment.getName().startsWith("origin ref")) { - index = i; - break; - } - } - if (index != -1) { - final MdxNode attachment = renderUnit.instance.getAttachment(index); - modelInstance.setParent(attachment); - } - else { - modelInstance.setLocation(renderUnit.location); - } - - modelInstance.setScene(War3MapViewer.this.worldScene); - SequenceUtils.randomBirthSequence(modelInstance); - War3MapViewer.this.projectiles.add(new RenderAttackInstant(modelInstance, War3MapViewer.this, - (float) Math.toRadians(renderUnit.getSimulationUnit().getFacing()))); - } - } - - protected BufferedImage getDestructablePathingPixelMap(final MutableGameObject row) { - return loadPathingTexture(row.getFieldAsString(DESTRUCTABLE_PATHING, 0)); - } - - protected BufferedImage getDestructablePathingDeathPixelMap(final MutableGameObject row) { - return loadPathingTexture(row.getFieldAsString(DESTRUCTABLE_PATHING_DEATH, 0)); - } - - private void loadSounds() { - this.uiSounds = new KeyedSounds(this.uiSoundsTable, this.mapMpq); - } - - /** - * Loads the map information that should be loaded after UI, such as units, who - * need to be able to setup their UI counterparts (icons, etc) for their - * abilities while loading. This allows the dynamic creation of units while the - * game is playing to better share code with the startup sequence's creation of - * units. - * - * @throws IOException - */ - public void loadAfterUI() throws IOException { - if (this.unitsAndItemsLoaded) { - this.loadUnitsAndItems(this.allObjectData); - } - else { - throw new IllegalStateException("transcription of JS has not loaded a map and has no JS async promises"); - } - - // After we finish loading units, we need to update & create the stored shadow - // information for all unit shadows - this.terrain.initShadows(); - } - - private void loadLightsAndShading(final char tileset) { - // TODO this should be set by the war3map.j actually, not by the tileset, so the - // call to set day night models is just for testing to make the test look pretty - final Element defaultTerrainLights = this.worldEditData.get("TerrainLights"); - final Element defaultUnitLights = this.worldEditData.get("UnitLights"); - setDayNightModels(defaultTerrainLights.getField(Character.toString(tileset)), - defaultUnitLights.getField(Character.toString(tileset))); - - } - - private void loadDoodadsAndDestructibles(final Warcraft3MapObjectData modifications) throws IOException { - this.applyModificationFile(this.doodadsData, this.doodadMetaData, modifications.getDoodads(), - WorldEditorDataType.DOODADS); - this.applyModificationFile(this.doodadsData, this.destructableMetaData, modifications.getDestructibles(), - WorldEditorDataType.DESTRUCTIBLES); - - final War3MapDoo doo = this.mapMpq.readDoodads(); - - for (final com.etheller.warsmash.parsers.w3x.doo.Doodad doodad : doo.getDoodads()) { - WorldEditorDataType type = WorldEditorDataType.DOODADS; - MutableGameObject row = modifications.getDoodads().get(doodad.getId()); - if (row == null) { - row = modifications.getDestructibles().get(doodad.getId()); - type = WorldEditorDataType.DESTRUCTIBLES; - } - if (row != null) { - BuildingShadow destructableShadow = null; - RemovablePathingMapInstance destructablePathing = null; - RemovablePathingMapInstance destructablePathingDeath = null; - String file = row.readSLKTag("file"); - final int numVar = row.readSLKTagInt("numVar"); - - if (file.endsWith(".mdx") || file.endsWith(".mdl")) { - file = file.substring(0, file.length() - 4); - } - - String fileVar = file; - - file += ".mdx"; - - if (numVar > 1) { - fileVar += Math.min(doodad.getVariation(), numVar - 1); - } - - fileVar += ".mdx"; - - final float maxPitch = row.readSLKTagFloat("maxPitch"); - final float maxRoll = row.readSLKTagFloat("maxRoll"); - if (type == WorldEditorDataType.DESTRUCTIBLES) { - final String shadowString = row.readSLKTag("shadow"); - if ((shadowString != null) && (shadowString.length() > 0) && !"_".equals(shadowString)) { - destructableShadow = this.terrain.addShadow(shadowString, doodad.getLocation()[0], - doodad.getLocation()[1]); - } - - final BufferedImage destructablePathingPixelMap = getDestructablePathingPixelMap(row); - if (destructablePathingPixelMap != null) { - destructablePathing = this.terrain.pathingGrid.createRemovablePathingOverlayTexture( - doodad.getLocation()[0], doodad.getLocation()[1], - (int) Math.toDegrees(doodad.getAngle()), destructablePathingPixelMap); - if (doodad.getLife() > 0) { - destructablePathing.add(); - } - } - final BufferedImage destructablePathingDeathPixelMap = getDestructablePathingDeathPixelMap(row); - if (destructablePathingDeathPixelMap != null) { - destructablePathingDeath = this.terrain.pathingGrid.createRemovablePathingOverlayTexture( - doodad.getLocation()[0], doodad.getLocation()[1], - (int) Math.toDegrees(doodad.getAngle()), destructablePathingDeathPixelMap); - if (doodad.getLife() <= 0) { - destructablePathingDeath.add(); - } - } - } - // First see if the model is local. - // Doodads referring to local models may have invalid variations, so if the - // variation doesn't exist, try without a variation. - - String path; - if (this.mapMpq.has(fileVar)) { - path = fileVar; - } - else { - path = file; - } - MdxModel model; - if (this.mapMpq.has(path)) { - model = (MdxModel) this.load(path, this.mapPathSolver, this.solverParams); - } - else { - model = (MdxModel) this.load(fileVar, this.mapPathSolver, this.solverParams); - } - - if (type == WorldEditorDataType.DESTRUCTIBLES) { - final float x = doodad.getLocation()[0]; - final float y = doodad.getLocation()[1]; - final CDestructable simulationDestructable = this.simulation.createDestructable(row.getAlias(), x, - y, destructablePathing, destructablePathingDeath); - simulationDestructable.setLife(this.simulation, - simulationDestructable.getLife() * (doodad.getLife() / 100f)); - final RenderDestructable renderDestructable = new RenderDestructable(this, model, row, doodad, type, - maxPitch, maxRoll, doodad.getLife(), destructableShadow, simulationDestructable); - if (row.readSLKTagBoolean("walkable")) { - final float angle = doodad.getAngle(); - final BoundingBox boundingBox = model.bounds.getBoundingBox(); - final Rectangle renderDestructableBounds = getRotatedBoundingBox(x, y, angle, boundingBox); - System.out.println("ROTATED BOUNDS TO: " + renderDestructableBounds); - this.walkableObjectsTree.add((MdxComplexInstance) renderDestructable.instance, - renderDestructableBounds); - renderDestructable.walkableBounds = renderDestructableBounds; - } - this.widgets.add(renderDestructable); - this.destructableToRenderPeer.put(simulationDestructable, renderDestructable); - } - else { - this.doodads.add(new RenderDoodad(this, model, row, doodad, type, maxPitch, maxRoll)); - } - } - } - - // Cliff/Terrain doodads. - for (final com.etheller.warsmash.parsers.w3x.doo.TerrainDoodad doodad : doo.getTerrainDoodads()) { - final MutableGameObject row = modifications.getDoodads().get(doodad.getId()); - String file = row.readSLKTag("file");// - if ("".equals(file)) { - final String blaBla = row.readSLKTag("file"); - System.out.println("bla"); - } - if (file.toLowerCase().endsWith(".mdl")) { - file = file.substring(0, file.length() - 4); - } - if (!file.toLowerCase().endsWith(".mdx")) { - file += ".mdx"; - } - final MdxModel model = (MdxModel) this.load(file, this.mapPathSolver, this.solverParams); - - final String pathingTexture = row.readSLKTag("pathTex"); - BufferedImage pathingTextureImage; - if ((pathingTexture != null) && (pathingTexture.length() > 0) && !"_".equals(pathingTexture)) { - - pathingTextureImage = this.filePathToPathingMap.get(pathingTexture.toLowerCase()); - if (pathingTextureImage == null) { - if (this.mapMpq.has(pathingTexture)) { - try { - pathingTextureImage = TgaFile.readTGA(pathingTexture, - this.mapMpq.getResourceAsStream(pathingTexture)); - this.filePathToPathingMap.put(pathingTexture.toLowerCase(), pathingTextureImage); - } - catch (final Exception exc) { - exc.printStackTrace(); - } - } - } - } - else { - pathingTextureImage = null; - } - if (pathingTextureImage != null) { - // blit out terrain cells under this TerrainDoodad - final int textureWidth = pathingTextureImage.getWidth(); - final int textureHeight = pathingTextureImage.getHeight(); - final int textureWidthTerrainCells = textureWidth / 4; - final int textureHeightTerrainCells = textureHeight / 4; - final int minCellX = ((int) doodad.getLocation()[0]); - final int minCellY = ((int) doodad.getLocation()[1]); - final int maxCellX = (minCellX + textureWidthTerrainCells) - 1; - final int maxCellY = (minCellY + textureHeightTerrainCells) - 1; - for (int j = minCellY; j <= maxCellY; j++) { - for (int i = minCellX; i <= maxCellX; i++) { - this.terrain.removeTerrainCellWithoutFlush(i, j); - } - } - this.terrain.flushRemovedTerrainCells(); - } - - System.out.println("Loading terrain doodad: " + file); - this.terrainDoodads.add(new TerrainDoodad(this, model, row, doodad, pathingTextureImage)); - } - - this.doodadsReady = true; - this.anyReady = true; - } - - private Rectangle getRotatedBoundingBox(final float x, final float y, final float angle, - final BoundingBox boundingBox) { - final float x1 = boundingBox.min.x; - final float y1 = boundingBox.min.y; - final float x2 = boundingBox.min.x + boundingBox.getWidth(); - final float y2 = boundingBox.min.y; - final float x3 = boundingBox.min.x + boundingBox.getWidth(); - final float y3 = boundingBox.min.y + boundingBox.getHeight(); - final float x4 = boundingBox.min.x; - final float y4 = boundingBox.min.y + boundingBox.getHeight(); - final float angle1 = (float) StrictMath.atan2(y1, x1) + angle; - final float len1 = (float) StrictMath.sqrt((x1 * x1) + (y1 * y1)); - final float angle2 = (float) StrictMath.atan2(y2, x2) + angle; - final float len2 = (float) StrictMath.sqrt((x2 * x2) + (y2 * y2)); - final float angle3 = (float) StrictMath.atan2(y3, x3) + angle; - final float len3 = (float) StrictMath.sqrt((x3 * x3) + (y3 * y3)); - final float angle4 = (float) StrictMath.atan2(y4, x4) + angle; - final float len4 = (float) StrictMath.sqrt((x4 * x4) + (y4 * y4)); - final double x1prime = StrictMath.cos(angle1) * len1; - final double x2prime = StrictMath.cos(angle2) * len2; - final double x3prime = StrictMath.cos(angle3) * len3; - final double x4prime = StrictMath.cos(angle4) * len4; - final double y1prime = StrictMath.sin(angle1) * len1; - final double y2prime = StrictMath.sin(angle2) * len2; - final double y3prime = StrictMath.sin(angle3) * len3; - final double y4prime = StrictMath.sin(angle4) * len4; - final float minX = (float) StrictMath.min(StrictMath.min(x1prime, x2prime), StrictMath.min(x3prime, x4prime)); - final float minY = (float) StrictMath.min(StrictMath.min(y1prime, y2prime), StrictMath.min(y3prime, y4prime)); - final float maxX = (float) StrictMath.max(StrictMath.max(x1prime, x2prime), StrictMath.max(x3prime, x4prime)); - final float maxY = (float) StrictMath.max(StrictMath.max(y1prime, y2prime), StrictMath.max(y3prime, y4prime)); - return new Rectangle(x + minX, y + minY, maxX - minX, maxY - minY); - } - - private void applyModificationFile(final MappedData doodadsData2, final MappedData doodadMetaData2, - final MutableObjectData destructibles, final WorldEditorDataType dataType) { - // TODO condense ported MappedData from Ghostwolf and MutableObjectData from - // Retera - - } - - private void loadUnitsAndItems(final Warcraft3MapObjectData modifications) throws IOException { - final War3Map mpq = this.mapMpq; - this.unitsReady = false; - - this.soundsetNameToSoundset = new HashMap<>(); - - if (this.dataSource.has("war3mapUnits.doo")) { - final War3MapUnitsDoo dooFile = mpq.readUnits(); - - // Collect the units and items data. - for (final com.etheller.warsmash.parsers.w3x.unitsdoo.Unit unit : dooFile.getUnits()) { - final War3ID unitId = unit.getId(); - final float unitX = unit.getLocation()[0]; - final float unitY = unit.getLocation()[1]; - final float unitZ = unit.getLocation()[2]; - final int playerIndex = unit.getPlayer(); - final int customTeamColor = unit.getCustomTeamColor(); - final float unitAngle = unit.getAngle(); - final int editorConfigHitPointPercent = unit.getHitpoints(); - - final CUnit unitCreated = createNewUnit(modifications, unitId, unitX, unitY, unitZ, playerIndex, - customTeamColor, unitAngle); - if (unitCreated != null) { - if (editorConfigHitPointPercent > 0) { - unitCreated.setLife(this.simulation, - unitCreated.getMaximumLife() * (editorConfigHitPointPercent / 100f)); - } - if (unit.getGoldAmount() != 0) { - unitCreated.setGold(unit.getGoldAmount()); - } - } - } - } - this.simulation.unitsLoaded(); - - this.terrain.loadSplats(); - - this.unitsReady = true; - this.anyReady = true; - } - - private CUnit createNewUnit(final Warcraft3MapObjectData modifications, final War3ID unitId, float unitX, - float unitY, final float unitZ, final int playerIndex, int customTeamColor, final float unitAngle) { - UnitSoundset soundset = null; - MutableGameObject row = null; - String path = null; - Splat unitShadowSplat = null; - SplatMover unitShadowSplatDynamicIngame = null; - Splat buildingUberSplat = null; - SplatMover buildingUberSplatDynamicIngame = null; - BufferedImage buildingPathingPixelMap = null; - final float unitVertexScale = 1.0f; - RemovablePathingMapInstance pathingInstance = null; - BuildingShadow buildingShadowInstance = null; - - // Hardcoded? - WorldEditorDataType type = null; - if (sloc.equals(unitId)) { -// path = "Objects\\StartLocation\\StartLocation.mdx"; - type = null; /// ?????? - this.startLocations[playerIndex] = new Vector2(unitX, unitY); - } - else { - row = modifications.getUnits().get(unitId); - if (row == null) { - row = modifications.getItems().get(unitId); - if (row != null) { - type = WorldEditorDataType.ITEM; - path = row.getFieldAsString(ITEM_FILE, 0); - - if (path.toLowerCase().endsWith(".mdl") || path.toLowerCase().endsWith(".mdx")) { - path = path.substring(0, path.length() - 4); - } - - final Element misc = this.miscData.get("Misc"); - final String itemShadowFile = misc.getField("ItemShadowFile"); - final int itemShadowWidth = misc.getFieldValue("ItemShadowSize", 0); - final int itemShadowHeight = misc.getFieldValue("ItemShadowSize", 1); - final int itemShadowX = misc.getFieldValue("ItemShadowOffset", 0); - final int itemShadowY = misc.getFieldValue("ItemShadowOffset", 1); - if ((itemShadowFile != null) && !"_".equals(itemShadowFile)) { - final String texture = "ReplaceableTextures\\Shadows\\" + itemShadowFile + ".blp"; - final float shadowX = itemShadowX; - final float shadowY = itemShadowY; - final float shadowWidth = itemShadowWidth; - final float shadowHeight = itemShadowHeight; - if (!this.terrain.splats.containsKey(texture)) { - final Splat splat = new Splat(); - splat.opacity = 0.5f; - this.terrain.splats.put(texture, splat); - } - final float x = unitX - shadowX; - final float y = unitY - shadowY; - this.terrain.splats.get(texture).locations - .add(new float[] { x, y, x + shadowWidth, y + shadowHeight, 3 }); - unitShadowSplat = this.terrain.splats.get(texture); - } - - path += ".mdx"; - } - } - else { - type = WorldEditorDataType.UNITS; - path = getUnitModelPath(row); - - buildingPathingPixelMap = getBuildingPathingPixelMap(row); - if (buildingPathingPixelMap != null) { - unitX = (float) Math.floor(unitX / 64f) * 64f; - unitY = (float) Math.floor(unitY / 64f) * 64f; - if (((buildingPathingPixelMap.getWidth() / 2) % 2) == 1) { - unitX += 32f; - } - if (((buildingPathingPixelMap.getHeight() / 2) % 2) == 1) { - unitY += 32f; - } - pathingInstance = this.terrain.pathingGrid.blitRemovablePathingOverlayTexture(unitX, unitY, - (int) Math.toDegrees(unitAngle), buildingPathingPixelMap); - } - - final String uberSplat = row.getFieldAsString(UBER_SPLAT, 0); - if (uberSplat != null) { - final Element uberSplatInfo = this.terrain.uberSplatTable.get(uberSplat); - if (uberSplatInfo != null) { - final String texturePath = uberSplatInfo.getField("Dir") + "\\" + uberSplatInfo.getField("file") - + ".blp"; - final float s = uberSplatInfo.getFieldFloatValue("Scale"); - if (this.unitsReady) { - buildingUberSplatDynamicIngame = this.terrain.addUberSplat(texturePath, unitX, unitY, 1, s, - false, false, false); - } - else { - if (!this.terrain.splats.containsKey(texturePath)) { - this.terrain.splats.put(texturePath, new Splat()); - } - final float x = unitX; - final float y = unitY; - buildingUberSplat = this.terrain.splats.get(texturePath); - buildingUberSplat.locations.add(new float[] { x - s, y - s, x + s, y + s, 1 }); - } - } - } - - final String unitShadow = row.getFieldAsString(UNIT_SHADOW, 0); - if ((unitShadow != null) && !"_".equals(unitShadow)) { - final String texture = "ReplaceableTextures\\Shadows\\" + unitShadow + ".blp"; - final float shadowX = row.getFieldAsFloat(UNIT_SHADOW_X, 0); - final float shadowY = row.getFieldAsFloat(UNIT_SHADOW_Y, 0); - final float shadowWidth = row.getFieldAsFloat(UNIT_SHADOW_W, 0); - final float shadowHeight = row.getFieldAsFloat(UNIT_SHADOW_H, 0); - if (this.mapMpq.has(texture)) { - final float x = unitX - shadowX; - final float y = unitY - shadowY; - if (this.unitsReady) { - unitShadowSplatDynamicIngame = this.terrain.addUnitShadowSplat(texture, x, y, - x + shadowWidth, y + shadowHeight, 3, 0.5f); - } - else { - if (!this.terrain.splats.containsKey(texture)) { - final Splat splat = new Splat(); - splat.opacity = 0.5f; - this.terrain.splats.put(texture, splat); - } - this.terrain.splats.get(texture).locations - .add(new float[] { x, y, x + shadowWidth, y + shadowHeight, 3 }); - unitShadowSplat = this.terrain.splats.get(texture); - } - } - } - - final String buildingShadow = row.getFieldAsString(BUILDING_SHADOW, 0); - if ((buildingShadow != null) && !"_".equals(buildingShadow)) { - buildingShadowInstance = this.terrain.addShadow(buildingShadow, unitX, unitY); - } - - final String soundName = row.getFieldAsString(UNIT_SOUNDSET, 0); - UnitSoundset unitSoundset = this.soundsetNameToSoundset.get(soundName); - if (unitSoundset == null) { - unitSoundset = new UnitSoundset(this.dataSource, this.unitAckSoundsTable, soundName); - this.soundsetNameToSoundset.put(soundName, unitSoundset); - } - soundset = unitSoundset; - - } - } - - if (path != null) { - final String unitSpecialArtPath = row.getFieldAsString(UNIT_SPECIAL, 0); - MdxModel specialArtModel; - if (unitSpecialArtPath != null) { - try { - specialArtModel = (MdxModel) this.load(mdx(unitSpecialArtPath), this.mapPathSolver, - this.solverParams); - } - catch (final Exception exc) { - exc.printStackTrace(); - specialArtModel = null; - } - } - else { - specialArtModel = null; - } - final MdxModel model = (MdxModel) this.load(path, this.mapPathSolver, this.solverParams); - MdxModel portraitModel; - final String portraitPath = path.substring(0, path.length() - 4) + "_portrait.mdx"; - if (this.dataSource.has(portraitPath)) { - portraitModel = (MdxModel) this.load(portraitPath, this.mapPathSolver, this.solverParams); - } - else { - portraitModel = model; - } - if (type == WorldEditorDataType.UNITS) { - final float angle = (float) Math.toDegrees(unitAngle); - final CUnit simulationUnit = this.simulation.internalCreateUnit(row.getAlias(), playerIndex, unitX, - unitY, angle, buildingPathingPixelMap, pathingInstance); - final RenderUnitTypeData typeData = getUnitTypeData(unitId, row); - if (!typeData.isAllowCustomTeamColor() || (customTeamColor == -1)) { - if (typeData.getTeamColor() != -1) { - customTeamColor = typeData.getTeamColor(); - } - else { - customTeamColor = playerIndex; - } - } - final RenderUnit renderUnit = new RenderUnit(this, model, row, unitX, unitY, unitZ, customTeamColor, - soundset, portraitModel, simulationUnit, typeData, specialArtModel, buildingShadowInstance, - this.selectionCircleScaleFactor, typeData.getAnimationWalkSpeed(), - typeData.getAnimationRunSpeed(), typeData.getScalingValue()); - this.unitToRenderPeer.put(simulationUnit, renderUnit); - this.widgets.add(renderUnit); - this.units.add(renderUnit); - if (unitShadowSplat != null) { - unitShadowSplat.unitMapping.add(new Consumer() { - @Override - public void accept(final SplatMover t) { - renderUnit.shadow = t; - } - }); - } - if (unitShadowSplatDynamicIngame != null) { - renderUnit.shadow = unitShadowSplatDynamicIngame; - } - if (buildingUberSplat != null) { - buildingUberSplat.unitMapping.add(new Consumer() { - - @Override - public void accept(final SplatMover t) { - renderUnit.uberSplat = t; - } - }); - } - if (buildingUberSplatDynamicIngame != null) { - renderUnit.uberSplat = buildingUberSplatDynamicIngame; - } - return simulationUnit; - } - else { - - final CItem simulationItem = this.simulation.createItem(row.getAlias(), unitX, unitY); - final RenderItem renderItem = new RenderItem(this, model, row, unitX, unitY, unitZ, unitAngle, soundset, - portraitModel, simulationItem); - this.widgets.add(renderItem); - this.itemToRenderPeer.put(simulationItem, renderItem); - - if (unitShadowSplat != null) { - unitShadowSplat.unitMapping.add(new Consumer() { - @Override - public void accept(final SplatMover t) { - renderItem.shadow = t; - } - }); - } - if (unitShadowSplatDynamicIngame != null) { - renderItem.shadow = unitShadowSplatDynamicIngame; - } - } - } - else { - System.err.println("Unknown unit ID: " + unitId); - } - return null; - } - - public String getUnitModelPath(final MutableGameObject row) { - String path; - path = row.getFieldAsString(UNIT_FILE, 0); - - if (path.toLowerCase().endsWith(".mdl") || path.toLowerCase().endsWith(".mdx")) { - path = path.substring(0, path.length() - 4); - } - if ((row.readSLKTagInt("fileVerFlags") == 2) && this.dataSource.has(path + "_V1.mdx")) { - path += "_V1"; - } - - path += ".mdx"; - return path; - } - - private BufferedImage getBuildingPathingPixelMap(final MutableGameObject row) { - final String pathingTexture = row.getFieldAsString(UNIT_PATHING, 0); - final BufferedImage buildingPathingPixelMap = loadPathingTexture(pathingTexture); - return buildingPathingPixelMap; - } - - private BufferedImage loadPathingTexture(final String pathingTexture) { - BufferedImage buildingPathingPixelMap = null; - if ((pathingTexture != null) && (pathingTexture.length() > 0) && !"_".equals(pathingTexture)) { - buildingPathingPixelMap = this.filePathToPathingMap.get(pathingTexture.toLowerCase()); - if (buildingPathingPixelMap == null) { - try { - if (pathingTexture.toLowerCase().endsWith(".tga")) { - buildingPathingPixelMap = TgaFile.readTGA(pathingTexture, - this.mapMpq.getResourceAsStream(pathingTexture)); - } - else { - try (InputStream stream = this.mapMpq.getResourceAsStream(pathingTexture)) { - buildingPathingPixelMap = ImageIO.read(stream); - System.out.println("LOADING BLP PATHING: " + pathingTexture); - } - } - this.filePathToPathingMap.put(pathingTexture.toLowerCase(), buildingPathingPixelMap); - } - catch (final Exception exc) { - System.err.println("Failure to get pathing: " + exc.getClass() + ":" + exc.getMessage()); - } - } - } - return buildingPathingPixelMap; - } - - public RenderUnitTypeData getUnitTypeData(final War3ID key, final MutableGameObject row) { - RenderUnitTypeData unitTypeData = this.unitIdToTypeData.get(key); - if (unitTypeData == null) { - unitTypeData = new RenderUnitTypeData(row.getFieldAsFloat(MAX_PITCH, 0), row.getFieldAsFloat(MAX_ROLL, 0), - row.getFieldAsFloat(ELEVATION_SAMPLE_RADIUS, 0), row.getFieldAsBoolean(ALLOW_CUSTOM_TEAM_COLOR, 0), - row.getFieldAsInteger(TEAM_COLOR, 0), row.getFieldAsFloat(ANIMATION_RUN_SPEED, 0), - row.getFieldAsFloat(ANIMATION_WALK_SPEED, 0), row.getFieldAsFloat(MODEL_SCALE, 0)); - this.unitIdToTypeData.put(key, unitTypeData); - } - return unitTypeData; - } - - @Override - public void update() { - if (this.anyReady) { - final float deltaTime = Gdx.graphics.getDeltaTime(); - this.terrain.update(deltaTime); - - super.update(); - - final Iterator textTagIterator = this.textTags.iterator(); - while (textTagIterator.hasNext()) { - if (textTagIterator.next().update(deltaTime)) { - textTagIterator.remove(); - } - } - for (final RenderWidget unit : this.widgets) { - unit.updateAnimations(this); - } - final Iterator projectileIterator = this.projectiles.iterator(); - while (projectileIterator.hasNext()) { - final RenderEffect projectile = projectileIterator.next(); - if (projectile.updateAnimations(this, Gdx.graphics.getDeltaTime())) { - projectileIterator.remove(); - } - } - for (final RenderDoodad item : this.doodads) { - final ModelInstance instance = item.instance; - if (instance instanceof MdxComplexInstance) { - final MdxComplexInstance mdxComplexInstance = (MdxComplexInstance) instance; - if ((mdxComplexInstance.sequence == -1) || (mdxComplexInstance.sequenceEnded - && ((item.getAnimation() != AnimationTokens.PrimaryTag.DEATH) - || (((MdxModel) mdxComplexInstance.model).sequences.get(mdxComplexInstance.sequence) - .getFlags() == 0)))) { - SequenceUtils.randomSequence(mdxComplexInstance, item.getAnimation(), SequenceUtils.EMPTY, - true); - - } - } - } - - final float rawDeltaTime = Gdx.graphics.getRawDeltaTime(); - this.updateTime += rawDeltaTime; - while (this.updateTime >= WarsmashConstants.SIMULATION_STEP_TIME) { - if (this.gameTurnManager.getLatestCompletedTurn() >= this.simulation.getGameTurnTick()) { - this.updateTime -= WarsmashConstants.SIMULATION_STEP_TIME; - this.simulation.update(); - this.gameTurnManager.turnCompleted(this.simulation.getGameTurnTick()); - } - else { - if (this.updateTime > (WarsmashConstants.SIMULATION_STEP_TIME * 3)) { - this.gameTurnManager.framesSkipped(this.updateTime / WarsmashConstants.SIMULATION_STEP_TIME); - this.updateTime = 0; - } - break; - } - } - this.dncTerrain.setFrameByRatio( - this.simulation.getGameTimeOfDay() / this.simulation.getGameplayConstants().getGameDayHours()); - this.dncTerrain.update(rawDeltaTime, null); - this.dncUnit.setFrameByRatio( - this.simulation.getGameTimeOfDay() / this.simulation.getGameplayConstants().getGameDayHours()); - this.dncUnit.update(rawDeltaTime, null); - this.dncUnitDay.setFrameByRatio(0.5f); - this.dncUnitDay.update(rawDeltaTime, null); - this.dncTarget.setFrameByRatio( - this.simulation.getGameTimeOfDay() / this.simulation.getGameplayConstants().getGameDayHours()); - this.dncTarget.update(rawDeltaTime, null); - } - } - - @Override - public void render() { - if (this.anyReady) { - final Scene worldScene = this.worldScene; - - startFrame(); - worldScene.startFrame(); - if (DEBUG_DEPTH > 0) { - worldScene.renderOpaque(this.dynamicShadowManager, this.webGL); - } - if (DEBUG_DEPTH > 1) { - this.terrain.renderGround(this.dynamicShadowManager); - } - if (DEBUG_DEPTH > 2) { - this.terrain.renderCliffs(); - } - if (DEBUG_DEPTH > 3) { - worldScene.renderOpaque(); - } - if (DEBUG_DEPTH > 4) { - this.terrain.renderUberSplats(false); - } - if (DEBUG_DEPTH > 5) { - this.terrain.renderWater(); - } - if (DEBUG_DEPTH > 6) { - worldScene.renderTranslucent(); - } - if (DEBUG_DEPTH > 7) { - this.terrain.renderUberSplats(true); - } - - final List scenes = this.scenes; - for (final Scene scene : scenes) { - if (scene != worldScene) { - scene.startFrame(); - if (DEBUG_DEPTH > 8) { - scene.renderOpaque(); - } - if (DEBUG_DEPTH > 9) { - scene.renderTranslucent(); - } - } - } - - final int glGetError = Gdx.gl.glGetError(); - if (glGetError != GL20.GL_NO_ERROR) { - throw new IllegalStateException("GL ERROR: " + glGetError); - } - } - } - - public void deselect() { - for (final String key : this.selectedSplatModelKeys) { - this.terrain.removeSplatBatchModel(key); - } - for (final RenderWidget unit : this.selected) { - unit.unassignSelectionCircle(); - } - this.selectedSplatModelKeys.clear(); - this.selected.clear(); - } - - public void doUnselectUnit(final RenderWidget widget) { - if (this.selected.remove(widget)) { - widget.getSelectionCircle(); - } - } - - public void doSelectUnit(final List units) { - deselect(); - if (units.isEmpty()) { - return; - } - - final Map splats = new HashMap(); - for (final RenderWidget unit : units) { - if (unit.getSelectionScale() > 0) { - String allyKey = "n:"; - final float selectionSize = unit.getSelectionScale(); - String path = null; - for (int i = 0; i < this.selectionCircleSizes.size(); i++) { - final SelectionCircleSize selectionCircleSize = this.selectionCircleSizes.get(i); - if ((selectionSize < selectionCircleSize.size) || (i == (this.selectionCircleSizes.size() - 1))) { - path = selectionCircleSize.texture; - break; - } - } - if (!path.toLowerCase().endsWith(".blp")) { - path += ".blp"; - } - if (unit instanceof RenderUnit) { - final int selectedUnitPlayerIndex = ((RenderUnit) unit).getSimulationUnit().getPlayerIndex(); - final CPlayer localPlayer = this.simulation.getPlayer(this.localPlayerIndex); - if (!localPlayer.hasAlliance(selectedUnitPlayerIndex, CAllianceType.PASSIVE)) { - allyKey = "e:"; - } - else if (localPlayer.hasAlliance(selectedUnitPlayerIndex, CAllianceType.HELP_REQUEST)) { - allyKey = "f:"; - } - } - path = allyKey + path; - final SplatModel splatModel = this.terrain.getSplatModel("selection:" + path); - if (splatModel != null) { - final float x = unit.getX(); - final float y = unit.getY(); - final SplatMover splatInstance = splatModel.add(x - (selectionSize / 2), y - (selectionSize / 2), - x + (selectionSize / 2), y + (selectionSize / 2), 5, this.terrain.centerOffset); - unit.assignSelectionCircle(splatInstance); - if (unit.getInstance().hidden()) { - splatInstance.hide(); - } - } - else { - if (!splats.containsKey(path)) { - splats.put(path, new Splat()); - } - final float x = unit.getX(); - final float y = unit.getY(); - System.out.println("Selecting a unit at " + x + "," + y); - splats.get(path).locations.add(new float[] { x - (selectionSize / 2), y - (selectionSize / 2), - x + (selectionSize / 2), y + (selectionSize / 2), 5 }); - splats.get(path).unitMapping.add(new Consumer() { - @Override - public void accept(final SplatMover t) { - unit.assignSelectionCircle(t); - if (unit.getInstance().hidden()) { - t.hide(); - } - } - }); - } - } - this.selected.add(unit); - } - for (final Map.Entry entry : splats.entrySet()) { - final String path = entry.getKey(); - final String filePath = path.substring(2); - final String allyKey = path.substring(0, 2); - final Splat locations = entry.getValue(); - final SplatModel model = new SplatModel(Gdx.gl30, (Texture) load(filePath, PathSolver.DEFAULT, null), - locations.locations, this.terrain.centerOffset, locations.unitMapping, true, false, true); - switch (allyKey) { - case "e:": - model.color[0] = this.selectionCircleColorEnemy.r; - model.color[1] = this.selectionCircleColorEnemy.g; - model.color[2] = this.selectionCircleColorEnemy.b; - model.color[3] = this.selectionCircleColorEnemy.a; - break; - case "f:": - model.color[0] = this.selectionCircleColorFriend.r; - model.color[1] = this.selectionCircleColorFriend.g; - model.color[2] = this.selectionCircleColorFriend.b; - model.color[3] = this.selectionCircleColorFriend.a; - break; - default: - model.color[0] = this.selectionCircleColorNeutral.r; - model.color[1] = this.selectionCircleColorNeutral.g; - model.color[2] = this.selectionCircleColorNeutral.b; - model.color[3] = this.selectionCircleColorNeutral.a; - break; - } - this.terrain.addSplatBatchModel("selection:" + path, model); - this.selectedSplatModelKeys.add("selection:" + path); - } - } - - public void clearUnitMouseOverHighlight(final RenderWidget unit) { - this.mouseHighlightWidgets.remove(unit); - unit.getSelectionPreviewHighlight().destroy(Gdx.gl30, this.terrain.centerOffset); - unit.unassignSelectionPreviewHighlight(); - } - - public void clearUnitMouseOverHighlight() { - for (final String modelKey : this.mouseHighlightSplatModelKeys) { - this.terrain.removeSplatBatchModel(modelKey); - } - for (final RenderWidget widget : this.mouseHighlightWidgets) { - widget.unassignSelectionPreviewHighlight(); - } - this.mouseHighlightSplatModelKeys.clear(); - this.mouseHighlightWidgets.clear(); - } - - public void showUnitMouseOverHighlight(final RenderWidget unit) { - final Map splats = new HashMap(); - if (unit.getSelectionScale() > 0) { - String allyKey = "n:"; - final float selectionSize = unit.getSelectionScale(); - String path = null; - for (int i = 0; i < this.selectionCircleSizes.size(); i++) { - final SelectionCircleSize selectionCircleSize = this.selectionCircleSizes.get(i); - if ((selectionSize < selectionCircleSize.size) || (i == (this.selectionCircleSizes.size() - 1))) { - path = selectionCircleSize.texture; - break; - } - } - if (!path.toLowerCase().endsWith(".blp")) { - path += ".blp"; - } - if (unit instanceof RenderUnit) { - final int selectedUnitPlayerIndex = ((RenderUnit) unit).getSimulationUnit().getPlayerIndex(); - final CPlayer localPlayer = this.simulation.getPlayer(this.localPlayerIndex); - if (!localPlayer.hasAlliance(selectedUnitPlayerIndex, CAllianceType.PASSIVE)) { - allyKey = "e:"; - } - else if (localPlayer.hasAlliance(selectedUnitPlayerIndex, CAllianceType.HELP_REQUEST)) { - allyKey = "f:"; - } - } - path = allyKey + path; - final SplatModel splatModel = this.terrain.getSplatModel("mouseover:" + path); - if (splatModel != null) { - final float x = unit.getX(); - final float y = unit.getY(); - final SplatMover splatInstance = splatModel.add(x - (selectionSize / 2), y - (selectionSize / 2), - x + (selectionSize / 2), y + (selectionSize / 2), 4, this.terrain.centerOffset); - unit.assignSelectionPreviewHighlight(splatInstance); - if (unit.getInstance().hidden()) { - splatInstance.hide(); - } - } - else { - if (!splats.containsKey(path)) { - splats.put(path, new Splat()); - } - final float x = unit.getX(); - final float y = unit.getY(); - splats.get(path).locations.add(new float[] { x - (selectionSize / 2), y - (selectionSize / 2), - x + (selectionSize / 2), y + (selectionSize / 2), 4 }); - splats.get(path).unitMapping.add(new Consumer() { - @Override - public void accept(final SplatMover t) { - unit.assignSelectionPreviewHighlight(t); - if (unit.getInstance().hidden()) { - t.hide(); - } - } - }); - } - } - this.mouseHighlightWidgets.add(unit); - for (final Map.Entry entry : splats.entrySet()) { - final String path = entry.getKey(); - final String filePath = path.substring(2); - final String allyKey = path.substring(0, 2); - final Splat locations = entry.getValue(); - final SplatModel model = new SplatModel(Gdx.gl30, (Texture) load(filePath, PathSolver.DEFAULT, null), - locations.locations, this.terrain.centerOffset, locations.unitMapping, true, false, true); - switch (allyKey) { - case "e:": - model.color[0] = this.selectionCircleColorEnemy.r; - model.color[1] = this.selectionCircleColorEnemy.g; - model.color[2] = this.selectionCircleColorEnemy.b; - model.color[3] = this.selectionCircleColorEnemy.a * 0.5f; - break; - case "f:": - model.color[0] = this.selectionCircleColorFriend.r; - model.color[1] = this.selectionCircleColorFriend.g; - model.color[2] = this.selectionCircleColorFriend.b; - model.color[3] = this.selectionCircleColorFriend.a * 0.5f; - break; - default: - model.color[0] = this.selectionCircleColorNeutral.r; - model.color[1] = this.selectionCircleColorNeutral.g; - model.color[2] = this.selectionCircleColorNeutral.b; - model.color[3] = this.selectionCircleColorNeutral.a * 0.5f; - break; - } - this.mouseHighlightSplatModelKeys.add("mouseover:" + path); - this.terrain.addSplatBatchModel("mouseover:" + path, model); - } - } - - public void getClickLocation(final Vector3 out, final int screenX, final int screenY) { - final float[] ray = rayHeap; - mousePosHeap.set(screenX, screenY); - this.worldScene.camera.screenToWorldRay(ray, mousePosHeap); - gdxRayHeap.set(ray[0], ray[1], ray[2], ray[3] - ray[0], ray[4] - ray[1], ray[5] - ray[2]); - gdxRayHeap.direction.nor();// needed for libgdx - RenderMathUtils.intersectRayTriangles(gdxRayHeap, this.terrain.softwareGroundMesh.vertices, - this.terrain.softwareGroundMesh.indices, 3, out); - rectangleHeap.set(Math.min(out.x, gdxRayHeap.origin.x), Math.min(out.y, gdxRayHeap.origin.y), - Math.abs(out.x - gdxRayHeap.origin.x), Math.abs(out.y - gdxRayHeap.origin.y)); - this.walkableObjectsTree.intersect(rectangleHeap, this.walkablesIntersectionFinder.reset(gdxRayHeap)); - if (this.walkablesIntersectionFinder.found) { - out.set(this.walkablesIntersectionFinder.intersection); - } - else { - out.z = Math.max(getWalkableRenderHeight(out.x, out.y), this.terrain.getGroundHeight(out.x, out.y)); - } - } - - public void showConfirmation(final Vector3 position, final float red, final float green, final float blue) { - this.confirmationInstance.show(); - this.confirmationInstance.setSequence(0); - this.confirmationInstance.setLocation(position); - this.worldScene.instanceMoved(this.confirmationInstance, position.x, position.y); - this.confirmationInstance.vertexColor[0] = red; - this.confirmationInstance.vertexColor[1] = green; - this.confirmationInstance.vertexColor[2] = blue; - } - - public RenderWidget rayPickUnit(final float x, final float y) { - return rayPickUnit(x, y, CWidgetFilterFunction.ACCEPT_ALL); - } - - public RenderWidget rayPickUnit(final float x, final float y, final CWidgetFilterFunction filter) { - final float[] ray = rayHeap; - mousePosHeap.set(x, y); - this.worldScene.camera.screenToWorldRay(ray, mousePosHeap); - gdxRayHeap.set(ray[0], ray[1], ray[2], ray[3] - ray[0], ray[4] - ray[1], ray[5] - ray[2]); - gdxRayHeap.direction.nor();// needed for libgdx - - RenderWidget entity = null; - intersectionHeap2.set(ray[3], ray[4], ray[5]); - for (final RenderWidget unit : this.widgets) { - final MdxComplexInstance instance = unit.getInstance(); - if (instance.shown() && instance.isVisible(this.worldScene.camera) - && instance.intersectRayWithCollisionSimple(gdxRayHeap, intersectionHeap)) { - if (filter.call(unit.getSimulationWidget())) { - final float groundHeight = this.terrain.getGroundHeight(intersectionHeap.x, intersectionHeap.y); - if (intersectionHeap.z > groundHeight) { - if (((entity == null) && !unit.isIntersectedOnMeshAlways())) { - entity = unit; - } - else { - if (instance.intersectRayWithMeshSlow(gdxRayHeap, intersectionHeap)) { - if (intersectionHeap.z > this.terrain.getGroundHeight(intersectionHeap.x, - intersectionHeap.y)) { - this.worldScene.camera.worldToCamera(intersectionHeap, intersectionHeap); - if ((entity == null) || (intersectionHeap.z > intersectionHeap2.z)) { - entity = unit; - intersectionHeap2.set(intersectionHeap); - } - } - } - } - } - } - } - } - return entity; - } - - private static final class MappedDataCallbackImplementation implements LoadGenericCallback { - @Override - public Object call(final InputStream data) { - final StringBuilder stringBuilder = new StringBuilder(); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(data, "utf-8"))) { - String line; - while ((line = reader.readLine()) != null) { - stringBuilder.append(line); - stringBuilder.append("\n"); - } - } - catch (final UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return new MappedData(stringBuilder.toString()); - } - } - - private static final class StringDataCallbackImplementation implements LoadGenericCallback { - @Override - public Object call(final InputStream data) { - if (data == null) { - System.err.println("data null"); - } - final StringBuilder stringBuilder = new StringBuilder(); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(data, "utf-8"))) { - String line; - while ((line = reader.readLine()) != null) { - stringBuilder.append(line); - stringBuilder.append("\n"); - } - } - catch (final UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - return stringBuilder.toString(); - } - } - - private static final class StreamDataCallbackImplementation implements LoadGenericCallback { - @Override - public Object call(final InputStream data) { - return data; - } - } - - public static final class SolverParams { - public char tileset; - public boolean reforged; - public boolean hd; - } - - public static final class CliffInfo { - public List locations = new ArrayList<>(); - public List textures = new ArrayList<>(); - } - - private static final int MAXIMUM_ACCEPTED = 1 << 30; - private float selectionCircleScaleFactor; - private DataTable worldEditData; - private WorldEditStrings worldEditStrings; - private Warcraft3MapObjectData allObjectData; - private AbilityDataUI abilityDataUI; - private Map soundsetNameToSoundset; - public int imageWalkableZOffset; - private WTS preloadedWTS; - - private Color selectionCircleColorFriend; - - private Color selectionCircleColorNeutral; - - private Color selectionCircleColorEnemy; - - /** - * Returns a power of two size for the given target capacity. - */ - private static final int pow2GreaterThan(final int capacity) { - int numElements = capacity - 1; - numElements |= numElements >>> 1; - numElements |= numElements >>> 2; - numElements |= numElements >>> 4; - numElements |= numElements >>> 8; - numElements |= numElements >>> 16; - return (numElements < 0) ? 1 : (numElements >= MAXIMUM_ACCEPTED) ? MAXIMUM_ACCEPTED : numElements + 1; - } - - public void standOnRepeat(final MdxComplexInstance instance) { - instance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - SequenceUtils.randomStandSequence(instance); - } - - private static final class SelectionCircleSize { - private final float size; - private final String texture; - private final String textureDotted; - - public SelectionCircleSize(final float size, final String texture, final String textureDotted) { - this.size = size; - this.texture = texture; - this.textureDotted = textureDotted; - } - } - - public void setDayNightModels(final String terrainDNCFile, final String unitDNCFile) { - final MdxModel terrainDNCModel = (MdxModel) load(mdx(terrainDNCFile), PathSolver.DEFAULT, null); - this.dncTerrain = (MdxComplexInstance) terrainDNCModel.addInstance(); - this.dncTerrain.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - this.dncTerrain.setSequence(0); - final MdxModel unitDNCModel = (MdxModel) load(mdx(unitDNCFile), PathSolver.DEFAULT, null); - this.dncUnit = (MdxComplexInstance) unitDNCModel.addInstance(); - this.dncUnit.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - this.dncUnit.setSequence(0); - this.dncUnitDay = (MdxComplexInstance) unitDNCModel.addInstance(); - this.dncUnitDay.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - this.dncUnitDay.setSequence(0); - final MdxModel targetDNCModel = (MdxModel) load( - mdx("Environment\\DNC\\DNCLordaeron\\DNCLordaeronTarget\\DNCLordaeronTarget.mdl"), PathSolver.DEFAULT, - null); - this.dncTarget = (MdxComplexInstance) targetDNCModel.addInstance(); - this.dncTarget.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - this.dncTarget.setSequence(0); - } - - public static String mdx(String mdxPath) { - if (mdxPath.toLowerCase().endsWith(".mdl")) { - mdxPath = mdxPath.substring(0, mdxPath.length() - 4); - } - if (!mdxPath.toLowerCase().endsWith(".mdx")) { - mdxPath += ".mdx"; - } - return mdxPath; - } - - public static String mdl(String mdxPath) { - if (mdxPath.toLowerCase().endsWith(".mdx")) { - mdxPath = mdxPath.substring(0, mdxPath.length() - 4); - } - if (!mdxPath.toLowerCase().endsWith(".mdl")) { - mdxPath += ".mdl"; - } - return mdxPath; - } - - public String blp(String iconPath) { - final int lastDotIndex = iconPath.lastIndexOf('.'); - if (lastDotIndex != -1) { - iconPath = iconPath.substring(0, lastDotIndex); - } - if (!iconPath.toLowerCase().endsWith(".blp")) { - iconPath += ".blp"; - } - return iconPath; - } - - public MdxModel loadModel(final String path) { - return (MdxModel) load(mdx(path), PathSolver.DEFAULT, null); - } - - @Override - public SceneLightManager createLightManager(final boolean simple) { - if (simple) { - return new W3xScenePortraitLightManager(this, this.lightDirection); - } - else { - return new W3xSceneWorldLightManager(this); - } - } - - @Override - public WorldEditStrings getWorldEditStrings() { - return this.worldEditStrings; - } - - public void setGameUI(final GameUI gameUI) { - this.gameUI = gameUI; - this.abilityDataUI = new AbilityDataUI(this.allObjectData.getAbilities(), this.allObjectData.getUnits(), - this.allObjectData.getItems(), this.allObjectData.getUpgrades(), gameUI, this); - } - - public GameUI getGameUI() { - return this.gameUI; - } - - public AbilityDataUI getAbilityDataUI() { - return this.abilityDataUI; - } - - public KeyedSounds getUiSounds() { - return this.uiSounds; - } - - public Warcraft3MapObjectData getAllObjectData() { - return this.allObjectData; - } - - public float getWalkableRenderHeight(final float x, final float y) { - this.walkableObjectsTree.intersect(x, y, this.walkablesIntersector.reset(x, y)); - return this.walkablesIntersector.z; - } - - public MdxComplexInstance getHighestWalkableUnder(final float x, final float y) { - this.walkableObjectsTree.intersect(x, y, this.intersectorFindsHighestWalkable.reset(x, y)); - return this.intersectorFindsHighestWalkable.highestInstance; - } - - public int getLocalPlayerIndex() { - return this.localPlayerIndex; - } - - public RenderUnit getRenderPeer(final CUnit unit) { - return this.unitToRenderPeer.get(unit); - } - - public RenderDestructable getRenderPeer(final CDestructable dest) { - return this.destructableToRenderPeer.get(dest); - } - - public RenderItem getRenderPeer(final CItem item) { - return this.itemToRenderPeer.get(item); - } - - public RenderWidget getRenderPeer(final CWidget damagedDestructable) { - RenderWidget damagedWidget = War3MapViewer.this.unitToRenderPeer.get(damagedDestructable); - if (damagedWidget == null) { - damagedWidget = War3MapViewer.this.destructableToRenderPeer.get(damagedDestructable); - } - if (damagedWidget == null) { - damagedWidget = War3MapViewer.this.itemToRenderPeer.get(damagedDestructable); - } - return damagedWidget; - } - - private static final class QuadtreeIntersectorFindsWalkableRenderHeight - implements QuadtreeIntersector { - private float z; - private final Ray ray = new Ray(); - private final Vector3 intersection = new Vector3(); - - private QuadtreeIntersectorFindsWalkableRenderHeight reset(final float x, final float y) { - this.z = -Float.MAX_VALUE; - this.ray.set(x, y, 4096, 0, 0, -8192); - return this; - } - - @Override - public boolean onIntersect(final MdxComplexInstance intersectingObject) { - if (intersectingObject.intersectRayWithCollision(this.ray, this.intersection, true, true)) { - this.z = Math.max(this.z, this.intersection.z); - } - return false; - } - } - - private static final class QuadtreeIntersectorFindsHighestWalkable - implements QuadtreeIntersector { - private float z; - private final Ray ray = new Ray(); - private final Vector3 intersection = new Vector3(); - private MdxComplexInstance highestInstance; - - private QuadtreeIntersectorFindsHighestWalkable reset(final float x, final float y) { - this.z = -Float.MAX_VALUE; - this.ray.set(x, y, 4096, 0, 0, -8192); - this.highestInstance = null; - return this; - } - - @Override - public boolean onIntersect(final MdxComplexInstance intersectingObject) { - if (intersectingObject.intersectRayWithCollision(this.ray, this.intersection, true, true)) { - if (this.intersection.z > this.z) { - this.z = this.intersection.z; - this.highestInstance = intersectingObject; - } - } - return false; - } - } - - private static final class QuadtreeIntersectorFindsHitPoint implements QuadtreeIntersector { - private Ray ray; - private final Vector3 intersection = new Vector3(); - private boolean found; - - private QuadtreeIntersectorFindsHitPoint reset(final Ray ray) { - this.ray = ray; - this.found = false; - return this; - } - - @Override - public boolean onIntersect(final MdxComplexInstance intersectingObject) { - if (intersectingObject.intersectRayWithCollision(this.ray, this.intersection, true, true)) { - this.found = true; - return true; - } - return false; - } - } - - public void add(final TextTag textTag) { - this.textTags.add(textTag); - } - - public SettableCommandErrorListener getCommandErrorListener() { - return this.commandErrorListener; - } - - public War3MapConfig getMapConfig() { - return this.mapConfig; - } - - public void setLocalPlayerIndex(final int playerIndex) { - // TODO this is HACKY to not do this on INIT, but it is a cheese way to try to - // do the networking for now!!! - this.localPlayerIndex = playerIndex; - } - - public void setGameTurnManager(final GameTurnManager gameTurnManager) { - this.gameTurnManager = gameTurnManager; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraManager.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraManager.java deleted file mode 100644 index d44d73e2..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraManager.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.camera; - -import com.badlogic.gdx.math.Quaternion; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.viewer5.Camera; -import com.etheller.warsmash.viewer5.CanvasProvider; -import com.etheller.warsmash.viewer5.Scene; - -public abstract class CameraManager { - private static final double HORIZONTAL_ANGLE_INCREMENT = Math.PI / 60; - protected final float[] cameraPositionTemp = new float[3]; - protected final float[] cameraTargetTemp = new float[3]; - protected CanvasProvider canvas; - public Camera camera; - protected float moveSpeed; - protected float rotationSpeed; - protected float zoomFactor; - public float horizontalAngle; - public float verticalAngle; - public float distance; - protected Vector3 position; - public Vector3 target; - protected Vector3 worldUp; - protected Vector3 vecHeap; - protected Quaternion quatHeap; - protected Quaternion quatHeap2; - - public CameraManager() { - } - - // An orbit camera setup example. - // Left mouse button controls the orbit itself. - // The right mouse button allows to move the camera and the point it's looking - // at on the XY plane. - // Scrolling zooms in and out. - public void setupCamera(final Scene scene) { - this.canvas = scene.viewer.canvas; - this.camera = scene.camera; - this.moveSpeed = 2; - this.rotationSpeed = (float) HORIZONTAL_ANGLE_INCREMENT; - this.zoomFactor = 0.1f; - this.horizontalAngle = 0;// (float) (Math.PI / 2); - this.verticalAngle = (float) Math.toRadians(34); - this.distance = 1650; - this.position = new Vector3(); - this.target = new Vector3(0, 0, 0); - this.worldUp = new Vector3(0, 0, 1); - this.vecHeap = new Vector3(); - this.quatHeap = new Quaternion(); - this.quatHeap2 = new Quaternion(); - - updateCamera(); - -// cameraUpdate(); - } - - public abstract void updateCamera(); - -// private void cameraUpdate() { -// -// } -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraPanControls.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraPanControls.java deleted file mode 100644 index 964dbb9a..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraPanControls.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.camera; - -public final class CameraPanControls { - protected boolean down; - protected boolean up; - protected boolean left; - protected boolean right; - protected boolean insertDown; - protected boolean deleteDown; -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraPreset.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraPreset.java deleted file mode 100644 index 92ed43c0..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraPreset.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.camera; - -public class CameraPreset { - private final float aoa; - private final float fov; - private final float rotation; - private final float rotationInsert; - private final float rotationDelete; - private final float distance; - private final float farZ; - private final float nearZ; - private final float height; - private final float listenerDistance; - private final float listenerAOA; - - public CameraPreset(final float aoa, final float fov, final float rotation, final float rotationInsert, - final float rotationDelete, final float distance, final float farZ, final float nearZ, final float height, - final float listenerDistance, final float listenerAOA) { - this.aoa = aoa; - this.fov = fov; - this.rotation = rotation; - this.rotationInsert = rotationInsert; - this.rotationDelete = rotationDelete; - this.distance = distance; - this.farZ = farZ; - this.nearZ = nearZ; - this.height = height; - this.listenerDistance = listenerDistance; - this.listenerAOA = listenerAOA; - } - - public float getRotation(final boolean insertDown, final boolean deleteDown) { - if (insertDown && !deleteDown) { - return this.rotationInsert; - } - if (!insertDown && deleteDown) { - return this.rotationDelete; - } - return this.rotation; - } - - public float getHeight() { - return this.height; - } - - public float getAoa() { - return this.aoa; - } - - public float getFov() { - return this.fov; - } - - public float getRotation() { - return this.rotation; - } - - public float getRotationInsert() { - return this.rotationInsert; - } - - public float getRotationDelete() { - return this.rotationDelete; - } - - public float getDistance() { - return this.distance; - } - - public float getFarZ() { - return this.farZ; - } - - public float getNearZ() { - return this.nearZ; - } - - public float getListenerDistance() { - return this.listenerDistance; - } - - public float getListenerAOA() { - return this.listenerAOA; - } -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraRates.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraRates.java deleted file mode 100644 index 430d4e81..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/CameraRates.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.camera; - -public class CameraRates { - public final float aoa; - public final float fov; - public final float rotation; - public final float distance; - public final float forward; - public final float strafe; - - public CameraRates(final float aoa, final float fov, final float rotation, final float distance, - final float forward, final float strafe) { - this.aoa = aoa; - this.fov = fov; - this.rotation = rotation; - this.distance = distance; - this.forward = forward; - this.strafe = strafe; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/GameCameraManager.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/GameCameraManager.java deleted file mode 100644 index 017deebf..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/GameCameraManager.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.camera; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Input; -import com.badlogic.gdx.math.Rectangle; - -public final class GameCameraManager extends CameraManager { - private static final CameraRates INFINITE_CAMERA_RATES = new CameraRates(Float.POSITIVE_INFINITY, - Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, - Float.POSITIVE_INFINITY); - private final CameraPreset[] presets; - private final CameraRates cameraRates; - public final CameraPanControls cameraPanControls; - private int currentPreset = 0; - private float fov; - - public GameCameraManager(final CameraPreset[] presets, final CameraRates cameraRates) { - this.presets = presets; - this.cameraRates = cameraRates; - this.cameraPanControls = new CameraPanControls(); - } - - @Override - public void updateCamera() { - final CameraPreset cameraPreset = this.presets[this.currentPreset]; - final CameraRates cameraRate = this.cameraRates; - updateCamera(cameraPreset, cameraRate); - } - - private void updateCamera(final CameraPreset cameraPreset, final CameraRates cameraRate) { - this.quatHeap2.idt(); - this.quatHeap.idt(); - this.horizontalAngle = applyAtRate(this.horizontalAngle, (float) Math.toRadians( - cameraPreset.getRotation(this.cameraPanControls.insertDown, this.cameraPanControls.deleteDown) - 90), - (float) Math.toRadians(cameraRate.rotation * 3)); - this.quatHeap.setFromAxisRad(0, 0, 1, this.horizontalAngle); - this.distance = applyAtRate(this.distance, Math.max(1200, cameraPreset.getDistance()), cameraRate.distance); - this.verticalAngle = applyAtRate(this.verticalAngle, - (float) Math.toRadians(Math.min(335, cameraPreset.getAoa()) - 270), - (float) Math.toRadians(cameraRate.aoa)); - this.quatHeap2.setFromAxisRad(1, 0, 0, this.verticalAngle); - this.quatHeap.mul(this.quatHeap2); - - this.position.set(0, 0, 1); - this.quatHeap.transform(this.position); - this.position.nor(); - this.position.scl(this.distance); - this.position = this.position.add(this.target); - this.fov = applyAtRate(this.fov, (float) Math.toRadians(cameraPreset.getFov() / 2), - (float) Math.toRadians(cameraRate.fov)); - this.camera.perspective(this.fov, this.camera.getAspect(), cameraPreset.getNearZ(), cameraPreset.getFarZ()); - - this.camera.moveToAndFace(this.position, this.target, this.worldUp); - } - - private static float applyAtRate(final float oldValue, final float newValue, float rate) { - rate *= Gdx.graphics.getDeltaTime(); - final float deltaDistance = newValue - oldValue; - if (Math.abs(deltaDistance) < rate) { - return newValue; - } - else { - return oldValue + (Math.signum(deltaDistance) * rate); - } - } - - public void resize(final Rectangle viewport) { - this.camera.viewport(viewport); - } - - public void applyVelocity(final float deltaTime, boolean up, boolean down, boolean left, boolean right) { - final float velocityX; - final float velocityY; - up |= this.cameraPanControls.up; - down |= this.cameraPanControls.down; - left |= this.cameraPanControls.left; - right |= this.cameraPanControls.right; - if (up) { - if (down) { - velocityY = 0; - } - else { - velocityY = this.cameraRates.forward; - } - } - else if (down) { - velocityY = -this.cameraRates.forward; - } - else { - velocityY = 0; - } - if (right) { - if (left) { - velocityX = 0; - } - else { - velocityX = this.cameraRates.strafe; - } - } - else if (left) { - velocityX = -this.cameraRates.strafe; - } - else { - velocityX = 0; - } - this.target.add(velocityX * deltaTime, velocityY * deltaTime, 0); - - } - - public void updateTargetZ(final float groundHeight) { - this.target.z = groundHeight + this.presets[this.currentPreset].getHeight(); - } - - public void scrolled(final int amount) { - this.currentPreset -= amount; - if (this.currentPreset < 0) { - this.currentPreset = 0; - } - if (this.currentPreset >= this.presets.length) { - this.currentPreset = this.presets.length - 1; - } - } - - public boolean keyDown(final int keycode) { - if (keycode == Input.Keys.LEFT) { - this.cameraPanControls.left = true; - return true; - } - else if (keycode == Input.Keys.RIGHT) { - this.cameraPanControls.right = true; - return true; - } - else if (keycode == Input.Keys.DOWN) { - this.cameraPanControls.down = true; - return true; - } - else if (keycode == Input.Keys.UP) { - this.cameraPanControls.up = true; - return true; - } - else if (keycode == Input.Keys.INSERT) { - this.cameraPanControls.insertDown = true; - return true; - } - else if (keycode == Input.Keys.FORWARD_DEL) { - this.cameraPanControls.deleteDown = true; - return true; - } - return false; - } - - public boolean keyUp(final int keycode) { - if (keycode == Input.Keys.LEFT) { - this.cameraPanControls.left = false; - return true; - } - else if (keycode == Input.Keys.RIGHT) { - this.cameraPanControls.right = false; - return true; - } - else if (keycode == Input.Keys.DOWN) { - this.cameraPanControls.down = false; - return true; - } - else if (keycode == Input.Keys.UP) { - this.cameraPanControls.up = false; - return true; - } - else if (keycode == Input.Keys.INSERT) { - this.cameraPanControls.insertDown = false; - return true; - } - else if (keycode == Input.Keys.FORWARD_DEL) { - this.cameraPanControls.deleteDown = false; - return true; - } - return false; - } -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/PortraitCameraManager.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/PortraitCameraManager.java deleted file mode 100644 index 4ecf1069..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/camera/PortraitCameraManager.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.camera; - -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; - -public final class PortraitCameraManager extends CameraManager { - public com.etheller.warsmash.viewer5.handlers.mdx.Camera modelCamera; - protected MdxComplexInstance modelInstance; - - @Override - public void updateCamera() { - this.quatHeap.idt(); - this.quatHeap.setFromAxisRad(0, 0, 1, this.horizontalAngle); - this.quatHeap2.idt(); - this.quatHeap2.setFromAxisRad(1, 0, 0, this.verticalAngle); - this.quatHeap.mul(this.quatHeap2); - - this.position.set(0, 0, 1); - this.quatHeap.transform(this.position); - this.position.scl(this.distance); - this.position = this.position.add(this.target); - if (this.modelCamera != null) { - this.modelCamera.getPositionTranslation(this.cameraPositionTemp, this.modelInstance.sequence, - this.modelInstance.frame, this.modelInstance.counter); - this.modelCamera.getTargetTranslation(this.cameraTargetTemp, this.modelInstance.sequence, - this.modelInstance.frame, this.modelInstance.counter); - - this.position.set(this.modelCamera.position); - this.target.set(this.modelCamera.targetPosition); - - this.position.add(this.cameraPositionTemp[0], this.cameraPositionTemp[1], this.cameraPositionTemp[2]); - this.target.add(this.cameraTargetTemp[0], this.cameraTargetTemp[1], this.cameraTargetTemp[2]); - this.camera.perspective(this.modelCamera.fieldOfView * 0.75f, this.camera.getAspect(), - this.modelCamera.nearClippingPlane, this.modelCamera.farClippingPlane); - } - else { - this.camera.perspective(70, this.camera.getAspect(), 100, 5000); - } - - this.camera.moveToAndFace(this.position, this.target, this.worldUp); - } - - public void setModelInstance(final MdxComplexInstance modelInstance, final MdxModel portraitModel) { - this.modelInstance = modelInstance; - if (modelInstance == null) { - this.modelCamera = null; - } - else if ((portraitModel != null) && (portraitModel.getCameras().size() > 0)) { - this.modelCamera = portraitModel.getCameras().get(0); - } - } -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/BuildingShadow.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/BuildingShadow.java deleted file mode 100644 index 942790e5..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/BuildingShadow.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.environment; - -public interface BuildingShadow { - void remove(); - - void move(float x, float y); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/CliffMesh.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/CliffMesh.java deleted file mode 100644 index bebea05c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/CliffMesh.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.environment; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; - -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.GL30; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.util.RenderMathUtils; -import com.hiveworkshop.rms.parsers.mdlx.MdlxGeoset; -import com.hiveworkshop.rms.parsers.mdlx.MdlxModel; - -public class CliffMesh { - public int vertexBuffer; - public int uvBuffer; - public int normalBuffer; - public int indexBuffer; - public int instanceBuffer; - public int indices; - - private FloatBuffer renderJobs = ByteBuffer.allocateDirect(16 * 16).order(ByteOrder.nativeOrder()).asFloatBuffer(); - private final GL30 gl; - - public CliffMesh(final String path, final DataSource dataSource, final GL30 gl) throws IOException { - this.gl = gl; - if (path.endsWith(".mdx") || path.endsWith(".MDX")) { - final MdlxModel model = new MdlxModel(dataSource.read(path)); - final MdlxGeoset geoset = model.getGeosets().get(0); - - this.vertexBuffer = gl.glGenBuffer(); - gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.vertexBuffer); - gl.glBufferData(GL20.GL_ARRAY_BUFFER, geoset.getVertices().length * 4, - RenderMathUtils.wrap(geoset.getVertices()), GL20.GL_STATIC_DRAW); - - this.uvBuffer = gl.glGenBuffer(); - gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.uvBuffer); - gl.glBufferData(GL20.GL_ARRAY_BUFFER, geoset.getUvSets()[0].length * 4, - RenderMathUtils.wrap(geoset.getUvSets()[0]), GL20.GL_STATIC_DRAW); - - this.normalBuffer = gl.glGenBuffer(); - gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.normalBuffer); - gl.glBufferData(GL20.GL_ARRAY_BUFFER, geoset.getNormals().length * 4, - RenderMathUtils.wrap(geoset.getNormals()), GL20.GL_STATIC_DRAW); - - this.instanceBuffer = gl.glGenBuffer(); - - this.indices = geoset.getFaces().length; - this.indexBuffer = gl.glGenBuffer(); - gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.indexBuffer); - gl.glBufferData(GL20.GL_ARRAY_BUFFER, geoset.getFaces().length * 2, - RenderMathUtils.wrapFaces(geoset.getFaces()), GL20.GL_STATIC_DRAW); - } - } - - public void renderQueue(final float[] position) { - if (this.renderJobs.remaining() < 4) { - final int newCapacity = this.renderJobs.capacity() * 2; - final FloatBuffer newRenderJobs = ByteBuffer.allocateDirect(newCapacity * 4).order(ByteOrder.nativeOrder()) - .asFloatBuffer(); - newRenderJobs.clear(); - this.renderJobs.flip(); - newRenderJobs.put(this.renderJobs); - this.renderJobs = newRenderJobs; - } - this.renderJobs.put(position); - } - - public void render(final ShaderProgram cliffShader) { - if (this.renderJobs.position() == 0) { - return; - } - this.renderJobs.flip(); - - this.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.instanceBuffer); - this.gl.glBufferData(GL20.GL_ARRAY_BUFFER, this.renderJobs.remaining() * 4, this.renderJobs, - GL20.GL_DYNAMIC_DRAW); - - this.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.vertexBuffer); - this.gl.glVertexAttribPointer(cliffShader.getAttributeLocation("vPosition"), 3, GL20.GL_FLOAT, false, 0, 0); - - this.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.uvBuffer); - this.gl.glVertexAttribPointer(cliffShader.getAttributeLocation("vUV"), 2, GL20.GL_FLOAT, false, 0, 0); - - this.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.normalBuffer); - this.gl.glVertexAttribPointer(cliffShader.getAttributeLocation("vNormal"), 3, GL20.GL_FLOAT, false, 0, 0); - - this.gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, this.instanceBuffer); - final int offsetAttributeLocation = cliffShader.getAttributeLocation("vOffset"); - this.gl.glVertexAttribPointer(offsetAttributeLocation, 4, GL20.GL_FLOAT, false, 0, 0); - this.gl.glVertexAttribDivisor(offsetAttributeLocation, 1); - - this.gl.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, this.indexBuffer); - this.gl.glDrawElementsInstanced(GL20.GL_TRIANGLES, this.indices, GL30.GL_UNSIGNED_SHORT, 0, - this.renderJobs.remaining() / 4); - - this.gl.glVertexAttribDivisor(offsetAttributeLocation, 0); // ToDo use vao - - this.renderJobs.clear(); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/GroundTexture.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/GroundTexture.java deleted file mode 100644 index 2f7dcf53..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/GroundTexture.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.environment; - -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.nio.Buffer; - -import com.badlogic.gdx.graphics.GL30; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.util.ImageUtils; -import com.etheller.warsmash.util.ImageUtils.AnyExtensionImage; - -public class GroundTexture { - public int id; - private int tileSize; - public boolean extended; - - public GroundTexture(final String path, final DataSource dataSource, final GL30 gl) throws IOException { - final AnyExtensionImage imageInfo = ImageUtils.getAnyExtensionImageFixRGB(dataSource, path, "ground texture"); - loadImage(path, gl, imageInfo.getImageData(), imageInfo.isNeedsSRGBFix()); - } - - private void loadImage(final String path, final GL30 gl, final BufferedImage image, final boolean sRGBFix) { - if (image == null) { - throw new IllegalStateException("Missing ground texture: " + path); - } - final Buffer buffer = ImageUtils.getTextureBuffer(sRGBFix ? ImageUtils.forceBufferedImagesRGB(image) : image); - final int width = image.getWidth(); - final int height = image.getHeight(); - - this.tileSize = (int) (height * 0.25); - this.extended = (width > height); - - this.id = gl.glGenTexture(); - gl.glBindTexture(GL30.GL_TEXTURE_2D_ARRAY, this.id); - gl.glTexImage3D(GL30.GL_TEXTURE_2D_ARRAY, 0, GL30.GL_RGBA8, this.tileSize, this.tileSize, - this.extended ? 32 : 16, 0, GL30.GL_RGBA, GL30.GL_UNSIGNED_BYTE, null); - gl.glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL30.GL_TEXTURE_MIN_FILTER, GL30.GL_LINEAR_MIPMAP_LINEAR); - gl.glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL30.GL_TEXTURE_WRAP_S, GL30.GL_CLAMP_TO_EDGE); - gl.glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL30.GL_TEXTURE_WRAP_T, GL30.GL_CLAMP_TO_EDGE); - - gl.glPixelStorei(GL30.GL_UNPACK_ROW_LENGTH, width); - for (int y = 0; y < 4; y++) { - for (int x = 0; x < 4; x++) { - buffer.position(((y * this.tileSize * width) + (x * this.tileSize)) * 4); - gl.glTexSubImage3D(GL30.GL_TEXTURE_2D_ARRAY, 0, 0, 0, (y * 4) + x, this.tileSize, this.tileSize, 1, - GL30.GL_RGBA, GL30.GL_UNSIGNED_BYTE, buffer); - - if (this.extended) { - buffer.position(((y * this.tileSize * width) + ((x + 4) * this.tileSize)) * 4); - gl.glTexSubImage3D(GL30.GL_TEXTURE_2D_ARRAY, 0, 0, 0, (y * 4) + x + 16, this.tileSize, - this.tileSize, 1, GL30.GL_RGBA, GL30.GL_UNSIGNED_BYTE, buffer); - } - } - } - gl.glPixelStorei(GL30.GL_UNPACK_ROW_LENGTH, 0); - gl.glGenerateMipmap(GL30.GL_TEXTURE_2D_ARRAY); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/IVec3.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/IVec3.java deleted file mode 100644 index 08ef4438..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/IVec3.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.environment; - -public class IVec3 { - public int x; - public int y; - public int z; - - public IVec3(final int x, final int y, final int z) { - this.x = x; - this.y = y; - this.z = z; - } - - public int getX() { - return this.x; - } - - public int getY() { - return this.y; - } - - public int getZ() { - return this.z; - } - - public void setX(final int x) { - this.x = x; - } - - public void setY(final int y) { - this.y = y; - } - - public void setZ(final int z) { - this.z = z; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/PathingGrid.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/PathingGrid.java deleted file mode 100644 index ac16514a..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/PathingGrid.java +++ /dev/null @@ -1,462 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.environment; - -import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.badlogic.gdx.math.Rectangle; -import com.etheller.warsmash.parsers.w3x.wpm.War3MapWpm; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWorldCollision; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CBuildingPathingType; - -public class PathingGrid { - private static final Map movetpToMovementType = new HashMap<>(); - static { - for (final MovementType movementType : MovementType.values()) { - if (!movementType.typeKey.isEmpty()) { - movetpToMovementType.put(movementType.typeKey, movementType); - } - } - } - - private final short[] pathingGrid; - private final short[] dynamicPathingOverlay; // for buildings and trees - private final int[] pathingGridSizes; - private final float[] centerOffset; - private final List dynamicPathingInstances; - - public PathingGrid(final War3MapWpm terrainPathing, final float[] centerOffset) { - this.centerOffset = centerOffset; - this.pathingGrid = terrainPathing.getPathing(); - this.pathingGridSizes = terrainPathing.getSize(); - this.dynamicPathingOverlay = new short[this.pathingGrid.length]; - this.dynamicPathingInstances = new ArrayList<>(); - } - - // this blit function is basically copied from HiveWE, maybe remember to mention - // that in credits as well: - // https://github.com/stijnherfst/HiveWE/blob/master/Base/PathingMap.cpp - private void blitPathingOverlayTexture(final float positionX, final float positionY, final int rotationInput, - final BufferedImage pathingTextureTga) { - final int rotation = (rotationInput + 450) % 360; - final int divW = ((rotation % 180) != 0) ? pathingTextureTga.getHeight() : pathingTextureTga.getWidth(); - final int divH = ((rotation % 180) != 0) ? pathingTextureTga.getWidth() : pathingTextureTga.getHeight(); - for (int j = 0; j < pathingTextureTga.getHeight(); j++) { - for (int i = 0; i < pathingTextureTga.getWidth(); i++) { - int x = i; - int y = j; - - switch (rotation) { - case 90: - x = pathingTextureTga.getHeight() - 1 - j; - y = i; - break; - case 180: - x = pathingTextureTga.getWidth() - 1 - i; - y = pathingTextureTga.getHeight() - 1 - j; - break; - case 270: - x = j; - y = pathingTextureTga.getWidth() - 1 - i; - break; - } - // Width and height for centering change if rotation is not divisible by 180 - final int xx = (getCellX(positionX) + x) - (divW / 2); - final int yy = (getCellY(positionY) + y) - (divH / 2); - - if ((xx < 0) || (xx > (this.pathingGridSizes[0] - 1)) || (yy < 0) - || (yy > (this.pathingGridSizes[1] - 1))) { - continue; - } - - final int rgb = pathingTextureTga.getRGB(i, pathingTextureTga.getHeight() - 1 - j); - byte data = 0; - if ((rgb & 0xFF) > 127) { - data |= PathingFlags.UNBUILDABLE; - } - if (((rgb & 0xFF00) >>> 8) > 127) { - data |= PathingFlags.UNFLYABLE; - } - if (((rgb & 0xFF0000) >>> 16) > 127) { - data |= PathingFlags.UNWALKABLE | PathingFlags.UNSWIMABLE; - } - this.dynamicPathingOverlay[(yy * this.pathingGridSizes[0]) + xx] |= data; - } - } - } - - public boolean checkPathingTexture(final float positionX, final float positionY, final int rotationInput, - final BufferedImage pathingTextureTga, final EnumSet preventPathingTypes, - final EnumSet requirePathingTypes, final CWorldCollision cWorldCollision, - final CUnit unitToExcludeFromCollisionChecks) { - final int rotation = (rotationInput + 450) % 360; - final int divW = ((rotation % 180) != 0) ? pathingTextureTga.getHeight() : pathingTextureTga.getWidth(); - final int divH = ((rotation % 180) != 0) ? pathingTextureTga.getWidth() : pathingTextureTga.getHeight(); - short anyPathingTypesInRegion = 0; - short pathingTypesFillingRegion = (short) 0xFFFF; - for (int j = 0; j < pathingTextureTga.getHeight(); j++) { - for (int i = 0; i < pathingTextureTga.getWidth(); i++) { - int x = i; - int y = j; - - switch (rotation) { - case 90: - x = pathingTextureTga.getHeight() - 1 - j; - y = i; - break; - case 180: - x = pathingTextureTga.getWidth() - 1 - i; - y = pathingTextureTga.getHeight() - 1 - j; - break; - case 270: - x = j; - y = pathingTextureTga.getWidth() - 1 - i; - break; - } - // Width and height for centering change if rotation is not divisible by 180 - final int xx = (getCellX(positionX) + x) - (divW / 2); - final int yy = (getCellY(positionY) + y) - (divH / 2); - - if ((xx < 0) || (xx > (this.pathingGridSizes[0] - 1)) || (yy < 0) - || (yy > (this.pathingGridSizes[1] - 1))) { - continue; - } - - final short cellPathing = getCellPathing(xx, yy); - anyPathingTypesInRegion |= cellPathing; - pathingTypesFillingRegion &= cellPathing; - } - } - final float width = pathingTextureTga.getWidth() * 32f; - final float height = pathingTextureTga.getHeight() * 32f; - final float offsetX = ((pathingTextureTga.getWidth() % 2) == 1) ? 16f : 0f; - final float offsetY = ((pathingTextureTga.getHeight() % 2) == 1) ? 16f : 0f; - final Rectangle pathingMapRectangle = new Rectangle((positionX - (width / 2)) + offsetX, - (positionY - (height / 2)) + offsetY, width, height); - if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, - MovementType.AMPHIBIOUS)) { - System.out.println("intersects amph unit"); - anyPathingTypesInRegion |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE | PathingFlags.UNSWIMABLE; - } - if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, - MovementType.FLOAT)) { - System.out.println("intersects float unit"); - anyPathingTypesInRegion |= PathingFlags.UNSWIMABLE; - } - if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, - MovementType.FLY)) { - System.out.println("intersects fly unit"); - anyPathingTypesInRegion |= PathingFlags.UNFLYABLE; - } - if (cWorldCollision.intersectsAnythingOtherThan(pathingMapRectangle, unitToExcludeFromCollisionChecks, - MovementType.FOOT)) { - System.out.println("intersects foot unit"); - anyPathingTypesInRegion |= PathingFlags.UNBUILDABLE | PathingFlags.UNWALKABLE; - } - for (final CBuildingPathingType pathingType : preventPathingTypes) { - if (PathingFlags.isPathingFlag(anyPathingTypesInRegion, pathingType)) { - return false; - } - } - for (final CBuildingPathingType pathingType : requirePathingTypes) { - if (!PathingFlags.isPathingFlag(pathingTypesFillingRegion, pathingType)) { - return false; - } - } - return true; - } - - public RemovablePathingMapInstance blitRemovablePathingOverlayTexture(final float positionX, final float positionY, - final int rotationInput, final BufferedImage pathingTextureTga) { - final RemovablePathingMapInstance removablePathingMapInstance = new RemovablePathingMapInstance(positionX, - positionY, rotationInput, pathingTextureTga); - removablePathingMapInstance.blit(); - this.dynamicPathingInstances.add(removablePathingMapInstance); - return removablePathingMapInstance; - } - - public RemovablePathingMapInstance createRemovablePathingOverlayTexture(final float positionX, - final float positionY, final int rotationInput, final BufferedImage pathingTextureTga) { - return new RemovablePathingMapInstance(positionX, positionY, rotationInput, pathingTextureTga); - } - - public int getWidth() { - return this.pathingGridSizes[0]; - } - - public int getHeight() { - return this.pathingGridSizes[1]; - } - - public boolean contains(final float x, final float y) { - final int cellX = getCellX(x); - final int cellY = getCellY(y); - return (cellX >= 0) && (cellY >= 0) && (cellX < this.pathingGridSizes[0]) && (cellY < this.pathingGridSizes[1]); - } - - public short getPathing(final float x, final float y) { - return getCellPathing(getCellX(x), getCellY(y)); - } - - public int getCellX(final float x) { - final float userCellSpaceX = (x - this.centerOffset[0]) / 32.0f; - final int cellX = (int) userCellSpaceX; - return cellX; - } - - public int getCellY(final float y) { - final float userCellSpaceY = (y - this.centerOffset[1]) / 32.0f; - final int cellY = (int) userCellSpaceY; - return cellY; - } - - public float getWorldX(final int cellX) { - return (cellX * 32f) + this.centerOffset[0] + 16f; - } - - public float getWorldY(final int cellY) { - return (cellY * 32f) + this.centerOffset[1] + 16f; - } - - public float getWorldXFromCorner(final int cornerX) { - return (cornerX * 32f) + this.centerOffset[0]; - } - - public float getWorldYFromCorner(final int cornerY) { - return (cornerY * 32f) + this.centerOffset[1]; - } - - public int getCornerX(final float x) { - final float userCellSpaceX = ((x + 16f) - this.centerOffset[0]) / 32.0f; - final int cellX = (int) userCellSpaceX; - return cellX; - } - - public int getCornerY(final float y) { - final float userCellSpaceY = ((y + 16f) - this.centerOffset[1]) / 32.0f; - final int cellY = (int) userCellSpaceY; - return cellY; - } - - public short getCellPathing(final int cellX, final int cellY) { - final int index = (cellY * this.pathingGridSizes[0]) + cellX; - return (short) (this.pathingGrid[index] | this.dynamicPathingOverlay[index]); - } - - public boolean isPathable(final float x, final float y, final PathingType pathingType) { - return !PathingFlags.isPathingFlag(getPathing(x, y), pathingType.preventionFlag); - } - - public boolean isPathable(final float x, final float y, final MovementType pathingType) { - return pathingType.isPathable(getPathing(x, y)); - } - - public boolean isPathable(final float unitX, final float unitY, final MovementType pathingType, - final float collisionSize) { - if (collisionSize == 0f) { - return pathingType.isPathable(getPathing(unitX, unitY)); - } - for (int i = -1; i <= 1; i++) { - for (int j = -1; j <= 1; j++) { - final float unitPathingX = unitX + (i * collisionSize); - final float unitPathingY = unitY + (j * collisionSize); - if (!contains(unitPathingX, unitPathingY) - || !pathingType.isPathable(getPathing(unitPathingX, unitPathingY))) { - return false; - } - } - } -// final float maxX = unitX + collisionSize; -// final float maxY = unitY + collisionSize; -// for (float minX = unitX - collisionSize; minX < maxX; minX += 32f) { -// for (float minY = unitY - collisionSize; minY < maxY; minY += 32f) { -// if (!pathingType.isPathable(getPathing(minX, minY))) { -// return false; -// } -// } -// } - return true; - } - - public boolean isUnitCell(final float queryX, final float queryY, final float unitX, final float unitY, - final MovementType movementType, final float collisionSize) { - final float maxX = unitX + collisionSize; - final float maxY = unitY + collisionSize; - final int cellX = getCellX(queryX); - final int cellY = getCellY(queryY); - for (float minX = unitX - collisionSize; minX < maxX; minX += 32f) { - for (float minY = unitY - collisionSize; minY < maxY; minY += 32f) { - final int yy = getCellY(minY); - final int xx = getCellX(minX); - if ((yy == cellY) && (xx == cellX)) { - return true; - } - } - } - return false; - } - - public boolean isCellPathable(final int x, final int y, final MovementType pathingType, final float collisionSize) { - return isPathable(getWorldX(x), getWorldY(y), pathingType, collisionSize); - } - - public boolean isCellPathable(final int x, final int y, final MovementType pathingType) { - return pathingType.isPathable(getCellPathing(x, y)); - } - - public static boolean isPathingFlag(final short pathingValue, final PathingType pathingType) { - return !PathingFlags.isPathingFlag(pathingValue, pathingType.preventionFlag); - } - - // movetp referring to the unit data field of the same name - public static MovementType getMovementType(final String movetp) { - return movetpToMovementType.get(movetp); - } - - public static final class PathingFlags { - public static int UNWALKABLE = 0x2; - public static int UNFLYABLE = 0x4; - public static int UNBUILDABLE = 0x8; - public static int BLIGHTED = 0x20; - public static int UNSWIMABLE = 0x40; // PROBABLY, didn't confirm this flag value is accurate - public static int BOUDNARY = 0xF0; - - public static boolean isPathingFlag(final short pathingValue, final int flag) { - return (pathingValue & flag) != 0; - } - - public static boolean isPathingFlag(final short pathingValue, final CBuildingPathingType pathingType) { - switch (pathingType) { - case BLIGHTED: - return PathingFlags.isPathingFlag(pathingValue, PathingFlags.BLIGHTED); - case UNAMPH: - return PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNWALKABLE) - && PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNSWIMABLE); - case UNBUILDABLE: - return PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNBUILDABLE); - case UNFLOAT: - return PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNSWIMABLE); - case UNFLYABLE: - return PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNFLYABLE); - case UNWALKABLE: - return PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNWALKABLE); - default: - return false; - } - } - - private PathingFlags() { - } - } - - public static enum MovementType { - FOOT("foot") { - @Override - public boolean isPathable(final short pathingValue) { - return !PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNWALKABLE); - } - }, - FOOT_NO_COLLISION("") { - @Override - public boolean isPathable(final short pathingValue) { - return !PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNWALKABLE); - } - }, - HORSE("horse") { - @Override - public boolean isPathable(final short pathingValue) { - return !PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNWALKABLE); - } - }, - FLY("fly") { - @Override - public boolean isPathable(final short pathingValue) { - return !PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNFLYABLE); - } - }, - HOVER("hover") { - @Override - public boolean isPathable(final short pathingValue) { - return !PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNWALKABLE); - } - }, - FLOAT("float") { - @Override - public boolean isPathable(final short pathingValue) { - return !PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNSWIMABLE); - } - }, - AMPHIBIOUS("amph") { - @Override - public boolean isPathable(final short pathingValue) { - return !PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNWALKABLE) - || !PathingFlags.isPathingFlag(pathingValue, PathingFlags.UNSWIMABLE); - } - }, - DISABLED("") { - @Override - public boolean isPathable(final short pathingValue) { - return true; - } - }; - private final String typeKey; - - // TODO windwalk pathing type can walk through units but not through items - - private MovementType(final String typeKey) { - this.typeKey = typeKey; - } - - public abstract boolean isPathable(short pathingValue); - } - - public static enum PathingType { - WALKABLE(PathingFlags.UNWALKABLE), - FLYABLE(PathingFlags.UNFLYABLE), - BUILDABLE(PathingFlags.UNBUILDABLE), - SWIMMABLE(PathingFlags.UNSWIMABLE); - - private final int preventionFlag; - - private PathingType(final int preventionFlag) { - this.preventionFlag = preventionFlag; - } - } - - public final class RemovablePathingMapInstance { - private final float positionX; - private final float positionY; - private final int rotationInput; - private final BufferedImage pathingTextureTga; - - public RemovablePathingMapInstance(final float positionX, final float positionY, final int rotationInput, - final BufferedImage pathingTextureTga) { - this.positionX = positionX; - this.positionY = positionY; - this.rotationInput = rotationInput; - this.pathingTextureTga = pathingTextureTga; - } - - private void blit() { - blitPathingOverlayTexture(this.positionX, this.positionY, this.rotationInput, this.pathingTextureTga); - } - - public void remove() { - PathingGrid.this.dynamicPathingInstances.remove(this); - Arrays.fill(PathingGrid.this.dynamicPathingOverlay, (short) 0); - for (final RemovablePathingMapInstance instance : PathingGrid.this.dynamicPathingInstances) { - instance.blit(); - } - } - - public void add() { - PathingGrid.this.dynamicPathingInstances.add(this); - blit(); - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/RenderCorner.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/RenderCorner.java deleted file mode 100644 index 421385eb..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/RenderCorner.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.environment; - -import com.etheller.warsmash.parsers.w3x.w3e.Corner; - -public class RenderCorner extends Corner { - public boolean cliff; - public boolean romp; - public float rampAdjust; - public float depth; - public boolean hideCliff; - - public RenderCorner(final Corner corner) { - super(corner); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/Shapes.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/Shapes.java deleted file mode 100644 index 588a682b..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/Shapes.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.environment; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL30; -import com.etheller.warsmash.util.RenderMathUtils; - -public class Shapes { - public static Shapes INSTANCE = new Shapes(); - static { - INSTANCE.init(); - } - - public int vertexBuffer; - public int indexBuffer; - - float[][] quadVertices = { { 1, 1 }, { 0, 1 }, { 0, 0 }, { 1, 0 } }; - - int[][] quadIndices = { { 1, 3, 0 }, { 2, 3, 1 } }; - - public void init() { - this.vertexBuffer = Gdx.gl30.glGenBuffer(); - Gdx.gl30.glBindBuffer(GL30.GL_ARRAY_BUFFER, this.vertexBuffer); - Gdx.gl30.glBufferData(GL30.GL_ARRAY_BUFFER, this.quadVertices.length * 8, - RenderMathUtils.wrapPairs(this.quadVertices), GL30.GL_STATIC_DRAW); - - this.indexBuffer = Gdx.gl30.glGenBuffer(); - Gdx.gl30.glBindBuffer(GL30.GL_ELEMENT_ARRAY_BUFFER, this.indexBuffer); - Gdx.gl30.glBufferData(GL30.GL_ELEMENT_ARRAY_BUFFER, this.quadIndices.length * 3 * 4, - RenderMathUtils.wrap(this.quadIndices), GL30.GL_STATIC_DRAW); - - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/Terrain.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/Terrain.java deleted file mode 100644 index 359cc18f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/Terrain.java +++ /dev/null @@ -1,1567 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.environment; - -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.InputStream; -import java.nio.Buffer; -import java.nio.FloatBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.TreeSet; -import java.util.function.Consumer; - -import org.apache.commons.compress.utils.IOUtils; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.GL30; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; -import com.badlogic.gdx.math.Intersector; -import com.badlogic.gdx.math.Matrix4; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector3; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.parsers.w3x.w3e.Corner; -import com.etheller.warsmash.parsers.w3x.w3e.War3MapW3e; -import com.etheller.warsmash.parsers.w3x.w3i.War3MapW3i; -import com.etheller.warsmash.parsers.w3x.wpm.War3MapWpm; -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.units.Element; -import com.etheller.warsmash.util.ImageUtils; -import com.etheller.warsmash.util.ImageUtils.AnyExtensionImage; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.util.WorldEditStrings; -import com.etheller.warsmash.viewer5.Camera; -import com.etheller.warsmash.viewer5.PathSolver; -import com.etheller.warsmash.viewer5.RawOpenGLTextureResource; -import com.etheller.warsmash.viewer5.Texture; -import com.etheller.warsmash.viewer5.gl.DataTexture; -import com.etheller.warsmash.viewer5.gl.Extensions; -import com.etheller.warsmash.viewer5.gl.WebGL; -import com.etheller.warsmash.viewer5.handlers.w3x.DynamicShadowManager; -import com.etheller.warsmash.viewer5.handlers.w3x.SplatModel; -import com.etheller.warsmash.viewer5.handlers.w3x.SplatModel.SplatMover; -import com.etheller.warsmash.viewer5.handlers.w3x.Variations; -import com.etheller.warsmash.viewer5.handlers.w3x.W3xSceneLightManager; -import com.etheller.warsmash.viewer5.handlers.w3x.W3xShaders; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; - -public class Terrain { - public static final float CELL_SIZE = 128f; - private static final String[] colorTags = { "R", "G", "B", "A" }; - private static final float[] sizeHeap = new float[2]; - private static final Vector3 normalHeap1 = new Vector3(); - private static final Vector3 normalHeap2 = new Vector3(); - private static final float[] fourComponentHeap = new float[4]; - private static final Matrix4 tempMatrix = new Matrix4(); - private static final boolean WIREFRAME_TERRAIN = false; - // In WC3 they didn't finish developing the height 3 ramps - // There are a couple of models for some of them but generally they are just bad - // voodoo. Enabling this setting should be coupled with creating - // new artwork for advanced ramp use cases that don't exist in WC3. - private static final boolean DISALLOW_HEIGHT_3_RAMPS = true; - - public ShaderProgram groundShader; - public ShaderProgram waterShader; - public ShaderProgram cliffShader; - public float waterIndex; - public float waterIncreasePerFrame; - public float waterHeightOffset; - - // - public List groundTextures = new ArrayList<>(); - public List cliffTextures = new ArrayList<>(); - public RenderCorner[][] corners; - public int columns; - public int rows; - public int blightTextureIndex = -1; - public float[] maxDeepColor = new float[4]; - public float[] minDeepColor = new float[4]; - public float[] maxShallowColor = new float[4]; - public float[] minShallowColor = new float[4]; - - private final DataTable terrainTable; - private final DataTable cliffTable; - private final DataTable waterTable; - private final int waterTextureCount; - private int cliffTexturesSize; - private final List cliffMeshes = new ArrayList<>(); - private final Map pathToCliff = new HashMap<>(); - private final Map groundTextureToId = new HashMap<>(); - private final List cliffToGroundTexture = new ArrayList<>(); - private final List cliffs = new ArrayList<>(); - private final DataSource dataSource; - private final float[] groundHeights; - private final float[] groundCornerHeights; - private final short[] groundTextureList; - private final float[] waterHeights; - private final byte[] waterExistsData; - - private int groundTextureData = -1; - private final int groundHeight; - private final int groundCornerHeight; - private final int groundCornerHeightLinear; - private final int cliffTextureArray; - private final int waterHeight; - private final int waterExists; - private final int waterTextureArray; - private final Camera camera; - private final War3MapViewer viewer; - public float[] centerOffset; - private final WebGL webGL; - private final ShaderProgram uberSplatShader; - public final DataTable uberSplatTable; - - private final Map uberSplatModels; - private final List uberSplatModelsList; - private int shadowMap; - public final Map splats = new HashMap<>(); - public final Map> shadows = new HashMap<>(); - public final Map shadowTextures = new HashMap<>(); - private final int[] mapBounds; - private final float[] shaderMapBounds; - private final int[] mapSize; - public final SoftwareGroundMesh softwareGroundMesh; - private final int testArrayBuffer; - private final int testElementBuffer; - private boolean initShadowsFinished = false; - private byte[] staticShadowData; - private byte[] shadowData; - - public Terrain(final War3MapW3e w3eFile, final War3MapWpm terrainPathing, final War3MapW3i w3iFile, - final WebGL webGL, final DataSource dataSource, final WorldEditStrings worldEditStrings, - final War3MapViewer viewer, final DataTable worldEditData) throws IOException { - this.webGL = webGL; - this.viewer = viewer; - this.camera = viewer.worldScene.camera; - this.dataSource = dataSource; - final String texturesExt = ".blp"; - final Corner[][] corners = w3eFile.getCorners(); - this.corners = new RenderCorner[corners[0].length][corners.length]; - for (int i = 0; i < corners.length; i++) { - for (int j = 0; j < corners[i].length; j++) { - this.corners[j][i] = new RenderCorner(corners[i][j]); - } - } - final int width = w3eFile.getMapSize()[0]; - final int height = w3eFile.getMapSize()[1]; - this.columns = width; - this.rows = height; - for (int i = 0; i < (width - 1); i++) { - for (int j = 0; j < (height - 1); j++) { - final RenderCorner bottomLeft = this.corners[i][j]; - final RenderCorner bottomRight = this.corners[i + 1][j]; - final RenderCorner topLeft = this.corners[i][j + 1]; - final RenderCorner topRight = this.corners[i + 1][j + 1]; - - bottomLeft.cliff = (bottomLeft.getLayerHeight() != bottomRight.getLayerHeight()) - || (bottomLeft.getLayerHeight() != topLeft.getLayerHeight()) - || (bottomLeft.getLayerHeight() != topRight.getLayerHeight()); - } - } - - this.terrainTable = new DataTable(worldEditStrings); - try (InputStream terrainSlkStream = dataSource.getResourceAsStream("TerrainArt\\Terrain.slk")) { - this.terrainTable.readSLK(terrainSlkStream); - } - this.cliffTable = new DataTable(worldEditStrings); - try (InputStream cliffSlkStream = dataSource.getResourceAsStream("TerrainArt\\CliffTypes.slk")) { - this.cliffTable.readSLK(cliffSlkStream); - } - this.waterTable = new DataTable(worldEditStrings); - try (InputStream waterSlkStream = dataSource.getResourceAsStream("TerrainArt\\Water.slk")) { - this.waterTable.readSLK(waterSlkStream); - } - this.uberSplatTable = new DataTable(worldEditStrings); - try (InputStream uberSlkStream = dataSource.getResourceAsStream("Splats\\UberSplatData.slk")) { - this.uberSplatTable.readSLK(uberSlkStream); - } - - final char tileset = w3eFile.getTileset(); - final Element waterInfo = this.waterTable.get(tileset + "Sha"); - if (waterInfo != null) { - this.waterHeightOffset = waterInfo.getFieldFloatValue("height"); - this.waterTextureCount = waterInfo.getFieldValue("numTex"); - this.waterIncreasePerFrame = waterInfo.getFieldValue("texRate"); - } - else { - this.waterHeightOffset = 0; - this.waterTextureCount = 0; - this.waterIncreasePerFrame = 0; - } - - loadWaterColor(this.minShallowColor, "Smin", waterInfo); - loadWaterColor(this.maxShallowColor, "Smax", waterInfo); - loadWaterColor(this.minDeepColor, "Dmin", waterInfo); - loadWaterColor(this.maxDeepColor, "Dmax", waterInfo); - for (int i = 0; i < 3; i++) { - if (this.minDeepColor[i] > this.maxDeepColor[i]) { - this.maxDeepColor[i] = this.minDeepColor[i]; - } - } - - // Cliff Meshes - - Map cliffVars = Variations.CLIFF_VARS; - for (final Map.Entry cliffVar : cliffVars.entrySet()) { - final Integer maxVariations = cliffVar.getValue(); - for (int variation = 0; variation <= maxVariations; variation++) { - final String fileName = "Doodads\\Terrain\\Cliffs\\Cliffs" + cliffVar.getKey() + variation + ".mdx"; - this.cliffMeshes.add(new CliffMesh(fileName, dataSource, Gdx.gl30)); - this.pathToCliff.put("Cliffs" + cliffVar.getKey() + variation, this.cliffMeshes.size() - 1); - } - } - cliffVars = Variations.CITY_CLIFF_VARS; - for (final Map.Entry cliffVar : cliffVars.entrySet()) { - final Integer maxVariations = cliffVar.getValue(); - for (int variation = 0; variation <= maxVariations; variation++) { - final String fileName = "Doodads\\Terrain\\CityCliffs\\CityCliffs" + cliffVar.getKey() + variation - + ".mdx"; - this.cliffMeshes.add(new CliffMesh(fileName, dataSource, Gdx.gl30)); - this.pathToCliff.put("CityCliffs" + cliffVar.getKey() + variation, this.cliffMeshes.size() - 1); - } - } - - // Ground textures - for (final War3ID groundTile : w3eFile.getGroundTiles()) { - final Element terrainTileInfo = this.terrainTable.get(groundTile.asStringValue()); - if (terrainTileInfo == null) { - throw new RuntimeException("No terrain info for: " + groundTile.asStringValue()); - } - final String dir = terrainTileInfo.getField("dir"); - final String file = terrainTileInfo.getField("file"); - this.groundTextures.add(new GroundTexture(dir + "\\" + file + texturesExt, dataSource, Gdx.gl30)); - this.groundTextureToId.put(groundTile.asStringValue(), this.groundTextures.size() - 1); - } - - final Element tilesets = worldEditData.get("TileSets"); - - this.blightTextureIndex = this.groundTextures.size(); - this.groundTextures.add(new GroundTexture( - tilesets.getField(Character.toString(tileset)).split(",")[1] + texturesExt, dataSource, Gdx.gl30)); - - // Cliff Textures - for (final War3ID cliffTile : w3eFile.getCliffTiles()) { - final Element cliffInfo = this.cliffTable.get(cliffTile.asStringValue()); - if (cliffInfo == null) { - System.err.println("Missing cliff type: " + cliffTile.asStringValue()); - continue; - } - final String texDir = cliffInfo.getField("texDir"); - final String texFile = cliffInfo.getField("texFile"); - final AnyExtensionImage imageInfo = ImageUtils.getAnyExtensionImageFixRGB(dataSource, - texDir + "\\" + texFile + texturesExt, "cliff texture"); - final BufferedImage image = imageInfo.getRGBCorrectImageData(); - this.cliffTextures - .add(new UnloadedTexture(image.getWidth(), image.getHeight(), ImageUtils.getTextureBuffer(image), - cliffInfo.getField("cliffModelDir"), cliffInfo.getField("rampModelDir"))); - this.cliffTexturesSize = Math.max(this.cliffTexturesSize, - this.cliffTextures.get(this.cliffTextures.size() - 1).width); - this.cliffToGroundTexture.add(this.groundTextureToId.get(cliffInfo.getField("groundTile"))); - } - - updateCliffMeshes(new Rectangle(0, 0, width - 1, height - 1)); - - // prepare GPU data - this.groundHeights = new float[width * height]; - this.groundCornerHeights = new float[width * height]; - this.groundTextureList = new short[(width - 1) * (height - 1) * 4]; - this.waterHeights = new float[width * height]; - this.waterExistsData = new byte[width * height]; - - updateGroundTextures(new Rectangle(0, 0, width - 1, height - 1)); - for (int i = 0; i < width; i++) { - for (int j = 0; j < height; j++) { - this.groundCornerHeights[(j * width) + i] = this.corners[i][j].computeFinalGroundHeight(); - this.waterExistsData[(j * width) + i] = (byte) this.corners[i][j].getWater(); - this.groundHeights[(j * width) + i] = this.corners[i][j].getGroundHeight(); - this.waterHeights[(j * width) + i] = this.corners[i][j].getWaterHeight(); - } - } - - final GL30 gl = Gdx.gl30; - // Ground - this.groundTextureData = gl.glGenTexture(); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.groundTextureData); - gl.glTexImage2D(GL30.GL_TEXTURE_2D, 0, GL30.GL_RGBA16UI, width - 1, height - 1, 0, GL30.GL_RGBA_INTEGER, - GL30.GL_UNSIGNED_SHORT, RenderMathUtils.wrapShort(this.groundTextureList)); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MAG_FILTER, GL30.GL_NEAREST); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MIN_FILTER, GL30.GL_NEAREST); - - this.groundHeight = gl.glGenTexture(); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.groundHeight); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MAG_FILTER, GL30.GL_LINEAR); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MIN_FILTER, GL30.GL_LINEAR); - - gl.glTexImage2D(GL30.GL_TEXTURE_2D, 0, GL30.GL_R16F, width, height, 0, GL30.GL_RED, GL30.GL_FLOAT, - RenderMathUtils.wrap(this.groundHeights)); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_WRAP_S, GL30.GL_CLAMP_TO_EDGE); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_WRAP_T, GL30.GL_CLAMP_TO_EDGE); - - this.groundCornerHeight = gl.glGenTexture(); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.groundCornerHeight); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MAG_FILTER, GL30.GL_NEAREST); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MIN_FILTER, GL30.GL_NEAREST); - - gl.glTexImage2D(GL30.GL_TEXTURE_2D, 0, GL30.GL_R16F, width, height, 0, GL30.GL_RED, GL30.GL_FLOAT, - RenderMathUtils.wrap(this.groundCornerHeights)); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_WRAP_S, GL30.GL_CLAMP_TO_EDGE); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_WRAP_T, GL30.GL_CLAMP_TO_EDGE); - - this.groundCornerHeightLinear = gl.glGenTexture(); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.groundCornerHeightLinear); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MAG_FILTER, GL30.GL_LINEAR); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MIN_FILTER, GL30.GL_LINEAR); - - gl.glTexImage2D(GL30.GL_TEXTURE_2D, 0, GL30.GL_R16F, width, height, 0, GL30.GL_RED, GL30.GL_FLOAT, - RenderMathUtils.wrap(this.groundCornerHeights)); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_WRAP_S, GL30.GL_CLAMP_TO_EDGE); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_WRAP_T, GL30.GL_CLAMP_TO_EDGE); - - // Cliff - this.cliffTextureArray = gl.glGenTexture(); - gl.glBindTexture(GL30.GL_TEXTURE_2D_ARRAY, this.cliffTextureArray); - gl.glTexImage3D(GL30.GL_TEXTURE_2D_ARRAY, 0, GL30.GL_RGBA8, this.cliffTexturesSize, this.cliffTexturesSize, - this.cliffTextures.size(), 0, GL30.GL_RGBA, GL30.GL_UNSIGNED_BYTE, null); - gl.glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL30.GL_TEXTURE_MIN_FILTER, GL30.GL_LINEAR_MIPMAP_LINEAR); - gl.glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL30.GL_TEXTURE_BASE_LEVEL, 0); - - int sub = 0; - for (final UnloadedTexture i : this.cliffTextures) { - gl.glTexSubImage3D(GL30.GL_TEXTURE_2D_ARRAY, 0, 0, 0, sub, i.width, i.height, 1, GL30.GL_RGBA, - GL30.GL_UNSIGNED_BYTE, i.data); - sub += 1; - } - gl.glGenerateMipmap(GL30.GL_TEXTURE_2D_ARRAY); - - // Water - this.waterHeight = gl.glGenTexture(); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.waterHeight); - gl.glTexImage2D(GL30.GL_TEXTURE_2D, 0, GL30.GL_R16F, width, height, 0, GL30.GL_RED, GL30.GL_FLOAT, - RenderMathUtils.wrap(this.waterHeights)); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MAG_FILTER, GL30.GL_NEAREST); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MIN_FILTER, GL30.GL_NEAREST); - - this.waterExists = gl.glGenTexture(); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.waterExists); - gl.glPixelStorei(GL30.GL_UNPACK_ALIGNMENT, 1); - gl.glTexImage2D(GL30.GL_TEXTURE_2D, 0, GL30.GL_R8, width, height, 0, GL30.GL_RED, GL30.GL_UNSIGNED_BYTE, - RenderMathUtils.wrap(this.waterExistsData)); - gl.glPixelStorei(GL30.GL_UNPACK_ALIGNMENT, 4); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MAG_FILTER, GL30.GL_NEAREST); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MIN_FILTER, GL30.GL_NEAREST); - - // Water textures - this.waterTextureArray = gl.glGenTexture(); - gl.glBindTexture(GL30.GL_TEXTURE_2D_ARRAY, this.waterTextureArray); - - final String fileName = waterInfo.getField("texFile"); - final List waterTextures = new ArrayList<>(); - boolean anyWaterTextureNeedsSRGB = false; - int waterImageDimension = 128; - for (int i = 0; i < this.waterTextureCount; i++) { - final AnyExtensionImage imageInfo = ImageUtils.getAnyExtensionImageFixRGB(dataSource, - fileName + (i < 10 ? "0" : "") + Integer.toString(i) + texturesExt, "water texture"); - final BufferedImage image = imageInfo.getImageData(); - if ((image.getWidth() != 128) || (image.getHeight() != 128)) { - System.err - .println("Odd water texture size detected of " + image.getWidth() + " x " + image.getHeight()); - waterImageDimension = image.getWidth(); - } - anyWaterTextureNeedsSRGB |= imageInfo.isNeedsSRGBFix(); - waterTextures.add(image); - } - - gl.glTexImage3D(GL30.GL_TEXTURE_2D_ARRAY, 0, anyWaterTextureNeedsSRGB ? GL30.GL_SRGB8_ALPHA8 : GL30.GL_RGBA8, - waterImageDimension, waterImageDimension, this.waterTextureCount, 0, GL30.GL_RGBA, - GL30.GL_UNSIGNED_BYTE, null); - gl.glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL30.GL_TEXTURE_WRAP_S, GL30.GL_CLAMP_TO_EDGE); - gl.glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL30.GL_TEXTURE_WRAP_T, GL30.GL_CLAMP_TO_EDGE); - gl.glTexParameteri(GL30.GL_TEXTURE_2D_ARRAY, GL30.GL_TEXTURE_BASE_LEVEL, 0); - - for (int i = 0; i < waterTextures.size(); i++) { - final BufferedImage image = waterTextures.get(i); - gl.glTexSubImage3D(GL30.GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, image.getWidth(), image.getHeight(), 1, - GL30.GL_RGBA, GL30.GL_UNSIGNED_BYTE, ImageUtils.getTextureBuffer(image)); - } - gl.glGenerateMipmap(GL30.GL_TEXTURE_2D_ARRAY); - - updateGroundHeights(new Rectangle(0, 0, width - 1, height - 1)); - - this.groundShader = webGL.createShaderProgram(TerrainShaders.Terrain.vert(), TerrainShaders.Terrain.frag); - this.cliffShader = webGL.createShaderProgram(TerrainShaders.Cliffs.vert(), TerrainShaders.Cliffs.frag); - this.waterShader = webGL.createShaderProgram(TerrainShaders.Water.vert(), TerrainShaders.Water.frag); - - this.uberSplatShader = webGL.createShaderProgram(W3xShaders.UberSplat.vert(), W3xShaders.UberSplat.frag); - - // TODO collision bodies (?) - - this.centerOffset = w3eFile.getCenterOffset(); - this.uberSplatModels = new LinkedHashMap<>(); - this.uberSplatModelsList = new ArrayList<>(); - this.mapBounds = w3iFile.getCameraBoundsComplements(); - this.shaderMapBounds = new float[] { (this.mapBounds[0] * 128.0f) + this.centerOffset[0], - (this.mapBounds[2] * 128.0f) + this.centerOffset[1], - ((this.columns - this.mapBounds[1] - 1) * 128.0f) + this.centerOffset[0], - ((this.rows - this.mapBounds[3] - 1) * 128.0f) + this.centerOffset[1] }; - this.shaderMapBoundsRectangle = new Rectangle(this.shaderMapBounds[0], this.shaderMapBounds[1], - this.shaderMapBounds[2] - this.shaderMapBounds[0], this.shaderMapBounds[3] - this.shaderMapBounds[1]); - this.mapSize = w3eFile.getMapSize(); - this.entireMapRectangle = new Rectangle(this.centerOffset[0], this.centerOffset[1], - (this.mapSize[0] * 128f) - 128, (this.mapSize[1] * 128f) - 128); - this.softwareGroundMesh = new SoftwareGroundMesh(this.groundHeights, this.groundCornerHeights, - this.centerOffset, width, height); - - this.testArrayBuffer = gl.glGenBuffer(); - gl.glBindBuffer(GL30.GL_ARRAY_BUFFER, this.testArrayBuffer); - gl.glBufferData(GL30.GL_ARRAY_BUFFER, this.softwareGroundMesh.vertices.length, - RenderMathUtils.wrap(this.softwareGroundMesh.vertices), GL30.GL_STATIC_DRAW); - - this.testElementBuffer = gl.glGenBuffer(); -// gl.glBindBuffer(GL30.GL_ELEMENT_ARRAY_BUFFER, this.testElementBuffer); -// gl.glBufferData(GL30.GL_ELEMENT_ARRAY_BUFFER, this.softwareGroundMesh.indices.length, -// RenderMathUtils.wrap(this.softwareGroundMesh.indices), GL30.GL_STATIC_DRAW); - - this.waveBuilder = new WaveBuilder(this.mapSize, this.waterTable, viewer, this.corners, this.centerOffset, - this.waterHeightOffset, w3eFile, w3iFile); - this.pathingGrid = new PathingGrid(terrainPathing, this.centerOffset); - } - - public void createWaves() { - this.waveBuilder.createWaves(this); - } - - private void updateGroundHeights(final Rectangle area) { - for (int j = (int) area.y; j < (area.y + area.height); j++) { - for (int i = (int) area.x; i < (area.x + area.width); i++) { - this.groundHeights[(j * this.columns) + i] = this.corners[i][j].getGroundHeight(); - - float rampHeight = 0f; - // Check if in one of the configurations the bottom_left is a ramp - XLoop: for (int xOffset = -1; xOffset <= 0; xOffset++) { - for (int yOffset = -1; yOffset <= 0; yOffset++) { - if (((i + xOffset) >= 0) && ((i + xOffset) < (this.columns - 1)) && ((j + yOffset) >= 0) - && ((j + yOffset) < (this.rows - 1))) { - final RenderCorner bottomLeft = this.corners[i + xOffset][j + yOffset]; - final RenderCorner bottomRight = this.corners[i + 1 + xOffset][j + yOffset]; - final RenderCorner topLeft = this.corners[i + xOffset][j + 1 + yOffset]; - final RenderCorner topRight = this.corners[i + 1 + xOffset][j + 1 + yOffset]; - - final int base = Math.min( - Math.min(bottomLeft.getLayerHeight(), bottomRight.getLayerHeight()), - Math.min(topLeft.getLayerHeight(), topRight.getLayerHeight())); - if (this.corners[i][j].getLayerHeight() != base) { - continue; - } - - if (isCornerRampEntrance(i + xOffset, j + yOffset)) { - rampHeight = 0.5f; - break XLoop; - } - } - } - } - - final RenderCorner corner = this.corners[i][j]; - final float newGroundCornerHeight = corner.computeFinalGroundHeight() + rampHeight; - this.groundCornerHeights[(j * this.columns) + i] = newGroundCornerHeight; - corner.depth = (corner.getWater() != 0) - ? (this.waterHeightOffset + corner.getWaterHeight()) - newGroundCornerHeight - : 0; - } - } - updateGroundHeights(); - updateCornerHeights(); - } - - private void updateGroundHeights() { - Gdx.gl30.glBindTexture(GL30.GL_TEXTURE_2D, this.groundHeight); - Gdx.gl30.glTexSubImage2D(GL30.GL_TEXTURE_2D, 0, 0, 0, this.columns, this.rows, GL30.GL_RED, GL30.GL_FLOAT, - RenderMathUtils.wrap(this.groundHeights)); - } - - private void updateCornerHeights() { - final FloatBuffer groundCornerHeightsWrapped = RenderMathUtils.wrap(this.groundCornerHeights); - Gdx.gl30.glBindTexture(GL30.GL_TEXTURE_2D, this.groundCornerHeight); - Gdx.gl30.glTexSubImage2D(GL30.GL_TEXTURE_2D, 0, 0, 0, this.columns, this.rows, GL30.GL_RED, GL30.GL_FLOAT, - groundCornerHeightsWrapped); - Gdx.gl30.glBindTexture(GL30.GL_TEXTURE_2D, this.groundCornerHeightLinear); - Gdx.gl30.glTexSubImage2D(GL30.GL_TEXTURE_2D, 0, 0, 0, this.columns, this.rows, GL30.GL_RED, GL30.GL_FLOAT, - groundCornerHeightsWrapped); - } - - /** - * calculateRamps() is copied from Riv whereas a lot of the rest of the terrain - * was copied from HiveWE - */ - private void calculateRamps() { - final int columns = this.mapSize[0]; - final int rows = this.mapSize[1]; - - final String[] ramps = { "AAHL", "AALH", "ABHL", "AHLA", "ALHA", "ALHB", "BALH", "BHLA", "HAAL", "HBAL", "HLAA", - "HLAB", "LAAH", "LABH", "LHAA", "LHBA" }; - - // Adjust terrain height inside ramps (set rampAdjust) - for (int y = 1; y < (rows - 1); ++y) { - for (int x = 1; x < (columns - 1); ++x) { - final RenderCorner o = this.corners[x][y]; - if (!o.isRamp()) { - continue; - } - final RenderCorner a = this.corners[x - 1][y - 1]; - final RenderCorner b = this.corners[x - 1][y]; - final RenderCorner c = this.corners[x - 1][y + 1]; - final RenderCorner d = this.corners[x][y + 1]; - final RenderCorner e = this.corners[x + 1][y + 1]; - final RenderCorner f = this.corners[x + 1][y]; - final RenderCorner g = this.corners[x + 1][y - 1]; - final RenderCorner h = this.corners[x][y - 1]; - final int base = o.getLayerHeight(); - if ((b.isRamp() && f.isRamp()) || (d.isRamp() && h.isRamp())) { - float adjust = 0; - if (b.isRamp() && f.isRamp()) { - adjust = Math.max(adjust, ((b.getLayerHeight() + f.getLayerHeight()) / 2) - base); - } - if (d.isRamp() && h.isRamp()) { - adjust = Math.max(adjust, ((d.getLayerHeight() + h.getLayerHeight()) / 2) - base); - } - if (a.isRamp() && e.isRamp()) { - adjust = Math.max(adjust, (((a.getLayerHeight() + e.getLayerHeight()) / 2) - base) / 2); - } - if (c.isRamp() && g.isRamp()) { - adjust = Math.max(adjust, (((c.getLayerHeight() + g.getLayerHeight()) / 2) - base) / 2); - } - o.rampAdjust = adjust; - } - } - } - } - - /// TODO clean - /// Function is a bit of a mess - /// Updates the cliff and ramp meshes for an area - private void updateCliffMeshes(final Rectangle area) throws IOException { - // Remove all existing cliff meshes in area - for (int i = this.cliffs.size(); i-- > 0;) { - final IVec3 pos = this.cliffs.get(i); - if (area.contains(pos.x, pos.y)) { - this.cliffs.remove(i); - } - } - - for (int i = (int) area.getX(); i < (int) (area.getX() + area.getWidth()); i++) { - for (int j = (int) area.getY(); j < (int) (area.getY() + area.getHeight()); j++) { - this.corners[i][j].romp = false; - } - } - - final Rectangle adjusted = new Rectangle(area.x - 2, area.y - 2, area.width + 4, area.height + 4); - final Rectangle rampArea = new Rectangle(); - Intersector.intersectRectangles(new Rectangle(0, 0, this.columns, this.rows), adjusted, rampArea); - - // Add new cliff meshes - final int xLimit = (int) ((rampArea.getX() + rampArea.getWidth()) - 1); - for (int i = (int) rampArea.getX(); i < xLimit; i++) { - final int yLimit = (int) ((rampArea.getY() + rampArea.getHeight()) - 1); - for (int j = (int) rampArea.getY(); j < yLimit; j++) { - final RenderCorner bottomLeft = this.corners[i][j]; - final RenderCorner bottomRight = this.corners[i + 1][j]; - final RenderCorner topLeft = this.corners[i][j + 1]; - final RenderCorner topRight = this.corners[i + 1][j + 1]; - - if (bottomLeft.cliff && !bottomLeft.hideCliff) { - final int base = Math.min(Math.min(bottomLeft.getLayerHeight(), bottomRight.getLayerHeight()), - Math.min(topLeft.getLayerHeight(), topRight.getLayerHeight())); - - final boolean facingDown = (topLeft.getLayerHeight() >= bottomLeft.getLayerHeight()) - && (topRight.getLayerHeight() >= bottomRight.getLayerHeight()); - final boolean facingLeft = (bottomRight.getLayerHeight() >= bottomLeft.getLayerHeight()) - && (topRight.getLayerHeight() >= topLeft.getLayerHeight()); - - int bottomLeftCliffTex = bottomLeft.getCliffTexture(); - if (bottomLeftCliffTex == 15) { - bottomLeftCliffTex -= 14; - } - if (!(facingDown && (j == 0)) && !(!facingDown && (j >= (this.rows - 2))) - && !(facingLeft && (i == 0)) && !(!facingLeft && (i >= (this.columns - 2)))) { - final boolean verticalRamp = ((bottomLeft.isRamp()) != (bottomRight.isRamp())) - && ((topLeft.isRamp()) != (topRight.isRamp())); - - final boolean horizontalRamp = ((bottomLeft.isRamp()) != (topLeft.isRamp())) - && ((bottomRight.isRamp()) != (topRight.isRamp())); - - if (verticalRamp || horizontalRamp) { - final boolean rampBlockedByCliff = ((verticalRamp - && this.corners[i][j + (facingDown ? -1 : 1)].cliff) - || (horizontalRamp && this.corners[i + (facingLeft ? -1 : 1)][j].cliff)); - final int topLeftHeight = topLeft.getLayerHeight() - base; - final int topRightHeight = topRight.getLayerHeight() - base; - final int bottomRightHeight = bottomRight.getLayerHeight() - base; - final int bottomLeftHeight = bottomLeft.getLayerHeight() - base; - boolean invalidRamp = false; - if (DISALLOW_HEIGHT_3_RAMPS) { - if (rampBlockedByCliff) { - invalidRamp = true; - } - else if (topLeftHeight > 1) { - invalidRamp = true; - topLeft.setRamp(0); - } - else if (topRightHeight > 1) { - invalidRamp = true; - topRight.setRamp(0); - } - else if (bottomRightHeight > 1) { - invalidRamp = true; - bottomRight.setRamp(0); - } - else if (bottomLeftHeight > 1) { - invalidRamp = true; - bottomLeft.setRamp(0); - } - } - if (!invalidRamp) { - String fileName = "" + getRampLetter(topLeftHeight, topLeft.isRamp()) - + getRampLetter(topRightHeight, topRight.isRamp()) - + getRampLetter(bottomRightHeight, bottomRight.isRamp()) - + getRampLetter(bottomLeftHeight, bottomLeft.isRamp()); - - final String rampModelDir = this.cliffTextures.get(bottomLeftCliffTex).rampModelDir; - fileName = "Doodads\\Terrain\\" + rampModelDir + "\\" + rampModelDir + fileName - + "0.mdx"; - - if (this.dataSource.has(fileName)) { - if (!this.pathToCliff.containsKey(fileName)) { - this.cliffMeshes.add(new CliffMesh(fileName, this.dataSource, Gdx.gl30)); - this.pathToCliff.put(fileName, this.cliffMeshes.size() - 1); - } - - for (int ji = this.cliffs.size(); ji-- > 0;) { - final IVec3 pos = this.cliffs.get(ji); - if ((pos.x == (i + ((horizontalRamp ? 1 : 0) * (facingLeft ? -1 : 0)))) - && (pos.y == (j - ((verticalRamp ? 1 : 0) * (facingDown ? 1 : 0))))) { - this.cliffs.remove(ji); - break; - } - } - - this.cliffs.add(new IVec3((i + ((horizontalRamp ? 1 : 0) * (facingLeft ? -1 : 0))), - (j - ((verticalRamp ? 1 : 0) * (facingDown ? 1 : 0))), - this.pathToCliff.get(fileName))); - bottomLeft.romp = true; - bottomLeft.setCliffTexture(bottomLeftCliffTex); - bottomRight.setCliffTexture(bottomLeftCliffTex); - topLeft.setCliffTexture(bottomLeftCliffTex); - topRight.setCliffTexture(bottomLeftCliffTex); - this.corners[i + ((facingLeft ? -1 : 1) * (horizontalRamp ? 1 : 0))][j - + ((facingDown ? -1 : 1) * (verticalRamp ? 1 : 0))] - .setCliffTexture(bottomLeftCliffTex); - - this.corners[i + ((facingLeft ? -1 : 1) * (horizontalRamp ? 1 : 0))][j - + ((facingDown ? -1 : 1) * (verticalRamp ? 1 : 0))].romp = true; - - continue; - } - } - } - } - - if (isCornerRampEntrance(i, j)) { - continue; - } - - // Ramps move 1 right/down in some cases and thus their area is one bigger to - // the top and left. - if (!area.contains(i, j)) { - continue; - } - - // Cliff model path - - String fileName = "" + (char) (('A' + topLeft.getLayerHeight()) - base) - + (char) (('A' + topRight.getLayerHeight()) - base) - + (char) (('A' + bottomRight.getLayerHeight()) - base) - + (char) (('A' + bottomLeft.getLayerHeight()) - base); - - if ("AAAA".equals(fileName)) { - continue; - } - - // Clamp to within max variations - - fileName = this.cliffTextures.get(bottomLeftCliffTex).cliffModelDir + fileName - + Variations.getCliffVariation(this.cliffTextures.get(bottomLeftCliffTex).cliffModelDir, - fileName, bottomLeft.getCliffVariation()); - if (!this.pathToCliff.containsKey(fileName)) { - throw new IllegalArgumentException("No such pathToCliff entry: " + fileName); - } - this.cliffs.add(new IVec3(i, j, this.pathToCliff.get(fileName))); - } - } - } - for (int i = (int) rampArea.getX(); i < xLimit; i++) { - final int yLimit = (int) ((rampArea.getY() + rampArea.getHeight()) - 1); - for (int j = (int) rampArea.getY(); j < yLimit; j++) { - final RenderCorner bottomLeft = this.corners[i][j]; - if (bottomLeft.isRamp() && !bottomLeft.romp) { - bottomLeft.hideCliff = true; - } - } - } - - } - - public void logRomp(final int x, final int y) { - System.out.println("romp: " + this.corners[x][y].romp); - System.out.println("ramp: " + this.corners[x][y].isRamp()); - System.out.println("cliff: " + this.corners[x][y].cliff); - } - - private void updateGroundTextures(final Rectangle area) { - final Rectangle adjusted = new Rectangle(area.x - 1, area.y - 1, area.width + 2, area.height + 2); - final Rectangle updateArea = new Rectangle(); - Intersector.intersectRectangles(new Rectangle(0, 0, this.columns - 1, this.rows - 1), adjusted, updateArea); - - for (int j = (int) (updateArea.getY()); j <= (int) ((updateArea.getY() + updateArea.getHeight()) - 1); j++) { - for (int i = (int) (updateArea.getX()); i <= (int) ((updateArea.getX() + updateArea.getWidth()) - 1); i++) { - getTextureVariations(i, j, this.groundTextureList, ((j * (this.columns - 1)) + i) * 4); - - if (this.corners[i][j].cliff || this.corners[i][j].romp) { - if (isCornerRampEntrance(i, j)) { - continue; - } - this.groundTextureList[(((j * (this.columns - 1)) + i) * 4) + 3] |= 0b1000000000000000; - } - } - } - - uploadGroundTexture(); - } - - public void removeTerrainCell(final int i, final int j) { - this.groundTextureList[(((j * (this.columns - 1)) + i) * 4) + 3] |= 0b1000000000000000; - this.corners[i][j].hideCliff = true; - uploadGroundTexture(); - try { - updateCliffMeshes(new Rectangle(i - 1, j - 1, 1, 1)); // TODO does this work? - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - public void removeTerrainCellWithoutFlush(final int i, final int j) { - this.groundTextureList[(((j * (this.columns - 1)) + i) * 4) + 3] |= 0b1000000000000000; - this.corners[i][j].hideCliff = true; - } - - public void flushRemovedTerrainCells() { - uploadGroundTexture(); - try { - updateCliffMeshes(new Rectangle(0, 0, this.columns - 1, this.rows - 1)); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - private void uploadGroundTexture() { - if (this.groundTextureData != -1) { - Gdx.gl30.glBindTexture(GL30.GL_TEXTURE_2D, this.groundTextureData); - Gdx.gl30.glTexSubImage2D(GL30.GL_TEXTURE_2D, 0, 0, 0, this.columns - 1, this.rows - 1, GL30.GL_RGBA_INTEGER, - GL30.GL_UNSIGNED_SHORT, RenderMathUtils.wrapShort(this.groundTextureList)); - } - } - - /// The 4 ground textures of the tilepoint. First 5 bits are which texture array - /// to use and the next 5 bits are which subtexture to use - private void getTextureVariations(final int x, final int y, final short[] out, final int outStartOffset) { - final int bottomLeft = realTileTexture(x, y); - final int bottomRight = realTileTexture(x + 1, y); - final int topLeft = realTileTexture(x, y + 1); - final int topRight = realTileTexture(x + 1, y + 1); - - final TreeSet set = new TreeSet<>(); - set.add(bottomLeft); - set.add(bottomRight); - set.add(topLeft); - set.add(topRight); - Arrays.fill(out, outStartOffset, outStartOffset + 4, (short) 17); - int component = outStartOffset + 1; - - final Iterator iterator = set.iterator(); - iterator.hasNext(); - final short firstValue = iterator.next().shortValue(); - out[outStartOffset] = (short) (firstValue - + (getVariation(firstValue, this.corners[x][y].getGroundVariation()) << 5)); - - int index; - while (iterator.hasNext()) { - index = 0; - final int texture = iterator.next().intValue(); - index |= (bottomRight == texture ? 1 : 0) << 0; - index |= (bottomLeft == texture ? 1 : 0) << 1; - index |= (topRight == texture ? 1 : 0) << 2; - index |= (topLeft == texture ? 1 : 0) << 3; - - out[component++] = (short) (texture + (index << 5)); - } - } - - private int realTileTexture(final int x, final int y) { - ILoop: for (int i = -1; i < 1; i++) { - for (int j = -1; j < 1; j++) { - if (((x + i) >= 0) && ((x + i) < this.columns) && ((y + j) >= 0) && ((y + j) < this.rows)) { - if (this.corners[x + i][y + j].cliff) { - if (((x + i) < (this.columns - 1)) && ((y + j) < (this.rows - 1))) { - final RenderCorner bottomLeft = this.corners[x + i][y + j]; - final RenderCorner bottomRight = this.corners[x + i + 1][y + j]; - final RenderCorner topLeft = this.corners[x + i][y + j + 1]; - final RenderCorner topRight = this.corners[x + i + 1][y + j + 1]; - - if ((bottomLeft.isRamp()) && (topLeft.isRamp()) && (bottomRight.isRamp()) - && (topRight.isRamp()) && (!bottomLeft.romp) && (!bottomRight.romp) - && (!topLeft.romp) && (!topRight.romp)) { - break ILoop; - } - } - } - if (this.corners[x + i][y + j].romp || this.corners[x + i][y + j].cliff) { - int texture = this.corners[x + i][y + j].getCliffTexture(); - // Number 15 seems to be something - if (texture == 15) { - texture -= 14; - } - - return this.cliffToGroundTexture.get(texture); - } - } - } - } - - if (this.corners[x][y].getBlight() != 0) { - return this.blightTextureIndex; - } - - return this.corners[x][y].getGroundTexture(); - } - - private boolean isCornerRampEntrance(final int x, final int y) { - if ((x == this.columns) || (y == this.rows)) { - return false; - } - - final RenderCorner bottomLeft = this.corners[x][y]; - final RenderCorner bottomRight = this.corners[x + 1][y]; - final RenderCorner topLeft = this.corners[x][y + 1]; - final RenderCorner topRight = this.corners[x + 1][y + 1]; - - return (bottomLeft.isRamp()) && (topLeft.isRamp()) && (bottomRight.isRamp()) && (topRight.isRamp()) - && !((bottomLeft.getLayerHeight() == topRight.getLayerHeight()) - && (topLeft.getLayerHeight() == bottomRight.getLayerHeight())); - } - - private static void loadWaterColor(final float[] out, final String prefix, final Element waterInfo) { - for (int i = 0; i < colorTags.length; i++) { - final String colorTag = colorTags[i]; - out[i] = waterInfo == null ? 0.0f : waterInfo.getFieldFloatValue(prefix + "_" + colorTag) / 255f; - } - } - - public short getVariation(final int groundTexture, final int variation) { - final GroundTexture texture = this.groundTextures.get(groundTexture); - - // Extended ? - if (texture.extended) { - if (variation <= 15) { - return (short) (16 + variation); - } - else if (variation == 16) { - return 15; - } - else { - return 0; - } - } - else { - if (variation == 0) { - return 0; - } - else { - return 15; - } - } - } - - public void update(final float deltaTime) { - this.waterIndex += this.waterIncreasePerFrame * deltaTime; - - if (this.waterIndex >= this.waterTextureCount) { - this.waterIndex = 0; - } - } - - public void renderGround(final DynamicShadowManager dynamicShadowManager) { - // Render tiles - - this.webGL.useShaderProgram(this.groundShader); - - final GL30 gl = Gdx.gl30; - gl.glEnable(GL20.GL_CULL_FACE); - gl.glDisable(GL30.GL_BLEND); - gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); - gl.glEnable(GL20.GL_DEPTH_TEST); - gl.glDepthMask(true); - - gl.glUniformMatrix4fv(this.groundShader.getUniformLocation("MVP"), 1, false, - this.camera.viewProjectionMatrix.val, 0); - gl.glUniform1i(this.groundShader.getUniformLocation("show_pathing_map"), this.viewer.renderPathing); - gl.glUniform1i(this.groundShader.getUniformLocation("show_lighting"), this.viewer.renderLighting); - gl.glUniform1i(this.groundShader.getUniformLocation("height_texture"), 0); - gl.glUniform1i(this.groundShader.getUniformLocation("height_cliff_texture"), 1); - gl.glUniform1i(this.groundShader.getUniformLocation("terrain_texture_list"), 2); - gl.glUniform1i(this.groundShader.getUniformLocation("shadowMap"), 20); - gl.glUniform1f(this.groundShader.getUniformLocation("centerOffsetX"), this.centerOffset[0]); - gl.glUniform1f(this.groundShader.getUniformLocation("centerOffsetY"), this.centerOffset[1]); - - final W3xSceneLightManager lightManager = (W3xSceneLightManager) this.viewer.worldScene.getLightManager(); - final DataTexture unitLightsTexture = lightManager.getTerrainLightsTexture(); - - unitLightsTexture.bind(21); - gl.glUniform1i(this.groundShader.getUniformLocation("lightTexture"), 21); - gl.glUniform1f(this.groundShader.getUniformLocation("lightCount"), lightManager.getTerrainLightCount()); - gl.glUniform1f(this.groundShader.getUniformLocation("lightTextureHeight"), unitLightsTexture.getHeight()); - - gl.glUniformMatrix4fv(this.groundShader.getUniformLocation("DepthBiasMVP"), 1, false, - dynamicShadowManager.getDepthBiasMVP().val, 0); - - gl.glUniform1i(this.groundShader.getUniformLocation("cliff_textures"), 0); - gl.glActiveTexture(GL30.GL_TEXTURE0); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.groundHeight); - - gl.glActiveTexture(GL30.GL_TEXTURE1); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.groundCornerHeight); - - gl.glUniform1i(this.groundShader.getUniformLocation("pathing_map_static"), 2); - gl.glActiveTexture(GL30.GL_TEXTURE2); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.groundTextureData); - - gl.glUniform1i(this.groundShader.getUniformLocation("sample0"), 3); - gl.glUniform1i(this.groundShader.getUniformLocation("sample1"), 4); - gl.glUniform1i(this.groundShader.getUniformLocation("sample2"), 5); - gl.glUniform1i(this.groundShader.getUniformLocation("sample3"), 6); - gl.glUniform1i(this.groundShader.getUniformLocation("sample4"), 7); - gl.glUniform1i(this.groundShader.getUniformLocation("sample5"), 8); - gl.glUniform1i(this.groundShader.getUniformLocation("sample6"), 9); - gl.glUniform1i(this.groundShader.getUniformLocation("sample7"), 10); - gl.glUniform1i(this.groundShader.getUniformLocation("sample8"), 11); - gl.glUniform1i(this.groundShader.getUniformLocation("sample9"), 12); - gl.glUniform1i(this.groundShader.getUniformLocation("sample10"), 13); - gl.glUniform1i(this.groundShader.getUniformLocation("sample11"), 14); - gl.glUniform1i(this.groundShader.getUniformLocation("sample12"), 15); - gl.glUniform1i(this.groundShader.getUniformLocation("sample13"), 16); - gl.glUniform1i(this.groundShader.getUniformLocation("sample14"), 17); - gl.glUniform1i(this.groundShader.getUniformLocation("sample15"), 18); - gl.glUniform1i(this.groundShader.getUniformLocation("sample16"), 19); - gl.glUniform1i(this.groundShader.getUniformLocation("shadowMap"), 20); - for (int i = 0; i < this.groundTextures.size(); i++) { - gl.glActiveTexture(GL30.GL_TEXTURE3 + i); - gl.glBindTexture(GL30.GL_TEXTURE_2D_ARRAY, this.groundTextures.get(i).id); - } - -// gl.glActiveTexture(GL30.GL_TEXTURE20, /*pathingMap.getTextureStatic()*/); -// gl.glActiveTexture(GL30.GL_TEXTURE21, /*pathingMap.getTextureDynamic()*/); - - gl.glActiveTexture(GL30.GL_TEXTURE20); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.shadowMap); - -// gl.glEnableVertexAttribArray(0); - gl.glBindBuffer(GL30.GL_ARRAY_BUFFER, Shapes.INSTANCE.vertexBuffer); - gl.glVertexAttribPointer(this.groundShader.getAttributeLocation("vPosition"), 2, GL30.GL_FLOAT, false, 0, 0); - - gl.glBindBuffer(GL30.GL_ELEMENT_ARRAY_BUFFER, Shapes.INSTANCE.indexBuffer); - if (WIREFRAME_TERRAIN) { - Extensions.wireframeExtension.glPolygonMode(GL20.GL_FRONT_AND_BACK, Extensions.GL_LINE); - } - gl.glDrawElementsInstanced(GL30.GL_TRIANGLES, Shapes.INSTANCE.quadIndices.length * 3, GL30.GL_UNSIGNED_INT, 0, - (this.columns - 1) * (this.rows - 1)); - if (WIREFRAME_TERRAIN) { - Extensions.wireframeExtension.glPolygonMode(GL20.GL_FRONT_AND_BACK, Extensions.GL_FILL); - } - -// gl.glDisableVertexAttribArray(0); - - gl.glEnable(GL30.GL_BLEND); - - } - - public void renderUberSplats(final boolean onTopLayer) { - final GL30 gl = Gdx.gl30; - final WebGL webGL = this.webGL; - final ShaderProgram shader = this.uberSplatShader; - - gl.glDepthMask(false); - gl.glEnable(GL30.GL_BLEND); - gl.glBlendFunc(GL30.GL_SRC_ALPHA, GL30.GL_ONE_MINUS_SRC_ALPHA); - gl.glBlendEquation(GL30.GL_FUNC_ADD); - - webGL.useShaderProgram(this.uberSplatShader); - - shader.setUniformMatrix("u_mvp", this.camera.viewProjectionMatrix); - shader.setUniformi("u_heightMap", 0); - sizeHeap[0] = this.columns - 1; - sizeHeap[1] = this.rows - 1; - shader.setUniform2fv("u_size", sizeHeap, 0, 2); - sizeHeap[0] = 1 / (float) this.columns; - sizeHeap[1] = 1 / (float) this.rows; - shader.setUniform2fv("u_pixel", sizeHeap, 0, 2); - shader.setUniform2fv("u_centerOffset", this.centerOffset, 0, 2); - shader.setUniformi("u_texture", 1); - shader.setUniformi("u_shadowMap", 2); - - gl.glActiveTexture(GL30.GL_TEXTURE0); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.groundCornerHeightLinear); - - gl.glActiveTexture(GL30.GL_TEXTURE2); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.shadowMap); - - final W3xSceneLightManager lightManager = (W3xSceneLightManager) this.viewer.worldScene.getLightManager(); - final DataTexture terrainLightsTexture = lightManager.getTerrainLightsTexture(); - - terrainLightsTexture.bind(21); - gl.glUniform1i(shader.getUniformLocation("u_lightTexture"), 21); - gl.glUniform1f(shader.getUniformLocation("u_lightCount"), lightManager.getTerrainLightCount()); - gl.glUniform1f(shader.getUniformLocation("u_lightTextureHeight"), terrainLightsTexture.getHeight()); - - // Render the cliffs - for (final SplatModel splat : this.uberSplatModelsList) { - if (splat.isHighPriority() == onTopLayer) { - splat.render(gl, shader); - } - } - } - - public void renderWater() { - // Render water - this.webGL.useShaderProgram(this.waterShader); - - final GL30 gl = Gdx.gl30; - gl.glDepthMask(false); - gl.glDisable(GL30.GL_CULL_FACE); - gl.glEnable(GL30.GL_BLEND); - gl.glBlendFunc(GL30.GL_SRC_ALPHA, GL30.GL_ONE_MINUS_SRC_ALPHA); - - this.waterShader.setUniformMatrix4fv("MVP", this.camera.viewProjectionMatrix.val, 0, 16); - this.waterShader.setUniform4fv("shallow_color_min", this.minShallowColor, 0, 4); - this.waterShader.setUniform4fv("shallow_color_max", this.maxShallowColor, 0, 4); - this.waterShader.setUniform4fv("deep_color_min", this.minDeepColor, 0, 4); - this.waterShader.setUniform4fv("deep_color_max", this.maxDeepColor, 0, 4); - this.waterShader.setUniformf("water_offset", this.waterHeightOffset); - this.waterShader.setUniformi("current_texture", (int) this.waterIndex); - this.waterShader.setUniformf("centerOffsetX", this.centerOffset[0]); - this.waterShader.setUniformf("centerOffsetY", this.centerOffset[1]); - this.waterShader.setUniform4fv("mapBounds", this.shaderMapBounds, 0, 4); - - final W3xSceneLightManager lightManager = (W3xSceneLightManager) this.viewer.worldScene.getLightManager(); - final DataTexture terrainLightsTexture = lightManager.getTerrainLightsTexture(); - - terrainLightsTexture.bind(3); - this.waterShader.setUniformi("lightTexture", 3); - this.waterShader.setUniformf("lightCount", lightManager.getTerrainLightCount()); - this.waterShader.setUniformf("lightTextureHeight", terrainLightsTexture.getHeight()); - - this.waterShader.setUniformi("water_height_texture", 0); - this.waterShader.setUniformi("ground_height_texture", 1); - this.waterShader.setUniformi("water_exists_texture", 2); - this.waterShader.setUniformi("water_textures", 4); - gl.glActiveTexture(GL30.GL_TEXTURE0); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.waterHeight); - gl.glActiveTexture(GL30.GL_TEXTURE1); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.groundCornerHeight); - gl.glActiveTexture(GL30.GL_TEXTURE2); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.waterExists); - gl.glActiveTexture(GL30.GL_TEXTURE4); - gl.glBindTexture(GL30.GL_TEXTURE_2D_ARRAY, this.waterTextureArray); - - gl.glBindBuffer(GL30.GL_ARRAY_BUFFER, Shapes.INSTANCE.vertexBuffer); - gl.glVertexAttribPointer(this.waterShader.getAttributeLocation("vPosition"), 2, GL30.GL_FLOAT, false, 0, 0); - - gl.glBindBuffer(GL30.GL_ELEMENT_ARRAY_BUFFER, Shapes.INSTANCE.indexBuffer); - gl.glDrawElementsInstanced(GL30.GL_TRIANGLES, Shapes.INSTANCE.quadIndices.length * 3, GL30.GL_UNSIGNED_INT, 0, - (this.columns - 1) * (this.rows - 1)); - - gl.glEnable(GL30.GL_BLEND); - } - - public void renderCliffs() { - - // Render cliffs - for (final IVec3 i : this.cliffs) { - final RenderCorner bottomLeft = this.corners[i.x][i.y]; - final RenderCorner bottomRight = this.corners[i.x + 1][i.y]; - final RenderCorner topLeft = this.corners[i.x][i.y + 1]; - final RenderCorner topRight = this.corners[i.x + 1][i.y + 1]; - - final float min = Math.min(Math.min(bottomLeft.getLayerHeight() - 2, bottomRight.getLayerHeight() - 2), - Math.min(topLeft.getLayerHeight() - 2, topRight.getLayerHeight() - 2)); - - fourComponentHeap[0] = i.x; - fourComponentHeap[1] = i.y; - fourComponentHeap[2] = min; - fourComponentHeap[3] = bottomLeft.getCliffTexture(); - this.cliffMeshes.get(i.z).renderQueue(fourComponentHeap); - } - - this.webGL.useShaderProgram(this.cliffShader); - - final GL30 gl = Gdx.gl30; - gl.glDisable(GL30.GL_BLEND); - - // WC3 models are 128x too large - tempMatrix.set(this.camera.viewProjectionMatrix); - gl.glUniformMatrix4fv(this.cliffShader.getUniformLocation("MVP"), 1, false, tempMatrix.val, 0); - gl.glUniform1i(this.cliffShader.getUniformLocation("show_lighting"), this.viewer.renderLighting); - - final W3xSceneLightManager lightManager = (W3xSceneLightManager) this.viewer.worldScene.getLightManager(); - final DataTexture unitLightsTexture = lightManager.getTerrainLightsTexture(); - - unitLightsTexture.bind(21); - gl.glUniform1i(this.cliffShader.getUniformLocation("lightTexture"), 21); - gl.glUniform1f(this.cliffShader.getUniformLocation("lightCount"), lightManager.getTerrainLightCount()); - gl.glUniform1f(this.cliffShader.getUniformLocation("lightTextureHeight"), unitLightsTexture.getHeight()); - - this.cliffShader.setUniformi("shadowMap", 2); - gl.glActiveTexture(GL30.GL_TEXTURE2); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.shadowMap); - - this.cliffShader.setUniformi("cliff_textures", 0); - gl.glActiveTexture(GL30.GL_TEXTURE0); - gl.glBindTexture(GL30.GL_TEXTURE_2D_ARRAY, this.cliffTextureArray); - this.cliffShader.setUniformi("height_texture", 1); - gl.glActiveTexture(GL30.GL_TEXTURE1); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.groundHeight); -// gl.glActiveTexture(GL30.GL_TEXTURE2); - for (final CliffMesh i : this.cliffMeshes) { - gl.glUniform1f(this.cliffShader.getUniformLocation("centerOffsetX"), this.centerOffset[0]); - gl.glUniform1f(this.cliffShader.getUniformLocation("centerOffsetY"), this.centerOffset[1]); - i.render(this.cliffShader); - } - } - - public BuildingShadow addShadow(final String file, final float shadowX, final float shadowY) { - if (!this.shadows.containsKey(file)) { - final String path = "ReplaceableTextures\\Shadows\\" + file + ".blp"; - this.shadows.put(file, new ArrayList<>()); - this.shadowTextures.put(file, (Texture) this.viewer.load(path, PathSolver.DEFAULT, null)); - } - final List shadowList = this.shadows.get(file); - final float[] shadowPositionArray = new float[] { shadowX, shadowY }; - shadowList.add(shadowPositionArray); - if (this.initShadowsFinished) { - final Texture texture = this.shadowTextures.get(file); - - final int columns = (this.columns - 1) * 4; - final int rows = (this.rows - 1) * 4; - blitShadowData(columns, rows, shadowX, shadowY, texture); - final GL30 gl = Gdx.gl30; - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.shadowMap); - gl.glTexImage2D(GL30.GL_TEXTURE_2D, 0, GL30.GL_R8, columns, rows, 0, GL30.GL_RED, GL30.GL_UNSIGNED_BYTE, - RenderMathUtils.wrap(this.shadowData)); - } - return new BuildingShadow() { - @Override - public void remove() { - shadowList.remove(shadowPositionArray); - reloadShadowDataToGPU(); - } - - @Override - public void move(final float x, final float y) { - shadowPositionArray[0] = x; - shadowPositionArray[1] = y; - reloadShadowDataToGPU(); - } - }; - } - - public void blitShadowData(final int columns, final int rows, final float shadowX, final float shadowY, - final Texture texture) { - final int width = texture.getWidth(); - final int height = texture.getHeight(); - final int ox = (int) Math.round(width * 0.3); - final int oy = (int) Math.round(height * 0.7); - blitShadowDataLocation(columns, rows, (RawOpenGLTextureResource) texture, width, height, ox, oy, - this.centerOffset, shadowX, shadowY, this.shadowData); - } - - public void initShadows() throws IOException { - final GL30 gl = Gdx.gl30; - final float[] centerOffset = this.centerOffset; - final int columns = (this.columns - 1) * 4; - final int rows = (this.rows - 1) * 4; - - final int shadowSize = columns * rows; - this.staticShadowData = new byte[columns * rows]; - this.shadowData = new byte[columns * rows]; - if (this.viewer.mapMpq.has("war3map.shd")) { - final byte[] buffer; - - try (final InputStream shadowSource = this.viewer.mapMpq.getResourceAsStream("war3map.shd")) { - buffer = IOUtils.toByteArray(shadowSource); - } - - for (int i = 0; i < shadowSize; i++) { - this.staticShadowData[i] = (byte) ((buffer[i] & 0xFF) / 2f); - } - } - - final byte outsideArea = (byte) 204; - final int x0 = this.mapBounds[0] * 4, x1 = (this.mapSize[0] - this.mapBounds[1] - 1) * 4, - y0 = this.mapBounds[2] * 4, y1 = (this.mapSize[1] - this.mapBounds[3] - 1) * 4; - for (int y = y0; y < y1; ++y) { - for (int x = x0; x < x1; ++x) { - final RenderCorner c = this.corners[x >> 2][y >> 2]; - if (c.getBoundary() != 0) { - this.staticShadowData[(y * columns) + x] = outsideArea; - } - } - } - for (int y = 0; y < rows; ++y) { - for (int x = 0; x < x0; ++x) { - this.staticShadowData[(y * columns) + x] = outsideArea; - } - for (int x = x1; x < columns; ++x) { - this.staticShadowData[(y * columns) + x] = outsideArea; - } - } - for (int x = x0; x < x1; ++x) { - for (int y = 0; y < y0; ++y) { - this.staticShadowData[(y * columns) + x] = outsideArea; - } - for (int y = y1; y < rows; ++y) { - this.staticShadowData[(y * columns) + x] = outsideArea; - } - } - reloadShadowData(centerOffset, columns, rows); - - this.shadowMap = gl.glGenTexture(); - gl.glBindTexture(GL30.GL_TEXTURE_2D, this.shadowMap); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MAG_FILTER, GL30.GL_LINEAR); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_MIN_FILTER, GL30.GL_LINEAR); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_WRAP_S, GL30.GL_CLAMP_TO_EDGE); - gl.glTexParameteri(GL30.GL_TEXTURE_2D, GL30.GL_TEXTURE_WRAP_T, GL30.GL_CLAMP_TO_EDGE); - gl.glTexImage2D(GL30.GL_TEXTURE_2D, 0, GL30.GL_R8, columns, rows, 0, GL30.GL_RED, GL30.GL_UNSIGNED_BYTE, - RenderMathUtils.wrap(this.shadowData)); - this.initShadowsFinished = true; - } - - private void reloadShadowData(final float[] centerOffset, final int columns, final int rows) { - System.arraycopy(this.staticShadowData, 0, this.shadowData, 0, this.staticShadowData.length); - for (final Map.Entry fileAndTexture : this.shadowTextures.entrySet()) { - final String file = fileAndTexture.getKey(); - final Texture texture = fileAndTexture.getValue(); - - final int width = texture.getWidth(); - final int height = texture.getHeight(); - final int ox = (int) Math.round(width * 0.3); - final int oy = (int) Math.round(height * 0.7); - for (final float[] location : this.shadows.get(file)) { - blitShadowDataLocation(columns, rows, (RawOpenGLTextureResource) texture, width, height, ox, oy, - centerOffset, location[0], location[1], this.shadowData); - } - } - } - - public void blitShadowDataLocation(final int columns, final int rows, final RawOpenGLTextureResource texture, - final int width, final int height, final int x01, final int y01, final float[] centerOffset, final float v, - final float v2, final byte[] shadowData) { - final int x0 = (int) Math.floor((v - centerOffset[0]) / 32.0) - x01; - final int y0 = (int) Math.floor((v2 - centerOffset[1]) / 32.0) + y01; - for (int y = 0; y < height; ++y) { - if (((y0 - y) < 0) || ((y0 - y) >= rows)) { - continue; - } - for (int x = 0; x < width; ++x) { - if (((x0 + x) < 0) || ((x0 + x) >= columns)) { - continue; - } - if (texture.getData().get((((y * width) + x) * 4) + 3) != 0) { - shadowData[((y0 - y) * columns) + x0 + x] = (byte) 128; - } - } - } - } - -// public Vector3 groundNormal(final Vector3 out, int x, int y) { -// final float[] centerOffset = this.centerOffset; -// final int[] mapSize = this.mapSize; -// -// x = (int) ((x - centerOffset[0]) / 128); -// y = (int) ((y - centerOffset[1]) / 128); -// -// final int cellX = x; -// final int cellY = y; -// -// // See if this coordinate is in the map -// -// if ((cellX >= 0) && (cellX < (mapSize[0] - 1)) && (cellY >= 0) && (cellY < (mapSize[1] - 1))) { -// // See http://gamedev.stackexchange.com/a/24574 -// final Corner[][] corners = this.corners; -// final float bottomLeft = corners[cellY][cellX].getGroundHeight(); -// final float bottomRight = corners[cellY][cellX + 1].getGroundHeight(); -// final float topLeft = corners[cellY + 1][cellX].getGroundHeight(); -// final float topRight = corners[cellY + 1][cellX + 1].getGroundHeight(); -// final int sqX = x - cellX; -// final int sqY = y - cellY; -// -// if ((sqX + sqY) < 1) { -// normalHeap1.set(1, 0, bottomRight - bottomLeft); -// normalHeap2.set(0, 1, topLeft - bottomLeft); -// } -// else { -// normalHeap1.set(-1, 0, topRight - topLeft); -// normalHeap2.set(0, 1, topRight - bottomRight); -// } -// -// out.set(normalHeap1.crs(normalHeap2)).nor(); -// } -// else { -// out.set(0, 0, 1); -// } -// -// return out; -// } - - private final WaveBuilder waveBuilder; - public PathingGrid pathingGrid; - private final Rectangle shaderMapBoundsRectangle; - private final Rectangle entireMapRectangle; - - private static final class UnloadedTexture { - private final int width; - private final int height; - private final Buffer data; - private final String cliffModelDir; - private final String rampModelDir; - - public UnloadedTexture(final int width, final int height, final Buffer data, final String cliffModelDir, - final String rampModelDir) { - this.width = width; - this.height = height; - this.data = data; - this.cliffModelDir = cliffModelDir; - this.rampModelDir = rampModelDir; - } - - } - - public float getGroundHeight(final float x, final float y) { - final float userCellSpaceX = (x - this.centerOffset[0]) / 128.0f; - final float userCellSpaceY = (y - this.centerOffset[1]) / 128.0f; - final int cellX = (int) userCellSpaceX; - final int cellY = (int) userCellSpaceY; - - if ((cellX >= 0) && (cellX < (this.mapSize[0] - 1)) && (cellY >= 0) && (cellY < (this.mapSize[1] - 1))) { - final float bottomLeft = this.groundCornerHeights[(cellY * this.columns) + cellX]; - final float bottomRight = this.groundCornerHeights[(cellY * this.columns) + cellX + 1]; - final float topLeft = this.groundCornerHeights[((cellY + 1) * this.columns) + cellX]; - final float topRight = this.groundCornerHeights[((cellY + 1) * this.columns) + cellX + 1]; - final float sqX = userCellSpaceX - cellX; - final float sqY = userCellSpaceY - cellY; - float height; - - if ((sqX + sqY) < 1) { - height = bottomLeft + ((bottomRight - bottomLeft) * sqX) + ((topLeft - bottomLeft) * sqY); - } - else { - height = topRight + ((bottomRight - topRight) * (1 - sqY)) + ((topLeft - topRight) * (1 - sqX)); - } - - return height * 128.0f; - } - - return 0; - } - - public float getWaterHeight(final float x, final float y) { - final float userCellSpaceX = (x - this.centerOffset[0]) / 128.0f; - final float userCellSpaceY = (y - this.centerOffset[1]) / 128.0f; - final int cellX = (int) userCellSpaceX; - final int cellY = (int) userCellSpaceY; - - if ((cellX >= 0) && (cellX < (this.mapSize[0] - 1)) && (cellY >= 0) && (cellY < (this.mapSize[1] - 1))) { - final float bottomLeft = this.waterHeights[(cellY * this.columns) + cellX]; - final float bottomRight = this.waterHeights[(cellY * this.columns) + cellX + 1]; - final float topLeft = this.waterHeights[((cellY + 1) * this.columns) + cellX]; - final float topRight = this.waterHeights[((cellY + 1) * this.columns) + cellX + 1]; - final float sqX = userCellSpaceX - cellX; - final float sqY = userCellSpaceY - cellY; - float height; - - if ((sqX + sqY) < 1) { - height = bottomLeft + ((bottomRight - bottomLeft) * sqX) + ((topLeft - bottomLeft) * sqY); - } - else { - height = topRight + ((bottomRight - topRight) * (1 - sqY)) + ((topLeft - topRight) * (1 - sqX)); - } - - return ((height + this.waterHeightOffset) * 128.0f); - } - - return this.waterHeightOffset * 128.0f; - } - - public static final class Splat { - public List locations = new ArrayList<>(); - public List> unitMapping = new ArrayList<>(); - public float opacity = 1; - } - - public void loadSplats() throws IOException { - for (final Map.Entry entry : this.splats.entrySet()) { - final String path = entry.getKey(); - final Splat splat = entry.getValue(); - - final SplatModel splatModel = new SplatModel(Gdx.gl30, - (Texture) this.viewer.load(path, PathSolver.DEFAULT, null), splat.locations, this.centerOffset, - splat.unitMapping.isEmpty() ? null : splat.unitMapping, false, false, false); - splatModel.color[3] = splat.opacity; - this.addSplatBatchModel(path, splatModel); - } - } - - public void removeSplatBatchModel(final String path) { - this.uberSplatModelsList.remove(this.uberSplatModels.remove(path)); - } - - public void addSplatBatchModel(final String path, final SplatModel model) { - this.uberSplatModels.put(path, model); - this.uberSplatModelsList.add(model); - Collections.sort(this.uberSplatModelsList); - } - - public SplatModel getSplatModel(final String pathKey) { - return this.uberSplatModels.get(pathKey); - } - - public SplatMover addUberSplat(final String path, final float x, final float y, final float z, final float scale, - final boolean unshaded, final boolean noDepthTest, final boolean highPriority) { - SplatModel splatModel = this.uberSplatModels.get(path); - if (splatModel == null) { - splatModel = new SplatModel(Gdx.gl30, (Texture) this.viewer.load(path, PathSolver.DEFAULT, null), - new ArrayList<>(), this.centerOffset, new ArrayList<>(), unshaded, noDepthTest, highPriority); - this.addSplatBatchModel(path, splatModel); - } - return splatModel.add(x - scale, y - scale, x + scale, y + scale, z, this.centerOffset); - } - - public SplatMover addUnitShadowSplat(final String texture, final float x, final float y, final float x2, - final float y2, final float zDepthUpward, final float opacity) { - SplatModel splatModel = this.uberSplatModels.get(texture); - if (splatModel == null) { - splatModel = new SplatModel(Gdx.gl30, (Texture) this.viewer.load(texture, PathSolver.DEFAULT, null), - new ArrayList<>(), this.centerOffset, new ArrayList<>(), false, false, false); - splatModel.color[3] = opacity; - this.addSplatBatchModel(texture, splatModel); - } - return splatModel.add(x, y, x2, y2, zDepthUpward, this.centerOffset); - } - - public static final class SoftwareGroundMesh { - public final float[] vertices; - public final int[] indices; - - private SoftwareGroundMesh(final float[] groundHeights, final float[] groundCornerHeights, - final float[] centerOffset, final int columns, final int rows) { - this.vertices = new float[(columns - 1) * (rows - 1) * Shapes.INSTANCE.quadVertices.length * 3]; - this.indices = new int[(columns - 1) * (rows - 1) * Shapes.INSTANCE.quadIndices.length * 3]; - for (int y = 0; y < (rows - 1); y++) { - for (int x = 0; x < (columns - 1); x++) { - final int instanceId = (y * (columns - 1)) + x; - for (int vertexId = 0; vertexId < Shapes.INSTANCE.quadVertices.length; vertexId++) { - final float vPositionX = Shapes.INSTANCE.quadVertices[vertexId][0]; - final float vPositionY = Shapes.INSTANCE.quadVertices[vertexId][1]; - final int groundCornerHeightIndex = (int) (((vPositionY + y) * (columns)) + (vPositionX + x)); - final float height = groundCornerHeights[groundCornerHeightIndex]; - this.vertices[(instanceId * 4 * 3) + (vertexId * 3)] = ((vPositionX + x) * 128f) - + centerOffset[0]; - this.vertices[(instanceId * 4 * 3) + (vertexId * 3) + 1] = ((vPositionY + y) * 128f) - + centerOffset[1]; - this.vertices[(instanceId * 4 * 3) + (vertexId * 3) + 2] = height * 128f; - } - for (int triangle = 0; triangle < Shapes.INSTANCE.quadIndices.length; triangle++) { - for (int vertexId = 0; vertexId < Shapes.INSTANCE.quadIndices[triangle].length; vertexId++) { - final int vertexIndex = Shapes.INSTANCE.quadIndices[triangle][vertexId]; - final int indexValue = (vertexIndex + (instanceId * 4)); - if ((indexValue * 3) >= this.vertices.length) { - throw new IllegalStateException(); - } - this.indices[(instanceId * 2 * 3) + (triangle * 3) + vertexId] = indexValue; - } - } - } - } - } - } - - public boolean inPlayableArea(float x, float y) { - x = (x - this.centerOffset[0]) / 128.0f; - y = (y - this.centerOffset[1]) / 128.0f; - if (x < this.mapBounds[0]) { - return false; - } - if (x >= (this.mapSize[0] - this.mapBounds[1] - 1)) { - return false; - } - if (y < this.mapBounds[2]) { - return false; - } - if (y >= (this.mapSize[1] - this.mapBounds[3] - 1)) { - return false; - } // TODO why do we use floor if we can use int cast? - return this.corners[(int) Math.floor(x)][(int) Math.floor(y)].getBoundary() == 0; - } - - public Rectangle getPlayableMapArea() { - return this.shaderMapBoundsRectangle; - } - - public Rectangle getEntireMap() { - return this.entireMapRectangle; - } - - private void reloadShadowDataToGPU() { - final int columns = (Terrain.this.columns - 1) * 4; - final int rows = (Terrain.this.rows - 1) * 4; - reloadShadowData(Terrain.this.centerOffset, columns, rows); - final GL30 gl = Gdx.gl30; - gl.glBindTexture(GL30.GL_TEXTURE_2D, Terrain.this.shadowMap); - gl.glTexImage2D(GL30.GL_TEXTURE_2D, 0, GL30.GL_R8, columns, rows, 0, GL30.GL_RED, GL30.GL_UNSIGNED_BYTE, - RenderMathUtils.wrap(Terrain.this.shadowData)); - } - - private static char getRampLetter(final int layerHeightOffset, final boolean isRamp) { - if (isRamp) { - switch (layerHeightOffset) { - case 0: - return 'L'; - case 1: - return 'H'; - case 2: - return 'X'; - default: - throw new IllegalArgumentException("Invalid ramp"); - } - } - else { - return (char) ('A' + layerHeightOffset); - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/TerrainShaders.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/TerrainShaders.java deleted file mode 100644 index b43b4abf..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/TerrainShaders.java +++ /dev/null @@ -1,388 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.environment; - -import com.etheller.warsmash.viewer5.Shaders; - -/** - * Mostly copied from HiveWE! - */ -public class TerrainShaders { - public static final class Cliffs { - private Cliffs() { - } - - public static final String vert() { - return "#version 330 core\r\n" + // - "\r\n" + // - "in vec3 vPosition;\r\n" + // - "in vec2 vUV;\r\n" + // - "in vec3 vNormal;\r\n" + // - "in vec4 vOffset;\r\n" + // - "\r\n" + // - "uniform mat4 MVP;\r\n" + // - "\r\n" + // - "uniform sampler2D height_texture;\r\n" + // - "uniform sampler2D shadowMap;\r\n" + // - "uniform float centerOffsetX;\r\n" + // - "uniform float centerOffsetY;\r\n" + // - "uniform sampler2D lightTexture;\r\n" + // - "uniform float lightCount;\r\n" + // - "uniform float lightTextureHeight;\r\n" + // - "\r\n" + // - "out vec3 UV;\r\n" + // - "out vec3 Normal;\r\n" + // - "out vec2 pathing_map_uv;\r\n" + // - "out vec3 position;\r\n" + // - "out vec2 v_suv;\r\n" + // - "out vec3 shadeColor;\r\n" + // - "\r\n" + // - "void main() {\r\n" + // - " pathing_map_uv = (vec2(vPosition.y, -vPosition.x) / 128 + vOffset.xy) * 4;\r\n" + // - " \r\n" + // - " ivec2 size = textureSize(height_texture, 0);\r\n" + // - " ivec2 shadowSize = textureSize(shadowMap, 0);\r\n" + // - " v_suv = pathing_map_uv / shadowSize;\r\n" + // - " float value = texture(height_texture, (vOffset.xy + vec2(vPosition.y + 64, -vPosition.x + 64) / 128.0) / vec2(size)).r;\r\n" - + // - "\r\n" + // - " position = (vec3(vPosition.y, -vPosition.x, vPosition.z) + vec3(vOffset.xy, vOffset.z + value) * 128 );\r\n" - + // - " vec4 myposition = vec4(position, 1);\r\n" + // - " myposition.x += centerOffsetX;\r\n" + // - " myposition.y += centerOffsetY;\r\n" + // - " position.x /= (size.x * 128.0);\r\n" + // - " position.y /= (size.y * 128.0);\r\n" + // - " gl_Position = MVP * myposition;\r\n" + // - " UV = vec3(vUV, vOffset.a);\r\n" + // - "\r\n" + // - " ivec2 height_pos = ivec2(vOffset.xy + vec2(vPosition.y, -vPosition.x) / 128);\r\n" + // - " ivec3 off = ivec3(1, 1, 0);\r\n" + // - " float hL = texelFetch(height_texture, height_pos - off.xz, 0).r;\r\n" + // - " float hR = texelFetch(height_texture, height_pos + off.xz, 0).r;\r\n" + // - " float hD = texelFetch(height_texture, height_pos - off.zy, 0).r;\r\n" + // - " float hU = texelFetch(height_texture, height_pos + off.zy, 0).r;\r\n" + // - " bool edgeX = (vPosition.y) == float((int(vPosition.y))/128*128);\r\n" + // - " bool edgeY = (vPosition.x) == float((int(vPosition.x))/128*128);\r\n" + // - " bool edgeZ = (vPosition.z) == float((int(vPosition.z))/128*128);\r\n" + // - " vec3 terrain_normal = vec3(vNormal.y, -vNormal.x, vNormal.z);\r\n" + // - " if(edgeX) {\r\n" + // - " terrain_normal.x = hL - hR;\r\n" + // - " }\r\n" + // - " if(edgeY) {\r\n" + // - " terrain_normal.y = hD - hU;\r\n" + // - " }\r\n" + // - " if(edgeZ) {\r\n" + // - " terrain_normal.z = 2.0;\r\n" + // - " }\r\n" + // - " terrain_normal = normalize(terrain_normal);\r\n" + // - "\r\n" + // - " Normal = terrain_normal;\r\n" + // - Shaders.lightSystem("terrain_normal", "myposition.xyz", "lightTexture", "lightTextureHeight", - "lightCount", true) - + "\r\n" + // - " shadeColor = clamp(lightFactor, 0.0, 1.0);\r\n" + // - "}"; - } - - public static final String frag = "#version 330 core\r\n" + // - "\r\n" + // - "uniform sampler2DArray cliff_textures;\r\n" + // - "uniform sampler2D shadowMap;\r\n" + // - "\r\n" + // - "uniform bool show_lighting;\r\n" + // - "\r\n" + // - "in vec3 UV;\r\n" + // - "in vec3 Normal;\r\n" + // - "in vec2 pathing_map_uv;\r\n" + // - "in vec3 position;\r\n" + // - "in vec2 v_suv;\r\n" + // - "in vec3 shadeColor;\r\n" + // - "\r\n" + // - "out vec4 color;\r\n" + // - "\r\n" + // - "void main() {\r\n" + // - " color = texture(cliff_textures, UV);\r\n" + // - "\r\n" + // - " float shadow = texture2D(shadowMap, v_suv).r;\r\n" + // - " color.rgb *= (1.0 - shadow);\r\n" + // - " if (show_lighting) {\r\n" + // - " color.rgb *= shadeColor;\r\n" + // - " }\r\n" + // - "\r\n" + // - "}"; - } - - public static final class Terrain { - private Terrain() { - } - - public static final String vert() { - return "#version 330 core\r\n" + // - "\r\n" + // - "in vec2 vPosition;\r\n" + // - "uniform mat4 MVP;\r\n" + // - "uniform mat4 DepthBiasMVP;\r\n" + // - "\r\n" + // - "uniform sampler2D height_texture;\r\n" + // - "uniform sampler2D height_cliff_texture;\r\n" + // - "uniform usampler2D terrain_texture_list;\r\n" + // - "uniform float centerOffsetX;\r\n" + // - "uniform float centerOffsetY;\r\n" + // - "uniform sampler2D lightTexture;\r\n" + // - "uniform float lightCount;\r\n" + // - "uniform float lightTextureHeight;\r\n" + // - "\r\n" + // - "out vec2 UV;\r\n" + // - "flat out uvec4 texture_indices;\r\n" + // - "out vec2 pathing_map_uv;\r\n" + // - "out vec3 position;\r\n" + // - "out vec3 ShadowCoord;\r\n" + // - "out vec2 v_suv;\r\n" + // - "out vec3 shadeColor;\r\n" + // - "\r\n" + // - "void main() { \r\n" + // - " ivec2 size = textureSize(terrain_texture_list, 0);\r\n" + // - " ivec2 pos = ivec2(gl_InstanceID % size.x, gl_InstanceID / size.x);\r\n" + // - "\r\n" + // - " ivec2 height_pos = ivec2(vPosition + pos);\r\n" + // - " vec4 height = texelFetch(height_cliff_texture, height_pos, 0);\r\n" + // - "\r\n" + // - " ivec3 off = ivec3(1, 1, 0);\r\n" + // - " float hL = texelFetch(height_texture, height_pos - off.xz, 0).r;\r\n" + // - " float hR = texelFetch(height_texture, height_pos + off.xz, 0).r;\r\n" + // - " float hD = texelFetch(height_texture, height_pos - off.zy, 0).r;\r\n" + // - " float hU = texelFetch(height_texture, height_pos + off.zy, 0).r;\r\n" + // - " vec3 normal = normalize(vec3(hL - hR, hD - hU, 2.0));\r\n" + // - "\r\n" + // - " UV = vec2(vPosition.x, 1 - vPosition.y);\r\n" + // - // " UV = vec2(vPosition.x==0?0.01:0.99, vPosition.y==0?0.99:0.01);\r\n" + // - " texture_indices = texelFetch(terrain_texture_list, pos, 0);\r\n" + // - " pathing_map_uv = (vPosition + pos) * 4; \r\n" + // - "\r\n" + // - " // Cliff culling\r\n" + // - " vec3 positionWorld = vec3((vPosition.x + pos.x)*128.0 + centerOffsetX, (vPosition.y + pos.y)*128.0 + centerOffsetY, height.r*128.0);\r\n" - + // - " position = positionWorld;\r\n" + // - " gl_Position = ((texture_indices.a & 32768u) == 0u) ? MVP * vec4(position.xyz, 1) : vec4(2.0, 0.0, 0.0, 1.0);\r\n" - + // - " ShadowCoord = (((texture_indices.a & 32768u) == 0u) ? DepthBiasMVP * vec4(position.xyz, 1) : vec4(2.0, 0.0, 0.0, 1.0)).xyz;\r\n" - + // - " v_suv = (vPosition + pos) / size;\r\n" + // - " position.x = (position.x - centerOffsetX) / (size.x * 128.0);\r\n" + // - " position.y = (position.y - centerOffsetY) / (size.y * 128.0);\r\n" + // - Shaders.lightSystem("normal", "positionWorld", "lightTexture", "lightTextureHeight", "lightCount", - true) - + "\r\n" + // - " shadeColor = clamp(lightFactor, 0.0, 1.0);\r\n" + // - "}"; - } - - public static final String frag = "#version 330 core\r\n" + // - "\r\n" + // - "uniform bool show_pathing_map;\r\n" + // - "uniform bool show_lighting;\r\n" + // - "\r\n" + // - "uniform sampler2DArray sample0;\r\n" + // - "uniform sampler2DArray sample1;\r\n" + // - "uniform sampler2DArray sample2;\r\n" + // - "uniform sampler2DArray sample3;\r\n" + // - "uniform sampler2DArray sample4;\r\n" + // - "uniform sampler2DArray sample5;\r\n" + // - "uniform sampler2DArray sample6;\r\n" + // - "uniform sampler2DArray sample7;\r\n" + // - "uniform sampler2DArray sample8;\r\n" + // - "uniform sampler2DArray sample9;\r\n" + // - "uniform sampler2DArray sample10;\r\n" + // - "uniform sampler2DArray sample11;\r\n" + // -// "uniform sampler2DArray sample12;\r\n" + // -// "uniform sampler2DArray sample13;\r\n" + // -// "uniform sampler2DArray sample14;\r\n" + // -// "uniform sampler2DArray sample15;\r\n" + // - "uniform sampler2DArray sample16;\r\n" + // - "\r\n" + // -// "layout (binding = 20) uniform usampler2D pathing_map_static;\r\n" + // -// "layout (binding = 21) uniform usampler2D pathing_map_dynamic;\r\n" + // - "uniform sampler2D shadowMap;\r\n" + // - "\r\n" + // - "in vec2 UV;\r\n" + // - "flat in uvec4 texture_indices;\r\n" + // - "in vec2 pathing_map_uv;\r\n" + // - "in vec3 position;\r\n" + // - "in vec3 ShadowCoord;\r\n" + // - "in vec2 v_suv;\r\n" + // - "in vec3 shadeColor;\r\n" + // - "\r\n" + // - "out vec4 color;\r\n" + // -// "layout (location = 1) out vec4 position;\r\n" + // - "\r\n" + // - "vec4 get_fragment(uint id, vec3 uv) {\r\n" + // - " vec2 dx = dFdx(uv.xy);\r\n" + // - " vec2 dy = dFdy(uv.xy);\r\n" + // - "\r\n" + // - " switch(id) {\r\n" + // - " case 0u:\r\n" + // - " return textureGrad(sample0, uv, dx, dy);\r\n" + // - " case 1u:\r\n" + // - " return textureGrad(sample1, uv, dx, dy);\r\n" + // - " case 2u:\r\n" + // - " return textureGrad(sample2, uv, dx, dy);\r\n" + // - " case 3u:\r\n" + // - " return textureGrad(sample3, uv, dx, dy);\r\n" + // - " case 4u:\r\n" + // - " return textureGrad(sample4, uv, dx, dy);\r\n" + // - " case 5u:\r\n" + // - " return textureGrad(sample5, uv, dx, dy);\r\n" + // - " case 6u:\r\n" + // - " return textureGrad(sample6, uv, dx, dy);\r\n" + // - " case 7u:\r\n" + // - " return textureGrad(sample7, uv, dx, dy);\r\n" + // - " case 8u:\r\n" + // - " return textureGrad(sample8, uv, dx, dy);\r\n" + // - " case 9u:\r\n" + // - " return textureGrad(sample9, uv, dx, dy);\r\n" + // - " case 10u:\r\n" + // - " return textureGrad(sample10, uv, dx, dy);\r\n" + // - " case 11u:\r\n" + // - " return textureGrad(sample11, uv, dx, dy);\r\n" + // -// " case 12u:\r\n" + // -// " return textureGrad(sample12, uv, dx, dy);\r\n" + // -// " case 13u:\r\n" + // -// " return textureGrad(sample13, uv, dx, dy);\r\n" + // -// " case 14u:\r\n" + // -// " return textureGrad(sample14, uv, dx, dy);\r\n" + // -// " case 15u:\r\n" + // -// " return textureGrad(sample15, uv, dx, dy);\r\n" + // - " case 16u:\r\n" + // - " return textureGrad(sample16, uv, dx, dy);\r\n" + // - " case 17u:\r\n" + // - " return vec4(0, 0, 0, 0);\r\n" + // - " }\r\n" + // - "}\r\n" + // - "\r\n" + // - "\r\n" + // - "void main() {\r\n" + // - " color = get_fragment(texture_indices.a & 31u, vec3(UV, texture_indices.a >> 5));\r\n" + // - " color = color * color.a + get_fragment(texture_indices.b & 31u, vec3(UV, texture_indices.b >> 5)) * (1 - color.a);\r\n" - + // - " color = color * color.a + get_fragment(texture_indices.g & 31u, vec3(UV, texture_indices.g >> 5)) * (1 - color.a);\r\n" - + // - " color = color * color.a + get_fragment(texture_indices.r & 31u, vec3(UV, texture_indices.r >> 5)) * (1 - color.a);\r\n" - + // - " float shadow = texture2D(shadowMap, v_suv).r;\r\n" + // -// " float visibility = 1.0;\r\n" + // -// " if ( texture2D(shadowMap, ShadowCoord.xy).z > ShadowCoord.z ) {\r\n" + // -// " visibility = 0.5;\r\n" + // -// " }\r\n" + // - "\r\n" + // - " if (show_lighting) {\r\n" + // - " color = vec4(color.xyz * (1.0 - shadow) * shadeColor, 1.0);\r\n" + // - " } else {\r\n" + // - " color = vec4(color.xyz * (1.0 - shadow), 1.0);\r\n" + // - " }\r\n" + // -// "\r\n" + // -// " if (show_pathing_map) {\r\n" + // -// " uint byte_static = texelFetch(pathing_map_static, ivec2(pathing_map_uv), 0).r;\r\n" + // -// " uint byte_dynamic = texelFetch(pathing_map_dynamic, ivec2(pathing_map_uv), 0).r;\r\n" + // -// " uint final = byte_static.r | byte_dynamic.r;\r\n" + // -// "\r\n" + // -// " vec4 pathing_static_color = vec4((final & 2) >> 1, (final & 4) >> 2, (final & 8) >> 3, 0.25);\r\n" -// + // -// "\r\n" + // -// " color = length(pathing_static_color.rgb) > 0 ? color * 0.75 + pathing_static_color * 0.5 : color;\r\n" -// + // -// " }\r\n" + // - "}"; - } - - public static final class Water { - private Water() { - } - - public static final String vert() { - return "#version 330 core\r\n" + // - "\r\n" + // - "in vec2 vPosition;\r\n" + // - "\r\n" + // - "uniform sampler2D water_height_texture;\r\n" + // - "uniform sampler2D ground_height_texture;\r\n" + // - "uniform sampler2D water_exists_texture;\r\n" + // - "uniform float centerOffsetX;\r\n" + // - "uniform float centerOffsetY;\r\n" + // - "\r\n" + // - "uniform mat4 MVP;\r\n" + // - "uniform vec4 shallow_color_min;\r\n" + // - "uniform vec4 shallow_color_max;\r\n" + // - "uniform vec4 deep_color_min;\r\n" + // - "uniform vec4 deep_color_max;\r\n" + // - "uniform float water_offset;\r\n" + // - "uniform sampler2D lightTexture;\r\n" + // - "uniform float lightCount;\r\n" + // - "uniform float lightTextureHeight;\r\n" + // - "\r\n" + // - "out vec2 UV;\r\n" + // - "out vec4 Color;\r\n" + // - "out vec2 position;\r\n" + // - "out vec3 shadeColor;\r\n" + // - "\r\n" + // - "const float min_depth = 10.f / 128;\r\n" + // - "const float deeplevel = 64.f / 128;\r\n" + // - "const float maxdepth = 72.f / 128;\r\n" + // - "\r\n" + // - "void main() { \r\n" + // - " ivec2 size = textureSize(water_height_texture, 0) - 1;\r\n" + // - " ivec2 pos = ivec2(gl_InstanceID % size.x, gl_InstanceID / size.x);\r\n" + // - " ivec2 height_pos = ivec2(vPosition + pos);\r\n" + // - " float water_height = texelFetch(water_height_texture, height_pos, 0).r + water_offset;\r\n" + // - "\r\n" + // - " bool is_water = texelFetch(water_exists_texture, pos, 0).r > 0\r\n" + // - " || texelFetch(water_exists_texture, pos + ivec2(1, 0), 0).r > 0\r\n" + // - " || texelFetch(water_exists_texture, pos + ivec2(1, 1), 0).r > 0\r\n" + // - " || texelFetch(water_exists_texture, pos + ivec2(0, 1), 0).r > 0;\r\n" + // - "\r\n" + // - " position = vec2((vPosition.x + pos.x)*128.0 + centerOffsetX, (vPosition.y + pos.y)*128.0 + centerOffsetY);\r\n" - + // - " vec4 myposition = vec4(position.xy, water_height*128.0, 1);\r\n" + // - " vec3 Normal = vec3(0,0,1);\r\n" + // - " gl_Position = is_water ? MVP * myposition : vec4(2.0, 0.0, 0.0, 1.0);\r\n" + // - "\r\n" + // - " UV = vec2((vPosition.x + pos.x%2)/2.0, (vPosition.y + pos.y%2)/2.0);\r\n" + // - "\r\n" + // - " float ground_height = texelFetch(ground_height_texture, height_pos, 0).r;\r\n" + // - " float value = clamp(water_height - ground_height, 0.f, 1.f);\r\n" + // - " if (value <= deeplevel) {\r\n" + // - " value = max(0.f, value - min_depth) / (deeplevel - min_depth);\r\n" + // - " Color = shallow_color_min * (1.f - value) + shallow_color_max * value;\r\n" + // - " } else {\r\n" + // - " value = clamp(value - deeplevel, 0.f, maxdepth - deeplevel) / (maxdepth - deeplevel);\r\n" + // - " Color = deep_color_min * (1.f - value) + deep_color_max * value;\r\n" + // - " }\r\n" + // - Shaders.lightSystem("Normal", "myposition.xyz", "lightTexture", "lightTextureHeight", "lightCount", - true) - + "\r\n" + // - " shadeColor = clamp(lightFactor, 0.0, 1.0);\r\n" + // - " }"; - } - - public static final String frag = "#version 330 core\r\n" + // - "\r\n" + // - "uniform sampler2DArray water_textures;\r\n" + // - "uniform sampler2D water_exists_texture;\r\n" + // - "\r\n" + // - "\r\n" + // - "uniform int current_texture;\r\n" + // - "uniform vec4 mapBounds;\r\n" + // - "\r\n" + // - "in vec2 UV;\r\n" + // - "in vec4 Color;\r\n" + // - "in vec2 position;\r\n" + // - "in vec3 shadeColor;\r\n" + // - "\r\n" + // - "out vec4 outColor;\r\n" + // - "\r\n" + // - "void main() {\r\n" + // - " vec2 d2 = min(position - mapBounds.xy, mapBounds.zw - position);\r\n" + // - " float d1 = clamp(min(d2.x, d2.y) / 64.0 + 1.0, 0.0, 1.0) * 0.8 + 0.2;;\r\n" + // - " outColor = texture(water_textures, vec3(UV, current_texture)) * vec4(Color.rgb * d1 * shadeColor, Color.a);\r\n" - + // - "}"; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/WaveBuilder.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/WaveBuilder.java deleted file mode 100644 index dfb639c7..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/environment/WaveBuilder.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.environment; - -import java.util.HashMap; -import java.util.Map; - -import com.badlogic.gdx.math.Quaternion; -import com.etheller.warsmash.parsers.w3x.w3e.War3MapW3e; -import com.etheller.warsmash.parsers.w3x.w3i.War3MapW3i; -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.units.Element; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; - -public class WaveBuilder { - - private final int[] mapSize; - private final DataTable waterTable; - private final War3MapViewer viewer; - private final RenderCorner[][] corners; - private final float[] centerOffset; - private final float waterHeightOffset; - private float[] locations; - - private final Map models; - private final War3MapW3e w3eFile; - private final War3MapW3i w3iFile; - - public WaveBuilder(final int[] mapSize, final DataTable waterTable, final War3MapViewer viewer, - final RenderCorner[][] corners, final float[] centerOffset, final float waterHeightOffset, - final War3MapW3e w3eFile, final War3MapW3i w3iFile) { - this.mapSize = mapSize; - this.waterTable = waterTable; - this.viewer = viewer; - this.corners = corners; - this.centerOffset = centerOffset; - this.waterHeightOffset = waterHeightOffset; - this.w3eFile = w3eFile; - this.w3iFile = w3iFile; - this.models = new HashMap<>(); - } - - public void createWaves(final Terrain terrain) { - final int columns = this.mapSize[0]; - final int rows = this.mapSize[1]; - final float wavesDepth = 25f / 128f; - final char tileset = this.w3eFile.getTileset(); - final Element waterRow = this.waterTable.get(tileset + "Sha"); - - final long wavesCliff = (this.w3iFile.getFlags() & 0x0800); - final long wavesRolling = (this.w3iFile.getFlags() & 0x1000); - - final String shoreline = waterRow.getField("shoreDir") + "\\" + waterRow.getField("shoreSFile") + "\\" - + waterRow.getField("shoreSFile") + "0.mdx"; - final String outsideCorner = waterRow.getField("shoreDir") + "\\" + waterRow.getField("shoreOCFile") + "\\" - + waterRow.getField("shoreOCFile") + "0.mdx"; - final String insideCorner = waterRow.getField("shoreDir") + "\\" + waterRow.getField("shoreICFile") + "\\" - + waterRow.getField("shoreICFile") + "0.mdx"; -// final String shoreline = "Buildings\\Other\\TempArtB\\TempArtB.mdx"; -// final String outsideCorner = "Buildings\\Other\\TempArtB\\TempArtB.mdx"; -// final String insideCorner = "Buildings\\Other\\TempArtB\\TempArtB.mdx"; - - this.locations = new float[3]; - - for (int y = 0; y < (rows - 1); ++y) { - for (int x = 0; x < (columns - 1); ++x) { - final RenderCorner a = this.corners[x][y]; - final RenderCorner b = this.corners[x + 1][y]; - final RenderCorner c = this.corners[x + 1][y + 1]; - final RenderCorner d = this.corners[x][y + 1]; - if ((a.getWater() != 0) || (b.getWater() != 0) || (c.getWater() != 0) || (d.getWater() != 0)) { - final boolean isCliff = (a.getLayerHeight() != b.getLayerHeight()) - || (a.getLayerHeight() != c.getLayerHeight()) || (a.getLayerHeight() != d.getLayerHeight()); - if (isCliff && (wavesCliff == 0)) { - continue; - } - if (!isCliff && (wavesRolling == 0)) { - continue; - } - final int ad = (a.depth > wavesDepth) ? 1 : 0; - final int bd = (b.depth > wavesDepth) ? 1 : 0; - final int cd = (c.depth > wavesDepth) ? 1 : 0; - final int dd = (d.depth > wavesDepth) ? 1 : 0; - final int count = ad + bd + cd + dd; - this.locations[0] = (x * 128.0f) + this.centerOffset[0] + 64.0f; - this.locations[1] = (y * 128.0f) + this.centerOffset[1] + 64.0f; - this.locations[2] = ((((a.getWaterHeight() + b.getWaterHeight() + c.getWaterHeight() - + d.getWaterHeight()) / 4f) + this.waterHeightOffset) * 128.0f) + 1.0f; - if (count == 1) { - addModelInstance(terrain, insideCorner, rotation(ad, bd, cd/* , dd */) - ((3 * Math.PI) / 4)); - } - else if (count == 2) { - final double rot = rotation2(ad, bd, cd, dd); - if (!Double.isNaN(rot)) { - addModelInstance(terrain, shoreline, rot); - } - } - else if (count == 3) { - addModelInstance(terrain, outsideCorner, - rotation(1 ^ ad, 1 ^ bd, 1 ^ cd/* , 1 ^ dd */) + ((5 * Math.PI) / 4)); - } - } - } - } - } - - private void addModelInstance(final Terrain terrain, final String path, final double rotation) { - if (!this.models.containsKey(path)) { - this.models.put(path, - (MdxModel) this.viewer.load(path, this.viewer.wc3PathSolver, this.viewer.solverParams)); - } - final MdxModel model = this.models.get(path); - final MdxComplexInstance instance = (MdxComplexInstance) model.addInstance(); - instance.setLocation(this.locations); - instance.setLocalRotation(new Quaternion().setFromAxisRad(RenderMathUtils.VEC3_UNIT_Z, (float) rotation)); - instance.setScene(this.viewer.worldScene); - if (!terrain.inPlayableArea(this.locations[0], this.locations[1])) { - instance.setVertexColor(new float[] { 51 / 255f, 51 / 255f, 51 / 255f, 1.0f }); - } - this.viewer.standOnRepeat(instance); - } - - private static double rotation(final int a, final int b, final int c) { - if (a != 0) { - return (-3 * Math.PI) / 4; - } - if (b != 0) { - return -Math.PI / 4; - } - if (c != 0) { - return Math.PI / 4; - } - return (3 * Math.PI) / 4; - } - - private static double rotation2(final int a, final int b, final int c, final int d) { - if ((a != 0) && (b != 0)) { - return -Math.PI / 2; - } - if ((b != 0) && (c != 0)) { - return 0; - } - if ((c != 0) && (d != 0)) { - return Math.PI / 2; - } - if ((a != 0) && (d != 0)) { - return Math.PI; - } - return Double.NaN; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/OrientationInterpolation.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/OrientationInterpolation.java deleted file mode 100644 index e761e7cf..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/OrientationInterpolation.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim; - -/** - * We observe this table during gameplay but I haven't found it anywhere in the - * data yet. So, I'm making my own. - */ -public enum OrientationInterpolation { - OI0(0.07f, 0.2f, 999f), - OI1(0.03f, 0.1f, 0.04f), - OI2(0.015f, 1.0f, 999), - OI3(0.005f, 0.1f, 0.0043f), - OI4(0.04f, 0.15f, 0.01f), - OI5(0.05f, 0.18f, 0.015f), - OI6(0.1f, 0.3f, 0.1f), - OI7(0.003f, 0.08f, 0.0027f), - OI8(0.001f, 0.05f, 0.001f); - - public static OrientationInterpolation[] VALUES = values(); - - private float startingAcceleration; - private float maxVelocity; - private float endingNegativeAcceleration; - private float endingAccelCutoff; - private float startingAccelCutoff; - - private OrientationInterpolation(final float startingAcceleration, final float maxVelocity, - final float endingNegativeAcceleration) { - this.startingAcceleration = startingAcceleration; - this.maxVelocity = maxVelocity; - this.endingNegativeAcceleration = endingNegativeAcceleration; - this.endingAccelCutoff = endingAccelCutoff(maxVelocity, endingNegativeAcceleration); - this.startingAccelCutoff = endingAccelCutoff(maxVelocity, startingAcceleration); - } - - public float getStartingAcceleration() { - return this.startingAcceleration; - } - - public float getMaxVelocity() { - return this.maxVelocity; - } - - public float getEndingNegativeAcceleration() { - return this.endingNegativeAcceleration; - } - - public float getEndingAccelCutoff() { - return this.endingAccelCutoff; - } - - public float getStartingAccelCutoff() { - return this.startingAccelCutoff; - } - - private static float endingAccelCutoff(final float maxVelocity, final float endingAccel) { - final float endingAccelFinishingTime = maxVelocity / endingAccel; - final float endingDistanceRequired = (maxVelocity * endingAccelFinishingTime) - - ((endingAccel / 2) * (endingAccelFinishingTime * endingAccelFinishingTime)); - return endingDistanceRequired; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderAttackInstant.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderAttackInstant.java deleted file mode 100644 index 31296906..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderAttackInstant.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim; - -import java.util.List; - -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.mdx.Sequence; -import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.IndexedSequence; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; - -public class RenderAttackInstant implements RenderEffect { - private final MdxComplexInstance modelInstance; - - public RenderAttackInstant(final MdxComplexInstance modelInstance, final War3MapViewer war3MapViewer, - final float yaw) { - this.modelInstance = modelInstance; - final MdxModel model = (MdxModel) this.modelInstance.model; - final List sequences = model.getSequences(); - final IndexedSequence sequence = SequenceUtils.selectSequence(PrimaryTag.DEATH, SequenceUtils.EMPTY, sequences, - true); - if ((sequence != null) && (sequence.index != -1)) { - this.modelInstance.setSequenceLoopMode(SequenceLoopMode.NEVER_LOOP); - this.modelInstance.setSequence(sequence.index); - } - this.modelInstance.localRotation.setFromAxisRad(0, 0, 1, yaw); - } - - @Override - public boolean updateAnimations(final War3MapViewer war3MapViewer, final float deltaTime) { - - final boolean everythingDone = this.modelInstance.sequenceEnded; - if (everythingDone) { - war3MapViewer.worldScene.removeInstance(this.modelInstance); - } - return everythingDone; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderAttackProjectile.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderAttackProjectile.java deleted file mode 100644 index 4731aafe..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderAttackProjectile.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim; - -import java.util.List; - -import com.badlogic.gdx.math.Quaternion; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.mdx.Sequence; -import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.IndexedSequence; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetWidgetVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CWeaponType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.projectile.CAttackProjectile; - -public class RenderAttackProjectile implements RenderEffect { - private static final Quaternion pitchHeap = new Quaternion(); - - private final CAttackProjectile simulationProjectile; - private final MdxComplexInstance modelInstance; - private float x; - private float y; - private float z; - private final float startingHeight; - private final float arcPeakHeight; - private float totalTravelDistance; - - private final float targetHeight; - - private float yaw; - - private float pitch; - private boolean done = false; - private float deathTimeElapsed; - - public RenderAttackProjectile(final CAttackProjectile simulationProjectile, final MdxComplexInstance modelInstance, - final float z, final float arc, final War3MapViewer war3MapViewer) { - this.simulationProjectile = simulationProjectile; - this.modelInstance = modelInstance; - this.x = simulationProjectile.getX(); - this.y = simulationProjectile.getY(); - this.z = z; - this.startingHeight = z; - final float targetX = this.simulationProjectile.getTarget().getX(); - final float targetY = this.simulationProjectile.getTarget().getY(); - final float dxToTarget = targetX - this.x; - final float dyToTarget = targetY - this.y; - final float d2DToTarget = (float) StrictMath.sqrt((dxToTarget * dxToTarget) + (dyToTarget * dyToTarget)); - final float startingDistance = d2DToTarget + this.totalTravelDistance; - final CWidget widgetTarget = this.simulationProjectile.getTarget().visit(AbilityTargetWidgetVisitor.INSTANCE); - float impactZ; - float flyHeight; - if ((simulationProjectile.getUnitAttack().getWeaponType() == CWeaponType.ARTILLERY) || (widgetTarget == null)) { - impactZ = 0; - flyHeight = 0; - } - else { - impactZ = widgetTarget.getImpactZ(); - flyHeight = widgetTarget.getFlyHeight(); - } - this.targetHeight = (war3MapViewer.terrain.getGroundHeight(targetX, targetY) + flyHeight + impactZ); - this.arcPeakHeight = arc * startingDistance; - this.yaw = (float) StrictMath.atan2(dyToTarget, dxToTarget); - } - - @Override - public boolean updateAnimations(final War3MapViewer war3MapViewer, final float deltaTime) { - final boolean wasDone = this.done; - if (this.done = this.simulationProjectile.isDone()) { - final MdxModel model = (MdxModel) this.modelInstance.model; - final List sequences = model.getSequences(); - final IndexedSequence sequence = SequenceUtils.selectSequence(PrimaryTag.DEATH, SequenceUtils.EMPTY, - sequences, true); - if ((sequence != null) && this.done && !wasDone) { - this.modelInstance.setSequenceLoopMode(SequenceLoopMode.NEVER_LOOP); - this.modelInstance.setSequence(sequence.index); - } - } - else { - if (this.modelInstance.sequenceEnded || (this.modelInstance.sequence == -1)) { - SequenceUtils.randomStandSequence(this.modelInstance); - } - } - final float simX = this.simulationProjectile.getX(); - final float simY = this.simulationProjectile.getY(); - final float simDx = simX - this.x; - final float simDy = simY - this.y; - final float simD = (float) StrictMath.sqrt((simDx * simDx) + (simDy * simDy)); - final float speed = StrictMath.min(simD, this.simulationProjectile.getSpeed() * deltaTime); - if (simD > 0) { - this.x = this.x + ((speed * simDx) / simD); - this.y = this.y + ((speed * simDy) / simD); - final float targetX = this.simulationProjectile.getTargetX(); - final float targetY = this.simulationProjectile.getTargetY(); - final float dxToTarget = targetX - this.x; - final float dyToTarget = targetY - this.y; - final float d2DToTarget = (float) StrictMath.sqrt((dxToTarget * dxToTarget) + (dyToTarget * dyToTarget)); - final float startingDistance = d2DToTarget + this.totalTravelDistance; - final float halfStartingDistance = startingDistance / 2f; - - final float dtsz = this.targetHeight - this.startingHeight; - final float d1z = dtsz / (halfStartingDistance * 2); - this.totalTravelDistance += speed; - final float dz = d1z * this.totalTravelDistance; - - final float distanceToPeak = this.totalTravelDistance - halfStartingDistance; - final float normPeakDist = distanceToPeak / halfStartingDistance; - final float currentHeightPercentage = 1 - (normPeakDist * normPeakDist); - final float arcCurrentHeight = currentHeightPercentage * this.arcPeakHeight; - this.z = this.startingHeight + dz + arcCurrentHeight; - - if (!this.done) { - this.yaw = (float) StrictMath.atan2(dyToTarget, dxToTarget); - - final float slope = (-2 * (normPeakDist) * this.arcPeakHeight) / halfStartingDistance; - this.pitch = (float) StrictMath.atan2(slope + d1z, 1); - } - } - if (this.done) { - this.pitch = 0; - this.deathTimeElapsed += deltaTime; - } - - this.modelInstance.setLocation(this.x, this.y, this.z); - this.modelInstance.localRotation.setFromAxisRad(0, 0, 1, this.yaw); - this.modelInstance.rotate(pitchHeap.setFromAxisRad(0, -1, 0, this.pitch)); - war3MapViewer.worldScene.instanceMoved(this.modelInstance, this.x, this.y); - - final boolean everythingDone = this.simulationProjectile.isDone() && (this.modelInstance.sequenceEnded - || (this.deathTimeElapsed >= war3MapViewer.simulation.getGameplayConstants().getBulletDeathTime())); - if (everythingDone) { - war3MapViewer.worldScene.removeInstance(this.modelInstance); - } - return everythingDone; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDestructable.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDestructable.java deleted file mode 100644 index d6468178..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDestructable.java +++ /dev/null @@ -1,190 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.math.Rectangle; -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.units.manager.MutableObjectData.WorldEditorDataType; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.SplatModel.SplatMover; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.BuildingShadow; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; - -public class RenderDestructable extends RenderDoodad implements RenderWidget { - private static final War3ID TEX_FILE = War3ID.fromString("btxf"); - private static final War3ID TEX_ID = War3ID.fromString("btxi"); - private static final War3ID SEL_CIRCLE_SIZE = War3ID.fromString("bgsc"); - - private float life; - public Rectangle walkableBounds; - private final CDestructable simulationDestructable; - private SplatMover selectionCircle; - private SplatMover selectionPreviewHighlight; - private final UnitAnimationListenerImpl unitAnimationListenerImpl; - private boolean dead; - private BuildingShadow destructableShadow; - private final boolean selectable; - private boolean blighted = false; - private final int replaceableTextureId; - private String replaceableTextureFile; - - public RenderDestructable(final War3MapViewer map, final MdxModel model, final MutableGameObject row, - final com.etheller.warsmash.parsers.w3x.doo.Doodad doodad, final WorldEditorDataType type, - final float maxPitch, final float maxRoll, final float life, final BuildingShadow destructableShadow, - final CDestructable simulationDestructable) { - super(map, model, row, doodad, type, maxPitch, maxRoll); - this.life = simulationDestructable.getLife(); - this.destructableShadow = destructableShadow; - this.simulationDestructable = simulationDestructable; - this.replaceableTextureFile = row.getFieldAsString(TEX_FILE, 0); - this.replaceableTextureId = row.getFieldAsInteger(TEX_ID, 0); - if ((this.replaceableTextureFile != null) && (this.replaceableTextureFile.length() > 1)) { - final int dotIndex = this.replaceableTextureFile.lastIndexOf('.'); - if (dotIndex != -1) { - this.replaceableTextureFile = this.replaceableTextureFile.substring(0, dotIndex); - } - if (simulationDestructable.isBlighted()) { - this.blighted = true; - this.replaceableTextureFile += "Blight"; - } - this.instance.setReplaceableTexture(this.replaceableTextureId, this.replaceableTextureFile + ".blp"); - } - this.selectionScale *= row.getFieldAsFloat(SEL_CIRCLE_SIZE, 0); - this.unitAnimationListenerImpl = new UnitAnimationListenerImpl((MdxComplexInstance) this.instance, 0, 0); - simulationDestructable.setUnitAnimationListener(this.unitAnimationListenerImpl); - this.unitAnimationListenerImpl.playAnimation(true, getAnimation(), SequenceUtils.EMPTY, 1.0f, true); - this.selectable = row.readSLKTagBoolean("selectable"); - } - - @Override - public PrimaryTag getAnimation() { - if (this.life <= 0) { - return PrimaryTag.DEATH; - } - return super.getAnimation(); - } - - @Override - public MdxComplexInstance getInstance() { - return (MdxComplexInstance) this.instance; - } - - @Override - public CWidget getSimulationWidget() { - return this.simulationDestructable; - } - - @Override - public void updateAnimations(final War3MapViewer war3MapViewer) { - // TODO maybe move getAnimation behaviors to here and make this thing not a - // doodad - - final boolean dead = this.simulationDestructable.isDead(); - if (dead && !this.dead) { - this.unitAnimationListenerImpl.playAnimation(true, PrimaryTag.DEATH, SequenceUtils.EMPTY, 1.0f, true); - if (this.destructableShadow != null) { - this.destructableShadow.remove(); - this.destructableShadow = null; - } - if (this.selectionCircle != null) { - this.selectionCircle.destroy(Gdx.gl30, war3MapViewer.terrain.centerOffset); - this.selectionCircle = null; - } - if (this.selectionPreviewHighlight != null) { - this.selectionPreviewHighlight.destroy(Gdx.gl30, war3MapViewer.terrain.centerOffset); - this.selectionPreviewHighlight = null; - } - } - else if (!dead) { - if (this.dead) { - this.unitAnimationListenerImpl.playAnimation(true, PrimaryTag.BIRTH, SequenceUtils.EMPTY, 1.0f, true); - // TODO add back shadow here - - } - else { - if (Math.abs(this.life - this.simulationDestructable.getLife()) > 0.003f) { - if (this.life > this.simulationDestructable.getLife()) { - this.unitAnimationListenerImpl.playAnimation(true, PrimaryTag.STAND, SequenceUtils.HIT, 1.0f, - true); - } - this.life = this.simulationDestructable.getLife(); - } - } - } - this.dead = dead; - final boolean blighted = this.simulationDestructable.isBlighted(); - if (blighted && !this.blighted) { - this.blighted = blighted; - if (this.replaceableTextureFile != null) { - this.replaceableTextureFile += "Blight"; - } - this.instance.setReplaceableTexture(this.replaceableTextureId, this.replaceableTextureFile + ".blp"); - } - this.unitAnimationListenerImpl.update(); - } - - @Override - public boolean isIntersectedOnMeshAlways() { - return false; - } - - @Override - public float getSelectionScale() { - return this.selectionScale; - } - - @Override - public float getX() { - return this.x; - } - - @Override - public float getY() { - return this.y; - } - - @Override - public float getZ() { - return this.instance.localLocation.z; - } - - @Override - public void unassignSelectionCircle() { - this.selectionCircle = null; - } - - @Override - public void assignSelectionCircle(final SplatMover selectionCircle) { - this.selectionCircle = selectionCircle; - } - - @Override - public void unassignSelectionPreviewHighlight() { - this.selectionPreviewHighlight = null; - } - - @Override - public void assignSelectionPreviewHighlight(final SplatMover t) { - this.selectionPreviewHighlight = t; - } - - @Override - public boolean isSelectable() { - return this.selectable; - } - - @Override - public SplatMover getSelectionPreviewHighlight() { - return this.selectionPreviewHighlight; - } - - @Override - public SplatMover getSelectionCircle() { - return this.selectionCircle; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDoodad.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDoodad.java deleted file mode 100644 index 2ce6b6e8..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderDoodad.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim; - -import com.badlogic.gdx.math.Quaternion; -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.units.manager.MutableObjectData.WorldEditorDataType; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.viewer5.ModelInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; - -public class RenderDoodad { - private static final int SAMPLE_RADIUS = 4; - private static final float[] VERTEX_COLOR_BLACK = { 0f, 0f, 0f, 1f }; - public final ModelInstance instance; - private final MutableGameObject row; - private final float maxPitch; - private final float maxRoll; - protected float x; - protected float y; - protected float selectionScale; - - public RenderDoodad(final War3MapViewer map, final MdxModel model, final MutableGameObject row, - final com.etheller.warsmash.parsers.w3x.doo.Doodad doodad, final WorldEditorDataType type, - final float maxPitch, final float maxRoll) { - this.maxPitch = maxPitch; - this.maxRoll = maxRoll; - final boolean isSimple = row.readSLKTagBoolean("lightweight"); - ModelInstance instance; - - if (isSimple && false) { - instance = model.addInstance(1); - } - else { - instance = model.addInstance(); - ((MdxComplexInstance) instance).setSequenceLoopMode(SequenceLoopMode.NEVER_LOOP); - } - - instance.move(doodad.getLocation()); - // TODO: the following pitch/roll system is a heuristic, and we probably want to - // revisit it later. - // Specifically, I was pretty convinced that whichever is applied first - // (pitch/roll) should be used to do a projection onto the already-tilted plane - // to find the angle used for the other of the two - // (instead of measuring down from an imaginary flat ground plane, as we do - // currently). - final float facingRadians = doodad.getAngle(); - float pitch, roll; - this.x = doodad.getLocation()[0]; - this.y = doodad.getLocation()[1]; - { - if (!map.terrain.inPlayableArea(this.x, this.y)) { - ((MdxComplexInstance) instance).setVertexColor(VERTEX_COLOR_BLACK); - } - } - final float pitchSampleForwardX = this.x + (SAMPLE_RADIUS * (float) Math.cos(facingRadians)); - final float pitchSampleForwardY = this.y + (SAMPLE_RADIUS * (float) Math.sin(facingRadians)); - final float pitchSampleBackwardX = this.x - (SAMPLE_RADIUS * (float) Math.cos(facingRadians)); - final float pitchSampleBackwardY = this.y - (SAMPLE_RADIUS * (float) Math.sin(facingRadians)); - final float pitchSampleGroundHeight1 = map.terrain.getGroundHeight(pitchSampleBackwardX, pitchSampleBackwardY); - final float pitchSampleGorundHeight2 = map.terrain.getGroundHeight(pitchSampleForwardX, pitchSampleForwardY); - pitch = Math.max(-maxPitch, Math.min(maxPitch, - (float) Math.atan2(pitchSampleGorundHeight2 - pitchSampleGroundHeight1, SAMPLE_RADIUS * 2))); - final double leftOfFacingAngle = facingRadians + (Math.PI / 2); - final float rollSampleForwardX = this.x + (SAMPLE_RADIUS * (float) Math.cos(leftOfFacingAngle)); - final float rollSampleForwardY = this.y + (SAMPLE_RADIUS * (float) Math.sin(leftOfFacingAngle)); - final float rollSampleBackwardX = this.x - (SAMPLE_RADIUS * (float) Math.cos(leftOfFacingAngle)); - final float rollSampleBackwardY = this.y - (SAMPLE_RADIUS * (float) Math.sin(leftOfFacingAngle)); - final float rollSampleGroundHeight1 = map.terrain.getGroundHeight(rollSampleBackwardX, rollSampleBackwardY); - final float rollSampleGroundHeight2 = map.terrain.getGroundHeight(rollSampleForwardX, rollSampleForwardY); - roll = Math.max(-maxRoll, Math.min(maxRoll, - (float) Math.atan2(rollSampleGroundHeight2 - rollSampleGroundHeight1, SAMPLE_RADIUS * 2))); - instance.rotate(new Quaternion().setFromAxisRad(RenderMathUtils.VEC3_UNIT_Z, facingRadians)); - instance.rotate(new Quaternion().setFromAxisRad(RenderMathUtils.VEC3_UNIT_Y, -pitch)); - instance.rotate(new Quaternion().setFromAxisRad(RenderMathUtils.VEC3_UNIT_X, roll)); -// instance.rotate(new Quaternion().setEulerAnglesRad(facingRadians, 0, 0)); - final float[] scale = doodad.getScale(); - instance.scale(scale); - if (type == WorldEditorDataType.DOODADS) { - final float defScale = row.readSLKTagFloat("defScale"); - instance.uniformScale(defScale); - this.selectionScale = defScale; - } - else { - this.selectionScale = (float) Math.sqrt((scale[0]) * (scale[1]) * (scale[2])); - } - instance.setScene(map.worldScene); - - this.instance = instance; - this.row = row; - } - - public PrimaryTag getAnimation() { - return PrimaryTag.STAND; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderEffect.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderEffect.java deleted file mode 100644 index 653b006e..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderEffect.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim; - -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; - -public interface RenderEffect { - boolean updateAnimations(final War3MapViewer war3MapViewer, float deltaTime); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderItem.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderItem.java deleted file mode 100644 index 626f3db6..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderItem.java +++ /dev/null @@ -1,205 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim; - -import com.badlogic.gdx.math.Quaternion; -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.SplatModel.SplatMover; -import com.etheller.warsmash.viewer5.handlers.w3x.UnitSoundset; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; - -public class RenderItem implements RenderWidget { - private static final War3ID ITEM_MODEL_SCALE = War3ID.fromString("isca"); - private static final War3ID ITEM_RED = War3ID.fromString("iclr"); - private static final War3ID ITEM_GREEN = War3ID.fromString("iclg"); - private static final War3ID ITEM_BLUE = War3ID.fromString("iclb"); - private final CItem simulationItem; - public final MdxComplexInstance instance; - public final MutableGameObject row; - public final float[] location = new float[3]; - public float radius; - public UnitSoundset soundset; - public final MdxModel portraitModel; - public SplatMover shadow; - public SplatMover selectionCircle; - public SplatMover selectionPreviewHighlight; - private boolean hidden; - private boolean dead; - - public RenderItem(final War3MapViewer map, final MdxModel model, final MutableGameObject row, final float x, - final float y, final float z, final float angle, final UnitSoundset soundset, final MdxModel portraitModel, - final CItem simulationItem) { - this.portraitModel = portraitModel; - this.simulationItem = simulationItem; - final MdxComplexInstance instance = (MdxComplexInstance) model.addInstance(); - - this.location[0] = x; - this.location[1] = y; - this.location[2] = z; - instance.move(this.location); -// instance.localRotation.setFromAxisRad(RenderMathUtils.VEC3_UNIT_Z, angle); - instance.rotate(new Quaternion().setFromAxisRad(RenderMathUtils.VEC3_UNIT_Z, angle)); - instance.setScene(map.worldScene); - - if (row != null) { - War3ID red; - War3ID green; - War3ID blue; - War3ID scale; - scale = ITEM_MODEL_SCALE; - red = ITEM_RED; - green = ITEM_GREEN; - blue = ITEM_BLUE; - instance.setVertexColor(new float[] { (row.getFieldAsInteger(red, 0)) / 255f, - (row.getFieldAsInteger(green, 0)) / 255f, (row.getFieldAsInteger(blue, 0)) / 255f }); - instance.uniformScale(row.getFieldAsFloat(scale, 0)); - - this.radius = 1 * 36; - } - - this.instance = instance; - this.row = row; - this.soundset = soundset; - } - - @Override - public MdxComplexInstance getInstance() { - return this.instance; - } - - @Override - public CWidget getSimulationWidget() { - return this.simulationItem; - } - - @Override - public void updateAnimations(final War3MapViewer map) { - final boolean hidden = this.simulationItem.isHidden(); - if (hidden != this.hidden) { - this.hidden = hidden; - if (hidden) { - this.instance.hide(); - if (this.shadow != null) { - this.shadow.hide(); - } - } - else { - this.instance.show(); - if (this.shadow != null) { - this.shadow.show(map.terrain.centerOffset); - } - } - } - final boolean dead = this.simulationItem.isDead(); - final MdxComplexInstance mdxComplexInstance = this.instance; - if (dead) { - if (!this.dead) { - this.dead = dead; - SequenceUtils.randomDeathSequence(mdxComplexInstance); - } - } - else if (mdxComplexInstance.sequenceEnded || (mdxComplexInstance.sequence == -1)) { - SequenceUtils.randomStandSequence(mdxComplexInstance); - } - - final float prevX = this.location[0]; - final float prevY = this.location[1]; - final float simulationX = this.simulationItem.getX(); - final float simulationY = this.simulationItem.getY(); - final float simDx = simulationX - this.location[0]; - final float simDy = simulationY - this.location[1]; - this.location[0] = simulationX; - this.location[1] = simulationY; - final float dx = this.location[0] - prevX; - final float dy = this.location[1] - prevY; - final float groundHeight; - // land units will have their feet pass under the surface of the water, so items - // here are in the same place - final float groundHeightTerrainAndWater = map.terrain.getGroundHeight(this.location[0], this.location[1]); - MdxComplexInstance currentWalkableUnder; - currentWalkableUnder = map.getHighestWalkableUnder(this.location[0], this.location[1]); - War3MapViewer.gdxRayHeap.set(this.location[0], this.location[1], 4096, 0, 0, -8192); - if ((currentWalkableUnder != null) - && currentWalkableUnder.intersectRayWithCollision(War3MapViewer.gdxRayHeap, - War3MapViewer.intersectionHeap, true, true) - && (War3MapViewer.intersectionHeap.z > groundHeightTerrainAndWater)) { - groundHeight = War3MapViewer.intersectionHeap.z; - } - else { - groundHeight = groundHeightTerrainAndWater; - currentWalkableUnder = null; - } - this.location[2] = this.simulationItem.getFlyHeight() + groundHeight; - - this.instance.moveTo(this.location); - if ((this.shadow != null) && !hidden) { - this.shadow.move(dx, dy, map.terrain.centerOffset); - this.shadow.setHeightAbsolute(currentWalkableUnder != null, groundHeight + map.imageWalkableZOffset); - } - } - - @Override - public boolean isIntersectedOnMeshAlways() { - return false; - } - - @Override - public float getSelectionScale() { - return 1.0f; - } - - @Override - public float getX() { - return this.location[0]; - } - - @Override - public float getY() { - return this.location[1]; - } - - @Override - public float getZ() { - return this.location[2]; - } - - @Override - public void unassignSelectionCircle() { - this.selectionCircle = null; - } - - @Override - public void assignSelectionCircle(final SplatMover t) { - this.selectionCircle = t; - } - - @Override - public void unassignSelectionPreviewHighlight() { - this.selectionPreviewHighlight = null; - } - - @Override - public void assignSelectionPreviewHighlight(final SplatMover t) { - this.selectionPreviewHighlight = t; - } - - @Override - public boolean isSelectable() { - return true; - } - - @Override - public SplatMover getSelectionPreviewHighlight() { - return this.selectionPreviewHighlight; - } - - @Override - public SplatMover getSelectionCircle() { - return this.selectionCircle; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnit.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnit.java deleted file mode 100644 index 77d022b2..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnit.java +++ /dev/null @@ -1,566 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim; - -import java.util.EnumSet; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.math.Quaternion; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.SecondaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.SplatModel.SplatMover; -import com.etheller.warsmash.viewer5.handlers.w3x.UnitSoundset; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.BuildingShadow; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.MovementType; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.AbilityDataUI; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.commandbuttons.CommandButtonListener; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.commandbuttons.CommandCardPopulatingAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; - -public class RenderUnit implements RenderWidget { - public static final Quaternion tempQuat = new Quaternion(); - private static final War3ID RED = War3ID.fromString("uclr"); - private static final War3ID GREEN = War3ID.fromString("uclg"); - private static final War3ID BLUE = War3ID.fromString("uclb"); - private static final War3ID MOVE_HEIGHT = War3ID.fromString("umvh"); - private static final War3ID ORIENTATION_INTERPOLATION = War3ID.fromString("uori"); - private static final War3ID ANIM_PROPS = War3ID.fromString("uani"); - private static final War3ID BLEND_TIME = War3ID.fromString("uble"); - private static final War3ID BUILD_SOUND_LABEL = War3ID.fromString("ubsl"); - private static final War3ID UNIT_SELECT_HEIGHT = War3ID.fromString("uslz"); - private static final float[] heapZ = new float[3]; - public final MdxComplexInstance instance; - public final MutableGameObject row; - public final float[] location = new float[3]; - public float selectionScale; - public UnitSoundset soundset; - public final MdxModel portraitModel; - public int playerIndex; - private final CUnit simulationUnit; - public SplatMover shadow; - private BuildingShadow buildingShadowInstance; - public SplatMover selectionCircle; - public SplatMover selectionPreviewHighlight; - - private float facing; - - private boolean swimming; - private boolean working; - - private boolean dead = false; - - private final UnitAnimationListenerImpl unitAnimationListenerImpl; - private OrientationInterpolation orientationInterpolation; - private float currentTurnVelocity = 0; - public long lastUnitResponseEndTimeMillis; - private boolean corpse; - private boolean boneCorpse; - private final RenderUnitTypeData typeData; - public final MdxModel specialArtModel; - public SplatMover uberSplat; - private float selectionHeight; - private RenderUnit preferredSelectionReplacement; - - public RenderUnit(final War3MapViewer map, final MdxModel model, final MutableGameObject row, final float x, - final float y, final float z, final int playerIndex, final UnitSoundset soundset, - final MdxModel portraitModel, final CUnit simulationUnit, final RenderUnitTypeData typeData, - final MdxModel specialArtModel, final BuildingShadow buildingShadow, final float selectionCircleScaleFactor, - final float animationWalkSpeed, final float animationRunSpeed, final float scalingValue) { - this.portraitModel = portraitModel; - this.simulationUnit = simulationUnit; - this.typeData = typeData; - this.specialArtModel = specialArtModel; - this.buildingShadowInstance = buildingShadow; - final MdxComplexInstance instance = (MdxComplexInstance) model.addInstance(); - - this.location[0] = x; - this.location[1] = y; - this.location[2] = z; - instance.move(this.location); - this.facing = simulationUnit.getFacing(); - final float angle = (float) Math.toRadians(this.facing); -// instance.localRotation.setFromAxisRad(RenderMathUtils.VEC3_UNIT_Z, angle); - instance.rotate(tempQuat.setFromAxisRad(RenderMathUtils.VEC3_UNIT_Z, angle)); - this.playerIndex = playerIndex & 0xFFFF; - instance.setTeamColor(this.playerIndex); - instance.setScene(map.worldScene); - this.unitAnimationListenerImpl = new UnitAnimationListenerImpl(instance, animationWalkSpeed, animationRunSpeed); - simulationUnit.setUnitAnimationListener(this.unitAnimationListenerImpl); - final String requiredAnimationNames = row.getFieldAsString(ANIM_PROPS, 0); - TokenLoop: for (final String animationName : requiredAnimationNames.split(",")) { - final String upperCaseToken = animationName.toUpperCase(); - for (final SecondaryTag secondaryTag : SecondaryTag.values()) { - if (upperCaseToken.equals(secondaryTag.name())) { - this.unitAnimationListenerImpl.addSecondaryTag(secondaryTag); - continue TokenLoop; - } - } - } - - if (row != null) { - heapZ[2] = simulationUnit.getFlyHeight(); - this.location[2] += heapZ[2]; - - instance.move(heapZ); - War3ID red; - War3ID green; - War3ID blue; - red = RED; - green = GREEN; - blue = BLUE; - instance.setVertexColor(new float[] { (row.getFieldAsInteger(red, 0)) / 255f, - (row.getFieldAsInteger(green, 0)) / 255f, (row.getFieldAsInteger(blue, 0)) / 255f }); - instance.uniformScale(scalingValue); - - this.selectionScale = row.getFieldAsFloat(War3MapViewer.UNIT_SELECT_SCALE, 0) * selectionCircleScaleFactor; - this.selectionHeight = row.getFieldAsFloat(UNIT_SELECT_HEIGHT, 0); - int orientationInterpolationOrdinal = row.getFieldAsInteger(ORIENTATION_INTERPOLATION, 0); - if ((orientationInterpolationOrdinal < 0) - || (orientationInterpolationOrdinal >= OrientationInterpolation.VALUES.length)) { - orientationInterpolationOrdinal = 0; - } - this.orientationInterpolation = OrientationInterpolation.VALUES[orientationInterpolationOrdinal]; - - final float blendTime = row.getFieldAsFloat(BLEND_TIME, 0); - instance.setBlendTime(blendTime * 1000.0f); - } - - this.instance = instance; - this.row = row; - this.soundset = soundset; - - } - - public void populateCommandCard(final CSimulation game, final GameUI gameUI, - final CommandButtonListener commandButtonListener, final AbilityDataUI abilityDataUI, - final int subMenuOrderId, final boolean multiSelect) { - final CommandCardPopulatingAbilityVisitor commandCardPopulatingVisitor = CommandCardPopulatingAbilityVisitor.INSTANCE - .reset(game, gameUI, this.simulationUnit, commandButtonListener, abilityDataUI, subMenuOrderId, - multiSelect); - for (final CAbility ability : this.simulationUnit.getAbilities()) { - ability.visit(commandCardPopulatingVisitor); - } - } - - @Override - public void updateAnimations(final War3MapViewer map) { - final boolean wasHidden = this.instance.hidden(); - if (this.simulationUnit.isHidden()) { - if (!wasHidden) { - if (this.selectionCircle != null) { - this.selectionCircle.hide(); - } - if (this.selectionPreviewHighlight != null) { - this.selectionPreviewHighlight.hide(); - } - if (this.shadow != null) { - this.shadow.hide(); - } - } - this.instance.hide(); - return; - } - else { - this.instance.show(); - if (wasHidden) { - if (this.selectionCircle != null) { - this.selectionCircle.show(map.terrain.centerOffset); - } - if (this.selectionPreviewHighlight != null) { - this.selectionPreviewHighlight.show(map.terrain.centerOffset); - } - if (this.shadow != null) { - this.shadow.show(map.terrain.centerOffset); - } - } - } - final float prevX = this.location[0]; - final float prevY = this.location[1]; - final float simulationX = this.simulationUnit.getX(); - final float simulationY = this.simulationUnit.getY(); - final float deltaTime = Gdx.graphics.getDeltaTime(); - final float simDx = simulationX - this.location[0]; - final float simDy = simulationY - this.location[1]; - final float distanceToSimulation = (float) Math.sqrt((simDx * simDx) + (simDy * simDy)); - final int speed = this.simulationUnit.getSpeed(); - final float speedDelta = speed * deltaTime; - if ((distanceToSimulation > speedDelta) && (deltaTime < 1.0)) { - // The 1.0 here says that after 1 second of lag, units just teleport to show - // where they actually are - this.location[0] += (speedDelta * simDx) / distanceToSimulation; - this.location[1] += (speedDelta * simDy) / distanceToSimulation; - } - else { - this.location[0] = simulationX; - this.location[1] = simulationY; - } - final float dx = this.location[0] - prevX; - final float dy = this.location[1] - prevY; - final float groundHeight; - final MovementType movementType = this.simulationUnit.getUnitType().getMovementType(); - final short terrainPathing = map.terrain.pathingGrid.getPathing(this.location[0], this.location[1]); - boolean swimming = (movementType == MovementType.AMPHIBIOUS) - && PathingGrid.isPathingFlag(terrainPathing, PathingGrid.PathingType.SWIMMABLE) - && !PathingGrid.isPathingFlag(terrainPathing, PathingGrid.PathingType.WALKABLE); - final boolean working = this.simulationUnit.getBuildQueueTypes()[0] != null; - final float groundHeightTerrain = map.terrain.getGroundHeight(this.location[0], this.location[1]); - float groundHeightTerrainAndWater; - MdxComplexInstance currentWalkableUnder; - final boolean standingOnWater = (swimming) || (movementType == MovementType.FLOAT) - || (movementType == MovementType.FLY) || (movementType == MovementType.HOVER); - if (standingOnWater) { - groundHeightTerrainAndWater = Math.max(groundHeightTerrain, - map.terrain.getWaterHeight(this.location[0], this.location[1])); - } - else { - // land units will have their feet pass under the surface of the water - groundHeightTerrainAndWater = groundHeightTerrain; - } - if (movementType == MovementType.FLOAT) { - // boats cant go on bridges - groundHeight = groundHeightTerrainAndWater; - currentWalkableUnder = null; - } - else { - currentWalkableUnder = map.getHighestWalkableUnder(this.location[0], this.location[1]); - War3MapViewer.gdxRayHeap.set(this.location[0], this.location[1], 4096, 0, 0, -8192); - if ((currentWalkableUnder != null) - && currentWalkableUnder.intersectRayWithCollision(War3MapViewer.gdxRayHeap, - War3MapViewer.intersectionHeap, true, true) - && (War3MapViewer.intersectionHeap.z > groundHeightTerrainAndWater)) { - groundHeight = War3MapViewer.intersectionHeap.z; - swimming = false; // Naga Royal Guard should slither across a bridge, not swim in rock - } - else { - groundHeight = groundHeightTerrainAndWater; - currentWalkableUnder = null; - } - } - if (swimming && !this.swimming) { - this.unitAnimationListenerImpl.addSecondaryTag(AnimationTokens.SecondaryTag.SWIM); - } - else if (!swimming && this.swimming) { - this.unitAnimationListenerImpl.removeSecondaryTag(AnimationTokens.SecondaryTag.SWIM); - } - if (working && !this.working) { - this.unitAnimationListenerImpl.addSecondaryTag(AnimationTokens.SecondaryTag.WORK); - } - else if (!working && this.working) { - this.unitAnimationListenerImpl.removeSecondaryTag(AnimationTokens.SecondaryTag.WORK); - } - this.swimming = swimming; - this.working = working; - final boolean dead = this.simulationUnit.isDead(); - final boolean corpse = this.simulationUnit.isCorpse(); - final boolean boneCorpse = this.simulationUnit.isBoneCorpse(); - if (dead && !this.dead) { - this.unitAnimationListenerImpl.playAnimation(true, PrimaryTag.DEATH, SequenceUtils.EMPTY, 1.0f, true); - removeSplats(map); - } - if (boneCorpse && !this.boneCorpse) { - if (this.simulationUnit.getUnitType().isHero()) { - this.unitAnimationListenerImpl.playAnimationWithDuration(true, PrimaryTag.DISSIPATE, - SequenceUtils.EMPTY, this.simulationUnit.getEndingDecayTime(map.simulation), true); - } - else { - this.unitAnimationListenerImpl.playAnimationWithDuration(true, PrimaryTag.DECAY, SequenceUtils.BONE, - this.simulationUnit.getEndingDecayTime(map.simulation), true); - } - } - else if (corpse && !this.corpse) { - this.unitAnimationListenerImpl.playAnimationWithDuration(true, PrimaryTag.DECAY, SequenceUtils.FLESH, - map.simulation.getGameplayConstants().getDecayTime(), true); - } - this.dead = dead; - this.corpse = corpse; - this.boneCorpse = boneCorpse; - this.location[2] = this.simulationUnit.getFlyHeight() + groundHeight; - final float selectionCircleHeight = this.selectionHeight + groundHeight; - this.instance.moveTo(this.location); - float simulationFacing = this.simulationUnit.getFacing(); - if (simulationFacing < 0) { - simulationFacing += 360; - } - float renderFacing = this.facing; - if (renderFacing < 0) { - renderFacing += 360; - } - float facingDelta = simulationFacing - renderFacing; - if (facingDelta < -180) { - facingDelta = 360 + facingDelta; - } - if (facingDelta > 180) { - facingDelta = -360 + facingDelta; - } - final float absoluteFacingDelta = Math.abs(facingDelta); - final float turningSign = Math.signum(facingDelta); - - final float absoluteFacingDeltaRadians = (float) Math.toRadians(absoluteFacingDelta); - float acceleration; - final boolean endPhase = (absoluteFacingDeltaRadians <= this.orientationInterpolation.getEndingAccelCutoff()) - && ((this.currentTurnVelocity * turningSign) > 0); - if (endPhase) { - this.currentTurnVelocity = (1 - - ((this.orientationInterpolation.getEndingAccelCutoff() - absoluteFacingDeltaRadians) - / this.orientationInterpolation.getEndingAccelCutoff())) - * (this.orientationInterpolation.getMaxVelocity()) * turningSign; - } - else { - acceleration = this.orientationInterpolation.getStartingAcceleration() * turningSign; - this.currentTurnVelocity = this.currentTurnVelocity + acceleration; - } - if ((this.currentTurnVelocity * turningSign) > this.orientationInterpolation.getMaxVelocity()) { - this.currentTurnVelocity = this.orientationInterpolation.getMaxVelocity() * turningSign; - } - float angleToAdd = (float) ((Math.toDegrees(this.currentTurnVelocity) * deltaTime) / 0.03f); - - if (absoluteFacingDelta < Math.abs(angleToAdd)) { - angleToAdd = facingDelta; - this.currentTurnVelocity = 0.0f; - } - this.facing = (((this.facing + angleToAdd) % 360) + 360) % 360; - this.instance.setLocalRotation(tempQuat.setFromAxis(RenderMathUtils.VEC3_UNIT_Z, this.facing)); - - final float facingRadians = (float) Math.toRadians(this.facing); - final float maxPitch = this.typeData.getMaxPitch(); - final float maxRoll = this.typeData.getMaxRoll(); - final float sampleRadius = this.typeData.getElevationSampleRadius(); - float pitch, roll; - final float pitchSampleForwardX = this.location[0] + (sampleRadius * (float) Math.cos(facingRadians)); - final float pitchSampleForwardY = this.location[1] + (sampleRadius * (float) Math.sin(facingRadians)); - final float pitchSampleBackwardX = this.location[0] - (sampleRadius * (float) Math.cos(facingRadians)); - final float pitchSampleBackwardY = this.location[1] - (sampleRadius * (float) Math.sin(facingRadians)); - final double leftOfFacingAngle = facingRadians + (Math.PI / 2); - final float rollSampleForwardX = this.location[0] + (sampleRadius * (float) Math.cos(leftOfFacingAngle)); - final float rollSampleForwardY = this.location[1] + (sampleRadius * (float) Math.sin(leftOfFacingAngle)); - final float rollSampleBackwardX = this.location[0] - (sampleRadius * (float) Math.cos(leftOfFacingAngle)); - final float rollSampleBackwardY = this.location[1] - (sampleRadius * (float) Math.sin(leftOfFacingAngle)); - final float pitchSampleGroundHeight1; - final float pitchSampleGroundHeight2; - final float rollSampleGroundHeight1; - final float rollSampleGroundHeight2; - if (currentWalkableUnder != null) { - pitchSampleGroundHeight1 = getGroundHeightSample(groundHeight, currentWalkableUnder, pitchSampleBackwardX, - pitchSampleBackwardY); - pitchSampleGroundHeight2 = getGroundHeightSample(groundHeight, currentWalkableUnder, pitchSampleForwardX, - pitchSampleForwardY); - rollSampleGroundHeight1 = getGroundHeightSample(groundHeight, currentWalkableUnder, rollSampleBackwardX, - rollSampleBackwardY); - rollSampleGroundHeight2 = getGroundHeightSample(groundHeight, currentWalkableUnder, rollSampleForwardX, - rollSampleForwardY); - } - else { - final float pitchGroundHeight1 = map.terrain.getGroundHeight(pitchSampleBackwardX, pitchSampleBackwardY); - final float pitchGroundHeight2 = map.terrain.getGroundHeight(pitchSampleForwardX, pitchSampleForwardY); - final float rollGroundHeight1 = map.terrain.getGroundHeight(rollSampleBackwardX, rollSampleBackwardY); - final float rollGroundHeight2 = map.terrain.getGroundHeight(rollSampleForwardX, rollSampleForwardY); - if (standingOnWater) { - pitchSampleGroundHeight1 = Math.max(pitchGroundHeight1, - map.terrain.getWaterHeight(pitchSampleBackwardX, pitchSampleBackwardY)); - pitchSampleGroundHeight2 = Math.max(pitchGroundHeight2, - map.terrain.getWaterHeight(pitchSampleForwardX, pitchSampleForwardY)); - rollSampleGroundHeight1 = Math.max(rollGroundHeight1, - map.terrain.getWaterHeight(rollSampleBackwardX, rollSampleBackwardY)); - rollSampleGroundHeight2 = Math.max(rollGroundHeight2, - map.terrain.getWaterHeight(rollSampleForwardX, rollSampleForwardY)); - } - else { - pitchSampleGroundHeight1 = pitchGroundHeight1; - pitchSampleGroundHeight2 = pitchGroundHeight2; - rollSampleGroundHeight1 = rollGroundHeight1; - rollSampleGroundHeight2 = rollGroundHeight2; - } - } - pitch = Math.max(-maxPitch, Math.min(maxPitch, - (float) Math.atan2(pitchSampleGroundHeight2 - pitchSampleGroundHeight1, sampleRadius * 2))); - roll = Math.max(-maxRoll, Math.min(maxRoll, - (float) Math.atan2(rollSampleGroundHeight2 - rollSampleGroundHeight1, sampleRadius * 2))); - this.instance.rotate(tempQuat.setFromAxisRad(RenderMathUtils.VEC3_UNIT_Y, -pitch)); - this.instance.rotate(tempQuat.setFromAxisRad(RenderMathUtils.VEC3_UNIT_X, roll)); - - map.worldScene.instanceMoved(this.instance, this.location[0], this.location[1]); - if (this.shadow != null) { - this.shadow.move(dx, dy, map.terrain.centerOffset); - this.shadow.setHeightAbsolute(currentWalkableUnder != null, groundHeight + map.imageWalkableZOffset); - } - if (this.selectionCircle != null) { - this.selectionCircle.move(dx, dy, map.terrain.centerOffset); - this.selectionCircle.setHeightAbsolute( - (currentWalkableUnder != null) - || ((movementType == MovementType.FLY) || (movementType == MovementType.HOVER)), - selectionCircleHeight + map.imageWalkableZOffset); - } - if (this.selectionPreviewHighlight != null) { - this.selectionPreviewHighlight.move(dx, dy, map.terrain.centerOffset); - this.selectionPreviewHighlight.setHeightAbsolute( - (currentWalkableUnder != null) - || ((movementType == MovementType.FLY) || (movementType == MovementType.HOVER)), - selectionCircleHeight + map.imageWalkableZOffset); - } - this.unitAnimationListenerImpl.update(); - if (!dead && this.simulationUnit.isConstructing()) { - this.instance.setFrameByRatio( - this.simulationUnit.getConstructionProgress() / this.simulationUnit.getUnitType().getBuildTime()); - } - } - - private void removeSplats(final War3MapViewer map) { - if (this.shadow != null) { - this.shadow.destroy(Gdx.gl30, map.terrain.centerOffset); - this.shadow = null; - } - if (this.buildingShadowInstance != null) { - this.buildingShadowInstance.remove(); - this.buildingShadowInstance = null; - } - if (this.uberSplat != null) { - this.uberSplat.destroy(Gdx.gl30, map.terrain.centerOffset); - this.uberSplat = null; - } - if (this.selectionCircle != null) { - this.selectionCircle.destroy(Gdx.gl30, map.terrain.centerOffset); - this.selectionCircle = null; - } - if (this.selectionPreviewHighlight != null) { - this.selectionPreviewHighlight.destroy(Gdx.gl30, map.terrain.centerOffset); - this.selectionPreviewHighlight = null; - } - } - - private float getGroundHeightSample(final float groundHeight, final MdxComplexInstance currentWalkableUnder, - final float sampleX, final float sampleY) { - final float sampleGroundHeight; - War3MapViewer.gdxRayHeap.origin.x = sampleX; - War3MapViewer.gdxRayHeap.origin.y = sampleY; - if (currentWalkableUnder.intersectRayWithCollision(War3MapViewer.gdxRayHeap, War3MapViewer.intersectionHeap, - true, true)) { - sampleGroundHeight = War3MapViewer.intersectionHeap.z; - } - else { - sampleGroundHeight = groundHeight; - } - return sampleGroundHeight; - } - - public CUnit getSimulationUnit() { - return this.simulationUnit; - } - - public EnumSet getSecondaryAnimationTags() { - return this.unitAnimationListenerImpl.secondaryAnimationTags; - } - - public void repositioned(final War3MapViewer map) { - final float prevX = this.location[0]; - final float prevY = this.location[1]; - final float simulationX = this.simulationUnit.getX(); - final float simulationY = this.simulationUnit.getY(); - final float dx = simulationX - prevX; - final float dy = simulationY - prevY; - if (this.shadow != null) { - this.shadow.move(dx, dy, map.terrain.centerOffset); - } - if (this.selectionCircle != null) { - this.selectionCircle.move(dx, dy, map.terrain.centerOffset); - } - if (this.selectionPreviewHighlight != null) { - this.selectionPreviewHighlight.move(dx, dy, map.terrain.centerOffset); - } - this.location[0] = this.simulationUnit.getX(); - this.location[1] = this.simulationUnit.getY(); - } - - @Override - public MdxComplexInstance getInstance() { - return this.instance; - } - - @Override - public CWidget getSimulationWidget() { - return this.simulationUnit; - } - - @Override - public boolean isIntersectedOnMeshAlways() { - return this.simulationUnit.isBuilding(); - } - - @Override - public float getSelectionScale() { - return this.selectionScale; - } - - @Override - public float getX() { - return this.location[0]; - } - - @Override - public float getY() { - return this.location[1]; - } - - @Override - public float getZ() { - return this.location[2]; - } - - @Override - public void unassignSelectionCircle() { - this.selectionCircle = null; - } - - @Override - public void assignSelectionCircle(final SplatMover t) { - this.selectionCircle = t; - } - - @Override - public void unassignSelectionPreviewHighlight() { - this.selectionPreviewHighlight = null; - } - - @Override - public void assignSelectionPreviewHighlight(final SplatMover t) { - this.selectionPreviewHighlight = t; - } - - @Override - public boolean isSelectable() { - return true; // later needs locust - } - - @Override - public SplatMover getSelectionPreviewHighlight() { - return this.selectionPreviewHighlight; - } - - public void onRemove(final War3MapViewer map) { - removeSplats(map); - } - - public void setPreferredSelectionReplacement(final RenderUnit preferredSelectionReplacement) { - this.preferredSelectionReplacement = preferredSelectionReplacement; - } - - public RenderUnit getPreferredSelectionReplacement() { - return this.preferredSelectionReplacement; - } - - @Override - public SplatMover getSelectionCircle() { - return this.selectionCircle; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnitTypeData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnitTypeData.java deleted file mode 100644 index 96ab81af..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderUnitTypeData.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim; - -public class RenderUnitTypeData { - private final float maxPitch; - private final float maxRoll; - private final float sampleRadius; - private final boolean allowCustomTeamColor; - private final int teamColor; - private final float animationRunSpeed; - private final float scalingValue; - private final float animationWalkSpeed; - - public RenderUnitTypeData(final float maxPitch, final float maxRoll, final float sampleRadius, - final boolean allowCustomTeamColor, final int teamColor, final float animationRunSpeed, - final float animationWalkSpeed, final float scalingValue) { - this.maxPitch = maxPitch; - this.maxRoll = maxRoll; - this.sampleRadius = sampleRadius; - this.allowCustomTeamColor = allowCustomTeamColor; - this.teamColor = teamColor; - this.animationRunSpeed = animationRunSpeed; - this.animationWalkSpeed = animationWalkSpeed; - this.scalingValue = scalingValue; - } - - public float getMaxPitch() { - return this.maxPitch; - } - - public float getMaxRoll() { - return this.maxRoll; - } - - public float getElevationSampleRadius() { - return this.sampleRadius; - } - - public boolean isAllowCustomTeamColor() { - return this.allowCustomTeamColor; - } - - public int getTeamColor() { - return this.teamColor; - } - - public float getAnimationRunSpeed() { - return this.animationRunSpeed; - } - - public float getAnimationWalkSpeed() { - return this.animationWalkSpeed; - } - - public float getScalingValue() { - return this.scalingValue; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderWidget.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderWidget.java deleted file mode 100644 index 5b7821d2..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/RenderWidget.java +++ /dev/null @@ -1,219 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim; - -import java.util.EnumSet; -import java.util.LinkedList; -import java.util.Queue; - -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.mdx.Sequence; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.SecondaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.SplatModel.SplatMover; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitAnimationListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; - -public interface RenderWidget { - MdxComplexInstance getInstance(); - - CWidget getSimulationWidget(); - - void updateAnimations(War3MapViewer war3MapViewer); - - boolean isIntersectedOnMeshAlways(); - - float getSelectionScale(); - - float getX(); - - float getY(); - - float getZ(); - - void unassignSelectionCircle(); - - void assignSelectionCircle(SplatMover t); - - void unassignSelectionPreviewHighlight(); - - void assignSelectionPreviewHighlight(SplatMover t); - - SplatMover getSelectionCircle(); - - boolean isSelectable(); - - public static final class UnitAnimationListenerImpl implements CUnitAnimationListener { - private final MdxComplexInstance instance; - protected final EnumSet secondaryAnimationTags = EnumSet - .noneOf(AnimationTokens.SecondaryTag.class); - private final EnumSet recycleSet = EnumSet - .noneOf(AnimationTokens.SecondaryTag.class); - private final EnumSet recycleWalkFastSet = EnumSet - .noneOf(AnimationTokens.SecondaryTag.class); - private PrimaryTag currentAnimation; - private EnumSet currentAnimationSecondaryTags = SequenceUtils.EMPTY; - private float currentSpeedRatio; - private boolean currentlyAllowingRarityVariations; - private final Queue animationQueue = new LinkedList<>(); - private int lastWalkFrame = -1; - private final float animationWalkSpeed; - private final float animationRunSpeed; - - public UnitAnimationListenerImpl(final MdxComplexInstance instance, final float animationWalkSpeed, - final float animationRunSpeed) { - this.instance = instance; - this.animationWalkSpeed = animationWalkSpeed; - this.animationRunSpeed = animationRunSpeed; - } - - @Override - public void playWalkAnimation(final boolean force, final float currentMovementSpeed, - final boolean allowRarityVariations) { - EnumSet secondaryWalkTags; - float animationMoveSpeed; - if (animationWalkSpeed < animationRunSpeed) { - final float midpoint = (animationWalkSpeed + animationRunSpeed) / 2; - if (currentMovementSpeed >= midpoint) { - secondaryWalkTags = SequenceUtils.FAST; - animationMoveSpeed = animationRunSpeed; - } - else { - secondaryWalkTags = SequenceUtils.EMPTY; - animationMoveSpeed = animationWalkSpeed; - } - } - else { - secondaryWalkTags = SequenceUtils.EMPTY; - animationMoveSpeed = animationWalkSpeed; - } - animationMoveSpeed *= instance.localScale.x; - final float speedRatio = (currentMovementSpeed) / animationMoveSpeed; - playAnimation(force, PrimaryTag.WALK, secondaryWalkTags, speedRatio, allowRarityVariations); - } - - @Override - public void addSecondaryTag(final AnimationTokens.SecondaryTag tag) { - if (!secondaryAnimationTags.contains(tag)) { - this.secondaryAnimationTags.add(tag); - if (!animationQueue.isEmpty()) { - final QueuedAnimation nextAnimation = animationQueue.poll(); - playAnimation(true, nextAnimation.animationName, nextAnimation.secondaryAnimationTags, 1.0f, - nextAnimation.allowRarityVariations); - } - else { - playAnimation(true, this.currentAnimation, this.currentAnimationSecondaryTags, - this.currentSpeedRatio, this.currentlyAllowingRarityVariations); - } - } - } - - @Override - public void removeSecondaryTag(final AnimationTokens.SecondaryTag tag) { - if (secondaryAnimationTags.contains(tag)) { - this.secondaryAnimationTags.remove(tag); - playAnimation(true, this.currentAnimation, this.currentAnimationSecondaryTags, this.currentSpeedRatio, - this.currentlyAllowingRarityVariations); - } - } - - @Override - public void playAnimation(final boolean force, final PrimaryTag animationName, - final EnumSet secondaryAnimationTags, final float speedRatio, - final boolean allowRarityVariations) { - this.animationQueue.clear(); - if (force || (animationName != this.currentAnimation) - || !secondaryAnimationTags.equals(this.currentAnimationSecondaryTags)) { - this.currentSpeedRatio = speedRatio; - this.recycleSet.clear(); - this.recycleSet.addAll(this.secondaryAnimationTags); - this.recycleSet.addAll(secondaryAnimationTags); - this.instance.setAnimationSpeed(speedRatio); - if ((animationName != PrimaryTag.WALK) && (currentAnimation == PrimaryTag.WALK)) { - lastWalkFrame = instance.frame; - } - if (SequenceUtils.randomSequence(this.instance, animationName, this.recycleSet, - allowRarityVariations) != null) { - if ((lastWalkFrame != -1) && (animationName == PrimaryTag.WALK) - && (currentAnimation != PrimaryTag.WALK)) { - instance.setFrame(instance.clampFrame(lastWalkFrame)); - } - this.currentAnimation = animationName; - this.currentAnimationSecondaryTags = secondaryAnimationTags; - this.currentlyAllowingRarityVariations = allowRarityVariations; - } - } - } - - public void playAnimationWithDuration(final boolean force, final PrimaryTag animationName, - final EnumSet secondaryAnimationTags, final float duration, - final boolean allowRarityVariations) { - this.animationQueue.clear(); - if (force || (animationName != this.currentAnimation) - || !secondaryAnimationTags.equals(this.currentAnimationSecondaryTags)) { - this.recycleSet.clear(); - this.recycleSet.addAll(this.secondaryAnimationTags); - this.recycleSet.addAll(secondaryAnimationTags); - if ((animationName != PrimaryTag.WALK) && (currentAnimation == PrimaryTag.WALK)) { - lastWalkFrame = instance.frame; - } - final Sequence sequence = SequenceUtils.randomSequence(this.instance, animationName, this.recycleSet, - allowRarityVariations); - if (sequence != null) { - if ((lastWalkFrame != -1) && (animationName == PrimaryTag.WALK) - && (currentAnimation != PrimaryTag.WALK)) { - instance.setFrame(instance.clampFrame(lastWalkFrame)); - } - this.currentAnimation = animationName; - this.currentAnimationSecondaryTags = secondaryAnimationTags; - this.currentlyAllowingRarityVariations = allowRarityVariations; - this.currentSpeedRatio = ((sequence.getInterval()[1] - sequence.getInterval()[0]) / 1000.0f) - / duration; - this.instance.setAnimationSpeed(this.currentSpeedRatio); - } - } - } - - @Override - public void queueAnimation(final PrimaryTag animationName, final EnumSet secondaryAnimationTags, - final boolean allowRarityVariations) { - this.animationQueue.add(new QueuedAnimation(animationName, secondaryAnimationTags, allowRarityVariations)); - } - - public void update() { - if (this.instance.sequenceEnded || (this.instance.sequence == -1)) { - // animation done - if ((this.instance.sequence != -1) && (((MdxModel) this.instance.model).getSequences() - .get(this.instance.sequence).getFlags() == 0)) { - // animation is a looping animation - playAnimation(true, this.currentAnimation, this.currentAnimationSecondaryTags, - this.currentSpeedRatio, this.currentlyAllowingRarityVariations); - } - else { - final QueuedAnimation nextAnimation = this.animationQueue.poll(); - if (nextAnimation != null) { - playAnimation(true, nextAnimation.animationName, nextAnimation.secondaryAnimationTags, 1.0f, - nextAnimation.allowRarityVariations); - } - } - } - } - } - - public static final class QueuedAnimation { - private final PrimaryTag animationName; - private final EnumSet secondaryAnimationTags; - private final boolean allowRarityVariations; - - public QueuedAnimation(final PrimaryTag animationName, final EnumSet secondaryAnimationTags, - final boolean allowRarityVariations) { - this.animationName = animationName; - this.secondaryAnimationTags = secondaryAnimationTags; - this.allowRarityVariations = allowRarityVariations; - } - } - - SplatMover getSelectionPreviewHighlight(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/AbilityDataUI.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/AbilityDataUI.java deleted file mode 100644 index 80cca950..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/AbilityDataUI.java +++ /dev/null @@ -1,357 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.badlogic.gdx.graphics.Texture; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.units.Element; -import com.etheller.warsmash.units.manager.MutableObjectData; -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; - -public class AbilityDataUI { - // Standard ability icon fields - private static final War3ID ICON_NORMAL_X = War3ID.fromString("abpx"); - private static final War3ID ICON_NORMAL_Y = War3ID.fromString("abpy"); - private static final War3ID ICON_NORMAL = War3ID.fromString("aart"); - private static final War3ID ICON_TURN_OFF = War3ID.fromString("auar"); - private static final War3ID ICON_TURN_OFF_X = War3ID.fromString("aubx"); - private static final War3ID ICON_TURN_OFF_Y = War3ID.fromString("auby"); - private static final War3ID ICON_RESEARCH = War3ID.fromString("arar"); - private static final War3ID ICON_RESEARCH_X = War3ID.fromString("arpx"); - private static final War3ID ICON_RESEARCH_Y = War3ID.fromString("arpy"); - private static final War3ID ABILITY_TIP = War3ID.fromString("atp1"); - private static final War3ID ABILITY_UBER_TIP = War3ID.fromString("aub1"); - private static final War3ID ABILITY_UN_TIP = War3ID.fromString("aut1"); - private static final War3ID ABILITY_UN_UBER_TIP = War3ID.fromString("auu1"); - private static final War3ID ABILITY_RESEARCH_TIP = War3ID.fromString("aret"); - private static final War3ID ABILITY_RESEARCH_UBER_TIP = War3ID.fromString("arut"); - private static final War3ID ABILITY_EFFECT_SOUND = War3ID.fromString("aefs"); - private static final War3ID ABILITY_EFFECT_SOUND_LOOPED = War3ID.fromString("aefl"); - - private static final War3ID ABILITY_HOTKEY_NORMAL = War3ID.fromString("ahky"); - private static final War3ID ABILITY_HOTKEY_TURNOFF = War3ID.fromString("auhk"); - private static final War3ID ABILITY_HOTKEY_LEARN = War3ID.fromString("arhk"); - - private static final War3ID CASTER_ART = War3ID.fromString("acat"); - private static final War3ID TARGET_ART = War3ID.fromString("atat"); - private static final War3ID SPECIAL_ART = War3ID.fromString("asat"); - private static final War3ID EFFECT_ART = War3ID.fromString("aeat"); - private static final War3ID AREA_EFFECT_ART = War3ID.fromString("aaea"); - private static final War3ID MISSILE_ART = War3ID.fromString("amat"); - - private static final War3ID UNIT_ICON_NORMAL_X = War3ID.fromString("ubpx"); - private static final War3ID UNIT_ICON_NORMAL_Y = War3ID.fromString("ubpy"); - private static final War3ID UNIT_ICON_NORMAL = War3ID.fromString("uico"); - private static final War3ID UNIT_TIP = War3ID.fromString("utip"); - private static final War3ID UNIT_REVIVE_TIP = War3ID.fromString("utpr"); - private static final War3ID UNIT_AWAKEN_TIP = War3ID.fromString("uawt"); - private static final War3ID UNIT_UBER_TIP = War3ID.fromString("utub"); - private static final War3ID UNIT_HOTKEY = War3ID.fromString("uhot"); - - private static final War3ID ITEM_ICON_NORMAL_X = War3ID.fromString("ubpx"); - private static final War3ID ITEM_ICON_NORMAL_Y = War3ID.fromString("ubpy"); - private static final War3ID ITEM_ICON_NORMAL = War3ID.fromString("iico"); - private static final War3ID ITEM_TIP = War3ID.fromString("utip"); - private static final War3ID ITEM_UBER_TIP = War3ID.fromString("utub"); - private static final War3ID ITEM_DESCRIPTION = War3ID.fromString("ides"); - private static final War3ID ITEM_HOTKEY = War3ID.fromString("uhot"); - - private static final War3ID UPGRADE_ICON_NORMAL_X = War3ID.fromString("gbpx"); - private static final War3ID UPGRADE_ICON_NORMAL_Y = War3ID.fromString("gbpy"); - private static final War3ID UPGRADE_ICON_NORMAL = War3ID.fromString("gar1"); - private static final War3ID UPGRADE_LEVELS = War3ID.fromString("glvl"); - private static final War3ID UPGRADE_TIP = War3ID.fromString("gtp1"); - private static final War3ID UPGRADE_UBER_TIP = War3ID.fromString("gub1"); - private static final War3ID UPGRADE_HOTKEY = War3ID.fromString("ghk1"); - - private final Map rawcodeToUI = new HashMap<>(); - private final Map rawcodeToUnitUI = new HashMap<>(); - private final Map rawcodeToItemUI = new HashMap<>(); - private final Map> rawcodeToUpgradeUI = new HashMap<>(); - private final IconUI moveUI; - private final IconUI stopUI; - private final IconUI holdPosUI; - private final IconUI patrolUI; - private final IconUI attackUI; - private final IconUI attackGroundUI; - private final IconUI buildHumanUI; - private final IconUI buildOrcUI; - private final IconUI buildNightElfUI; - private final IconUI buildUndeadUI; - private final IconUI buildNeutralUI; - private final IconUI buildNagaUI; - private final IconUI cancelUI; - private final IconUI cancelBuildUI; - private final IconUI cancelTrainUI; - private final IconUI rallyUI; - private final IconUI selectSkillUI; - - public AbilityDataUI(final MutableObjectData abilityData, final MutableObjectData unitData, - final MutableObjectData itemData, final MutableObjectData upgradeData, final GameUI gameUI, - final War3MapViewer viewer) { - final String disabledPrefix = gameUI.getSkinField("CommandButtonDisabledArtPath"); - for (final War3ID alias : abilityData.keySet()) { - final MutableGameObject abilityTypeData = abilityData.get(alias); - final String iconResearchPath = gameUI.trySkinField(abilityTypeData.getFieldAsString(ICON_RESEARCH, 0)); - final String iconNormalPath = gameUI.trySkinField(abilityTypeData.getFieldAsString(ICON_NORMAL, 0)); - final String iconTurnOffPath = gameUI.trySkinField(abilityTypeData.getFieldAsString(ICON_TURN_OFF, 0)); - final String iconTip = abilityTypeData.getFieldAsString(ABILITY_TIP, 1); - final String iconUberTip = abilityTypeData.getFieldAsString(ABILITY_UBER_TIP, 1); - final char iconHotkey = getHotkey(abilityTypeData, ABILITY_HOTKEY_NORMAL); - final String iconTurnOffTip = abilityTypeData.getFieldAsString(ABILITY_UN_TIP, 1); - final String iconTurnOffUberTip = abilityTypeData.getFieldAsString(ABILITY_UN_UBER_TIP, 1); - final char iconTurnOffHotkey = getHotkey(abilityTypeData, ABILITY_HOTKEY_TURNOFF); - final String iconResearchTip = abilityTypeData.getFieldAsString(ABILITY_RESEARCH_TIP, 1); - final String iconResearchUberTip = abilityTypeData.getFieldAsString(ABILITY_RESEARCH_UBER_TIP, 1); - final char iconResearchHotkey = getHotkey(abilityTypeData, ABILITY_HOTKEY_LEARN); - final int iconResearchX = abilityTypeData.getFieldAsInteger(ICON_RESEARCH_X, 0); - final int iconResearchY = abilityTypeData.getFieldAsInteger(ICON_RESEARCH_Y, 0); - final int iconNormalX = abilityTypeData.getFieldAsInteger(ICON_NORMAL_X, 0); - final int iconNormalY = abilityTypeData.getFieldAsInteger(ICON_NORMAL_Y, 0); - final int iconTurnOffX = abilityTypeData.getFieldAsInteger(ICON_TURN_OFF_X, 0); - final int iconTurnOffY = abilityTypeData.getFieldAsInteger(ICON_TURN_OFF_Y, 0); - final Texture iconResearch = gameUI.loadTexture(iconResearchPath); - final Texture iconResearchDisabled = gameUI.loadTexture(disable(iconResearchPath, disabledPrefix)); - final Texture iconNormal = gameUI.loadTexture(iconNormalPath); - final Texture iconNormalDisabled = gameUI.loadTexture(disable(iconNormalPath, disabledPrefix)); - final Texture iconTurnOff = gameUI.loadTexture(iconTurnOffPath); - final Texture iconTurnOffDisabled = gameUI.loadTexture(disable(iconTurnOffPath, disabledPrefix)); - - final List casterArt = Arrays.asList(abilityTypeData.getFieldAsString(CASTER_ART, 0).split(",")); - final List targetArt = Arrays.asList(abilityTypeData.getFieldAsString(TARGET_ART, 0).split(",")); - final List specialArt = Arrays.asList(abilityTypeData.getFieldAsString(SPECIAL_ART, 0).split(",")); - final List effectArt = Arrays.asList(abilityTypeData.getFieldAsString(EFFECT_ART, 0).split(",")); - final List areaEffectArt = Arrays - .asList(abilityTypeData.getFieldAsString(AREA_EFFECT_ART, 0).split(",")); - final List missileArt = Arrays.asList(abilityTypeData.getFieldAsString(MISSILE_ART, 0).split(",")); - - final String effectSound = abilityTypeData.getFieldAsString(ABILITY_EFFECT_SOUND, 0); - final String effectSoundLooped = abilityTypeData.getFieldAsString(ABILITY_EFFECT_SOUND_LOOPED, 0); - - this.rawcodeToUI.put(alias, - new AbilityUI( - new IconUI(iconResearch, iconResearchDisabled, iconResearchX, iconResearchY, - iconResearchTip, iconResearchUberTip, iconResearchHotkey), - new IconUI(iconNormal, iconNormalDisabled, iconNormalX, iconNormalY, iconTip, iconUberTip, - iconHotkey), - new IconUI(iconTurnOff, iconTurnOffDisabled, iconTurnOffX, iconTurnOffY, iconTurnOffTip, - iconTurnOffUberTip, iconTurnOffHotkey), - casterArt, targetArt, specialArt, effectArt, areaEffectArt, missileArt, effectSound, - effectSoundLooped)); - } - for (final War3ID alias : unitData.keySet()) { - final MutableGameObject abilityTypeData = unitData.get(alias); - final String iconNormalPath = gameUI.trySkinField(abilityTypeData.getFieldAsString(UNIT_ICON_NORMAL, 0)); - final int iconNormalX = abilityTypeData.getFieldAsInteger(UNIT_ICON_NORMAL_X, 0); - final int iconNormalY = abilityTypeData.getFieldAsInteger(UNIT_ICON_NORMAL_Y, 0); - final String iconTip = abilityTypeData.getFieldAsString(UNIT_TIP, 0); - final String reviveTip = abilityTypeData.getFieldAsString(UNIT_REVIVE_TIP, 0); - final String awakenTip = abilityTypeData.getFieldAsString(UNIT_AWAKEN_TIP, 0); - final String iconUberTip = abilityTypeData.getFieldAsString(UNIT_UBER_TIP, 0); - final char iconHotkey = getHotkey(abilityTypeData, UNIT_HOTKEY); - final Texture iconNormal = gameUI.loadTexture(iconNormalPath); - final Texture iconNormalDisabled = gameUI.loadTexture(disable(iconNormalPath, disabledPrefix)); - this.rawcodeToUnitUI.put(alias, new UnitIconUI(iconNormal, iconNormalDisabled, iconNormalX, iconNormalY, - iconTip, iconUberTip, iconHotkey, reviveTip, awakenTip)); - } - for (final War3ID alias : itemData.keySet()) { - final MutableGameObject abilityTypeData = itemData.get(alias); - final String iconNormalPath = gameUI.trySkinField(abilityTypeData.getFieldAsString(ITEM_ICON_NORMAL, 0)); - final int iconNormalX = abilityTypeData.getFieldAsInteger(ITEM_ICON_NORMAL_X, 0); - final int iconNormalY = abilityTypeData.getFieldAsInteger(ITEM_ICON_NORMAL_Y, 0); - final String iconTip = abilityTypeData.getFieldAsString(ITEM_TIP, 0); - final String iconUberTip = abilityTypeData.getFieldAsString(ITEM_UBER_TIP, 0); - final String iconDescription = abilityTypeData.getFieldAsString(ITEM_DESCRIPTION, 0); - final char iconHotkey = getHotkey(abilityTypeData, ITEM_HOTKEY); - final Texture iconNormal = gameUI.loadTexture(iconNormalPath); - final Texture iconNormalDisabled = gameUI.loadTexture(disable(iconNormalPath, disabledPrefix)); - this.rawcodeToItemUI - .put(alias, - new ItemUI( - new IconUI(iconNormal, iconNormalDisabled, iconNormalX, iconNormalY, iconTip, - iconUberTip, iconHotkey), - abilityTypeData.getName(), iconDescription, iconNormalPath)); - } - for (final War3ID alias : upgradeData.keySet()) { - final MutableGameObject upgradeTypeData = upgradeData.get(alias); - final int upgradeLevels = upgradeTypeData.getFieldAsInteger(UPGRADE_LEVELS, 0); - final int iconNormalX = upgradeTypeData.getFieldAsInteger(UPGRADE_ICON_NORMAL_X, 0); - final int iconNormalY = upgradeTypeData.getFieldAsInteger(UPGRADE_ICON_NORMAL_Y, 0); - final List upgradeIconsByLevel = new ArrayList<>(); - for (int i = 0; i < upgradeLevels; i++) { - final String iconTip = upgradeTypeData.getFieldAsString(UPGRADE_TIP, 0); - final String iconUberTip = upgradeTypeData.getFieldAsString(UPGRADE_UBER_TIP, 0); - final String iconNormalPath = gameUI - .trySkinField(upgradeTypeData.getFieldAsString(UPGRADE_ICON_NORMAL, i)); - final char iconHotkey = getHotkey(upgradeTypeData, UPGRADE_HOTKEY, i); - final Texture iconNormal = gameUI.loadTexture(iconNormalPath); - final Texture iconNormalDisabled = gameUI.loadTexture(disable(iconNormalPath, disabledPrefix)); - upgradeIconsByLevel.add(new IconUI(iconNormal, iconNormalDisabled, iconNormalX, iconNormalY, iconTip, - iconUberTip, iconHotkey)); - } - this.rawcodeToUpgradeUI.put(alias, upgradeIconsByLevel); - } - this.moveUI = createBuiltInIconUI(gameUI, "CmdMove", disabledPrefix); - this.stopUI = createBuiltInIconUI(gameUI, "CmdStop", disabledPrefix); - this.holdPosUI = createBuiltInIconUI(gameUI, "CmdHoldPos", disabledPrefix); - this.patrolUI = createBuiltInIconUI(gameUI, "CmdPatrol", disabledPrefix); - this.attackUI = createBuiltInIconUI(gameUI, "CmdAttack", disabledPrefix); - this.buildHumanUI = createBuiltInIconUI(gameUI, "CmdBuildHuman", disabledPrefix); - this.buildOrcUI = createBuiltInIconUI(gameUI, "CmdBuildOrc", disabledPrefix); - this.buildNightElfUI = createBuiltInIconUI(gameUI, "CmdBuildNightElf", disabledPrefix); - this.buildUndeadUI = createBuiltInIconUI(gameUI, "CmdBuildUndead", disabledPrefix); - this.buildNagaUI = createBuiltInIconUI(gameUI, "CmdBuildNaga", disabledPrefix); - this.buildNeutralUI = createBuiltInIconUI(gameUI, "CmdBuild", disabledPrefix); - this.attackGroundUI = createBuiltInIconUI(gameUI, "CmdAttackGround", disabledPrefix); - this.cancelUI = createBuiltInIconUI(gameUI, "CmdCancel", disabledPrefix); - this.cancelBuildUI = createBuiltInIconUI(gameUI, "CmdCancelBuild", disabledPrefix); - this.cancelTrainUI = createBuiltInIconUI(gameUI, "CmdCancelTrain", disabledPrefix); - this.rallyUI = createBuiltInIconUI(gameUI, "CmdRally", disabledPrefix); - this.selectSkillUI = createBuiltInIconUI(gameUI, "CmdSelectSkill", disabledPrefix); - } - - private char getHotkey(final MutableGameObject abilityTypeData, final War3ID abilityHotkeyNormal) { - return getHotkey(abilityTypeData, abilityHotkeyNormal, 1); - } - - private char getHotkey(final MutableGameObject abilityTypeData, final War3ID abilityHotkeyNormal, final int level) { - final String iconHotkeyString = abilityTypeData.getFieldAsString(abilityHotkeyNormal, level); - final char itemHotkey = getHotkeyChar(iconHotkeyString); - return itemHotkey; - } - - private IconUI createBuiltInIconUI(final GameUI gameUI, final String key, final String disabledPrefix) { - final Element builtInAbility = gameUI.getSkinData().get(key); - final String iconPath = gameUI.trySkinField(builtInAbility.getField("Art")); - final Texture icon = gameUI.loadTexture(iconPath); - final Texture iconDisabled = gameUI.loadTexture(disable(iconPath, disabledPrefix)); - final int buttonPositionX = builtInAbility.getFieldValue("Buttonpos", 0); - final int buttonPositionY = builtInAbility.getFieldValue("Buttonpos", 1); - final String tip = builtInAbility.getField("Tip"); - final String uberTip = builtInAbility.getField("UberTip"); - final String hotkeyString = builtInAbility.getField("Hotkey"); - final char hotkey = getHotkeyChar(hotkeyString); - return new IconUI(icon, iconDisabled, buttonPositionX, buttonPositionY, tip, uberTip, hotkey); - } - - private char getHotkeyChar(final String hotkeyString) { - if (hotkeyString.length() > 1) { - final int hotkeyInt = Integer.parseInt(hotkeyString); - if (hotkeyInt == 512) { - return WarsmashConstants.SPECIAL_ESCAPE_KEYCODE; - } - return (char) hotkeyInt; - } - return hotkeyString.length() > 0 ? hotkeyString.charAt(0) : '\0'; - } - - public AbilityUI getUI(final War3ID rawcode) { - return this.rawcodeToUI.get(rawcode); - } - - public UnitIconUI getUnitUI(final War3ID rawcode) { - return this.rawcodeToUnitUI.get(rawcode); - } - - public ItemUI getItemUI(final War3ID rawcode) { - return this.rawcodeToItemUI.get(rawcode); - } - - public IconUI getUpgradeUI(final War3ID rawcode, final int level) { - final List upgradeUI = this.rawcodeToUpgradeUI.get(rawcode); - if (upgradeUI != null) { - if (level < upgradeUI.size()) { - return upgradeUI.get(level); - } - else { - return upgradeUI.get(upgradeUI.size() - 1); - } - } - return null; - } - - private static String disable(final String path, final String disabledPrefix) { - final int slashIndex = path.lastIndexOf('\\'); - String name = path; - if (slashIndex != -1) { - name = path.substring(slashIndex + 1); - } - return disabledPrefix + "DIS" + name; - } - - public IconUI getMoveUI() { - return this.moveUI; - } - - public IconUI getStopUI() { - return this.stopUI; - } - - public IconUI getHoldPosUI() { - return this.holdPosUI; - } - - public IconUI getPatrolUI() { - return this.patrolUI; - } - - public IconUI getAttackUI() { - return this.attackUI; - } - - public IconUI getAttackGroundUI() { - return this.attackGroundUI; - } - - public IconUI getBuildHumanUI() { - return this.buildHumanUI; - } - - public IconUI getBuildNightElfUI() { - return this.buildNightElfUI; - } - - public IconUI getBuildOrcUI() { - return this.buildOrcUI; - } - - public IconUI getBuildUndeadUI() { - return this.buildUndeadUI; - } - - public IconUI getBuildNagaUI() { - return this.buildNagaUI; - } - - public IconUI getBuildNeutralUI() { - return this.buildNeutralUI; - } - - public IconUI getCancelUI() { - return this.cancelUI; - } - - public IconUI getCancelBuildUI() { - return this.cancelBuildUI; - } - - public IconUI getCancelTrainUI() { - return this.cancelTrainUI; - } - - public IconUI getRallyUI() { - return this.rallyUI; - } - - public IconUI getSelectSkillUI() { - return this.selectSkillUI; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/AbilityUI.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/AbilityUI.java deleted file mode 100644 index 28caf03a..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/AbilityUI.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability; - -import java.util.List; - -public class AbilityUI { - private final IconUI learnIconUI; - private final IconUI onIconUI; - private final IconUI offIconUI; - private final List casterArt; - private final List targetArt; - private final List specialArt; - private final List effectArt; - private final List areaEffectArt; - private final List missileArt; - private final String effectSound; - private final String effectSoundLooped; - - public AbilityUI(final IconUI learnIconUI, final IconUI onIconUI, final IconUI offIconUI, - final List casterArt, final List targetArt, final List specialArt, - final List effectArt, final List areaEffectArt, final List missileArt, - final String effectSound, final String effectSoundLooped) { - this.learnIconUI = learnIconUI; - this.onIconUI = onIconUI; - this.offIconUI = offIconUI; - this.casterArt = casterArt; - this.targetArt = targetArt; - this.specialArt = specialArt; - this.effectArt = effectArt; - this.areaEffectArt = areaEffectArt; - this.missileArt = missileArt; - this.effectSound = effectSound; - this.effectSoundLooped = effectSoundLooped; - } - - public IconUI getLearnIconUI() { - return this.learnIconUI; - } - - public IconUI getOnIconUI() { - return this.onIconUI; - } - - public IconUI getOffIconUI() { - return this.offIconUI; - } - - public String getCasterArt(final int index) { - return tryGet(this.casterArt, index); - } - - public String getTargetArt(final int index) { - return tryGet(this.targetArt, index); - } - - public String getSpecialArt(final int index) { - return tryGet(this.specialArt, index); - } - - public String getEffectArt(final int index) { - return tryGet(this.effectArt, index); - } - - public String getAreaEffectArt(final int index) { - return tryGet(this.areaEffectArt, index); - } - - public String getMissileArt(final int index) { - return tryGet(this.missileArt, index); - } - - public String getEffectSound() { - return this.effectSound; - } - - public String getEffectSoundLooped() { - return this.effectSoundLooped; - } - - private static String tryGet(final List items, final int index) { - if (index < items.size()) { - return items.get(index); - } - return items.get(items.size() - 1); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/IconUI.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/IconUI.java deleted file mode 100644 index 46c7341c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/IconUI.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability; - -import com.badlogic.gdx.graphics.Texture; - -public class IconUI { - private final Texture icon; - private final Texture iconDisabled; - private final int buttonPositionX; - private final int buttonPositionY; - private final String toolTip; - private final String uberTip; - private final char hotkey; - - public IconUI(final Texture icon, final Texture iconDisabled, final int buttonPositionX, final int buttonPositionY, - final String toolTip, final String uberTip, final char hotkey) { - this.icon = icon; - this.iconDisabled = iconDisabled; - this.buttonPositionX = buttonPositionX; - this.buttonPositionY = buttonPositionY; - this.toolTip = toolTip; - this.uberTip = uberTip; - this.hotkey = hotkey; - } - - public Texture getIcon() { - return this.icon; - } - - public Texture getIconDisabled() { - return this.iconDisabled; - } - - public int getButtonPositionX() { - return this.buttonPositionX; - } - - public int getButtonPositionY() { - return this.buttonPositionY; - } - - public String getToolTip() { - return this.toolTip; - } - - public String getUberTip() { - return this.uberTip; - } - - public char getHotkey() { - return this.hotkey; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/ItemUI.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/ItemUI.java deleted file mode 100644 index b1a6a4db..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/ItemUI.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability; - -public class ItemUI { - private final IconUI iconUI; - private final String name; - private final String description; - private final String itemIconPathForDragging; - - public ItemUI(final IconUI iconUI, final String name, final String description, - final String itemIconPathForDragging) { - this.iconUI = iconUI; - this.name = name; - this.description = description; - this.itemIconPathForDragging = itemIconPathForDragging; - } - - public IconUI getIconUI() { - return this.iconUI; - } - - public String getName() { - return this.name; - } - - public String getDescription() { - return this.description; - } - - public String getItemIconPathForDragging() { - return this.itemIconPathForDragging; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/UnitIconUI.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/UnitIconUI.java deleted file mode 100644 index 78ec30e9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/ability/UnitIconUI.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability; - -import com.badlogic.gdx.graphics.Texture; - -public class UnitIconUI extends IconUI { - private final String reviveTip; - private final String awakenTip; - - public UnitIconUI(final Texture icon, final Texture iconDisabled, final int buttonPositionX, - final int buttonPositionY, final String toolTip, final String uberTip, final char hotkey, - final String reviveTip, final String awakenTip) { - super(icon, iconDisabled, buttonPositionX, buttonPositionY, toolTip, uberTip, hotkey); - this.reviveTip = reviveTip; - this.awakenTip = awakenTip; - } - - public String getReviveTip() { - return this.reviveTip; - } - - public String getAwakenTip() { - return this.awakenTip; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/AbilityCommandButton.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/AbilityCommandButton.java deleted file mode 100644 index 5f3a73d5..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/AbilityCommandButton.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim.commandbuttons; - -import com.badlogic.gdx.graphics.Texture; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.AbilityUI; - -public class AbilityCommandButton implements CommandButton { - private final AbilityUI abilityIconUI; - private final int orderId; - - public AbilityCommandButton(final AbilityUI abilityIconUI, final int orderId) { - this.abilityIconUI = abilityIconUI; - this.orderId = orderId; - } - - @Override - public String getToolTip() { - return null; - } - - @Override - public String getUberTip() { - return null; - } - - @Override - public int getLumberCost() { - return 0; - } - - @Override - public int getGoldCost() { - return 0; - } - - @Override - public int getManaCost() { - return 0; - } - - @Override - public int getFoodCost() { - return 0; - } - - @Override - public Texture getIcon() { - return this.abilityIconUI.getOnIconUI().getIcon(); - } - - @Override - public Texture getDisabledIcon() { - return this.abilityIconUI.getOnIconUI().getIconDisabled(); - } - - @Override - public boolean isEnabled() { - return true; - } - - @Override - public float getCooldown() { - return 0; - } - - @Override - public float getCooldownRemaining() { - return 0; - } - - @Override - public boolean isAutoCastCapable() { - return false; - } - - @Override - public boolean isAutoCastActive() { - return false; - } - - @Override - public int getButtonPositionX() { - return this.abilityIconUI.getOnIconUI().getButtonPositionX(); - } - - @Override - public int getButtonPositionY() { - return this.abilityIconUI.getOnIconUI().getButtonPositionY(); - } - - @Override - public int getOrderId() { - return this.orderId; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/BasicCommandButton.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/BasicCommandButton.java deleted file mode 100644 index c9cc9067..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/BasicCommandButton.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim.commandbuttons; - -import com.badlogic.gdx.graphics.Texture; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.IconUI; - -public class BasicCommandButton implements CommandButton { - private final IconUI iconUI; - private final int orderId; - - public BasicCommandButton(final IconUI iconUI, final int orderId) { - this.iconUI = iconUI; - this.orderId = orderId; - } - - @Override - public String getToolTip() { - return null; - } - - @Override - public String getUberTip() { - return null; - } - - @Override - public int getLumberCost() { - return 0; - } - - @Override - public int getGoldCost() { - return 0; - } - - @Override - public int getManaCost() { - return 0; - } - - @Override - public int getFoodCost() { - return 0; - } - - @Override - public Texture getIcon() { - return this.iconUI.getIcon(); - } - - @Override - public Texture getDisabledIcon() { - return this.iconUI.getIconDisabled(); - } - - @Override - public boolean isEnabled() { - return true; - } - - @Override - public float getCooldown() { - return 0; - } - - @Override - public float getCooldownRemaining() { - return 0; - } - - @Override - public boolean isAutoCastCapable() { - return false; - } - - @Override - public boolean isAutoCastActive() { - return false; - } - - @Override - public int getButtonPositionX() { - return this.iconUI.getButtonPositionX(); - } - - @Override - public int getButtonPositionY() { - return this.iconUI.getButtonPositionY(); - } - - @Override - public int getOrderId() { - return this.orderId; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandButton.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandButton.java deleted file mode 100644 index af4e9c9e..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandButton.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim.commandbuttons; - -import com.badlogic.gdx.graphics.Texture; - -public interface CommandButton { - String getToolTip(); - - String getUberTip(); - - int getLumberCost(); - - int getGoldCost(); - - int getManaCost(); - - int getFoodCost(); - - Texture getIcon(); - - Texture getDisabledIcon(); - - boolean isEnabled(); - - float getCooldown(); - - float getCooldownRemaining(); - - boolean isAutoCastCapable(); - - boolean isAutoCastActive(); - - int getButtonPositionX(); - - int getButtonPositionY(); - - int getOrderId(); - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandButtonListener.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandButtonListener.java deleted file mode 100644 index 9f5da3d4..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandButtonListener.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim.commandbuttons; - -import com.badlogic.gdx.graphics.Texture; - -public interface CommandButtonListener { -// String getToolTip(); -// -// String getUberTip(); -// -// int getLumberCost(); -// -// int getGoldCost(); -// -// int getManaCost(); -// -// int getFoodCost(); -// -// Texture getIcon(); -// -// Texture getDisabledIcon(); -// -// boolean isEnabled(); -// -// float getCooldown(); -// -// float getCooldownRemaining(); -// -// boolean isAutoCastCapable(); -// -// boolean isAutoCastActive(); -// -// int getButtonPositionX(); -// -// int getButtonPositionY(); -// -// int getOrderId(); - void commandButton(int buttonPositionX, int buttonPositionY, Texture icon, int abilityHandleId, int orderId, - int autoCastOrderId, boolean active, boolean autoCastActive, boolean menuButton, String tip, String uberTip, - char hotkey, int goldCost, int lumberCost, int foodCost); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardPopulatingAbilityVisitor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardPopulatingAbilityVisitor.java deleted file mode 100644 index 8aeab7c6..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/rendersim/commandbuttons/CommandCardPopulatingAbilityVisitor.java +++ /dev/null @@ -1,405 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.rendersim.commandbuttons; - -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.AbilityDataUI; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.AbilityUI; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.IconUI; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.UnitIconUI; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGeneric; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityMove; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.AbstractCAbilityBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityBuildInProgress; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNagaBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNeutralBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNightElfBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityOrcBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityUndeadBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityColdArrows; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericNoIconAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericSingleIconActiveAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CAbilityHero; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityQueue; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityRally; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityReviveHero; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; - -public class CommandCardPopulatingAbilityVisitor implements CAbilityVisitor { - private static final boolean ENABLE_PLACEHOLDERS = false; - public static final CommandCardPopulatingAbilityVisitor INSTANCE = new CommandCardPopulatingAbilityVisitor(); - private CSimulation game; - private CUnit unit; - - private CommandButtonListener commandButtonListener; - private AbilityDataUI abilityDataUI; - private int menuBaseOrderId; - private boolean multiSelect; - private boolean hasStop; - private final CommandCardActivationReceiverPreviewCallback previewCallback = new CommandCardActivationReceiverPreviewCallback(); - private GameUI gameUI; - private boolean hasCancel; - - public CommandCardPopulatingAbilityVisitor reset(final CSimulation game, final GameUI gameUI, final CUnit unit, - final CommandButtonListener commandButtonListener, final AbilityDataUI abilityDataUI, - final int menuBaseOrderId, final boolean multiSelect) { - this.game = game; - this.gameUI = gameUI; - this.unit = unit; - this.commandButtonListener = commandButtonListener; - this.abilityDataUI = abilityDataUI; - this.menuBaseOrderId = menuBaseOrderId; - this.multiSelect = multiSelect; - this.hasStop = false; - this.hasCancel = false; - return this; - } - - @Override - public Void accept(final CAbilityAttack ability) { - if ((this.menuBaseOrderId == 0) && ability.isIconShowing()) { - addCommandButton(ability, this.abilityDataUI.getAttackUI(), ability.getHandleId(), OrderIds.attack, 0, - false, false); - boolean attackGroundEnabled = false; - for (final CUnitAttack attack : this.unit.getAttacks()) { - if (attack.getWeaponType().isAttackGroundSupported()) { - attackGroundEnabled = true; - break; - } - } - if (attackGroundEnabled) { - addCommandButton(ability, this.abilityDataUI.getAttackGroundUI(), ability.getHandleId(), - OrderIds.attackground, 0, false, false); - } - if (!this.hasStop) { - this.hasStop = true; - addCommandButton(ability, this.abilityDataUI.getStopUI(), 0, OrderIds.stop, 0, false, false); - } - } - return null; - } - - @Override - public Void accept(final CAbilityMove ability) { - if ((this.menuBaseOrderId == 0) && ability.isIconShowing()) { - addCommandButton(ability, this.abilityDataUI.getMoveUI(), ability.getHandleId(), OrderIds.move, 0, false, - false); - addCommandButton(ability, this.abilityDataUI.getHoldPosUI(), 0, OrderIds.holdposition, 0, false, false); - addCommandButton(ability, this.abilityDataUI.getPatrolUI(), ability.getHandleId(), OrderIds.patrol, 0, - false, false); - if (!this.hasStop) { - this.hasStop = true; - addCommandButton(ability, this.abilityDataUI.getStopUI(), 0, OrderIds.stop, 0, false, false); - } - } - return null; - } - - @Override - public Void accept(final CAbilityGeneric ability) { - if (ENABLE_PLACEHOLDERS) { - if ((this.menuBaseOrderId == 0) && ability.isIconShowing()) { - final AbilityUI abilityUI = this.abilityDataUI.getUI(ability.getRawcode()); - if (abilityUI != null) { - addCommandButton(ability, abilityUI.getOnIconUI(), ability.getHandleId(), 0, 0, false, false); - } - else { - addCommandButton(ability, this.abilityDataUI.getStopUI(), ability.getHandleId(), 0, 0, false, - false); - } - } - } - return null; - } - - @Override - public Void accept(final GenericSingleIconActiveAbility ability) { - if ((this.menuBaseOrderId == 0) && ability.isIconShowing()) { - final AbilityUI ui = this.abilityDataUI.getUI(ability.getAlias()); - addCommandButton(ability, ability.isToggleOn() ? ui.getOffIconUI() : ui.getOnIconUI(), - ability.getHandleId(), ability.getBaseOrderId(), 0, false, false, ability.getUIGoldCost(), - ability.getUILumberCost(), 0); - } - return null; - } - - @Override - public Void accept(final GenericNoIconAbility ability) { - return null; - } - - @Override - public Void accept(final CAbilityRally ability) { - if (this.menuBaseOrderId == 0) { - addCommandButton(ability, this.abilityDataUI.getRallyUI(), ability.getHandleId(), ability.getBaseOrderId(), - 0, false, false); - } - return null; - } - - @Override - public Void accept(final CAbilityColdArrows ability) { - if ((this.menuBaseOrderId == 0) && ability.isIconShowing()) { - final boolean autoCastActive = ability.isAutoCastActive(); - int autoCastId; - if (autoCastActive) { - autoCastId = OrderIds.coldarrows; - } - else { - autoCastId = OrderIds.uncoldarrows; - } - final IconUI onIconUI = this.abilityDataUI.getUI(ability.getRawcode()).getOnIconUI(); - addCommandButton(ability, onIconUI, ability.getHandleId(), OrderIds.coldarrowstarg, autoCastId, - autoCastActive, false); - } - return null; - } - - @Override - public Void accept(final CAbilityOrcBuild ability) { - handleBuildMenu(ability, this.abilityDataUI.getBuildOrcUI()); - return null; - } - - @Override - public Void accept(final CAbilityHumanBuild ability) { - handleBuildMenu(ability, this.abilityDataUI.getBuildHumanUI()); - return null; - } - - @Override - public Void accept(final CAbilityNightElfBuild ability) { - handleBuildMenu(ability, this.abilityDataUI.getBuildNightElfUI()); - return null; - } - - @Override - public Void accept(final CAbilityUndeadBuild ability) { - handleBuildMenu(ability, this.abilityDataUI.getBuildUndeadUI()); - return null; - } - - @Override - public Void accept(final CAbilityNagaBuild ability) { - handleBuildMenu(ability, this.abilityDataUI.getBuildNagaUI()); - return null; - } - - @Override - public Void accept(final CAbilityNeutralBuild ability) { - handleBuildMenu(ability, this.abilityDataUI.getBuildNeutralUI()); - return null; - } - - private void handleBuildMenu(final AbstractCAbilityBuild ability, final IconUI buildUI) { - if ((this.menuBaseOrderId == ability.getBaseOrderId()) && ability.isIconShowing()) { - for (final War3ID unitType : ability.getStructuresBuilt()) { - final IconUI unitUI = this.abilityDataUI.getUnitUI(unitType); - if (unitUI != null) { - final CUnitType simulationUnitType = this.game.getUnitData().getUnitType(unitType); - addCommandButton(ability, unitUI, ability.getHandleId(), unitType.getValue(), 0, false, false, - simulationUnitType.getGoldCost(), simulationUnitType.getLumberCost(), - simulationUnitType.getFoodUsed()); - } - } - } - else { - if (this.multiSelect) { - return; - } - addCommandButton(ability, buildUI, ability.getHandleId(), ability.getBaseOrderId(), 0, false, true); - } - } - - private void addCommandButton(final CAbility ability, final IconUI iconUI, final int handleId, final int orderId, - final int autoCastOrderId, final boolean autoCastActive, final boolean menuButton) { - addCommandButton(ability, iconUI, handleId, orderId, autoCastOrderId, autoCastActive, menuButton, 0, 0, 0); - } - - private void addCommandButton(final CAbility ability, final IconUI iconUI, final int handleId, final int orderId, - final int autoCastOrderId, final boolean autoCastActive, final boolean menuButton, final int goldCost, - final int lumberCost, final int foodCost) { - addCommandButton(ability, iconUI, iconUI.getToolTip(), iconUI.getButtonPositionX(), iconUI.getButtonPositionY(), - handleId, orderId, autoCastOrderId, autoCastActive, menuButton, goldCost, lumberCost, foodCost); - } - - private void addCommandButton(final CAbility ability, final IconUI iconUI, final String toolTip, - final int buttonPosX, final int buttonPosY, final int handleId, final int orderId, - final int autoCastOrderId, final boolean autoCastActive, final boolean menuButton, int goldCost, - int lumberCost, int foodCost) { - ability.checkCanUse(this.game, this.unit, orderId, this.previewCallback.reset()); - final boolean active = ((this.unit.getCurrentBehavior() != null) - && (orderId == this.unit.getCurrentBehavior().getHighlightOrderId())); - final boolean disabled = ((ability != null) && ability.isDisabled()) || this.previewCallback.disabled; - String uberTip = iconUI.getUberTip(); - if (disabled) { - // dont show these on disabled - goldCost = 0; - lumberCost = 0; - foodCost = 0; - } - if (this.previewCallback.isShowingRequirements()) { - uberTip = this.previewCallback.getRequirementsText() + "|r" + uberTip; - } - this.commandButtonListener.commandButton(buttonPosX, buttonPosY, - disabled ? iconUI.getIconDisabled() : iconUI.getIcon(), handleId, disabled ? 0 : orderId, - autoCastOrderId, active, autoCastActive, menuButton, toolTip, uberTip, iconUI.getHotkey(), goldCost, - lumberCost, foodCost); - } - - @Override - public Void accept(final CAbilityBuildInProgress ability) { - if (this.menuBaseOrderId == 0) { - addCommandButton(ability, this.abilityDataUI.getCancelBuildUI(), ability.getHandleId(), OrderIds.cancel, 0, - false, false); - } - return null; - } - - @Override - public Void accept(final CAbilityReviveHero ability) { - if ((this.menuBaseOrderId == 0) && ability.isIconShowing()) { - int heroIndex = 0; - for (final CUnit playerHero : this.game.getPlayerHeroes(this.unit.getPlayerIndex())) { - final CAbilityHero heroData = playerHero.getHeroData(); - if (playerHero.isDead() && (heroData != null) && heroData.isAwaitingRevive() - && !heroData.isReviving()) { - - final UnitIconUI unitUI = this.abilityDataUI.getUnitUI(playerHero.getTypeId()); - if (unitUI != null) { - final CUnitType simulationUnitType = playerHero.getUnitType(); - final int goldCost = this.game.getGameplayConstants() - .getHeroReviveGoldCost(simulationUnitType.getGoldCost(), heroData.getHeroLevel()); - final int lumberCost = this.game.getGameplayConstants() - .getHeroReviveLumberCost(simulationUnitType.getLumberCost(), heroData.getHeroLevel()); - addCommandButton(ability, unitUI, unitUI.getReviveTip() + " - " + heroData.getProperName(), - heroIndex++, 0, ability.getHandleId(), playerHero.getHandleId(), 0, false, false, - goldCost, lumberCost, simulationUnitType.getFoodUsed()); - } - } - } - if (this.unit.getBuildQueueTypes()[0] != null) { - if (!this.hasCancel) { - this.hasCancel = true; - addCommandButton(ability, this.abilityDataUI.getCancelTrainUI(), ability.getHandleId(), - OrderIds.cancel, 0, false, false); - } - } - } - return null; - } - - @Override - public Void accept(final CAbilityQueue ability) { - if ((this.menuBaseOrderId == 0) && ability.isIconShowing()) { - for (final War3ID unitType : ability.getUnitsTrained()) { - final IconUI unitUI = this.abilityDataUI.getUnitUI(unitType); - if (unitUI != null) { - final CUnitType simulationUnitType = this.game.getUnitData().getUnitType(unitType); - addCommandButton(ability, unitUI, ability.getHandleId(), unitType.getValue(), 0, false, false, - simulationUnitType.getGoldCost(), simulationUnitType.getLumberCost(), - simulationUnitType.getFoodUsed()); - } - } - if (ENABLE_PLACEHOLDERS) { - for (final War3ID unitType : ability.getResearchesAvailable()) { - final CPlayer player = this.game.getPlayer(this.unit.getPlayerIndex()); - final IconUI unitUI = this.abilityDataUI.getUpgradeUI(unitType, - player.getTechtreeUnlocked(unitType)); - if (unitUI != null) { - addCommandButton(ability, unitUI, ability.getHandleId(), unitType.getValue(), 0, false, false); - } - } - } - if (this.unit.getBuildQueueTypes()[0] != null) { - if (!this.hasCancel) { - this.hasCancel = true; - addCommandButton(ability, this.abilityDataUI.getCancelTrainUI(), ability.getHandleId(), - OrderIds.cancel, 0, false, false); - } - } - } - return null; - } - - private final class CommandCardActivationReceiverPreviewCallback implements AbilityActivationReceiver { - private boolean disabled; - private final StringBuilder requirementsTextBuilder = new StringBuilder(); - - public CommandCardActivationReceiverPreviewCallback reset() { - this.disabled = false; - this.requirementsTextBuilder.setLength(0); - return this; - } - - @Override - public void useOk() { - - } - - @Override - public void notEnoughResources(final ResourceType resource) { - - } - - @Override - public void notAnActiveAbility() { - - } - - @Override - public void missingRequirement(final War3ID type, final int level) { - this.disabled = true; - if (this.requirementsTextBuilder.length() == 0) { - this.requirementsTextBuilder.append(CommandCardPopulatingAbilityVisitor.this.gameUI.getTemplates() - .getDecoratedString("REQUIRESTOOLTIP")); - this.requirementsTextBuilder.append("|n - "); - } - else { - this.requirementsTextBuilder.append(" - "); - } - final CUnitType unitType = CommandCardPopulatingAbilityVisitor.this.game.getUnitData().getUnitType(type); - this.requirementsTextBuilder - .append(unitType == null ? "NOTEXTERN Unknown ('" + type + "')" : unitType.getName()); - this.requirementsTextBuilder.append("|n"); - } - - @Override - public void casterMovementDisabled() { - - } - - @Override - public void cargoCapacityUnavailable() { - } - - @Override - public void disabled() { - this.disabled = true; - } - - public boolean isShowingRequirements() { - return this.requirementsTextBuilder.length() != 0; - } - - public String getRequirementsText() { - return this.requirementsTextBuilder.toString(); - } - } - - @Override - public Void accept(final CAbilityHero ability) { - // TODO - return null; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CDestructable.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CDestructable.java deleted file mode 100644 index cc646a60..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CDestructable.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.RemovablePathingMapInstance; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderWidget.UnitAnimationListenerImpl; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CBuildingPathingType; - -public class CDestructable extends CWidget { - - private final CDestructableType destType; - private final RemovablePathingMapInstance pathingInstance; - private final RemovablePathingMapInstance pathingInstanceDeath; - private UnitAnimationListenerImpl unitAnimationListenerImpl; - private boolean invulnerable; - private boolean blighted; - - public CDestructable(final int handleId, final float x, final float y, final float life, - final CDestructableType destTypeInstance, final RemovablePathingMapInstance pathingInstance, - final RemovablePathingMapInstance pathingInstanceDeath) { - super(handleId, x, y, life); - this.destType = destTypeInstance; - this.pathingInstance = pathingInstance; - this.pathingInstanceDeath = pathingInstanceDeath; - } - - @Override - public float getFlyHeight() { - return 0; - } - - @Override - public float getImpactZ() { - return 0; // TODO maybe from DestructableType - } - - @Override - public void damage(final CSimulation simulation, final CUnit source, final CAttackType attackType, - final String weaponType, final float damage) { - final boolean wasDead = isDead(); - this.life -= damage; - if (!wasDead && isDead()) { - if (this.pathingInstance != null) { - this.pathingInstance.remove(); - } - if (this.pathingInstanceDeath != null) { - this.pathingInstanceDeath.add(); - } - } - simulation.destructableDamageEvent(this, weaponType, this.destType.getArmorType()); - } - - @Override - public boolean canBeTargetedBy(final CSimulation simulation, final CUnit source, - final EnumSet targetsAllowed) { - if (targetsAllowed.containsAll(this.destType.getTargetedAs())) { - if (isDead()) { - return targetsAllowed.contains(CTargetType.DEAD); - } - else { - return !targetsAllowed.contains(CTargetType.DEAD) || targetsAllowed.contains(CTargetType.ALIVE); - } - } - else { - System.err.println("Not targeting because " + targetsAllowed + " does not contain all of " - + this.destType.getTargetedAs()); - } - return false; - } - - @Override - public T visit(final AbilityTargetVisitor visitor) { - return visitor.accept(this); - } - - public CDestructableType getDestType() { - return this.destType; - } - - public void setUnitAnimationListener(final UnitAnimationListenerImpl unitAnimationListenerImpl) { - this.unitAnimationListenerImpl = unitAnimationListenerImpl; - } - - @Override - public float getMaxLife() { - return this.destType.getMaxLife(); - } - - public void setInvulnerable(final boolean invulnerable) { - this.invulnerable = invulnerable; - } - - @Override - public boolean isInvulnerable() { - return this.invulnerable; - } - - public void setBlighted(final boolean blighted) { - this.blighted = blighted; - } - - public boolean isBlighted() { - return this.blighted; - } - - public boolean checkIsOnBlight(final CSimulation game) { - return !game.getPathingGrid().checkPathingTexture(getX(), getY(), 0, this.destType.getPathingPixelMap(), - EnumSet.of(CBuildingPathingType.BLIGHTED), EnumSet.noneOf(CBuildingPathingType.class), - game.getWorldCollision(), null); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CDestructableType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CDestructableType.java deleted file mode 100644 index db73f8b9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CDestructableType.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import java.awt.image.BufferedImage; -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CDestructableType { - - private final String name; - private final float maxLife; - private final EnumSet targetedAs; - private final String armorType; - private final int buildTime; - private final BufferedImage pathingPixelMap; - private final BufferedImage pathingDeathPixelMap; - - public CDestructableType(final String name, final float maxLife, final EnumSet targetedAs, - final String armorType, final int buildTime, final BufferedImage pathingPixelMap, - final BufferedImage pathingDeathPixelMap) { - this.name = name; - this.maxLife = maxLife; - this.targetedAs = targetedAs; - this.armorType = armorType; - this.buildTime = buildTime; - this.pathingPixelMap = pathingPixelMap; - this.pathingDeathPixelMap = pathingDeathPixelMap; - } - - public String getName() { - return this.name; - } - - public float getMaxLife() { - return this.maxLife; - } - - public EnumSet getTargetedAs() { - return this.targetedAs; - } - - public String getArmorType() { - return this.armorType; - } - - public int getBuildTime() { - return this.buildTime; - } - - public BufferedImage getPathingPixelMap() { - return this.pathingPixelMap; - } - - public BufferedImage getPathingDeathPixelMap() { - return this.pathingDeathPixelMap; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CGameplayConstants.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CGameplayConstants.java deleted file mode 100644 index 05b0eda7..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CGameplayConstants.java +++ /dev/null @@ -1,495 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import java.util.Arrays; - -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.units.Element; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CDefenseType; - -/** - * Stores some gameplay constants at runtime in a java object (symbol table) to - * maybe be faster than a map. - */ -public class CGameplayConstants { - private final float attackHalfAngle; - private final float[][] damageBonusTable; - private final float maxCollisionRadius; - private final float decayTime; - private final float boneDecayTime; - private final float dissipateTime; - private final float bulletDeathTime; - private final float closeEnoughRange; - private final float dawnTimeGameHours; - private final float duskTimeGameHours; - private final float gameDayHours; - private final float gameDayLength; - private final float structureDecayTime; - private final float buildingAngle; - private final float rootAngle; - - private final float defenseArmor; - - private final int heroMaxReviveCostGold; - private final int heroMaxReviveCostLumber; - private final int heroMaxReviveTime; - - private final int heroMaxAwakenCostGold; - private final int heroMaxAwakenCostLumber; - - private final float heroReviveManaStart; - private final float heroReviveManaFactor; - private final float heroReviveLifeFactor; - private final float heroAwakenManaStart; - private final float heroAwakenManaFactor; - private final float heroAwakenLifeFactor; - - private final int heroExpRange; - - private final float reviveBaseFactor; - private final float reviveLevelFactor; - private final float reviveBaseLumberFactor; - private final float reviveLumberLevelFactor; - private final float reviveMaxFactor; - private final float reviveTimeFactor; - private final float reviveMaxTimeFactor; - - private final float awakenBaseFactor; - private final float awakenLevelFactor; - private final float awakenBaseLumberFactor; - private final float awakenLumberLevelFactor; - private final float awakenMaxFactor; - - private final int maxHeroLevel; - private final int maxUnitLevel; - private final int[] needHeroXp; - private final int[] needHeroXpSum; - private final int[] grantHeroXp; - private final int[] grantNormalXp; - private final int[] heroFactorXp; - private final float summonedKillFactor; - private final float strAttackBonus; - private final float strHitPointBonus; - private final float strRegenBonus; - private final float intManaBonus; - private final float intRegenBonus; - private final float agiDefenseBonus; - private final float agiDefenseBase; - private final int agiMoveBonus; - private final float agiAttackSpeedBonus; - - private final int needHeroXPFormulaA; - private final int needHeroXPFormulaB; - private final int needHeroXPFormulaC; - private final int grantHeroXPFormulaA; - private final int grantHeroXPFormulaB; - private final int grantHeroXPFormulaC; - private final int grantNormalXPFormulaA; - private final int grantNormalXPFormulaB; - private final int grantNormalXPFormulaC; - - private final int heroAbilityLevelSkip; - - private final boolean globalExperience; - private final boolean maxLevelHeroesDrainExp; - private final boolean buildingKillsGiveExp; - - private final float dropItemRange; - private final float giveItemRange; - private final float pickupItemRange; - private final float pawnItemRange; - private final float pawnItemRate; - - private final float followRange; - private final float structureFollowRange; - private final float followItemRange; - private final float spellCastRangeBuffer; - - public CGameplayConstants(final DataTable parsedDataTable) { - final Element miscData = parsedDataTable.get("Misc"); - // TODO use radians for half angle - this.attackHalfAngle = (float) Math.toDegrees(miscData.getFieldFloatValue("AttackHalfAngle")); - this.maxCollisionRadius = miscData.getFieldFloatValue("MaxCollisionRadius"); - this.decayTime = miscData.getFieldFloatValue("DecayTime"); - this.boneDecayTime = miscData.getFieldFloatValue("BoneDecayTime"); - this.dissipateTime = miscData.getFieldFloatValue("DissipateTime"); - this.structureDecayTime = miscData.getFieldFloatValue("StructureDecayTime"); - this.bulletDeathTime = miscData.getFieldFloatValue("BulletDeathTime"); - this.closeEnoughRange = miscData.getFieldFloatValue("CloseEnoughRange"); - - this.dawnTimeGameHours = miscData.getFieldFloatValue("Dawn"); - this.duskTimeGameHours = miscData.getFieldFloatValue("Dusk"); - this.gameDayHours = miscData.getFieldFloatValue("DayHours"); - this.gameDayLength = miscData.getFieldFloatValue("DayLength"); - - this.buildingAngle = miscData.getFieldFloatValue("BuildingAngle"); - this.rootAngle = miscData.getFieldFloatValue("RootAngle"); - - final CDefenseType[] defenseTypeOrder = { CDefenseType.SMALL, CDefenseType.MEDIUM, CDefenseType.LARGE, - CDefenseType.FORT, CDefenseType.NORMAL, CDefenseType.HERO, CDefenseType.DIVINE, CDefenseType.NONE, }; - this.damageBonusTable = new float[CAttackType.values().length][defenseTypeOrder.length]; - for (int i = 0; i < CAttackType.VALUES.length; i++) { - Arrays.fill(this.damageBonusTable[i], 1.0f); - final CAttackType attackType = CAttackType.VALUES[i]; - final String damageBonus = miscData.getField("DamageBonus" + attackType.getDamageKey()); - final String[] damageComponents = damageBonus.split(","); - for (int j = 0; j < damageComponents.length; j++) { - if (damageComponents[j].length() > 0) { - final CDefenseType defenseType = defenseTypeOrder[j]; - try { - this.damageBonusTable[i][defenseType.ordinal()] = Float.parseFloat(damageComponents[j]); -// System.out.println(attackType + ":" + defenseType + ": " + damageComponents[j]); - } - catch (final NumberFormatException e) { - throw new RuntimeException("DamageBonus" + attackType.getDamageKey(), e); - } - } - } - } - - this.defenseArmor = miscData.getFieldFloatValue("DefenseArmor"); - - this.globalExperience = miscData.getFieldValue("GlobalExperience") != 0; - this.maxLevelHeroesDrainExp = miscData.getFieldValue("MaxLevelHeroesDrainExp") != 0; - this.buildingKillsGiveExp = miscData.getFieldValue("BuildingKillsGiveExp") != 0; - - this.heroMaxReviveCostGold = miscData.getFieldValue("HeroMaxReviveCostGold"); - this.heroMaxReviveCostLumber = miscData.getFieldValue("HeroMaxReviveCostLumber"); - this.heroMaxReviveTime = miscData.getFieldValue("HeroMaxReviveTime"); - - this.heroMaxAwakenCostGold = miscData.getFieldValue("HeroMaxAwakenCostGold"); - this.heroMaxAwakenCostLumber = miscData.getFieldValue("HeroMaxAwakenCostLumber"); - - this.heroReviveManaStart = miscData.getFieldFloatValue("HeroReviveManaStart"); - this.heroReviveManaFactor = miscData.getFieldFloatValue("HeroReviveManaFactor"); - this.heroReviveLifeFactor = miscData.getFieldFloatValue("HeroReviveLifeFactor"); - this.heroAwakenManaStart = miscData.getFieldFloatValue("HeroAwakenManaStart"); - this.heroAwakenManaFactor = miscData.getFieldFloatValue("HeroAwakenManaFactor"); - this.heroAwakenLifeFactor = miscData.getFieldFloatValue("HeroAwakenLifeFactor"); - - this.heroExpRange = miscData.getFieldValue("HeroExpRange"); - - this.reviveBaseFactor = miscData.getFieldFloatValue("ReviveBaseFactor"); - this.reviveLevelFactor = miscData.getFieldFloatValue("ReviveLevelFactor"); - this.reviveBaseLumberFactor = miscData.getFieldFloatValue("ReviveBaseLumberFactor"); - this.reviveLumberLevelFactor = miscData.getFieldFloatValue("ReviveLumberLevelFactor"); - this.reviveMaxFactor = miscData.getFieldFloatValue("ReviveMaxFactor"); - this.reviveTimeFactor = miscData.getFieldFloatValue("ReviveTimeFactor"); - this.reviveMaxTimeFactor = miscData.getFieldFloatValue("ReviveMaxTimeFactor"); - - this.awakenBaseFactor = miscData.getFieldFloatValue("AwakenBaseFactor"); - this.awakenLevelFactor = miscData.getFieldFloatValue("AwakenLevelFactor"); - this.awakenBaseLumberFactor = miscData.getFieldFloatValue("AwakenBaseLumberFactor"); - this.awakenLumberLevelFactor = miscData.getFieldFloatValue("AwakenLumberLevelFactor"); - this.awakenMaxFactor = miscData.getFieldFloatValue("AwakenMaxFactor"); - - this.maxHeroLevel = miscData.getFieldValue("MaxHeroLevel"); - this.maxUnitLevel = miscData.getFieldValue("MaxUnitLevel"); - - this.needHeroXPFormulaA = miscData.getFieldValue("NeedHeroXPFormulaA"); - this.needHeroXPFormulaB = miscData.getFieldValue("NeedHeroXPFormulaB"); - this.needHeroXPFormulaC = miscData.getFieldValue("NeedHeroXPFormulaC"); - this.grantHeroXPFormulaA = miscData.getFieldValue("GrantHeroXPFormulaA"); - this.grantHeroXPFormulaB = miscData.getFieldValue("GrantHeroXPFormulaB"); - this.grantHeroXPFormulaC = miscData.getFieldValue("GrantHeroXPFormulaC"); - this.grantNormalXPFormulaA = miscData.getFieldValue("GrantNormalXPFormulaA"); - this.grantNormalXPFormulaB = miscData.getFieldValue("GrantNormalXPFormulaB"); - this.grantNormalXPFormulaC = miscData.getFieldValue("GrantNormalXPFormulaC"); - - this.needHeroXp = parseTable(miscData.getField("NeedHeroXP"), this.needHeroXPFormulaA, this.needHeroXPFormulaB, - this.needHeroXPFormulaC, this.maxHeroLevel); - this.needHeroXpSum = new int[this.needHeroXp.length]; - for (int i = 0; i < this.needHeroXpSum.length; i++) { - if (i == 0) { - this.needHeroXpSum[i] = this.needHeroXp[i]; - } - else { - this.needHeroXpSum[i] = this.needHeroXp[i] + this.needHeroXpSum[i - 1]; - } - } - this.grantHeroXp = parseTable(miscData.getField("GrantHeroXP"), this.grantHeroXPFormulaA, - this.grantHeroXPFormulaB, this.grantHeroXPFormulaC, this.maxHeroLevel); - this.grantNormalXp = parseTable(miscData.getField("GrantNormalXP"), this.grantNormalXPFormulaA, - this.grantNormalXPFormulaB, this.grantNormalXPFormulaC, this.maxUnitLevel); - this.heroFactorXp = parseIntArray(miscData.getField("HeroFactorXP")); - this.summonedKillFactor = miscData.getFieldFloatValue("SummonedKillFactor"); - this.strAttackBonus = miscData.getFieldFloatValue("StrAttackBonus"); - this.strHitPointBonus = miscData.getFieldFloatValue("StrHitPointBonus"); - this.strRegenBonus = miscData.getFieldFloatValue("StrRegenBonus"); - this.intManaBonus = miscData.getFieldFloatValue("IntManaBonus"); - this.intRegenBonus = miscData.getFieldFloatValue("IntRegenBonus"); - this.agiDefenseBonus = miscData.getFieldFloatValue("AgiDefenseBonus"); - this.agiDefenseBase = miscData.getFieldFloatValue("AgiDefenseBase"); - this.agiMoveBonus = miscData.getFieldValue("AgiMoveBonus"); - this.agiAttackSpeedBonus = miscData.getFieldFloatValue("AgiAttackSpeedBonus"); - - this.heroAbilityLevelSkip = miscData.getFieldValue("HeroAbilityLevelSkip"); - - this.dropItemRange = miscData.getFieldFloatValue("DropItemRange"); - this.giveItemRange = miscData.getFieldFloatValue("GiveItemRange"); - this.pickupItemRange = miscData.getFieldFloatValue("PickupItemRange"); - this.pawnItemRange = miscData.getFieldFloatValue("PawnItemRange"); - this.pawnItemRate = miscData.getFieldFloatValue("PawnItemRate"); - - this.followRange = miscData.getFieldFloatValue("FollowRange"); - this.structureFollowRange = miscData.getFieldFloatValue("StructureFollowRange"); - this.followItemRange = miscData.getFieldFloatValue("FollowItemRange"); - - this.spellCastRangeBuffer = miscData.getFieldFloatValue("SpellCastRangeBuffer"); - } - - public float getAttackHalfAngle() { - return this.attackHalfAngle; - } - - public float getDamageRatioAgainst(final CAttackType attackType, final CDefenseType defenseType) { - return this.damageBonusTable[attackType.ordinal()][defenseType.ordinal()]; - } - - public float getMaxCollisionRadius() { - return this.maxCollisionRadius; - } - - public float getDecayTime() { - return this.decayTime; - } - - public float getBoneDecayTime() { - return this.boneDecayTime; - } - - public float getDissipateTime() { - return this.dissipateTime; - } - - public float getBulletDeathTime() { - return this.bulletDeathTime; - } - - public float getCloseEnoughRange() { - return this.closeEnoughRange; - } - - public float getGameDayHours() { - return this.gameDayHours; - } - - public float getGameDayLength() { - return this.gameDayLength; - } - - public float getDawnTimeGameHours() { - return this.dawnTimeGameHours; - } - - public float getDuskTimeGameHours() { - return this.duskTimeGameHours; - } - - public float getStructureDecayTime() { - return this.structureDecayTime; - } - - public float getBuildingAngle() { - return this.buildingAngle; - } - - public float getRootAngle() { - return this.rootAngle; - } - - public float getDefenseArmor() { - return this.defenseArmor; - } - - public boolean isGlobalExperience() { - return this.globalExperience; - } - - public boolean isMaxLevelHeroesDrainExp() { - return this.maxLevelHeroesDrainExp; - } - - public boolean isBuildingKillsGiveExp() { - return this.buildingKillsGiveExp; - } - - public int getHeroAbilityLevelSkip() { - return this.heroAbilityLevelSkip; - } - - public int getHeroExpRange() { - return this.heroExpRange; - } - - public int getMaxHeroLevel() { - return this.maxHeroLevel; - } - - public int getMaxUnitLevel() { - return this.maxUnitLevel; - } - - public float getSummonedKillFactor() { - return this.summonedKillFactor; - } - - public float getStrAttackBonus() { - return this.strAttackBonus; - } - - public float getStrHitPointBonus() { - return this.strHitPointBonus; - } - - public float getStrRegenBonus() { - return this.strRegenBonus; - } - - public float getIntManaBonus() { - return this.intManaBonus; - } - - public float getIntRegenBonus() { - return this.intRegenBonus; - } - - public float getAgiDefenseBonus() { - return this.agiDefenseBonus; - } - - public float getAgiDefenseBase() { - return this.agiDefenseBase; - } - - public int getAgiMoveBonus() { - return this.agiMoveBonus; - } - - public float getAgiAttackSpeedBonus() { - return this.agiAttackSpeedBonus; - } - - public float getHeroFactorXp(final int level) { - return getTableValue(this.heroFactorXp, level) / 100f; - } - - public int getNeedHeroXP(final int level) { - return getTableValue(this.needHeroXp, level); - } - - public int getNeedHeroXPSum(final int level) { - return getTableValue(this.needHeroXpSum, level); - } - - public int getGrantHeroXP(final int level) { - return getTableValue(this.grantHeroXp, level); - } - - public int getGrantNormalXP(final int level) { - return getTableValue(this.grantNormalXp, level); - } - - public float getDropItemRange() { - return this.dropItemRange; - } - - public float getPickupItemRange() { - return this.pickupItemRange; - } - - public float getGiveItemRange() { - return this.giveItemRange; - } - - public float getPawnItemRange() { - return this.pawnItemRange; - } - - public float getPawnItemRate() { - return this.pawnItemRate; - } - - public float getFollowRange() { - return this.followRange; - } - - public float getStructureFollowRange() { - return this.structureFollowRange; - } - - public float getFollowItemRange() { - return this.followItemRange; - } - - public float getSpellCastRangeBuffer() { - return this.spellCastRangeBuffer; - } - - public int getHeroReviveGoldCost(final int originalCost, final int level) { - final int goldRevivalCost = (int) (originalCost - * (this.reviveBaseFactor + (this.reviveLevelFactor * (level - 1)))); - return Math.min(goldRevivalCost, (int) (originalCost * this.reviveMaxFactor)); - } - - public int getHeroReviveLumberCost(final int originalCost, final int level) { - final int lumberRevivalCost = (int) (originalCost - * (this.reviveBaseLumberFactor + (this.reviveLumberLevelFactor * (level - 1)))); - return Math.min(lumberRevivalCost, (int) (originalCost * this.reviveMaxFactor)); - } - - public int getHeroReviveTime(final int originalTime, final int level) { - final int revivalTime = (int) (originalTime * level * this.reviveTimeFactor); - return Math.min(revivalTime, (int) (originalTime * this.reviveMaxTimeFactor)); - } - - public float getHeroReviveLifeFactor() { - return this.heroReviveLifeFactor; - } - - public float getHeroReviveManaFactor() { - return this.heroReviveManaFactor; - } - - public float getHeroReviveManaStart() { - return this.heroReviveManaStart; - } - - private static int getTableValue(final int[] table, int level) { - if (level <= 0) { - return 0; - } - if (level > table.length) { - level = table.length; - } - return table[level - 1]; - } - - /* - * This incorporates the function "f(x)" documented both on - * http://classic.battle.net/war3/basics/heroes.shtml and also on MiscGame.txt. - */ - private static int[] parseTable(final String txt, final int formulaA, final int formulaB, final int formulaC, - final int tableSize) { - final String[] splitTxt = txt.split(","); - final int[] result = new int[tableSize]; - for (int i = 0; i < tableSize; i++) { - if (i < splitTxt.length) { - result[i] = Integer.parseInt(splitTxt[i]); - } - else { - result[i] = (formulaA * result[i - 1]) + (formulaB * i) + formulaC; - } - } - return result; - } - - private static int[] parseIntArray(final String txt) { - final String[] splitTxt = txt.split(","); - final int[] result = new int[splitTxt.length]; - for (int i = 0; i < splitTxt.length; i++) { - result[i] = Integer.parseInt(splitTxt[i]); - } - return result; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CItem.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CItem.java deleted file mode 100644 index 75b32e57..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CItem.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import java.util.EnumSet; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.MovementType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CItem extends CWidget { - private final War3ID typeId; - private final CItemType itemType; - private boolean hidden; - - public CItem(final int handleId, final float x, final float y, final float life, final War3ID typeId, - final CItemType itemTypeInstance) { - super(handleId, x, y, life); - this.typeId = typeId; - this.itemType = itemTypeInstance; - } - - @Override - public float getFlyHeight() { - return 0; - } - - @Override - public float getImpactZ() { - return 0; // TODO probably from ItemType - } - - @Override - public void damage(final CSimulation simulation, final CUnit source, final CAttackType attackType, - final String weaponType, final float damage) { - this.life -= damage; - simulation.itemDamageEvent(this, weaponType, this.itemType.getArmorType()); - } - - @Override - public boolean canBeTargetedBy(final CSimulation simulation, final CUnit source, - final EnumSet targetsAllowed) { - return targetsAllowed.contains(CTargetType.ITEM); - } - - public void setX(final float x, final CWorldCollision collision) { - super.setX(x); - } - - public void setY(final float y, final CWorldCollision collision) { - super.setY(y); - } - - @Override - public T visit(final AbilityTargetVisitor visitor) { - return visitor.accept(this); - } - - public War3ID getTypeId() { - return this.typeId; - } - - public CItemType getItemType() { - return this.itemType; - } - - public void setHidden(final boolean hidden) { - this.hidden = hidden; - } - - public boolean isHidden() { - return this.hidden; - } - - @Override - public float getMaxLife() { - return itemType.getMaxLife(); - } - - public void setPointAndCheckUnstuck(final float newX, final float newY, final CSimulation game) { - final CWorldCollision collision = game.getWorldCollision(); - final PathingGrid pathingGrid = game.getPathingGrid(); - ; - float outputX = newX, outputY = newY; - int checkX = 0; - int checkY = 0; - float collisionSize; - tempRect.setSize(16, 16); - collisionSize = 16; - for (int i = 0; i < 300; i++) { - final float centerX = newX + (checkX * 64); - final float centerY = newY + (checkY * 64); - tempRect.setCenter(centerX, centerY); - if (pathingGrid.isPathable(centerX, centerY, MovementType.FOOT, collisionSize)) { - outputX = centerX; - outputY = centerY; - break; - } - final double angle = ((((int) Math.floor(Math.sqrt((4 * i) + 1))) % 4) * Math.PI) / 2; - checkX -= (int) Math.cos(angle); - checkY -= (int) Math.sin(angle); - } - setX(outputX); - setY(outputY); - } - - @Override - public boolean isInvulnerable() { - return false; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CItemType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CItemType.java deleted file mode 100644 index 98ea433c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CItemType.java +++ /dev/null @@ -1,156 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import java.util.List; - -import com.etheller.warsmash.util.War3ID; - -public class CItemType { - private final List abilityList; - private final War3ID cooldownGroup; - private final boolean ignoreCooldown; - private final int numberOfCharges; - private final boolean activelyUsed; - private final boolean perishable; - private final boolean useAutomaticallyWhenAcquired; - private final int goldCost; - private final int lumberCost; - private final int stockMax; - private final int stockReplenishInterval; - private final int stockStartDelay; - private final int maxLife; - private final String armorType; - private final int level; - private final int levelUnclassified; - private final int priority; - private final boolean sellable; - private final boolean pawnable; - private final boolean droppedWhenCarrierDies; - private final boolean canBeDropped; - private final boolean validTargetForTransformation; - private final boolean includeAsRandomChoice; - - public CItemType(final List abilityList, final War3ID cooldownGroup, final boolean ignoreCooldown, - final int numberOfCharges, final boolean activelyUsed, final boolean perishable, - final boolean useAutomaticallyWhenAcquired, final int goldCost, final int lumberCost, final int stockMax, - final int stockReplenishInterval, final int stockStartDelay, final int maxLife, final String armorType, - final int level, final int levelUnclassified, final int priority, final boolean sellable, - final boolean pawnable, final boolean droppedWhenCarrierDies, final boolean canBeDropped, - final boolean validTargetForTransformation, final boolean includeAsRandomChoice) { - this.abilityList = abilityList; - this.cooldownGroup = cooldownGroup; - this.ignoreCooldown = ignoreCooldown; - this.numberOfCharges = numberOfCharges; - this.activelyUsed = activelyUsed; - this.perishable = perishable; - this.useAutomaticallyWhenAcquired = useAutomaticallyWhenAcquired; - this.goldCost = goldCost; - this.lumberCost = lumberCost; - this.stockMax = stockMax; - this.stockReplenishInterval = stockReplenishInterval; - this.stockStartDelay = stockStartDelay; - this.maxLife = maxLife; - this.armorType = armorType; - this.level = level; - this.levelUnclassified = levelUnclassified; - this.priority = priority; - this.sellable = sellable; - this.pawnable = pawnable; - this.droppedWhenCarrierDies = droppedWhenCarrierDies; - this.canBeDropped = canBeDropped; - this.validTargetForTransformation = validTargetForTransformation; - this.includeAsRandomChoice = includeAsRandomChoice; - } - - public List getAbilityList() { - return this.abilityList; - } - - public War3ID getCooldownGroup() { - return this.cooldownGroup; - } - - public boolean isIgnoreCooldown() { - return this.ignoreCooldown; - } - - public int getNumberOfCharges() { - return this.numberOfCharges; - } - - public boolean isActivelyUsed() { - return this.activelyUsed; - } - - public boolean isPerishable() { - return this.perishable; - } - - public boolean isUseAutomaticallyWhenAcquired() { - return this.useAutomaticallyWhenAcquired; - } - - public int getGoldCost() { - return this.goldCost; - } - - public int getLumberCost() { - return this.lumberCost; - } - - public int getStockMax() { - return this.stockMax; - } - - public int getStockReplenishInterval() { - return this.stockReplenishInterval; - } - - public int getStockStartDelay() { - return this.stockStartDelay; - } - - public int getMaxLife() { - return this.maxLife; - } - - public String getArmorType() { - return this.armorType; - } - - public int getLevel() { - return this.level; - } - - public int getLevelUnclassified() { - return this.levelUnclassified; - } - - public int getPriority() { - return this.priority; - } - - public boolean isSellable() { - return this.sellable; - } - - public boolean isPawnable() { - return this.pawnable; - } - - public boolean isDroppedWhenCarrierDies() { - return this.droppedWhenCarrierDies; - } - - public boolean isCanBeDropped() { - return this.canBeDropped; - } - - public boolean isValidTargetForTransformation() { - return this.validTargetForTransformation; - } - - public boolean isIncludeAsRandomChoice() { - return this.includeAsRandomChoice; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CPlayerStateListener.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CPlayerStateListener.java deleted file mode 100644 index ff515a7e..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CPlayerStateListener.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import com.etheller.warsmash.util.SubscriberSetNotifier; - -public interface CPlayerStateListener { - void goldChanged(); - - void lumberChanged(); - - void foodChanged(); - - void upkeepChanged(); - - void heroDeath(); - - public static final class CPlayerStateNotifier extends SubscriberSetNotifier - implements CPlayerStateListener { - @Override - public void goldChanged() { - for (final CPlayerStateListener listener : set) { - listener.goldChanged(); - } - } - - @Override - public void lumberChanged() { - for (final CPlayerStateListener listener : set) { - listener.lumberChanged(); - } - } - - @Override - public void foodChanged() { - for (final CPlayerStateListener listener : set) { - listener.foodChanged(); - } - } - - @Override - public void upkeepChanged() { - for (final CPlayerStateListener listener : set) { - listener.upkeepChanged(); - } - } - - @Override - public void heroDeath() { - for (final CPlayerStateListener listener : set) { - listener.heroDeath(); - } - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulation.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulation.java deleted file mode 100644 index 588614cb..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulation.java +++ /dev/null @@ -1,526 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import java.awt.geom.Point2D; -import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Random; - -import com.badlogic.gdx.math.Rectangle; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.trigger.RemovableTriggerEvent; -import com.etheller.interpreter.ast.scope.trigger.Trigger; -import com.etheller.interpreter.ast.scope.variableevent.CLimitOp; -import com.etheller.interpreter.ast.scope.variableevent.VariableEvent; -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.units.manager.MutableObjectData; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.RemovablePathingMapInstance; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorMove; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackInstant; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissile; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.projectile.CAttackProjectile; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.CBasePlayer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.CPlayerAPI; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.War3MapConfig; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.War3MapConfigStartLoc; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.data.CAbilityData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.data.CDestructableData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.data.CItemData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.data.CUnitData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CPathfindingProcessor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerJass; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRace; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.region.CRegionManager; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.timers.CTimer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandErrorListener; - -public class CSimulation implements CPlayerAPI { - private final CAbilityData abilityData; - private final CUnitData unitData; - private final CDestructableData destructableData; - private final CItemData itemData; - private final List units; - private final List newUnits; - private final List removedUnits; - private final List destructables; - private final List items; - private final List players; - private final List projectiles; - private final List newProjectiles; - private final HandleIdAllocator handleIdAllocator; - private transient final SimulationRenderController simulationRenderController; - private int gameTurnTick = 0; - private final PathingGrid pathingGrid; - private final CWorldCollision worldCollision; - private final CPathfindingProcessor[] pathfindingProcessors; - private final CGameplayConstants gameplayConstants; - private final Random seededRandom; - private float currentGameDayTimeElapsed; - private final Map handleIdToUnit = new HashMap<>(); - private final Map handleIdToDestructable = new HashMap<>(); - private final Map handleIdToItem = new HashMap<>(); - private final Map handleIdToAbility = new HashMap<>(); - private final LinkedList activeTimers = new LinkedList<>(); - private transient CommandErrorListener commandErrorListener; - private final CRegionManager regionManager; - private final List timeOfDayVariableEvents = new ArrayList<>(); - - public CSimulation(final War3MapConfig config, final DataTable miscData, final MutableObjectData parsedUnitData, - final MutableObjectData parsedItemData, final MutableObjectData parsedDestructableData, - final MutableObjectData parsedAbilityData, final SimulationRenderController simulationRenderController, - final PathingGrid pathingGrid, final Rectangle entireMapBounds, final Random seededRandom, - final CommandErrorListener commandErrorListener) { - this.gameplayConstants = new CGameplayConstants(miscData); - this.simulationRenderController = simulationRenderController; - this.pathingGrid = pathingGrid; - this.abilityData = new CAbilityData(parsedAbilityData); - this.unitData = new CUnitData(this.gameplayConstants, parsedUnitData, this.abilityData, - this.simulationRenderController); - this.destructableData = new CDestructableData(parsedDestructableData, simulationRenderController); - this.itemData = new CItemData(parsedItemData); - this.units = new ArrayList<>(); - this.newUnits = new ArrayList<>(); - this.removedUnits = new ArrayList<>(); - this.destructables = new ArrayList<>(); - this.items = new ArrayList<>(); - this.projectiles = new ArrayList<>(); - this.newProjectiles = new ArrayList<>(); - this.handleIdAllocator = new HandleIdAllocator(); - this.worldCollision = new CWorldCollision(entireMapBounds, this.gameplayConstants.getMaxCollisionRadius()); - this.regionManager = new CRegionManager(entireMapBounds, pathingGrid); - this.pathfindingProcessors = new CPathfindingProcessor[WarsmashConstants.MAX_PLAYERS]; - for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) { - this.pathfindingProcessors[i] = new CPathfindingProcessor(pathingGrid, this.worldCollision); - } - this.seededRandom = seededRandom; - this.players = new ArrayList<>(); - for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) { - final CBasePlayer configPlayer = config.getPlayer(i); - final War3MapConfigStartLoc startLoc = config.getStartLoc(configPlayer.getStartLocationIndex()); - final CRace defaultRace = CRace.UNDEAD; - final CPlayer newPlayer = new CPlayer(defaultRace, new float[] { startLoc.getX(), startLoc.getY() }, - configPlayer); - this.players.add(newPlayer); - } - this.players.get(this.players.size() - 4).setName(miscData.getLocalizedString("WESTRING_PLAYER_NA")); - this.players.get(this.players.size() - 3).setName(miscData.getLocalizedString("WESTRING_PLAYER_NV")); - this.players.get(this.players.size() - 2).setName(miscData.getLocalizedString("WESTRING_PLAYER_NE")); - final CPlayer neutralPassive = this.players.get(this.players.size() - 1); - neutralPassive.setName(miscData.getLocalizedString("WESTRING_PLAYER_NP")); - - for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) { - final CPlayer cPlayer = this.players.get(i); - cPlayer.setAlliance(neutralPassive, CAllianceType.PASSIVE, true); - neutralPassive.setAlliance(cPlayer, CAllianceType.PASSIVE, true); - } - - this.commandErrorListener = commandErrorListener; - - } - - public CUnitData getUnitData() { - return this.unitData; - } - - public CAbilityData getAbilityData() { - return this.abilityData; - } - - public CDestructableData getDestructableData() { - return this.destructableData; - } - - public CItemData getItemData() { - return this.itemData; - } - - public List getUnits() { - return this.units; - } - - public List getDestructables() { - return this.destructables; - } - - public void registerTimer(final CTimer timer) { - final ListIterator listIterator = this.activeTimers.listIterator(); - while (listIterator.hasNext()) { - final CTimer nextTimer = listIterator.next(); - if (nextTimer.getEngineFireTick() > timer.getEngineFireTick()) { - listIterator.previous(); - listIterator.add(timer); - } - } - this.activeTimers.add(timer); - } - - public void unregisterTimer(final CTimer time) { - this.activeTimers.remove(time); - } - - public CUnit internalCreateUnit(final War3ID typeId, final int playerIndex, final float x, final float y, - final float facing, final BufferedImage buildingPathingPixelMap, - final RemovablePathingMapInstance pathingInstance) { - final CUnit unit = this.unitData.create(this, playerIndex, typeId, x, y, facing, buildingPathingPixelMap, - this.handleIdAllocator, pathingInstance); - this.newUnits.add(unit); - this.handleIdToUnit.put(unit.getHandleId(), unit); - this.worldCollision.addUnit(unit); - if (unit.getHeroData() != null) { - heroCreateEvent(unit); - } - return unit; - } - - public CDestructable createDestructable(final War3ID typeId, final float x, final float y, - final RemovablePathingMapInstance pathingInstance, final RemovablePathingMapInstance pathingInstanceDeath) { - final CDestructable dest = this.destructableData.create(this, typeId, x, y, this.handleIdAllocator, - pathingInstance, pathingInstanceDeath); - this.handleIdToDestructable.put(dest.getHandleId(), dest); - this.destructables.add(dest); - dest.setBlighted(dest.checkIsOnBlight(this)); - return dest; - } - - public CItem createItem(final War3ID alias, final float unitX, final float unitY) { - final CItem item = this.itemData.create(this, alias, unitX, unitY, this.handleIdAllocator.createId()); - this.handleIdToItem.put(item.getHandleId(), item); - this.items.add(item); - return item; - } - - public CUnit createUnit(final War3ID typeId, final int playerIndex, final float x, final float y, - final float facing) { - return this.simulationRenderController.createUnit(this, typeId, playerIndex, x, y, facing); - } - - public CUnit getUnit(final int handleId) { - return this.handleIdToUnit.get(handleId); - } - - public CAbility getAbility(final int handleId) { - return this.handleIdToAbility.get(handleId); - } - - protected void onAbilityAddedToUnit(final CUnit unit, final CAbility ability) { - this.handleIdToAbility.put(ability.getHandleId(), ability); - } - - protected void onAbilityRemovedFromUnit(final CUnit unit, final CAbility ability) { - this.handleIdToAbility.remove(ability.getHandleId()); - } - - public CAttackProjectile createProjectile(final CUnit source, final float launchX, final float launchY, - final float launchFacing, final CUnitAttackMissile attack, final AbilityTarget target, final float damage, - final int bounceIndex, final CUnitAttackListener attackListener) { - final CAttackProjectile projectile = this.simulationRenderController.createAttackProjectile(this, launchX, - launchY, launchFacing, source, attack, target, damage, bounceIndex, attackListener); - this.newProjectiles.add(projectile); - return projectile; - } - - public void createInstantAttackEffect(final CUnit source, final CUnitAttackInstant attack, final CWidget target) { - this.simulationRenderController.createInstantAttackEffect(this, source, attack, target); - } - - public PathingGrid getPathingGrid() { - return this.pathingGrid; - } - - public void findNaiveSlowPath(final CUnit ignoreIntersectionsWithThisUnit, - final CUnit ignoreIntersectionsWithThisSecondUnit, final float startX, final float startY, - final Point2D.Float goal, final PathingGrid.MovementType movementType, final float collisionSize, - final boolean allowSmoothing, final CBehaviorMove queueItem) { - final int playerIndex = queueItem.getUnit().getPlayerIndex(); - this.pathfindingProcessors[playerIndex].findNaiveSlowPath(ignoreIntersectionsWithThisUnit, - ignoreIntersectionsWithThisSecondUnit, startX, startY, goal, movementType, collisionSize, - allowSmoothing, queueItem); - } - - public void removeFromPathfindingQueue(final CBehaviorMove behaviorMove) { - final int playerIndex = behaviorMove.getUnit().getPlayerIndex(); - this.pathfindingProcessors[playerIndex].removeFromPathfindingQueue(behaviorMove); - } - - public void update() { - final Iterator unitIterator = this.units.iterator(); - while (unitIterator.hasNext()) { - final CUnit unit = unitIterator.next(); - if (unit.update(this)) { - unitIterator.remove(); - for (final CAbility ability : unit.getAbilities()) { - this.handleIdToAbility.remove(ability.getHandleId()); - } - this.handleIdToUnit.remove(unit.getHandleId()); - this.simulationRenderController.removeUnit(unit); - getPlayerHeroes(unit.getPlayerIndex()).remove(unit); - unit.onRemove(this); - } - } - finishAddingNewUnits(); - final Iterator projectileIterator = this.projectiles.iterator(); - while (projectileIterator.hasNext()) { - final CAttackProjectile projectile = projectileIterator.next(); - if (projectile.update(this)) { - projectileIterator.remove(); - } - } - this.projectiles.addAll(this.newProjectiles); - this.newProjectiles.clear(); - for (final CPathfindingProcessor pathfindingProcessor : this.pathfindingProcessors) { - pathfindingProcessor.update(this); - } - this.gameTurnTick++; - final float timeOfDayBefore = getGameTimeOfDay(); - this.currentGameDayTimeElapsed = (this.currentGameDayTimeElapsed + WarsmashConstants.SIMULATION_STEP_TIME) - % this.gameplayConstants.getGameDayLength(); - final float timeOfDayAfter = getGameTimeOfDay(); - while (!this.activeTimers.isEmpty() && (this.activeTimers.peek().getEngineFireTick() <= this.gameTurnTick)) { - this.activeTimers.pop().fire(this); - } - for (final TimeOfDayVariableEvent timeOfDayEvent : this.timeOfDayVariableEvents) { - if (!timeOfDayEvent.isMatching(timeOfDayBefore) && timeOfDayEvent.isMatching(timeOfDayAfter)) { - timeOfDayEvent.fire(); - } - } - - } - - public void removeUnit(final CUnit unit) { - this.removedUnits.add(unit); - } - - private void finishAddingNewUnits() { - this.units.addAll(this.newUnits); - this.newUnits.clear(); - for (final CUnit unit : this.removedUnits) { - this.units.remove(unit); - for (final CAbility ability : unit.getAbilities()) { - this.handleIdToAbility.remove(ability.getHandleId()); - } - this.handleIdToUnit.remove(unit.getHandleId()); - this.simulationRenderController.removeUnit(unit); - getPlayerHeroes(unit.getPlayerIndex()).remove(unit); - unit.onRemove(this); - } - this.removedUnits.clear(); - } - - public float getGameTimeOfDay() { - return (this.currentGameDayTimeElapsed / this.gameplayConstants.getGameDayLength()) - * this.gameplayConstants.getGameDayHours(); - } - - public int getGameTurnTick() { - return this.gameTurnTick; - } - - public CWorldCollision getWorldCollision() { - return this.worldCollision; - } - - public CRegionManager getRegionManager() { - return this.regionManager; - } - - public CGameplayConstants getGameplayConstants() { - return this.gameplayConstants; - } - - public Random getSeededRandom() { - return this.seededRandom; - } - - public void unitDamageEvent(final CUnit damagedUnit, final String weaponSound, final String armorType) { - this.simulationRenderController.spawnDamageSound(damagedUnit, weaponSound, armorType); - } - - public void destructableDamageEvent(final CDestructable damagedDestructable, final String weaponSound, - final String armorType) { - this.simulationRenderController.spawnDamageSound(damagedDestructable, weaponSound, armorType); - } - - public void itemDamageEvent(final CItem damageItem, final String weaponSound, final String armorType) { - this.simulationRenderController.spawnDamageSound(damageItem, weaponSound, armorType); - } - - public void unitConstructedEvent(final CUnit constructingUnit, final CUnit constructedStructure) { - this.simulationRenderController.spawnUnitConstructionSound(constructingUnit, constructedStructure); - } - - @Override - public CPlayer getPlayer(final int index) { - return this.players.get(index); - } - - public CommandErrorListener getCommandErrorListener(final int playerIndex) { - return this.commandErrorListener; - } - - public void unitConstructFinishEvent(final CUnit constructedStructure) { - final CPlayer player = getPlayer(constructedStructure.getPlayerIndex()); - player.addTechtreeUnlocked(constructedStructure.getTypeId()); - this.simulationRenderController.spawnUnitConstructionFinishSound(constructedStructure); - } - - public void createBuildingDeathEffect(final CUnit cUnit) { - this.simulationRenderController.spawnBuildingDeathEffect(cUnit); - } - - public HandleIdAllocator getHandleIdAllocator() { - return this.handleIdAllocator; - } - - public void unitTrainedEvent(final CUnit trainingUnit, final CUnit trainedUnit) { - this.simulationRenderController.spawnUnitReadySound(trainedUnit); - } - - public void heroReviveEvent(final CUnit trainingUnit, final CUnit trainedUnit) { - this.simulationRenderController.heroRevived(trainedUnit); - this.simulationRenderController.spawnUnitReadySound(trainedUnit); - } - - public void unitRepositioned(final CUnit cUnit) { - this.simulationRenderController.unitRepositioned(cUnit); - } - - public void unitGainResourceEvent(final CUnit unit, final ResourceType resourceType, final int amount) { - this.simulationRenderController.spawnGainResourceTextTag(unit, resourceType, amount); - } - - public void unitGainLevelEvent(final CUnit unit) { - this.players.get(unit.getPlayerIndex()).fireHeroLevelEvents(unit); - this.simulationRenderController.spawnGainLevelEffect(unit); - } - - public void heroCreateEvent(final CUnit hero) { - getPlayerHeroes(hero.getPlayerIndex()).add(hero); - } - - public void unitPickUpItemEvent(final CUnit cUnit, final CItem item) { - this.simulationRenderController.spawnUIUnitGetItemSound(cUnit, item); - } - - public void unitDropItemEvent(final CUnit cUnit, final CItem item) { - this.simulationRenderController.spawnUIUnitDropItemSound(cUnit, item); - } - - public List getPlayerHeroes(final int playerIndex) { - return this.players.get(playerIndex).getHeroes(); - } - - public void unitsLoaded() { - // called on startup after the system loads the map's units layer, but not any - // custom scripts yet - finishAddingNewUnits(); - for (final CUnit unit : this.units) { - final CPlayer player = this.players.get(unit.getPlayerIndex()); - player.setUnitFoodUsed(unit, unit.getUnitType().getFoodUsed()); - player.setUnitFoodMade(unit, unit.getUnitType().getFoodMade()); - player.addTechtreeUnlocked(unit.getTypeId()); - } - } - - public CWidget getWidget(final int handleId) { - final CUnit unit = this.handleIdToUnit.get(handleId); - if (unit != null) { - return unit; - } - final CDestructable destructable = this.handleIdToDestructable.get(handleId); - if (destructable != null) { - return destructable; - } - final CItem item = this.handleIdToItem.get(handleId); - if (item != null) { - return item; - } - return null; - } - - public void createEffectOnUnit(final CUnit unit, final String effectPath) { - this.simulationRenderController.spawnEffectOnUnit(unit, effectPath); - } - - public void createSpellEffectOnUnit(final CUnit unit, final War3ID alias) { - this.simulationRenderController.spawnSpellEffectOnUnit(unit, alias); - } - - public void unitSoundEffectEvent(final CUnit caster, final War3ID alias) { - this.simulationRenderController.spawnAbilitySoundEffect(caster, alias); - } - - public void unitPreferredSelectionReplacement(final CUnit unit, final CUnit newUnit) { - this.simulationRenderController.unitPreferredSelectionReplacement(unit, newUnit); - } - - public RemovableTriggerEvent registerTimeOfDayEvent(final GlobalScope globalScope, final Trigger trigger, - final CLimitOp opcode, final double doubleValue) { - final TimeOfDayVariableEvent timeOfDayVariableEvent = new TimeOfDayVariableEvent(trigger, opcode, doubleValue, - globalScope); - this.timeOfDayVariableEvents.add(timeOfDayVariableEvent); - return new RemovableTriggerEvent() { - @Override - public void remove() { - CSimulation.this.timeOfDayVariableEvents.remove(timeOfDayVariableEvent); - } - }; - } - - public void heroDeathEvent(final CUnit cUnit) { - this.simulationRenderController.heroDeathEvent(cUnit); - } - - public void heroDissipateEvent(final CUnit cUnit) { - getPlayer(cUnit.getPlayerIndex()).onHeroDeath(cUnit); - } - - public void removeItem(final CItem cItem) { - cItem.setHidden(true); // TODO fix - cItem.setLife(this, 0); - } - - private static final class TimeOfDayVariableEvent extends VariableEvent { - private final GlobalScope globalScope; - - public TimeOfDayVariableEvent(final Trigger trigger, final CLimitOp limitOp, final double doubleValue, - final GlobalScope globalScope) { - super(trigger, limitOp, doubleValue); - this.globalScope = globalScope; - } - - public void fire() { - fire(this.globalScope); - } - } - - public RemovableTriggerEvent registerEventPlayerDefeat(final GlobalScope globalScope, final Trigger whichTrigger, - final CPlayerJass whichPlayer) { - if (true) { - throw new UnsupportedOperationException("registerEventPlayerDefeat is NYI"); - } - return RemovableTriggerEvent.DO_NOTHING; - } - - public RemovableTriggerEvent registerEventPlayerVictory(final GlobalScope globalScope, final Trigger whichTrigger, - final CPlayerJass whichPlayer) { - if (true) { - throw new UnsupportedOperationException("registerEventPlayerVictory is NYI"); - } - return RemovableTriggerEvent.DO_NOTHING; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulationMapData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulationMapData.java deleted file mode 100644 index 21c2147e..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CSimulationMapData.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -/** - * Provides limited access to game map data when necessary for the game - * simulation logic. Do not add methods to this to query anything that isn't - * going to be network sync'ed. - */ -public interface CSimulationMapData { - short getTerrainPathing(float x, float y); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnit.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnit.java deleted file mode 100644 index a3f003df..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnit.java +++ /dev/null @@ -1,1747 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; -import java.util.Set; - -import com.badlogic.gdx.math.Rectangle; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.RemovablePathingMapInstance; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitStateListener.CUnitStateNotifier; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityBuildInProgress; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CAbilityHero; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.inventory.CAbilityInventory; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.mine.CAbilityGoldMine; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttackListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttackMove; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorFollow; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorHoldPosition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorMove; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorPatrol; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorStop; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrder; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrderNoTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrderTargetPoint; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrderTargetWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.region.CRegion; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.region.CRegionEnumFunction; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.region.CRegionManager; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.BooleanAbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.BooleanAbilityTargetCheckReceiver; - -public class CUnit extends CWidget { - private static RegionCheckerImpl regionCheckerImpl = new RegionCheckerImpl(); - - private War3ID typeId; - private float facing; // degrees - private float mana; - private int maximumLife; - private int maximumMana; - private int speed; - private int agilityDefenseBonus; - private int permanentDefenseBonus; - private int temporaryDefenseBonus; - - private int currentDefenseDisplay; - private int currentDefense; - - private int cooldownEndTime = 0; - private float flyHeight; - private int playerIndex; - - private final List abilities = new ArrayList<>(); - - private CBehavior currentBehavior; - private final Queue orderQueue = new LinkedList<>(); - private final CUnitType unitType; - - private Rectangle collisionRectangle; - private RemovablePathingMapInstance pathingInstance; - - private final EnumSet classifications = EnumSet.noneOf(CUnitClassification.class); - - private int deathTurnTick; - private boolean corpse; - private boolean boneCorpse; - - private transient CUnitAnimationListener unitAnimationListener; - - // if you use triggers for this then the transient tag here becomes really - // questionable -- it already was -- but I meant for those to inform us - // which fields shouldn't be persisted if we do game state save later - private transient CUnitStateNotifier stateNotifier = new CUnitStateNotifier(); - private transient List stateListenersUpdates = new ArrayList<>(); - private final float acquisitionRange; - private transient static AutoAttackTargetFinderEnum autoAttackTargetFinderEnum = new AutoAttackTargetFinderEnum(); - - private transient CBehaviorMove moveBehavior; - private transient CBehaviorAttack attackBehavior; - private transient CBehaviorAttackMove attackMoveBehavior; - private transient CBehaviorFollow followBehavior; - private transient CBehaviorPatrol patrolBehavior; - private transient CBehaviorStop stopBehavior; - private transient CBehaviorHoldPosition holdPositionBehavior; - private boolean constructing = false; - private float constructionProgress; - private boolean hidden = false; - private boolean paused = false; - private boolean acceptingOrders = true; - private boolean invulnerable = false; - private CBehavior defaultBehavior; - private COrder lastStartedOrder = null; - private CUnit workerInside; - private final War3ID[] buildQueue = new War3ID[WarsmashConstants.BUILD_QUEUE_SIZE]; - private final QueueItemType[] buildQueueTypes = new QueueItemType[WarsmashConstants.BUILD_QUEUE_SIZE]; - private boolean queuedUnitFoodPaid = false; - private AbilityTarget rallyPoint; - - private int foodMade; - private int foodUsed; - - private List unitSpecificAttacks; - private transient Set containingRegions = new LinkedHashSet<>(); - private transient Set priorContainingRegions = new LinkedHashSet<>(); - - public CUnit(final int handleId, final int playerIndex, final float x, final float y, final float life, - final War3ID typeId, final float facing, final float mana, final int maximumLife, final int maximumMana, - final int speed, final CUnitType unitType, final RemovablePathingMapInstance pathingInstance) { - super(handleId, x, y, life); - this.playerIndex = playerIndex; - this.typeId = typeId; - this.facing = facing; - this.mana = mana; - this.maximumLife = maximumLife; - this.maximumMana = maximumMana; - this.speed = speed; - this.pathingInstance = pathingInstance; - this.flyHeight = unitType.getDefaultFlyingHeight(); - this.unitType = unitType; - this.classifications.addAll(unitType.getClassifications()); - this.acquisitionRange = unitType.getDefaultAcquisitionRange(); - this.stopBehavior = new CBehaviorStop(this); - this.defaultBehavior = this.stopBehavior; - this.currentBehavior = this.defaultBehavior; - } - - private void computeDerivedFields() { - this.currentDefenseDisplay = this.unitType.getDefense() + this.agilityDefenseBonus + this.permanentDefenseBonus; - this.currentDefense = this.currentDefenseDisplay + this.temporaryDefenseBonus; - } - - public void setAgilityDefenseBonus(final int agilityDefenseBonus) { - this.agilityDefenseBonus = agilityDefenseBonus; - computeDerivedFields(); - } - - public void setPermanentDefenseBonus(final int permanentDefenseBonus) { - this.permanentDefenseBonus = permanentDefenseBonus; - computeDerivedFields(); - } - - public void setTemporaryDefenseBonus(final int temporaryDefenseBonus) { - this.temporaryDefenseBonus = temporaryDefenseBonus; - computeDerivedFields(); - } - - public int getTemporaryDefenseBonus() { - return this.temporaryDefenseBonus; - } - - public int getCurrentDefenseDisplay() { - return this.currentDefenseDisplay; - } - - public void setUnitAnimationListener(final CUnitAnimationListener unitAnimationListener) { - this.unitAnimationListener = unitAnimationListener; - this.unitAnimationListener.playAnimation(true, PrimaryTag.STAND, SequenceUtils.EMPTY, 1.0f, true); - } - - public CUnitAnimationListener getUnitAnimationListener() { - return this.unitAnimationListener; - } - - public void add(final CSimulation simulation, final CAbility ability) { - this.abilities.add(ability); - simulation.onAbilityAddedToUnit(this, ability); - ability.onAdd(simulation, this); - } - - public void remove(final CSimulation simulation, final CAbility ability) { - this.abilities.remove(ability); - simulation.onAbilityRemovedFromUnit(this, ability); - ability.onRemove(simulation, this); - } - - public War3ID getTypeId() { - return this.typeId; - } - - /** - * @return facing in DEGREES - */ - public float getFacing() { - return this.facing; - } - - public float getMana() { - return this.mana; - } - - public int getMaximumMana() { - return this.maximumMana; - } - - public int getMaximumLife() { - return this.maximumLife; - } - - public void setTypeId(final War3ID typeId) { - this.typeId = typeId; - } - - public void setFacing(final float facing) { - // java modulo output can be negative, but not if we - // force positive and modulo again - this.facing = ((facing % 360) + 360) % 360; - } - - public void setMana(final float mana) { - this.mana = mana; - } - - public void setMaximumLife(final int maximumLife) { - this.maximumLife = maximumLife; - } - - public void setMaximumMana(final int maximumMana) { - this.maximumMana = maximumMana; - } - - public void setSpeed(final int speed) { - this.speed = speed; - } - - public int getSpeed() { - return this.speed; - } - - /** - * Updates one tick of simulation logic and return true if it's time to remove - * this unit from the game. - */ - public boolean update(final CSimulation game) { - for (final StateListenerUpdate update : this.stateListenersUpdates) { - switch (update.getUpdateType()) { - case ADD: - this.stateNotifier.subscribe(update.listener); - break; - case REMOVE: - this.stateNotifier.unsubscribe(update.listener); - break; - } - } - if (isDead()) { - if (this.collisionRectangle != null) { - // Moved this here because doing it on "kill" was able to happen in some cases - // while also iterating over the units that are in the collision system, and - // then it hit the "writing while iterating" problem. - game.getWorldCollision().removeUnit(this); - } - final int gameTurnTick = game.getGameTurnTick(); - if (!this.corpse) { - if (gameTurnTick > (this.deathTurnTick - + (int) (this.unitType.getDeathTime() / WarsmashConstants.SIMULATION_STEP_TIME))) { - this.corpse = true; - if (!this.unitType.isRaise()) { - this.boneCorpse = true; - // start final phase immediately for "cant raise" case - } - if (!this.unitType.isHero()) { - if (!this.unitType.isDecay()) { - // if we dont raise AND dont decay, then now that death anim is over - // we just delete the unit - return true; - } - } - else { - game.heroDeathEvent(this); - } - this.deathTurnTick = gameTurnTick; - } - } - else if (!this.boneCorpse) { - if (game.getGameTurnTick() > (this.deathTurnTick + (int) (game.getGameplayConstants().getDecayTime() - / WarsmashConstants.SIMULATION_STEP_TIME))) { - this.boneCorpse = true; - this.deathTurnTick = gameTurnTick; - } - } - else if (game.getGameTurnTick() > (this.deathTurnTick - + (int) (getEndingDecayTime(game) / WarsmashConstants.SIMULATION_STEP_TIME))) { - if (this.unitType.isHero()) { - if (!getHeroData().isAwaitingRevive()) { - setHidden(true); - getHeroData().setAwaitingRevive(true); - game.heroDissipateEvent(this); - } - return false; - } - return true; - } - } - else if (!this.paused) { - if ((this.rallyPoint != this) && (this.rallyPoint instanceof CUnit) && ((CUnit) this.rallyPoint).isDead()) { - setRallyPoint(this); - } - if (this.constructing) { - this.constructionProgress += WarsmashConstants.SIMULATION_STEP_TIME; - final int buildTime = this.unitType.getBuildTime(); - final float healthGain = (WarsmashConstants.SIMULATION_STEP_TIME / buildTime) - * (this.maximumLife * (1.0f - WarsmashConstants.BUILDING_CONSTRUCT_START_LIFE)); - setLife(game, Math.min(this.life + healthGain, this.maximumLife)); - if (this.constructionProgress >= buildTime) { - this.constructing = false; - this.constructionProgress = 0; - popoutWorker(game); - final Iterator abilityIterator = this.abilities.iterator(); - while (abilityIterator.hasNext()) { - final CAbility ability = abilityIterator.next(); - if (ability instanceof CAbilityBuildInProgress) { - abilityIterator.remove(); - } - else { - ability.setDisabled(false); - ability.setIconShowing(true); - } - } - if (this.unitType.getFoodMade() != 0) { - final CPlayer player = game.getPlayer(this.playerIndex); - player.setFoodCap(player.getFoodCap() + this.unitType.getFoodMade()); - } - game.unitConstructFinishEvent(this); - this.stateNotifier.ordersChanged(); - } - } - else { - final War3ID queuedRawcode = this.buildQueue[0]; - if (queuedRawcode != null) { - // queue step forward - if (this.queuedUnitFoodPaid) { - this.constructionProgress += WarsmashConstants.SIMULATION_STEP_TIME; - } - else { - if (this.buildQueueTypes[0] == QueueItemType.UNIT) { - final CPlayer player = game.getPlayer(this.playerIndex); - final CUnitType trainedUnitType = game.getUnitData().getUnitType(queuedRawcode); - final int newFoodUsed = player.getFoodUsed() + trainedUnitType.getFoodUsed(); - if (newFoodUsed <= player.getFoodCap()) { - player.setFoodUsed(newFoodUsed); - this.queuedUnitFoodPaid = true; - } - } - else if (this.buildQueueTypes[0] == QueueItemType.HERO_REVIVE) { - final CPlayer player = game.getPlayer(this.playerIndex); - final CUnitType trainedUnitType = game.getUnit(queuedRawcode.getValue()).getUnitType(); - final int newFoodUsed = player.getFoodUsed() + trainedUnitType.getFoodUsed(); - if (newFoodUsed <= player.getFoodCap()) { - player.setFoodUsed(newFoodUsed); - this.queuedUnitFoodPaid = true; - } - } - else { - this.queuedUnitFoodPaid = true; - System.err.println( - "Unpaid food for non unit queue item ???? Attempting to correct this by setting paid=true"); - } - } - if (this.buildQueueTypes[0] == QueueItemType.UNIT) { - final CUnitType trainedUnitType = game.getUnitData().getUnitType(queuedRawcode); - if (this.constructionProgress >= trainedUnitType.getBuildTime()) { - this.constructionProgress = 0; - final CUnit trainedUnit = game.createUnit(queuedRawcode, this.playerIndex, getX(), getY(), - game.getGameplayConstants().getBuildingAngle()); - // dont add food cost to player 2x - trainedUnit.setFoodUsed(trainedUnitType.getFoodUsed()); - final CPlayer player = game.getPlayer(this.playerIndex); - player.setUnitFoodMade(trainedUnit, trainedUnitType.getFoodMade()); - player.addTechtreeUnlocked(queuedRawcode); - // nudge the trained unit out around us - trainedUnit.nudgeAround(game, this); - game.unitTrainedEvent(this, trainedUnit); - if (this.rallyPoint != null) { - final int rallyOrderId = OrderIds.smart; - this.rallyPoint.visit( - UseAbilityOnTargetByIdVisitor.INSTANCE.reset(game, trainedUnit, rallyOrderId)); - } - for (int i = 0; i < (this.buildQueue.length - 1); i++) { - setBuildQueueItem(game, i, this.buildQueue[i + 1], this.buildQueueTypes[i + 1]); - } - setBuildQueueItem(game, this.buildQueue.length - 1, null, null); - this.stateNotifier.queueChanged(); - } - } - else if (this.buildQueueTypes[0] == QueueItemType.HERO_REVIVE) { - final CUnit revivingHero = game.getUnit(queuedRawcode.getValue()); - final CUnitType trainedUnitType = revivingHero.getUnitType(); - final CGameplayConstants gameplayConstants = game.getGameplayConstants(); - if (this.constructionProgress >= gameplayConstants.getHeroReviveTime( - trainedUnitType.getBuildTime(), revivingHero.getHeroData().getHeroLevel())) { - this.constructionProgress = 0; - revivingHero.getHeroData().setReviving(false); - revivingHero.getHeroData().setAwaitingRevive(false); - revivingHero.corpse = false; - revivingHero.boneCorpse = false; - revivingHero.deathTurnTick = 0; - revivingHero.setX(getX()); - revivingHero.setY(getY()); - game.getWorldCollision().addUnit(revivingHero); - revivingHero.setPoint(getX(), getY(), game.getWorldCollision(), game.getRegionManager()); - revivingHero.setHidden(false); - revivingHero.setLife(game, - revivingHero.getMaximumLife() * gameplayConstants.getHeroReviveLifeFactor()); - revivingHero.setMana((revivingHero.getMaximumMana() - * gameplayConstants.getHeroReviveManaFactor()) - + (gameplayConstants.getHeroReviveManaStart() * trainedUnitType.getManaInitial())); - // dont add food cost to player 2x - revivingHero.setFoodUsed(trainedUnitType.getFoodUsed()); - final CPlayer player = game.getPlayer(this.playerIndex); - player.setUnitFoodMade(revivingHero, trainedUnitType.getFoodMade()); - player.addTechtreeUnlocked(queuedRawcode); - // nudge the trained unit out around us - revivingHero.nudgeAround(game, this); - game.heroReviveEvent(this, revivingHero); - if (this.rallyPoint != null) { - final int rallyOrderId = OrderIds.smart; - this.rallyPoint.visit( - UseAbilityOnTargetByIdVisitor.INSTANCE.reset(game, revivingHero, rallyOrderId)); - } - for (int i = 0; i < (this.buildQueue.length - 1); i++) { - setBuildQueueItem(game, i, this.buildQueue[i + 1], this.buildQueueTypes[i + 1]); - } - setBuildQueueItem(game, this.buildQueue.length - 1, null, null); - this.stateNotifier.queueChanged(); - } - } - else if (this.buildQueueTypes[0] == QueueItemType.RESEARCH) { - final CUnitType trainedUnitType = game.getUnitData().getUnitType(queuedRawcode); - if (this.constructionProgress >= trainedUnitType.getBuildTime()) { - this.constructionProgress = 0; - for (int i = 0; i < (this.buildQueue.length - 1); i++) { - setBuildQueueItem(game, i, this.buildQueue[i + 1], this.buildQueueTypes[i + 1]); - } - setBuildQueueItem(game, this.buildQueue.length - 1, null, null); - this.stateNotifier.queueChanged(); - } - } - } - for (final CAbility ability : this.abilities) { - ability.onTick(game, this); - } - if (this.currentBehavior != null) { - final CBehavior lastBehavior = this.currentBehavior; - final int lastBehaviorHighlightOrderId = lastBehavior.getHighlightOrderId(); - this.currentBehavior = this.currentBehavior.update(game); - if (lastBehavior != this.currentBehavior) { - lastBehavior.end(game, false); - this.currentBehavior.begin(game); - } - if (this.currentBehavior.getHighlightOrderId() != lastBehaviorHighlightOrderId) { - this.stateNotifier.ordersChanged(); - } - } - else { - // check to auto acquire targets - autoAcquireAttackTargets(game, false); - } - } - } - return false; - - } - - private void popoutWorker(final CSimulation game) { - if (this.workerInside != null) { - this.workerInside.setInvulnerable(false); - this.workerInside.setHidden(false); - this.workerInside.setPaused(false); - this.workerInside.nudgeAround(game, this); - this.workerInside = null; - } - } - - public boolean autoAcquireAttackTargets(final CSimulation game, final boolean disableMove) { - if (!this.getAttacks().isEmpty() && !this.unitType.getClassifications().contains(CUnitClassification.PEON)) { - if (this.collisionRectangle != null) { - tempRect.set(this.collisionRectangle); - } - else { - tempRect.set(this.getX(), this.getY(), 0, 0); - } - final float halfSize = this.acquisitionRange; - tempRect.x -= halfSize; - tempRect.y -= halfSize; - tempRect.width += halfSize * 2; - tempRect.height += halfSize * 2; - game.getWorldCollision().enumUnitsInRect(tempRect, - autoAttackTargetFinderEnum.reset(game, this, disableMove)); - return autoAttackTargetFinderEnum.foundAnyTarget; - } - return false; - } - - public float getEndingDecayTime(final CSimulation game) { - if (this.isBuilding()) { - return game.getGameplayConstants().getStructureDecayTime(); - } - if (this.unitType.isHero()) { - return game.getGameplayConstants().getDissipateTime(); - } - return game.getGameplayConstants().getBoneDecayTime(); - } - - public void order(final CSimulation game, final COrder order, final boolean queue) { - if (isDead()) { - return; - } - - if (order != null) { - final CAbility ability = game.getAbility(order.getAbilityHandleId()); - if (ability != null) { - // Allow the ability to response to the order without actually placing itself in - // the queue, nor modifying (interrupting) the queue. - if (!ability.checkBeforeQueue(game, this, order.getOrderId(), order.getTarget(game))) { - this.stateNotifier.ordersChanged(); - return; - } - } - } - - if ((this.lastStartedOrder != null) && this.lastStartedOrder.equals(order) - && (this.lastStartedOrder.getOrderId() == OrderIds.smart)) { - // I skip your spammed move orders, TODO this will probably break some repeat - // attack order or something later - return; - } - if ((queue || !this.acceptingOrders) && ((this.currentBehavior != this.stopBehavior) - && (this.currentBehavior != this.holdPositionBehavior))) { - this.orderQueue.add(order); - this.stateNotifier.waypointsChanged(); - } - else { - setDefaultBehavior(this.stopBehavior); - if (this.currentBehavior != null) { - this.currentBehavior.end(game, true); - } - this.currentBehavior = beginOrder(game, order); - if (this.currentBehavior != null) { - this.currentBehavior.begin(game); - } - for (final COrder queuedOrder : this.orderQueue) { - final int abilityHandleId = queuedOrder.getAbilityHandleId(); - final CAbility ability = game.getAbility(abilityHandleId); - ability.onCancelFromQueue(game, this, queuedOrder.getOrderId()); - } - this.orderQueue.clear(); - this.stateNotifier.ordersChanged(); - this.stateNotifier.waypointsChanged(); - } - } - - public boolean order(final CSimulation simulation, final int orderId, final AbilityTarget target) { - if (orderId == OrderIds.stop) { - order(simulation, new COrderNoTarget(0, orderId, false), false); - return true; - } - for (final CAbility ability : this.abilities) { - final BooleanAbilityActivationReceiver activationReceiver = BooleanAbilityActivationReceiver.INSTANCE; - ability.checkCanUse(simulation, this, orderId, activationReceiver); - if (activationReceiver.isOk()) { - if (target == null) { - final BooleanAbilityTargetCheckReceiver booleanTargetReceiver = BooleanAbilityTargetCheckReceiver - .getInstance().reset(); - ability.checkCanTargetNoTarget(simulation, this, orderId, booleanTargetReceiver); - if (booleanTargetReceiver.isTargetable()) { - order(simulation, new COrderNoTarget(ability.getHandleId(), orderId, false), false); - return true; - } - } - final boolean targetable = target.visit(new AbilityTargetVisitor() { - @Override - public Boolean accept(final AbilityPointTarget target) { - final BooleanAbilityTargetCheckReceiver booleanTargetReceiver = BooleanAbilityTargetCheckReceiver - .getInstance().reset(); - ability.checkCanTarget(simulation, CUnit.this, orderId, target, booleanTargetReceiver); - final boolean pointTargetable = booleanTargetReceiver.isTargetable(); - if (pointTargetable) { - order(simulation, new COrderTargetPoint(ability.getHandleId(), orderId, target, false), - false); - } - return pointTargetable; - } - - public Boolean acceptWidget(final CWidget target) { - final BooleanAbilityTargetCheckReceiver booleanTargetReceiver = BooleanAbilityTargetCheckReceiver - .getInstance().reset(); - ability.checkCanTarget(simulation, CUnit.this, orderId, target, booleanTargetReceiver); - final boolean widgetTargetable = booleanTargetReceiver.isTargetable(); - if (widgetTargetable) { - order(simulation, - new COrderTargetWidget(ability.getHandleId(), orderId, target.getHandleId(), false), - false); - } - return widgetTargetable; - } - - @Override - public Boolean accept(final CUnit target) { - return acceptWidget(target); - } - - @Override - public Boolean accept(final CDestructable target) { - return acceptWidget(target); - } - - @Override - public Boolean accept(final CItem target) { - return acceptWidget(target); - } - }); - if (targetable) { - return true; - } - } - } - return false; - } - - private CBehavior beginOrder(final CSimulation game, final COrder order) { - this.lastStartedOrder = order; - CBehavior nextBehavior; - if (order != null) { - nextBehavior = order.begin(game, this); - } - else { - nextBehavior = this.defaultBehavior; - } - return nextBehavior; - } - - public CBehavior getCurrentBehavior() { - return this.currentBehavior; - } - - public List getAbilities() { - return this.abilities; - } - - public T getAbility(final CAbilityVisitor visitor) { - for (final CAbility ability : this.abilities) { - final T visited = ability.visit(visitor); - if (visited != null) { - return visited; - } - } - return null; - } - - public T getFirstAbilityOfType(final Class cAbilityClass) { - for (final CAbility ability : this.abilities) { - if (cAbilityClass.isAssignableFrom(ability.getClass())) { - return (T) ability; - } - } - return null; - } - - public void setCooldownEndTime(final int cooldownEndTime) { - this.cooldownEndTime = cooldownEndTime; - } - - public int getCooldownEndTime() { - return this.cooldownEndTime; - } - - @Override - public float getFlyHeight() { - return this.flyHeight; - } - - public void setFlyHeight(final float flyHeight) { - this.flyHeight = flyHeight; - } - - public int getPlayerIndex() { - return this.playerIndex; - } - - public void setPlayerIndex(final int playerIndex) { - this.playerIndex = playerIndex; - } - - public CUnitType getUnitType() { - return this.unitType; - } - - public void setCollisionRectangle(final Rectangle collisionRectangle) { - this.collisionRectangle = collisionRectangle; - } - - public Rectangle getCollisionRectangle() { - return this.collisionRectangle; - } - - public void setX(final float newX, final CWorldCollision collision, final CRegionManager regionManager) { - final float prevX = getX(); - if (!this.isBuilding()) { - setX(newX); - collision.translate(this, newX - prevX, 0); - } - checkRegionEvents(regionManager); - } - - public void setY(final float newY, final CWorldCollision collision, final CRegionManager regionManager) { - final float prevY = getY(); - if (!this.isBuilding()) { - setY(newY); - collision.translate(this, 0, newY - prevY); - } - checkRegionEvents(regionManager); - } - - public void setPointAndCheckUnstuck(final float newX, final float newY, final CSimulation game) { - final CWorldCollision collision = game.getWorldCollision(); - final PathingGrid pathingGrid = game.getPathingGrid(); - ; - float outputX = newX, outputY = newY; - int checkX = 0; - int checkY = 0; - float collisionSize; - if (this.unitType.getBuildingPathingPixelMap() != null) { - tempRect.setSize(this.unitType.getBuildingPathingPixelMap().getWidth() * 32, - this.unitType.getBuildingPathingPixelMap().getHeight() * 32); - collisionSize = tempRect.getWidth() / 2; - } - else if (this.collisionRectangle != null) { - tempRect.set(this.collisionRectangle); - collisionSize = this.unitType.getCollisionSize(); - } - else { - tempRect.setSize(16, 16); - collisionSize = this.unitType.getCollisionSize(); - } - final boolean repos = false; - for (int i = 0; i < 300; i++) { - final float centerX = newX + (checkX * 64); - final float centerY = newY + (checkY * 64); - tempRect.setCenter(centerX, centerY); - if (!collision.intersectsAnythingOtherThan(tempRect, this, this.unitType.getMovementType()) - && pathingGrid.isPathable(centerX, centerY, this.unitType.getMovementType(), collisionSize)) { - outputX = centerX; - outputY = centerY; - break; - } - final double angle = ((((int) Math.floor(Math.sqrt((4 * i) + 1))) % 4) * Math.PI) / 2; - checkX -= (int) Math.cos(angle); - checkY -= (int) Math.sin(angle); - } - setPoint(outputX, outputY, collision, game.getRegionManager()); - game.unitRepositioned(this); - } - - public void setPoint(final float newX, final float newY, final CWorldCollision collision, - final CRegionManager regionManager) { - final float prevX = getX(); - final float prevY = getY(); - setX(newX); - setY(newY); - if (!this.isBuilding()) { - collision.translate(this, newX - prevX, newY - prevY); - } - checkRegionEvents(regionManager); - } - - private void checkRegionEvents(final CRegionManager regionManager) { - final Set temp = this.containingRegions; - this.containingRegions = this.priorContainingRegions; - this.priorContainingRegions = temp; - this.containingRegions.clear(); - regionManager.checkRegions(this.collisionRectangle == null ? tempRect.set(this.getX(), this.getY(), 0, 0) - : this.collisionRectangle, regionCheckerImpl.reset(this, regionManager)); - for (final CRegion region : this.priorContainingRegions) { - if (!this.containingRegions.contains(region)) { - regionManager.onUnitLeaveRegion(this, region); - } - } - } - - public EnumSet getClassifications() { - return this.classifications; - } - - public int getDefense() { - return this.currentDefense; - } - - @Override - public float getImpactZ() { - return this.unitType.getImpactZ(); - } - - public double angleTo(final AbilityTarget target) { - final double dx = target.getX() - getX(); - final double dy = target.getY() - getY(); - return StrictMath.atan2(dy, dx); - } - - public double distance(final AbilityTarget target) { - double dx = StrictMath.abs(target.getX() - getX()); - double dy = StrictMath.abs(target.getY() - getY()); - final float thisCollisionSize = this.unitType.getCollisionSize(); - float targetCollisionSize; - if (target instanceof CUnit) { - final CUnitType targetUnitType = ((CUnit) target).getUnitType(); - targetCollisionSize = targetUnitType.getCollisionSize(); - } - else { - targetCollisionSize = 0; // TODO destructable collision size here - } - if (dx < 0) { - dx = 0; - } - if (dy < 0) { - dy = 0; - } - - double groundDistance = StrictMath.sqrt((dx * dx) + (dy * dy)) - thisCollisionSize - targetCollisionSize; - if (groundDistance < 0) { - groundDistance = 0; - } - return groundDistance; - } - - public double distance(final float x, final float y) { - double dx = Math.abs(x - getX()); - double dy = Math.abs(y - getY()); - final float thisCollisionSize = this.unitType.getCollisionSize(); - if (dx < 0) { - dx = 0; - } - if (dy < 0) { - dy = 0; - } - - double groundDistance = StrictMath.sqrt((dx * dx) + (dy * dy)) - thisCollisionSize; - if (groundDistance < 0) { - groundDistance = 0; - } - return groundDistance; - } - - @Override - public void damage(final CSimulation simulation, final CUnit source, final CAttackType attackType, - final String weaponType, final float damage) { - final boolean wasDead = isDead(); - if (!this.invulnerable) { - final float damageRatioFromArmorClass = simulation.getGameplayConstants().getDamageRatioAgainst(attackType, - this.unitType.getDefenseType()); - final float damageRatioFromDefense; - final int defense = this.currentDefense; - if (defense >= 0) { - damageRatioFromDefense = 1f - (((defense) * simulation.getGameplayConstants().getDefenseArmor()) - / (1 + (simulation.getGameplayConstants().getDefenseArmor() * defense))); - } - else { - damageRatioFromDefense = 2f - (float) StrictMath.pow(0.94, -defense); - } - final float trueDamage = damageRatioFromArmorClass * damageRatioFromDefense * damage; - this.life -= trueDamage; - this.stateNotifier.lifeChanged(); - } - simulation.unitDamageEvent(this, weaponType, this.unitType.getArmorType()); - if (!this.invulnerable && isDead()) { - if (!wasDead) { - kill(simulation, source); - } - } - else { - if ((this.currentBehavior == null) || (this.currentBehavior == this.defaultBehavior)) { - boolean foundMatchingReturnFireAttack = false; - if (!simulation.getPlayer(getPlayerIndex()).hasAlliance(source.getPlayerIndex(), CAllianceType.PASSIVE) - && !this.unitType.getClassifications().contains(CUnitClassification.PEON)) { - for (final CUnitAttack attack : this.getAttacks()) { - if (source.canBeTargetedBy(simulation, this, attack.getTargetsAllowed())) { - this.currentBehavior = getAttackBehavior().reset(OrderIds.attack, attack, source, false, - CBehaviorAttackListener.DO_NOTHING); - this.currentBehavior.begin(simulation); - foundMatchingReturnFireAttack = true; - break; - } - } - } - if (!foundMatchingReturnFireAttack && this.unitType.isCanFlee() && !isMovementDisabled() - && (this.moveBehavior != null) && (this.playerIndex != source.getPlayerIndex())) { - final double angleTo = source.angleTo(this); - final int distanceToFlee = getSpeed(); - this.currentBehavior = this.moveBehavior.reset(OrderIds.move, - new AbilityPointTarget((float) (getX() + (distanceToFlee * StrictMath.cos(angleTo))), - (float) (getY() + (distanceToFlee * StrictMath.sin(angleTo))))); - this.currentBehavior.begin(simulation); - } - } - } - } - - private void kill(final CSimulation simulation, final CUnit source) { - if (this.currentBehavior != null) { - this.currentBehavior.end(simulation, true); - } - this.currentBehavior = null; - this.orderQueue.clear(); - if (this.constructing) { - simulation.createBuildingDeathEffect(this); - } - else { - this.deathTurnTick = simulation.getGameTurnTick(); - } - if (this.pathingInstance != null) { - this.pathingInstance.remove(); - this.pathingInstance = null; - } - popoutWorker(simulation); - final CPlayer player = simulation.getPlayer(this.playerIndex); - if (this.foodMade != 0) { - player.setUnitFoodMade(this, 0); - } - if (this.foodUsed != 0) { - player.setUnitFoodUsed(this, 0); - } - - // Award hero experience - if (source != null) { - final CPlayer sourcePlayer = simulation.getPlayer(source.getPlayerIndex()); - if (!sourcePlayer.hasAlliance(this.playerIndex, CAllianceType.PASSIVE)) { - final CGameplayConstants gameplayConstants = simulation.getGameplayConstants(); - if (gameplayConstants.isBuildingKillsGiveExp() || !source.isBuilding()) { - final CUnit killedUnit = this; - final CAbilityHero killedUnitHeroData = getHeroData(); - final boolean killedUnitIsAHero = killedUnitHeroData != null; - int availableAwardXp; - if (killedUnitIsAHero) { - availableAwardXp = gameplayConstants.getGrantHeroXP(killedUnitHeroData.getHeroLevel()); - } - else { - availableAwardXp = gameplayConstants.getGrantNormalXP(this.unitType.getLevel()); - } - final List xpReceivingHeroes = new ArrayList<>(); - final int heroExpRange = gameplayConstants.getHeroExpRange(); - simulation.getWorldCollision().enumUnitsInRect(new Rectangle(this.getX() - heroExpRange, - this.getY() - heroExpRange, heroExpRange * 2, heroExpRange * 2), new CUnitEnumFunction() { - @Override - public boolean call(final CUnit unit) { - if ((unit.distance(killedUnit) <= heroExpRange) - && sourcePlayer.hasAlliance(unit.getPlayerIndex(), CAllianceType.SHARED_XP) - && (unit.getHeroData() != null)) { - xpReceivingHeroes.add(unit); - } - return false; - } - }); - if (xpReceivingHeroes.isEmpty()) { - if (gameplayConstants.isGlobalExperience()) { - for (int i = 0; i < WarsmashConstants.MAX_PLAYERS; i++) { - if (sourcePlayer.hasAlliance(i, CAllianceType.SHARED_XP)) { - xpReceivingHeroes.addAll(simulation.getPlayerHeroes(i)); - } - } - } - } - for (final CUnit receivingHero : xpReceivingHeroes) { - final CAbilityHero heroData = receivingHero.getHeroData(); - heroData.addXp(simulation, receivingHero, - (int) (availableAwardXp * (1f / xpReceivingHeroes.size()) - * gameplayConstants.getHeroFactorXp(heroData.getHeroLevel()))); - } - } - } - } - } - - public boolean canReach(final AbilityTarget target, final float range) { - final double distance = distance(target); - if (target instanceof CUnit) { - final CUnit targetUnit = (CUnit) target; - final CUnitType targetUnitType = targetUnit.getUnitType(); - if (targetUnit.isBuilding() && (targetUnitType.getBuildingPathingPixelMap() != null)) { - final BufferedImage buildingPathingPixelMap = targetUnitType.getBuildingPathingPixelMap(); - final float targetX = target.getX(); - final float targetY = target.getY(); - if (canReachToPathing(range, targetUnit.getFacing(), buildingPathingPixelMap, targetX, targetY)) { - return true; - } - } - } - else if (target instanceof CDestructable) { - final CDestructable targetDest = (CDestructable) target; - final CDestructableType targetDestType = targetDest.getDestType(); - final BufferedImage pathingPixelMap = targetDest.isDead() ? targetDestType.getPathingDeathPixelMap() - : targetDestType.getPathingPixelMap(); - final float targetX = target.getX(); - final float targetY = target.getY(); - if ((pathingPixelMap != null) && canReachToPathing(range, 270, pathingPixelMap, targetX, targetY)) { - return true; - } - } - return distance <= range; - } - - public boolean canReach(final float x, final float y, final float range) { - return distance(x, y) <= range; // TODO use dist squared for performance - } - - public boolean canReachToPathing(final float range, final float rotationForPathing, - final BufferedImage buildingPathingPixelMap, final float targetX, final float targetY) { - final int rotation = ((int) rotationForPathing + 450) % 360; - final float relativeOffsetX = getX() - targetX; - final float relativeOffsetY = getY() - targetY; - final int gridWidth = ((rotation % 180) != 0) ? buildingPathingPixelMap.getHeight() - : buildingPathingPixelMap.getWidth(); - final int gridHeight = ((rotation % 180) != 0) ? buildingPathingPixelMap.getWidth() - : buildingPathingPixelMap.getHeight(); - final int relativeGridX = (int) Math.floor(relativeOffsetX / 32f) + (gridWidth / 2); - final int relativeGridY = (int) Math.floor(relativeOffsetY / 32f) + (gridHeight / 2); - final int rangeInCells = (int) Math.floor(range / 32f) + 1; - final int rangeInCellsSquare = rangeInCells * rangeInCells; - int minCheckX = relativeGridX - rangeInCells; - int minCheckY = relativeGridY - rangeInCells; - int maxCheckX = relativeGridX + rangeInCells; - int maxCheckY = relativeGridY + rangeInCells; - if ((minCheckX < gridWidth) && (maxCheckX >= 0)) { - if ((minCheckY < gridHeight) && (maxCheckY >= 0)) { - if (minCheckX < 0) { - minCheckX = 0; - } - if (minCheckY < 0) { - minCheckY = 0; - } - if (maxCheckX > (gridWidth - 1)) { - maxCheckX = gridWidth - 1; - } - if (maxCheckY > (gridHeight - 1)) { - maxCheckY = gridHeight - 1; - } - for (int checkX = minCheckX; checkX <= maxCheckX; checkX++) { - for (int checkY = minCheckY; checkY <= maxCheckY; checkY++) { - final int dx = relativeGridX - checkX; - final int dy = relativeGridY - checkY; - if (((dx * dx) + (dy * dy)) <= rangeInCellsSquare) { - if (((getRGBFromPixelData(buildingPathingPixelMap, checkX, checkY, rotation) - & 0xFF0000) >>> 16) > 127) { - return true; - } - } - } - } - } - } - return false; - } - - private int getRGBFromPixelData(final BufferedImage buildingPathingPixelMap, final int checkX, final int checkY, - final int rotation) { - - // Below: y is downwards (:() - int x; - int y; - switch (rotation) { - case 90: - x = checkY; - y = buildingPathingPixelMap.getWidth() - 1 - checkX; - break; - case 180: - x = buildingPathingPixelMap.getWidth() - 1 - checkX; - y = buildingPathingPixelMap.getHeight() - 1 - checkY; - break; - case 270: - x = buildingPathingPixelMap.getHeight() - 1 - checkY; - y = checkX; - break; - default: - case 0: - x = checkX; - y = checkY; - } - return buildingPathingPixelMap.getRGB(x, buildingPathingPixelMap.getHeight() - 1 - y); - } - - public void addStateListener(final CUnitStateListener listener) { - this.stateListenersUpdates.add(new StateListenerUpdate(listener, StateListenerUpdateType.ADD)); - } - - public void removeStateListener(final CUnitStateListener listener) { - this.stateListenersUpdates.add(new StateListenerUpdate(listener, StateListenerUpdateType.REMOVE)); - } - - public boolean isCorpse() { - return this.corpse; - } - - public boolean isBoneCorpse() { - return this.boneCorpse; - } - - @Override - public boolean canBeTargetedBy(final CSimulation simulation, final CUnit source, - final EnumSet targetsAllowed) { - if (targetsAllowed.containsAll(this.unitType.getTargetedAs()) || (!targetsAllowed.contains(CTargetType.GROUND) - && (!targetsAllowed.contains(CTargetType.STRUCTURE) && !targetsAllowed.contains(CTargetType.AIR)))) { - final int sourcePlayerIndex = source.getPlayerIndex(); - final CPlayer sourcePlayer = simulation.getPlayer(sourcePlayerIndex); - if (!targetsAllowed.contains(CTargetType.ENEMIES) - || !sourcePlayer.hasAlliance(this.playerIndex, CAllianceType.PASSIVE)) { - if (isDead()) { - if (this.unitType.isRaise() && this.unitType.isDecay() && isBoneCorpse()) { - return targetsAllowed.contains(CTargetType.DEAD); - } - } - else { - return !targetsAllowed.contains(CTargetType.DEAD) || targetsAllowed.contains(CTargetType.ALIVE); - } - } - } - else { - System.err.println("No targeting because " + targetsAllowed + " does not contain all of " - + this.unitType.getTargetedAs()); - } - return false; - } - - public boolean isMovementDisabled() { - return this.isBuilding(); - } - - public float getAcquisitionRange() { - return this.acquisitionRange; - } - - public void heal(final CSimulation game, final int lifeToRegain) { - setLife(game, Math.min(getLife() + lifeToRegain, getMaximumLife())); - } - - private static final class AutoAttackTargetFinderEnum implements CUnitEnumFunction { - private CSimulation game; - private CUnit source; - private boolean disableMove; - private boolean foundAnyTarget; - - private AutoAttackTargetFinderEnum reset(final CSimulation game, final CUnit source, - final boolean disableMove) { - this.game = game; - this.source = source; - this.disableMove = disableMove; - this.foundAnyTarget = false; - return this; - } - - @Override - public boolean call(final CUnit unit) { - if (!this.game.getPlayer(this.source.getPlayerIndex()).hasAlliance(unit.getPlayerIndex(), - CAllianceType.PASSIVE) && !unit.isDead() && !unit.isInvulnerable()) { - for (final CUnitAttack attack : this.source.getAttacks()) { - if (this.source.canReach(unit, this.source.acquisitionRange) - && unit.canBeTargetedBy(this.game, this.source, attack.getTargetsAllowed()) - && (this.source.distance(unit) >= this.source.getUnitType().getMinimumAttackRange())) { - if (this.source.currentBehavior != null) { - this.source.currentBehavior.end(this.game, false); - } - this.source.currentBehavior = this.source.getAttackBehavior().reset(OrderIds.attack, attack, - unit, this.disableMove, CBehaviorAttackListener.DO_NOTHING); - this.source.currentBehavior.begin(this.game); - this.foundAnyTarget = true; - return true; - } - } - } - return false; - } - } - - public CBehaviorMove getMoveBehavior() { - return this.moveBehavior; - } - - public void setMoveBehavior(final CBehaviorMove moveBehavior) { - this.moveBehavior = moveBehavior; - } - - public CBehaviorAttack getAttackBehavior() { - return this.attackBehavior; - } - - public void setAttackBehavior(final CBehaviorAttack attackBehavior) { - this.attackBehavior = attackBehavior; - } - - public void setAttackMoveBehavior(final CBehaviorAttackMove attackMoveBehavior) { - this.attackMoveBehavior = attackMoveBehavior; - } - - public CBehaviorAttackMove getAttackMoveBehavior() { - return this.attackMoveBehavior; - } - - public CBehaviorStop getStopBehavior() { - return this.stopBehavior; - } - - public void setFollowBehavior(final CBehaviorFollow followBehavior) { - this.followBehavior = followBehavior; - } - - public void setPatrolBehavior(final CBehaviorPatrol patrolBehavior) { - this.patrolBehavior = patrolBehavior; - } - - public void setHoldPositionBehavior(final CBehaviorHoldPosition holdPositionBehavior) { - this.holdPositionBehavior = holdPositionBehavior; - } - - public CBehaviorFollow getFollowBehavior() { - return this.followBehavior; - } - - public CBehaviorPatrol getPatrolBehavior() { - return this.patrolBehavior; - } - - public CBehaviorHoldPosition getHoldPositionBehavior() { - return this.holdPositionBehavior; - } - - public CBehavior pollNextOrderBehavior(final CSimulation game) { - if (this.defaultBehavior != this.stopBehavior) { - // kind of a stupid hack, meant to align in feel with some behaviors that were - // observed on War3 - return this.defaultBehavior; - } - final COrder order = this.orderQueue.poll(); - final CBehavior nextOrderBehavior = beginOrder(game, order); - this.stateNotifier.waypointsChanged(); - return nextOrderBehavior; - } - - public boolean isMoving() { - return getCurrentBehavior() instanceof CBehaviorMove; - } - - public void setConstructing(final boolean constructing) { - this.constructing = constructing; - if (constructing) { - this.unitAnimationListener.playAnimation(true, PrimaryTag.BIRTH, SequenceUtils.EMPTY, 0.0f, true); - } - } - - public void setConstructionProgress(final float constructionProgress) { - this.constructionProgress = constructionProgress; - } - - public boolean isConstructing() { - return this.constructing; - } - - public float getConstructionProgress() { - return this.constructionProgress; - } - - public void setHidden(final boolean hidden) { - this.hidden = hidden; - } - - public void setPaused(final boolean paused) { - this.paused = paused; - } - - public void setAcceptingOrders(final boolean acceptingOrders) { - this.acceptingOrders = acceptingOrders; - } - - public boolean isHidden() { - return this.hidden; - } - - public void setInvulnerable(final boolean invulnerable) { - this.invulnerable = invulnerable; - } - - @Override - public boolean isInvulnerable() { - return this.invulnerable; - } - - public void setWorkerInside(final CUnit unit) { - this.workerInside = unit; - } - - public CUnit getWorkerInside() { - return this.workerInside; - } - - private void nudgeAround(final CSimulation simulation, final CUnit structure) { - setPointAndCheckUnstuck(structure.getX(), structure.getY(), simulation); - } - - @Override - public void setLife(final CSimulation simulation, final float life) { - final boolean wasDead = isDead(); - super.setLife(simulation, life); - if (isDead() && !wasDead) { - kill(simulation, null); - } - this.stateNotifier.lifeChanged(); - } - - private boolean queue(final CSimulation game, final War3ID rawcode, final QueueItemType queueItemType) { - for (int i = 0; i < this.buildQueue.length; i++) { - if (this.buildQueue[i] == null) { - setBuildQueueItem(game, i, rawcode, queueItemType); - return true; - } - } - return false; - } - - public War3ID[] getBuildQueue() { - return this.buildQueue; - } - - public QueueItemType[] getBuildQueueTypes() { - return this.buildQueueTypes; - } - - public float getBuildQueueTimeRemaining(final CSimulation simulation) { - if (this.buildQueueTypes[0] == null) { - return 0; - } - switch (this.buildQueueTypes[0]) { - case RESEARCH: - return 999; // TODO - case UNIT: { - final CUnitType trainedUnitType = simulation.getUnitData().getUnitType(this.buildQueue[0]); - return trainedUnitType.getBuildTime(); - } - case HERO_REVIVE: { - final CUnit hero = simulation.getUnit(this.buildQueue[0].getValue()); - final CUnitType trainedUnitType = hero.getUnitType(); - return simulation.getGameplayConstants().getHeroReviveTime(trainedUnitType.getBuildTime(), - hero.getHeroData().getHeroLevel()); - } - default: - return 0; - } - } - - public void cancelBuildQueueItem(final CSimulation game, final int cancelIndex) { - if ((cancelIndex >= 0) && (cancelIndex < this.buildQueueTypes.length)) { - final QueueItemType cancelledType = this.buildQueueTypes[cancelIndex]; - if (cancelledType != null) { - // TODO refund here! - if (cancelIndex == 0) { - this.constructionProgress = 0.0f; - switch (cancelledType) { - case RESEARCH: - break; - case UNIT: { - final CPlayer player = game.getPlayer(this.playerIndex); - final CUnitType unitType = game.getUnitData().getUnitType(this.buildQueue[cancelIndex]); - player.setFoodUsed(player.getFoodUsed() - unitType.getFoodUsed()); - break; - } - case HERO_REVIVE: { - final CPlayer player = game.getPlayer(this.playerIndex); - final CUnitType unitType = game.getUnit(this.buildQueue[cancelIndex].getValue()).getUnitType(); - player.setFoodUsed(player.getFoodUsed() - unitType.getFoodUsed()); - break; - } - } - } - switch (cancelledType) { - case RESEARCH: - break; - case UNIT: { - final CPlayer player = game.getPlayer(this.playerIndex); - final CUnitType unitType = game.getUnitData().getUnitType(this.buildQueue[cancelIndex]); - player.refundFor(unitType); - break; - } - case HERO_REVIVE: { - final CPlayer player = game.getPlayer(this.playerIndex); - final CUnit hero = game.getUnit(this.buildQueue[cancelIndex].getValue()); - final CUnitType unitType = hero.getUnitType(); - final CAbilityHero heroData = hero.getHeroData(); - heroData.setReviving(false); - final CGameplayConstants gameplayConstants = game.getGameplayConstants(); - player.refund( - gameplayConstants.getHeroReviveGoldCost(unitType.getGoldCost(), heroData.getHeroLevel()), - gameplayConstants.getHeroReviveLumberCost(unitType.getLumberCost(), - heroData.getHeroLevel())); - break; - } - } - for (int i = cancelIndex; i < (this.buildQueueTypes.length - 1); i++) { - setBuildQueueItem(game, i, this.buildQueue[i + 1], this.buildQueueTypes[i + 1]); - } - setBuildQueueItem(game, this.buildQueue.length - 1, null, null); - this.stateNotifier.queueChanged(); - } - } - } - - public void setBuildQueueItem(final CSimulation game, final int index, final War3ID rawcode, - final QueueItemType queueItemType) { - this.buildQueue[index] = rawcode; - this.buildQueueTypes[index] = queueItemType; - if (index == 0) { - this.queuedUnitFoodPaid = true; - if (rawcode != null) { - if (queueItemType == QueueItemType.UNIT) { - final CPlayer player = game.getPlayer(this.playerIndex); - final CUnitType unitType = game.getUnitData().getUnitType(this.buildQueue[index]); - if (unitType.getFoodUsed() != 0) { - final int newFoodUsed = player.getFoodUsed() + unitType.getFoodUsed(); - if (newFoodUsed <= player.getFoodCap()) { - player.setFoodUsed(newFoodUsed); - } - else { - this.queuedUnitFoodPaid = false; - game.getCommandErrorListener(this.playerIndex).showNoFoodError(); - } - } - } - else if (queueItemType == QueueItemType.HERO_REVIVE) { - final CPlayer player = game.getPlayer(this.playerIndex); - final CUnitType unitType = game.getUnit(this.buildQueue[index].getValue()).getUnitType(); - if (unitType.getFoodUsed() != 0) { - final int newFoodUsed = player.getFoodUsed() + unitType.getFoodUsed(); - if (newFoodUsed <= player.getFoodCap()) { - player.setFoodUsed(newFoodUsed); - } - else { - this.queuedUnitFoodPaid = false; - game.getCommandErrorListener(this.playerIndex).showNoFoodError(); - } - } - } - } - } - } - - public void queueTrainingUnit(final CSimulation game, final War3ID rawcode) { - if (queue(game, rawcode, QueueItemType.UNIT)) { - final CPlayer player = game.getPlayer(this.playerIndex); - final CUnitType unitType = game.getUnitData().getUnitType(rawcode); - player.chargeFor(unitType); - } - } - - public void queueRevivingHero(final CSimulation game, final CUnit hero) { - if (queue(game, new War3ID(hero.getHandleId()), QueueItemType.HERO_REVIVE)) { - hero.getHeroData().setReviving(true); - final CPlayer player = game.getPlayer(this.playerIndex); - final int heroReviveGoldCost = game.getGameplayConstants() - .getHeroReviveGoldCost(hero.getUnitType().getGoldCost(), hero.getHeroData().getHeroLevel()); - final int heroReviveLumberCost = game.getGameplayConstants() - .getHeroReviveLumberCost(hero.getUnitType().getGoldCost(), hero.getHeroData().getHeroLevel()); - player.charge(heroReviveGoldCost, heroReviveLumberCost); - } - } - - public void queueResearch(final CSimulation game, final War3ID rawcode) { - queue(game, rawcode, QueueItemType.RESEARCH); - } - - public static enum QueueItemType { - UNIT, - RESEARCH, - HERO_REVIVE; - } - - public void setRallyPoint(final AbilityTarget target) { - this.rallyPoint = target; - this.stateNotifier.rallyPointChanged(); - } - - public void internalPublishHeroStatsChanged() { - this.stateNotifier.heroStatsChanged(); - } - - public AbilityTarget getRallyPoint() { - return this.rallyPoint; - } - - private static interface RallyProvider { - float getX(); - - float getY(); - } - - @Override - public T visit(final AbilityTargetVisitor visitor) { - return visitor.accept(this); - } - - private static final class UseAbilityOnTargetByIdVisitor implements AbilityTargetVisitor { - private static final UseAbilityOnTargetByIdVisitor INSTANCE = new UseAbilityOnTargetByIdVisitor(); - private CSimulation game; - private CUnit trainedUnit; - private int rallyOrderId; - - private UseAbilityOnTargetByIdVisitor reset(final CSimulation game, final CUnit trainedUnit, - final int rallyOrderId) { - this.game = game; - this.trainedUnit = trainedUnit; - this.rallyOrderId = rallyOrderId; - return this; - } - - @Override - public Void accept(final AbilityPointTarget target) { - CAbility abilityToUse = null; - for (final CAbility ability : this.trainedUnit.getAbilities()) { - ability.checkCanUse(this.game, this.trainedUnit, this.rallyOrderId, - BooleanAbilityActivationReceiver.INSTANCE); - if (BooleanAbilityActivationReceiver.INSTANCE.isOk()) { - final BooleanAbilityTargetCheckReceiver targetCheckReceiver = BooleanAbilityTargetCheckReceiver - .getInstance().reset(); - ability.checkCanTarget(this.game, this.trainedUnit, this.rallyOrderId, target, targetCheckReceiver); - if (targetCheckReceiver.isTargetable()) { - abilityToUse = ability; - } - } - } - if (abilityToUse != null) { - this.trainedUnit.order(this.game, - new COrderTargetPoint(abilityToUse.getHandleId(), this.rallyOrderId, target, false), false); - } - return null; - } - - @Override - public Void accept(final CUnit targetUnit) { - return acceptWidget(this.game, this.trainedUnit, this.rallyOrderId, targetUnit); - } - - private Void acceptWidget(final CSimulation game, final CUnit trainedUnit, final int rallyOrderId, - final CWidget target) { - CAbility abilityToUse = null; - for (final CAbility ability : trainedUnit.getAbilities()) { - ability.checkCanUse(game, trainedUnit, rallyOrderId, BooleanAbilityActivationReceiver.INSTANCE); - if (BooleanAbilityActivationReceiver.INSTANCE.isOk()) { - final BooleanAbilityTargetCheckReceiver targetCheckReceiver = BooleanAbilityTargetCheckReceiver - .getInstance().reset(); - ability.checkCanTarget(game, trainedUnit, rallyOrderId, target, targetCheckReceiver); - if (targetCheckReceiver.isTargetable()) { - abilityToUse = ability; - } - } - } - if (abilityToUse != null) { - trainedUnit.order(game, - new COrderTargetWidget(abilityToUse.getHandleId(), rallyOrderId, target.getHandleId(), false), - false); - } - return null; - } - - @Override - public Void accept(final CDestructable target) { - return acceptWidget(this.game, this.trainedUnit, this.rallyOrderId, target); - } - - @Override - public Void accept(final CItem target) { - return acceptWidget(this.game, this.trainedUnit, this.rallyOrderId, target); - } - } - - public int getFoodMade() { - return this.foodMade; - } - - public int getFoodUsed() { - return this.foodUsed; - } - - public int setFoodMade(final int foodMade) { - final int delta = foodMade - this.foodMade; - this.foodMade = foodMade; - return delta; - } - - public int setFoodUsed(final int foodUsed) { - final int delta = foodUsed - this.foodUsed; - this.foodUsed = foodUsed; - return delta; - } - - public void setDefaultBehavior(final CBehavior defaultBehavior) { - this.defaultBehavior = defaultBehavior; - } - - public int getGold() { - for (final CAbility ability : this.abilities) { - if (ability instanceof CAbilityGoldMine) { - return ((CAbilityGoldMine) ability).getGold(); - } - } - return 0; - } - - public void setGold(final int goldAmount) { - for (final CAbility ability : this.abilities) { - if (ability instanceof CAbilityGoldMine) { - ((CAbilityGoldMine) ability).setGold(goldAmount); - } - } - } - - public Queue getOrderQueue() { - return this.orderQueue; - } - - public COrder getCurrentOrder() { - return this.lastStartedOrder; - } - - public CAbilityHero getHeroData() { - for (final CAbility ability : this.abilities) { - if (ability instanceof CAbilityHero) { - return (CAbilityHero) ability; - } - } - return null; - } - - public CAbilityInventory getInventoryData() { - for (final CAbility ability : this.abilities) { - if (ability instanceof CAbilityInventory) { - return (CAbilityInventory) ability; - } - } - return null; - } - - public void setUnitSpecificAttacks(final List unitSpecificAttacks) { - this.unitSpecificAttacks = unitSpecificAttacks; - } - - public List getUnitSpecificAttacks() { - return this.unitSpecificAttacks; - } - - public List getAttacks() { - if (this.unitSpecificAttacks != null) { - return this.unitSpecificAttacks; - } - return this.unitType.getAttacks(); - } - - public void onPickUpItem(final CSimulation game, final CItem item, final boolean playUserUISounds) { - this.stateNotifier.inventoryChanged(); - if (playUserUISounds) { - game.unitPickUpItemEvent(this, item); - } - } - - public void onDropItem(final CSimulation game, final CItem droppedItem, final boolean playUserUISounds) { - this.stateNotifier.inventoryChanged(); - if (playUserUISounds) { - game.unitDropItemEvent(this, droppedItem); - } - } - - public boolean isInRegion(final CRegion region) { - return this.containingRegions.contains(region); - } - - @Override - public float getMaxLife() { - return this.maximumLife; - } - - private static final class RegionCheckerImpl implements CRegionEnumFunction { - private CUnit unit; - private CRegionManager regionManager; - - public RegionCheckerImpl reset(final CUnit unit, final CRegionManager regionManager) { - this.unit = unit; - this.regionManager = regionManager; - return this; - } - - @Override - public boolean call(final CRegion region) { - if (this.unit.containingRegions.add(region)) { - if (!this.unit.priorContainingRegions.contains(region)) { - this.regionManager.onUnitEnterRegion(this.unit, region); - } - } - return false; - } - - } - - public boolean isBuilding() { - return this.unitType.isBuilding(); - } - - public void onRemove(final CSimulation simulation) { - setLife(simulation, 0); - simulation.getWorldCollision().removeUnit(this); - } - - private static enum StateListenerUpdateType { - ADD, - REMOVE; - } - - private static final class StateListenerUpdate { - private final CUnitStateListener listener; - private final StateListenerUpdateType updateType; - - public StateListenerUpdate(final CUnitStateListener listener, final StateListenerUpdateType updateType) { - this.listener = listener; - this.updateType = updateType; - } - - public CUnitStateListener getListener() { - return this.listener; - } - - public StateListenerUpdateType getUpdateType() { - return this.updateType; - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitAnimationListener.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitAnimationListener.java deleted file mode 100644 index 65f616c7..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitAnimationListener.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.SecondaryTag; - -public interface CUnitAnimationListener { - void playAnimation(boolean force, final PrimaryTag animationName, - final EnumSet secondaryAnimationTags, float speedRatio, boolean allowRarityVariations); - - void playWalkAnimation(boolean force, float currentMovementSpeed, boolean allowRarityVariations); - - void queueAnimation(final PrimaryTag animationName, final EnumSet secondaryAnimationTags, - boolean allowRarityVariations); - - void addSecondaryTag(SecondaryTag secondaryTag); - - void removeSecondaryTag(SecondaryTag secondaryTag); - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitClassification.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitClassification.java deleted file mode 100644 index d603983d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitClassification.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import java.util.HashMap; -import java.util.Map; - -/** - * We think in the original WC3 sourcecode, these are probably referred to as - * "Unit Types", but the community turn of phrase "Unit Type" has come to refer - * to what WC3 sourcecode calls "Unit Class", hence this is now named "Unit - * Classification" instead of "Unit Type" or "Unit Class" to disambiguate. This - * is consistent with the World Editor naming: "Stats - Unit Classification". - */ -public enum CUnitClassification { - GIANT("giant", "GiantClass"), - UNDEAD("undead", "UndeadClass"), - SUMMONED("summoned"), - MECHANICAL("mechanical", "MechanicalClass"), - PEON("peon"), - SAPPER("sapper"), - TOWNHALL("townhall"), - TREE("tree"), - WARD("ward"), - ANCIENT("ancient"), - STANDON("standon"), - NEURAL("neutral"), - TAUREN("tauren", "TaurenClass"); - private static final Map UNIT_EDITOR_KEY_TO_CLASSIFICATION = new HashMap<>(); - static { - for (final CUnitClassification unitClassification : values()) { - UNIT_EDITOR_KEY_TO_CLASSIFICATION.put(unitClassification.getUnitDataKey(), unitClassification); - } - } - - private String localeKey; - private String unitDataKey; - private String displayName; - - private CUnitClassification(final String unitDataKey, final String localeKey) { - this.unitDataKey = unitDataKey; - this.localeKey = localeKey; - } - - private CUnitClassification(final String unitDataKey) { - this.unitDataKey = unitDataKey; - this.localeKey = null; - } - - public String getUnitDataKey() { - return this.unitDataKey; - } - - public String getLocaleKey() { - return this.localeKey; - } - - public String getDisplayName() { - return this.displayName; - } - - public void setDisplayName(final String displayName) { - this.displayName = displayName; - } - - public static CUnitClassification parseUnitClassification(final String unitEditorKey) { - return UNIT_EDITOR_KEY_TO_CLASSIFICATION.get(unitEditorKey.toLowerCase()); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitEnumFunction.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitEnumFunction.java deleted file mode 100644 index 3f0392dd..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitEnumFunction.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -public interface CUnitEnumFunction { - /** - * Operates on a unit, returning true if we should stop execution. - * - * @param unit - * @return - */ - boolean call(CUnit unit); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitStateListener.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitStateListener.java deleted file mode 100644 index 2f1356a2..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitStateListener.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import com.etheller.warsmash.util.SubscriberSetNotifier; - -public interface CUnitStateListener { - void lifeChanged(); // hp (current) changes - - void ordersChanged(); - - void queueChanged(); - - void rallyPointChanged(); - - void waypointsChanged(); - - void heroStatsChanged(); - - void inventoryChanged(); - - public static final class CUnitStateNotifier extends SubscriberSetNotifier - implements CUnitStateListener { - @Override - public void lifeChanged() { - for (final CUnitStateListener listener : set) { - listener.lifeChanged(); - } - } - - @Override - public void ordersChanged() { - for (final CUnitStateListener listener : set) { - listener.ordersChanged(); - } - } - - @Override - public void queueChanged() { - for (final CUnitStateListener listener : set) { - listener.queueChanged(); - } - } - - @Override - public void rallyPointChanged() { - for (final CUnitStateListener listener : set) { - listener.rallyPointChanged(); - } - } - - @Override - public void waypointsChanged() { - for (final CUnitStateListener listener : set) { - listener.waypointsChanged(); - } - } - - @Override - public void heroStatsChanged() { - for (final CUnitStateListener listener : set) { - listener.heroStatsChanged(); - } - } - - @Override - public void inventoryChanged() { - for (final CUnitStateListener listener : set) { - listener.inventoryChanged(); - } - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitType.java deleted file mode 100644 index cea6b5f2..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitType.java +++ /dev/null @@ -1,368 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import java.awt.image.BufferedImage; -import java.util.EnumSet; -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.MovementType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CPrimaryAttribute; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CDefenseType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.data.CUnitRace; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CBuildingPathingType; - -/** - * The quick (symbol table instead of map) lookup for unit type values that we - * probably cannot change per unit instance. - */ -public class CUnitType { - private final String name; - private final String legacyName; - private final War3ID typeId; - private final int maxLife; - private final int manaInitial; - private final int manaMaximum; - private final int speed; - private final int defense; - private final String abilityList; - private final boolean building; - private final PathingGrid.MovementType movementType; - private final float defaultFlyingHeight; - private final float collisionSize; - private final EnumSet classifications; - private final List attacks; - private final String armorType; // used for audio - private final boolean raise; - private final boolean decay; - private final CDefenseType defenseType; - private final float impactZ; - private final float deathTime; - - // TODO: this should probably not be stored as game state, i.e., is it really - // game data? can we store it in a cleaner way? - private final BufferedImage buildingPathingPixelMap; - private final EnumSet targetedAs; - private final float defaultAcquisitionRange; - private final float minimumAttackRange; - private final List structuresBuilt; - private final List unitsTrained; - private final List researchesAvailable; - private final CUnitRace unitRace; - private final int goldCost; - private final int lumberCost; - private final int foodUsed; - private final int foodMade; - private final int buildTime; - private final EnumSet preventedPathingTypes; - private final EnumSet requiredPathingTypes; - private final float propWindow; - private final float turnRate; - private final List requirements; - private final int level; - private final boolean hero; - private final int startingStrength; - private final float strengthPerLevel; - private final int startingAgility; - private final float agilityPerLevel; - private final int startingIntelligence; - private final float intelligencePerLevel; - private final CPrimaryAttribute primaryAttribute; - private final List heroAbilityList; - private final List heroProperNames; - private final int properNamesCount; - private final boolean canFlee; - private final int priority; - private final boolean revivesHeroes; - - public CUnitType(final String name, final String legacyName, final War3ID typeId, final int maxLife, - final int manaInitial, final int manaMaximum, final int speed, final int defense, final String abilityList, - final boolean isBldg, final MovementType movementType, final float defaultFlyingHeight, - final float collisionSize, final EnumSet classifications, - final List attacks, final String armorType, final boolean raise, final boolean decay, - final CDefenseType defenseType, final float impactZ, final BufferedImage buildingPathingPixelMap, - final float deathTime, final EnumSet targetedAs, final float defaultAcquisitionRange, - final float minimumAttackRange, final List structuresBuilt, final List unitsTrained, - final List researchesAvailable, final CUnitRace unitRace, final int goldCost, final int lumberCost, - final int foodUsed, final int foodMade, final int buildTime, - final EnumSet preventedPathingTypes, - final EnumSet requiredPathingTypes, final float propWindow, final float turnRate, - final List requirements, final int level, final boolean hero, final int strength, - final float strengthPerLevel, final int agility, final float agilityPerLevel, final int intelligence, - final float intelligencePerLevel, final CPrimaryAttribute primaryAttribute, - final List heroAbilityList, final List heroProperNames, final int properNamesCount, - final boolean canFlee, final int priority, final boolean revivesHeroes) { - this.name = name; - this.legacyName = legacyName; - this.typeId = typeId; - this.maxLife = maxLife; - this.manaInitial = manaInitial; - this.manaMaximum = manaMaximum; - this.speed = speed; - this.defense = defense; - this.abilityList = abilityList; - this.building = isBldg; - this.movementType = movementType; - this.defaultFlyingHeight = defaultFlyingHeight; - this.collisionSize = collisionSize; - this.classifications = classifications; - this.attacks = attacks; - this.armorType = armorType; - this.raise = raise; - this.decay = decay; - this.defenseType = defenseType; - this.impactZ = impactZ; - this.buildingPathingPixelMap = buildingPathingPixelMap; - this.deathTime = deathTime; - this.targetedAs = targetedAs; - this.defaultAcquisitionRange = defaultAcquisitionRange; - this.minimumAttackRange = minimumAttackRange; - this.structuresBuilt = structuresBuilt; - this.unitsTrained = unitsTrained; - this.researchesAvailable = researchesAvailable; - this.unitRace = unitRace; - this.goldCost = goldCost; - this.lumberCost = lumberCost; - this.foodUsed = foodUsed; - this.foodMade = foodMade; - this.buildTime = buildTime; - this.preventedPathingTypes = preventedPathingTypes; - this.requiredPathingTypes = requiredPathingTypes; - this.propWindow = propWindow; - this.turnRate = turnRate; - this.requirements = requirements; - this.level = level; - this.hero = hero; - this.startingStrength = strength; - this.strengthPerLevel = strengthPerLevel; - this.startingAgility = agility; - this.agilityPerLevel = agilityPerLevel; - this.startingIntelligence = intelligence; - this.intelligencePerLevel = intelligencePerLevel; - this.primaryAttribute = primaryAttribute; - this.heroAbilityList = heroAbilityList; - this.heroProperNames = heroProperNames; - this.properNamesCount = properNamesCount; - this.canFlee = canFlee; - this.priority = priority; - this.revivesHeroes = revivesHeroes; - } - - public String getName() { - return this.name; - } - - public String getLegacyName() { - return this.legacyName; - } - - public War3ID getTypeId() { - return this.typeId; - } - - public int getMaxLife() { - return this.maxLife; - } - - public int getManaInitial() { - return this.manaInitial; - } - - public int getManaMaximum() { - return this.manaMaximum; - } - - public int getSpeed() { - return this.speed; - } - - public int getDefense() { - return this.defense; - } - - public String getAbilityList() { - return this.abilityList; - } - - public float getDefaultFlyingHeight() { - return this.defaultFlyingHeight; - } - - public PathingGrid.MovementType getMovementType() { - return this.movementType; - } - - public float getCollisionSize() { - return this.collisionSize; - } - - public boolean isBuilding() { - return this.building; - } - - public EnumSet getClassifications() { - return this.classifications; - } - - public List getAttacks() { - return this.attacks; - } - - public boolean isRaise() { - return this.raise; - } - - public boolean isDecay() { - return this.decay; - } - - public String getArmorType() { - return this.armorType; - } - - public CDefenseType getDefenseType() { - return this.defenseType; - } - - public float getImpactZ() { - return this.impactZ; - } - - public BufferedImage getBuildingPathingPixelMap() { - return this.buildingPathingPixelMap; - } - - public float getDeathTime() { - return this.deathTime; - } - - public EnumSet getTargetedAs() { - return this.targetedAs; - } - - public float getDefaultAcquisitionRange() { - return this.defaultAcquisitionRange; - } - - public float getMinimumAttackRange() { - return this.minimumAttackRange; - } - - public List getStructuresBuilt() { - return this.structuresBuilt; - } - - public List getUnitsTrained() { - return this.unitsTrained; - } - - public List getResearchesAvailable() { - return this.researchesAvailable; - } - - public CUnitRace getRace() { - return this.unitRace; - } - - public int getGoldCost() { - return this.goldCost; - } - - public int getLumberCost() { - return this.lumberCost; - } - - public int getFoodUsed() { - return this.foodUsed; - } - - public int getFoodMade() { - return this.foodMade; - } - - public int getBuildTime() { - return this.buildTime; - } - - public EnumSet getPreventedPathingTypes() { - return this.preventedPathingTypes; - } - - public EnumSet getRequiredPathingTypes() { - return this.requiredPathingTypes; - } - - public float getPropWindow() { - return this.propWindow; - } - - public float getTurnRate() { - return this.turnRate; - } - - public List getRequirements() { - return this.requirements; - } - - public int getLevel() { - return this.level; - } - - public boolean isHero() { - return this.hero; - } - - public int getStartingStrength() { - return this.startingStrength; - } - - public float getStrengthPerLevel() { - return this.strengthPerLevel; - } - - public int getStartingAgility() { - return this.startingAgility; - } - - public float getAgilityPerLevel() { - return this.agilityPerLevel; - } - - public int getStartingIntelligence() { - return this.startingIntelligence; - } - - public float getIntelligencePerLevel() { - return this.intelligencePerLevel; - } - - public CPrimaryAttribute getPrimaryAttribute() { - return this.primaryAttribute; - } - - public List getHeroAbilityList() { - return this.heroAbilityList; - } - - public List getHeroProperNames() { - return this.heroProperNames; - } - - public int getProperNamesCount() { - return this.properNamesCount; - } - - public boolean isCanFlee() { - return this.canFlee; - } - - public int getPriority() { - return this.priority; - } - - public boolean isRevivesHeroes() { - return this.revivesHeroes; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitTypeRequirement.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitTypeRequirement.java deleted file mode 100644 index 63b810de..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CUnitTypeRequirement.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import com.etheller.warsmash.util.War3ID; - -public class CUnitTypeRequirement { - private final War3ID requirement; - private final int requiredLevel; - - public CUnitTypeRequirement(final War3ID requirement, final int requiredLevel) { - this.requirement = requirement; - this.requiredLevel = requiredLevel; - } - - public War3ID getRequirement() { - return this.requirement; - } - - public int getRequiredLevel() { - return this.requiredLevel; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWidget.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWidget.java deleted file mode 100644 index 428d9c61..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWidget.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import java.util.EnumSet; - -import com.badlogic.gdx.math.Rectangle; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public abstract class CWidget implements AbilityTarget { - protected static final Rectangle tempRect = new Rectangle(); - private final int handleId; - private float x; - private float y; - protected float life; - - public CWidget(final int handleId, final float x, final float y, final float life) { - this.handleId = handleId; - this.x = x; - this.y = y; - this.life = life; - } - - public int getHandleId() { - return this.handleId; - } - - @Override - public float getX() { - return this.x; - } - - @Override - public float getY() { - return this.y; - } - - public float getLife() { - return this.life; - } - - public abstract float getMaxLife(); - - protected void setX(final float x) { - this.x = x; - } - - protected void setY(final float y) { - this.y = y; - } - - public void setLife(final CSimulation simulation, final float life) { - this.life = life; - } - - public abstract void damage(final CSimulation simulation, final CUnit source, final CAttackType attackType, - final String weaponType, final float damage); - - public abstract float getFlyHeight(); - - public abstract float getImpactZ(); - - public boolean isDead() { - return this.life <= 0; - } - - public abstract boolean canBeTargetedBy(CSimulation simulation, CUnit source, - final EnumSet targetsAllowed); - - public double distanceSquaredNoCollision(final AbilityTarget target) { - final double dx = Math.abs(target.getX() - getX()); - final double dy = Math.abs(target.getY() - getY()); - return (dx * dx) + (dy * dy); - } - - public abstract boolean isInvulnerable(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWidgetFilterFunction.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWidgetFilterFunction.java deleted file mode 100644 index dc1a7bdb..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWidgetFilterFunction.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -public interface CWidgetFilterFunction { - boolean call(CWidget unit); - - CWidgetFilterFunction ACCEPT_ALL = new CWidgetFilterFunction() { - @Override - public boolean call(final CWidget unit) { - return true; - } - }; - - CWidgetFilterFunction ACCEPT_ALL_LIVING = new CWidgetFilterFunction() { - @Override - public boolean call(final CWidget unit) { - return !unit.isDead(); - } - }; -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWorldCollision.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWorldCollision.java deleted file mode 100644 index 9cc9a242..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/CWorldCollision.java +++ /dev/null @@ -1,240 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -import java.util.HashSet; -import java.util.Set; - -import com.badlogic.gdx.math.Rectangle; -import com.etheller.warsmash.util.Quadtree; -import com.etheller.warsmash.util.QuadtreeIntersector; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.MovementType; - -public class CWorldCollision { - private static final float MINIMUM_COLLISION_SIZE = 0.001f /* THIS IS TO STOP QUADTREE FROM BUSTING */; - private final Quadtree groundUnitCollision; - private final Quadtree airUnitCollision; - private final Quadtree seaUnitCollision; - private final Quadtree buildingUnitCollision; - private final float maxCollisionRadius; - private final AnyUnitExceptTwoIntersector anyUnitExceptTwoIntersector; - private final EachUnitOnlyOnceIntersector eachUnitOnlyOnceIntersector; - - public CWorldCollision(final Rectangle entireMapBounds, final float maxCollisionRadius) { - this.groundUnitCollision = new Quadtree<>(entireMapBounds); - this.airUnitCollision = new Quadtree<>(entireMapBounds); - this.seaUnitCollision = new Quadtree<>(entireMapBounds); - this.buildingUnitCollision = new Quadtree<>(entireMapBounds); - this.maxCollisionRadius = maxCollisionRadius; - this.anyUnitExceptTwoIntersector = new AnyUnitExceptTwoIntersector(); - this.eachUnitOnlyOnceIntersector = new EachUnitOnlyOnceIntersector(); - } - - public void addUnit(final CUnit unit) { - Rectangle bounds = unit.getCollisionRectangle(); - if (bounds == null) { - final float collisionSize = Math.max(MINIMUM_COLLISION_SIZE, - Math.min(this.maxCollisionRadius, unit.getUnitType().getCollisionSize())); - bounds = new Rectangle(unit.getX() - collisionSize, unit.getY() - collisionSize, collisionSize * 2, - collisionSize * 2); - unit.setCollisionRectangle(bounds); - } - if (unit.isBuilding()) { - // buildings are here so that we can include them when enumerating all units in - // a rect, but they don't really move dynamically, this is kind of pointless - this.buildingUnitCollision.add(unit, bounds); - } - else { - final MovementType movementType = unit.getUnitType().getMovementType(); - if (movementType != null) { - switch (movementType) { - case AMPHIBIOUS: - this.seaUnitCollision.add(unit, bounds); - this.groundUnitCollision.add(unit, bounds); - break; - case FLOAT: - this.seaUnitCollision.add(unit, bounds); - break; - case FLY: - this.airUnitCollision.add(unit, bounds); - break; - case DISABLED: - break; - default: - case FOOT: - case FOOT_NO_COLLISION: - case HORSE: - case HOVER: - this.groundUnitCollision.add(unit, bounds); - break; - } - } - } - } - - public void removeUnit(final CUnit unit) { - final Rectangle bounds = unit.getCollisionRectangle(); - if (bounds != null) { - if (unit.isBuilding()) { - this.buildingUnitCollision.remove(unit, bounds); - } - else { - final MovementType movementType = unit.getUnitType().getMovementType(); - if (movementType != null) { - switch (movementType) { - case AMPHIBIOUS: - this.seaUnitCollision.remove(unit, bounds); - this.groundUnitCollision.remove(unit, bounds); - break; - case FLOAT: - this.seaUnitCollision.remove(unit, bounds); - break; - case FLY: - this.airUnitCollision.remove(unit, bounds); - break; - case DISABLED: - break; - default: - case FOOT: - case FOOT_NO_COLLISION: - case HORSE: - case HOVER: - this.groundUnitCollision.remove(unit, bounds); - break; - } - } - } - } - unit.setCollisionRectangle(null); - } - - public void enumUnitsInRect(final Rectangle rect, final CUnitEnumFunction callback) { - this.eachUnitOnlyOnceIntersector.reset(callback); - this.groundUnitCollision.intersect(rect, this.eachUnitOnlyOnceIntersector); - this.airUnitCollision.intersect(rect, this.eachUnitOnlyOnceIntersector); - this.seaUnitCollision.intersect(rect, this.eachUnitOnlyOnceIntersector); - this.buildingUnitCollision.intersect(rect, this.eachUnitOnlyOnceIntersector); - } - - public boolean intersectsAnythingOtherThan(final Rectangle newPossibleRectangle, final CUnit sourceUnitToIgnore, - final MovementType movementType) { - return intersectsAnythingOtherThan(newPossibleRectangle, sourceUnitToIgnore, null, movementType); - } - - public boolean intersectsAnythingOtherThan(final Rectangle newPossibleRectangle, final CUnit sourceUnitToIgnore, - final CUnit sourceSecondUnitToIgnore, final MovementType movementType) { - if (movementType != null) { - switch (movementType) { - case AMPHIBIOUS: - if (this.seaUnitCollision.intersect(newPossibleRectangle, - this.anyUnitExceptTwoIntersector.reset(sourceUnitToIgnore, sourceSecondUnitToIgnore))) { - return true; - } - if (this.groundUnitCollision.intersect(newPossibleRectangle, - this.anyUnitExceptTwoIntersector.reset(sourceUnitToIgnore, sourceSecondUnitToIgnore))) { - return true; - } - return false; - case FLOAT: - return this.seaUnitCollision.intersect(newPossibleRectangle, - this.anyUnitExceptTwoIntersector.reset(sourceUnitToIgnore, sourceSecondUnitToIgnore)); - case FLY: - return this.airUnitCollision.intersect(newPossibleRectangle, - this.anyUnitExceptTwoIntersector.reset(sourceUnitToIgnore, sourceSecondUnitToIgnore)); - case DISABLED: - case FOOT_NO_COLLISION: - return false; - default: - case FOOT: - case HORSE: - case HOVER: - return this.groundUnitCollision.intersect(newPossibleRectangle, - this.anyUnitExceptTwoIntersector.reset(sourceUnitToIgnore, sourceSecondUnitToIgnore)); - } - } - return false; - } - - public void translate(final CUnit unit, final float xShift, final float yShift) { - if (unit.isBuilding()) { - throw new IllegalArgumentException("Cannot add building to the CWorldCollision"); - } - final MovementType movementType = unit.getUnitType().getMovementType(); - final Rectangle bounds = unit.getCollisionRectangle(); - if (movementType != null) { - switch (movementType) { - case AMPHIBIOUS: - final float oldX = bounds.x; - final float oldY = bounds.y; - this.seaUnitCollision.translate(unit, bounds, xShift, yShift); - bounds.x = oldX; - bounds.y = oldY; - this.groundUnitCollision.translate(unit, bounds, xShift, yShift); - break; - case FLOAT: - this.seaUnitCollision.translate(unit, bounds, xShift, yShift); - break; - case FLY: - this.airUnitCollision.translate(unit, bounds, xShift, yShift); - break; - case DISABLED: - break; - default: - case FOOT: - case FOOT_NO_COLLISION: - case HORSE: - case HOVER: - this.groundUnitCollision.translate(unit, bounds, xShift, yShift); - break; - } - } - } - - private static final class AnyUnitExceptTwoIntersector implements QuadtreeIntersector { - private CUnit firstUnit; - private CUnit secondUnit; - - public AnyUnitExceptTwoIntersector reset(final CUnit firstUnit, final CUnit secondUnit) { - this.firstUnit = firstUnit; - this.secondUnit = secondUnit; - return this; - } - - @Override - public boolean onIntersect(final CUnit intersectingObject) { - if (intersectingObject.isHidden()) { - return false; - } - return (intersectingObject != this.firstUnit) && (intersectingObject != this.secondUnit); - } - } - - private static final class EachUnitOnlyOnceIntersector implements QuadtreeIntersector { - private CUnitEnumFunction consumerDelegate; - private final Set intersectedUnits = new HashSet<>(); - private boolean done; - - public EachUnitOnlyOnceIntersector reset(final CUnitEnumFunction consumerDelegate) { - this.consumerDelegate = consumerDelegate; - this.intersectedUnits.clear(); - this.done = false; - return this; - } - - @Override - public boolean onIntersect(final CUnit intersectingObject) { - if (intersectingObject.isHidden()) { - return false; - } - if (this.done) { - // This check is because we may use the intersector for multiple intersect - // calls, see "enumUnitsInRect" and how it uses this intersector first on the - // ground unit layer, then the flying unit layer, without recycling - return true; - } - if (this.intersectedUnits.add(intersectingObject)) { - this.done = this.consumerDelegate.call(intersectingObject); - return this.done; - } - return false; - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/HandleIdAllocator.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/HandleIdAllocator.java deleted file mode 100644 index c1be65c8..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/HandleIdAllocator.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -/** - * This class is not similar to how WC3 allocates handle IDs in any way. - * Changing this would probably be necessary to support TimerUtils madness, - * because I forget how it works but I know it uses subtraction on handle IDs. - */ -public class HandleIdAllocator { - private int next = 3412532; // bogus number - - public int createId() { - return this.next++; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/StringsToExternalizeLater.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/StringsToExternalizeLater.java deleted file mode 100644 index 83986431..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/StringsToExternalizeLater.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation; - -public class StringsToExternalizeLater { - public static final String MUST_TARGET_POINT = "Must target a point."; - public static final String MUST_TARGET_WIDGET = "Must target a unit with this action."; -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/AbstractCAbility.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/AbstractCAbility.java deleted file mode 100644 index 7aab18f6..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/AbstractCAbility.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; - -public abstract class AbstractCAbility implements CAbility { - private final int handleId; - private boolean disabled = false; - private boolean iconShowing = true; - - public AbstractCAbility(final int handleId) { - this.handleId = handleId; - } - - @Override - public final int getHandleId() { - return this.handleId; - } - - @Override - public final boolean isDisabled() { - return this.disabled; - } - - @Override - public final void setDisabled(final boolean disabled) { - this.disabled = disabled; - } - - @Override - public final boolean isIconShowing() { - return this.iconShowing; - } - - @Override - public final void setIconShowing(final boolean iconShowing) { - this.iconShowing = iconShowing; - } - - @Override - public final void checkCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - if (this.disabled) { - receiver.disabled(); - } - else { - innerCheckCanUse(game, unit, orderId, receiver); - } - } - - protected abstract void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbility.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbility.java deleted file mode 100644 index 7664f44b..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbility.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; - -public interface CAbility extends CAbilityView { - /* should fire when ability added to unit */ - void onAdd(CSimulation game, CUnit unit); - - /* should fire when ability removed from unit */ - void onRemove(CSimulation game, CUnit unit); - - void onTick(CSimulation game, CUnit unit); - - void onCancelFromQueue(CSimulation game, CUnit unit, int orderId); - - /* return false to not do anything, such as for toggling autocast */ - boolean checkBeforeQueue(CSimulation game, CUnit caster, int orderId, AbilityTarget target); - - CBehavior begin(CSimulation game, CUnit caster, int orderId, CWidget target); - - CBehavior begin(CSimulation game, CUnit caster, int orderId, AbilityPointTarget point); - - CBehavior beginNoTarget(CSimulation game, CUnit caster, int orderId); - - void setDisabled(boolean disabled); - - void setIconShowing(boolean iconShowing); - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityAttack.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityAttack.java deleted file mode 100644 index d0e59a2d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityAttack.java +++ /dev/null @@ -1,186 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttackListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttackMove; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver.TargetType; - -public class CAbilityAttack extends AbstractCAbility { - - public CAbilityAttack(final int handleId) { - super(handleId); - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - receiver.useOk(); - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - if (target == unit) { - receiver.mustTargetType(TargetType.UNIT); - return; // no attacking self ever - } - if (orderId == OrderIds.smart) { - if (target instanceof CUnit) { - if (game.getPlayer(unit.getPlayerIndex()).hasAlliance(((CUnit) target).getPlayerIndex(), - CAllianceType.PASSIVE)) { - receiver.orderIdNotAccepted(); - return; - } - } - else { - receiver.orderIdNotAccepted(); - return; - } - } - if ((orderId == OrderIds.smart) || (orderId == OrderIds.attack)) { - boolean canTarget = false; - for (final CUnitAttack attack : unit.getAttacks()) { - if (target.canBeTargetedBy(game, unit, attack.getTargetsAllowed())) { - canTarget = true; - break; - } - } - if (canTarget) { - receiver.targetOk(target); - } - else { - // TODO obviously we should later support better warnings here - receiver.mustTargetType(TargetType.UNIT); - } - } - else { - receiver.orderIdNotAccepted(); - } - } - - @Override - public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, - final AbilityTarget target) { - return true; - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - switch (orderId) { - case OrderIds.attack: - receiver.targetOk(target); - break; - case OrderIds.attackground: - boolean allowAttackGround = false; - for (final CUnitAttack attack : unit.getAttacks()) { - if (attack.getWeaponType().isAttackGroundSupported()) { - allowAttackGround = true; - break; - } - } - if (allowAttackGround) { - receiver.targetOk(target); - } - else { - receiver.orderIdNotAccepted(); - } - break; - default: - receiver.orderIdNotAccepted(); - break; - } - } - - @Override - public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - receiver.mustTargetType(TargetType.UNIT); - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - unit.setAttackBehavior(new CBehaviorAttack(unit)); - if (!unit.isMovementDisabled()) { - unit.setAttackMoveBehavior(new CBehaviorAttackMove(unit)); - } - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - CBehavior behavior = null; - for (final CUnitAttack attack : caster.getAttacks()) { - if (target.canBeTargetedBy(game, caster, attack.getTargetsAllowed())) { - behavior = caster.getAttackBehavior().reset(OrderIds.attack, attack, target, false, - CBehaviorAttackListener.DO_NOTHING); - break; - } - } - if (behavior == null) { - behavior = caster.getMoveBehavior().reset(OrderIds.attack, target); - } - return behavior; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - switch (orderId) { - case OrderIds.attack: - if (caster.getAttackMoveBehavior() == null) { - return caster.pollNextOrderBehavior(game); - } - caster.setDefaultBehavior(caster.getAttackMoveBehavior()); - return caster.getAttackMoveBehavior().reset(point); - case OrderIds.attackground: - CBehavior behavior = null; - for (final CUnitAttack attack : caster.getAttacks()) { - if (attack.getWeaponType().isAttackGroundSupported()) { - behavior = caster.getAttackBehavior().reset(OrderIds.attackground, attack, point, false, - CBehaviorAttackListener.DO_NOTHING); - break; - } - } - if (behavior == null) { - behavior = caster.getMoveBehavior().reset(OrderIds.attackground, point); - } - return behavior; - default: - return caster.pollNextOrderBehavior(game); - } - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityGeneric.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityGeneric.java deleted file mode 100644 index df4e1704..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityGeneric.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -/** - * Represents an ability from the object data - */ -public class CAbilityGeneric extends AbstractCAbility { - private final War3ID rawcode; - - public CAbilityGeneric(final War3ID rawcode, final int handleId) { - super(handleId); - this.rawcode = rawcode; - } - - public War3ID getRawcode() { - return this.rawcode; - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - receiver.notAnActiveAbility(); - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - } - - @Override - public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, AbilityTarget target) { - return false; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityMove.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityMove.java deleted file mode 100644 index ac37866a..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityMove.java +++ /dev/null @@ -1,137 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorFollow; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorHoldPosition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorMove; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorPatrol; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver.TargetType; - -public class CAbilityMove extends AbstractCAbility { - - public CAbilityMove(final int handleId) { - super(handleId); - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - receiver.useOk(); - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - switch (orderId) { - case OrderIds.smart: - case OrderIds.patrol: - case OrderIds.move: - if ((target instanceof CUnit) && (target != unit)) { - receiver.targetOk(target); - } - else { - receiver.mustTargetType(TargetType.UNIT_OR_POINT); - } - break; - default: - receiver.orderIdNotAccepted(); - break; - } - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - switch (orderId) { - case OrderIds.smart: - case OrderIds.move: - case OrderIds.patrol: - receiver.targetOk(target); - break; - default: - receiver.orderIdNotAccepted(); - break; - } - } - - @Override - public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - switch (orderId) { - case OrderIds.holdposition: - receiver.targetOk(null); - break; - default: - receiver.orderIdNotAccepted(); - break; - } - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - unit.setMoveBehavior(new CBehaviorMove(unit)); - unit.setFollowBehavior(new CBehaviorFollow(unit)); - unit.setPatrolBehavior(new CBehaviorPatrol(unit)); - unit.setHoldPositionBehavior(new CBehaviorHoldPosition(unit)); - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - } - - @Override - public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, AbilityTarget target) { - return true; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - CBehavior followBehavior = caster.getFollowBehavior().reset(orderId == OrderIds.smart ? OrderIds.move : orderId, (CUnit) target); - caster.setDefaultBehavior(followBehavior); - return followBehavior; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - if (orderId == OrderIds.patrol) { - final CBehavior patrolBehavior = caster.getPatrolBehavior().reset(point); - caster.setDefaultBehavior(patrolBehavior); - return patrolBehavior; - } - else { - return caster.getMoveBehavior().reset(OrderIds.move, point); - } - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - if (orderId == OrderIds.holdposition) { - caster.setDefaultBehavior(caster.getHoldPositionBehavior()); - } - return caster.pollNextOrderBehavior(game); - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityToggleableView.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityToggleableView.java deleted file mode 100644 index 810dd9f6..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityToggleableView.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities; - -public interface CAbilityToggleableView extends CAbilityView { - boolean isActive(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityView.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityView.java deleted file mode 100644 index 05cd8118..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityView.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -public interface CAbilityView { - void checkCanUse(CSimulation game, CUnit unit, int orderId, AbilityActivationReceiver receiver); - - void checkCanTarget(CSimulation game, CUnit unit, int orderId, CWidget target, - AbilityTargetCheckReceiver receiver); - - void checkCanTarget(CSimulation game, CUnit unit, int orderId, AbilityPointTarget target, - AbilityTargetCheckReceiver receiver); - - void checkCanTargetNoTarget(CSimulation game, CUnit unit, int orderId, AbilityTargetCheckReceiver receiver); - - int getHandleId(); - - boolean isDisabled(); - - boolean isIconShowing(); - - T visit(CAbilityVisitor visitor); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityVisitor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityVisitor.java deleted file mode 100644 index 58741703..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/CAbilityVisitor.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityBuildInProgress; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNagaBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNeutralBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNightElfBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityOrcBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityUndeadBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityColdArrows; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericNoIconAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericSingleIconActiveAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CAbilityHero; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityQueue; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityRally; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityReviveHero; - -/** - * A visitor for the lowest level inherent types of an ability. It's a bit of a - * design clash to have the notion of an ability visitor pattern while also - * having any arbitrary number of "ability types" defined in config files. But - * the way that we will handle this for now will be with the notion of a generic - * ability (one whose UI information and behaviors come from a rawcode) versus - * abilities with engine-level type information (move, stop, attack). - */ -public interface CAbilityVisitor { - T accept(CAbilityAttack ability); - - T accept(CAbilityMove ability); - - T accept(CAbilityOrcBuild ability); - - T accept(CAbilityHumanBuild ability); - - T accept(CAbilityUndeadBuild ability); - - T accept(CAbilityNightElfBuild ability); - - T accept(CAbilityGeneric ability); - - T accept(CAbilityColdArrows ability); - - T accept(CAbilityNagaBuild ability); - - T accept(CAbilityNeutralBuild ability); - - T accept(CAbilityBuildInProgress ability); - - T accept(CAbilityQueue ability); - - T accept(CAbilityReviveHero ability); - - T accept(GenericSingleIconActiveAbility ability); - - T accept(CAbilityRally ability); - - T accept(GenericNoIconAbility ability); - - T accept(CAbilityHero ability); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/AbstractCAbilityBuild.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/AbstractCAbilityBuild.java deleted file mode 100644 index 811ca64b..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/AbstractCAbilityBuild.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build; - -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitTypeRequirement; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.menu.CAbilityMenu; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; - -public abstract class AbstractCAbilityBuild extends AbstractCAbility implements CAbilityMenu { - private static boolean REFUND_ON_ORDER_CANCEL = false; - private final Set structuresBuilt; - - public AbstractCAbilityBuild(final int handleId, final List structuresBuilt) { - super(handleId); - this.structuresBuilt = new LinkedHashSet<>(structuresBuilt); - } - - public Collection getStructuresBuilt() { - return this.structuresBuilt; - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - final War3ID orderIdAsRawtype = new War3ID(orderId); - if (this.structuresBuilt.contains(orderIdAsRawtype)) { - final CUnitType unitType = game.getUnitData().getUnitType(orderIdAsRawtype); - if (unitType != null) { - final CPlayer player = game.getPlayer(unit.getPlayerIndex()); - final List requirements = unitType.getRequirements(); - boolean requirementsMet = true; - for (final CUnitTypeRequirement requirement : requirements) { - if (player.getTechtreeUnlocked(requirement.getRequirement()) < requirement.getRequiredLevel()) { - requirementsMet = false; - } - } - if (requirementsMet) { - if (player.getGold() >= unitType.getGoldCost()) { - if (player.getLumber() >= unitType.getLumberCost()) { - if ((unitType.getFoodUsed() == 0) - || ((player.getFoodUsed() + unitType.getFoodUsed()) <= player.getFoodCap())) { - - receiver.useOk(); - } - else { - receiver.notEnoughResources(ResourceType.FOOD); - } - } - else { - receiver.notEnoughResources(ResourceType.LUMBER); - } - } - else { - receiver.notEnoughResources(ResourceType.GOLD); - } - } - else { - for (final CUnitTypeRequirement requirement : requirements) { - receiver.missingRequirement(requirement.getRequirement(), requirement.getRequiredLevel()); - } - } - } - else { - receiver.useOk(); - } - } - else { - /// ??? - receiver.useOk(); - } - } - - @Override - public final void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public final void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - if (this.structuresBuilt.contains(new War3ID(orderId))) { - receiver.targetOk(target); - } - else { - receiver.orderIdNotAccepted(); - } - } - - @Override - public final void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, AbilityTarget target) { - return true; - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - if (REFUND_ON_ORDER_CANCEL) { - final CPlayer player = game.getPlayer(unit.getPlayerIndex()); - final War3ID orderIdAsRawtype = new War3ID(orderId); - final CUnitType unitType = game.getUnitData().getUnitType(orderIdAsRawtype); - player.refundFor(unitType); - if (unitType.getFoodUsed() != 0) { - player.setFoodUsed(player.getFoodUsed() - unitType.getFoodUsed()); - } - } - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityBuildInProgress.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityBuildInProgress.java deleted file mode 100644 index 7c9c0859..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityBuildInProgress.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -public class CAbilityBuildInProgress extends AbstractCAbility { - - public CAbilityBuildInProgress(final int handleId) { - super(handleId); - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - } - - @Override - public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, AbilityTarget target) { - final CPlayer player = game.getPlayer(caster.getPlayerIndex()); - player.refundFor(caster.getUnitType()); - caster.setLife(game, 0); - return false; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return null; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - return null; - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return null; - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - receiver.useOk(); - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - if (orderId == OrderIds.cancel) { - receiver.targetOk(null); - } - else { - receiver.orderIdNotAccepted(); - } - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - // TODO Auto-generated method stub - - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityHumanBuild.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityHumanBuild.java deleted file mode 100644 index b6f420ff..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityHumanBuild.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build; - -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; - -public class CAbilityHumanBuild extends AbstractCAbilityBuild { - - public CAbilityHumanBuild(final int handleId, final List structuresBuilt) { - super(handleId, structuresBuilt); - // TODO Auto-generated constructor stub - } - - @Override - public int getBaseOrderId() { - return OrderIds.humanbuild; - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - // TODO Auto-generated method stub - - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - // TODO Auto-generated method stub - - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - // TODO Auto-generated method stub - return null; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { -// caster.getMoveBehavior().reset(point.x, point.y, ) - return null; - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - // TODO Auto-generated method stub - return null; - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - // TODO Auto-generated method stub - - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityHumanRepair.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityHumanRepair.java deleted file mode 100644 index 3b1ec140..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityHumanRepair.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericSingleIconActiveAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build.CBehaviorHumanRepair; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -import java.util.EnumSet; - -public class CAbilityHumanRepair extends AbstractGenericSingleIconActiveAbility { - private EnumSet targetsAllowed; - private final float navalRangeBonus; - private final float repairCostRatio; - private final float repairTimeRatio; - private final float castRange; - private CBehaviorHumanRepair behaviorRepair; - - public CAbilityHumanRepair(int handleId, War3ID alias, EnumSet targetsAllowed, - float navalRangeBonus, float repairCostRatio, float repairTimeRatio, - float castRange) { - super(handleId, alias); - this.targetsAllowed = targetsAllowed; - this.navalRangeBonus = navalRangeBonus; - this.repairCostRatio = repairCostRatio; - this.repairTimeRatio = repairTimeRatio; - this.castRange = castRange; - } - - @Override - protected void innerCheckCanTarget(CSimulation game, CUnit unit, int orderId, CWidget target, AbilityTargetCheckReceiver receiver) { - if(target.canBeTargetedBy(game, unit, targetsAllowed) && target.getLife() < target.getMaxLife()) { - receiver.targetOk(target); - } else { - receiver.orderIdNotAccepted(); - } - } - - @Override - protected void innerCheckCanSmartTarget(CSimulation game, CUnit unit, int orderId, CWidget target, AbilityTargetCheckReceiver receiver) { - innerCheckCanTarget(game, unit, orderId, target, receiver); - } - - @Override - protected void innerCheckCanTarget(CSimulation game, CUnit unit, int orderId, AbilityPointTarget target, AbilityTargetCheckReceiver receiver) { - receiver.mustTargetType(AbilityTargetCheckReceiver.TargetType.UNIT); - } - - @Override - protected void innerCheckCanSmartTarget(CSimulation game, CUnit unit, int orderId, AbilityPointTarget target, AbilityTargetCheckReceiver receiver) { - innerCheckCanTarget(game, unit, orderId, target, receiver); - } - - @Override - protected void innerCheckCanTargetNoTarget(CSimulation game, CUnit unit, int orderId, AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - protected void innerCheckCanUse(CSimulation game, CUnit unit, int orderId, AbilityActivationReceiver receiver) { - receiver.useOk(); - } - - @Override - public void onAdd(CSimulation game, CUnit unit) { - behaviorRepair = new CBehaviorHumanRepair(unit, this); - } - - @Override - public void onRemove(CSimulation game, CUnit unit) { - - } - - @Override - public void onTick(CSimulation game, CUnit unit) { - - } - - @Override - public void onCancelFromQueue(CSimulation game, CUnit unit, int orderId) { - - } - - @Override - public CBehavior begin(CSimulation game, CUnit caster, int orderId, CWidget target) { - return behaviorRepair.reset(target); - } - - @Override - public CBehavior begin(CSimulation game, CUnit caster, int orderId, AbilityPointTarget point) { - return null; - } - - @Override - public CBehavior beginNoTarget(CSimulation game, CUnit caster, int orderId) { - return null; - } - - @Override - public int getBaseOrderId() { - return OrderIds.repair; - } - - @Override - public boolean isToggleOn() { - return false; - } - - public EnumSet getTargetsAllowed() { - return targetsAllowed; - } - - public float getNavalRangeBonus() { - return navalRangeBonus; - } - - public float getRepairCostRatio() { - return repairCostRatio; - } - - public float getRepairTimeRatio() { - return repairTimeRatio; - } - - public float getCastRange() { - return castRange; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityNagaBuild.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityNagaBuild.java deleted file mode 100644 index 57587a6b..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityNagaBuild.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build; - -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; - -public class CAbilityNagaBuild extends AbstractCAbilityBuild { - - public CAbilityNagaBuild(final int handleId, final List structuresBuilt) { - super(handleId, structuresBuilt); - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - // TODO Auto-generated method stub - return null; - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public int getBaseOrderId() { - return OrderIds.nagabuild; - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - // TODO Auto-generated method stub - - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityNeutralBuild.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityNeutralBuild.java deleted file mode 100644 index bbfb9de6..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityNeutralBuild.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build; - -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; - -public class CAbilityNeutralBuild extends AbstractCAbilityBuild { - - public CAbilityNeutralBuild(final int handleId, final List structuresBuilt) { - super(handleId, structuresBuilt); - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - // TODO Auto-generated method stub - return null; - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public int getBaseOrderId() { - return OrderIds.buildmenu; - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - // TODO Auto-generated method stub - - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityNightElfBuild.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityNightElfBuild.java deleted file mode 100644 index 9fd0a2ad..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityNightElfBuild.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build; - -import java.awt.image.BufferedImage; -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build.CBehaviorOrcBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; - -public class CAbilityNightElfBuild extends AbstractCAbilityBuild { - private CBehaviorOrcBuild buildBehavior; - - public CAbilityNightElfBuild(final int handleId, final List structuresBuilt) { - super(handleId, structuresBuilt); - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - this.buildBehavior = new CBehaviorOrcBuild(unit); - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - final War3ID orderIdAsRawtype = new War3ID(orderId); - final CUnitType unitType = game.getUnitData().getUnitType(orderIdAsRawtype); - final BufferedImage buildingPathingPixelMap = unitType.getBuildingPathingPixelMap(); - if (buildingPathingPixelMap != null) { - point.x = (float) Math.floor(point.x / 64f) * 64f; - point.y = (float) Math.floor(point.y / 64f) * 64f; - if (((buildingPathingPixelMap.getWidth() / 2) % 2) == 1) { - point.x += 32f; - } - if (((buildingPathingPixelMap.getHeight() / 2) % 2) == 1) { - point.y += 32f; - } - } - final CPlayer player = game.getPlayer(caster.getPlayerIndex()); - player.chargeFor(unitType); - if (unitType.getFoodUsed() != 0) { - player.setFoodUsed(player.getFoodUsed() + unitType.getFoodUsed()); - } - return this.buildBehavior.reset(point, orderId, getBaseOrderId()); - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public int getBaseOrderId() { - return OrderIds.nightelfbuild; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityOrcBuild.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityOrcBuild.java deleted file mode 100644 index 37a9f57c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityOrcBuild.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build; - -import java.awt.image.BufferedImage; -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build.CBehaviorOrcBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; - -public class CAbilityOrcBuild extends AbstractCAbilityBuild { - private CBehaviorOrcBuild buildBehavior; - - public CAbilityOrcBuild(final int handleId, final List structuresBuilt) { - super(handleId, structuresBuilt); - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - this.buildBehavior = new CBehaviorOrcBuild(unit); - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - final War3ID orderIdAsRawtype = new War3ID(orderId); - final CUnitType unitType = game.getUnitData().getUnitType(orderIdAsRawtype); - final BufferedImage buildingPathingPixelMap = unitType.getBuildingPathingPixelMap(); - if (buildingPathingPixelMap != null) { - point.x = (float) Math.floor(point.x / 64f) * 64f; - point.y = (float) Math.floor(point.y / 64f) * 64f; - if (((buildingPathingPixelMap.getWidth() / 2) % 2) == 1) { - point.x += 32f; - } - if (((buildingPathingPixelMap.getHeight() / 2) % 2) == 1) { - point.y += 32f; - } - } - final CPlayer player = game.getPlayer(caster.getPlayerIndex()); - player.chargeFor(unitType); - if (unitType.getFoodUsed() != 0) { - player.setFoodUsed(player.getFoodUsed() + unitType.getFoodUsed()); - } - return this.buildBehavior.reset(point, orderId, getBaseOrderId()); - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public int getBaseOrderId() { - return OrderIds.orcbuild; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityUndeadBuild.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityUndeadBuild.java deleted file mode 100644 index 8d5a8f7a..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/build/CAbilityUndeadBuild.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build; - -import java.awt.image.BufferedImage; -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build.CBehaviorUndeadBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; - -public class CAbilityUndeadBuild extends AbstractCAbilityBuild { - private CBehaviorUndeadBuild buildBehavior; - - public CAbilityUndeadBuild(final int handleId, final List structuresBuilt) { - super(handleId, structuresBuilt); - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - this.buildBehavior = new CBehaviorUndeadBuild(unit); - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - final War3ID orderIdAsRawtype = new War3ID(orderId); - final CUnitType unitType = game.getUnitData().getUnitType(orderIdAsRawtype); - final BufferedImage buildingPathingPixelMap = unitType.getBuildingPathingPixelMap(); - if (buildingPathingPixelMap != null) { - point.x = (float) Math.floor(point.x / 64f) * 64f; - point.y = (float) Math.floor(point.y / 64f) * 64f; - if (((buildingPathingPixelMap.getWidth() / 2) % 2) == 1) { - point.x += 32f; - } - if (((buildingPathingPixelMap.getHeight() / 2) % 2) == 1) { - point.y += 32f; - } - } - final CPlayer player = game.getPlayer(caster.getPlayerIndex()); - player.chargeFor(unitType); - if (unitType.getFoodUsed() != 0) { - player.setFoodUsed(player.getFoodUsed() + unitType.getFoodUsed()); - } - return this.buildBehavior.reset(point, orderId, getBaseOrderId()); - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public int getBaseOrderId() { - return OrderIds.undeadbuild; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/combat/CAbilityColdArrows.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/combat/CAbilityColdArrows.java deleted file mode 100644 index 14dd9a07..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/combat/CAbilityColdArrows.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttackListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -/** - * Represents an ability from the object data - */ -public class CAbilityColdArrows extends AbstractCAbility { - private final War3ID rawcode; - private boolean autoCastActive; - - public CAbilityColdArrows(final War3ID rawcode, final int handleId) { - super(handleId); - this.rawcode = rawcode; - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - receiver.useOk(); - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - switch (orderId) { - case OrderIds.coldarrowstarg: - receiver.targetOk(target); - break; - default: - receiver.orderIdNotAccepted(); - break; - } - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - switch (orderId) { - case OrderIds.coldarrows: - case OrderIds.uncoldarrows: - receiver.targetOk(null); - break; - default: - receiver.orderIdNotAccepted(); - break; - } - } - - public War3ID getRawcode() { - return this.rawcode; - } - - public boolean isAutoCastActive() { - return this.autoCastActive; - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - } - - @Override - public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, AbilityTarget target) { - switch (orderId) { - case OrderIds.coldarrows: - case OrderIds.uncoldarrows: - this.autoCastActive = !this.autoCastActive; - return false; - default: - return true; - } - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - CBehavior behavior = null; - for (final CUnitAttack attack : caster.getAttacks()) { - if (target.canBeTargetedBy(game, caster, attack.getTargetsAllowed())) { - behavior = caster.getAttackBehavior().reset(OrderIds.coldarrowstarg, attack, target, false, - CBehaviorAttackListener.DO_NOTHING); - break; - } - } - if (behavior != null) { - return behavior; - } - return caster.pollNextOrderBehavior(game); - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/combat/CAbilityInvulnerable.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/combat/CAbilityInvulnerable.java deleted file mode 100644 index 4d14ecd1..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/combat/CAbilityInvulnerable.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericNoIconAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -public class CAbilityInvulnerable extends AbstractGenericNoIconAbility { - - public CAbilityInvulnerable(final int handleId, final War3ID alias) { - super(handleId, alias); - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - unit.setInvulnerable(true); - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - unit.setInvulnerable(false); - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return null; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - return null; - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return null; - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - receiver.notAnActiveAbility(); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/AbstractGenericNoIconAbility.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/AbstractGenericNoIconAbility.java deleted file mode 100644 index 8abdcaec..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/AbstractGenericNoIconAbility.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; - -public abstract class AbstractGenericNoIconAbility extends AbstractCAbility implements GenericNoIconAbility { - private final War3ID alias; - - public AbstractGenericNoIconAbility(final int handleId, final War3ID alias) { - super(handleId); - this.alias = alias; - } - - @Override - public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, - final AbilityTarget target) { - return true; - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public War3ID getAlias() { - return this.alias; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/AbstractGenericSingleIconActiveAbility.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/AbstractGenericSingleIconActiveAbility.java deleted file mode 100644 index a9a536ee..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/AbstractGenericSingleIconActiveAbility.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -public abstract class AbstractGenericSingleIconActiveAbility extends AbstractCAbility - implements GenericSingleIconActiveAbility { - private final War3ID alias; - - public AbstractGenericSingleIconActiveAbility(final int handleId, final War3ID alias) { - super(handleId); - this.alias = alias; - } - - @Override - public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, - final AbilityTarget target) { - return true; - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - if (orderId == getBaseOrderId()) { - innerCheckCanTarget(game, unit, orderId, target, receiver); - } - else if (orderId == OrderIds.smart) { - innerCheckCanSmartTarget(game, unit, orderId, target, receiver); - } - else { - receiver.orderIdNotAccepted(); - } - } - - protected abstract void innerCheckCanTarget(CSimulation game, CUnit unit, int orderId, CWidget target, - AbilityTargetCheckReceiver receiver); - - protected abstract void innerCheckCanSmartTarget(CSimulation game, CUnit unit, int orderId, CWidget target, - AbilityTargetCheckReceiver receiver); - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - if (orderId == getBaseOrderId()) { - innerCheckCanTarget(game, unit, orderId, target, receiver); - } - else if (orderId == OrderIds.smart) { - innerCheckCanSmartTarget(game, unit, orderId, target, receiver); - } - else { - receiver.orderIdNotAccepted(); - } - } - - protected abstract void innerCheckCanTarget(CSimulation game, CUnit unit, int orderId, AbilityPointTarget target, - AbilityTargetCheckReceiver receiver); - - protected abstract void innerCheckCanSmartTarget(CSimulation game, CUnit unit, int orderId, - AbilityPointTarget target, AbilityTargetCheckReceiver receiver); - - @Override - public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - if (orderId == getBaseOrderId()) { - innerCheckCanTargetNoTarget(game, unit, orderId, receiver); - } - else { - receiver.orderIdNotAccepted(); - } - } - - protected abstract void innerCheckCanTargetNoTarget(CSimulation game, CUnit unit, int orderId, - AbilityTargetCheckReceiver receiver); - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public War3ID getAlias() { - return this.alias; - } - - @Override - public int getUIGoldCost() { - return 0; - } - - @Override - public int getUILumberCost() { - return 0; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/AbstractGenericSingleIconNoSmartActiveAbility.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/AbstractGenericSingleIconNoSmartActiveAbility.java deleted file mode 100644 index aa26147e..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/AbstractGenericSingleIconNoSmartActiveAbility.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -public abstract class AbstractGenericSingleIconNoSmartActiveAbility extends AbstractGenericSingleIconActiveAbility { - - public AbstractGenericSingleIconNoSmartActiveAbility(final int handleId, final War3ID alias) { - super(handleId, alias); - } - - @Override - protected void innerCheckCanSmartTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - protected void innerCheckCanSmartTarget(final CSimulation game, final CUnit unit, final int orderId, - final CWidget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/GenericNoIconAbility.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/GenericNoIconAbility.java deleted file mode 100644 index fb6dd4c6..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/GenericNoIconAbility.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; - -public interface GenericNoIconAbility extends CAbility { - War3ID getAlias(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/GenericSingleIconActiveAbility.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/GenericSingleIconActiveAbility.java deleted file mode 100644 index c52a396d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/generic/GenericSingleIconActiveAbility.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; - -public interface GenericSingleIconActiveAbility extends CAbility { - War3ID getAlias(); - - int getBaseOrderId(); - - boolean isToggleOn(); - - int getUIGoldCost(); - - int getUILumberCost(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/harvest/CAbilityHarvest.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/harvest/CAbilityHarvest.java deleted file mode 100644 index 8e34f181..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/harvest/CAbilityHarvest.java +++ /dev/null @@ -1,236 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest; - -import java.util.EnumSet; -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericSingleIconActiveAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.mine.CAbilityGoldMine; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.harvest.CBehaviorHarvest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.harvest.CBehaviorReturnResources; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CWeaponType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackNormal; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; - -public class CAbilityHarvest extends AbstractGenericSingleIconActiveAbility { - private final int damageToTree; - private final int goldCapacity; - private final int lumberCapacity; - private final float castRange; - private final float duration; - private CBehaviorHarvest behaviorHarvest; - private CBehaviorReturnResources behaviorReturnResources; - private int carriedResourceAmount; - private ResourceType carriedResourceType; - private CUnitAttack treeAttack; - private CWidget lastHarvestTarget; - private CBehaviorAttack behaviorTreeAttack; - - public CAbilityHarvest(final int handleId, final War3ID alias, final int damageToTree, final int goldCapacity, - final int lumberCapacity, final float castRange, final float duration) { - super(handleId, alias); - this.damageToTree = damageToTree; - this.goldCapacity = goldCapacity; - this.lumberCapacity = lumberCapacity; - this.castRange = castRange; - this.duration = duration; - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - - this.behaviorTreeAttack = new CBehaviorAttack(unit); - this.behaviorHarvest = new CBehaviorHarvest(unit, this); - this.behaviorReturnResources = new CBehaviorReturnResources(unit, this); - - final List unitAttacks = unit.getAttacks(); - CUnitAttack bestFitTreeAttack = null; - for (final CUnitAttack attack : unitAttacks) { - if (attack.getTargetsAllowed().contains(CTargetType.TREE)) { - bestFitTreeAttack = attack; - } - } - this.treeAttack = new CUnitAttackNormal( - bestFitTreeAttack == null ? 0.433f : bestFitTreeAttack.getAnimationBackswingPoint(), - bestFitTreeAttack == null ? 0.433f : bestFitTreeAttack.getAnimationDamagePoint(), CAttackType.NORMAL, - this.duration, 0, 1, this.damageToTree * 2, 0, (int) this.castRange, - bestFitTreeAttack == null ? 250 : bestFitTreeAttack.getRangeMotionBuffer(), - bestFitTreeAttack == null ? false : bestFitTreeAttack.isShowUI(), - bestFitTreeAttack == null ? EnumSet.of(CTargetType.TREE) : bestFitTreeAttack.getTargetsAllowed(), - bestFitTreeAttack == null ? "AxeMediumChop" : bestFitTreeAttack.getWeaponSound(), - bestFitTreeAttack == null ? CWeaponType.NORMAL : bestFitTreeAttack.getWeaponType()); - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return this.behaviorHarvest.reset(target); - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - if (isToggleOn() && (orderId == OrderIds.returnresources)) { - return this.behaviorReturnResources.reset(game); - } - return caster.pollNextOrderBehavior(game); - } - - @Override - public int getBaseOrderId() { - return isToggleOn() ? OrderIds.returnresources : OrderIds.harvest; - } - - @Override - public boolean isToggleOn() { - return this.carriedResourceAmount > 0; - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - receiver.useOk(); - } - - @Override - protected void innerCheckCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final CWidget target, final AbilityTargetCheckReceiver receiver) { - if (target instanceof CUnit) { - final CUnit targetUnit = (CUnit) target; - for (final CAbility ability : targetUnit.getAbilities()) { - if (ability instanceof CAbilityGoldMine) { - receiver.targetOk(target); - return; - } - else if ((this.carriedResourceType != null) && (ability instanceof CAbilityReturnResources)) { - final CAbilityReturnResources abilityReturn = (CAbilityReturnResources) ability; - if (abilityReturn.accepts(this.carriedResourceType)) { - receiver.targetOk(target); - return; - } - } - } - receiver.mustTargetResources(); - } - else if (target instanceof CDestructable) { - if (target.canBeTargetedBy(game, unit, this.treeAttack.getTargetsAllowed())) { - receiver.targetOk(target); - } - else { - receiver.mustTargetResources(); - } - } - else { - receiver.mustTargetResources(); - } - } - - @Override - protected void innerCheckCanSmartTarget(final CSimulation game, final CUnit unit, final int orderId, - final CWidget target, final AbilityTargetCheckReceiver receiver) { - innerCheckCanTarget(game, unit, orderId, target, receiver); - } - - @Override - protected void innerCheckCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - protected void innerCheckCanSmartTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - protected void innerCheckCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - if ((orderId == OrderIds.returnresources) && isToggleOn()) { - receiver.targetOk(null); - } - else { - receiver.orderIdNotAccepted(); - } - } - - public int getDamageToTree() { - return this.damageToTree; - } - - public int getGoldCapacity() { - return this.goldCapacity; - } - - public int getLumberCapacity() { - return this.lumberCapacity; - } - - public int getCarriedResourceAmount() { - return this.carriedResourceAmount; - } - - public ResourceType getCarriedResourceType() { - return this.carriedResourceType; - } - - public void setCarriedResources(final ResourceType carriedResourceType, final int carriedResourceAmount) { - this.carriedResourceType = carriedResourceType; - this.carriedResourceAmount = carriedResourceAmount; - } - - public CBehaviorHarvest getBehaviorHarvest() { - return this.behaviorHarvest; - } - - public CBehaviorReturnResources getBehaviorReturnResources() { - return this.behaviorReturnResources; - } - - public CUnitAttack getTreeAttack() { - return this.treeAttack; - } - - public void setLastHarvestTarget(final CWidget lastHarvestTarget) { - this.lastHarvestTarget = lastHarvestTarget; - } - - public CWidget getLastHarvestTarget() { - return this.lastHarvestTarget; - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - } - - public CBehaviorAttack getBehaviorTreeAttack() { - return this.behaviorTreeAttack; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/harvest/CAbilityReturnResources.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/harvest/CAbilityReturnResources.java deleted file mode 100644 index c3d10512..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/harvest/CAbilityReturnResources.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest; - -import java.util.EnumSet; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericNoIconAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; - -/** - * Was probably named CAbilityReturn in 2002, idk - */ -public class CAbilityReturnResources extends AbstractGenericNoIconAbility { - private final EnumSet acceptedResourceTypes; - - public CAbilityReturnResources(final int handleId, final War3ID alias, - final EnumSet acceptedResourceTypes) { - super(handleId, alias); - this.acceptedResourceTypes = acceptedResourceTypes; - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return null; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - return null; - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return null; - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - receiver.notAnActiveAbility(); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - } - - public boolean accepts(final ResourceType resourceType) { - if (isDisabled()) { - return false; - } - return this.acceptedResourceTypes.contains(resourceType); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/hero/CAbilityHero.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/hero/CAbilityHero.java deleted file mode 100644 index a8afef88..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/hero/CAbilityHero.java +++ /dev/null @@ -1,295 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero; - -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CGameplayConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -public class CAbilityHero extends AbstractCAbility { - private final List skillsAvailable; - private int xp; - private int heroLevel; - private int skillPoints; - - private HeroStatValue strength; - private HeroStatValue agility; - private HeroStatValue intelligence; - private String properName; - private boolean awaitingRevive; - private boolean reviving; - - public CAbilityHero(final int handleId, final List skillsAvailable) { - super(handleId); - this.skillsAvailable = skillsAvailable; - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - this.heroLevel = 1; - this.xp = 0; - final CUnitType unitType = unit.getUnitType(); - this.strength = new HeroStatValue(unitType.getStartingStrength(), unitType.getStrengthPerLevel()); - this.agility = new HeroStatValue(unitType.getStartingAgility(), unitType.getAgilityPerLevel()); - this.intelligence = new HeroStatValue(unitType.getStartingIntelligence(), unitType.getIntelligencePerLevel()); - calculateDerivatedFields(game, unit); - - final int nameIndex = game.getSeededRandom().nextInt(unitType.getProperNamesCount()); - - String properName; - final List heroProperNames = unitType.getHeroProperNames(); - if (heroProperNames.size() > 0) { - if (nameIndex < heroProperNames.size()) { - properName = heroProperNames.get(nameIndex); - } - else { - properName = heroProperNames.get(heroProperNames.size() - 1); - } - } - else { - properName = WarsmashConstants.DEFAULT_STRING; - } - this.properName = properName; - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - - } - - @Override - public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, - final AbilityTarget target) { - return true; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return null; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - return null; - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return null; - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - receiver.useOk(); - } - - public int getSkillPoints() { - return this.skillPoints; - } - - public void setSkillPoints(final int skillPoints) { - this.skillPoints = skillPoints; - } - - public int getXp() { - return this.xp; - } - - public void setXp(final int xp) { - this.xp = xp; - } - - public int getHeroLevel() { - return this.heroLevel; - } - - public void setHeroLevel(final int level) { - this.heroLevel = level; - } - - public HeroStatValue getStrength() { - return this.strength; - } - - public HeroStatValue getAgility() { - return this.agility; - } - - public HeroStatValue getIntelligence() { - return this.intelligence; - } - - public String getProperName() { - return this.properName; - } - - public void setAwaitingRevive(final boolean awaitingRevive) { - this.awaitingRevive = awaitingRevive; - } - - public boolean isAwaitingRevive() { - return this.awaitingRevive; - } - - public void setReviving(final boolean reviving) { - this.reviving = reviving; - } - - public boolean isReviving() { - return this.reviving; - } - - public void addXp(final CSimulation simulation, final CUnit unit, final int xp) { - this.xp += xp; - final CGameplayConstants gameplayConstants = simulation.getGameplayConstants(); - while ((this.heroLevel < gameplayConstants.getMaxHeroLevel()) - && (this.xp >= gameplayConstants.getNeedHeroXPSum(this.heroLevel))) { - this.heroLevel++; - this.skillPoints++; - calculateDerivatedFields(simulation, unit); - simulation.unitGainLevelEvent(unit); - } - unit.internalPublishHeroStatsChanged(); - } - - private HeroStatValue getStat(final CPrimaryAttribute attribute) { - switch (attribute) { - case AGILITY: - return this.agility; - case INTELLIGENCE: - return this.intelligence; - default: - case STRENGTH: - return this.strength; - } - } - - private void calculateDerivatedFields(final CSimulation game, final CUnit unit) { - final CGameplayConstants gameplayConstants = game.getGameplayConstants(); - final int prevStrength = this.strength.getCurrent(); - final int prevAgility = this.agility.getCurrent(); - final int prevIntelligence = this.intelligence.getCurrent(); - this.strength.calculate(this.heroLevel); - this.agility.calculate(this.heroLevel); - this.intelligence.calculate(this.heroLevel); - final int deltaStrength = this.strength.getCurrent() - prevStrength; - final int deltaIntelligence = this.intelligence.getCurrent() - prevIntelligence; - final int currentAgility = this.agility.getCurrent(); - final int deltaAgility = currentAgility - prevAgility; - - final int primaryAttribute = getStat(unit.getUnitType().getPrimaryAttribute()).getCurrent(); - for (final CUnitAttack attack : unit.getUnitSpecificAttacks()) { - attack.setPrimaryAttributeDamageBonus((int) (primaryAttribute * gameplayConstants.getStrAttackBonus())); - } - - final float hitPointIncrease = gameplayConstants.getStrHitPointBonus() * deltaStrength; - final int oldMaximumLife = unit.getMaximumLife(); - final float oldLife = unit.getLife(); - final int newMaximumLife = Math.round(oldMaximumLife + hitPointIncrease); - final float newLife = (oldLife * (newMaximumLife)) / oldMaximumLife; - unit.setMaximumLife(newMaximumLife); - unit.setLife(game, newLife); - - final float manaPointIncrease = gameplayConstants.getIntManaBonus() * deltaIntelligence; - final int oldMaximumMana = unit.getMaximumMana(); - final float oldMana = unit.getMana(); - final int newMaximumMana = Math.round(oldMaximumMana + manaPointIncrease); - final float newMana = (oldMana * (newMaximumMana)) / oldMaximumMana; - unit.setMaximumMana(newMaximumMana); - unit.setMana(newMana); - - final int agilityDefenseBonus = Math.round( - gameplayConstants.getAgiDefenseBase() + (gameplayConstants.getAgiDefenseBonus() * currentAgility)); - unit.setAgilityDefenseBonus(agilityDefenseBonus); - } - - public static final class HeroStatValue { - private final float perLevelFactor; - private int base; - private int bonus; - private int currentBase; - private int current; - - private HeroStatValue(final int base, final float perLevelFactor) { - this.base = base; - this.perLevelFactor = perLevelFactor; - } - - public void calculate(final int level) { - this.currentBase = this.base + (int) ((level - 1) * this.perLevelFactor); - this.current = this.currentBase + this.bonus; - } - - public void setBase(final int base) { - this.base = base; - } - - public void setBonus(final int bonus) { - this.bonus = bonus; - } - - public int getCurrent() { - return this.current; - } - - public String getDisplayText() { - String text = Integer.toString(this.currentBase); - if (this.bonus != 0) { - if (this.bonus > 0) { - text += "|cFF00FF00 (+" + this.bonus + ")"; - } - else { - text += "|cFFFF0000 (+" + this.bonus + ")"; - } - } - return text; - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/hero/CPrimaryAttribute.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/hero/CPrimaryAttribute.java deleted file mode 100644 index f00d4d7b..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/hero/CPrimaryAttribute.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero; - -public enum CPrimaryAttribute { - STRENGTH, - INTELLIGENCE, - AGILITY; - - public static CPrimaryAttribute parsePrimaryAttribute(final String targetTypeString) { - if (targetTypeString == null) { - return STRENGTH; - } - switch (targetTypeString.toUpperCase()) { - case "STR": - return STRENGTH; - case "INT": - return INTELLIGENCE; - case "AGI": - return AGILITY; - default: - return STRENGTH; - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/inventory/CAbilityInventory.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/inventory/CAbilityInventory.java deleted file mode 100644 index 803dc6e3..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/inventory/CAbilityInventory.java +++ /dev/null @@ -1,304 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.inventory; - -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItemType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericNoIconAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericSingleIconActiveAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.inventory.CBehaviorDropItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.inventory.CBehaviorGetItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -public class CAbilityInventory extends AbstractGenericNoIconAbility { - private final boolean canDropItems; - private final boolean canGetItems; - private final boolean canUseItems; - private final boolean dropItemsOnDeath; - private final CItem[] itemsHeld; - private final List[] itemsHeldAbilities; - private CBehaviorGetItem behaviorGetItem; - private CBehaviorDropItem behaviorDropItem; - - public CAbilityInventory(final int handleId, final War3ID alias, final boolean canDropItems, - final boolean canGetItems, final boolean canUseItems, final boolean dropItemsOnDeath, - final int itemCapacity) { - super(handleId, alias); - this.canDropItems = canDropItems; - this.canGetItems = canGetItems; - this.canUseItems = canUseItems; - this.dropItemsOnDeath = dropItemsOnDeath; - this.itemsHeld = new CItem[itemCapacity]; - this.itemsHeldAbilities = new List[itemCapacity]; - for (int i = 0; i < this.itemsHeldAbilities.length; i++) { - this.itemsHeldAbilities[i] = new ArrayList<>(); - } - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - this.behaviorGetItem = new CBehaviorGetItem(unit, this); - this.behaviorDropItem = new CBehaviorDropItem(unit, this); - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - - } - - @Override - public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, - final AbilityTarget target) { - if ((orderId >= OrderIds.itemdrag00) && (orderId <= OrderIds.itemdrag05)) { - for (int i = 0; i < this.itemsHeld.length; i++) { - if (this.itemsHeld[i] == target) { - final CItem temp = this.itemsHeld[i]; - final List swapList = this.itemsHeldAbilities[i]; - final int dragDropDestinationIndex = orderId - OrderIds.itemdrag00; - this.itemsHeld[i] = this.itemsHeld[dragDropDestinationIndex]; - this.itemsHeldAbilities[i] = this.itemsHeldAbilities[dragDropDestinationIndex]; - this.itemsHeld[dragDropDestinationIndex] = temp; - this.itemsHeldAbilities[dragDropDestinationIndex] = swapList; - return false; - } - } - } - else if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse05)) { - final CAbility cAbility = this.itemsHeldAbilities[orderId - OrderIds.itemuse00].get(0); - int forwardedOrderId = orderId; - if (cAbility instanceof GenericSingleIconActiveAbility) { - forwardedOrderId = ((GenericSingleIconActiveAbility) cAbility).getBaseOrderId(); - } - cAbility.checkBeforeQueue(game, caster, forwardedOrderId, target); - } - return super.checkBeforeQueue(game, caster, orderId, target); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - - } - - public int getItemCapacity() { - return this.itemsHeld.length; - } - - public CItem getItemInSlot(final int slotIndex) { - if ((slotIndex < 0) || (slotIndex >= this.itemsHeld.length)) { - return null; - } - return this.itemsHeld[slotIndex]; - } - - public boolean isDropItemsOnDeath() { - return this.dropItemsOnDeath; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return this.behaviorGetItem.reset((CItem) target); - } - - public CBehavior beginDropItem(final CSimulation game, final CUnit caster, final int orderId, - final CItem itemToDrop, final AbilityPointTarget target) { - return this.behaviorDropItem.reset(itemToDrop, target); - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - // TODO Auto-generated method stub - return null; - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - final int slot = orderId - OrderIds.itemuse00; - final CBehavior behavior = this.itemsHeldAbilities[slot].get(0).beginNoTarget(game, caster, orderId); - final CItem cItem = this.itemsHeld[slot]; - if (cItem.getItemType().isPerishable()) { - dropItem(game, caster, slot, caster.getX(), caster.getY(), false); - game.removeItem(cItem); - } - return behavior; - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - if (((orderId == OrderIds.getitem) || (orderId == OrderIds.smart)) && !target.isDead()) { - if (target instanceof CItem) { - final CItem targetItem = (CItem) target; - if (!targetItem.isHidden()) { - receiver.targetOk(target); - } - else { - receiver.orderIdNotAccepted(); - } - } - else { - receiver.orderIdNotAccepted(); - } - } - else { - if ((orderId >= OrderIds.itemdrag00) && (orderId <= OrderIds.itemdrag05)) { - if (target instanceof CItem) { - final int slot = getSlot((CItem) target); - if (slot != -1) { - receiver.targetOk(target); - } - else { - receiver.orderIdNotAccepted(); - } - } - else { - receiver.orderIdNotAccepted(); - } - } - receiver.orderIdNotAccepted(); - } - } - - public int getSlot(final CItem target) { - int slot = -1; - for (int i = 0; i < this.itemsHeld.length; i++) { - if (this.itemsHeld[i] == target) { - slot = i; - } - } - return slot; - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - if (orderId == OrderIds.dropitem) { - receiver.orderIdNotAccepted(); - } - } - - @Override - public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse05)) { - receiver.targetOk(null); - } - else { - receiver.orderIdNotAccepted(); - } - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - if ((orderId >= OrderIds.itemuse00) && (orderId <= OrderIds.itemuse05)) { - final int slot = orderId - OrderIds.itemuse00; - if (this.itemsHeldAbilities[slot].size() < 1) { - receiver.notAnActiveAbility(); - } - else { - this.itemsHeldAbilities[slot].get(0).checkCanUse(game, unit, orderId, receiver); - } - } - else { - receiver.useOk(); - } - } - - /** - * Attempts to give the hero the specified item, returning the item slot to - * which the item is added or -1 if no available slot is found - * - * @param item - * @return - */ - public int giveItem(final CSimulation simulation, final CUnit hero, final CItem item, - final boolean playUserUISounds) { - if ((item != null) && !item.isDead() && !item.isHidden()) { - final CItemType itemType = item.getItemType(); - if (itemType.isUseAutomaticallyWhenAcquired()) { - if (itemType.isActivelyUsed()) { - item.setLife(simulation, 0); - // TODO when we give unit ability here, then use ability - } - } - else { - for (int i = 0; i < this.itemsHeld.length; i++) { - if (this.itemsHeld[i] == null) { - this.itemsHeld[i] = item; - item.setHidden(true); - for (final War3ID abilityId : item.getItemType().getAbilityList()) { - final CAbilityType abilityType = simulation.getAbilityData().getAbilityType(abilityId); - if (abilityType != null) { - final CAbility abilityFromItem = abilityType - .createAbility(simulation.getHandleIdAllocator().createId()); - abilityFromItem.setIconShowing(false); - hero.add(simulation, abilityFromItem); - this.itemsHeldAbilities[i].add(abilityFromItem); - } - } - hero.onPickUpItem(simulation, item, true); - return i; - } - } - if (playUserUISounds) { - simulation.getCommandErrorListener(hero.getPlayerIndex()).showInventoryFullError(); - } - } - } - return -1; - } - - public void dropItem(final CSimulation simulation, final CUnit hero, final int slotIndex, final float x, - final float y, final boolean playUserUISounds) { - final CItem droppedItem = this.itemsHeld[slotIndex]; - hero.onDropItem(simulation, droppedItem, playUserUISounds); - this.itemsHeld[slotIndex] = null; - for (final CAbility ability : this.itemsHeldAbilities[slotIndex]) { - hero.remove(simulation, ability); - } - this.itemsHeldAbilities[slotIndex].clear(); - droppedItem.setHidden(false); - droppedItem.setPointAndCheckUnstuck(x, y, simulation); - } - - public void dropItem(final CSimulation simulation, final CUnit hero, final CItem itemToDrop, final float x, - final float y, final boolean playUserUISounds) { - boolean foundItem = false; - int index = -1; - for (int i = 0; i < this.itemsHeld.length; i++) { - if (this.itemsHeld[i] == itemToDrop) { - this.itemsHeld[i] = null; - index = i; - foundItem = true; - } - } - if (foundItem) { - hero.onDropItem(simulation, itemToDrop, playUserUISounds); - itemToDrop.setHidden(false); - for (final CAbility ability : this.itemsHeldAbilities[index]) { - hero.remove(simulation, ability); - } - this.itemsHeldAbilities[index].clear(); - itemToDrop.setPointAndCheckUnstuck(x, y, simulation); - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/item/CAbilityItemAttackBonus.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/item/CAbilityItemAttackBonus.java deleted file mode 100644 index 112b93ea..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/item/CAbilityItemAttackBonus.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.item; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericNoIconAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -public class CAbilityItemAttackBonus extends AbstractGenericNoIconAbility { - private final int damageBonus; - - public CAbilityItemAttackBonus(final int handleId, final War3ID alias, final int damageBonus) { - super(handleId, alias); - this.damageBonus = damageBonus; - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - for (final CUnitAttack attack : unit.getAttacks()) { - attack.setTemporaryDamageBonus(attack.getTemporaryDamageBonus() + this.damageBonus); - } - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - for (final CUnitAttack attack : unit.getAttacks()) { - attack.setTemporaryDamageBonus(attack.getTemporaryDamageBonus() - this.damageBonus); - } - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return null; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - return null; - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return null; - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - receiver.notAnActiveAbility(); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/item/CAbilityItemHeal.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/item/CAbilityItemHeal.java deleted file mode 100644 index e5ff52a7..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/item/CAbilityItemHeal.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.item; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericSingleIconNoSmartActiveAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -public class CAbilityItemHeal extends AbstractGenericSingleIconNoSmartActiveAbility { - private final int lifeToRegain; - - public CAbilityItemHeal(int handleId, War3ID alias, int lifeToRegain) { - super(handleId, alias); - this.lifeToRegain = lifeToRegain; - } - - @Override - protected void innerCheckCanTarget(CSimulation game, CUnit unit, int orderId, CWidget target, AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - protected void innerCheckCanTarget(CSimulation game, CUnit unit, int orderId, AbilityPointTarget target, AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - protected void innerCheckCanTargetNoTarget(CSimulation game, CUnit unit, int orderId, AbilityTargetCheckReceiver receiver) { - if(orderId == getBaseOrderId()) { - receiver.targetOk(null); - } else { - receiver.orderIdNotAccepted(); - } - } - - @Override - protected void innerCheckCanUse(CSimulation game, CUnit unit, int orderId, AbilityActivationReceiver receiver) { - receiver.useOk(); - } - - @Override - public int getBaseOrderId() { - return OrderIds.heal; - } - - @Override - public boolean isToggleOn() { - return false; - } - - @Override - public void onAdd(CSimulation game, CUnit unit) { - - } - - @Override - public void onRemove(CSimulation game, CUnit unit) { - - } - - @Override - public void onTick(CSimulation game, CUnit unit) { - - } - - @Override - public void onCancelFromQueue(CSimulation game, CUnit unit, int orderId) { - - } - - @Override - public boolean checkBeforeQueue(CSimulation game, CUnit caster, int orderId, AbilityTarget target) { - if(target == null && orderId == getBaseOrderId()) { - caster.heal(game, lifeToRegain); - game.createSpellEffectOnUnit(caster, getAlias()); - return false; - } - return super.checkBeforeQueue(game, caster, orderId, target); - } - - @Override - public CBehavior begin(CSimulation game, CUnit caster, int orderId, CWidget target) { - return null; - } - - @Override - public CBehavior begin(CSimulation game, CUnit caster, int orderId, AbilityPointTarget point) { - return null; - } - - @Override - public CBehavior beginNoTarget(CSimulation game, CUnit caster, int orderId) { - return null; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/menu/CAbilityMenu.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/menu/CAbilityMenu.java deleted file mode 100644 index 73440847..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/menu/CAbilityMenu.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.menu; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; - -public interface CAbilityMenu extends CAbility { - // the base order ID of the menu - int getBaseOrderId(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/mine/CAbilityBlightedGoldMine.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/mine/CAbilityBlightedGoldMine.java deleted file mode 100644 index b029b99d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/mine/CAbilityBlightedGoldMine.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.mine; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericNoIconAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -public class CAbilityBlightedGoldMine extends AbstractGenericNoIconAbility { - private int gold; - private final int goldPerInterval; - private final float intervalDuration; - private final int maxNumberOfMiners; - private final float radiusOfMiningRing; - - public CAbilityBlightedGoldMine(final int handleId, final War3ID alias, final int goldPerInterval, - final float intervalDuration, final int maxNumberOfMiners, final float radiusOfMiningRing) { - super(handleId, alias); - this.goldPerInterval = goldPerInterval; - this.intervalDuration = intervalDuration; - this.maxNumberOfMiners = maxNumberOfMiners; - this.radiusOfMiningRing = radiusOfMiningRing; - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { -// final boolean empty = this.activeMiners.isEmpty(); -// if (empty != this.wasEmpty) { -// if (empty) { -// unit.getUnitAnimationListener().removeSecondaryTag(SecondaryTag.WORK); -// } -// else { -// unit.getUnitAnimationListener().addSecondaryTag(SecondaryTag.WORK); -// } -// this.wasEmpty = empty; -// } -// for (int i = this.activeMiners.size() - 1; i >= 0; i--) { -// final CBehaviorHarvest activeMiner = this.activeMiners.get(i); -// if (game.getGameTurnTick() >= activeMiner.getPopoutFromMineTurnTick()) { -// -// final int goldMined = Math.min(this.gold, activeMiner.getGoldCapacity()); -// this.gold -= goldMined; -// if (this.gold <= 0) { -// unit.setLife(game, 0); -// } -// activeMiner.popoutFromMine(goldMined); -// this.activeMiners.remove(i); -// } -// } - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return null; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - return null; - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return null; - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - receiver.notAnActiveAbility(); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - } - - public int getGold() { - return this.gold; - } - - public void setGold(final int gold) { - this.gold = gold; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/mine/CAbilityGoldMine.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/mine/CAbilityGoldMine.java deleted file mode 100644 index 3a28cc60..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/mine/CAbilityGoldMine.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.mine; - -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.SecondaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericNoIconAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.harvest.CBehaviorHarvest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -public class CAbilityGoldMine extends AbstractGenericNoIconAbility { - private int gold; - private final float miningDuration; - private final int miningCapacity; - private final List activeMiners; - private boolean wasEmpty; - - public CAbilityGoldMine(final int handleId, final War3ID alias, final int maxGold, final float miningDuration, - final int miningCapacity) { - super(handleId, alias); - this.gold = maxGold; - this.miningDuration = miningDuration; - this.miningCapacity = miningCapacity; - this.activeMiners = new ArrayList<>(); - this.wasEmpty = this.activeMiners.isEmpty(); - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - final boolean empty = this.activeMiners.isEmpty(); - if (empty != this.wasEmpty) { - if (empty) { - unit.getUnitAnimationListener().removeSecondaryTag(SecondaryTag.WORK); - } - else { - unit.getUnitAnimationListener().addSecondaryTag(SecondaryTag.WORK); - } - this.wasEmpty = empty; - } - for (int i = this.activeMiners.size() - 1; i >= 0; i--) { - final CBehaviorHarvest activeMiner = this.activeMiners.get(i); - if (game.getGameTurnTick() >= activeMiner.getPopoutFromMineTurnTick()) { - - final int goldMined = Math.min(this.gold, activeMiner.getGoldCapacity()); - this.gold -= goldMined; - if (this.gold <= 0) { - unit.setLife(game, 0); - } - activeMiner.popoutFromMine(goldMined); - this.activeMiners.remove(i); - } - } - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return null; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - return null; - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return null; - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - receiver.notAnActiveAbility(); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - } - - public int getGold() { - return this.gold; - } - - public void setGold(final int gold) { - this.gold = gold; - } - - public int getActiveMinerCount() { - return this.activeMiners.size(); - } - - public void addMiner(final CBehaviorHarvest miner) { - this.activeMiners.add(miner); - } - - public int getMiningCapacity() { - return this.miningCapacity; - } - - public float getMiningDuration() { - return this.miningDuration; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityQueue.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityQueue.java deleted file mode 100644 index 72508412..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityQueue.java +++ /dev/null @@ -1,173 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue; - -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitTypeRequirement; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; - -public final class CAbilityQueue extends AbstractCAbility { - private final Set unitsTrained; - private final Set researchesAvailable; - - public CAbilityQueue(final int handleId, final List unitsTrained, final List researchesAvailable) { - super(handleId); - this.unitsTrained = new LinkedHashSet<>(unitsTrained); - this.researchesAvailable = new LinkedHashSet<>(researchesAvailable); - } - - public Set getUnitsTrained() { - return this.unitsTrained; - } - - public Set getResearchesAvailable() { - return this.researchesAvailable; - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - final War3ID orderIdAsRawtype = new War3ID(orderId); - if (this.unitsTrained.contains(orderIdAsRawtype) || this.researchesAvailable.contains(orderIdAsRawtype)) { - final CUnitType unitType = game.getUnitData().getUnitType(orderIdAsRawtype); - if (unitType != null) { - final CPlayer player = game.getPlayer(unit.getPlayerIndex()); - final List requirements = unitType.getRequirements(); - boolean requirementsMet = true; - for (final CUnitTypeRequirement requirement : requirements) { - if (player.getTechtreeUnlocked(requirement.getRequirement()) < requirement.getRequiredLevel()) { - requirementsMet = false; - } - } - if (requirementsMet) { - if (player.getGold() >= unitType.getGoldCost()) { - if (player.getLumber() >= unitType.getLumberCost()) { - if ((unitType.getFoodUsed() == 0) - || ((player.getFoodUsed() + unitType.getFoodUsed()) <= player.getFoodCap())) { - receiver.useOk(); - } - else { - receiver.notEnoughResources(ResourceType.FOOD); - } - } - else { - receiver.notEnoughResources(ResourceType.LUMBER); - } - } - else { - receiver.notEnoughResources(ResourceType.GOLD); - } - } - else { - for (final CUnitTypeRequirement requirement : requirements) { - receiver.missingRequirement(requirement.getRequirement(), requirement.getRequiredLevel()); - } - } - } - else { - receiver.useOk(); - } - } - else { - /// ??? - receiver.useOk(); - } - } - - @Override - public final void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public final void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public final void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - if (this.unitsTrained.contains(new War3ID(orderId)) || this.researchesAvailable.contains(new War3ID(orderId))) { - receiver.targetOk(null); - } - else if (orderId == OrderIds.cancel) { - receiver.targetOk(null); - } - else { - receiver.orderIdNotAccepted(); - } - } - - @Override - public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, AbilityTarget target) { - return true; - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return null; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - return null; - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - if (orderId == OrderIds.cancel) { - caster.cancelBuildQueueItem(game, 0); - } - else { - final War3ID rawcode = new War3ID(orderId); - if (this.unitsTrained.contains(rawcode)) { - caster.queueTrainingUnit(game, rawcode); - } - else if (this.researchesAvailable.contains(rawcode)) { - caster.queueResearch(game, rawcode); - } - } - return null; - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityRally.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityRally.java deleted file mode 100644 index 4f2feccb..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityRally.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -public class CAbilityRally extends AbstractCAbility { - - public CAbilityRally(final int handleId) { - super(handleId); - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - unit.setRallyPoint(unit); - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - receiver.useOk(); - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - switch (orderId) { - case OrderIds.smart: - case OrderIds.setrally: - receiver.targetOk(target); - break; - default: - receiver.orderIdNotAccepted(); - break; - } - } - - @Override - public void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - switch (orderId) { - case OrderIds.smart: - case OrderIds.setrally: - receiver.targetOk(target); - break; - default: - receiver.orderIdNotAccepted(); - break; - } - } - - @Override - public void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, AbilityTarget target) { - return true; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - caster.setRallyPoint(target); - return caster.pollNextOrderBehavior(game); - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - caster.setRallyPoint(point); - return caster.pollNextOrderBehavior(game); - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return null; - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - public int getBaseOrderId() { - return OrderIds.setrally; - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityReviveHero.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityReviveHero.java deleted file mode 100644 index 5767087b..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/queue/CAbilityReviveHero.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.AbstractCAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CAbilityHero; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; - -public final class CAbilityReviveHero extends AbstractCAbility { - - public CAbilityReviveHero(final int handleId) { - super(handleId); - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - final CUnit deadHero = game.getUnit(orderId); - if ((deadHero != null) && (deadHero.getPlayerIndex() == unit.getPlayerIndex())) { - final CAbilityHero heroData = deadHero.getHeroData(); - if ((heroData != null) && heroData.isAwaitingRevive() && !heroData.isReviving()) { - final CPlayer player = game.getPlayer(unit.getPlayerIndex()); - final int heroReviveGoldCost = game.getGameplayConstants() - .getHeroReviveGoldCost(deadHero.getUnitType().getGoldCost(), heroData.getHeroLevel()); - final int heroReviveLumberCost = game.getGameplayConstants() - .getHeroReviveLumberCost(deadHero.getUnitType().getGoldCost(), heroData.getHeroLevel()); - - if (player.getGold() >= heroReviveGoldCost) { - if (player.getLumber() >= heroReviveLumberCost) { - if ((deadHero.getUnitType().getFoodUsed() == 0) - || ((player.getFoodUsed() + deadHero.getUnitType().getFoodUsed()) <= player - .getFoodCap())) { - receiver.useOk(); - } - else { - receiver.notEnoughResources(ResourceType.FOOD); - } - } - else { - receiver.notEnoughResources(ResourceType.LUMBER); - } - } - else { - receiver.notEnoughResources(ResourceType.GOLD); - } - } - } - else { - /// ??? - receiver.useOk(); - } - } - - @Override - public final void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, final CWidget target, - final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public final void checkCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - public final void checkCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - final CUnit deadHero = game.getUnit(orderId); - if ((deadHero != null) && (deadHero.getPlayerIndex() == unit.getPlayerIndex())) { - receiver.targetOk(null); - } - else if (orderId == OrderIds.cancel) { - receiver.targetOk(null); - } - else { - receiver.orderIdNotAccepted(); - } - } - - @Override - public boolean checkBeforeQueue(final CSimulation game, final CUnit caster, final int orderId, - final AbilityTarget target) { - return true; - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return null; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - return null; - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - if (orderId == OrderIds.cancel) { - caster.cancelBuildQueueItem(game, 0); - } - else { - caster.queueRevivingHero(game, game.getUnit(orderId)); - } - return null; - } - - @Override - public T visit(final CAbilityVisitor visitor) { - return visitor.accept(this); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityPointTarget.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityPointTarget.java deleted file mode 100644 index bc443a68..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityPointTarget.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting; - -import com.badlogic.gdx.math.Vector2; - -public class AbilityPointTarget extends Vector2 implements AbilityTarget { - - public AbilityPointTarget() { - super(); - } - - public AbilityPointTarget(final float x, final float y) { - super(x, y); - } - - public AbilityPointTarget(final Vector2 v) { - super(v); - } - - @Override - public float getX() { - return this.x; - } - - @Override - public float getY() { - return this.y; - } - - @Override - public T visit(final AbilityTargetVisitor visitor) { - return visitor.accept(this); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTarget.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTarget.java deleted file mode 100644 index c172d19f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTarget.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting; - -public interface AbilityTarget { - float getX(); - - float getY(); - - T visit(AbilityTargetVisitor visitor); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetItemVisitor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetItemVisitor.java deleted file mode 100644 index b1276abc..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetItemVisitor.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; - -public class AbilityTargetItemVisitor implements AbilityTargetVisitor { - public static final AbilityTargetItemVisitor INSTANCE = new AbilityTargetItemVisitor(); - - @Override - public CItem accept(final AbilityPointTarget target) { - return null; - } - - @Override - public CItem accept(final CUnit target) { - return null; - } - - @Override - public CItem accept(final CDestructable target) { - return null; - } - - @Override - public CItem accept(final CItem target) { - return target; - } - -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetStillAliveAndTargetableVisitor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetStillAliveAndTargetableVisitor.java deleted file mode 100644 index 571a3c17..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetStillAliveAndTargetableVisitor.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public final class AbilityTargetStillAliveAndTargetableVisitor implements AbilityTargetVisitor { - private CSimulation simulation; - private CUnit unit; - private EnumSet targetsAllowed; - - public AbilityTargetStillAliveAndTargetableVisitor reset(final CSimulation simulation, final CUnit unit, - final EnumSet targetsAllowed) { - this.simulation = simulation; - this.unit = unit; - this.targetsAllowed = targetsAllowed; - return this; - } - - @Override - public Boolean accept(final AbilityPointTarget target) { - return Boolean.TRUE; - } - - @Override - public Boolean accept(final CUnit target) { - return !target.isDead() && !target.isHidden() - && target.canBeTargetedBy(this.simulation, this.unit, this.targetsAllowed); - } - - @Override - public Boolean accept(final CDestructable target) { - return !target.isDead() && target.canBeTargetedBy(this.simulation, this.unit, this.targetsAllowed); - } - - @Override - public Boolean accept(final CItem target) { - return !target.isDead() && target.canBeTargetedBy(this.simulation, this.unit, this.targetsAllowed); - } - -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetStillAliveVisitor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetStillAliveVisitor.java deleted file mode 100644 index d6a79175..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetStillAliveVisitor.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; - -public class AbilityTargetStillAliveVisitor implements AbilityTargetVisitor { - public static final AbilityTargetStillAliveVisitor INSTANCE = new AbilityTargetStillAliveVisitor(); - - @Override - public Boolean accept(final AbilityPointTarget target) { - return Boolean.TRUE; - } - - @Override - public Boolean accept(final CUnit target) { - return !target.isDead() && !target.isHidden(); - } - - @Override - public Boolean accept(final CDestructable target) { - return !target.isDead(); - } - - @Override - public Boolean accept(final CItem target) { - return !target.isDead() && !target.isHidden(); - } - -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetVisitor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetVisitor.java deleted file mode 100644 index 4768f679..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetVisitor.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; - -public interface AbilityTargetVisitor { - T accept(AbilityPointTarget target); - - T accept(CUnit target); - - T accept(CDestructable target); - - T accept(CItem target); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetWidgetVisitor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetWidgetVisitor.java deleted file mode 100644 index 7a3deb58..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/targeting/AbilityTargetWidgetVisitor.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; - -public class AbilityTargetWidgetVisitor implements AbilityTargetVisitor { - public static final AbilityTargetWidgetVisitor INSTANCE = new AbilityTargetWidgetVisitor(); - - @Override - public CWidget accept(final AbilityPointTarget target) { - return null; - } - - @Override - public CWidget accept(final CUnit target) { - return target; - } - - @Override - public CWidget accept(final CDestructable target) { - return target; - } - - @Override - public CWidget accept(final CItem target) { - return target; - } - -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/test/CAbilityChannelTest.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/test/CAbilityChannelTest.java deleted file mode 100644 index db50488b..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/test/CAbilityChannelTest.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.test; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericSingleIconNoSmartActiveAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.test.CBehaviorChannelTest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; - -public class CAbilityChannelTest extends AbstractGenericSingleIconNoSmartActiveAbility { - private CBehaviorChannelTest behaviorChannelTest; - private final float artDuration; - - public CAbilityChannelTest(final int handleId, final War3ID alias, final float artDuration) { - super(handleId, alias); - this.artDuration = artDuration; - } - - @Override - public int getBaseOrderId() { - return OrderIds.channel; - } - - @Override - public boolean isToggleOn() { - return false; - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - this.behaviorChannelTest = new CBehaviorChannelTest(unit, this.artDuration); - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - return this.behaviorChannelTest; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - return this.behaviorChannelTest; - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - return this.behaviorChannelTest; - } - - @Override - protected void innerCheckCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final CWidget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - protected void innerCheckCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - protected void innerCheckCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - receiver.targetOk(null); - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - receiver.useOk(); - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/test/CAbilityCoupleInstant.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/test/CAbilityCoupleInstant.java deleted file mode 100644 index 4aeb4cb8..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/test/CAbilityCoupleInstant.java +++ /dev/null @@ -1,213 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.test; - -import java.util.EnumSet; - -import com.badlogic.gdx.math.Rectangle; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitEnumFunction; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.AbstractGenericSingleIconNoSmartActiveAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.test.CBehaviorCoupleInstant; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrderTargetWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityTargetCheckReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; - -public class CAbilityCoupleInstant extends AbstractGenericSingleIconNoSmartActiveAbility { - - private final War3ID resultingUnitType; - private final War3ID partnerUnitType; - private final boolean moveToPartner; - private final float castRange; - private final float area; - private final EnumSet targetsAllowed; - private CBehaviorCoupleInstant behaviorCoupleInstant; - private final int goldCost; - private final int lumberCost; - - public CAbilityCoupleInstant(final int handleId, final War3ID alias, final War3ID resultingUnitType, - final War3ID partnerUnitType, final boolean moveToPartner, final float castRange, final float area, - final EnumSet targetsAllowed, final int goldCost, final int lumberCost) { - super(handleId, alias); - this.resultingUnitType = resultingUnitType; - this.partnerUnitType = partnerUnitType; - this.moveToPartner = moveToPartner; - this.castRange = castRange; - this.area = area; - this.targetsAllowed = targetsAllowed; - this.goldCost = goldCost; - this.lumberCost = lumberCost; - } - - @Override - public int getBaseOrderId() { - return OrderIds.coupleinstant; - } - - @Override - public boolean isToggleOn() { - return false; - } - - @Override - public void onAdd(final CSimulation game, final CUnit unit) { - this.behaviorCoupleInstant = new CBehaviorCoupleInstant(unit, this); - } - - @Override - public void onRemove(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onTick(final CSimulation game, final CUnit unit) { - - } - - @Override - public void onCancelFromQueue(final CSimulation game, final CUnit unit, final int orderId) { - - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, final CWidget target) { - // only from engine, not ever allowed by the checks - if (target instanceof CUnit) { - return this.behaviorCoupleInstant.reset((CUnit) target); - } - return caster.pollNextOrderBehavior(game); - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster, final int orderId, - final AbilityPointTarget point) { - return caster.pollNextOrderBehavior(game); - } - - @Override - public CBehavior beginNoTarget(final CSimulation game, final CUnit caster, final int orderId) { - final PossiblePairFinderEnum possiblePairFinder = new PossiblePairFinderEnum(caster); - game.getWorldCollision().enumUnitsInRect( - new Rectangle(caster.getX() - this.area, caster.getY() - this.area, this.area * 2, this.area * 2), - possiblePairFinder); - final CUnit coupleTarget = possiblePairFinder.pairMatchFound; - if (coupleTarget == null) { - game.getCommandErrorListener(caster.getPlayerIndex()).showUnableToFindCoupleTargetError(); - return caster.pollNextOrderBehavior(game); - } - coupleTarget.order(game, new COrderTargetWidget(possiblePairFinder.pairMatchAbility.getHandleId(), - possiblePairFinder.pairMatchAbility.getBaseOrderId(), caster.getHandleId(), false), false); - return this.behaviorCoupleInstant.reset(coupleTarget); - } - - @Override - protected void innerCheckCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final CWidget target, final AbilityTargetCheckReceiver receiver) { - receiver.targetOk(target); - } - - @Override - protected void innerCheckCanTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityPointTarget target, final AbilityTargetCheckReceiver receiver) { - receiver.orderIdNotAccepted(); - } - - @Override - protected void innerCheckCanTargetNoTarget(final CSimulation game, final CUnit unit, final int orderId, - final AbilityTargetCheckReceiver receiver) { - receiver.targetOk(null); - } - - @Override - protected void innerCheckCanUse(final CSimulation game, final CUnit unit, final int orderId, - final AbilityActivationReceiver receiver) { - final CPlayer player = game.getPlayer(unit.getPlayerIndex()); - if (player.getGold() >= this.goldCost) { - if (player.getLumber() >= this.lumberCost) { - receiver.useOk(); - } - else { - receiver.notEnoughResources(ResourceType.LUMBER); - } - } - else { - receiver.notEnoughResources(ResourceType.GOLD); - } - } - - public float getCastRange() { - return this.castRange; - } - - public float getArea() { - return this.area; - } - - public EnumSet getTargetsAllowed() { - return this.targetsAllowed; - } - - public War3ID getResultingUnitType() { - return this.resultingUnitType; - } - - public int getGoldCost() { - return this.goldCost; - } - - public int getLumberCost() { - return this.lumberCost; - } - - private final class PossiblePairFinderEnum implements CUnitEnumFunction { - private final CUnit unit; - private CUnit pairMatchFound = null; - private CAbilityCoupleInstant pairMatchAbility; - - private PossiblePairFinderEnum(final CUnit unit) { - this.unit = unit; - } - - @Override - public boolean call(final CUnit otherUnit) { - if (otherUnit.getPlayerIndex() == this.unit.getPlayerIndex()) { - for (final CAbility ability : otherUnit.getAbilities()) { - if (ability instanceof CAbilityCoupleInstant) { - final CAbilityCoupleInstant otherCoupleInstant = (CAbilityCoupleInstant) ability; - if (otherCoupleInstant.partnerUnitType.equals(this.unit.getTypeId())) { - if (CAbilityCoupleInstant.this.partnerUnitType.equals(otherUnit.getTypeId())) { - // we're a pair, make sure other unit is not already actively pairing - if (!(otherUnit.getCurrentBehavior() instanceof CBehaviorCoupleInstant)) { - if (otherUnit.distance(this.unit) <= CAbilityCoupleInstant.this.area) { - this.pairMatchFound = otherUnit; - this.pairMatchAbility = otherCoupleInstant; - break; - } - } - } - } - } - } - } - return this.pairMatchFound != null; - } - } - - @Override - public int getUIGoldCost() { - return this.goldCost; - } - - @Override - public int getUILumberCost() { - return this.lumberCost; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/CAbilityType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/CAbilityType.java deleted file mode 100644 index 5c8725b1..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/CAbilityType.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types; - -import java.util.EnumSet; -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public abstract class CAbilityType { - /* alias: defines which ability editor ability to use */ - private final War3ID alias; - /* code: defines which CAbility class to use */ - private final War3ID code; - - private final List levelData; - - public CAbilityType(final War3ID alias, final War3ID code, final List levelData) { - this.alias = alias; - this.code = code; - this.levelData = levelData; - } - - public War3ID getAlias() { - return this.alias; - } - - public War3ID getCode() { - return this.code; - } - - public EnumSet getTargetsAllowed(final int level) { - return getLevelData(level).getTargetsAllowed(); - } - - protected final TYPE_LEVEL_DATA getLevelData(final int level) { - return this.levelData.get(level); - } - - public abstract CAbility createAbility(int handleId); - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/CAbilityTypeLevelData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/CAbilityTypeLevelData.java deleted file mode 100644 index d0234523..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/CAbilityTypeLevelData.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeLevelData { - private final EnumSet targetsAllowed; - - public CAbilityTypeLevelData(final EnumSet targetsAllowed) { - this.targetsAllowed = targetsAllowed; - } - - public EnumSet getTargetsAllowed() { - return this.targetsAllowed; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/CAbilityTypeDefinition.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/CAbilityTypeDefinition.java deleted file mode 100644 index 361e2440..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/CAbilityTypeDefinition.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions; - -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; - -public interface CAbilityTypeDefinition { - CAbilityType createAbilityType(War3ID rawcode, MutableGameObject abilityEditorData); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/AbstractCAbilityTypeDefinition.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/AbstractCAbilityTypeDefinition.java deleted file mode 100644 index c5d893d6..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/AbstractCAbilityTypeDefinition.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl; - -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; - -public abstract class AbstractCAbilityTypeDefinition - implements CAbilityTypeDefinition { - protected static final War3ID TARGETS_ALLOWED = War3ID.fromString("atar"); - private static final War3ID LEVELS = War3ID.fromString("alev"); - protected static final War3ID CAST_RANGE = War3ID.fromString("aran"); - protected static final War3ID DURATION = War3ID.fromString("adur"); - protected static final War3ID AREA = War3ID.fromString("aare"); - - @Override - public CAbilityType createAbilityType(final War3ID alias, final MutableGameObject abilityEditorData) { - final int levels = abilityEditorData.getFieldAsInteger(LEVELS, 0); - final List levelData = new ArrayList<>(); - for (int level = 1; level <= levels; level++) { - levelData.add(createLevelData(abilityEditorData, level)); - } - return innerCreateAbilityType(alias, abilityEditorData, levelData); - } - - protected abstract TYPE_LEVEL_DATA createLevelData(MutableGameObject abilityEditorData, int level); - - protected abstract CAbilityType innerCreateAbilityType(War3ID alias, MutableGameObject abilityEditorData, - List levelData); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionChannelTest.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionChannelTest.java deleted file mode 100644 index 6d4808af..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionChannelTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl; - -import java.util.EnumSet; -import java.util.List; - -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeChannelTest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeChannelTestLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeDefinitionChannelTest extends AbstractCAbilityTypeDefinition - implements CAbilityTypeDefinition { - protected static final War3ID ART_DURATION = War3ID.fromString("Ncl4"); - - @Override - protected CAbilityTypeChannelTestLevelData createLevelData(final MutableGameObject abilityEditorData, - final int level) { - final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level); - final float artDuration = abilityEditorData.getFieldAsFloat(ART_DURATION, level); - final EnumSet targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString); - return new CAbilityTypeChannelTestLevelData(targetsAllowedAtLevel, artDuration); - } - - @Override - protected CAbilityType innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData, - final List levelData) { - return new CAbilityTypeChannelTest(alias, abilityEditorData.getCode(), levelData); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionColdArrows.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionColdArrows.java deleted file mode 100644 index 55a6557e..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionColdArrows.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl; - -import java.util.List; - -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeColdArrows; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeColdArrowsLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeDefinitionColdArrows extends AbstractCAbilityTypeDefinition { - - @Override - protected CAbilityTypeColdArrowsLevelData createLevelData(final MutableGameObject abilityEditorData, - final int level) { - return new CAbilityTypeColdArrowsLevelData( - CTargetType.parseTargetTypeSet(abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level))); - } - - @Override - protected CAbilityType innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData, - final List levelData) { - return new CAbilityTypeColdArrows(alias, abilityEditorData.getCode(), levelData); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionCoupleInstant.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionCoupleInstant.java deleted file mode 100644 index da16f23f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionCoupleInstant.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl; - -import java.util.EnumSet; -import java.util.List; - -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeCoupleInstant; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeCoupleInstantLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeDefinitionCoupleInstant - extends AbstractCAbilityTypeDefinition implements CAbilityTypeDefinition { - protected static final War3ID RESULTING_UNIT_TYPE = War3ID.fromString("coau"); - protected static final War3ID PARTNER_UNIT_TYPE = War3ID.fromString("coa1"); - protected static final War3ID MOVE_TO_PARTNER = War3ID.fromString("coa2"); - protected static final War3ID GOLD_COST = War3ID.fromString("coa3"); - protected static final War3ID LUMBER_COST = War3ID.fromString("coa4"); - - @Override - protected CAbilityTypeCoupleInstantLevelData createLevelData(final MutableGameObject abilityEditorData, - final int level) { - final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level); - final War3ID resultingUnitTypeId = War3ID - .fromString(abilityEditorData.getFieldAsString(RESULTING_UNIT_TYPE, level)); - final War3ID partnerUnitTypeId = War3ID - .fromString(abilityEditorData.getFieldAsString(PARTNER_UNIT_TYPE, level)); - final boolean moveToPartner = abilityEditorData.getFieldAsBoolean(MOVE_TO_PARTNER, level); - final float castRange = abilityEditorData.getFieldAsFloat(CAST_RANGE, level); - final float area = abilityEditorData.getFieldAsFloat(AREA, level); - -// final int goldCost = abilityEditorData.getFieldAsInteger(GOLD_COST, level); -// final int lumberCost = abilityEditorData.getFieldAsInteger(LUMBER_COST, level); - - final EnumSet targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString); - return new CAbilityTypeCoupleInstantLevelData(targetsAllowedAtLevel, resultingUnitTypeId, partnerUnitTypeId, - moveToPartner, castRange, area, 0, 0); - } - - @Override - protected CAbilityType innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData, - final List levelData) { - return new CAbilityTypeCoupleInstant(alias, abilityEditorData.getCode(), levelData); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionGoldMine.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionGoldMine.java deleted file mode 100644 index 0b86b098..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionGoldMine.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl; - -import java.util.EnumSet; -import java.util.List; - -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeGoldMine; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeGoldMineLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeDefinitionGoldMine extends AbstractCAbilityTypeDefinition - implements CAbilityTypeDefinition { - protected static final War3ID MAX_GOLD = War3ID.fromString("Gld1"); - protected static final War3ID MINING_DURATION = War3ID.fromString("Gld2"); - protected static final War3ID MINING_CAPACITY = War3ID.fromString("Gld3"); - - @Override - protected CAbilityTypeGoldMineLevelData createLevelData(final MutableGameObject abilityEditorData, - final int level) { - final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level); - final EnumSet targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString); - final int maxGold = abilityEditorData.getFieldAsInteger(MAX_GOLD, level); - final float miningDuration = abilityEditorData.getFieldAsFloat(MINING_DURATION, level); - final int miningCapacity = abilityEditorData.getFieldAsInteger(MINING_CAPACITY, level); - return new CAbilityTypeGoldMineLevelData(targetsAllowedAtLevel, maxGold, miningDuration, miningCapacity); - } - - @Override - protected CAbilityType innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData, - final List levelData) { - return new CAbilityTypeGoldMine(alias, abilityEditorData.getCode(), levelData); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvest.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvest.java deleted file mode 100644 index 2efca49d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvest.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl; - -import java.util.EnumSet; -import java.util.List; - -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeHarvest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeHarvestLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeDefinitionHarvest extends AbstractCAbilityTypeDefinition - implements CAbilityTypeDefinition { - protected static final War3ID DAMAGE_TO_TREE = War3ID.fromString("Har1"); - protected static final War3ID LUMBER_CAPACITY = War3ID.fromString("Har2"); - protected static final War3ID GOLD_CAPACITY = War3ID.fromString("Har3"); - - @Override - protected CAbilityTypeHarvestLevelData createLevelData(final MutableGameObject abilityEditorData, final int level) { - final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level); - final EnumSet targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString); - final int damageToTree = abilityEditorData.getFieldAsInteger(DAMAGE_TO_TREE, level); - final int goldCapacity = abilityEditorData.getFieldAsInteger(GOLD_CAPACITY, level); - final int lumberCapacity = abilityEditorData.getFieldAsInteger(LUMBER_CAPACITY, level); - final float castRange = abilityEditorData.getFieldAsFloat(CAST_RANGE, level); - final float duration = abilityEditorData.getFieldAsFloat(DURATION, level); - return new CAbilityTypeHarvestLevelData(targetsAllowedAtLevel, damageToTree, goldCapacity, lumberCapacity, - castRange, duration); - } - - @Override - protected CAbilityType innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData, - final List levelData) { - return new CAbilityTypeHarvest(alias, abilityEditorData.getCode(), levelData); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvestLumber.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvestLumber.java deleted file mode 100644 index b89f69b9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHarvestLumber.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl; - -import java.util.EnumSet; -import java.util.List; - -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeHarvestLumber; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeHarvestLumberLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeDefinitionHarvestLumber - extends AbstractCAbilityTypeDefinition implements CAbilityTypeDefinition { - protected static final War3ID DAMAGE_TO_TREE = War3ID.fromString("Har1"); - protected static final War3ID LUMBER_CAPACITY = War3ID.fromString("Har2"); - - @Override - protected CAbilityTypeHarvestLumberLevelData createLevelData(final MutableGameObject abilityEditorData, - final int level) { - final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level); - final EnumSet targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString); - final int damageToTree = abilityEditorData.getFieldAsInteger(DAMAGE_TO_TREE, level); - final int lumberCapacity = abilityEditorData.getFieldAsInteger(LUMBER_CAPACITY, level); - final float castRange = abilityEditorData.getFieldAsFloat(CAST_RANGE, level); - final float duration = abilityEditorData.getFieldAsFloat(DURATION, level); - return new CAbilityTypeHarvestLumberLevelData(targetsAllowedAtLevel, damageToTree, lumberCapacity, castRange, - duration); - } - - @Override - protected CAbilityType innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData, - final List levelData) { - return new CAbilityTypeHarvestLumber(alias, abilityEditorData.getCode(), levelData); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHumanRepair.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHumanRepair.java deleted file mode 100644 index 758d6ad0..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionHumanRepair.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl; - -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeHumanRepair; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeHumanRepairLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -import java.util.EnumSet; -import java.util.List; - -public class CAbilityTypeDefinitionHumanRepair extends AbstractCAbilityTypeDefinition - implements CAbilityTypeDefinition { - protected static final War3ID COST_RATIO = War3ID.fromString("Rep1"); - protected static final War3ID TIME_RATIO = War3ID.fromString("Rep2"); - protected static final War3ID NAVAL_RANGE_BONUS = War3ID.fromString("Rep5"); - - @Override - protected CAbilityTypeHumanRepairLevelData createLevelData(final MutableGameObject abilityEditorData, final int level) { - final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level); - final EnumSet targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString); - final float costRatio = abilityEditorData.getFieldAsFloat(COST_RATIO, level); - final float timeRatio = abilityEditorData.getFieldAsFloat(TIME_RATIO, level); - final float navalRangeBonus = abilityEditorData.getFieldAsFloat(NAVAL_RANGE_BONUS, level); - final float castRange = abilityEditorData.getFieldAsFloat(CAST_RANGE, level); - return new CAbilityTypeHumanRepairLevelData(targetsAllowedAtLevel, navalRangeBonus, costRatio, timeRatio, castRange); - } - - @Override - protected CAbilityType innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData, - final List levelData) { - return new CAbilityTypeHumanRepair(alias, abilityEditorData.getCode(), levelData); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionInventory.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionInventory.java deleted file mode 100644 index 89d387bf..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionInventory.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl; - -import java.util.EnumSet; -import java.util.List; - -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeInventory; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeInventoryLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeDefinitionInventory extends AbstractCAbilityTypeDefinition - implements CAbilityTypeDefinition { - protected static final War3ID ITEM_CAPACITY = War3ID.fromString("inv1"); - protected static final War3ID DROP_ITEMS_ON_DEATH = War3ID.fromString("inv2"); - protected static final War3ID CAN_USE_ITEMS = War3ID.fromString("inv3"); - protected static final War3ID CAN_GET_ITEMS = War3ID.fromString("inv4"); - protected static final War3ID CAN_DROP_ITEMS = War3ID.fromString("inv5"); - - @Override - protected CAbilityTypeInventoryLevelData createLevelData(final MutableGameObject abilityEditorData, - final int level) { - final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level); - final EnumSet targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString); - final int itemCapacity = abilityEditorData.getFieldAsInteger(ITEM_CAPACITY, level); - final boolean dropItemsOnDeath = abilityEditorData.getFieldAsBoolean(DROP_ITEMS_ON_DEATH, level); - final boolean canUseItems = abilityEditorData.getFieldAsBoolean(CAN_USE_ITEMS, level); - final boolean canGetItems = abilityEditorData.getFieldAsBoolean(CAN_GET_ITEMS, level); - final boolean canDropItems = abilityEditorData.getFieldAsBoolean(CAN_DROP_ITEMS, level); - return new CAbilityTypeInventoryLevelData(targetsAllowedAtLevel, canDropItems, canGetItems, canUseItems, - dropItemsOnDeath, itemCapacity); - } - - @Override - protected CAbilityType innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData, - final List levelData) { - return new CAbilityTypeInventory(alias, abilityEditorData.getCode(), levelData); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionInvulnerable.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionInvulnerable.java deleted file mode 100644 index 2bbf7465..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionInvulnerable.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl; - -import java.util.EnumSet; -import java.util.List; - -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeInvulnerable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeDefinitionInvulnerable extends AbstractCAbilityTypeDefinition - implements CAbilityTypeDefinition { - - @Override - protected CAbilityTypeLevelData createLevelData(final MutableGameObject abilityEditorData, final int level) { - final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level); - final EnumSet targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString); - return new CAbilityTypeLevelData(targetsAllowedAtLevel); - } - - @Override - protected CAbilityType innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData, - final List levelData) { - return new CAbilityTypeInvulnerable(alias, abilityEditorData.getCode(), levelData); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionItemAttackBonus.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionItemAttackBonus.java deleted file mode 100644 index 8881ffa9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionItemAttackBonus.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl; - -import java.util.EnumSet; -import java.util.List; - -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeItemAttackBonus; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeItemAttackBonusLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeDefinitionItemAttackBonus - extends AbstractCAbilityTypeDefinition implements CAbilityTypeDefinition { - protected static final War3ID ATTACK_BONUS = War3ID.fromString("Iatt"); - - @Override - protected CAbilityTypeItemAttackBonusLevelData createLevelData(final MutableGameObject abilityEditorData, - final int level) { - final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level); - final int attackBonus = abilityEditorData.getFieldAsInteger(ATTACK_BONUS, level); - final EnumSet targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString); - return new CAbilityTypeItemAttackBonusLevelData(targetsAllowedAtLevel, attackBonus); - } - - @Override - protected CAbilityType innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData, - final List levelData) { - return new CAbilityTypeItemAttackBonus(alias, abilityEditorData.getCode(), levelData); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionItemHeal.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionItemHeal.java deleted file mode 100644 index a7bd3984..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionItemHeal.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl; - -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeChannelTest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeItemHeal; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeItemHealLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -import java.util.EnumSet; -import java.util.List; - -public class CAbilityTypeDefinitionItemHeal extends AbstractCAbilityTypeDefinition - implements CAbilityTypeDefinition { - protected static final War3ID HIT_POINTS_GAINED = War3ID.fromString("Ihpg"); - - @Override - protected CAbilityTypeItemHealLevelData createLevelData(final MutableGameObject abilityEditorData, - final int level) { - final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level); - final int hitPointsGained = abilityEditorData.getFieldAsInteger(HIT_POINTS_GAINED, level); - final EnumSet targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString); - return new CAbilityTypeItemHealLevelData(targetsAllowedAtLevel, hitPointsGained); - } - - @Override - protected CAbilityType innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData, - final List levelData) { - return new CAbilityTypeItemHeal(alias, abilityEditorData.getCode(), levelData); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionReturnResources.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionReturnResources.java deleted file mode 100644 index 07c11787..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/definitions/impl/CAbilityTypeDefinitionReturnResources.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl; - -import java.util.EnumSet; -import java.util.List; - -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeReturnResources; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl.CAbilityTypeReturnResourcesLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeDefinitionReturnResources - extends AbstractCAbilityTypeDefinition implements CAbilityTypeDefinition { - protected static final War3ID ACCEPTS_GOLD = War3ID.fromString("Rtn1"); - protected static final War3ID ACCEPTS_LUMBER = War3ID.fromString("Rtn2"); - - @Override - protected CAbilityTypeReturnResourcesLevelData createLevelData(final MutableGameObject abilityEditorData, - final int level) { - final String targetsAllowedAtLevelString = abilityEditorData.getFieldAsString(TARGETS_ALLOWED, level); - final EnumSet targetsAllowedAtLevel = CTargetType.parseTargetTypeSet(targetsAllowedAtLevelString); - final boolean acceptsGold = abilityEditorData.getFieldAsBoolean(ACCEPTS_GOLD, level); - final boolean acceptsLumber = abilityEditorData.getFieldAsBoolean(ACCEPTS_LUMBER, level); - return new CAbilityTypeReturnResourcesLevelData(targetsAllowedAtLevel, acceptsGold, acceptsLumber); - } - - @Override - protected CAbilityType innerCreateAbilityType(final War3ID alias, final MutableGameObject abilityEditorData, - final List levelData) { - return new CAbilityTypeReturnResources(alias, abilityEditorData.getCode(), levelData); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeChannelTest.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeChannelTest.java deleted file mode 100644 index 3359527c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeChannelTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.test.CAbilityChannelTest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; - -public class CAbilityTypeChannelTest extends CAbilityType { - - public CAbilityTypeChannelTest(final War3ID alias, final War3ID code, - final List levelData) { - super(alias, code, levelData); - } - - @Override - public CAbility createAbility(final int handleId) { - final CAbilityTypeChannelTestLevelData levelData = getLevelData(0); - return new CAbilityChannelTest(handleId, getAlias(), levelData.getArtDuration()); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeChannelTestLevelData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeChannelTestLevelData.java deleted file mode 100644 index 0c300974..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeChannelTestLevelData.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeChannelTestLevelData extends CAbilityTypeLevelData { - private final float artDuration; - - public CAbilityTypeChannelTestLevelData(final EnumSet targetsAllowed, final float artDuration) { - super(targetsAllowed); - this.artDuration = artDuration; - } - - public float getArtDuration() { - return this.artDuration; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeColdArrows.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeColdArrows.java deleted file mode 100644 index 5e86f3bf..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeColdArrows.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityColdArrows; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; - -public class CAbilityTypeColdArrows extends CAbilityType { - - public CAbilityTypeColdArrows(final War3ID alias, final War3ID code, - final List levelData) { - super(alias, code, levelData); - } - - @Override - public CAbility createAbility(final int handleId) { - return new CAbilityColdArrows(getAlias(), handleId); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeColdArrowsLevelData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeColdArrowsLevelData.java deleted file mode 100644 index 7b16958f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeColdArrowsLevelData.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeColdArrowsLevelData extends CAbilityTypeLevelData { - - public CAbilityTypeColdArrowsLevelData(final EnumSet targetsAllowed) { - super(targetsAllowed); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeCoupleInstant.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeCoupleInstant.java deleted file mode 100644 index b3a50164..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeCoupleInstant.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.test.CAbilityCoupleInstant; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; - -public class CAbilityTypeCoupleInstant extends CAbilityType { - - public CAbilityTypeCoupleInstant(final War3ID alias, final War3ID code, - final List levelData) { - super(alias, code, levelData); - } - - @Override - public CAbility createAbility(final int handleId) { - final CAbilityTypeCoupleInstantLevelData levelData = getLevelData(0); - return new CAbilityCoupleInstant(handleId, getAlias(), levelData.getResultingUnitTypeId(), - levelData.getPartnerUnitTypeId(), levelData.isMoveToPartner(), levelData.getCastRange(), - levelData.getArea(), levelData.getTargetsAllowed(), levelData.getGoldCost(), levelData.getLumberCost()); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeCoupleInstantLevelData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeCoupleInstantLevelData.java deleted file mode 100644 index 3e7e7468..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeCoupleInstantLevelData.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.EnumSet; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeCoupleInstantLevelData extends CAbilityTypeLevelData { - private final War3ID resultingUnitTypeId; - private final War3ID partnerUnitTypeId; - private final boolean moveToPartner; - private final float castRange; - private final float area; - private final int goldCost; - private final int lumberCost; - - public CAbilityTypeCoupleInstantLevelData(final EnumSet targetsAllowed, - final War3ID resultingUnitTypeId, final War3ID partnerUnitTypeId, final boolean moveToPartner, - final float castRange, final float area, final int goldCost, final int lumberCost) { - super(targetsAllowed); - this.resultingUnitTypeId = resultingUnitTypeId; - this.partnerUnitTypeId = partnerUnitTypeId; - this.moveToPartner = moveToPartner; - this.castRange = castRange; - this.area = area; - this.goldCost = goldCost; - this.lumberCost = lumberCost; - } - - public War3ID getResultingUnitTypeId() { - return this.resultingUnitTypeId; - } - - public War3ID getPartnerUnitTypeId() { - return this.partnerUnitTypeId; - } - - public boolean isMoveToPartner() { - return this.moveToPartner; - } - - public float getCastRange() { - return this.castRange; - } - - public float getArea() { - return this.area; - } - - public int getGoldCost() { - return this.goldCost; - } - - public int getLumberCost() { - return this.lumberCost; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeGoldMine.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeGoldMine.java deleted file mode 100644 index bd0f428f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeGoldMine.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.mine.CAbilityGoldMine; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; - -public class CAbilityTypeGoldMine extends CAbilityType { - - public CAbilityTypeGoldMine(final War3ID alias, final War3ID code, - final List levelData) { - super(alias, code, levelData); - } - - @Override - public CAbility createAbility(final int handleId) { - final CAbilityTypeGoldMineLevelData levelData = getLevelData(0); - return new CAbilityGoldMine(handleId, getAlias(), levelData.getMaxGold(), levelData.getMiningDuration(), - levelData.getMiningCapacity()); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeGoldMineLevelData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeGoldMineLevelData.java deleted file mode 100644 index 522fd620..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeGoldMineLevelData.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeGoldMineLevelData extends CAbilityTypeLevelData { - private final int maxGold; - private final float miningDuration; - private final int miningCapacity; - - public CAbilityTypeGoldMineLevelData(final EnumSet targetsAllowed, final int maxGold, - final float miningDuration, final int miningCapacity) { - super(targetsAllowed); - this.maxGold = maxGold; - this.miningDuration = miningDuration; - this.miningCapacity = miningCapacity; - } - - public int getMaxGold() { - return this.maxGold; - } - - public float getMiningDuration() { - return this.miningDuration; - } - - public int getMiningCapacity() { - return this.miningCapacity; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvest.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvest.java deleted file mode 100644 index 1e8ec15f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvest.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityHarvest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; - -public class CAbilityTypeHarvest extends CAbilityType { - - public CAbilityTypeHarvest(final War3ID alias, final War3ID code, - final List levelData) { - super(alias, code, levelData); - } - - @Override - public CAbility createAbility(final int handleId) { - final CAbilityTypeHarvestLevelData levelData = getLevelData(0); - return new CAbilityHarvest(handleId, getAlias(), levelData.getDamageToTree(), levelData.getGoldCapacity(), - levelData.getLumberCapacity(), levelData.getCastRange(), levelData.getDuration()); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLevelData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLevelData.java deleted file mode 100644 index 46854de8..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLevelData.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeHarvestLevelData extends CAbilityTypeLevelData { - private final int damageToTree; - private final int goldCapacity; - private final int lumberCapacity; - private final float castRange; - private final float duration; - - public CAbilityTypeHarvestLevelData(final EnumSet targetsAllowed, final int damageToTree, - final int goldCapacity, final int lumberCapacity, final float castRange, final float duration) { - super(targetsAllowed); - this.damageToTree = damageToTree; - this.goldCapacity = goldCapacity; - this.lumberCapacity = lumberCapacity; - this.castRange = castRange; - this.duration = duration; - } - - public int getDamageToTree() { - return this.damageToTree; - } - - public int getGoldCapacity() { - return this.goldCapacity; - } - - public int getLumberCapacity() { - return this.lumberCapacity; - } - - public float getCastRange() { - return this.castRange; - } - - public float getDuration() { - return this.duration; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumber.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumber.java deleted file mode 100644 index b433318a..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumber.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityHarvest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; - -public class CAbilityTypeHarvestLumber extends CAbilityType { - - public CAbilityTypeHarvestLumber(final War3ID alias, final War3ID code, - final List levelData) { - super(alias, code, levelData); - } - - @Override - public CAbility createAbility(final int handleId) { - final CAbilityTypeHarvestLumberLevelData levelData = getLevelData(0); - return new CAbilityHarvest(handleId, getAlias(), levelData.getDamageToTree(), 0, levelData.getLumberCapacity(), - levelData.getCastRange(), levelData.getDuration()); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumberLevelData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumberLevelData.java deleted file mode 100644 index acdad7b6..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHarvestLumberLevelData.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeHarvestLumberLevelData extends CAbilityTypeLevelData { - private final int damageToTree; - private final int lumberCapacity; - private final float castRange; - private final float duration; - - public CAbilityTypeHarvestLumberLevelData(final EnumSet targetsAllowed, final int damageToTree, - final int lumberCapacity, final float castRange, final float duration) { - super(targetsAllowed); - this.damageToTree = damageToTree; - this.lumberCapacity = lumberCapacity; - this.castRange = castRange; - this.duration = duration; - } - - public int getDamageToTree() { - return this.damageToTree; - } - - public int getLumberCapacity() { - return this.lumberCapacity; - } - - public float getCastRange() { - return this.castRange; - } - - public float getDuration() { - return this.duration; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHumanRepair.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHumanRepair.java deleted file mode 100644 index e1c76922..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHumanRepair.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanRepair; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; - -import java.util.List; - -public class CAbilityTypeHumanRepair extends CAbilityType { - - public CAbilityTypeHumanRepair(final War3ID alias, final War3ID code, - final List levelData) { - super(alias, code, levelData); - } - - @Override - public CAbility createAbility(final int handleId) { - final CAbilityTypeHumanRepairLevelData levelData = getLevelData(0); - return new CAbilityHumanRepair(handleId, getAlias(), levelData.getTargetsAllowed(), - levelData.getNavalRangeBonus(), levelData.getRepairCostRatio(), levelData.getRepairTimeRatio(), - levelData.getCastRange()); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHumanRepairLevelData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHumanRepairLevelData.java deleted file mode 100644 index 834bf879..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeHumanRepairLevelData.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -import java.util.EnumSet; - -public class CAbilityTypeHumanRepairLevelData extends CAbilityTypeLevelData { - - private final float navalRangeBonus; - private final float repairCostRatio; - private final float repairTimeRatio; - private final float castRange; - - public CAbilityTypeHumanRepairLevelData(EnumSet targetsAllowed, float navalRangeBonus, float repairCostRatio, float repairTimeRatio, float castRange) { - super(targetsAllowed); - this.navalRangeBonus = navalRangeBonus; - this.repairCostRatio = repairCostRatio; - this.repairTimeRatio = repairTimeRatio; - this.castRange = castRange; - } - - public float getCastRange() { - return this.castRange; - } - - public float getNavalRangeBonus() { - return navalRangeBonus; - } - - public float getRepairCostRatio() { - return repairCostRatio; - } - - public float getRepairTimeRatio() { - return repairTimeRatio; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeInventory.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeInventory.java deleted file mode 100644 index 66b06f21..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeInventory.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.inventory.CAbilityInventory; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; - -public class CAbilityTypeInventory extends CAbilityType { - - public CAbilityTypeInventory(final War3ID alias, final War3ID code, - final List levelData) { - super(alias, code, levelData); - } - - @Override - public CAbility createAbility(final int handleId) { - final CAbilityTypeInventoryLevelData levelData = getLevelData(0); - return new CAbilityInventory(handleId, getAlias(), levelData.isCanDropItems(), levelData.isCanGetItems(), - levelData.isCanUseItems(), levelData.isDropItemsOnDeath(), levelData.getItemCapacity()); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeInventoryLevelData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeInventoryLevelData.java deleted file mode 100644 index 518b95f4..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeInventoryLevelData.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeInventoryLevelData extends CAbilityTypeLevelData { - - private final boolean canDropItems; - private final boolean canGetItems; - private final boolean canUseItems; - private final boolean dropItemsOnDeath; - private final int itemCapacity; - - public CAbilityTypeInventoryLevelData(final EnumSet targetsAllowed, final boolean canDropItems, - final boolean canGetItems, final boolean canUseItems, final boolean dropItemsOnDeath, - final int itemCapacity) { - super(targetsAllowed); - this.canDropItems = canDropItems; - this.canGetItems = canGetItems; - this.canUseItems = canUseItems; - this.dropItemsOnDeath = dropItemsOnDeath; - this.itemCapacity = itemCapacity; - } - - public boolean isCanDropItems() { - return this.canDropItems; - } - - public boolean isCanGetItems() { - return this.canGetItems; - } - - public boolean isCanUseItems() { - return this.canUseItems; - } - - public boolean isDropItemsOnDeath() { - return this.dropItemsOnDeath; - } - - public int getItemCapacity() { - return this.itemCapacity; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeInvulnerable.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeInvulnerable.java deleted file mode 100644 index b6cbdb83..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeInvulnerable.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityInvulnerable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; - -public class CAbilityTypeInvulnerable extends CAbilityType { - - public CAbilityTypeInvulnerable(final War3ID alias, final War3ID code, - final List levelData) { - super(alias, code, levelData); - } - - @Override - public CAbility createAbility(final int handleId) { - final CAbilityTypeLevelData levelData = getLevelData(0); - return new CAbilityInvulnerable(handleId, getAlias()); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemAttackBonus.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemAttackBonus.java deleted file mode 100644 index fe4bf99a..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemAttackBonus.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.item.CAbilityItemAttackBonus; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; - -public class CAbilityTypeItemAttackBonus extends CAbilityType { - - public CAbilityTypeItemAttackBonus(final War3ID alias, final War3ID code, - final List levelData) { - super(alias, code, levelData); - } - - @Override - public CAbility createAbility(final int handleId) { - final CAbilityTypeItemAttackBonusLevelData levelData = getLevelData(0); - return new CAbilityItemAttackBonus(handleId, getAlias(), levelData.getDamageBonus()); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemAttackBonusLevelData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemAttackBonusLevelData.java deleted file mode 100644 index e2331adc..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemAttackBonusLevelData.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeItemAttackBonusLevelData extends CAbilityTypeLevelData { - private final int damageBonus; - - public CAbilityTypeItemAttackBonusLevelData(final EnumSet targetsAllowed, final int damageBonus) { - super(targetsAllowed); - this.damageBonus = damageBonus; - } - - public int getDamageBonus() { - return this.damageBonus; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemHeal.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemHeal.java deleted file mode 100644 index ec0ac83a..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemHeal.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.item.CAbilityItemHeal; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.test.CAbilityChannelTest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; - -import java.util.List; - -public class CAbilityTypeItemHeal extends CAbilityType { - - public CAbilityTypeItemHeal(final War3ID alias, final War3ID code, - final List levelData) { - super(alias, code, levelData); - } - - @Override - public CAbility createAbility(final int handleId) { - final CAbilityTypeItemHealLevelData levelData = getLevelData(0); - return new CAbilityItemHeal(handleId, getAlias(), levelData.getLifeToRegain()); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemHealLevelData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemHealLevelData.java deleted file mode 100644 index ad205b78..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeItemHealLevelData.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -import java.util.EnumSet; - -public class CAbilityTypeItemHealLevelData extends CAbilityTypeLevelData { - private final int lifeToRegain; - - public CAbilityTypeItemHealLevelData(final EnumSet targetsAllowed, final int lifeToRegain) { - super(targetsAllowed); - this.lifeToRegain = lifeToRegain; - } - - public int getLifeToRegain() { - return lifeToRegain; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeReturnResources.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeReturnResources.java deleted file mode 100644 index a10ed6d1..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeReturnResources.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.EnumSet; -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityReturnResources; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; - -public class CAbilityTypeReturnResources extends CAbilityType { - - public CAbilityTypeReturnResources(final War3ID alias, final War3ID code, - final List levelData) { - super(alias, code, levelData); - } - - @Override - public CAbility createAbility(final int handleId) { - final CAbilityTypeReturnResourcesLevelData levelData = getLevelData(0); - final EnumSet acceptedResourceTypes = EnumSet.noneOf(ResourceType.class); - if (levelData.isAcceptsGold()) { - acceptedResourceTypes.add(ResourceType.GOLD); - } - if (levelData.isAcceptsLumber()) { - acceptedResourceTypes.add(ResourceType.LUMBER); - } - return new CAbilityReturnResources(handleId, getAlias(), acceptedResourceTypes); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeReturnResourcesLevelData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeReturnResourcesLevelData.java deleted file mode 100644 index 2366f35b..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/types/impl/CAbilityTypeReturnResourcesLevelData.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.impl; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityTypeLevelData; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; - -public class CAbilityTypeReturnResourcesLevelData extends CAbilityTypeLevelData { - - private final boolean acceptsGold; - private final boolean acceptsLumber; - - public CAbilityTypeReturnResourcesLevelData(final EnumSet targetsAllowed, final boolean acceptsGold, - final boolean acceptsLumber) { - super(targetsAllowed); - this.acceptsGold = acceptsGold; - this.acceptsLumber = acceptsLumber; - } - - public boolean isAcceptsGold() { - return this.acceptsGold; - } - - public boolean isAcceptsLumber() { - return this.acceptsLumber; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/upgrade/CAbilityUpgrade.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/upgrade/CAbilityUpgrade.java deleted file mode 100644 index fb529228..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/abilities/upgrade/CAbilityUpgrade.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.upgrade; - -public class CAbilityUpgrade { - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/ai/AIDifficulty.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/ai/AIDifficulty.java deleted file mode 100644 index 681f7100..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/ai/AIDifficulty.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.ai; - -public enum AIDifficulty { - NEWBIE, - NORMAL, - INSANE; - - public static AIDifficulty[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CAbstractRangedBehavior.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CAbstractRangedBehavior.java deleted file mode 100644 index ba079eb5..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CAbstractRangedBehavior.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; - -public abstract class CAbstractRangedBehavior implements CRangedBehavior { - protected final CUnit unit; - - public CAbstractRangedBehavior(final CUnit unit) { - this.unit = unit; - } - - protected AbilityTarget target; - private boolean wasWithinPropWindow = false; - private boolean wasInRange = false; - private boolean disableMove = false; - private CBehaviorMove moveBehavior; - - protected final CAbstractRangedBehavior innerReset(final AbilityTarget target) { - return innerReset(target, false); - } - - protected final CAbstractRangedBehavior innerReset(final AbilityTarget target, final boolean disableCollision) { - this.target = target; - this.wasWithinPropWindow = false; - this.wasInRange = false; - CBehaviorMove moveBehavior; - if (!this.unit.isMovementDisabled()) { - moveBehavior = this.unit.getMoveBehavior().reset(this.target, this, disableCollision); - } - else { - moveBehavior = null; - } - this.moveBehavior = moveBehavior; - return this; - } - - protected abstract CBehavior update(CSimulation simulation, boolean withinFacingWindow); - - protected abstract CBehavior updateOnInvalidTarget(CSimulation simulation); - - protected abstract boolean checkTargetStillValid(CSimulation simulation); - - protected abstract void resetBeforeMoving(CSimulation simulation); - - @Override - public final CBehavior update(final CSimulation simulation) { - if (!checkTargetStillValid(simulation)) { - return updateOnInvalidTarget(simulation); - } - if (!isWithinRange(simulation)) { - if ((this.moveBehavior == null) || this.disableMove) { - return this.unit.pollNextOrderBehavior(simulation); - } - this.wasInRange = false; - resetBeforeMoving(simulation); - return this.unit.getMoveBehavior(); - } - this.wasInRange = true; - if (!this.unit.isMovementDisabled()) { - final float prevX = this.unit.getX(); - final float prevY = this.unit.getY(); - final float deltaX = this.target.getX() - prevX; - final float deltaY = this.target.getY() - prevY; - final double goalAngleRad = Math.atan2(deltaY, deltaX); - float goalAngle = (float) Math.toDegrees(goalAngleRad); - if (goalAngle < 0) { - goalAngle += 360; - } - float facing = this.unit.getFacing(); - float delta = goalAngle - facing; - final float propulsionWindow = simulation.getGameplayConstants().getAttackHalfAngle(); - final float turnRate = simulation.getUnitData().getTurnRate(this.unit.getTypeId()); - - if (delta < -180) { - delta = 360 + delta; - } - if (delta > 180) { - delta = -360 + delta; - } - final float absDelta = Math.abs(delta); - - if ((absDelta <= 1.0) && (absDelta != 0)) { - this.unit.setFacing(goalAngle); - } - else { - float angleToAdd = Math.signum(delta) * (float) Math.toDegrees(turnRate); - if (absDelta < Math.abs(angleToAdd)) { - angleToAdd = delta; - } - facing += angleToAdd; - this.unit.setFacing(facing); - } - if (absDelta < propulsionWindow) { - this.wasWithinPropWindow = true; - } - else { - // If this happens, the unit is facing the wrong way, and has to turn before - // moving. - this.wasWithinPropWindow = false; - } - } - else { - this.wasWithinPropWindow = true; - } - - return update(simulation, this.wasWithinPropWindow); - } - - public void setDisableMove(final boolean disableMove) { - this.disableMove = disableMove; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehavior.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehavior.java deleted file mode 100644 index beb10a07..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehavior.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; - -public interface CBehavior { - /** - * Executes one step of game simulation of the current order, and then returns - * the next behavior for the unit after the result of the update cycle. - * - * @return - */ - CBehavior update(CSimulation game); - - void begin(CSimulation game); - - void end(CSimulation game, boolean interrupted); - - int getHighlightOrderId(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorAttack.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorAttack.java deleted file mode 100644 index a6792156..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorAttack.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors; - -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetStillAliveAndTargetableVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack; - -public class CBehaviorAttack extends CAbstractRangedBehavior { - - private int highlightOrderId; - private final AbilityTargetStillAliveAndTargetableVisitor abilityTargetStillAliveVisitor; - - public CBehaviorAttack(final CUnit unit) { - super(unit); - this.abilityTargetStillAliveVisitor = new AbilityTargetStillAliveAndTargetableVisitor(); - } - - private CUnitAttack unitAttack; - private int damagePointLaunchTime; - private int backSwingTime; - private int thisOrderCooldownEndTime; - private CBehaviorAttackListener attackListener; - - public CBehaviorAttack reset(final int highlightOrderId, final CUnitAttack unitAttack, final AbilityTarget target, - final boolean disableMove, final CBehaviorAttackListener attackListener) { - this.highlightOrderId = highlightOrderId; - this.attackListener = attackListener; - super.innerReset(target); - this.unitAttack = unitAttack; - this.damagePointLaunchTime = 0; - this.backSwingTime = 0; - this.thisOrderCooldownEndTime = 0; - setDisableMove(disableMove); - return this; - } - - @Override - public int getHighlightOrderId() { - return this.highlightOrderId; - } - - @Override - public boolean isWithinRange(final CSimulation simulation) { - float range = this.unitAttack.getRange(); - if (simulation.getGameTurnTick() < this.unit.getCooldownEndTime()) { - range += this.unitAttack.getRangeMotionBuffer(); - } - return this.unit.canReach(this.target, range) - && (this.unit.distance(this.target) >= this.unit.getUnitType().getMinimumAttackRange()); - } - - @Override - protected boolean checkTargetStillValid(final CSimulation simulation) { - return this.target.visit( - this.abilityTargetStillAliveVisitor.reset(simulation, this.unit, this.unitAttack.getTargetsAllowed())); - } - - @Override - protected void resetBeforeMoving(final CSimulation simulation) { - this.damagePointLaunchTime = 0; - this.thisOrderCooldownEndTime = 0; - } - - @Override - protected CBehavior updateOnInvalidTarget(final CSimulation simulation) { - return this.attackListener.onFinish(simulation, this.unit); - } - - @Override - public CBehavior update(final CSimulation simulation, final boolean withinFacingWindow) { - final int cooldownEndTime = this.unit.getCooldownEndTime(); - final int currentTurnTick = simulation.getGameTurnTick(); - if (withinFacingWindow) { - if (this.damagePointLaunchTime != 0) { - if (currentTurnTick >= this.damagePointLaunchTime) { - int minDamage = this.unitAttack.getMinDamage(); - final int maxDamage = Math.max(0, this.unitAttack.getMaxDamage()); - if (minDamage > maxDamage) { - minDamage = maxDamage; - } - final int damage; - if (maxDamage == 0) { - damage = 0; - } - else if (minDamage == maxDamage) { - damage = minDamage; - } - else { - damage = simulation.getSeededRandom().nextInt(maxDamage - minDamage) + minDamage; - } - this.unitAttack.launch(simulation, this.unit, this.target, damage, this.attackListener); - this.damagePointLaunchTime = 0; - } - } - else if (currentTurnTick >= cooldownEndTime) { - final float cooldownTime = this.unitAttack.getCooldownTime(); - final float animationBackswingPoint = this.unitAttack.getAnimationBackswingPoint(); - final int a1CooldownSteps = (int) (cooldownTime / WarsmashConstants.SIMULATION_STEP_TIME); - final int a1BackswingSteps = (int) (animationBackswingPoint / WarsmashConstants.SIMULATION_STEP_TIME); - final int a1DamagePointSteps = (int) (this.unitAttack.getAnimationDamagePoint() - / WarsmashConstants.SIMULATION_STEP_TIME); - this.unit.setCooldownEndTime(currentTurnTick + a1CooldownSteps); - this.thisOrderCooldownEndTime = currentTurnTick + a1CooldownSteps; - this.damagePointLaunchTime = currentTurnTick + a1DamagePointSteps; - this.backSwingTime = currentTurnTick + a1DamagePointSteps + a1BackswingSteps; - this.unit.getUnitAnimationListener().playAnimation(true, PrimaryTag.ATTACK, SequenceUtils.EMPTY, 1.0f, - true); - this.unit.getUnitAnimationListener().queueAnimation(PrimaryTag.STAND, SequenceUtils.READY, false); - } - else if ((currentTurnTick >= this.thisOrderCooldownEndTime)) { - this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.READY, 1.0f, - false); - } - } - else { - this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.READY, 1.0f, - false); - } - - if ((this.backSwingTime != 0) && (currentTurnTick >= this.backSwingTime)) { - this.backSwingTime = 0; - return this.attackListener.onFirstUpdateAfterBackswing(this); - } - return this; - } - - @Override - public void begin(final CSimulation game) { - - } - - @Override - public void end(final CSimulation game, final boolean interrupted) { - } - - @Override - public void endMove(final CSimulation game, final boolean interrupted) { - - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorAttackListener.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorAttackListener.java deleted file mode 100644 index 2c51f47c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorAttackListener.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackListener; - -public interface CBehaviorAttackListener extends CUnitAttackListener { - - // For this function, return the current attack behavior to keep attacking, or - // else return something else to interrupt it - CBehavior onFirstUpdateAfterBackswing(CBehaviorAttack currentAttackBehavior); - - CBehavior onFinish(CSimulation game, final CUnit finishingUnit); - - CBehaviorAttackListener DO_NOTHING = new CBehaviorAttackListener() { - @Override - public void onHit(final AbilityTarget target, final float damage) { - } - - @Override - public void onLaunch() { - } - - @Override - public CBehavior onFirstUpdateAfterBackswing(final CBehaviorAttack currentAttackBehavior) { - return currentAttackBehavior; - } - - @Override - public CBehavior onFinish(final CSimulation game, final CUnit finishingUnit) { - return finishingUnit.pollNextOrderBehavior(game); - } - }; -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorAttackMove.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorAttackMove.java deleted file mode 100644 index fc251e9d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorAttackMove.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; - -public class CBehaviorAttackMove implements CRangedBehavior { - - private final CUnit unit; - private AbilityPointTarget target; - private boolean justAutoAttacked = false; - private boolean endedMove = false; - - public CBehaviorAttackMove(final CUnit unit) { - this.unit = unit; - } - - public CBehavior reset(final AbilityPointTarget target) { - this.target = target; - this.endedMove = false; - return this; - } - - @Override - public int getHighlightOrderId() { - return OrderIds.attack; - } - - @Override - public boolean isWithinRange(final CSimulation simulation) { - if (this.justAutoAttacked = this.unit.autoAcquireAttackTargets(simulation, false)) { - // kind of a hack - return true; - } - return innerIsWithinRange(); // TODO this is not how it was meant to be used - } - - private boolean innerIsWithinRange() { - return this.unit.distance(this.target.x, this.target.y) <= 16f; - } - - @Override - public CBehavior update(final CSimulation simulation) { - if (this.justAutoAttacked) { - this.justAutoAttacked = false; - return this.unit.getCurrentBehavior(); - } - if (innerIsWithinRange()) { - this.unit.setDefaultBehavior(this.unit.getStopBehavior()); - return this.unit.pollNextOrderBehavior(simulation); - } - return this.unit.getMoveBehavior().reset(this.target, this, false); - } - - @Override - public void begin(final CSimulation game) { - - } - - @Override - public void end(final CSimulation game, final boolean interrupted) { - } - - @Override - public void endMove(final CSimulation game, final boolean interrupted) { - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorFollow.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorFollow.java deleted file mode 100644 index 6820bb87..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorFollow.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors; - -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetStillAliveVisitor; - -public class CBehaviorFollow extends CAbstractRangedBehavior { - - private int higlightOrderId; - private boolean justAutoAttacked = false; - - public CBehaviorFollow(final CUnit unit) { - super(unit); - } - - public CBehavior reset(final int higlightOrderId, final CUnit target) { - this.higlightOrderId = higlightOrderId; - return innerReset(target); - } - - @Override - public int getHighlightOrderId() { - return this.higlightOrderId; - } - - @Override - public boolean isWithinRange(final CSimulation simulation) { - if(justAutoAttacked = this.unit.autoAcquireAttackTargets(simulation, false)) { - return true; - } - return this.unit.canReach(this.target, this.unit.getAcquisitionRange()); - } - - @Override - protected CBehavior update(final CSimulation simulation, final boolean withinFacingWindow) { - - this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.EMPTY, 1.0f, false); - return this; - } - - @Override - protected CBehavior updateOnInvalidTarget(final CSimulation simulation) { - unit.setDefaultBehavior(unit.getStopBehavior()); - return this.unit.pollNextOrderBehavior(simulation); - } - - @Override - protected boolean checkTargetStillValid(final CSimulation simulation) { - if (this.justAutoAttacked) { - this.justAutoAttacked = false; - this.unit.getMoveBehavior().reset(target, this, false); - } - return this.target.visit(AbilityTargetStillAliveVisitor.INSTANCE); - } - - @Override - protected void resetBeforeMoving(final CSimulation simulation) { - - } - - @Override - public void begin(final CSimulation game) { - - } - - @Override - public void end(final CSimulation game, final boolean interrupted) { - - } - - @Override - public void endMove(final CSimulation game, final boolean interrupted) { - - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorHoldPosition.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorHoldPosition.java deleted file mode 100644 index 91cbd532..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorHoldPosition.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors; - -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; - -public class CBehaviorHoldPosition implements CBehavior { - - private final CUnit unit; - - public CBehaviorHoldPosition(final CUnit unit) { - this.unit = unit; - } - - @Override - public int getHighlightOrderId() { - return OrderIds.holdposition; - } - - @Override - public CBehavior update(final CSimulation game) { - if (this.unit.autoAcquireAttackTargets(game, true)) { - // kind of a hack - return this.unit.getCurrentBehavior(); - } - this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.EMPTY, 1.0f, true); - return this.unit.pollNextOrderBehavior(game); - } - - @Override - public void begin(final CSimulation game) { - - } - - @Override - public void end(final CSimulation game, boolean interrupted) { - - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorMove.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorMove.java deleted file mode 100644 index f49b4725..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorMove.java +++ /dev/null @@ -1,483 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors; - -import java.awt.geom.Point2D; -import java.awt.geom.Point2D.Float; -import java.util.List; - -import com.badlogic.gdx.math.Rectangle; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.MovementType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWorldCollision; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CPathfindingProcessor; - -public class CBehaviorMove implements CBehavior { - private static boolean ALWAYS_INTERRUPT_MOVE = false; - - private static final Rectangle tempRect = new Rectangle(); - private final CUnit unit; - private int highlightOrderId; - private final TargetVisitingResetter targetVisitingResetter; - - public CBehaviorMove(final CUnit unit) { - this.unit = unit; - this.targetVisitingResetter = new TargetVisitingResetter(); - } - - private boolean wasWithinPropWindow = false; - private List path = null; - private CPathfindingProcessor.GridMapping gridMapping; - private Point2D.Float target; - private int searchCycles = 0; - private CUnit followUnit; - private CRangedBehavior rangedBehavior; - private boolean firstUpdate = true; - private boolean disableCollision = false; - private boolean pathfindingActive = false; - private boolean firstPathfindJob = false; - private boolean pathfindingFailedGiveUp; - private int giveUpUntilTurnTick; - - public CBehaviorMove reset(final int highlightOrderId, final AbilityTarget target) { - target.visit(this.targetVisitingResetter.reset(highlightOrderId)); - this.rangedBehavior = null; - this.disableCollision = false; - return this; - } - - public CBehaviorMove reset(final AbilityTarget target, final CRangedBehavior rangedBehavior, - final boolean disableCollision) { - final int highlightOrderId = rangedBehavior.getHighlightOrderId(); - target.visit(this.targetVisitingResetter.reset(highlightOrderId)); - this.rangedBehavior = rangedBehavior; - this.disableCollision = disableCollision; - return this; - } - - private void internalResetMove(final int highlightOrderId, final float targetX, final float targetY) { - this.highlightOrderId = highlightOrderId; - this.wasWithinPropWindow = false; - this.gridMapping = CPathfindingProcessor.isCollisionSizeBetterSuitedForCorners( - this.unit.getUnitType().getCollisionSize()) ? CPathfindingProcessor.GridMapping.CORNERS - : CPathfindingProcessor.GridMapping.CELLS; - this.target = new Point2D.Float(targetX, targetY); - this.path = null; - this.searchCycles = 0; - this.followUnit = null; - this.firstUpdate = true; - this.pathfindingFailedGiveUp = false; - this.giveUpUntilTurnTick = 0; - } - - private void internalResetMove(final int highlightOrderId, final CUnit followUnit) { - this.highlightOrderId = highlightOrderId; - this.wasWithinPropWindow = false; - this.gridMapping = CPathfindingProcessor.isCollisionSizeBetterSuitedForCorners( - this.unit.getUnitType().getCollisionSize()) ? CPathfindingProcessor.GridMapping.CORNERS - : CPathfindingProcessor.GridMapping.CELLS; - this.target = new Float(followUnit.getX(), followUnit.getY()); - this.path = null; - this.searchCycles = 0; - this.followUnit = followUnit; - this.firstUpdate = true; - this.pathfindingFailedGiveUp = false; - this.giveUpUntilTurnTick = 0; - } - - @Override - public int getHighlightOrderId() { - return this.highlightOrderId; - } - - @Override - public CBehavior update(final CSimulation simulation) { - if ((this.rangedBehavior != null) && this.rangedBehavior.isWithinRange(simulation)) { - return this.rangedBehavior.update(simulation); - } - if (this.firstUpdate) { - // when units start moving, if they're on top of other units, maybe push them to - // the side - this.unit.setPointAndCheckUnstuck(this.unit.getX(), this.unit.getY(), simulation); - this.firstUpdate = false; - } - if (this.pathfindingFailedGiveUp) { - onMoveGiveUp(simulation); - return this.unit.pollNextOrderBehavior(simulation); - } - final float prevX = this.unit.getX(); - final float prevY = this.unit.getY(); - - MovementType movementType = this.unit.getUnitType().getMovementType(); - if (movementType == null) { - movementType = MovementType.DISABLED; - } - else if ((movementType == MovementType.FOOT) && this.disableCollision) { - movementType = MovementType.FOOT_NO_COLLISION; - } - final PathingGrid pathingGrid = simulation.getPathingGrid(); - final CWorldCollision worldCollision = simulation.getWorldCollision(); - final float collisionSize = this.unit.getUnitType().getCollisionSize(); - final float startFloatingX = prevX; - final float startFloatingY = prevY; - if (this.path == null) { - if (!this.pathfindingActive) { - if (this.followUnit != null) { - this.target.x = this.followUnit.getX(); - this.target.y = this.followUnit.getY(); - } - simulation.findNaiveSlowPath(this.unit, this.followUnit, startFloatingX, startFloatingY, this.target, - movementType, collisionSize, true, this); - this.pathfindingActive = true; - this.firstPathfindJob = true; - } - } - else if ((this.followUnit != null) && (this.path.size() > 1) && (this.target.distance(this.followUnit.getX(), - this.followUnit.getY()) > (0.1 * this.target.distance(this.unit.getX(), this.unit.getY())))) { - this.target.x = this.followUnit.getX(); - this.target.y = this.followUnit.getY(); - if (this.pathfindingActive) { - simulation.removeFromPathfindingQueue(this); - } - simulation.findNaiveSlowPath(this.unit, this.followUnit, startFloatingX, startFloatingY, this.target, - movementType, collisionSize, this.searchCycles < 4, this); - this.pathfindingActive = true; - } - float currentTargetX; - float currentTargetY; - if ((this.path == null) || this.path.isEmpty()) { - if (this.followUnit != null) { - currentTargetX = this.followUnit.getX(); - currentTargetY = this.followUnit.getY(); - } - else { - currentTargetX = this.target.x; - currentTargetY = this.target.y; - } - } - else { - if ((this.followUnit != null) && (this.path.size() == 1)) { - currentTargetX = this.followUnit.getX(); - currentTargetY = this.followUnit.getY(); - } - else { - final Point2D.Float nextPathElement = this.path.get(0); - currentTargetX = nextPathElement.x; - currentTargetY = nextPathElement.y; - } - } - - float deltaX = currentTargetX - prevX; - float deltaY = currentTargetY - prevY; - double goalAngleRad = Math.atan2(deltaY, deltaX); - float goalAngle = (float) Math.toDegrees(goalAngleRad); - if (goalAngle < 0) { - goalAngle += 360; - } - float facing = this.unit.getFacing(); - float delta = goalAngle - facing; - final float propulsionWindow = this.unit.getUnitType().getPropWindow(); - final float turnRate = this.unit.getUnitType().getTurnRate(); - final int speed = this.unit.getSpeed(); - - if (delta < -180) { - delta = 360 + delta; - } - if (delta > 180) { - delta = -360 + delta; - } - float absDelta = Math.abs(delta); - - if ((absDelta <= 1.0) && (absDelta != 0)) { - this.unit.setFacing(goalAngle); - } - else { - float angleToAdd = Math.signum(delta) * (float) Math.toDegrees(turnRate); - if (absDelta < Math.abs(angleToAdd)) { - angleToAdd = delta; - } - facing += angleToAdd; - this.unit.setFacing(facing); - } - final boolean blockedByGiveUpUntilTickDelay = simulation.getGameTurnTick() < this.giveUpUntilTurnTick; - if (!blockedByGiveUpUntilTickDelay && (this.path != null) && !this.pathfindingActive - && (absDelta < propulsionWindow)) { - final float speedTick = speed * WarsmashConstants.SIMULATION_STEP_TIME; - double continueDistance = speedTick; - do { - boolean done; - float nextX, nextY; - final double travelDistance = Math.sqrt((deltaX * deltaX) + (deltaY * deltaY)); - if (travelDistance <= continueDistance) { - nextX = currentTargetX; - nextY = currentTargetY; - continueDistance = continueDistance - travelDistance; - done = true; - } - else { - final double radianFacing = Math.toRadians(facing); - nextX = (prevX + (float) (Math.cos(radianFacing) * continueDistance)); - nextY = (prevY + (float) (Math.sin(radianFacing) * continueDistance)); - continueDistance = 0; -// done = (this.gridMapping.getX(pathingGrid, nextX) == this.gridMapping.getX(pathingGrid, -// currentTargetX)) -// && (this.gridMapping.getY(pathingGrid, nextY) == this.gridMapping.getY(pathingGrid, -// currentTargetY)); - done = false; - } - tempRect.set(this.unit.getCollisionRectangle()); - tempRect.setCenter(nextX, nextY); - if ((movementType == null) || (pathingGrid.isPathable(nextX, nextY, movementType, collisionSize)// ((int) - // collisionSize - // / 16) - // * 16 - && !worldCollision.intersectsAnythingOtherThan(tempRect, this.unit, movementType))) { - this.unit.setPoint(nextX, nextY, worldCollision, simulation.getRegionManager()); - if (done) { - // if we're making headway along the path then it's OK to start thinking fast - // again - if (travelDistance > 0) { - this.searchCycles = 0; - } - if (this.path.isEmpty()) { - onMoveGiveUp(simulation); - return this.unit.pollNextOrderBehavior(simulation); - } - else { - System.out.println(this.path); - final Float removed = this.path.remove(0); - System.out.println( - "We think we reached " + removed + " because we are at " + nextX + "," + nextY); - final boolean emptyPath = this.path.isEmpty(); - if (emptyPath) { - if (this.followUnit != null) { - currentTargetX = this.followUnit.getX(); - currentTargetY = this.followUnit.getY(); - } - else { - currentTargetX = this.target.x; - currentTargetY = this.target.y; - } - } - else { - if ((this.followUnit != null) && (this.path.size() == 1)) { - currentTargetX = this.followUnit.getX(); - currentTargetY = this.followUnit.getY(); - } - else { - final Point2D.Float firstPathElement = this.path.get(0); - currentTargetX = firstPathElement.x; - currentTargetY = firstPathElement.y; - } - } - deltaY = currentTargetY - nextY; - deltaX = currentTargetX - nextX; - if ((deltaX == 0.000f) && (deltaY == 0.000f) && this.path.isEmpty()) { - onMoveGiveUp(simulation); - return this.unit.pollNextOrderBehavior(simulation); - } - System.out.println("new target: " + currentTargetX + "," + currentTargetY); - System.out.println("new delta: " + deltaX + "," + deltaY); - goalAngleRad = Math.atan2(deltaY, deltaX); - goalAngle = (float) Math.toDegrees(goalAngleRad); - if (goalAngle < 0) { - goalAngle += 360; - } - facing = this.unit.getFacing(); - delta = goalAngle - facing; - - if (delta < -180) { - delta = 360 + delta; - } - if (delta > 180) { - delta = -360 + delta; - } - absDelta = Math.abs(delta); - if (absDelta >= propulsionWindow) { - if (this.wasWithinPropWindow) { - this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, - SequenceUtils.EMPTY, 1.0f, true); - } - this.wasWithinPropWindow = false; - return this; - } - } - } - } - else { - if (this.followUnit != null) { - this.target.x = this.followUnit.getX(); - this.target.y = this.followUnit.getY(); - } - if (!this.pathfindingActive) { - simulation.findNaiveSlowPath(this.unit, this.followUnit, startFloatingX, startFloatingY, - this.target, movementType, collisionSize, this.searchCycles < 4, this); - this.pathfindingActive = true; - this.searchCycles++; - return this; - } - } - this.unit.getUnitAnimationListener().playWalkAnimation(false, this.unit.getSpeed(), true); - this.wasWithinPropWindow = true; - } - while (continueDistance > 0); - } - else { - // If this happens, the unit is facing the wrong way, and has to turn before - // moving. - if (this.wasWithinPropWindow) { - this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.EMPTY, 1.0f, - true); - } - this.wasWithinPropWindow = false; - } - - return this; - } - - private void onMoveGiveUp(final CSimulation simulation) { - if (this.rangedBehavior != null) { - this.rangedBehavior.endMove(simulation, true); - } - } - - private final class TargetVisitingResetter implements AbilityTargetVisitor { - private int highlightOrderId; - - private TargetVisitingResetter reset(final int highlightOrderId) { - this.highlightOrderId = highlightOrderId; - return this; - } - - @Override - public Void accept(final AbilityPointTarget target) { - internalResetMove(this.highlightOrderId, target.x, target.y); - return null; - } - - @Override - public Void accept(final CUnit target) { - internalResetMove(this.highlightOrderId, target); - return null; - } - - @Override - public Void accept(final CDestructable target) { - internalResetMove(this.highlightOrderId, target.getX(), target.getY()); - return null; - } - - @Override - public Void accept(final CItem target) { - internalResetMove(this.highlightOrderId, target.getX(), target.getY()); - return null; - } - } - - @Override - public void begin(final CSimulation game) { - - } - - @Override - public void end(final CSimulation game, final boolean interrupted) { - if (ALWAYS_INTERRUPT_MOVE) { - game.removeFromPathfindingQueue(this); - this.pathfindingActive = false; - } - if (this.rangedBehavior != null) { - this.rangedBehavior.endMove(game, interrupted); - } - } - - public CUnit getUnit() { - return this.unit; - } - - public void pathFound(final List waypoints, final CSimulation simulation) { - this.pathfindingActive = false; - - final float prevX = this.unit.getX(); - final float prevY = this.unit.getY(); - - MovementType movementType = this.unit.getUnitType().getMovementType(); - if (movementType == null) { - movementType = MovementType.DISABLED; - } - else if ((movementType == MovementType.FOOT) && this.disableCollision) { - movementType = MovementType.FOOT_NO_COLLISION; - } - final PathingGrid pathingGrid = simulation.getPathingGrid(); - final CWorldCollision worldCollision = simulation.getWorldCollision(); - final float collisionSize = this.unit.getUnitType().getCollisionSize(); - final float startFloatingX = prevX; - final float startFloatingY = prevY; - - this.path = waypoints; - if (this.firstPathfindJob) { - this.firstPathfindJob = false; - System.out.println("init path " + this.path); - // check for smoothing - if (!this.path.isEmpty()) { - float lastX = startFloatingX; - float lastY = startFloatingY; - float smoothingGroupStartX = startFloatingX; - float smoothingGroupStartY = startFloatingY; - final Point2D.Float firstPathElement = this.path.get(0); - double totalPathDistance = firstPathElement.distance(lastX, lastY); - lastX = firstPathElement.x; - lastY = firstPathElement.y; - int smoothingStartIndex = -1; - for (int i = 0; i < (this.path.size() - 1); i++) { - final Point2D.Float nextPossiblePathElement = this.path.get(i + 1); - totalPathDistance += nextPossiblePathElement.distance(lastX, lastY); - if ((totalPathDistance < (1.15 - * nextPossiblePathElement.distance(smoothingGroupStartX, smoothingGroupStartY))) - && pathingGrid.isPathable((smoothingGroupStartX + nextPossiblePathElement.x) / 2, - (smoothingGroupStartY + nextPossiblePathElement.y) / 2, movementType)) { - if (smoothingStartIndex == -1) { - smoothingStartIndex = i; - } - } - else { - if (smoothingStartIndex != -1) { - for (int j = i - 1; j >= smoothingStartIndex; j--) { - this.path.remove(j); - } - i = smoothingStartIndex; - } - smoothingStartIndex = -1; - final Point2D.Float smoothGroupNext = this.path.get(i); - smoothingGroupStartX = smoothGroupNext.x; - smoothingGroupStartY = smoothGroupNext.y; - totalPathDistance = nextPossiblePathElement.distance(smoothGroupNext); - } - lastX = nextPossiblePathElement.x; - lastY = nextPossiblePathElement.y; - } - if (smoothingStartIndex != -1) { - for (int j = smoothingStartIndex; j < (this.path.size() - 1); j++) { - final Point2D.Float removed = this.path.remove(j); - } - } - } - } - else if (this.path.isEmpty() || (this.searchCycles > 6)) { - if (this.searchCycles > 9) { - this.pathfindingFailedGiveUp = true; - } - else { - this.giveUpUntilTurnTick = simulation.getGameTurnTick() - + (int) (5 / WarsmashConstants.SIMULATION_STEP_TIME); - } - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorPatrol.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorPatrol.java deleted file mode 100644 index b1edb7b2..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorPatrol.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; - -public class CBehaviorPatrol implements CRangedBehavior { - - private final CUnit unit; - private AbilityPointTarget target; - private AbilityPointTarget startPoint; - private boolean justAutoAttacked = false; - - public CBehaviorPatrol(final CUnit unit) { - this.unit = unit; - } - - public CBehavior reset(final AbilityPointTarget target) { - this.target = target; - this.startPoint = new AbilityPointTarget(this.unit.getX(), this.unit.getY()); - return this; - } - - @Override - public int getHighlightOrderId() { - return OrderIds.patrol; - } - - @Override - public boolean isWithinRange(final CSimulation simulation) { - if (this.justAutoAttacked = this.unit.autoAcquireAttackTargets(simulation, false)) { - // kind of a hack - return true; - } - return this.unit.distance(this.target.x, this.target.y) <= 16f; // TODO this is not how it was meant to be used - } - - @Override - public CBehavior update(final CSimulation simulation) { - if (this.justAutoAttacked) { - this.justAutoAttacked = false; - return this.unit.getCurrentBehavior(); - } - final AbilityPointTarget temp = this.target; - this.target = this.startPoint; - this.startPoint = temp; - return this.unit.getMoveBehavior().reset(this.target, this, false); - } - - @Override - public void begin(final CSimulation game) { - - } - - @Override - public void end(final CSimulation game, final boolean interrupted) { - - } - - @Override - public void endMove(final CSimulation game, final boolean interrupted) { - - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorStop.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorStop.java deleted file mode 100644 index e45bc02d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CBehaviorStop.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors; - -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; - -public class CBehaviorStop implements CBehavior { - - private final CUnit unit; - - public CBehaviorStop(final CUnit unit) { - this.unit = unit; - } - - @Override - public int getHighlightOrderId() { - return OrderIds.stop; - } - - @Override - public CBehavior update(final CSimulation game) { - if (this.unit.autoAcquireAttackTargets(game, false)) { - return this.unit.getCurrentBehavior(); - } - this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.EMPTY, 1.0f, true); - return this.unit.pollNextOrderBehavior(game); - } - - @Override - public void begin(final CSimulation game) { - - } - - @Override - public void end(final CSimulation game, boolean interrupted) { - - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CRangedBehavior.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CRangedBehavior.java deleted file mode 100644 index 6b8ce91c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/CRangedBehavior.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; - -public interface CRangedBehavior extends CBehavior { - boolean isWithinRange(final CSimulation simulation); - - void endMove(CSimulation game, boolean interrupted); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/AbilityDisableWhileUnderConstructionVisitor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/AbilityDisableWhileUnderConstructionVisitor.java deleted file mode 100644 index 7580353d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/AbilityDisableWhileUnderConstructionVisitor.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGeneric; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityMove; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityBuildInProgress; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNagaBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNeutralBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNightElfBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityOrcBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityUndeadBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityColdArrows; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericNoIconAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericSingleIconActiveAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CAbilityHero; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityQueue; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityRally; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityReviveHero; - -public class AbilityDisableWhileUnderConstructionVisitor implements CAbilityVisitor { - public static final AbilityDisableWhileUnderConstructionVisitor INSTANCE = new AbilityDisableWhileUnderConstructionVisitor(); - - @Override - public Void accept(final CAbilityAttack ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final CAbilityMove ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final CAbilityOrcBuild ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final CAbilityHumanBuild ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final CAbilityUndeadBuild ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final CAbilityNightElfBuild ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final CAbilityGeneric ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final CAbilityColdArrows ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final CAbilityNagaBuild ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final CAbilityNeutralBuild ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final CAbilityBuildInProgress ability) { - ability.setDisabled(false); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final CAbilityQueue ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(CAbilityReviveHero ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final GenericSingleIconActiveAbility ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final CAbilityRally ability) { - ability.setDisabled(false); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final GenericNoIconAbility ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - - @Override - public Void accept(final CAbilityHero ability) { - ability.setDisabled(true); - ability.setIconShowing(false); - return null; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/CBehaviorHumanRepair.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/CBehaviorHumanRepair.java deleted file mode 100644 index 33055545..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/CBehaviorHumanRepair.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build; - -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.*; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanRepair; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetStillAliveAndTargetableVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CAbstractRangedBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.harvest.CBehaviorHarvest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; - -public class CBehaviorHumanRepair extends CAbstractRangedBehavior { - private final CAbilityHumanRepair ability; - private AbilityTargetStillAliveAndTargetableVisitor stillAliveVisitor; - - public CBehaviorHumanRepair(CUnit unit, CAbilityHumanRepair ability) { - super(unit); - this.ability = ability; - stillAliveVisitor = new AbilityTargetStillAliveAndTargetableVisitor(); - } - - public CBehaviorHumanRepair reset(final CWidget target) { - innerReset(target, false); - return this; - } - - @Override - public boolean isWithinRange(CSimulation simulation) { - float castRange = ability.getCastRange(); - if(target instanceof CUnit) { - CUnit unitTarget = (CUnit)target; - if(unitTarget.getUnitType().getMovementType() == PathingGrid.MovementType.FLOAT) { - castRange += ability.getNavalRangeBonus(); - } - } - return unit.canReach(target, castRange); - } - - @Override - protected CBehavior update(CSimulation simulation, boolean withinFacingWindow) { - unit.getUnitAnimationListener().playAnimation(false, AnimationTokens.PrimaryTag.STAND, - SequenceUtils.WORK, 1.0f, true); - if(this.target instanceof CWidget) { - CWidget targetWidget = (CWidget) this.target; - float newLifeValue = targetWidget.getLife() + 1; - boolean done = newLifeValue > targetWidget.getMaxLife(); - if(done) { - newLifeValue = targetWidget.getMaxLife(); - } - targetWidget.setLife(simulation, newLifeValue); - if(done) { - return unit.pollNextOrderBehavior(simulation); - } - } - return this; - } - - @Override - protected CBehavior updateOnInvalidTarget(CSimulation simulation) { - return unit.pollNextOrderBehavior(simulation); - } - - @Override - protected boolean checkTargetStillValid(CSimulation simulation) { - return target.visit(stillAliveVisitor.reset(simulation, unit, ability.getTargetsAllowed())); - } - - @Override - protected void resetBeforeMoving(CSimulation simulation) {} - - @Override - public void begin(CSimulation game) {} - - @Override - public void end(CSimulation game, boolean interrupted) {} - - @Override - public void endMove(CSimulation game, boolean interrupted) {} - - @Override - public int getHighlightOrderId() { - return OrderIds.repair; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/CBehaviorOrcBuild.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/CBehaviorOrcBuild.java deleted file mode 100644 index 9f7cd1b9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/CBehaviorOrcBuild.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build; - -import java.awt.image.BufferedImage; -import java.util.EnumSet; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityBuildInProgress; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CAbstractRangedBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CBuildingPathingType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; - -public class CBehaviorOrcBuild extends CAbstractRangedBehavior { - private int highlightOrderId; - private War3ID orderId; - private boolean unitCreated = false; - - public CBehaviorOrcBuild(final CUnit unit) { - super(unit); - } - - public CBehavior reset(final AbilityPointTarget target, final int orderId, final int highlightOrderId) { - this.highlightOrderId = highlightOrderId; - this.orderId = new War3ID(orderId); - this.unitCreated = false; - return innerReset(target); - } - - @Override - public boolean isWithinRange(final CSimulation simulation) { - final CUnitType unitType = simulation.getUnitData().getUnitType(this.orderId); - return this.unit.canReachToPathing(0, simulation.getGameplayConstants().getBuildingAngle(), - unitType.getBuildingPathingPixelMap(), this.target.getX(), this.target.getY()); - } - - @Override - public int getHighlightOrderId() { - return this.highlightOrderId; - } - - @Override - protected CBehavior update(final CSimulation simulation, final boolean withinFacingWindow) { - if (!this.unitCreated) { - this.unitCreated = true; - final CUnitType unitTypeToCreate = simulation.getUnitData().getUnitType(this.orderId); - final BufferedImage buildingPathingPixelMap = unitTypeToCreate.getBuildingPathingPixelMap(); - boolean buildLocationObstructed = false; - if (buildingPathingPixelMap != null) { - final EnumSet preventedPathingTypes = unitTypeToCreate.getPreventedPathingTypes(); - final EnumSet requiredPathingTypes = unitTypeToCreate.getRequiredPathingTypes(); - - if (!simulation.getPathingGrid().checkPathingTexture(this.target.getX(), this.target.getY(), - (int) simulation.getGameplayConstants().getBuildingAngle(), buildingPathingPixelMap, - preventedPathingTypes, requiredPathingTypes, simulation.getWorldCollision(), this.unit)) { - buildLocationObstructed = true; - } - } - final int playerIndex = this.unit.getPlayerIndex(); - if (!buildLocationObstructed) { - final CUnit constructedStructure = simulation.createUnit(this.orderId, playerIndex, this.target.getX(), - this.target.getY(), simulation.getGameplayConstants().getBuildingAngle()); - constructedStructure.setConstructing(true); - constructedStructure.setWorkerInside(this.unit); - constructedStructure.setLife(simulation, - constructedStructure.getMaximumLife() * WarsmashConstants.BUILDING_CONSTRUCT_START_LIFE); - constructedStructure.setFoodUsed(unitTypeToCreate.getFoodUsed()); - constructedStructure.add(simulation, - new CAbilityBuildInProgress(simulation.getHandleIdAllocator().createId())); - for (final CAbility ability : constructedStructure.getAbilities()) { - ability.visit(AbilityDisableWhileUnderConstructionVisitor.INSTANCE); - } - this.unit.setHidden(true); - this.unit.setPaused(true); - this.unit.setInvulnerable(true); - simulation.unitConstructedEvent(this.unit, constructedStructure); - } - else { - final CPlayer player = simulation.getPlayer(playerIndex); - refund(player, unitTypeToCreate); - simulation.getCommandErrorListener(playerIndex).showCantPlaceError(); - } - } - return this.unit.pollNextOrderBehavior(simulation); - } - - @Override - protected boolean checkTargetStillValid(final CSimulation simulation) { - return true; - } - - @Override - protected CBehavior updateOnInvalidTarget(final CSimulation simulation) { - return this.unit.pollNextOrderBehavior(simulation); - } - - @Override - protected void resetBeforeMoving(final CSimulation simulation) { - - } - - @Override - public void begin(final CSimulation game) { - - } - - @Override - public void end(final CSimulation game, final boolean interrupted) { - if (!this.unitCreated && interrupted) { - final CPlayer player = game.getPlayer(this.unit.getPlayerIndex()); - final CUnitType unitTypeToCreate = game.getUnitData().getUnitType(this.orderId); - refund(player, unitTypeToCreate); - } - } - - private void refund(final CPlayer player, final CUnitType unitTypeToCreate) { - player.setFoodUsed(player.getFoodUsed() - unitTypeToCreate.getFoodUsed()); - player.refundFor(unitTypeToCreate); - } - - @Override - public void endMove(final CSimulation game, final boolean interrupted) { - if (!this.unitCreated && interrupted) { - final CPlayer player = game.getPlayer(this.unit.getPlayerIndex()); - final CUnitType unitTypeToCreate = game.getUnitData().getUnitType(this.orderId); - refund(player, unitTypeToCreate); - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/CBehaviorUndeadBuild.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/CBehaviorUndeadBuild.java deleted file mode 100644 index d274dd21..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/build/CBehaviorUndeadBuild.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.build; - -import java.awt.image.BufferedImage; -import java.util.EnumSet; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityBuildInProgress; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CAbstractRangedBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CBuildingPathingType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; - -public class CBehaviorUndeadBuild extends CAbstractRangedBehavior { - private static int delayAnimationTicks = (int) (2.267f / WarsmashConstants.SIMULATION_STEP_TIME); - private int highlightOrderId; - private War3ID orderId; - private boolean unitCreated = false; - private int doneTick = 0; - - public CBehaviorUndeadBuild(final CUnit unit) { - super(unit); - } - - public CBehavior reset(final AbilityPointTarget target, final int orderId, final int highlightOrderId) { - this.highlightOrderId = highlightOrderId; - this.orderId = new War3ID(orderId); - this.unitCreated = false; - this.doneTick = 0; - return innerReset(target); - } - - @Override - public boolean isWithinRange(final CSimulation simulation) { - if (this.doneTick != 0) { - return true; - } - final CUnitType unitType = simulation.getUnitData().getUnitType(this.orderId); - final BufferedImage buildingPathingPixelMap = unitType.getBuildingPathingPixelMap(); - if (buildingPathingPixelMap == null) { - return this.unit.canReach(this.target.getX(), this.target.getY(), unitType.getCollisionSize()); - } - return this.unit.canReachToPathing(0, simulation.getGameplayConstants().getBuildingAngle(), - buildingPathingPixelMap, this.target.getX(), this.target.getY()); - } - - @Override - public int getHighlightOrderId() { - return this.highlightOrderId; - } - - @Override - protected CBehavior update(final CSimulation simulation, final boolean withinFacingWindow) { - if (this.doneTick != 0) { - if (simulation.getGameTurnTick() > this.doneTick) { - return this.unit.pollNextOrderBehavior(simulation); - } - } - else if (!this.unitCreated) { - this.unitCreated = true; - final CUnitType unitTypeToCreate = simulation.getUnitData().getUnitType(this.orderId); - final BufferedImage buildingPathingPixelMap = unitTypeToCreate.getBuildingPathingPixelMap(); - boolean buildLocationObstructed = false; - if (buildingPathingPixelMap != null) { - final EnumSet preventedPathingTypes = unitTypeToCreate.getPreventedPathingTypes(); - final EnumSet requiredPathingTypes = unitTypeToCreate.getRequiredPathingTypes(); - - if (!simulation.getPathingGrid().checkPathingTexture(this.target.getX(), this.target.getY(), - (int) simulation.getGameplayConstants().getBuildingAngle(), buildingPathingPixelMap, - preventedPathingTypes, requiredPathingTypes, simulation.getWorldCollision(), this.unit)) { - buildLocationObstructed = true; - } - } - final int playerIndex = this.unit.getPlayerIndex(); - if (!buildLocationObstructed) { - final CUnit constructedStructure = simulation.createUnit(this.orderId, playerIndex, this.target.getX(), - this.target.getY(), simulation.getGameplayConstants().getBuildingAngle()); - constructedStructure.setConstructing(true); - constructedStructure.setLife(simulation, - constructedStructure.getMaximumLife() * WarsmashConstants.BUILDING_CONSTRUCT_START_LIFE); - constructedStructure.setFoodUsed(unitTypeToCreate.getFoodUsed()); - constructedStructure.add(simulation, - new CAbilityBuildInProgress(simulation.getHandleIdAllocator().createId())); - for (final CAbility ability : constructedStructure.getAbilities()) { - ability.visit(AbilityDisableWhileUnderConstructionVisitor.INSTANCE); - } - final float deltaX = this.unit.getX() - this.target.getX(); - final float deltaY = this.unit.getY() - this.target.getY(); - final float delta = (float) Math.sqrt((deltaX * deltaX) + (deltaY * deltaY)); - this.unit.setPoint(this.target.getX() + ((deltaX / delta) * unitTypeToCreate.getCollisionSize()), - this.target.getY() + ((deltaY / delta) * unitTypeToCreate.getCollisionSize()), - simulation.getWorldCollision(), simulation.getRegionManager()); - simulation.unitRepositioned(this.unit); - simulation.unitConstructedEvent(this.unit, constructedStructure); - this.doneTick = simulation.getGameTurnTick() + delayAnimationTicks; - } - else { - final CPlayer player = simulation.getPlayer(playerIndex); - refund(player, unitTypeToCreate); - simulation.getCommandErrorListener(playerIndex).showCantPlaceError(); - return this.unit.pollNextOrderBehavior(simulation); - } - } - this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.WORK, 1.0f, true); - return this; - } - - @Override - protected boolean checkTargetStillValid(final CSimulation simulation) { - return true; - } - - @Override - protected CBehavior updateOnInvalidTarget(final CSimulation simulation) { - return this.unit.pollNextOrderBehavior(simulation); - } - - @Override - protected void resetBeforeMoving(final CSimulation simulation) { - - } - - @Override - public void begin(final CSimulation game) { - - } - - @Override - public void end(final CSimulation game, final boolean interrupted) { - if (!this.unitCreated && interrupted) { - final CPlayer player = game.getPlayer(this.unit.getPlayerIndex()); - final CUnitType unitTypeToCreate = game.getUnitData().getUnitType(this.orderId); - refund(player, unitTypeToCreate); - } - } - - private void refund(final CPlayer player, final CUnitType unitTypeToCreate) { - player.setFoodUsed(player.getFoodUsed() - unitTypeToCreate.getFoodUsed()); - player.refundFor(unitTypeToCreate); - } - - @Override - public void endMove(final CSimulation game, final boolean interrupted) { - if (!this.unitCreated && interrupted) { - final CPlayer player = game.getPlayer(this.unit.getPlayerIndex()); - final CUnitType unitTypeToCreate = game.getUnitData().getUnitType(this.orderId); - refund(player, unitTypeToCreate); - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/harvest/CBehaviorHarvest.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/harvest/CBehaviorHarvest.java deleted file mode 100644 index 396d48b3..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/harvest/CBehaviorHarvest.java +++ /dev/null @@ -1,239 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.harvest; - -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.SecondaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitClassification; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityHarvest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.mine.CAbilityGoldMine; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetStillAliveVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CAbstractRangedBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorAttackListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; - -public class CBehaviorHarvest extends CAbstractRangedBehavior - implements AbilityTargetVisitor, CBehaviorAttackListener { - private final CAbilityHarvest abilityHarvest; - private CSimulation simulation; - private int popoutFromMineTurnTick = 0; - - public CBehaviorHarvest(final CUnit unit, final CAbilityHarvest abilityHarvest) { - super(unit); - this.abilityHarvest = abilityHarvest; - } - - public CBehaviorHarvest reset(final CWidget target) { - innerReset(target, target instanceof CUnit); - this.abilityHarvest.setLastHarvestTarget(target); - if (this.popoutFromMineTurnTick != 0) { - // TODO this check is probably only for debug and should be removed after - // extensive testing - throw new IllegalStateException("A unit took action while within a gold mine."); - } - return this; - } - - @Override - public boolean isWithinRange(final CSimulation simulation) { - return this.unit.canReach(this.target, this.abilityHarvest.getTreeAttack().getRange()); - } - - @Override - public int getHighlightOrderId() { - return OrderIds.harvest; - } - - @Override - protected CBehavior update(final CSimulation simulation, final boolean withinFacingWindow) { - this.simulation = simulation; - return this.target.visit(this); - } - - @Override - public CBehavior accept(final AbilityPointTarget target) { - return CBehaviorHarvest.this.unit.pollNextOrderBehavior(this.simulation); - } - - @Override - public CBehavior accept(final CUnit target) { - if ((this.abilityHarvest.getCarriedResourceAmount() == 0) - || (this.abilityHarvest.getCarriedResourceType() != ResourceType.GOLD)) { - for (final CAbility ability : target.getAbilities()) { - if (ability instanceof CAbilityGoldMine) { - final CAbilityGoldMine abilityGoldMine = (CAbilityGoldMine) ability; - final int activeMiners = abilityGoldMine.getActiveMinerCount(); - if (activeMiners < abilityGoldMine.getMiningCapacity()) { - abilityGoldMine.addMiner(this); - this.unit.setHidden(true); - this.unit.setInvulnerable(true); - this.unit.setPaused(true); - this.unit.setAcceptingOrders(false); - this.popoutFromMineTurnTick = this.simulation.getGameTurnTick() - + (int) (abilityGoldMine.getMiningDuration() / WarsmashConstants.SIMULATION_STEP_TIME); - } - else { - // we are stuck waiting to mine, let's make sure we play stand animation - this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.EMPTY, - 1.0f, true); - } - return this; - } - } - // weird invalid target and we have no resources, consider harvesting done - if (this.abilityHarvest.getCarriedResourceAmount() == 0) { - return this.unit.pollNextOrderBehavior(this.simulation); - } - else { - return this.abilityHarvest.getBehaviorReturnResources().reset(this.simulation); - } - } - else { - // we have some GOLD and we're not in a mine (?) lets do a return resources - // order - return this.abilityHarvest.getBehaviorReturnResources().reset(this.simulation); - } - } - - public void popoutFromMine(final int goldMined) { - this.popoutFromMineTurnTick = 0; - this.unit.setHidden(false); - this.unit.setInvulnerable(false); - this.unit.setPaused(false); - this.unit.setAcceptingOrders(true); - dropResources(); - this.abilityHarvest.setCarriedResources(ResourceType.GOLD, goldMined); - this.unit.getUnitAnimationListener().addSecondaryTag(SecondaryTag.GOLD); - this.simulation.unitRepositioned(this.unit); - } - - @Override - public CBehavior accept(final CDestructable target) { - if ((this.abilityHarvest.getCarriedResourceType() != ResourceType.LUMBER) - || (this.abilityHarvest.getCarriedResourceAmount() < this.abilityHarvest.getLumberCapacity())) { - return this.abilityHarvest.getBehaviorTreeAttack().reset(getHighlightOrderId(), - this.abilityHarvest.getTreeAttack(), target, false, this); - } - else { - // we have some LUMBER and we can't carry any more, time to return resources - return this.abilityHarvest.getBehaviorReturnResources().reset(this.simulation); - } - } - - @Override - public void onHit(final AbilityTarget target, final float damage) { - if (this.abilityHarvest.getCarriedResourceType() != ResourceType.LUMBER) { - dropResources(); - } - this.abilityHarvest.setCarriedResources(ResourceType.LUMBER, - Math.min(this.abilityHarvest.getCarriedResourceAmount() + this.abilityHarvest.getDamageToTree(), - this.abilityHarvest.getLumberCapacity())); - this.unit.getUnitAnimationListener().addSecondaryTag(SecondaryTag.LUMBER); - if (target instanceof CDestructable) { - if (this.unit.getUnitType().getClassifications().contains(CUnitClassification.UNDEAD)) { - ((CDestructable) target).setBlighted(true); - } - } - } - - @Override - public void onLaunch() { - - } - - @Override - public CBehavior onFirstUpdateAfterBackswing(final CBehaviorAttack currentAttackBehavior) { - if (this.abilityHarvest.getCarriedResourceAmount() >= this.abilityHarvest.getLumberCapacity()) { - return this.abilityHarvest.getBehaviorReturnResources().reset(this.simulation); - } - return currentAttackBehavior; - } - - @Override - public CBehavior onFinish(final CSimulation game, final CUnit finishingUnit) { - if (this.abilityHarvest.getCarriedResourceAmount() >= this.abilityHarvest.getLumberCapacity()) { - return this.abilityHarvest.getBehaviorReturnResources().reset(this.simulation); - } - return updateOnInvalidTarget(game); - } - - @Override - public CBehavior accept(final CItem target) { - return this.unit.pollNextOrderBehavior(this.simulation); - } - - @Override - protected boolean checkTargetStillValid(final CSimulation simulation) { - return this.target.visit(AbilityTargetStillAliveVisitor.INSTANCE); - } - - @Override - protected CBehavior updateOnInvalidTarget(final CSimulation simulation) { - if (this.target instanceof CDestructable) { - // wood - final CDestructable nearestTree = CBehaviorReturnResources.findNearestTree(this.unit, this.abilityHarvest, - simulation, this.unit); - if (nearestTree != null) { - return reset(nearestTree); - } - } - return this.unit.pollNextOrderBehavior(simulation); - } - - @Override - protected void resetBeforeMoving(final CSimulation simulation) { - - } - - @Override - public void begin(final CSimulation game) { - - } - - @Override - public void end(final CSimulation game, final boolean interrupted) { - - } - - public int getPopoutFromMineTurnTick() { - return this.popoutFromMineTurnTick; - } - - public int getGoldCapacity() { - return this.abilityHarvest.getGoldCapacity(); - } - - private void dropResources() { - if (this.abilityHarvest.getCarriedResourceType() != null) { - switch (this.abilityHarvest.getCarriedResourceType()) { - case FOOD: - throw new IllegalStateException("Unit used Harvest skill to carry FOOD resource!"); - case GOLD: - this.unit.getUnitAnimationListener().removeSecondaryTag(SecondaryTag.GOLD); - break; - case LUMBER: - this.unit.getUnitAnimationListener().removeSecondaryTag(SecondaryTag.LUMBER); - break; - } - } - this.abilityHarvest.setCarriedResources(null, 0); - } - - @Override - public void endMove(final CSimulation game, final boolean interrupted) { - - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/harvest/CBehaviorReturnResources.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/harvest/CBehaviorReturnResources.java deleted file mode 100644 index 9254d29d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/harvest/CBehaviorReturnResources.java +++ /dev/null @@ -1,235 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.harvest; - -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.SecondaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityHarvest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.harvest.CAbilityReturnResources; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.mine.CAbilityGoldMine; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetStillAliveVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CAbstractRangedBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; - -public class CBehaviorReturnResources extends CAbstractRangedBehavior implements AbilityTargetVisitor { - private final CAbilityHarvest abilityHarvest; - private CSimulation simulation; - - public CBehaviorReturnResources(final CUnit unit, final CAbilityHarvest abilityHarvest) { - super(unit); - this.abilityHarvest = abilityHarvest; - } - - public CBehavior reset(final CSimulation simulation) { - final CUnit nearestDropoffPoint = findNearestDropoffPoint(simulation); - if (nearestDropoffPoint == null) { - // TODO it is unconventional not to return self here - return this.unit.pollNextOrderBehavior(simulation); - } - innerReset(nearestDropoffPoint, true); - return this; - } - - @Override - public boolean isWithinRange(final CSimulation simulation) { - // TODO this is probably not what the CloseEnoughRange constant is for - return this.unit.canReach(this.target, this.unit.getUnitType().getCollisionSize()); - } - - @Override - public int getHighlightOrderId() { - return OrderIds.returnresources; - } - - @Override - protected CBehavior update(final CSimulation simulation, final boolean withinFacingWindow) { - this.simulation = simulation; - return this.target.visit(this); - } - - @Override - public CBehavior accept(final AbilityPointTarget target) { - return CBehaviorReturnResources.this.unit.pollNextOrderBehavior(this.simulation); - } - - @Override - public CBehavior accept(final CUnit target) { - for (final CAbility ability : target.getAbilities()) { - if (ability instanceof CAbilityReturnResources) { - final CAbilityReturnResources abilityReturnResources = (CAbilityReturnResources) ability; - if (abilityReturnResources.accepts(this.abilityHarvest.getCarriedResourceType())) { - final CPlayer player = this.simulation.getPlayer(this.unit.getPlayerIndex()); - CWidget nextTarget = null; - switch (this.abilityHarvest.getCarriedResourceType()) { - case FOOD: - throw new IllegalStateException("Unit used Harvest skill to carry FOOD resource!"); - case GOLD: - player.setGold(player.getGold() + this.abilityHarvest.getCarriedResourceAmount()); - this.unit.getUnitAnimationListener().removeSecondaryTag(SecondaryTag.GOLD); - if ((this.abilityHarvest.getLastHarvestTarget() != null) && this.abilityHarvest - .getLastHarvestTarget().visit(AbilityTargetStillAliveVisitor.INSTANCE)) { - nextTarget = this.abilityHarvest.getLastHarvestTarget(); - } - else { - nextTarget = findNearestMine(this.unit, this.simulation); - } - break; - case LUMBER: - player.setLumber(player.getLumber() + this.abilityHarvest.getCarriedResourceAmount()); - this.unit.getUnitAnimationListener().removeSecondaryTag(SecondaryTag.LUMBER); - if (this.abilityHarvest.getLastHarvestTarget() != null) { - if (this.abilityHarvest.getLastHarvestTarget() - .visit(AbilityTargetStillAliveVisitor.INSTANCE)) { - nextTarget = this.abilityHarvest.getLastHarvestTarget(); - } - else { - nextTarget = findNearestTree(this.unit, this.abilityHarvest, this.simulation, - this.abilityHarvest.getLastHarvestTarget()); - } - } - else { - nextTarget = findNearestTree(this.unit, this.abilityHarvest, this.simulation, this.unit); - } - break; - } - this.simulation.unitGainResourceEvent(this.unit, this.abilityHarvest.getCarriedResourceType(), - this.abilityHarvest.getCarriedResourceAmount()); - this.abilityHarvest.setCarriedResources(null, 0); - if (nextTarget != null) { - return this.abilityHarvest.getBehaviorHarvest().reset(nextTarget); - } - return this.unit.pollNextOrderBehavior(this.simulation); - } - } - } - return this; - } - - @Override - public CBehavior accept(final CDestructable target) { - // TODO cut trees! - return this.unit.pollNextOrderBehavior(this.simulation); - } - - @Override - public CBehavior accept(final CItem target) { - return this.unit.pollNextOrderBehavior(this.simulation); - } - - @Override - protected boolean checkTargetStillValid(final CSimulation simulation) { - return this.target.visit(AbilityTargetStillAliveVisitor.INSTANCE); - } - - @Override - protected CBehavior updateOnInvalidTarget(final CSimulation simulation) { - final CUnit nearestDropoff = findNearestDropoffPoint(simulation); - if (nearestDropoff != null) { - this.target = nearestDropoff; - return this; - } - return this.unit.pollNextOrderBehavior(simulation); - } - - @Override - protected void resetBeforeMoving(final CSimulation simulation) { - - } - - private CUnit findNearestDropoffPoint(final CSimulation simulation) { - CUnit nearestDropoffPoint = null; - double nearestDropoffDistance = Float.MAX_VALUE; - for (final CUnit unit : simulation.getUnits()) { - if (unit.getPlayerIndex() == this.unit.getPlayerIndex()) { - if (unit.visit(AbilityTargetStillAliveVisitor.INSTANCE)) { - boolean acceptedUnit = false; - for (final CAbility ability : unit.getAbilities()) { - if (ability instanceof CAbilityReturnResources) { - final CAbilityReturnResources abilityReturnResources = (CAbilityReturnResources) ability; - if (abilityReturnResources.accepts(this.abilityHarvest.getCarriedResourceType())) { - acceptedUnit = true; - break; - } - } - } - if (acceptedUnit) { - // TODO maybe use distance squared, problem is that we're using this - // inefficient more complex distance function on unit - final double distance = unit.distanceSquaredNoCollision(this.unit); - if (distance < nearestDropoffDistance) { - nearestDropoffDistance = distance; - nearestDropoffPoint = unit; - } - } - } - } - } - return nearestDropoffPoint; - } - - private static CUnit findNearestMine(final CUnit worker, final CSimulation simulation) { - CUnit nearestMine = null; - double nearestMineDistance = Float.MAX_VALUE; - for (final CUnit unit : simulation.getUnits()) { - boolean acceptedUnit = false; - for (final CAbility ability : unit.getAbilities()) { - if (ability instanceof CAbilityGoldMine) { - acceptedUnit = true; - break; - } - } - if (acceptedUnit) { - // TODO maybe use distance squared, problem is that we're using this - // inefficient more complex distance function on unit - final double distance = unit.distanceSquaredNoCollision(worker); - if (distance < nearestMineDistance) { - nearestMineDistance = distance; - nearestMine = unit; - } - } - } - return nearestMine; - } - - public static CDestructable findNearestTree(final CUnit worker, final CAbilityHarvest abilityHarvest, - final CSimulation simulation, final CWidget toObject) { - CDestructable nearestMine = null; - double nearestMineDistance = Float.MAX_VALUE; - for (final CDestructable unit : simulation.getDestructables()) { - if (!unit.isDead() - && unit.canBeTargetedBy(simulation, worker, abilityHarvest.getTreeAttack().getTargetsAllowed())) { - // TODO maybe use distance squared, problem is that we're using this - // inefficient more complex distance function on unit - final double distance = unit.distanceSquaredNoCollision(toObject); - if (distance < nearestMineDistance) { - nearestMineDistance = distance; - nearestMine = unit; - } - } - } - return nearestMine; - } - - @Override - public void begin(final CSimulation game) { - - } - - @Override - public void end(final CSimulation game, final boolean interrupted) { - - } - - @Override - public void endMove(final CSimulation game, final boolean interrupted) { - - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/inventory/CBehaviorDropItem.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/inventory/CBehaviorDropItem.java deleted file mode 100644 index d798a0b9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/inventory/CBehaviorDropItem.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.inventory; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.inventory.CAbilityInventory; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetStillAliveVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CAbstractRangedBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; - -public class CBehaviorDropItem extends CAbstractRangedBehavior { - private final CAbilityInventory inventory; - private CItem targetItem; - - public CBehaviorDropItem(final CUnit unit, final CAbilityInventory inventory) { - super(unit); - this.inventory = inventory; - } - - public CBehaviorDropItem reset(final CItem targetItem, final AbilityPointTarget targetPoint) { - innerReset(targetPoint); - this.targetItem = targetItem; - return this; - } - - @Override - public boolean isWithinRange(final CSimulation simulation) { - return this.unit.canReach(this.target, simulation.getGameplayConstants().getDropItemRange()); - } - - @Override - public void endMove(final CSimulation game, final boolean interrupted) { - } - - @Override - public void begin(final CSimulation game) { - } - - @Override - public void end(final CSimulation game, final boolean interrupted) { - } - - @Override - public int getHighlightOrderId() { - return OrderIds.dropitem; - } - - @Override - protected CBehavior update(final CSimulation simulation, final boolean withinFacingWindow) { - this.inventory.dropItem(simulation, this.unit, this.targetItem, this.target.getX(), this.target.getY(), true); - return this.unit.pollNextOrderBehavior(simulation); - } - - @Override - protected CBehavior updateOnInvalidTarget(final CSimulation simulation) { - return this.unit.pollNextOrderBehavior(simulation); - } - - @Override - protected boolean checkTargetStillValid(final CSimulation simulation) { - return this.target.visit(AbilityTargetStillAliveVisitor.INSTANCE); - } - - @Override - protected void resetBeforeMoving(final CSimulation simulation) { - - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/inventory/CBehaviorGetItem.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/inventory/CBehaviorGetItem.java deleted file mode 100644 index 749ce369..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/inventory/CBehaviorGetItem.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.inventory; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.inventory.CAbilityInventory; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetItemVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetStillAliveVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CAbstractRangedBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; - -public class CBehaviorGetItem extends CAbstractRangedBehavior { - private final CAbilityInventory inventory; - - public CBehaviorGetItem(final CUnit unit, final CAbilityInventory inventory) { - super(unit); - this.inventory = inventory; - } - - public CBehaviorGetItem reset(final CItem targetItem) { - innerReset(targetItem); - return this; - } - - @Override - public boolean isWithinRange(final CSimulation simulation) { - return this.unit.canReach(this.target, simulation.getGameplayConstants().getPickupItemRange()); - } - - @Override - public void endMove(final CSimulation game, final boolean interrupted) { - } - - @Override - public void begin(final CSimulation game) { - } - - @Override - public void end(final CSimulation game, final boolean interrupted) { - } - - @Override - public int getHighlightOrderId() { - return OrderIds.getitem; - } - - @Override - protected CBehavior update(final CSimulation simulation, final boolean withinFacingWindow) { - final CItem targetItem = this.target.visit(AbilityTargetItemVisitor.INSTANCE); - this.inventory.giveItem(simulation, this.unit, targetItem, true); - return this.unit.pollNextOrderBehavior(simulation); - } - - @Override - protected CBehavior updateOnInvalidTarget(final CSimulation simulation) { - return this.unit.pollNextOrderBehavior(simulation); - } - - @Override - protected boolean checkTargetStillValid(final CSimulation simulation) { - return this.target.visit(AbilityTargetStillAliveVisitor.INSTANCE); - } - - @Override - protected void resetBeforeMoving(final CSimulation simulation) { - - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/test/CBehaviorChannelTest.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/test/CBehaviorChannelTest.java deleted file mode 100644 index d64ecd94..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/test/CBehaviorChannelTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.test; - -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; - -public class CBehaviorChannelTest implements CBehavior { - private final CUnit unit; - private final float artDuration; - private int nextArtTick; - - public CBehaviorChannelTest(final CUnit unit, final float artDuration) { - this.unit = unit; - this.artDuration = artDuration; - } - - public CBehaviorChannelTest reset() { - this.nextArtTick = 0; - return this; - } - - @Override - public CBehavior update(final CSimulation game) { - this.unit.getUnitAnimationListener().playAnimation(false, null, SequenceUtils.SPELL, 1.0f, true); - final int gameTurnTick = game.getGameTurnTick(); - if (gameTurnTick >= this.nextArtTick) { - game.createEffectOnUnit(this.unit, "Abilities\\Spells\\Undead\\DeathPact\\DeathPactTarget.mdl"); - this.nextArtTick = gameTurnTick + (int) (this.artDuration / WarsmashConstants.SIMULATION_STEP_TIME); - } - return this; - } - - @Override - public void begin(final CSimulation game) { - } - - @Override - public void end(final CSimulation game, boolean interrupted) { - } - - @Override - public int getHighlightOrderId() { - return OrderIds.channel; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/test/CBehaviorCoupleInstant.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/test/CBehaviorCoupleInstant.java deleted file mode 100644 index 9930f37d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/behaviors/test/CBehaviorCoupleInstant.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.test; - -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetStillAliveAndTargetableVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.test.CAbilityCoupleInstant; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CAbstractRangedBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; - -public class CBehaviorCoupleInstant extends CAbstractRangedBehavior { - - private final CAbilityCoupleInstant abilityCoupleInstant; - private final AbilityTargetStillAliveAndTargetableVisitor stillAliveVisitor; - - public CBehaviorCoupleInstant(final CUnit unit, final CAbilityCoupleInstant abilityCoupleInstant) { - super(unit); - this.abilityCoupleInstant = abilityCoupleInstant; - this.stillAliveVisitor = new AbilityTargetStillAliveAndTargetableVisitor(); - } - - public CBehaviorCoupleInstant reset(final CUnit coupleTarget) { - innerReset(coupleTarget); - return this; - } - - @Override - public boolean isWithinRange(final CSimulation simulation) { - return this.unit.canReach(this.target, this.abilityCoupleInstant.getCastRange()); - } - - @Override - public void endMove(final CSimulation game, final boolean interrupted) { - } - - @Override - public void begin(final CSimulation game) { - } - - @Override - public void end(final CSimulation game, final boolean interrupted) { - } - - @Override - public int getHighlightOrderId() { - return OrderIds.coupleinstant; - } - - @Override - protected CBehavior update(final CSimulation simulation, final boolean withinRange) { - final CBehavior targetBehavior = ((CUnit) this.target).getCurrentBehavior(); - if (targetBehavior instanceof CBehaviorCoupleInstant) { - if (((CBehaviorCoupleInstant) targetBehavior).isWithinRange(simulation)) { - // we are both within range - final int goldCost = this.abilityCoupleInstant.getGoldCost(); - final int lumberCost = this.abilityCoupleInstant.getLumberCost(); - if (((goldCost == 0) && (lumberCost == 0)) - || simulation.getPlayer(this.unit.getPlayerIndex()).charge(goldCost, lumberCost)) { - final CUnit newUnit = simulation.createUnit(this.abilityCoupleInstant.getResultingUnitType(), - this.unit.getPlayerIndex(), this.unit.getX(), this.unit.getY(), this.unit.getFacing()); - simulation.unitPreferredSelectionReplacement(this.unit, newUnit); - simulation.unitPreferredSelectionReplacement(((CUnit) this.target), newUnit); - simulation.removeUnit(this.unit); - simulation.removeUnit((CUnit) this.target); - simulation.unitSoundEffectEvent(newUnit, this.abilityCoupleInstant.getAlias()); - } - return this.unit.pollNextOrderBehavior(simulation); - } - } - this.unit.getUnitAnimationListener().playAnimation(false, PrimaryTag.STAND, SequenceUtils.EMPTY, 1.0f, true); - return this; - } - - @Override - protected CBehavior updateOnInvalidTarget(final CSimulation simulation) { - return this.unit.pollNextOrderBehavior(simulation); - } - - @Override - protected boolean checkTargetStillValid(final CSimulation simulation) { - return this.target.visit( - this.stillAliveVisitor.reset(simulation, this.unit, this.abilityCoupleInstant.getTargetsAllowed())); - } - - @Override - protected void resetBeforeMoving(final CSimulation simulation) { - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CAttackType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CAttackType.java deleted file mode 100644 index cd540b85..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CAttackType.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat; - -public enum CAttackType implements CodeKeyType { - UNKNOWN, - NORMAL, - PIERCE, - SIEGE, - SPELLS, - CHAOS, - MAGIC, - HERO; - - public static CAttackType[] VALUES = values(); - - private String codeKey; - private String damageKey; - - private CAttackType() { - final String name = name(); - final String computedCodeKey = name.charAt(0) + name.substring(1).toLowerCase(); - if (computedCodeKey.equals("Spells")) { - this.codeKey = "Magic"; - } - else { - this.codeKey = computedCodeKey; - } - this.damageKey = this.codeKey; - } - - @Override - public String getCodeKey() { - return this.codeKey; - } - - public String getDamageKey() { - return this.damageKey; - } - - public static CAttackType parseAttackType(final String attackTypeString) { - final String upperCaseAttackType = attackTypeString.toUpperCase(); - if ("SEIGE".equals(upperCaseAttackType)) { - return SIEGE; - } - return valueOf(upperCaseAttackType); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CDefenseType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CDefenseType.java deleted file mode 100644 index 1360513e..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CDefenseType.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat; - -public enum CDefenseType implements CodeKeyType { - NONE, - NORMAL, - SMALL, - MEDIUM, - LARGE, - FORT, - HERO, - DIVINE; - - public static CDefenseType[] VALUES = values(); - - private String codeKey; - - private CDefenseType() { - this.codeKey = name().charAt(0) + name().substring(1).toLowerCase(); - } - - @Override - public String getCodeKey() { - return this.codeKey; - } - - public static CDefenseType parseDefenseType(final String typeString) { - final String upperCaseTypeString = typeString.toUpperCase(); - if (upperCaseTypeString.equals("HEAVY")) { - return LARGE; - } - return valueOf(upperCaseTypeString); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CRegenType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CRegenType.java deleted file mode 100644 index b3032723..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CRegenType.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat; - -public enum CRegenType { - NONE, - ALWAYS, - BLIGHT, - DAY, - NIGHT; - - public static CRegenType parseRegenType(final String typeString) { - return valueOf(typeString.toUpperCase()); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CTargetType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CTargetType.java deleted file mode 100644 index 5fb484ab..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CTargetType.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat; - -import java.util.EnumSet; - -public enum CTargetType { - AIR, - ALIVE, - ALLIES, - DEAD, - DEBRIS, - ENEMIES, - GROUND, - HERO, - INVULNERABLE, - ITEM, - MECHANICAL, - NEUTRAL, - NONE, - NONHERO, - NONSAPPER, - NOTSELF, - ORGANIC, - PLAYERUNITS, - SAPPER, - SELF, - STRUCTURE, - TERRAIN, - TREE, - VULNERABLE, - WALL, - WARD, - ANCIENT, - NONANCIENT, - FRIEND, - BRIDGE, - DECORATION; - - public static CTargetType parseTargetType(final String targetTypeString) { - if (targetTypeString == null) { - return null; - } - switch (targetTypeString.toLowerCase()) { - case "air": - return AIR; - case "alive": - case "aliv": - return ALIVE; - case "allies": - case "alli": - case "ally": - return ALLIES; - case "dead": - return DEAD; - case "debris": - case "debr": - return DEBRIS; - case "enemies": - case "enem": - case "enemy": - return ENEMIES; - case "ground": - case "grou": - return GROUND; - case "hero": - return HERO; - case "invulnerable": - case "invu": - return INVULNERABLE; - case "item": - return ITEM; - case "mechanical": - case "mech": - return MECHANICAL; - case "neutral": - case "neut": - return NEUTRAL; - case "none": - return NONE; - case "nonhero": - case "nonh": - return NONHERO; - case "nonsapper": - return NONSAPPER; - case "notself": - case "nots": - return NOTSELF; - case "organic": - case "orga": - return ORGANIC; - case "player": - case "play": - return PLAYERUNITS; - case "sapper": - return SAPPER; - case "self": - return SELF; - case "structure": - case "stru": - return STRUCTURE; - case "terrain": - case "terr": - return TERRAIN; - case "tree": - return TREE; - case "vulnerable": - case "vuln": - return VULNERABLE; - case "wall": - return WALL; - case "ward": - return WARD; - case "ancient": - return ANCIENT; - case "nonancient": - return NONANCIENT; - case "friend": - case "frie": - return FRIEND; - case "bridge": - return BRIDGE; - case "decoration": - case "deco": - return DECORATION; - default: - return null; - } - } - - public static EnumSet parseTargetTypeSet(final String targetTypeString) { - final EnumSet types = EnumSet.noneOf(CTargetType.class); - for (final String type : targetTypeString.split(",")) { - final CTargetType parsedType = parseTargetType(type); - if (parsedType != null) { - types.add(parsedType); - } - } - return types; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CUpgradeClass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CUpgradeClass.java deleted file mode 100644 index 3112bf63..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CUpgradeClass.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat; - -public enum CUpgradeClass { - ARMOR, - ARTILLERY, - MELEE, - RANGED, - CASTER; - - public static CUpgradeClass parseUpgradeClass(final String upgradeClassString) { - return valueOf(upgradeClassString.toUpperCase()); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CWeaponType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CWeaponType.java deleted file mode 100644 index b47162f8..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CWeaponType.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat; - -public enum CWeaponType { - NORMAL, - INSTANT, - ARTILLERY, - ALINE, - MISSILE, - MSPLASH, - MBOUNCE, - MLINE; - - public static CWeaponType parseWeaponType(final String weaponTypeString) { - return valueOf(weaponTypeString.toUpperCase()); - } - - public boolean isAttackGroundSupported() { - return (this == CWeaponType.ARTILLERY) || (this == CWeaponType.ALINE); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CodeKeyType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CodeKeyType.java deleted file mode 100644 index d727a020..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/CodeKeyType.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat; - -public interface CodeKeyType { - String getCodeKey(); - - int ordinal(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttack.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttack.java deleted file mode 100644 index 0b885f59..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttack.java +++ /dev/null @@ -1,271 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CWeaponType; - -/** - * The base class for unit-data-based combat attacks. - * - * I really wanted to split this out into sub classes based on weapon type, but - * I came to realize the Ballista in RoC probably had the spill distance effect - * & area of effect both after it upgrades Impaling Bolt, and this would point - * out that the behaviors were not mutually exclusive. - * - * Then I reviewed it and decided that in RoC, the Impaling Bolts upgrade did - * not interact with the damage spill combat settings from the UnitWeapons.slk, - * because many of those settings did not exist. So I will attempt to emulate - * these attacks as best as possible. - */ -public abstract class CUnitAttack { - private float animationBackswingPoint; - private float animationDamagePoint; - private CAttackType attackType; - private float cooldownTime; - private int damageBase; - private int damageDice; - private int damageSidesPerDie; - private int damageUpgradeAmount; - private int range; - private float rangeMotionBuffer; - private boolean showUI; - private EnumSet targetsAllowed; - private String weaponSound; - private CWeaponType weaponType; - - // calculate - private int minDamage; - private int maxDamage; - private int minDamageDisplay; - private int maxDamageDisplay; - - private int primaryAttributeDamageBonus; - private int permanentDamageBonus; - private int temporaryDamageBonus; - - public CUnitAttack(final float animationBackswingPoint, final float animationDamagePoint, - final CAttackType attackType, final float cooldownTime, final int damageBase, final int damageDice, - final int damageSidesPerDie, final int damageUpgradeAmount, final int range, final float rangeMotionBuffer, - final boolean showUI, final EnumSet targetsAllowed, final String weaponSound, - final CWeaponType weaponType) { - this.animationBackswingPoint = animationBackswingPoint; - this.animationDamagePoint = animationDamagePoint; - this.attackType = attackType; - this.cooldownTime = cooldownTime; - this.damageBase = damageBase; - this.damageDice = damageDice; - this.damageSidesPerDie = damageSidesPerDie; - this.damageUpgradeAmount = damageUpgradeAmount; - this.range = range; - this.rangeMotionBuffer = rangeMotionBuffer; - this.showUI = showUI; - this.targetsAllowed = targetsAllowed; - this.weaponSound = weaponSound; - this.weaponType = weaponType; - computeDerivedFields(); - } - - public CUnitAttack(final CUnitAttack other) { - this.animationBackswingPoint = other.animationBackswingPoint; - this.animationDamagePoint = other.animationDamagePoint; - this.attackType = other.attackType; - this.cooldownTime = other.cooldownTime; - this.damageBase = other.damageBase; - this.damageDice = other.damageDice; - this.damageSidesPerDie = other.damageSidesPerDie; - this.damageUpgradeAmount = other.damageUpgradeAmount; - this.range = other.range; - this.rangeMotionBuffer = other.rangeMotionBuffer; - this.showUI = other.showUI; - this.targetsAllowed = other.targetsAllowed; - this.weaponSound = other.weaponSound; - this.weaponType = other.weaponType; - - this.primaryAttributeDamageBonus = other.primaryAttributeDamageBonus; - this.permanentDamageBonus = other.permanentDamageBonus; - this.temporaryDamageBonus = other.temporaryDamageBonus; - computeDerivedFields(); - } - - public abstract CUnitAttack copy(); - - private void computeDerivedFields() { - final int baseDamage = this.damageBase + this.primaryAttributeDamageBonus + this.permanentDamageBonus; - this.minDamageDisplay = baseDamage + this.damageDice; - this.maxDamageDisplay = baseDamage + (this.damageDice * this.damageSidesPerDie); - if (this.minDamageDisplay < 0) { - this.minDamageDisplay = 0; - } - if (this.maxDamageDisplay < 0) { - this.maxDamageDisplay = 0; - } - this.minDamage = this.minDamageDisplay + this.temporaryDamageBonus; - this.maxDamage = this.maxDamageDisplay + this.temporaryDamageBonus; - } - - public float getAnimationBackswingPoint() { - return this.animationBackswingPoint; - } - - public float getAnimationDamagePoint() { - return this.animationDamagePoint; - } - - public CAttackType getAttackType() { - return this.attackType; - } - - public float getCooldownTime() { - return this.cooldownTime; - } - - public int getDamageBase() { - return this.damageBase; - } - - public int getDamageDice() { - return this.damageDice; - } - - public int getDamageSidesPerDie() { - return this.damageSidesPerDie; - } - - public int getDamageUpgradeAmount() { - return this.damageUpgradeAmount; - } - - public int getRange() { - return this.range; - } - - public float getRangeMotionBuffer() { - return this.rangeMotionBuffer; - } - - public boolean isShowUI() { - return this.showUI; - } - - public EnumSet getTargetsAllowed() { - return this.targetsAllowed; - } - - public String getWeaponSound() { - return this.weaponSound; - } - - public CWeaponType getWeaponType() { - return this.weaponType; - } - - public void setAnimationBackswingPoint(final float animationBackswingPoint) { - this.animationBackswingPoint = animationBackswingPoint; - } - - public void setAnimationDamagePoint(final float animationDamagePoint) { - this.animationDamagePoint = animationDamagePoint; - } - - public void setAttackType(final CAttackType attackType) { - this.attackType = attackType; - } - - public void setCooldownTime(final float cooldownTime) { - this.cooldownTime = cooldownTime; - } - - public void setDamageBase(final int damageBase) { - this.damageBase = damageBase; - computeDerivedFields(); - } - - public void setDamageDice(final int damageDice) { - this.damageDice = damageDice; - computeDerivedFields(); - } - - public void setDamageSidesPerDie(final int damageSidesPerDie) { - this.damageSidesPerDie = damageSidesPerDie; - computeDerivedFields(); - } - - public void setDamageUpgradeAmount(final int damageUpgradeAmount) { - this.damageUpgradeAmount = damageUpgradeAmount; - } - - public void setRange(final int range) { - this.range = range; - } - - public void setRangeMotionBuffer(final float rangeMotionBuffer) { - this.rangeMotionBuffer = rangeMotionBuffer; - } - - public void setShowUI(final boolean showUI) { - this.showUI = showUI; - } - - public void setTargetsAllowed(final EnumSet targetsAllowed) { - this.targetsAllowed = targetsAllowed; - } - - public void setWeaponSound(final String weaponSound) { - this.weaponSound = weaponSound; - } - - public void setWeaponType(final CWeaponType weaponType) { - this.weaponType = weaponType; - } - - public int getMinDamage() { - return this.minDamage; - } - - public int getMaxDamage() { - return this.maxDamage; - } - - public int getMinDamageDisplay() { - return this.minDamageDisplay; - } - - public int getMaxDamageDisplay() { - return this.maxDamageDisplay; - } - - public void setPrimaryAttributeDamageBonus(final int primaryAttributeDamageBonus) { - this.primaryAttributeDamageBonus = primaryAttributeDamageBonus; - computeDerivedFields(); - } - - public void setPermanentDamageBonus(final int permanentDamageBonus) { - this.permanentDamageBonus = permanentDamageBonus; - computeDerivedFields(); - } - - public void setTemporaryDamageBonus(final int temporaryDamageBonus) { - this.temporaryDamageBonus = temporaryDamageBonus; - computeDerivedFields(); - } - - public int getPrimaryAttributeDamageBonus() { - return this.primaryAttributeDamageBonus; - } - - public int getPermanentDamageBonus() { - return this.permanentDamageBonus; - } - - public int getTemporaryDamageBonus() { - return this.temporaryDamageBonus; - } - - public abstract void launch(CSimulation simulation, CUnit unit, AbilityTarget target, float damage, - CUnitAttackListener attackListener); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackInstant.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackInstant.java deleted file mode 100644 index 33bbec40..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackInstant.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetWidgetVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CWeaponType; - -public class CUnitAttackInstant extends CUnitAttack { - private String projectileArt; - - public CUnitAttackInstant(final float animationBackswingPoint, final float animationDamagePoint, - final CAttackType attackType, final float cooldownTime, final int damageBase, final int damageDice, - final int damageSidesPerDie, final int damageUpgradeAmount, final int range, final float rangeMotionBuffer, - final boolean showUI, final EnumSet targetsAllowed, final String weaponSound, - final CWeaponType weaponType, final String projectileArt) { - super(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime, damageBase, damageDice, - damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound, - weaponType); - this.projectileArt = projectileArt; - } - - @Override - public CUnitAttack copy() { - return new CUnitAttackInstant(getAnimationBackswingPoint(), getAnimationDamagePoint(), getAttackType(), - getCooldownTime(), getDamageBase(), getDamageDice(), getDamageSidesPerDie(), getDamageUpgradeAmount(), - getRange(), getRangeMotionBuffer(), isShowUI(), getTargetsAllowed(), getWeaponSound(), getWeaponType(), - this.projectileArt); - } - - public String getProjectileArt() { - return this.projectileArt; - } - - public void setProjectileArt(final String projectileArt) { - this.projectileArt = projectileArt; - } - - @Override - public void launch(final CSimulation simulation, final CUnit unit, final AbilityTarget target, final float damage, - final CUnitAttackListener attackListener) { - attackListener.onLaunch(); - final CWidget widget = target.visit(AbilityTargetWidgetVisitor.INSTANCE); - if (widget != null) { - simulation.createInstantAttackEffect(unit, this, widget); - widget.damage(simulation, unit, getAttackType(), getWeaponSound(), damage); - attackListener.onHit(target, damage); - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackListener.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackListener.java deleted file mode 100644 index e833fc7e..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackListener.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; - -public interface CUnitAttackListener { - void onLaunch(); - - void onHit(AbilityTarget target, float damage); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissile.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissile.java deleted file mode 100644 index f3017d85..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissile.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetWidgetVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CWeaponType; - -public class CUnitAttackMissile extends CUnitAttack { - private float projectileArc; - private String projectileArt; - private boolean projectileHomingEnabled; - private int projectileSpeed; - - public CUnitAttackMissile(final float animationBackswingPoint, final float animationDamagePoint, - final CAttackType attackType, final float cooldownTime, final int damageBase, final int damageDice, - final int damageSidesPerDie, final int damageUpgradeAmount, final int range, final float rangeMotionBuffer, - final boolean showUI, final EnumSet targetsAllowed, final String weaponSound, - final CWeaponType weaponType, final float projectileArc, final String projectileArt, - final boolean projectileHomingEnabled, final int projectileSpeed) { - super(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime, damageBase, damageDice, - damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound, - weaponType); - this.projectileArc = projectileArc; - this.projectileArt = projectileArt; - this.projectileHomingEnabled = projectileHomingEnabled; - this.projectileSpeed = projectileSpeed; - } - - @Override - public CUnitAttack copy() { - return new CUnitAttackMissile(this.getAnimationBackswingPoint(), getAnimationDamagePoint(), getAttackType(), - getCooldownTime(), getDamageBase(), getDamageDice(), getDamageSidesPerDie(), getDamageUpgradeAmount(), - getRange(), getRangeMotionBuffer(), isShowUI(), getTargetsAllowed(), getWeaponSound(), getWeaponType(), - this.projectileArc, this.projectileArt, this.projectileHomingEnabled, this.projectileSpeed); - } - - public float getProjectileArc() { - return this.projectileArc; - } - - public String getProjectileArt() { - return this.projectileArt; - } - - public boolean isProjectileHomingEnabled() { - return this.projectileHomingEnabled; - } - - public int getProjectileSpeed() { - return this.projectileSpeed; - } - - public void setProjectileArc(final float projectileArc) { - this.projectileArc = projectileArc; - } - - public void setProjectileArt(final String projectileArt) { - this.projectileArt = projectileArt; - } - - public void setProjectileHomingEnabled(final boolean projectileHomingEnabled) { - this.projectileHomingEnabled = projectileHomingEnabled; - } - - public void setProjectileSpeed(final int projectileSpeed) { - this.projectileSpeed = projectileSpeed; - } - - @Override - public void launch(final CSimulation simulation, final CUnit unit, final AbilityTarget target, final float damage, - final CUnitAttackListener attackListener) { - attackListener.onLaunch(); - simulation.createProjectile(unit, unit.getX(), unit.getY(), (float) Math.toRadians(unit.getFacing()), this, - target, damage, 0, attackListener); - } - - public void doDamage(final CSimulation cSimulation, final CUnit source, final AbilityTarget target, - final float damage, final float x, final float y, final int bounceIndex, - final CUnitAttackListener attackListener) { - final CWidget widget = target.visit(AbilityTargetWidgetVisitor.INSTANCE); - if (widget != null) { - widget.damage(cSimulation, source, getAttackType(), getWeaponSound(), damage); - attackListener.onHit(target, damage); - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissileBounce.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissileBounce.java deleted file mode 100644 index b56f99ba..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissileBounce.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks; - -import java.util.EnumSet; - -import com.badlogic.gdx.math.Rectangle; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitEnumFunction; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetWidgetVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CWeaponType; - -public class CUnitAttackMissileBounce extends CUnitAttackMissile { - private float damageLossFactor; - private int maximumNumberOfTargets; - private final int areaOfEffectFullDamage; - private final EnumSet areaOfEffectTargets; - - public CUnitAttackMissileBounce(final float animationBackswingPoint, final float animationDamagePoint, - final CAttackType attackType, final float cooldownTime, final int damageBase, final int damageDice, - final int damageSidesPerDie, final int damageUpgradeAmount, final int range, final float rangeMotionBuffer, - final boolean showUI, final EnumSet targetsAllowed, final String weaponSound, - final CWeaponType weaponType, final float projectileArc, final String projectileArt, - final boolean projectileHomingEnabled, final int projectileSpeed, final float damageLossFactor, - final int maximumNumberOfTargets, final int areaOfEffectFullDamage, - final EnumSet areaOfEffectTargets) { - super(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime, damageBase, damageDice, - damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound, - weaponType, projectileArc, projectileArt, projectileHomingEnabled, projectileSpeed); - this.damageLossFactor = damageLossFactor; - this.maximumNumberOfTargets = maximumNumberOfTargets; - this.areaOfEffectFullDamage = areaOfEffectFullDamage; - this.areaOfEffectTargets = areaOfEffectTargets; - } - - @Override - public CUnitAttack copy() { - return new CUnitAttackMissileBounce(getAnimationBackswingPoint(), getAnimationDamagePoint(), getAttackType(), - getCooldownTime(), getDamageBase(), getDamageDice(), getDamageSidesPerDie(), getDamageUpgradeAmount(), - getRange(), getRangeMotionBuffer(), isShowUI(), getTargetsAllowed(), getWeaponSound(), getWeaponType(), - getProjectileArc(), getProjectileArt(), isProjectileHomingEnabled(), getProjectileSpeed(), - this.damageLossFactor, this.maximumNumberOfTargets, this.areaOfEffectFullDamage, - this.areaOfEffectTargets); - } - - public float getDamageLossFactor() { - return this.damageLossFactor; - } - - public int getMaximumNumberOfTargets() { - return this.maximumNumberOfTargets; - } - - public void setDamageLossFactor(final float damageLossFactor) { - this.damageLossFactor = damageLossFactor; - } - - public void setMaximumNumberOfTargets(final int maximumNumberOfTargets) { - this.maximumNumberOfTargets = maximumNumberOfTargets; - } - - @Override - public void doDamage(final CSimulation cSimulation, final CUnit source, final AbilityTarget target, - final float damage, final float x, final float y, final int bounceIndex, - final CUnitAttackListener attackListener) { - super.doDamage(cSimulation, source, target, damage, x, y, bounceIndex, attackListener); - final CWidget widget = target.visit(AbilityTargetWidgetVisitor.INSTANCE); - if (widget != null) { - final int nextBounceIndex = bounceIndex + 1; - if (nextBounceIndex != this.maximumNumberOfTargets) { - BounceMissileConsumer.INSTANCE.nextBounce(cSimulation, source, widget, this, x, y, damage, - nextBounceIndex, attackListener); - } - } - } - - private static final class BounceMissileConsumer implements CUnitEnumFunction { - private static final BounceMissileConsumer INSTANCE = new BounceMissileConsumer(); - private final Rectangle rect = new Rectangle(); - private CUnitAttackMissileBounce attack; - private CSimulation simulation; - private CUnit source; - private CWidget target; - private float x; - private float y; - private float damage; - private int bounceIndex; - private CUnitAttackListener attackListener; - private boolean launched = false; - - public void nextBounce(final CSimulation simulation, final CUnit source, final CWidget target, - final CUnitAttackMissileBounce attack, final float x, final float y, final float damage, - final int bounceIndex, final CUnitAttackListener attackListener) { - this.simulation = simulation; - this.source = source; - this.target = target; - this.attack = attack; - this.x = x; - this.y = y; - this.damage = damage; - this.bounceIndex = bounceIndex; - this.attackListener = attackListener; - this.launched = false; - final float doubleMaxArea = attack.areaOfEffectFullDamage - + (this.simulation.getGameplayConstants().getCloseEnoughRange() * 2); - final float maxArea = doubleMaxArea / 2; - this.rect.set(x - maxArea, y - maxArea, doubleMaxArea, doubleMaxArea); - simulation.getWorldCollision().enumUnitsInRect(this.rect, this); - - } - - @Override - public boolean call(final CUnit enumUnit) { - if (enumUnit == this.target) { - return false; - } - if (enumUnit.canBeTargetedBy(this.simulation, this.source, this.attack.areaOfEffectTargets)) { - if (this.launched) { - throw new IllegalStateException("already launched"); - } - final float dx = enumUnit.getX() - this.x; - final float dy = enumUnit.getY() - this.y; - final float angle = (float) Math.atan2(dy, dx); - this.simulation.createProjectile(this.source, this.x, this.y, angle, this.attack, enumUnit, - this.damage * (1.0f - this.attack.damageLossFactor), this.bounceIndex, this.attackListener); - this.launched = true; - return true; - } - return false; - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissileLine.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissileLine.java deleted file mode 100644 index bd95e8ab..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissileLine.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CWeaponType; - -public class CUnitAttackMissileLine extends CUnitAttackMissile { - private float damageSpillDistance; - private float damageSpillRadius; - - public CUnitAttackMissileLine(final float animationBackswingPoint, final float animationDamagePoint, - final CAttackType attackType, final float cooldownTime, final int damageBase, final int damageDice, - final int damageSidesPerDie, final int damageUpgradeAmount, final int range, final float rangeMotionBuffer, - final boolean showUI, final EnumSet targetsAllowed, final String weaponSound, - final CWeaponType weaponType, final float projectileArc, final String projectileArt, - final boolean projectileHomingEnabled, final int projectileSpeed, final float damageSpillDistance, - final float damageSpillRadius) { - super(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime, damageBase, damageDice, - damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound, - weaponType, projectileArc, projectileArt, projectileHomingEnabled, projectileSpeed); - this.damageSpillDistance = damageSpillDistance; - this.damageSpillRadius = damageSpillRadius; - } - - @Override - public CUnitAttack copy() { - return new CUnitAttackMissileLine(getAnimationBackswingPoint(), getAnimationDamagePoint(), getAttackType(), - getCooldownTime(), getDamageBase(), getDamageDice(), getDamageSidesPerDie(), getDamageUpgradeAmount(), - getRange(), getRangeMotionBuffer(), isShowUI(), getTargetsAllowed(), getWeaponSound(), getWeaponType(), - getProjectileArc(), getProjectileArt(), isProjectileHomingEnabled(), getProjectileSpeed(), - this.damageSpillDistance, this.damageSpillRadius); - } - - public float getDamageSpillDistance() { - return this.damageSpillDistance; - } - - public float getDamageSpillRadius() { - return this.damageSpillRadius; - } - - public void setDamageSpillDistance(final float damageSpillDistance) { - this.damageSpillDistance = damageSpillDistance; - } - - public void setDamageSpillRadius(final float damageSpillRadius) { - this.damageSpillRadius = damageSpillRadius; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissileSplash.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissileSplash.java deleted file mode 100644 index b292ac14..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackMissileSplash.java +++ /dev/null @@ -1,176 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks; - -import java.util.EnumSet; - -import com.badlogic.gdx.math.Rectangle; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitEnumFunction; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CWeaponType; - -public class CUnitAttackMissileSplash extends CUnitAttackMissile { - private int areaOfEffectFullDamage; - private int areaOfEffectMediumDamage; - private int areaOfEffectSmallDamage; - private EnumSet areaOfEffectTargets; - private float damageFactorMedium; - private float damageFactorSmall; - - public CUnitAttackMissileSplash(final float animationBackswingPoint, final float animationDamagePoint, - final CAttackType attackType, final float cooldownTime, final int damageBase, final int damageDice, - final int damageSidesPerDie, final int damageUpgradeAmount, final int range, final float rangeMotionBuffer, - final boolean showUI, final EnumSet targetsAllowed, final String weaponSound, - final CWeaponType weaponType, final float projectileArc, final String projectileArt, - final boolean projectileHomingEnabled, final int projectileSpeed, final int areaOfEffectFullDamage, - final int areaOfEffectMediumDamage, final int areaOfEffectSmallDamage, - final EnumSet areaOfEffectTargets, final float damageFactorMedium, - final float damageFactorSmall) { - super(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime, damageBase, damageDice, - damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound, - weaponType, projectileArc, projectileArt, projectileHomingEnabled, projectileSpeed); - this.areaOfEffectFullDamage = areaOfEffectFullDamage; - this.areaOfEffectMediumDamage = areaOfEffectMediumDamage; - this.areaOfEffectSmallDamage = areaOfEffectSmallDamage; - this.areaOfEffectTargets = areaOfEffectTargets; - this.damageFactorMedium = damageFactorMedium; - this.damageFactorSmall = damageFactorSmall; - } - - @Override - public CUnitAttack copy() { - return new CUnitAttackMissileSplash(getAnimationBackswingPoint(), getAnimationDamagePoint(), getAttackType(), - getCooldownTime(), getDamageBase(), getDamageDice(), getDamageSidesPerDie(), getDamageUpgradeAmount(), - getRange(), getRangeMotionBuffer(), isShowUI(), getTargetsAllowed(), getWeaponSound(), getWeaponType(), - getProjectileArc(), getProjectileArt(), isProjectileHomingEnabled(), getProjectileSpeed(), - this.areaOfEffectFullDamage, this.areaOfEffectMediumDamage, this.areaOfEffectSmallDamage, - this.areaOfEffectTargets, this.damageFactorMedium, this.damageFactorSmall); - } - - @Override - public int getRange() { - return super.getRange(); - } - - public int getAreaOfEffectFullDamage() { - return this.areaOfEffectFullDamage; - } - - public int getAreaOfEffectMediumDamage() { - return this.areaOfEffectMediumDamage; - } - - public int getAreaOfEffectSmallDamage() { - return this.areaOfEffectSmallDamage; - } - - public EnumSet getAreaOfEffectTargets() { - return this.areaOfEffectTargets; - } - - public float getDamageFactorMedium() { - return this.damageFactorMedium; - } - - public float getDamageFactorSmall() { - return this.damageFactorSmall; - } - - public void setAreaOfEffectFullDamage(final int areaOfEffectFullDamage) { - this.areaOfEffectFullDamage = areaOfEffectFullDamage; - } - - public void setAreaOfEffectMediumDamage(final int areaOfEffectMediumDamage) { - this.areaOfEffectMediumDamage = areaOfEffectMediumDamage; - } - - public void setAreaOfEffectSmallDamage(final int areaOfEffectSmallDamage) { - this.areaOfEffectSmallDamage = areaOfEffectSmallDamage; - } - - public void setAreaOfEffectTargets(final EnumSet areaOfEffectTargets) { - this.areaOfEffectTargets = areaOfEffectTargets; - } - - public void setDamageFactorMedium(final float damageFactorMedium) { - this.damageFactorMedium = damageFactorMedium; - } - - public void setDamageFactorSmall(final float damageFactorSmall) { - this.damageFactorSmall = damageFactorSmall; - } - - @Override - public void doDamage(final CSimulation cSimulation, final CUnit source, final AbilityTarget target, - final float damage, final float x, final float y, final int bounceIndex, - final CUnitAttackListener attackListener) { - SplashDamageConsumer.INSTANCE.doDamage(cSimulation, source, target, this, x, y, damage, attackListener); - if ((getWeaponType() != CWeaponType.ARTILLERY) && !SplashDamageConsumer.INSTANCE.hitTarget) { - float originalTargetDamage = damage; - if (Math.abs(this.damageFactorSmall) > 0.0001) { - originalTargetDamage *= this.damageFactorSmall; - } - super.doDamage(cSimulation, source, target, originalTargetDamage, x, y, bounceIndex, attackListener); - } - } - - private static final class SplashDamageConsumer implements CUnitEnumFunction { - private static final SplashDamageConsumer INSTANCE = new SplashDamageConsumer(); - private final Rectangle rect = new Rectangle(); - private CUnitAttackMissileSplash attack; - private CSimulation simulation; - private CUnit source; - private AbilityTarget target; - private float x; - private float y; - private float damage; - private CUnitAttackListener attackListener; - private boolean hitTarget; - - public void doDamage(final CSimulation simulation, final CUnit source, final AbilityTarget target, - final CUnitAttackMissileSplash attack, final float x, final float y, final float damage, - final CUnitAttackListener attackListener) { - this.simulation = simulation; - this.source = source; - this.target = target; - this.attack = attack; - this.x = x; - this.y = y; - this.damage = damage; - this.attackListener = attackListener; - this.hitTarget = false; - final float doubleMaxArea = (attack.areaOfEffectSmallDamage) * 2; - final float maxArea = doubleMaxArea / 2; - this.rect.set(x - maxArea, y - maxArea, doubleMaxArea, doubleMaxArea); - simulation.getWorldCollision().enumUnitsInRect(this.rect, this); - } - - @Override - public boolean call(final CUnit enumUnit) { - if (enumUnit.canBeTargetedBy(this.simulation, this.source, this.attack.areaOfEffectTargets)) { - final double distance = enumUnit.distance(this.x, this.y); - if (distance <= (this.attack.areaOfEffectFullDamage)) { - enumUnit.damage(this.simulation, this.source, this.attack.getAttackType(), - this.attack.getWeaponSound(), this.damage); - this.attackListener.onHit(enumUnit, this.damage); - } - else if (distance <= (this.attack.areaOfEffectMediumDamage)) { - enumUnit.damage(this.simulation, this.source, this.attack.getAttackType(), - this.attack.getWeaponSound(), this.damage * this.attack.damageFactorMedium); - this.attackListener.onHit(enumUnit, this.damage); - } - else if (distance <= (this.attack.areaOfEffectSmallDamage)) { - enumUnit.damage(this.simulation, this.source, this.attack.getAttackType(), - this.attack.getWeaponSound(), this.damage * this.attack.damageFactorSmall); - this.attackListener.onHit(enumUnit, this.damage); - } - if (enumUnit == this.target) { - this.hitTarget = true; - } - } - return false; - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackNormal.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackNormal.java deleted file mode 100644 index 301070c9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/attacks/CUnitAttackNormal.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks; - -import java.util.EnumSet; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetWidgetVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CWeaponType; - -public class CUnitAttackNormal extends CUnitAttack { - - public CUnitAttackNormal(final float animationBackswingPoint, final float animationDamagePoint, - final CAttackType attackType, final float cooldownTime, final int damageBase, final int damageDice, - final int damageSidesPerDie, final int damageUpgradeAmount, final int range, final float rangeMotionBuffer, - final boolean showUI, final EnumSet targetsAllowed, final String weaponSound, - final CWeaponType weaponType) { - super(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime, damageBase, damageDice, - damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound, - weaponType); - } - - @Override - public CUnitAttack copy() { - return new CUnitAttackNormal(getAnimationBackswingPoint(), getAnimationDamagePoint(), getAttackType(), - getCooldownTime(), getDamageBase(), getDamageDice(), getDamageSidesPerDie(), getDamageUpgradeAmount(), - getRange(), getRangeMotionBuffer(), isShowUI(), getTargetsAllowed(), getWeaponSound(), getWeaponType()); - } - - @Override - public void launch(final CSimulation simulation, final CUnit unit, final AbilityTarget target, final float damage, - final CUnitAttackListener attackListener) { - attackListener.onLaunch(); - final CWidget widget = target.visit(AbilityTargetWidgetVisitor.INSTANCE); - if (widget != null) { - widget.damage(simulation, unit, getAttackType(), getWeaponSound(), damage); - attackListener.onHit(target, damage); - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/projectile/CAttackProjectile.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/projectile/CAttackProjectile.java deleted file mode 100644 index 58013db7..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/combat/projectile/CAttackProjectile.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.projectile; - -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CWeaponType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissile; - -public class CAttackProjectile { - private float x; - private float y; - private final float initialTargetX; - private final float initialTargetY; - private final float speed; - private final AbilityTarget target; - private boolean done; - private final CUnit source; - private final float damage; - private final CUnitAttackMissile unitAttack; - private final int bounceIndex; - private final CUnitAttackListener attackListener; - - public CAttackProjectile(final float x, final float y, final float speed, final AbilityTarget target, - final CUnit source, final float damage, final CUnitAttackMissile unitAttack, final int bounceIndex, - final CUnitAttackListener attackListener) { - this.x = x; - this.y = y; - this.speed = speed; - this.target = target; - this.source = source; - this.damage = damage; - this.unitAttack = unitAttack; - this.bounceIndex = bounceIndex; - this.attackListener = attackListener; - this.initialTargetX = target.getX(); - this.initialTargetY = target.getY(); - } - - public boolean update(final CSimulation cSimulation) { - final float tx = getTargetX(); - final float ty = getTargetY(); - final float sx = this.x; - final float sy = this.y; - final float dtsx = tx - sx; - final float dtsy = ty - sy; - final float c = (float) Math.sqrt((dtsx * dtsx) + (dtsy * dtsy)); - - final float d1x = dtsx / c; - final float d1y = dtsy / c; - - float travelDistance = Math.min(c, this.speed * WarsmashConstants.SIMULATION_STEP_TIME); - final boolean done = c <= travelDistance; - if (done) { - travelDistance = c; - } - - final float dx = d1x * travelDistance; - final float dy = d1y * travelDistance; - - this.x = this.x + dx; - this.y = this.y + dy; - - if (done && !this.done) { - this.unitAttack.doDamage(cSimulation, this.source, this.target, this.damage, this.x, this.y, - this.bounceIndex, this.attackListener); - this.done = true; - } - return this.done; - } - - public float getX() { - return this.x; - } - - public float getY() { - return this.y; - } - - public float getSpeed() { - return this.speed; - } - - public AbilityTarget getTarget() { - return this.target; - } - - public boolean isDone() { - return this.done; - } - - public CUnitAttackMissile getUnitAttack() { - return this.unitAttack; - } - - public float getTargetX() { - if (this.unitAttack.isProjectileHomingEnabled() && (this.unitAttack.getWeaponType() != CWeaponType.ARTILLERY)) { - return this.target.getX(); - } - else { - return this.initialTargetX; - } - } - - public float getTargetY() { - if (this.unitAttack.isProjectileHomingEnabled() && (this.unitAttack.getWeaponType() != CWeaponType.ARTILLERY)) { - return this.target.getY(); - } - else { - return this.initialTargetY; - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CBasePlayer.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CBasePlayer.java deleted file mode 100644 index 37090932..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CBasePlayer.java +++ /dev/null @@ -1,187 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.config; - -import java.util.EnumMap; -import java.util.EnumSet; - -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CAllianceType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapControl; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerJass; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerState; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRacePreference; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CPlayerSlotState; - -public abstract class CBasePlayer implements CPlayerJass { - private final int id; - private String name; - private int team; - private int startLocationIndex; - private int forcedStartLocationIndex = -1; - private int color; - private final EnumSet racePrefs; - private final EnumSet[] alliances; - private final EnumMap[] taxRates; - private boolean onScoreScreen; - private boolean raceSelectable; - private CMapControl mapControl = CMapControl.NEUTRAL; - private CPlayerSlotState slotState = CPlayerSlotState.EMPTY; - - public CBasePlayer(final CBasePlayer other) { - this.id = other.id; - this.name = other.name; - this.team = other.team; - this.startLocationIndex = other.startLocationIndex; - this.forcedStartLocationIndex = other.forcedStartLocationIndex; - this.color = other.color; - this.racePrefs = other.racePrefs; - this.alliances = other.alliances; - this.taxRates = other.taxRates; - this.onScoreScreen = other.onScoreScreen; - this.raceSelectable = other.raceSelectable; - this.mapControl = other.mapControl; - this.slotState = other.slotState; - } - - public CBasePlayer(final int id) { - this.id = id; - this.alliances = new EnumSet[WarsmashConstants.MAX_PLAYERS]; - this.taxRates = new EnumMap[WarsmashConstants.MAX_PLAYERS]; - this.racePrefs = EnumSet.noneOf(CRacePreference.class); - for (int i = 0; i < this.alliances.length; i++) { - if (i == id) { - // player is fully allied with self - this.alliances[i] = EnumSet.allOf(CAllianceType.class); - } - else { - this.alliances[i] = EnumSet.noneOf(CAllianceType.class); - } - this.taxRates[i] = new EnumMap<>(CPlayerState.class); - } - } - - @Override - public int getId() { - return this.id; - } - - @Override - public void setName(final String name) { - this.name = name; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public void setOnScoreScreen(final boolean onScoreScreen) { - this.onScoreScreen = onScoreScreen; - } - - public boolean isOnScoreScreen() { - return this.onScoreScreen; - } - - @Override - public void setRaceSelectable(final boolean raceSelectable) { - this.raceSelectable = raceSelectable; - } - - @Override - public void setTeam(final int team) { - this.team = team; - } - - @Override - public int getTeam() { - return this.team; - } - - @Override - public int getStartLocationIndex() { - return this.startLocationIndex; - } - - @Override - public void setStartLocationIndex(final int startLocationIndex) { - this.startLocationIndex = startLocationIndex; - } - - @Override - public void setColor(final int color) { - this.color = color; - } - - @Override - public int getColor() { - return this.color; - } - - @Override - public boolean isRacePrefSet(final CRacePreference racePref) { - return this.racePrefs.contains(racePref); - } - - @Override - public void setRacePref(final CRacePreference racePref) { - this.racePrefs.add(racePref); - } - - @Override - public void setAlliance(final int otherPlayerIndex, final CAllianceType allianceType, final boolean value) { - final EnumSet alliancesWithOtherPlayer = this.alliances[otherPlayerIndex]; - if (value) { - alliancesWithOtherPlayer.add(allianceType); - } - else { - alliancesWithOtherPlayer.remove(allianceType); - } - } - - @Override - public boolean hasAlliance(final int otherPlayerIndex, final CAllianceType allianceType) { - final EnumSet alliancesWithOtherPlayer = this.alliances[otherPlayerIndex]; - return alliancesWithOtherPlayer.contains(allianceType); - } - - @Override - public void forceStartLocation(final int startLocIndex) { - this.forcedStartLocationIndex = startLocIndex; - } - - @Override - public void setTaxRate(final int otherPlayerIndex, final CPlayerState whichResource, final int rate) { - this.taxRates[otherPlayerIndex].put(whichResource, rate); - } - - @Override - public void setController(final CMapControl mapControl) { - this.mapControl = mapControl; - - } - - @Override - public boolean isSelectable() { - return this.raceSelectable; - } - - @Override - public CMapControl getController() { - return this.mapControl; - } - - @Override - public CPlayerSlotState getSlotState() { - return this.slotState; - } - - @Override - public int getTaxRate(final int otherPlayerIndex, final CPlayerState whichResource) { - final Integer taxRate = this.taxRates[otherPlayerIndex].get(whichResource); - if (taxRate == null) { - return 0; - } - return taxRate; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CPlayerAPI.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CPlayerAPI.java deleted file mode 100644 index 61baa4f0..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/CPlayerAPI.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.config; - -public interface CPlayerAPI { - CBasePlayer getPlayer(int index); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfig.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfig.java deleted file mode 100644 index d38e396e..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfig.java +++ /dev/null @@ -1,153 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.config; - -import java.util.EnumMap; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapFlag; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CMapPlacement; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CGameSpeed; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CGameType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CMapDensity; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CMapDifficulty; - -public class War3MapConfig implements CPlayerAPI { - private String mapName; - private String mapDescription; - private int teamCount; - private int playerCount; - private final War3MapConfigStartLoc[] startLocations; - private final CBasePlayer[] players; - private final EnumMap gameTypeToSupported = new EnumMap<>(CGameType.class); - private final EnumMap mapFlagToEnabled = new EnumMap<>(CMapFlag.class); - private CMapPlacement placement; - private CGameSpeed gameSpeed; - private CMapDifficulty gameDifficulty; - private CMapDensity resourceDensity; - private CMapDensity creatureDensity; - private CGameType gameTypeSelected; - - public War3MapConfig(final int maxPlayers) { - this.startLocations = new War3MapConfigStartLoc[maxPlayers]; - this.players = new CBasePlayer[maxPlayers]; - for (int i = 0; i < maxPlayers; i++) { - this.startLocations[i] = new War3MapConfigStartLoc(); - this.players[i] = new War3MapConfigPlayer(i); - } - } - - public void setMapName(final String mapName) { - this.mapName = mapName; - } - - public void setMapDescription(final String mapDescription) { - this.mapDescription = mapDescription; - } - - public String getMapName() { - return this.mapName; - } - - public String getMapDescription() { - return this.mapDescription; - } - - public void setTeamCount(final int teamCount) { - this.teamCount = teamCount; - } - - public void setPlayerCount(final int playerCount) { - this.playerCount = playerCount; - } - - public void defineStartLocation(final int whichStartLoc, final float x, final float y) { - final War3MapConfigStartLoc startLoc = this.startLocations[whichStartLoc]; - startLoc.setX(x); - startLoc.setY(y); - } - - public War3MapConfigStartLoc getStartLoc(final int whichStartLoc) { - return this.startLocations[whichStartLoc]; - } - - public void setGameTypeSupported(final CGameType gameType, final boolean supported) { - this.gameTypeToSupported.put(gameType, supported); - } - - public void setMapFlag(final CMapFlag mapFlag, final boolean set) { - this.mapFlagToEnabled.put(mapFlag, set); - } - - public void setPlacement(final CMapPlacement placement) { - this.placement = placement; - } - - public void setGameSpeed(final CGameSpeed gameSpeed) { - this.gameSpeed = gameSpeed; - } - - public void setGameDifficulty(final CMapDifficulty gameDifficulty) { - this.gameDifficulty = gameDifficulty; - } - - public void setResourceDensity(final CMapDensity resourceDensity) { - this.resourceDensity = resourceDensity; - } - - public void setCreatureDensity(final CMapDensity creatureDensity) { - this.creatureDensity = creatureDensity; - } - - public int getTeamCount() { - return this.teamCount; - } - - public int getPlayerCount() { - return this.playerCount; - } - - public boolean isGameTypeSupported(final CGameType gameType) { - final Boolean supported = this.gameTypeToSupported.get(gameType); - return (supported != null) && supported; - } - - public CGameType getGameTypeSelected() { - return this.gameTypeSelected; - } - - public boolean isMapFlagSet(final CMapFlag mapFlag) { - final Boolean flag = this.mapFlagToEnabled.get(mapFlag); - return (flag != null) && flag; - } - - public CMapPlacement getPlacement() { - return this.placement; - } - - public CGameSpeed getGameSpeed() { - return this.gameSpeed; - } - - public CMapDifficulty getGameDifficulty() { - return this.gameDifficulty; - } - - public CMapDensity getResourceDensity() { - return this.resourceDensity; - } - - public CMapDensity getCreatureDensity() { - return this.creatureDensity; - } - - public float getStartLocationX(final int startLocIndex) { - return this.startLocations[startLocIndex].getX(); - } - - public float getStartLocationY(final int startLocIndex) { - return this.startLocations[startLocIndex].getY(); - } - - @Override - public CBasePlayer getPlayer(final int index) { - return this.players[index]; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfigPlayer.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfigPlayer.java deleted file mode 100644 index ec7647f8..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfigPlayer.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.config; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.trigger.RemovableTriggerEvent; -import com.etheller.interpreter.ast.scope.trigger.Trigger; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerEvent; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.JassGameEventsWar3; - -public class War3MapConfigPlayer extends CBasePlayer { - - public War3MapConfigPlayer(final CBasePlayer other) { - super(other); - } - - public War3MapConfigPlayer(final int id) { - super(id); - } - - @Override - public RemovableTriggerEvent addEvent(final GlobalScope globalScope, final Trigger whichTrigger, - final JassGameEventsWar3 eventType) { - return RemovableTriggerEvent.DO_NOTHING; - } - - @Override - public void removeEvent(final CPlayerEvent playerEvent) { - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfigStartLoc.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfigStartLoc.java deleted file mode 100644 index 281eb768..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/config/War3MapConfigStartLoc.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.config; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CStartLocPrio; - -public class War3MapConfigStartLoc { - private float x; - private float y; - private int[] otherStartIndices; - private CStartLocPrio[] otherStartLocPriorities; - - public void setX(final float x) { - this.x = x; - } - - public void setY(final float y) { - this.y = y; - } - - public float getX() { - return this.x; - } - - public float getY() { - return this.y; - } - - public int[] getOtherStartIndices() { - return this.otherStartIndices; - } - - public CStartLocPrio[] getOtherStartLocPriorities() { - return this.otherStartLocPriorities; - } - - public void setStartLocPrioCount(final int startLocPrioCount) { - this.otherStartIndices = new int[startLocPrioCount]; - this.otherStartLocPriorities = new CStartLocPrio[startLocPrioCount]; - } - - public void setStartLocPrio(final int prioSlotIndex, final int otherStartLocIndex, final CStartLocPrio priority) { - this.otherStartIndices[prioSlotIndex] = otherStartLocIndex; - this.otherStartLocPriorities[prioSlotIndex] = priority; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CAbilityData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CAbilityData.java deleted file mode 100644 index 4533bdfc..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CAbilityData.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.data; - -import java.util.HashMap; -import java.util.Map; - -import com.etheller.warsmash.units.manager.MutableObjectData; -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGeneric; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.CAbilityType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.CAbilityTypeDefinition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionChannelTest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionColdArrows; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionCoupleInstant; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionGoldMine; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHarvest; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHarvestLumber; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionHumanRepair; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionInventory; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionInvulnerable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionItemAttackBonus; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionItemHeal; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.types.definitions.impl.CAbilityTypeDefinitionReturnResources; - -public class CAbilityData { - - private final MutableObjectData abilityData; - private Map> aliasToAbilityType = new HashMap<>(); - private final Map codeToAbilityTypeDefinition = new HashMap<>(); - - public CAbilityData(final MutableObjectData abilityData) { - this.abilityData = abilityData; - this.aliasToAbilityType = new HashMap<>(); - registerCodes(); - } - - private void registerCodes() { - this.codeToAbilityTypeDefinition.put(War3ID.fromString("ACcw"), new CAbilityTypeDefinitionColdArrows()); - this.codeToAbilityTypeDefinition.put(War3ID.fromString("Agld"), new CAbilityTypeDefinitionGoldMine()); - this.codeToAbilityTypeDefinition.put(War3ID.fromString("Artn"), new CAbilityTypeDefinitionReturnResources()); - this.codeToAbilityTypeDefinition.put(War3ID.fromString("Ahar"), new CAbilityTypeDefinitionHarvest()); - this.codeToAbilityTypeDefinition.put(War3ID.fromString("Ahrl"), new CAbilityTypeDefinitionHarvestLumber()); - this.codeToAbilityTypeDefinition.put(War3ID.fromString("ANcl"), new CAbilityTypeDefinitionChannelTest()); - this.codeToAbilityTypeDefinition.put(War3ID.fromString("AInv"), new CAbilityTypeDefinitionInventory()); - this.codeToAbilityTypeDefinition.put(War3ID.fromString("Arep"), new CAbilityTypeDefinitionHumanRepair()); - this.codeToAbilityTypeDefinition.put(War3ID.fromString("Avul"), new CAbilityTypeDefinitionInvulnerable()); - this.codeToAbilityTypeDefinition.put(War3ID.fromString("Acoi"), new CAbilityTypeDefinitionCoupleInstant()); - this.codeToAbilityTypeDefinition.put(War3ID.fromString("AIhe"), new CAbilityTypeDefinitionItemHeal()); - this.codeToAbilityTypeDefinition.put(War3ID.fromString("AIat"), new CAbilityTypeDefinitionItemAttackBonus()); - } - - public CAbilityType getAbilityType(final War3ID alias) { - CAbilityType abilityType = this.aliasToAbilityType.get(alias); - if (abilityType == null) { - final MutableGameObject mutableGameObject = this.abilityData.get(alias); - if (mutableGameObject == null) { - return null; - } - final War3ID code = War3ID.fromString(mutableGameObject.readSLKTag("code")); - final CAbilityTypeDefinition abilityTypeDefinition = this.codeToAbilityTypeDefinition.get(code); - if (abilityTypeDefinition != null) { - abilityType = abilityTypeDefinition.createAbilityType(alias, mutableGameObject); - this.aliasToAbilityType.put(alias, abilityType); - } - } - return abilityType; - } - - public CAbility createAbility(final String ability, final int handleId) { - final War3ID war3Id = War3ID.fromString(ability.trim()); - final CAbilityType abilityType = getAbilityType(war3Id); - if (abilityType != null) { - return abilityType.createAbility(handleId); - } - return new CAbilityGeneric(war3Id, handleId); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CDestructableData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CDestructableData.java deleted file mode 100644 index a14bf8e1..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CDestructableData.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.data; - -import java.awt.image.BufferedImage; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.Map; - -import com.etheller.warsmash.units.manager.MutableObjectData; -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.RemovablePathingMapInstance; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructableType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.HandleIdAllocator; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController; - -public class CDestructableData { - private static final War3ID NAME = War3ID.fromString("bnam"); - private static final War3ID HIT_POINT_MAXIMUM = War3ID.fromString("bhps"); - private static final War3ID TARGETED_AS = War3ID.fromString("btar"); - private static final War3ID ARMOR_TYPE = War3ID.fromString("barm"); - - private static final War3ID BUILD_TIME = War3ID.fromString("bbut"); - private static final War3ID REPAIR_TIME = War3ID.fromString("bret"); - private static final War3ID GOLD_REPAIR = War3ID.fromString("breg"); - private static final War3ID LUMBER_REPAIR = War3ID.fromString("brel"); - - private final MutableObjectData unitData; - private final Map unitIdToUnitType = new HashMap<>(); - private final SimulationRenderController simulationRenderController; - - public CDestructableData(final MutableObjectData unitData, - final SimulationRenderController simulationRenderController) { - this.unitData = unitData; - this.simulationRenderController = simulationRenderController; - } - - public CDestructable create(final CSimulation simulation, final War3ID typeId, final float x, final float y, - final HandleIdAllocator handleIdAllocator, final RemovablePathingMapInstance pathingInstance, - final RemovablePathingMapInstance pathingInstanceDeath) { - final MutableGameObject unitType = this.unitData.get(typeId); - final int handleId = handleIdAllocator.createId(); - - final CDestructableType unitTypeInstance = getUnitTypeInstance(typeId, unitType); - - final float life = unitTypeInstance.getMaxLife(); - - final CDestructable destructable = new CDestructable(handleId, x, y, life, unitTypeInstance, pathingInstance, - pathingInstanceDeath); - return destructable; - } - - private CDestructableType getUnitTypeInstance(final War3ID typeId, final MutableGameObject unitType) { - CDestructableType unitTypeInstance = this.unitIdToUnitType.get(typeId); - if (unitTypeInstance == null) { - final BufferedImage buildingPathingPixelMap = this.simulationRenderController - .getDestructablePathingPixelMap(typeId); - final BufferedImage buildingPathingDeathPixelMap = this.simulationRenderController - .getDestructablePathingDeathPixelMap(typeId); - final String name = unitType.getFieldAsString(NAME, 0); - final float life = unitType.getFieldAsFloat(HIT_POINT_MAXIMUM, 0); - final EnumSet targetedAs = CTargetType - .parseTargetTypeSet(unitType.getFieldAsString(TARGETED_AS, 0)); - final String armorType = unitType.getFieldAsString(ARMOR_TYPE, 0); - final int buildTime = unitType.getFieldAsInteger(BUILD_TIME, 0); - - unitTypeInstance = new CDestructableType(name, life, targetedAs, armorType, buildTime, - buildingPathingPixelMap, buildingPathingDeathPixelMap); - this.unitIdToUnitType.put(typeId, unitTypeInstance); - } - return unitTypeInstance; - } - - public CDestructableType getUnitType(final War3ID rawcode) { - final CDestructableType unitTypeInstance = this.unitIdToUnitType.get(rawcode); - if (unitTypeInstance != null) { - return unitTypeInstance; - } - final MutableGameObject unitType = this.unitData.get(rawcode); - if (unitType == null) { - return null; - } - return getUnitTypeInstance(rawcode, unitType); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CItemData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CItemData.java deleted file mode 100644 index ab7d0929..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CItemData.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.data; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.etheller.warsmash.units.manager.MutableObjectData; -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItemType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; - -public class CItemData { - private static final War3ID ABILITY_LIST = War3ID.fromString("iabi"); - private static final War3ID COOLDOWN_GROUP = War3ID.fromString("icid"); - private static final War3ID IGNORE_COOLDOWN = War3ID.fromString("iicd"); - private static final War3ID NUMBER_OF_CHARGES = War3ID.fromString("iuse"); - private static final War3ID ACTIVELY_USED = War3ID.fromString("iusa"); - private static final War3ID PERISHABLE = War3ID.fromString("iper"); - private static final War3ID USE_AUTOMATICALLY_WHEN_ACQUIRED = War3ID.fromString("ipow"); - - private static final War3ID GOLD_COST = War3ID.fromString("igol"); - private static final War3ID LUMBER_COST = War3ID.fromString("ilum"); - private static final War3ID STOCK_MAX = War3ID.fromString("isto"); - private static final War3ID STOCK_REPLENISH_INTERVAL = War3ID.fromString("istr"); - private static final War3ID STOCK_START_DELAY = War3ID.fromString("isst"); - - private static final War3ID HIT_POINTS = War3ID.fromString("ihtp"); - private static final War3ID ARMOR_TYPE = War3ID.fromString("iarm"); - - private static final War3ID LEVEL = War3ID.fromString("ilev"); - private static final War3ID LEVEL_UNCLASSIFIED = War3ID.fromString("ilvo"); - private static final War3ID PRIORITY = War3ID.fromString("ipri"); - - private static final War3ID SELLABLE = War3ID.fromString("isel"); - private static final War3ID PAWNABLE = War3ID.fromString("ipaw"); - - private static final War3ID DROPPED_WHEN_CARRIER_DIES = War3ID.fromString("idrp"); - private static final War3ID CAN_BE_DROPPED = War3ID.fromString("idro"); - - private static final War3ID VALID_TARGET_FOR_TRANSFORMATION = War3ID.fromString("imor"); - private static final War3ID INCLUDE_AS_RANDOM_CHOICE = War3ID.fromString("iprn"); - - private final Map itemIdToItemType = new HashMap<>(); - private final MutableObjectData itemData; - - public CItemData(final MutableObjectData itemData) { - this.itemData = itemData; - } - - public CItem create(final CSimulation simulation, final War3ID typeId, final float x, final float y, - final int handleId) { - final MutableGameObject itemType = this.itemData.get(typeId); - final CItemType itemTypeInstance = getItemTypeInstance(typeId, itemType); - - return new CItem(handleId, x, y, itemTypeInstance.getMaxLife(), typeId, itemTypeInstance); - } - - public CItemType getItemType(final War3ID typeId) { - final MutableGameObject itemType = this.itemData.get(typeId); - if (itemType == null) { - return null; - } - return getItemTypeInstance(typeId, itemType); - } - - private CItemType getItemTypeInstance(final War3ID typeId, final MutableGameObject itemType) { - CItemType itemTypeInstance = this.itemIdToItemType.get(typeId); - if (itemTypeInstance == null) { - final String abilityListString = itemType.getFieldAsString(ABILITY_LIST, 0); - final String[] abilityListStringItems = abilityListString.split(","); - final List abilityList = new ArrayList<>(); - for (final String abilityListStringItem : abilityListStringItems) { - if (abilityListStringItem.length() == 4) { - abilityList.add(War3ID.fromString(abilityListStringItem)); - } - } - - final War3ID cooldownGroup; - final String cooldownGroupString = itemType.getFieldAsString(COOLDOWN_GROUP, 0); - if ((cooldownGroupString != null) && (cooldownGroupString.length() == 4)) { - cooldownGroup = War3ID.fromString(cooldownGroupString); - } - else { - cooldownGroup = null; - } - final boolean ignoreCooldown = itemType.getFieldAsBoolean(IGNORE_COOLDOWN, 0); - final int numberOfCharges = itemType.getFieldAsInteger(NUMBER_OF_CHARGES, 0); - final boolean activelyUsed = itemType.getFieldAsBoolean(ACTIVELY_USED, 0); - final boolean perishable = itemType.getFieldAsBoolean(PERISHABLE, 0); - final boolean useAutomaticallyWhenAcquired = itemType.getFieldAsBoolean(USE_AUTOMATICALLY_WHEN_ACQUIRED, 0); - - final int goldCost = itemType.getFieldAsInteger(GOLD_COST, 0); - final int lumberCost = itemType.getFieldAsInteger(LUMBER_COST, 0); - final int stockMax = itemType.getFieldAsInteger(STOCK_MAX, 0); - final int stockReplenishInterval = itemType.getFieldAsInteger(STOCK_REPLENISH_INTERVAL, 0); - final int stockStartDelay = itemType.getFieldAsInteger(STOCK_START_DELAY, 0); - - final int hitPoints = itemType.getFieldAsInteger(HIT_POINTS, 0); - final String armorType = itemType.getFieldAsString(ARMOR_TYPE, 0); - - final int level = itemType.getFieldAsInteger(LEVEL, 0); - final int levelUnclassified = itemType.getFieldAsInteger(LEVEL_UNCLASSIFIED, 0); - final int priority = itemType.getFieldAsInteger(PRIORITY, 0); - - final boolean sellable = itemType.getFieldAsBoolean(SELLABLE, 0); - final boolean pawnable = itemType.getFieldAsBoolean(PAWNABLE, 0); - - final boolean droppedWhenCarrierDies = itemType.getFieldAsBoolean(DROPPED_WHEN_CARRIER_DIES, 0); - final boolean canBeDropped = itemType.getFieldAsBoolean(CAN_BE_DROPPED, 0); - - final boolean validTargetForTransformation = itemType.getFieldAsBoolean(VALID_TARGET_FOR_TRANSFORMATION, 0); - final boolean includeAsRandomChoice = itemType.getFieldAsBoolean(INCLUDE_AS_RANDOM_CHOICE, 0); - - itemTypeInstance = new CItemType(abilityList, cooldownGroup, ignoreCooldown, numberOfCharges, activelyUsed, - perishable, useAutomaticallyWhenAcquired, goldCost, lumberCost, stockMax, stockReplenishInterval, - stockStartDelay, hitPoints, armorType, level, levelUnclassified, priority, sellable, pawnable, - droppedWhenCarrierDies, canBeDropped, validTargetForTransformation, includeAsRandomChoice); - this.itemIdToItemType.put(typeId, itemTypeInstance); - } - return itemTypeInstance; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitData.java deleted file mode 100644 index abfb4e45..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitData.java +++ /dev/null @@ -1,756 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.data; - -import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.etheller.warsmash.units.manager.MutableObjectData; -import com.etheller.warsmash.units.manager.MutableObjectData.MutableGameObject; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.MovementType; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.RemovablePathingMapInstance; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CGameplayConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitClassification; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitTypeRequirement; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.HandleIdAllocator; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityMove; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNagaBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNightElfBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityOrcBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityUndeadBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CAbilityHero; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CPrimaryAttribute; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityQueue; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityRally; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityReviveHero; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CDefenseType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CTargetType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CWeaponType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackInstant; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissile; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissileBounce; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissileLine; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissileSplash; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackNormal; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CBuildingPathingType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.SimulationRenderController; - -public class CUnitData { - private static final War3ID MANA_INITIAL_AMOUNT = War3ID.fromString("umpi"); - private static final War3ID MANA_MAXIMUM = War3ID.fromString("umpm"); - private static final War3ID HIT_POINT_MAXIMUM = War3ID.fromString("uhpm"); - private static final War3ID MOVEMENT_SPEED_BASE = War3ID.fromString("umvs"); - private static final War3ID PROPULSION_WINDOW = War3ID.fromString("uprw"); - private static final War3ID TURN_RATE = War3ID.fromString("umvr"); - private static final War3ID IS_BLDG = War3ID.fromString("ubdg"); - private static final War3ID NAME = War3ID.fromString("unam"); - private static final War3ID PROPER_NAMES = War3ID.fromString("upro"); - private static final War3ID PROPER_NAMES_COUNT = War3ID.fromString("upru"); - private static final War3ID PROJECTILE_LAUNCH_X = War3ID.fromString("ulpx"); - private static final War3ID PROJECTILE_LAUNCH_Y = War3ID.fromString("ulpy"); - private static final War3ID PROJECTILE_LAUNCH_Z = War3ID.fromString("ulpz"); - private static final War3ID ATTACKS_ENABLED = War3ID.fromString("uaen"); - private static final War3ID ATTACK1_BACKSWING_POINT = War3ID.fromString("ubs1"); - private static final War3ID ATTACK1_DAMAGE_POINT = War3ID.fromString("udp1"); - private static final War3ID ATTACK1_AREA_OF_EFFECT_FULL_DMG = War3ID.fromString("ua1f"); - private static final War3ID ATTACK1_AREA_OF_EFFECT_HALF_DMG = War3ID.fromString("ua1h"); - private static final War3ID ATTACK1_AREA_OF_EFFECT_QUARTER_DMG = War3ID.fromString("ua1q"); - private static final War3ID ATTACK1_AREA_OF_EFFECT_TARGETS = War3ID.fromString("ua1p"); - private static final War3ID ATTACK1_ATTACK_TYPE = War3ID.fromString("ua1t"); - private static final War3ID ATTACK1_COOLDOWN = War3ID.fromString("ua1c"); - private static final War3ID ATTACK1_DMG_BASE = War3ID.fromString("ua1b"); - private static final War3ID ATTACK1_DAMAGE_FACTOR_HALF = War3ID.fromString("uhd1"); - private static final War3ID ATTACK1_DAMAGE_FACTOR_QUARTER = War3ID.fromString("uqd1"); - private static final War3ID ATTACK1_DAMAGE_LOSS_FACTOR = War3ID.fromString("udl1"); - private static final War3ID ATTACK1_DMG_DICE = War3ID.fromString("ua1d"); - private static final War3ID ATTACK1_DMG_SIDES_PER_DIE = War3ID.fromString("ua1s"); - private static final War3ID ATTACK1_DMG_SPILL_DIST = War3ID.fromString("usd1"); - private static final War3ID ATTACK1_DMG_SPILL_RADIUS = War3ID.fromString("usr1"); - private static final War3ID ATTACK1_DMG_UPGRADE_AMT = War3ID.fromString("udu1"); - private static final War3ID ATTACK1_TARGET_COUNT = War3ID.fromString("utc1"); - private static final War3ID ATTACK1_PROJECTILE_ARC = War3ID.fromString("uma1"); - private static final War3ID ATTACK1_MISSILE_ART = War3ID.fromString("ua1m"); - private static final War3ID ATTACK1_PROJECTILE_HOMING_ENABLED = War3ID.fromString("umh1"); - private static final War3ID ATTACK1_PROJECTILE_SPEED = War3ID.fromString("ua1z"); - private static final War3ID ATTACK1_RANGE = War3ID.fromString("ua1r"); - private static final War3ID ATTACK1_RANGE_MOTION_BUFFER = War3ID.fromString("urb1"); - private static final War3ID ATTACK1_SHOW_UI = War3ID.fromString("uwu1"); - private static final War3ID ATTACK1_TARGETS_ALLOWED = War3ID.fromString("ua1g"); - private static final War3ID ATTACK1_WEAPON_SOUND = War3ID.fromString("ucs1"); - private static final War3ID ATTACK1_WEAPON_TYPE = War3ID.fromString("ua1w"); - - private static final War3ID ATTACK2_BACKSWING_POINT = War3ID.fromString("ubs2"); - private static final War3ID ATTACK2_DAMAGE_POINT = War3ID.fromString("udp2"); - private static final War3ID ATTACK2_AREA_OF_EFFECT_FULL_DMG = War3ID.fromString("ua2f"); - private static final War3ID ATTACK2_AREA_OF_EFFECT_HALF_DMG = War3ID.fromString("ua2h"); - private static final War3ID ATTACK2_AREA_OF_EFFECT_QUARTER_DMG = War3ID.fromString("ua2q"); - private static final War3ID ATTACK2_AREA_OF_EFFECT_TARGETS = War3ID.fromString("ua2p"); - private static final War3ID ATTACK2_ATTACK_TYPE = War3ID.fromString("ua2t"); - private static final War3ID ATTACK2_COOLDOWN = War3ID.fromString("ua2c"); - private static final War3ID ATTACK2_DMG_BASE = War3ID.fromString("ua2b"); - private static final War3ID ATTACK2_DAMAGE_FACTOR_HALF = War3ID.fromString("uhd2"); - private static final War3ID ATTACK2_DAMAGE_FACTOR_QUARTER = War3ID.fromString("uqd2"); - private static final War3ID ATTACK2_DAMAGE_LOSS_FACTOR = War3ID.fromString("udl2"); - private static final War3ID ATTACK2_DMG_DICE = War3ID.fromString("ua2d"); - private static final War3ID ATTACK2_DMG_SIDES_PER_DIE = War3ID.fromString("ua2s"); - private static final War3ID ATTACK2_DMG_SPILL_DIST = War3ID.fromString("usd2"); - private static final War3ID ATTACK2_DMG_SPILL_RADIUS = War3ID.fromString("usr2"); - private static final War3ID ATTACK2_DMG_UPGRADE_AMT = War3ID.fromString("udu2"); - private static final War3ID ATTACK2_TARGET_COUNT = War3ID.fromString("utc2"); - private static final War3ID ATTACK2_PROJECTILE_ARC = War3ID.fromString("uma2"); - private static final War3ID ATTACK2_MISSILE_ART = War3ID.fromString("ua2m"); - private static final War3ID ATTACK2_PROJECTILE_HOMING_ENABLED = War3ID.fromString("umh2"); - private static final War3ID ATTACK2_PROJECTILE_SPEED = War3ID.fromString("ua2z"); - private static final War3ID ATTACK2_RANGE = War3ID.fromString("ua2r"); - private static final War3ID ATTACK2_RANGE_MOTION_BUFFER = War3ID.fromString("urb2"); - private static final War3ID ATTACK2_SHOW_UI = War3ID.fromString("uwu2"); - private static final War3ID ATTACK2_TARGETS_ALLOWED = War3ID.fromString("ua2g"); - private static final War3ID ATTACK2_WEAPON_SOUND = War3ID.fromString("ucs2"); - private static final War3ID ATTACK2_WEAPON_TYPE = War3ID.fromString("ua2w"); - - private static final War3ID ACQUISITION_RANGE = War3ID.fromString("uacq"); - private static final War3ID MINIMUM_ATTACK_RANGE = War3ID.fromString("uamn"); - - private static final War3ID PROJECTILE_IMPACT_Z = War3ID.fromString("uimz"); - - private static final War3ID DEATH_TYPE = War3ID.fromString("udea"); - private static final War3ID ARMOR_TYPE = War3ID.fromString("uarm"); - - private static final War3ID DEFENSE = War3ID.fromString("udef"); - private static final War3ID DEFENSE_TYPE = War3ID.fromString("udty"); - private static final War3ID MOVE_HEIGHT = War3ID.fromString("umvh"); - private static final War3ID MOVE_TYPE = War3ID.fromString("umvt"); - private static final War3ID COLLISION_SIZE = War3ID.fromString("ucol"); - private static final War3ID CLASSIFICATION = War3ID.fromString("utyp"); - private static final War3ID DEATH_TIME = War3ID.fromString("udtm"); - private static final War3ID TARGETED_AS = War3ID.fromString("utar"); - - private static final War3ID ABILITIES_NORMAL = War3ID.fromString("uabi"); - private static final War3ID ABILITIES_HERO = War3ID.fromString("uhab"); - - private static final War3ID STRUCTURES_BUILT = War3ID.fromString("ubui"); - private static final War3ID UNITS_TRAINED = War3ID.fromString("utra"); - private static final War3ID RESEARCHES_AVAILABLE = War3ID.fromString("ures"); - private static final War3ID REVIVES_HEROES = War3ID.fromString("urev"); - private static final War3ID UNIT_RACE = War3ID.fromString("urac"); - - private static final War3ID REQUIRES = War3ID.fromString("ureq"); - private static final War3ID REQUIRES_AMOUNT = War3ID.fromString("urqc"); - - private static final War3ID GOLD_COST = War3ID.fromString("ugol"); - private static final War3ID LUMBER_COST = War3ID.fromString("ulum"); - private static final War3ID BUILD_TIME = War3ID.fromString("ubld"); - private static final War3ID FOOD_USED = War3ID.fromString("ufoo"); - private static final War3ID FOOD_MADE = War3ID.fromString("ufma"); - - private static final War3ID REQUIRE_PLACE = War3ID.fromString("upar"); - private static final War3ID PREVENT_PLACE = War3ID.fromString("upap"); - - private static final War3ID UNIT_LEVEL = War3ID.fromString("ulev"); - - private static final War3ID STR = War3ID.fromString("ustr"); - private static final War3ID STR_PLUS = War3ID.fromString("ustp"); - private static final War3ID AGI = War3ID.fromString("uagi"); - private static final War3ID AGI_PLUS = War3ID.fromString("uagp"); - private static final War3ID INT = War3ID.fromString("uint"); - private static final War3ID INT_PLUS = War3ID.fromString("uinp"); - private static final War3ID PRIMARY_ATTRIBUTE = War3ID.fromString("upra"); - - private static final War3ID CAN_FLEE = War3ID.fromString("ufle"); - private static final War3ID PRIORITY = War3ID.fromString("upri"); - - private final CGameplayConstants gameplayConstants; - private final MutableObjectData unitData; - private final Map unitIdToUnitType = new HashMap<>(); - private final Map jassLegacyNameToUnitId = new HashMap<>(); - private final CAbilityData abilityData; - private final SimulationRenderController simulationRenderController; - - public CUnitData(final CGameplayConstants gameplayConstants, final MutableObjectData unitData, - final CAbilityData abilityData, final SimulationRenderController simulationRenderController) { - this.gameplayConstants = gameplayConstants; - this.unitData = unitData; - this.abilityData = abilityData; - this.simulationRenderController = simulationRenderController; - } - - public CUnit create(final CSimulation simulation, final int playerIndex, final War3ID typeId, final float x, - final float y, final float facing, final BufferedImage buildingPathingPixelMap, - final HandleIdAllocator handleIdAllocator, final RemovablePathingMapInstance pathingInstance) { - final MutableGameObject unitType = this.unitData.get(typeId); - final int handleId = handleIdAllocator.createId(); - - final CUnitType unitTypeInstance = getUnitTypeInstance(typeId, buildingPathingPixelMap, unitType); - final int life = unitTypeInstance.getMaxLife(); - final int manaInitial = unitTypeInstance.getManaInitial(); - final int manaMaximum = unitTypeInstance.getManaMaximum(); - final int speed = unitTypeInstance.getSpeed(); - - final CUnit unit = new CUnit(handleId, playerIndex, x, y, life, typeId, facing, manaInitial, life, manaMaximum, - speed, unitTypeInstance, pathingInstance); - if (speed > 0) { - unit.add(simulation, new CAbilityMove(handleIdAllocator.createId())); - } - if (unitTypeInstance.isHero()) { - final List heroAttacks = new ArrayList<>(); - for (final CUnitAttack attack : unitTypeInstance.getAttacks()) { - heroAttacks.add(attack.copy()); - } - unit.setUnitSpecificAttacks(heroAttacks); - } - if (!unit.getAttacks().isEmpty()) { - unit.add(simulation, new CAbilityAttack(handleIdAllocator.createId())); - } - final List structuresBuilt = unitTypeInstance.getStructuresBuilt(); - if (!structuresBuilt.isEmpty()) { - switch (unitTypeInstance.getRace()) { - case ORC: - unit.add(simulation, new CAbilityOrcBuild(handleIdAllocator.createId(), structuresBuilt)); - break; - case HUMAN: - unit.add(simulation, new CAbilityHumanBuild(handleIdAllocator.createId(), structuresBuilt)); - break; - case UNDEAD: - unit.add(simulation, new CAbilityUndeadBuild(handleIdAllocator.createId(), structuresBuilt)); - break; - case NIGHTELF: - unit.add(simulation, new CAbilityNightElfBuild(handleIdAllocator.createId(), structuresBuilt)); - break; - case NAGA: - unit.add(simulation, new CAbilityNagaBuild(handleIdAllocator.createId(), structuresBuilt)); - break; - case CREEPS: - case CRITTERS: - case DEMON: - case OTHER: - unit.add(simulation, new CAbilityOrcBuild(handleIdAllocator.createId(), structuresBuilt)); - break; - } - } - final List unitsTrained = unitTypeInstance.getUnitsTrained(); - final List researchesAvailable = unitTypeInstance.getResearchesAvailable(); - if (!unitsTrained.isEmpty() || !researchesAvailable.isEmpty()) { - unit.add(simulation, new CAbilityQueue(handleIdAllocator.createId(), unitsTrained, researchesAvailable)); - } - if (unitTypeInstance.isRevivesHeroes()) { - unit.add(simulation, new CAbilityReviveHero(handleIdAllocator.createId())); - } - if (!unitsTrained.isEmpty() || unitTypeInstance.isRevivesHeroes()) { - unit.add(simulation, new CAbilityRally(handleIdAllocator.createId())); - } - if (unitTypeInstance.isHero()) { - final List heroAbilityList = unitTypeInstance.getHeroAbilityList(); - unit.add(simulation, new CAbilityHero(handleIdAllocator.createId(), heroAbilityList)); - // reset initial mana after the value is adjusted for hero data - unit.setMana(manaInitial); - } - for (final String ability : unitTypeInstance.getAbilityList().split(",")) { - if ((ability.length() > 0) && !"_".equals(ability)) { - final CAbility createAbility = this.abilityData.createAbility(ability, handleIdAllocator.createId()); - if (createAbility != null) { - unit.add(simulation, createAbility); - } - } - } - return unit; - } - - private CUnitType getUnitTypeInstance(final War3ID typeId, final BufferedImage buildingPathingPixelMap, - final MutableGameObject unitType) { - CUnitType unitTypeInstance = this.unitIdToUnitType.get(typeId); - if (unitTypeInstance == null) { - final String legacyName = getLegacyName(unitType); - final int life = unitType.getFieldAsInteger(HIT_POINT_MAXIMUM, 0); - final int manaInitial = unitType.getFieldAsInteger(MANA_INITIAL_AMOUNT, 0); - final int manaMaximum = unitType.getFieldAsInteger(MANA_MAXIMUM, 0); - final int speed = unitType.getFieldAsInteger(MOVEMENT_SPEED_BASE, 0); - final int defense = unitType.getFieldAsInteger(DEFENSE, 0); - final String abilityList = unitType.getFieldAsString(ABILITIES_NORMAL, 0); - final String heroAbilityListString = unitType.getFieldAsString(ABILITIES_HERO, 0); - final int unitLevel = unitType.getFieldAsInteger(UNIT_LEVEL, 0); - final int priority = unitType.getFieldAsInteger(PRIORITY, 0); - - final float moveHeight = unitType.getFieldAsFloat(MOVE_HEIGHT, 0); - final String movetp = unitType.getFieldAsString(MOVE_TYPE, 0); - final float collisionSize = unitType.getFieldAsFloat(COLLISION_SIZE, 0); - final float propWindow = unitType.getFieldAsFloat(PROPULSION_WINDOW, 0); - final float turnRate = unitType.getFieldAsFloat(TURN_RATE, 0); - - final boolean canFlee = unitType.getFieldAsBoolean(CAN_FLEE, 0); - - final float strPlus = unitType.getFieldAsFloat(STR_PLUS, 0); - final float agiPlus = unitType.getFieldAsFloat(AGI_PLUS, 0); - final float intPlus = unitType.getFieldAsFloat(INT_PLUS, 0); - - final int strength = unitType.getFieldAsInteger(STR, 0); - final int agility = unitType.getFieldAsInteger(AGI, 0); - final int intelligence = unitType.getFieldAsInteger(INT, 0); - final CPrimaryAttribute primaryAttribute = CPrimaryAttribute - .parsePrimaryAttribute(unitType.getFieldAsString(PRIMARY_ATTRIBUTE, 0)); - - final String properNames = unitType.getFieldAsString(PROPER_NAMES, 0); - final int properNamesCount = unitType.getFieldAsInteger(PROPER_NAMES_COUNT, 0); - - final boolean isBldg = unitType.getFieldAsBoolean(IS_BLDG, 0); - PathingGrid.MovementType movementType = PathingGrid.getMovementType(movetp); - if (movementType == null) { - movementType = MovementType.DISABLED; - } - final String unitName = unitType.getFieldAsString(NAME, 0); - final float acquisitionRange = unitType.getFieldAsFloat(ACQUISITION_RANGE, 0); - final float minimumAttackRange = unitType.getFieldAsFloat(MINIMUM_ATTACK_RANGE, 0); - final EnumSet targetedAs = CTargetType - .parseTargetTypeSet(unitType.getFieldAsString(TARGETED_AS, 0)); - final String classificationString = unitType.getFieldAsString(CLASSIFICATION, 0); - final EnumSet classifications = EnumSet.noneOf(CUnitClassification.class); - if (classificationString != null) { - final String[] classificationValues = classificationString.split(","); - for (final String unitEditorKey : classificationValues) { - final CUnitClassification unitClassification = CUnitClassification - .parseUnitClassification(unitEditorKey); - if (unitClassification != null) { - classifications.add(unitClassification); - } - } - } - final List attacks = new ArrayList<>(); - final int attacksEnabled = unitType.getFieldAsInteger(ATTACKS_ENABLED, 0); - if ((attacksEnabled & 0x1) != 0) { - try { - // attack one - final float animationBackswingPoint = unitType.getFieldAsFloat(ATTACK1_BACKSWING_POINT, 0); - final float animationDamagePoint = unitType.getFieldAsFloat(ATTACK1_DAMAGE_POINT, 0); - final int areaOfEffectFullDamage = unitType.getFieldAsInteger(ATTACK1_AREA_OF_EFFECT_FULL_DMG, 0); - final int areaOfEffectMediumDamage = unitType.getFieldAsInteger(ATTACK1_AREA_OF_EFFECT_HALF_DMG, 0); - final int areaOfEffectSmallDamage = unitType.getFieldAsInteger(ATTACK1_AREA_OF_EFFECT_QUARTER_DMG, - 0); - final EnumSet areaOfEffectTargets = CTargetType - .parseTargetTypeSet(unitType.getFieldAsString(ATTACK1_AREA_OF_EFFECT_TARGETS, 0)); - final CAttackType attackType = CAttackType - .parseAttackType(unitType.getFieldAsString(ATTACK1_ATTACK_TYPE, 0)); - final float cooldownTime = unitType.getFieldAsFloat(ATTACK1_COOLDOWN, 0); - final int damageBase = unitType.getFieldAsInteger(ATTACK1_DMG_BASE, 0); - final float damageFactorMedium = unitType.getFieldAsFloat(ATTACK1_DAMAGE_FACTOR_HALF, 0); - final float damageFactorSmall = unitType.getFieldAsFloat(ATTACK1_DAMAGE_FACTOR_QUARTER, 0); - final float damageLossFactor = unitType.getFieldAsFloat(ATTACK1_DAMAGE_LOSS_FACTOR, 0); - final int damageDice = unitType.getFieldAsInteger(ATTACK1_DMG_DICE, 0); - final int damageSidesPerDie = unitType.getFieldAsInteger(ATTACK1_DMG_SIDES_PER_DIE, 0); - final float damageSpillDistance = unitType.getFieldAsFloat(ATTACK1_DMG_SPILL_DIST, 0); - final float damageSpillRadius = unitType.getFieldAsFloat(ATTACK1_DMG_SPILL_RADIUS, 0); - final int damageUpgradeAmount = unitType.getFieldAsInteger(ATTACK1_DMG_UPGRADE_AMT, 0); - final int maximumNumberOfTargets = unitType.getFieldAsInteger(ATTACK1_TARGET_COUNT, 0); - final float projectileArc = unitType.getFieldAsFloat(ATTACK1_PROJECTILE_ARC, 0); - final String projectileArt = unitType.getFieldAsString(ATTACK1_MISSILE_ART, 0); - final boolean projectileHomingEnabled = unitType - .getFieldAsBoolean(ATTACK1_PROJECTILE_HOMING_ENABLED, 0); - final int projectileSpeed = unitType.getFieldAsInteger(ATTACK1_PROJECTILE_SPEED, 0); - final int range = unitType.getFieldAsInteger(ATTACK1_RANGE, 0); - final float rangeMotionBuffer = unitType.getFieldAsFloat(ATTACK1_RANGE_MOTION_BUFFER, 0); - final boolean showUI = unitType.getFieldAsBoolean(ATTACK1_SHOW_UI, 0); - final EnumSet targetsAllowed = CTargetType - .parseTargetTypeSet(unitType.getFieldAsString(ATTACK1_TARGETS_ALLOWED, 0)); - final String weaponSound = unitType.getFieldAsString(ATTACK1_WEAPON_SOUND, 0); - final CWeaponType weaponType = CWeaponType - .parseWeaponType(unitType.getFieldAsString(ATTACK1_WEAPON_TYPE, 0)); - attacks.add(createAttack(animationBackswingPoint, animationDamagePoint, areaOfEffectFullDamage, - areaOfEffectMediumDamage, areaOfEffectSmallDamage, areaOfEffectTargets, attackType, - cooldownTime, damageBase, damageFactorMedium, damageFactorSmall, damageLossFactor, - damageDice, damageSidesPerDie, damageSpillDistance, damageSpillRadius, damageUpgradeAmount, - maximumNumberOfTargets, projectileArc, projectileArt, projectileHomingEnabled, - projectileSpeed, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound, - weaponType)); - } - catch (final Exception exc) { - System.err.println("Attack 1 failed to parse with: " + exc.getClass() + ":" + exc.getMessage()); - } - } - if ((attacksEnabled & 0x2) != 0) { - try { - // attack two - final float animationBackswingPoint = unitType.getFieldAsFloat(ATTACK2_BACKSWING_POINT, 0); - final float animationDamagePoint = unitType.getFieldAsFloat(ATTACK2_DAMAGE_POINT, 0); - final int areaOfEffectFullDamage = unitType.getFieldAsInteger(ATTACK2_AREA_OF_EFFECT_FULL_DMG, 0); - final int areaOfEffectMediumDamage = unitType.getFieldAsInteger(ATTACK2_AREA_OF_EFFECT_HALF_DMG, 0); - final int areaOfEffectSmallDamage = unitType.getFieldAsInteger(ATTACK2_AREA_OF_EFFECT_QUARTER_DMG, - 0); - final EnumSet areaOfEffectTargets = CTargetType - .parseTargetTypeSet(unitType.getFieldAsString(ATTACK2_AREA_OF_EFFECT_TARGETS, 0)); - final CAttackType attackType = CAttackType - .parseAttackType(unitType.getFieldAsString(ATTACK2_ATTACK_TYPE, 0)); - final float cooldownTime = unitType.getFieldAsFloat(ATTACK2_COOLDOWN, 0); - final int damageBase = unitType.getFieldAsInteger(ATTACK2_DMG_BASE, 0); - final float damageFactorMedium = unitType.getFieldAsFloat(ATTACK2_DAMAGE_FACTOR_HALF, 0); - final float damageFactorSmall = unitType.getFieldAsFloat(ATTACK2_DAMAGE_FACTOR_QUARTER, 0); - final float damageLossFactor = unitType.getFieldAsFloat(ATTACK2_DAMAGE_LOSS_FACTOR, 0); - final int damageDice = unitType.getFieldAsInteger(ATTACK2_DMG_DICE, 0); - final int damageSidesPerDie = unitType.getFieldAsInteger(ATTACK2_DMG_SIDES_PER_DIE, 0); - final float damageSpillDistance = unitType.getFieldAsFloat(ATTACK2_DMG_SPILL_DIST, 0); - final float damageSpillRadius = unitType.getFieldAsFloat(ATTACK2_DMG_SPILL_RADIUS, 0); - final int damageUpgradeAmount = unitType.getFieldAsInteger(ATTACK2_DMG_UPGRADE_AMT, 0); - final int maximumNumberOfTargets = unitType.getFieldAsInteger(ATTACK2_TARGET_COUNT, 0); - float projectileArc = unitType.getFieldAsFloat(ATTACK2_PROJECTILE_ARC, 0); - String projectileArt = unitType.getFieldAsString(ATTACK2_MISSILE_ART, 0); - int projectileSpeed = unitType.getFieldAsInteger(ATTACK2_PROJECTILE_SPEED, 0); - if ("_".equals(projectileArt) || projectileArt.isEmpty()) { - projectileArt = unitType.getFieldAsString(ATTACK1_MISSILE_ART, 0); - projectileSpeed = unitType.getFieldAsInteger(ATTACK1_PROJECTILE_SPEED, 0); - projectileArc = unitType.getFieldAsFloat(ATTACK1_PROJECTILE_ARC, 0); - } - final boolean projectileHomingEnabled = unitType - .getFieldAsBoolean(ATTACK2_PROJECTILE_HOMING_ENABLED, 0); - final int range = unitType.getFieldAsInteger(ATTACK2_RANGE, 0); - final float rangeMotionBuffer = unitType.getFieldAsFloat(ATTACK2_RANGE_MOTION_BUFFER, 0); - boolean showUI = unitType.getFieldAsBoolean(ATTACK2_SHOW_UI, 0); - final EnumSet targetsAllowed = CTargetType - .parseTargetTypeSet(unitType.getFieldAsString(ATTACK2_TARGETS_ALLOWED, 0)); - final String weaponSound = unitType.getFieldAsString(ATTACK2_WEAPON_SOUND, 0); - final CWeaponType weaponType = CWeaponType - .parseWeaponType(unitType.getFieldAsString(ATTACK2_WEAPON_TYPE, 0)); - if (!attacks.isEmpty()) { - final CUnitAttack otherAttack = attacks.get(0); - if ((otherAttack.getAttackType() == attackType) && (targetsAllowed.size() == 1) - && (targetsAllowed.contains(CTargetType.TREE) - || (targetsAllowed.contains(CTargetType.STRUCTURE) - && (otherAttack.getDamageBase() == damageBase) - && (otherAttack.getDamageSidesPerDie() == damageSidesPerDie) - && (otherAttack.getDamageDice() == damageDice)))) { - showUI = false; - } - } - attacks.add(createAttack(animationBackswingPoint, animationDamagePoint, areaOfEffectFullDamage, - areaOfEffectMediumDamage, areaOfEffectSmallDamage, areaOfEffectTargets, attackType, - cooldownTime, damageBase, damageFactorMedium, damageFactorSmall, damageLossFactor, - damageDice, damageSidesPerDie, damageSpillDistance, damageSpillRadius, damageUpgradeAmount, - maximumNumberOfTargets, projectileArc, projectileArt, projectileHomingEnabled, - projectileSpeed, range, rangeMotionBuffer, showUI, targetsAllowed, weaponSound, - weaponType)); - } - catch (final Exception exc) { - System.err.println("Attack 2 failed to parse with: " + exc.getClass() + ":" + exc.getMessage()); - } - } - final int deathType = unitType.getFieldAsInteger(DEATH_TYPE, 0); - final boolean raise = (deathType & 0x1) != 0; - final boolean decay = (deathType & 0x2) != 0; - final String armorType = unitType.getFieldAsString(ARMOR_TYPE, 0); - final float impactZ = unitType.getFieldAsFloat(PROJECTILE_IMPACT_Z, 0); - final CDefenseType defenseType = CDefenseType.parseDefenseType(unitType.getFieldAsString(DEFENSE_TYPE, 0)); - final float deathTime = unitType.getFieldAsFloat(DEATH_TIME, 0); - final int goldCost = unitType.getFieldAsInteger(GOLD_COST, 0); - final int lumberCost = unitType.getFieldAsInteger(LUMBER_COST, 0); - final int buildTime = unitType.getFieldAsInteger(BUILD_TIME, 0); - final int foodUsed = unitType.getFieldAsInteger(FOOD_USED, 0); - final int foodMade = unitType.getFieldAsInteger(FOOD_MADE, 0); - - final boolean revivesHeroes = unitType.getFieldAsBoolean(REVIVES_HEROES, 0); - - final String unitsTrainedString = unitType.getFieldAsString(UNITS_TRAINED, 0); - final String[] unitsTrainedStringItems = unitsTrainedString.trim().split(","); - final List unitsTrained = new ArrayList<>(); - for (final String unitsTrainedStringItem : unitsTrainedStringItems) { - if (unitsTrainedStringItem.length() == 4) { - unitsTrained.add(War3ID.fromString(unitsTrainedStringItem)); - } - } - - final String researchesAvailableString = unitType.getFieldAsString(RESEARCHES_AVAILABLE, 0); - final String[] researchesAvailableStringItems = researchesAvailableString.trim().split(","); - final List researchesAvailable = new ArrayList<>(); - for (final String researchesAvailableStringItem : researchesAvailableStringItems) { - if (researchesAvailableStringItem.length() == 4) { - researchesAvailable.add(War3ID.fromString(researchesAvailableStringItem)); - } - } - - final String structuresBuiltString = unitType.getFieldAsString(STRUCTURES_BUILT, 0); - final String[] structuresBuiltStringItems = structuresBuiltString.split(","); - final List structuresBuilt = new ArrayList<>(); - for (final String structuresBuiltStringItem : structuresBuiltStringItems) { - if (structuresBuiltStringItem.length() == 4) { - structuresBuilt.add(War3ID.fromString(structuresBuiltStringItem)); - } - } - - final String[] heroAbilityListStringItems = heroAbilityListString.split(","); - final List heroAbilityList = new ArrayList<>(); - for (final String heroAbilityItem : heroAbilityListStringItems) { - if (heroAbilityItem.length() == 4) { - heroAbilityList.add(War3ID.fromString(heroAbilityItem)); - } - } - - final String requirementsString = unitType.getFieldAsString(REQUIRES, 0); - final String requirementsLevelsString = unitType.getFieldAsString(REQUIRES_AMOUNT, 0); - final String[] requirementsStringItems = requirementsString.split(","); - final String[] requirementsLevelsStringItems = requirementsLevelsString.split(","); - final List requirements = new ArrayList<>(); - for (int i = 0; i < requirementsStringItems.length; i++) { - final String item = requirementsStringItems[i]; - if (!item.isEmpty() && (item.length() == 4)) { - int level; - if (i < requirementsLevelsStringItems.length) { - if (requirementsLevelsStringItems[i].isEmpty()) { - level = 1; - } - else { - level = Integer.parseInt(requirementsLevelsStringItems[i]); - } - } - else if (requirementsLevelsStringItems.length > 0) { - final String requirementLevel = requirementsLevelsStringItems[requirementsLevelsStringItems.length - - 1]; - if (requirementLevel.isEmpty()) { - level = 1; - } - else { - level = Integer.parseInt(requirementLevel); - } - } - else { - level = 1; - } - requirements.add(new CUnitTypeRequirement(War3ID.fromString(item), level)); - } - } - - final EnumSet preventedPathingTypes = CBuildingPathingType - .parsePathingTypeListSet(unitType.getFieldAsString(PREVENT_PLACE, 0)); - final EnumSet requiredPathingTypes = CBuildingPathingType - .parsePathingTypeListSet(unitType.getFieldAsString(REQUIRE_PLACE, 0)); - - final String raceString = unitType.getFieldAsString(UNIT_RACE, 0); - final CUnitRace unitRace = CUnitRace.parseRace(raceString); - - final boolean hero = Character.isUpperCase(typeId.charAt(0)); - - final List heroProperNames = Arrays.asList(properNames.split(",")); - - unitTypeInstance = new CUnitType(unitName, legacyName, typeId, life, manaInitial, manaMaximum, speed, - defense, abilityList, isBldg, movementType, moveHeight, collisionSize, classifications, attacks, - armorType, raise, decay, defenseType, impactZ, buildingPathingPixelMap, deathTime, targetedAs, - acquisitionRange, minimumAttackRange, structuresBuilt, unitsTrained, researchesAvailable, unitRace, - goldCost, lumberCost, foodUsed, foodMade, buildTime, preventedPathingTypes, requiredPathingTypes, - propWindow, turnRate, requirements, unitLevel, hero, strength, strPlus, agility, agiPlus, - intelligence, intPlus, primaryAttribute, heroAbilityList, heroProperNames, properNamesCount, - canFlee, priority, revivesHeroes); - this.unitIdToUnitType.put(typeId, unitTypeInstance); - this.jassLegacyNameToUnitId.put(legacyName, typeId); - } - return unitTypeInstance; - } - - private String getLegacyName(final MutableGameObject unitType) { - String legacyName; - if (unitType.isCustom()) { - legacyName = "custom_" + unitType.getAlias(); - } - else { - // ?? this might be correct here, not sure, legacy name is mostly only used - // for spawning hidden units in campaign secrets - legacyName = unitType.readSLKTag("name"); - } - return legacyName; - } - - private static int[] populateHeroStatTable(final int maxHeroLevel, final float statPerLevel) { - final int[] table = new int[maxHeroLevel]; - float sumBonusAtLevel = 0f; - for (int i = 0; i < table.length; i++) { - final float newSumBonusAtLevel = sumBonusAtLevel + statPerLevel; - if (i == 0) { - table[i] = (int) newSumBonusAtLevel; - } - else { - table[i] = (int) newSumBonusAtLevel - table[i - 1]; - } - sumBonusAtLevel = newSumBonusAtLevel; - } - return table; - } - - private CUnitAttack createAttack(final float animationBackswingPoint, final float animationDamagePoint, - final int areaOfEffectFullDamage, final int areaOfEffectMediumDamage, final int areaOfEffectSmallDamage, - final EnumSet areaOfEffectTargets, final CAttackType attackType, final float cooldownTime, - final int damageBase, final float damageFactorMedium, final float damageFactorSmall, - final float damageLossFactor, final int damageDice, final int damageSidesPerDie, - final float damageSpillDistance, final float damageSpillRadius, final int damageUpgradeAmount, - final int maximumNumberOfTargets, final float projectileArc, final String projectileArt, - final boolean projectileHomingEnabled, final int projectileSpeed, final int range, - final float rangeMotionBuffer, final boolean showUI, final EnumSet targetsAllowed, - final String weaponSound, final CWeaponType weaponType) { - final CUnitAttack attack; - switch (weaponType) { - case MISSILE: - attack = new CUnitAttackMissile(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime, - damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI, - targetsAllowed, weaponSound, weaponType, projectileArc, projectileArt, projectileHomingEnabled, - projectileSpeed); - break; - case MBOUNCE: - attack = new CUnitAttackMissileBounce(animationBackswingPoint, animationDamagePoint, attackType, - cooldownTime, damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range, - rangeMotionBuffer, showUI, targetsAllowed, weaponSound, weaponType, projectileArc, projectileArt, - projectileHomingEnabled, projectileSpeed, damageLossFactor, maximumNumberOfTargets, - areaOfEffectFullDamage, areaOfEffectTargets); - break; - case MSPLASH: - case ARTILLERY: - attack = new CUnitAttackMissileSplash(animationBackswingPoint, animationDamagePoint, attackType, - cooldownTime, damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range, - rangeMotionBuffer, showUI, targetsAllowed, weaponSound, weaponType, projectileArc, projectileArt, - projectileHomingEnabled, projectileSpeed, areaOfEffectFullDamage, areaOfEffectMediumDamage, - areaOfEffectSmallDamage, areaOfEffectTargets, damageFactorMedium, damageFactorSmall); - break; - case MLINE: - case ALINE: - attack = new CUnitAttackMissileLine(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime, - damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI, - targetsAllowed, weaponSound, weaponType, projectileArc, projectileArt, projectileHomingEnabled, - projectileSpeed, damageSpillDistance, damageSpillRadius); - break; - case INSTANT: - attack = new CUnitAttackInstant(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime, - damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI, - targetsAllowed, weaponSound, weaponType, projectileArt); - break; - default: - case NORMAL: - attack = new CUnitAttackNormal(animationBackswingPoint, animationDamagePoint, attackType, cooldownTime, - damageBase, damageDice, damageSidesPerDie, damageUpgradeAmount, range, rangeMotionBuffer, showUI, - targetsAllowed, weaponSound, weaponType); - break; - } - return attack; - } - - public float getPropulsionWindow(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsFloat(PROPULSION_WINDOW, 0); - } - - public float getTurnRate(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsFloat(TURN_RATE, 0); - } - - public boolean isBuilding(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsBoolean(IS_BLDG, 0); - } - - public String getName(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getName(); - } - - public int getA1MinDamage(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_BASE, 0) - + this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_DICE, 0); - } - - public int getA1MaxDamage(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_BASE, 0) - + (this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_DICE, 0) - * this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_DMG_SIDES_PER_DIE, 0)); - } - - public int getA2MinDamage(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_BASE, 0) - + this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_DICE, 0); - } - - public int getA2MaxDamage(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_BASE, 0) - + (this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_DICE, 0) - * this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_DMG_SIDES_PER_DIE, 0)); - } - - public int getDefense(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsInteger(DEFENSE, 0); - } - - public int getA1ProjectileSpeed(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK1_PROJECTILE_SPEED, 0); - } - - public float getA1ProjectileArc(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsFloat(ATTACK1_PROJECTILE_ARC, 0); - } - - public int getA2ProjectileSpeed(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsInteger(ATTACK2_PROJECTILE_SPEED, 0); - } - - public float getA2ProjectileArc(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsFloat(ATTACK2_PROJECTILE_ARC, 0); - } - - public String getA1MissileArt(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsString(ATTACK1_MISSILE_ART, 0); - } - - public String getA2MissileArt(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsString(ATTACK2_MISSILE_ART, 0); - } - - public float getA1Cooldown(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsFloat(ATTACK1_COOLDOWN, 0); - } - - public float getA2Cooldown(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsFloat(ATTACK2_COOLDOWN, 0); - } - - public float getProjectileLaunchX(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsFloat(PROJECTILE_LAUNCH_X, 0); - } - - public float getProjectileLaunchY(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsFloat(PROJECTILE_LAUNCH_Y, 0); - } - - public float getProjectileLaunchZ(final War3ID unitTypeId) { - return this.unitData.get(unitTypeId).getFieldAsFloat(PROJECTILE_LAUNCH_Z, 0); - } - - public CUnitType getUnitType(final War3ID rawcode) { - final CUnitType unitTypeInstance = this.unitIdToUnitType.get(rawcode); - if (unitTypeInstance != null) { - return unitTypeInstance; - } - final MutableGameObject unitType = this.unitData.get(rawcode); - if (unitType == null) { - return null; - } - final BufferedImage buildingPathingPixelMap = this.simulationRenderController - .getBuildingPathingPixelMap(rawcode); - return getUnitTypeInstance(rawcode, buildingPathingPixelMap, unitType); - } - - public CUnitType getUnitTypeByJassLegacyName(final String jassLegacyName) { - final War3ID typeId = this.jassLegacyNameToUnitId.get(jassLegacyName); - if (typeId == null) { - // VERY inefficient, but this is a crazy system anyway, they should not be using - // this! - System.err.println( - "We are doing a highly inefficient lookup for a non-cached unit type based on its legacy string ID that I am pretty sure is not used by modding community: " - + jassLegacyName); - for (final War3ID key : this.unitData.keySet()) { - final MutableGameObject mutableGameObject = this.unitData.get(key); - if (jassLegacyName.equals(getLegacyName(mutableGameObject))) { - return getUnitType(mutableGameObject.getAlias()); - } - } - } - return getUnitType(typeId); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitRace.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitRace.java deleted file mode 100644 index 57f77f89..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/data/CUnitRace.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.data; - -import java.util.HashMap; -import java.util.Map; - -public enum CUnitRace { - HUMAN, - ORC, - UNDEAD, - NIGHTELF, - NAGA, - CREEPS, - DEMON, - CRITTERS, - OTHER; - - private static Map keyToRace = new HashMap<>(); - - static { - for (final CUnitRace race : CUnitRace.values()) { - keyToRace.put(race.name(), race); - } - } - - public static CUnitRace parseRace(final String raceString) { - final CUnitRace race = keyToRace.get(raceString.toUpperCase()); - if (race == null) { - return OTHER; - } - return race; - } -} \ No newline at end of file diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/item/CItemTypeJass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/item/CItemTypeJass.java deleted file mode 100644 index bde3174f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/item/CItemTypeJass.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.item; - -public enum CItemTypeJass { - PERMANENT, - CHARGED, - POWERUP, - ARTIFACT, - PURCHASABLE, - CAMPAIGN, - MISCELLANEOUS, - UNKNOWN, - ANY; - - public static CItemTypeJass[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrder.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrder.java deleted file mode 100644 index 30706f88..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrder.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgAbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgTargetCheckReceiver; - -public interface COrder { - int getAbilityHandleId(); - - int getOrderId(); - - CBehavior begin(final CSimulation game, CUnit caster); - - AbilityTarget getTarget(CSimulation game); - - boolean isQueued(); - - final StringMsgTargetCheckReceiver targetCheckReceiver = new StringMsgTargetCheckReceiver<>(); - final StringMsgAbilityActivationReceiver abilityActivationReceiver = new StringMsgAbilityActivationReceiver(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderDropItemAtPoint.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderDropItemAtPoint.java deleted file mode 100644 index 0084a25f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderDropItemAtPoint.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.inventory.CAbilityInventory; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgTargetCheckReceiver; - -public class COrderDropItemAtPoint implements COrder { - private final int abilityHandleId; - private final int orderId; - private final int itemHandleId; - private final AbilityPointTarget target; - private final boolean queued; - - public COrderDropItemAtPoint(final int abilityHandleId, final int orderId, final int itemHandleId, - final AbilityPointTarget target, final boolean queued) { - this.abilityHandleId = abilityHandleId; - this.orderId = orderId; - this.itemHandleId = itemHandleId; - this.target = target; - this.queued = queued; - } - - @Override - public int getAbilityHandleId() { - return this.abilityHandleId; - } - - @Override - public int getOrderId() { - return this.orderId; - } - - @Override - public AbilityPointTarget getTarget(final CSimulation game) { - return this.target; - } - - @Override - public boolean isQueued() { - return this.queued; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster) { - final CAbilityInventory ability = (CAbilityInventory) game.getAbility(this.abilityHandleId); - ability.checkCanUse(game, caster, this.orderId, this.abilityActivationReceiver.reset()); - if (this.abilityActivationReceiver.isUseOk()) { - final StringMsgTargetCheckReceiver targetReceiver = (StringMsgTargetCheckReceiver) targetCheckReceiver; - final CItem itemToDrop = (CItem) game.getWidget(this.itemHandleId); - return ability.beginDropItem(game, caster, this.orderId, itemToDrop, this.target); - } - else { - game.getCommandErrorListener(caster.getPlayerIndex()) - .showCommandError(this.abilityActivationReceiver.getMessage()); - return caster.pollNextOrderBehavior(game); - } - - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + this.abilityHandleId; - result = (prime * result) + this.itemHandleId; - result = (prime * result) + this.orderId; - result = (prime * result) + (this.queued ? 1231 : 1237); - result = (prime * result) + ((this.target == null) ? 0 : this.target.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final COrderDropItemAtPoint other = (COrderDropItemAtPoint) obj; - if (this.abilityHandleId != other.abilityHandleId) { - return false; - } - if (this.itemHandleId != other.itemHandleId) { - return false; - } - if (this.orderId != other.orderId) { - return false; - } - if (this.queued != other.queued) { - return false; - } - if (this.target == null) { - if (other.target != null) { - return false; - } - } - else if (!this.target.equals(other.target)) { - return false; - } - return true; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderNoTarget.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderNoTarget.java deleted file mode 100644 index 6b08cd99..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderNoTarget.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgTargetCheckReceiver; - -public class COrderNoTarget implements COrder { - private final int abilityHandleId; - private final int orderId; - private final boolean queued; - - public COrderNoTarget(final int abilityHandleId, final int orderId, final boolean queued) { - this.abilityHandleId = abilityHandleId; - this.orderId = orderId; - this.queued = queued; - } - - @Override - public int getAbilityHandleId() { - return this.abilityHandleId; - } - - @Override - public int getOrderId() { - return this.orderId; - } - - @Override - public boolean isQueued() { - return this.queued; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster) { - final CAbility ability = game.getAbility(this.abilityHandleId); - ability.checkCanUse(game, caster, this.orderId, this.abilityActivationReceiver.reset()); - if (this.abilityActivationReceiver.isUseOk()) { - final StringMsgTargetCheckReceiver targetReceiver = (StringMsgTargetCheckReceiver) targetCheckReceiver; - ability.checkCanTargetNoTarget(game, caster, this.orderId, targetReceiver); - if (targetReceiver.getMessage() == null) { - return ability.beginNoTarget(game, caster, this.orderId); - } - else { - game.getCommandErrorListener(caster.getPlayerIndex()).showCommandError(targetReceiver.getMessage()); - return caster.pollNextOrderBehavior(game); - } - } - else { - game.getCommandErrorListener(caster.getPlayerIndex()) - .showCommandError(this.abilityActivationReceiver.getMessage()); - return caster.pollNextOrderBehavior(game); - } - } - - @Override - public AbilityTarget getTarget(final CSimulation game) { - return null; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + this.abilityHandleId; - result = (prime * result) + this.orderId; - result = (prime * result) + (this.queued ? 1231 : 1237); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final COrderNoTarget other = (COrderNoTarget) obj; - if (this.abilityHandleId != other.abilityHandleId) { - return false; - } - if (this.orderId != other.orderId) { - return false; - } - if (this.queued != other.queued) { - return false; - } - return true; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderTargetPoint.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderTargetPoint.java deleted file mode 100644 index 89e25c84..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderTargetPoint.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgTargetCheckReceiver; - -public class COrderTargetPoint implements COrder { - private final int abilityHandleId; - private final int orderId; - private final AbilityPointTarget target; - private final boolean queued; - - public COrderTargetPoint(final int abilityHandleId, final int orderId, final AbilityPointTarget target, - final boolean queued) { - this.abilityHandleId = abilityHandleId; - this.orderId = orderId; - this.target = target; - this.queued = queued; - } - - @Override - public int getAbilityHandleId() { - return this.abilityHandleId; - } - - @Override - public int getOrderId() { - return this.orderId; - } - - @Override - public AbilityPointTarget getTarget(final CSimulation game) { - return this.target; - } - - @Override - public boolean isQueued() { - return this.queued; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster) { - final CAbility ability = game.getAbility(this.abilityHandleId); - ability.checkCanUse(game, caster, this.orderId, this.abilityActivationReceiver.reset()); - if (this.abilityActivationReceiver.isUseOk()) { - final StringMsgTargetCheckReceiver targetReceiver = (StringMsgTargetCheckReceiver) targetCheckReceiver; - ability.checkCanTarget(game, caster, this.orderId, this.target, targetReceiver); - if (targetReceiver.getTarget() != null) { - return ability.begin(game, caster, this.orderId, this.target); - } - else { - game.getCommandErrorListener(caster.getPlayerIndex()).showCommandError(targetReceiver.getMessage()); - return caster.pollNextOrderBehavior(game); - } - } - else { - game.getCommandErrorListener(caster.getPlayerIndex()) - .showCommandError(this.abilityActivationReceiver.getMessage()); - return caster.pollNextOrderBehavior(game); - } - - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + this.abilityHandleId; - result = (prime * result) + this.orderId; - result = (prime * result) + (this.queued ? 1231 : 1237); - result = (prime * result) + ((this.target == null) ? 0 : this.target.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final COrderTargetPoint other = (COrderTargetPoint) obj; - if (this.abilityHandleId != other.abilityHandleId) { - return false; - } - if (this.orderId != other.orderId) { - return false; - } - if (this.queued != other.queued) { - return false; - } - if (this.target == null) { - if (other.target != null) { - return false; - } - } - else if (!this.target.equals(other.target)) { - return false; - } - return true; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderTargetWidget.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderTargetWidget.java deleted file mode 100644 index 0262d056..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/COrderTargetWidget.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehavior; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.StringMsgTargetCheckReceiver; - -public class COrderTargetWidget implements COrder { - private final int abilityHandleId; - private final int orderId; - private final int targetHandleId; - private final boolean queued; - - public COrderTargetWidget(final int abilityHandleId, final int orderId, final int targetHandleId, - final boolean queued) { - this.abilityHandleId = abilityHandleId; - this.orderId = orderId; - this.targetHandleId = targetHandleId; - this.queued = queued; - } - - @Override - public int getAbilityHandleId() { - return this.abilityHandleId; - } - - @Override - public int getOrderId() { - return this.orderId; - } - - @Override - public AbilityTarget getTarget(final CSimulation game) { - final CWidget target = game.getWidget(this.targetHandleId); - return target; - } - - @Override - public boolean isQueued() { - return this.queued; - } - - @Override - public CBehavior begin(final CSimulation game, final CUnit caster) { - final CAbility ability = game.getAbility(this.abilityHandleId); - ability.checkCanUse(game, caster, this.orderId, abilityActivationReceiver.reset()); - if (abilityActivationReceiver.isUseOk()) { - final CWidget target = game.getWidget(this.targetHandleId); - final StringMsgTargetCheckReceiver targetReceiver = (StringMsgTargetCheckReceiver) targetCheckReceiver; - ability.checkCanTarget(game, caster, this.orderId, target, targetReceiver); - if (targetReceiver.getTarget() != null) { - return ability.begin(game, caster, this.orderId, targetReceiver.getTarget()); - } - else { - game.getCommandErrorListener(caster.getPlayerIndex()).showCommandError(targetReceiver.getMessage()); - return caster.pollNextOrderBehavior(game); - } - } - else { - game.getCommandErrorListener(caster.getPlayerIndex()) - .showCommandError(this.abilityActivationReceiver.getMessage()); - return caster.pollNextOrderBehavior(game); - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = (prime * result) + this.abilityHandleId; - result = (prime * result) + this.orderId; - result = (prime * result) + (this.queued ? 1231 : 1237); - result = (prime * result) + this.targetHandleId; - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final COrderTargetWidget other = (COrderTargetWidget) obj; - if (this.abilityHandleId != other.abilityHandleId) { - return false; - } - if (this.orderId != other.orderId) { - return false; - } - if (this.queued != other.queued) { - return false; - } - if (this.targetHandleId != other.targetHandleId) { - return false; - } - return true; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIdUtils.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIdUtils.java deleted file mode 100644 index 90375e3c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIdUtils.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Map; - -public class OrderIdUtils { - private static Map orderIdToString = new HashMap<>(); - private static Map stringToOrderId = new HashMap<>(); - - static { - for (final Field field : OrderIds.class.getDeclaredFields()) { - final String name = field.getName(); - try { - final Object value = field.get(null); - if (value instanceof Integer) { - final Integer orderId = (Integer) value; - orderIdToString.put(orderId, name); - stringToOrderId.put(name, orderId); - } - } - catch (final IllegalArgumentException e) { - e.printStackTrace(); - } - catch (final IllegalAccessException e) { - e.printStackTrace(); - } - } - } - - public static int getOrderId(final String orderIdString) { - return stringToOrderId.get(orderIdString); - } - - public static String getStringFromOrderId(final Integer orderId) { - return orderIdToString.get(orderId); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIds.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIds.java deleted file mode 100644 index ee9022dc..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/orders/OrderIds.java +++ /dev/null @@ -1,457 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders; - -/** - * Thanks to the Wurst guys for this list of ids, taken from this link: - * https://github.com/wurstscript/WurstStdlib2/blob/master/wurst/_wurst/assets/Orders.wurst - * - * The original code ported to create this Java file is licensed under the - * Apache License; you can read more at the link above. - * - */ -public class OrderIds { - ;/** - * This is an order with no target that opens up the build menu of a unit that - * can build structures. - */ - ; - public static final int buildmenu = 851994; - /** - * 851976 (cancel): This is an order with no target that is like a click on a - * cancel button. We used to be able to catch cancel clicks with this id back - * then but this id doesn't seem to work any more. - */ - public static final int cancel = 851976; - /** - * An item targeted order that move the target item to a certain inventory slot - * of the ordered hero. - */ - public static final int itemdrag00 = 852002; - /** - * An item targeted order that move the target item to a certain inventory slot - * of the ordered hero. - */ - public static final int itemdrag01 = 852003; - /** - * An item targeted order that move the target item to a certain inventory slot - * of the ordered hero. - */ - public static final int itemdrag02 = 852004; - /** - * An item targeted order that move the target item to a certain inventory slot - * of the ordered hero. - */ - public static final int itemdrag03 = 852005; - /** - * An item targeted order that move the target item to a certain inventory slot - * of the ordered hero. - */ - public static final int itemdrag04 = 852006; - /** - * An item targeted order that move the target item to a certain inventory slot - * of the ordered hero. - */ - public static final int itemdrag05 = 852007; - /** - * An order that will make the ordered hero use the item in a certain inventory - * slot. If it's an order with no target or object or point targeted depends on - * the type of item. - */ - public static final int itemuse00 = 852008; - /** - * An order that will make the ordered hero use the item in a certain inventory - * slot. If it's an order with no target or object or point targeted depends on - * the type of item. - */ - public static final int itemuse01 = 852009; - /** - * An order that will make the ordered hero use the item in a certain inventory - * slot. If it's an order with no target or object or point targeted depends on - * the type of item. - */ - public static final int itemuse02 = 852010; - /** - * An order that will make the ordered hero use the item in a certain inventory - * slot. If it's an order with no target or object or point targeted depends on - * the type of item. - */ - public static final int itemuse03 = 852011; - /** - * An order that will make the ordered hero use the item in a certain inventory - * slot. If it's an order with no target or object or point targeted depends on - * the type of item. - */ - public static final int itemuse04 = 852012; - /** - * An order that will make the ordered hero use the item in a certain inventory - * slot. If it's an order with no target or object or point targeted depends on - * the type of item. - */ - public static final int itemuse05 = 852013; - /** - * Order for AIaa ability, which blizzard made for tome of attack, but never - * used it. But it can actually change caster's base attack! - */ - public static final int tomeOfAttack = 852259; - /** This is a point or object targeted order that is like a right click. */ - public static final int smart = 851971; - /** - * This is an order with no target that opens the skill menu of heroes. If it is - * issued for a normal unit with triggers it will black out the command card for - * this unit, the command card will revert to normal after reselecting the unit. - */ - public static final int skillmenu = 852000; - /** - * This order is issued to units that get stunned by a spell, for example War - * Stomp (AOws). This is probably a hold position + hold fire order. The ordered - * unit will be unable to move and attack. - */ - public static final int stunned = 851973; - public static final int wandOfIllusion = 852274; - public static final int absorb = 852529; - public static final int acidbomb = 852662; - public static final int acolyteharvest = 852185; - public static final int ambush = 852131; - public static final int ancestralspirit = 852490; - public static final int ancestralspirittarget = 852491; - public static final int animatedead = 852217; - public static final int antimagicshell = 852186; - public static final int attack = 851983; - public static final int attackground = 851984; - public static final int attackonce = 851985; - public static final int attributemodskill = 852576; - public static final int auraunholy = 852215; - public static final int auravampiric = 852216; - public static final int autodispel = 852132; - public static final int autodispeloff = 852134; - public static final int autodispelon = 852133; - public static final int autoentangle = 852505; - public static final int autoentangleinstant = 852506; - public static final int autoharvestgold = 852021; - public static final int autoharvestlumber = 852022; - public static final int avatar = 852086; - public static final int avengerform = 852531; - public static final int awaken = 852466; - public static final int banish = 852486; - public static final int barkskin = 852135; - public static final int barkskinoff = 852137; - public static final int barkskinon = 852136; - public static final int battleroar = 852599; - public static final int battlestations = 852099; - public static final int bearform = 852138; - public static final int berserk = 852100; - public static final int blackarrow = 852577; - public static final int blackarrowoff = 852579; - public static final int blackarrowon = 852578; - public static final int blight = 852187; - public static final int blink = 852525; - public static final int blizzard = 852089; - public static final int bloodlust = 852101; - public static final int bloodlustoff = 852103; - public static final int bloodluston = 852102; - public static final int board = 852043; - public static final int breathoffire = 852580; - public static final int breathoffrost = 852560; - public static final int build = 851994; - public static final int burrow = 852533; - public static final int cannibalize = 852188; - public static final int carrionscarabs = 852551; - public static final int carrionscarabsinstant = 852554; - public static final int carrionscarabsoff = 852553; - public static final int carrionscarabson = 852552; - public static final int carrionswarm = 852218; - public static final int chainlightning = 852119; - public static final int channel = 852600; - public static final int charm = 852581; - public static final int chemicalrage = 852663; - public static final int cloudoffog = 852473; - public static final int clusterrockets = 852652; - public static final int coldarrows = 852244; - public static final int coldarrowstarg = 852243; - public static final int controlmagic = 852474; - public static final int corporealform = 852493; - public static final int corrosivebreath = 852140; - public static final int coupleinstant = 852508; - public static final int coupletarget = 852507; - public static final int creepanimatedead = 852246; - public static final int creepdevour = 852247; - public static final int creepheal = 852248; - public static final int creephealoff = 852250; - public static final int creephealon = 852249; - public static final int creepthunderbolt = 852252; - public static final int creepthunderclap = 852253; - public static final int cripple = 852189; - public static final int curse = 852190; - public static final int curseoff = 852192; - public static final int curseon = 852191; - public static final int cyclone = 852144; - public static final int darkconversion = 852228; - public static final int darkportal = 852229; - public static final int darkritual = 852219; - public static final int darksummoning = 852220; - public static final int deathanddecay = 852221; - public static final int deathcoil = 852222; - public static final int deathpact = 852223; - public static final int decouple = 852509; - public static final int defend = 852055; - public static final int detectaoe = 852015; - public static final int detonate = 852145; - public static final int devour = 852104; - public static final int devourmagic = 852536; - public static final int disassociate = 852240; - public static final int disenchant = 852495; - public static final int dismount = 852470; - public static final int dispel = 852057; - public static final int divineshield = 852090; - public static final int doom = 852583; - public static final int drain = 852487; - public static final int dreadlordinferno = 852224; - public static final int dropitem = 852001; - public static final int drunkenhaze = 852585; - public static final int earthquake = 852121; - public static final int eattree = 852146; - public static final int elementalfury = 852586; - public static final int ensnare = 852106; - public static final int ensnareoff = 852108; - public static final int ensnareon = 852107; - public static final int entangle = 852147; - public static final int entangleinstant = 852148; - public static final int entanglingroots = 852171; - public static final int etherealform = 852496; - public static final int evileye = 852105; - public static final int faeriefire = 852149; - public static final int faeriefireoff = 852151; - public static final int faeriefireon = 852150; - public static final int fanofknives = 852526; - public static final int farsight = 852122; - public static final int fingerofdeath = 852230; - public static final int firebolt = 852231; - public static final int flamestrike = 852488; - public static final int flamingarrows = 852174; - public static final int flamingarrowstarg = 852173; - public static final int flamingattack = 852540; - public static final int flamingattacktarg = 852539; - public static final int flare = 852060; - public static final int forceboard = 852044; - public static final int forceofnature = 852176; - public static final int forkedlightning = 852587; - public static final int freezingbreath = 852195; - public static final int frenzy = 852561; - public static final int frenzyoff = 852563; - public static final int frenzyon = 852562; - public static final int frostarmor = 852225; - public static final int frostarmoroff = 852459; - public static final int frostarmoron = 852458; - public static final int frostnova = 852226; - public static final int getitem = 851981; - public static final int gold2lumber = 852233; - public static final int grabtree = 852511; - public static final int harvest = 852018; - public static final int heal = 852063; - public static final int healingspray = 852664; - public static final int healingward = 852109; - public static final int healingwave = 852501; - public static final int healoff = 852065; - public static final int healon = 852064; - public static final int hex = 852502; - public static final int holdposition = 851993; - public static final int holybolt = 852092; - public static final int howlofterror = 852588; - public static final int humanbuild = 851995; - public static final int immolation = 852177; - public static final int impale = 852555; - public static final int incineratearrow = 852670; - public static final int incineratearrowoff = 852672; - public static final int incineratearrowon = 852671; - public static final int inferno = 852232; - public static final int innerfire = 852066; - public static final int innerfireoff = 852068; - public static final int innerfireon = 852067; - public static final int instant = 852200; - public static final int invisibility = 852069; - public static final int lavamonster = 852667; - public static final int lightningshield = 852110; - public static final int load = 852046; - public static final int loadarcher = 852142; - public static final int loadcorpse = 852050; - public static final int loadcorpseinstant = 852053; - public static final int locustswarm = 852556; - public static final int lumber2gold = 852234; - public static final int magicdefense = 852478; - public static final int magicleash = 852480; - public static final int magicundefense = 852479; - public static final int manaburn = 852179; - public static final int manaflareoff = 852513; - public static final int manaflareon = 852512; - public static final int manashieldoff = 852590; - public static final int manashieldon = 852589; - public static final int massteleport = 852093; - public static final int mechanicalcritter = 852564; - public static final int metamorphosis = 852180; - public static final int militia = 852072; - public static final int militiaconvert = 852071; - public static final int militiaoff = 852073; - public static final int militiaunconvert = 852651; - public static final int mindrot = 852565; - public static final int mirrorimage = 852123; - public static final int monsoon = 852591; - public static final int mount = 852469; - public static final int mounthippogryph = 852143; - public static final int move = 851986; - public static final int moveAI = 851988; - public static final int nagabuild = 852467; - public static final int neutraldetectaoe = 852023; - public static final int neutralinteract = 852566; - public static final int neutralspell = 852630; - public static final int nightelfbuild = 851997; - public static final int orcbuild = 851996; - public static final int parasite = 852601; - public static final int parasiteoff = 852603; - public static final int parasiteon = 852602; - public static final int patrol = 851990; - public static final int phaseshift = 852514; - public static final int phaseshiftinstant = 852517; - public static final int phaseshiftoff = 852516; - public static final int phaseshifton = 852515; - public static final int phoenixfire = 852481; - public static final int phoenixmorph = 852482; - public static final int poisonarrows = 852255; - public static final int poisonarrowstarg = 852254; - public static final int polymorph = 852074; - public static final int possession = 852196; - public static final int preservation = 852568; - public static final int purge = 852111; - public static final int rainofchaos = 852237; - public static final int rainoffire = 852238; - public static final int raisedead = 852197; - public static final int raisedeadoff = 852199; - public static final int raisedeadon = 852198; - public static final int ravenform = 852155; - public static final int recharge = 852157; - public static final int rechargeoff = 852159; - public static final int rechargeon = 852158; - public static final int rejuvination = 852160; - public static final int renew = 852161; - public static final int renewoff = 852163; - public static final int renewon = 852162; - public static final int repair = 852024; - public static final int repairoff = 852026; - public static final int repairon = 852025; - public static final int replenish = 852542; - public static final int replenishlife = 852545; - public static final int replenishlifeoff = 852547; - public static final int replenishlifeon = 852546; - public static final int replenishmana = 852548; - public static final int replenishmanaoff = 852550; - public static final int replenishmanaon = 852549; - public static final int replenishoff = 852544; - public static final int replenishon = 852543; - public static final int request_hero = 852239; - public static final int requestsacrifice = 852201; - public static final int restoration = 852202; - public static final int restorationoff = 852204; - public static final int restorationon = 852203; - public static final int resumebuild = 851999; - public static final int resumeharvesting = 852017; - public static final int resurrection = 852094; - public static final int returnresources = 852020; - public static final int revenge = 852241; - public static final int revive = 852039; - public static final int roar = 852164; - public static final int robogoblin = 852656; - public static final int root = 852165; - public static final int sacrifice = 852205; - public static final int sanctuary = 852569; - public static final int scout = 852181; - public static final int selfdestruct = 852040; - public static final int selfdestructoff = 852042; - public static final int selfdestructon = 852041; - public static final int sentinel = 852182; - public static final int setrally = 851980; - public static final int shadowsight = 852570; - public static final int shadowstrike = 852527; - public static final int shockwave = 852125; - public static final int silence = 852592; - public static final int sleep = 852227; - public static final int slow = 852075; - public static final int slowoff = 852077; - public static final int slowon = 852076; - public static final int soulburn = 852668; - public static final int soulpreservation = 852242; - public static final int spellshield = 852571; - public static final int spellshieldaoe = 852572; - public static final int spellsteal = 852483; - public static final int spellstealoff = 852485; - public static final int spellstealon = 852484; - public static final int spies = 852235; - public static final int spiritlink = 852499; - public static final int spiritofvengeance = 852528; - public static final int spirittroll = 852573; - public static final int spiritwolf = 852126; - public static final int stampede = 852593; - public static final int standdown = 852113; - public static final int starfall = 852183; - public static final int stasistrap = 852114; - public static final int steal = 852574; - public static final int stomp = 852127; - public static final int stoneform = 852206; - public static final int stop = 851972; - public static final int submerge = 852604; - public static final int summonfactory = 852658; - public static final int summongrizzly = 852594; - public static final int summonphoenix = 852489; - public static final int summonquillbeast = 852595; - public static final int summonwareagle = 852596; - public static final int tankdroppilot = 852079; - public static final int tankloadpilot = 852080; - public static final int tankpilot = 852081; - public static final int taunt = 852520; - public static final int thunderbolt = 852095; - public static final int thunderclap = 852096; - public static final int tornado = 852597; - public static final int townbelloff = 852083; - public static final int townbellon = 852082; - public static final int tranquility = 852184; - public static final int transmute = 852665; - public static final int unavatar = 852087; - public static final int unavengerform = 852532; - public static final int unbearform = 852139; - public static final int unburrow = 852534; - public static final int uncoldarrows = 852245; - public static final int uncorporealform = 852494; - public static final int undeadbuild = 851998; - public static final int undefend = 852056; - public static final int undivineshield = 852091; - public static final int unetherealform = 852497; - public static final int unflamingarrows = 852175; - public static final int unflamingattack = 852541; - public static final int unholyfrenzy = 852209; - public static final int unimmolation = 852178; - public static final int unload = 852047; - public static final int unloadall = 852048; - public static final int unloadallcorpses = 852054; - public static final int unloadallinstant = 852049; - public static final int unpoisonarrows = 852256; - public static final int unravenform = 852156; - public static final int unrobogoblin = 852657; - public static final int unroot = 852166; - public static final int unstableconcoction = 852500; - public static final int unstoneform = 852207; - public static final int unsubmerge = 852605; - public static final int unsummon = 852210; - public static final int unwindwalk = 852130; - public static final int vengeance = 852521; - public static final int vengeanceinstant = 852524; - public static final int vengeanceoff = 852523; - public static final int vengeanceon = 852522; - public static final int volcano = 852669; - public static final int voodoo = 852503; - public static final int ward = 852504; - public static final int waterelemental = 852097; - public static final int wateryminion = 852598; - public static final int web = 852211; - public static final int weboff = 852213; - public static final int webon = 852212; - public static final int whirlwind = 852128; - public static final int windwalk = 852129; - public static final int wispharvest = 852214; -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/pathing/CBuildingPathingType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/pathing/CBuildingPathingType.java deleted file mode 100644 index b64c72ee..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/pathing/CBuildingPathingType.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing; - -import java.util.EnumSet; - -public enum CBuildingPathingType { - BLIGHTED, - UNBUILDABLE, - UNFLYABLE, - UNWALKABLE, - UNAMPH, - UNFLOAT; - - public static CBuildingPathingType parsePathingType(final String typeString) { - if ("_".equals(typeString) || "".equals(typeString)) { - return null; - } - return valueOf(typeString.toUpperCase()); - } - - public static EnumSet parsePathingTypeListSet(final String pathingListString) { - final EnumSet types = EnumSet.noneOf(CBuildingPathingType.class); - for (final String type : pathingListString.split(",")) { - final CBuildingPathingType parsedType = parsePathingType(type); - if (parsedType != null) { - types.add(parsedType); - } - } - return types; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/pathing/CPathfindingProcessor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/pathing/CPathfindingProcessor.java deleted file mode 100644 index f6b8b22d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/pathing/CPathfindingProcessor.java +++ /dev/null @@ -1,486 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing; - -import java.awt.geom.Point2D; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.PriorityQueue; - -import com.badlogic.gdx.math.Rectangle; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.MovementType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWorldCollision; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorMove; - -public class CPathfindingProcessor { - private static final Rectangle tempRect = new Rectangle(); - private final PathingGrid pathingGrid; - private final CWorldCollision worldCollision; - private final LinkedList moveQueue = new LinkedList<>(); - // things with modified state per current job: - private final Node[][] nodes; - private final Node[][] cornerNodes; - private final Node[] goalSet = new Node[4]; - private int goals = 0; - private int pathfindJobId = 0; - private int totalIterations = 0; - private int totalJobLoops = 0; - - public CPathfindingProcessor(final PathingGrid pathingGrid, final CWorldCollision worldCollision) { - this.pathingGrid = pathingGrid; - this.worldCollision = worldCollision; - this.nodes = new Node[pathingGrid.getHeight()][pathingGrid.getWidth()]; - this.cornerNodes = new Node[pathingGrid.getHeight() + 1][pathingGrid.getWidth() + 1]; - System.out.println("pathing size: "); - for (int i = 0; i < this.nodes.length; i++) { - for (int j = 0; j < this.nodes[i].length; j++) { - this.nodes[i][j] = new Node(new Point2D.Float(pathingGrid.getWorldX(j), pathingGrid.getWorldY(i))); - } - } - for (int i = 0; i < this.cornerNodes.length; i++) { - for (int j = 0; j < this.cornerNodes[i].length; j++) { - this.cornerNodes[i][j] = new Node( - new Point2D.Float(pathingGrid.getWorldXFromCorner(j), pathingGrid.getWorldYFromCorner(i))); - } - } - } - - /** - * Finds the path to a point using a naive, slow, and unoptimized algorithm. - * Does not have optimizations yet, do this for a bunch of units and it will - * probably lag like a walrus. The implementation here was created by reading - * the wikipedia article on A* to jog my memory from data structures class back - * in college, and is meant only as a first draft to get things working. - * - * @param collisionSize - * - * - * @param start - * @param goal - * @param playerIndex - * @param queueItem - * @return - */ - public void findNaiveSlowPath(final CUnit ignoreIntersectionsWithThisUnit, - final CUnit ignoreIntersectionsWithThisSecondUnit, final float startX, final float startY, - final Point2D.Float goal, final PathingGrid.MovementType movementType, final float collisionSize, - final boolean allowSmoothing, final CBehaviorMove queueItem) { - this.moveQueue.offer(new PathfindingJob(ignoreIntersectionsWithThisUnit, ignoreIntersectionsWithThisSecondUnit, - startX, startY, goal, movementType, collisionSize, allowSmoothing, queueItem)); - } - - public void removeFromPathfindingQueue(final CBehaviorMove behaviorMove) { - // TODO because of silly java things, this remove is O(N) for now, - // we could do some refactors to make it O(1) but do we care? - final Iterator iterator = this.moveQueue.iterator(); - while (iterator.hasNext()) { - final PathfindingJob job = iterator.next(); - if (job.queueItem == behaviorMove) { - iterator.remove(); - } - } - - } - - private boolean pathableBetween(final CUnit ignoreIntersectionsWithThisUnit, - final CUnit ignoreIntersectionsWithThisSecondUnit, final float startX, final float startY, - final PathingGrid.MovementType movementType, final float collisionSize, final float x, final float y) { - return this.pathingGrid.isPathable(x, y, movementType, collisionSize) - && this.pathingGrid.isPathable(startX, y, movementType, collisionSize) - && this.pathingGrid.isPathable(x, startY, movementType, collisionSize) - && isPathableDynamically(x, y, ignoreIntersectionsWithThisUnit, ignoreIntersectionsWithThisSecondUnit, - movementType) - && isPathableDynamically(x, startY, ignoreIntersectionsWithThisUnit, - ignoreIntersectionsWithThisSecondUnit, movementType) - && isPathableDynamically(startX, y, ignoreIntersectionsWithThisUnit, - ignoreIntersectionsWithThisSecondUnit, movementType); - } - - private boolean isPathableDynamically(final float x, final float y, final CUnit ignoreIntersectionsWithThisUnit, - final CUnit ignoreIntersectionsWithThisSecondUnit, final PathingGrid.MovementType movementType) { - return !this.worldCollision.intersectsAnythingOtherThan(tempRect.setCenter(x, y), - ignoreIntersectionsWithThisUnit, ignoreIntersectionsWithThisSecondUnit, movementType); - } - - public static boolean isCollisionSizeBetterSuitedForCorners(final float collisionSize) { - return (((2 * (int) collisionSize) / 32) % 2) == 1; - } - - public double f(final Node n) { - return n.g + h(n); - } - - public double g(final Node n) { - return n.g; - } - - private boolean isGoal(final Node n) { - for (int i = 0; i < this.goals; i++) { - if (n == this.goalSet[i]) { - return true; - } - } - return false; - } - - public float h(final Node n) { - float bestDistance = 0; - for (int i = 0; i < this.goals; i++) { - final float possibleDistance = (float) n.point.distance(this.goalSet[i].point); - if (possibleDistance > bestDistance) { - bestDistance = possibleDistance; // always overestimate - } - } - return bestDistance; - } - - public static final class Node { - public Direction cameFromDirection; - private final Point2D.Float point; - private double f; - private double g; - private Node cameFrom; - private int pathfindJobId; - - private Node(final Point2D.Float point) { - this.point = point; - } - - private void touch(final int pathfindJobId) { - if (pathfindJobId != this.pathfindJobId) { - this.g = Float.POSITIVE_INFINITY; - this.f = Float.POSITIVE_INFINITY; - this.cameFrom = null; - this.cameFromDirection = null; - this.pathfindJobId = pathfindJobId; - } - } - } - - private static enum Direction { - NORTH_WEST(-1, 1), - NORTH(0, 1), - NORTH_EAST(1, 1), - EAST(1, 0), - SOUTH_EAST(1, -1), - SOUTH(0, -1), - SOUTH_WEST(-1, -1), - WEST(-1, 0); - - public static final Direction[] VALUES = values(); - - private final int xOffset; - private final int yOffset; - private final double length; - - private Direction(final int xOffset, final int yOffset) { - this.xOffset = xOffset; - this.yOffset = yOffset; - final double sqrt = Math.sqrt((xOffset * xOffset) + (yOffset * yOffset)); - this.length = sqrt; - } - } - - public static interface GridMapping { - int getX(PathingGrid grid, float worldX); - - int getY(PathingGrid grid, float worldY); - - public static final GridMapping CELLS = new GridMapping() { - @Override - public int getX(final PathingGrid grid, final float worldX) { - return grid.getCellX(worldX); - } - - @Override - public int getY(final PathingGrid grid, final float worldY) { - return grid.getCellY(worldY); - } - - }; - - public static final GridMapping CORNERS = new GridMapping() { - @Override - public int getX(final PathingGrid grid, final float worldX) { - return grid.getCornerX(worldX); - } - - @Override - public int getY(final PathingGrid grid, final float worldY) { - return grid.getCornerY(worldY); - } - - }; - } - - public void update(final CSimulation simulation) { - int workIterations = 0; - JobsLoop: while (!this.moveQueue.isEmpty()) { - this.totalJobLoops++; - final PathfindingJob job = this.moveQueue.peek(); - if (!job.jobStarted) { - this.pathfindJobId++; - this.totalIterations = 0; - this.totalJobLoops = 0; - job.jobStarted = true; - System.out.println("starting job with smoothing=" + job.allowSmoothing); - workIterations += 5; // setup of job predicted cost - job.goalX = job.goal.x; - job.goalY = job.goal.y; - job.weightForHittingWalls = 1E9f; - if (!this.pathingGrid.isPathable(job.goalX, job.goalY, job.movementType, job.collisionSize) - || !isPathableDynamically(job.goalX, job.goalY, job.ignoreIntersectionsWithThisUnit, - job.ignoreIntersectionsWithThisSecondUnit, job.movementType)) { - job.weightForHittingWalls = 5E2f; - } - System.out.println("beginning findNaiveSlowPath for " + job.startX + "," + job.startY + "," + job.goalX - + "," + job.goalY); - if ((job.startX == job.goalX) && (job.startY == job.goalY)) { - job.queueItem.pathFound(Collections.emptyList(), simulation); - this.moveQueue.poll(); - continue JobsLoop; - } - tempRect.set(0, 0, job.collisionSize * 2, job.collisionSize * 2); - if (isCollisionSizeBetterSuitedForCorners(job.collisionSize)) { - job.searchGraph = this.cornerNodes; - job.gridMapping = GridMapping.CORNERS; - System.out.println("using corners"); - } - else { - job.searchGraph = this.nodes; - job.gridMapping = GridMapping.CELLS; - System.out.println("using cells"); - } - final int goalCellY = job.gridMapping.getY(this.pathingGrid, job.goalY); - final int goalCellX = job.gridMapping.getX(this.pathingGrid, job.goalX); - final Node mostLikelyGoal = job.searchGraph[goalCellY][goalCellX]; - mostLikelyGoal.touch(this.pathfindJobId); - final double bestGoalDistance = mostLikelyGoal.point.distance(job.goalX, job.goalY); - Arrays.fill(this.goalSet, null); - this.goals = 0; - for (int i = goalCellX - 1; i <= (goalCellX + 1); i++) { - for (int j = goalCellY - 1; j <= (goalCellY + 1); j++) { - final Node possibleGoal = job.searchGraph[j][i]; - possibleGoal.touch(this.pathfindJobId); - if (possibleGoal.point.distance(job.goalX, job.goalY) <= bestGoalDistance) { - this.goalSet[this.goals++] = possibleGoal; - } - } - } - final int startGridY = job.gridMapping.getY(this.pathingGrid, job.startY); - final int startGridX = job.gridMapping.getX(this.pathingGrid, job.startX); - job.openSet = new PriorityQueue<>(new Comparator() { - @Override - public int compare(final Node a, final Node b) { - return Double.compare(f(a), f(b)); - } - }); - - job.start = job.searchGraph[startGridY][startGridX]; - job.start.touch(this.pathfindJobId); - if (job.startX > job.start.point.x) { - job.startGridMinX = startGridX; - job.startGridMaxX = startGridX + 1; - } - else if (job.startX < job.start.point.x) { - job.startGridMinX = startGridX - 1; - job.startGridMaxX = startGridX; - } - else { - job.startGridMinX = startGridX; - job.startGridMaxX = startGridX; - } - if (job.startY > job.start.point.y) { - job.startGridMinY = startGridY; - job.startGridMaxY = startGridY + 1; - } - else if (job.startY < job.start.point.y) { - job.startGridMinY = startGridY - 1; - job.startGridMaxY = startGridY; - } - else { - job.startGridMinY = startGridY; - job.startGridMaxY = startGridY; - } - for (int cellX = job.startGridMinX; cellX <= job.startGridMaxX; cellX++) { - for (int cellY = job.startGridMinY; cellY <= job.startGridMaxY; cellY++) { - if ((cellX >= 0) && (cellX < this.pathingGrid.getWidth()) && (cellY >= 0) - && (cellY < this.pathingGrid.getHeight())) { - final Node possibleNode = job.searchGraph[cellY][cellX]; - possibleNode.touch(this.pathfindJobId); - final float x = possibleNode.point.x; - final float y = possibleNode.point.y; - if (pathableBetween(job.ignoreIntersectionsWithThisUnit, - job.ignoreIntersectionsWithThisSecondUnit, job.startX, job.startY, job.movementType, - job.collisionSize, x, y)) { - - final double tentativeScore = possibleNode.point.distance(job.startX, job.startY); - possibleNode.g = tentativeScore; - possibleNode.f = tentativeScore + h(possibleNode); - job.openSet.add(possibleNode); - - } - else { - final double tentativeScore = job.weightForHittingWalls; - possibleNode.g = tentativeScore; - possibleNode.f = tentativeScore + h(possibleNode); - job.openSet.add(possibleNode); - - } - } - } - } - } - - while (!job.openSet.isEmpty()) { - Node current = job.openSet.poll(); - current.touch(this.pathfindJobId); - if (isGoal(current)) { - final LinkedList totalPath = new LinkedList<>(); - Direction lastCameFromDirection = null; - - if ((current.cameFrom != null) - && pathableBetween(job.ignoreIntersectionsWithThisUnit, - job.ignoreIntersectionsWithThisSecondUnit, current.point.x, current.point.y, - job.movementType, job.collisionSize, job.goalX, job.goalY) - && pathableBetween(job.ignoreIntersectionsWithThisUnit, - job.ignoreIntersectionsWithThisSecondUnit, current.cameFrom.point.x, - current.cameFrom.point.y, job.movementType, job.collisionSize, current.point.x, - current.point.y) - && pathableBetween(job.ignoreIntersectionsWithThisUnit, - job.ignoreIntersectionsWithThisSecondUnit, current.cameFrom.point.x, - current.cameFrom.point.y, job.movementType, job.collisionSize, job.goalX, job.goalY) - && job.allowSmoothing) { - // do some basic smoothing to walk straight to the goal if it is not obstructed, - // skipping the last grid location - totalPath.addFirst(job.goal); - current = current.cameFrom; - } - else { - totalPath.addFirst(job.goal); - totalPath.addFirst(current.point); - } - lastCameFromDirection = current.cameFromDirection; - Node lastNode = null; - while (current.cameFrom != null) { - lastNode = current; - current = current.cameFrom; - if ((lastCameFromDirection == null) || (current.cameFromDirection != lastCameFromDirection) - || (current.cameFromDirection == null)) { - if ((current.cameFromDirection != null) || (lastNode == null) - || !pathableBetween(job.ignoreIntersectionsWithThisUnit, - job.ignoreIntersectionsWithThisSecondUnit, job.startX, job.startY, - job.movementType, job.collisionSize, current.point.x, current.point.y) - || !pathableBetween(job.ignoreIntersectionsWithThisUnit, - job.ignoreIntersectionsWithThisSecondUnit, current.point.x, current.point.y, - job.movementType, job.collisionSize, lastNode.point.x, lastNode.point.y) - || !pathableBetween(job.ignoreIntersectionsWithThisUnit, - job.ignoreIntersectionsWithThisSecondUnit, job.startX, job.startY, - job.movementType, job.collisionSize, lastNode.point.x, lastNode.point.y) - || !job.allowSmoothing) { - // Add the point if it's not the first one, or if we can only complete - // the journey by specifically walking to the first one - totalPath.addFirst(current.point); - lastCameFromDirection = current.cameFromDirection; - } - } - } - job.queueItem.pathFound(totalPath, simulation); - this.moveQueue.poll(); - System.out.println("Task " + this.pathfindJobId + " took " + this.totalIterations - + " iterations and " + this.totalJobLoops + " job loops!"); - continue JobsLoop; - } - - for (final Direction direction : Direction.VALUES) { - final float x = current.point.x + (direction.xOffset * 32); - final float y = current.point.y + (direction.yOffset * 32); - if (this.pathingGrid.contains(x, y)) { - double turnCost; - if ((current.cameFromDirection != null) && (direction != current.cameFromDirection)) { - turnCost = 0.25; - } - else { - turnCost = 0; - } - double tentativeScore = current.g + ((direction.length + turnCost) * 32); - if (!pathableBetween(job.ignoreIntersectionsWithThisUnit, - job.ignoreIntersectionsWithThisSecondUnit, current.point.x, current.point.y, - job.movementType, job.collisionSize, x, y)) { - tentativeScore += (direction.length) * job.weightForHittingWalls; - } - final Node neighbor = job.searchGraph[job.gridMapping.getY(this.pathingGrid, y)][job.gridMapping - .getX(this.pathingGrid, x)]; - neighbor.touch(this.pathfindJobId); - if (tentativeScore < neighbor.g) { - neighbor.cameFrom = current; - neighbor.cameFromDirection = direction; - neighbor.g = tentativeScore; - neighbor.f = tentativeScore + h(neighbor); - if (!job.openSet.contains(neighbor)) { - job.openSet.add(neighbor); - } - } - } - } - workIterations++; - this.totalIterations++; - if (this.totalIterations > 20000) { - break; - } - if (workIterations >= 1500) { - // breaking jobs loop will implicitly exit without calling pathFound() below - break JobsLoop; - } - } - job.queueItem.pathFound(Collections.emptyList(), simulation); - this.moveQueue.poll(); - System.out.println("Task " + this.pathfindJobId + " took " + this.totalIterations + " iterations and " - + this.totalJobLoops + " job loops!"); - } - } - - public static final class PathfindingJob { - private final CUnit ignoreIntersectionsWithThisUnit; - private final CUnit ignoreIntersectionsWithThisSecondUnit; - private final float startX; - private final float startY; - private final Point2D.Float goal; - private final MovementType movementType; - private final float collisionSize; - private final boolean allowSmoothing; - private final CBehaviorMove queueItem; - private boolean jobStarted; - public float goalY; - public float goalX; - public float weightForHittingWalls; - Node[][] searchGraph; - GridMapping gridMapping; - PriorityQueue openSet; - Node start; - int startGridMinX; - int startGridMinY; - int startGridMaxX; - int startGridMaxY; - - public PathfindingJob(final CUnit ignoreIntersectionsWithThisUnit, - final CUnit ignoreIntersectionsWithThisSecondUnit, final float startX, final float startY, - final Point2D.Float goal, final PathingGrid.MovementType movementType, final float collisionSize, - final boolean allowSmoothing, final CBehaviorMove queueItem) { - this.ignoreIntersectionsWithThisUnit = ignoreIntersectionsWithThisUnit; - this.ignoreIntersectionsWithThisSecondUnit = ignoreIntersectionsWithThisSecondUnit; - this.startX = startX; - this.startY = startY; - this.goal = goal; - this.movementType = movementType; - this.collisionSize = collisionSize; - this.allowSmoothing = allowSmoothing; - this.queueItem = queueItem; - this.jobStarted = false; - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CAllianceType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CAllianceType.java deleted file mode 100644 index ea1f28a0..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CAllianceType.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -public enum CAllianceType { - PASSIVE, - HELP_REQUEST, - HELP_RESPONSE, - SHARED_XP, - SHARED_SPELLS, - SHARED_VISION, - SHARED_CONTROL, - SHARED_ADVANCED_CONTROL, - RESCUABLE, - SHARED_VISION_FORCED; - - public static CAllianceType[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapControl.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapControl.java deleted file mode 100644 index 423e4580..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapControl.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -public enum CMapControl { - USER, - COMPUTER, - RESCUABLE, - NEUTRAL, - CREEP, - NONE; - - public static CMapControl[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapFlag.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapFlag.java deleted file mode 100644 index f001bc81..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapFlag.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -public enum CMapFlag { - MAP_FOG_HIDE_TERRAIN, - MAP_FOG_MAP_EXPLORED, - MAP_FOG_ALWAYS_VISIBLE, - - MAP_USE_HANDICAPS, - MAP_OBSERVERS, - MAP_OBSERVERS_ON_DEATH, - - MAP_FIXED_COLORS, - - MAP_LOCK_RESOURCE_TRADING, - MAP_RESOURCE_TRADING_ALLIES_ONLY, - - MAP_LOCK_ALLIANCE_CHANGES, - MAP_ALLIANCE_CHANGES_HIDDEN, - - MAP_CHEATS, - MAP_CHEATS_HIDDEN, - - MAP_LOCK_SPEED, - MAP_LOCK_RANDOM_SEED, - MAP_SHARED_ADVANCED_CONTROL, - MAP_RANDOM_HERO, - MAP_RANDOM_RACES, - MAP_RELOADED; - - public static CMapFlag[] VALUES = values(); - - public static CMapFlag getById(final int id) { - for (final CMapFlag type : VALUES) { - if ((type.getId()) == id) { - return type; - } - } - return null; - } - - public int getId() { - return 1 << ordinal(); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapPlacement.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapPlacement.java deleted file mode 100644 index 29eb00e8..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CMapPlacement.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -public enum CMapPlacement { - RANDOM, - FIXED, - USE_MAP_SETTINGS, - TEAMS_TOGETHER; - - public static CMapPlacement[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayer.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayer.java deleted file mode 100644 index 0bf8ea42..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayer.java +++ /dev/null @@ -1,223 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.trigger.RemovableTriggerEvent; -import com.etheller.interpreter.ast.scope.trigger.Trigger; -import com.etheller.warsmash.parsers.jass.scope.CommonTriggerExecutionScope; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CPlayerStateListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CPlayerStateListener.CPlayerStateNotifier; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.CBasePlayer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.JassGameEventsWar3; - -public class CPlayer extends CBasePlayer { - private final CRace race; - private final float[] startLocation; - private int gold = 500; - private int lumber = 150; - private int foodCap; - private int foodUsed; - private final Map rawcodeToTechtreeUnlocked = new HashMap<>(); - private final List heroes = new ArrayList<>(); - private final EnumMap> eventTypeToEvents = new EnumMap<>( - JassGameEventsWar3.class); - - // if you use triggers for this then the transient tag here becomes really - // questionable -- it already was -- but I meant for those to inform us - // which fields shouldn't be persisted if we do game state save later - private transient CPlayerStateNotifier stateNotifier = new CPlayerStateNotifier(); - - public CPlayer(final CRace race, final float[] startLocation, final CBasePlayer configPlayer) { - super(configPlayer); - this.race = race; - this.startLocation = startLocation; - } - - public void setAlliance(final CPlayer other, final CAllianceType alliance, final boolean flag) { - setAlliance(other.getId(), alliance, flag); - } - - public CRace getRace() { - return this.race; - } - - public int getGold() { - return this.gold; - } - - public int getLumber() { - return this.lumber; - } - - public int getFoodCap() { - return this.foodCap; - } - - public int getFoodUsed() { - return this.foodUsed; - } - - public float[] getStartLocation() { - return this.startLocation; - } - - public void setGold(final int gold) { - this.gold = gold; - this.stateNotifier.goldChanged(); - } - - public void setLumber(final int lumber) { - this.lumber = lumber; - this.stateNotifier.lumberChanged(); - } - - public void setFoodCap(final int foodCap) { - this.foodCap = foodCap; - this.stateNotifier.foodChanged(); - } - - public void setFoodUsed(final int foodUsed) { - this.foodUsed = foodUsed; - this.stateNotifier.foodChanged(); - } - - public int getTechtreeUnlocked(final War3ID rawcode) { - final Integer techtreeUnlocked = this.rawcodeToTechtreeUnlocked.get(rawcode); - if (techtreeUnlocked == null) { - return 0; - } - return techtreeUnlocked; - } - - public void addTechtreeUnlocked(final War3ID rawcode) { - final Integer techtreeUnlocked = this.rawcodeToTechtreeUnlocked.get(rawcode); - if (techtreeUnlocked == null) { - this.rawcodeToTechtreeUnlocked.put(rawcode, 1); - } - else { - this.rawcodeToTechtreeUnlocked.put(rawcode, techtreeUnlocked + 1); - } - } - - public void removeTechtreeUnlocked(final War3ID rawcode) { - final Integer techtreeUnlocked = this.rawcodeToTechtreeUnlocked.get(rawcode); - if (techtreeUnlocked == null) { - this.rawcodeToTechtreeUnlocked.put(rawcode, -1); - } - else { - this.rawcodeToTechtreeUnlocked.put(rawcode, techtreeUnlocked - 1); - } - } - - public void addStateListener(final CPlayerStateListener listener) { - this.stateNotifier.subscribe(listener); - } - - public void removeStateListener(final CPlayerStateListener listener) { - this.stateNotifier.unsubscribe(listener); - } - - public void chargeFor(final CUnitType unitType) { - this.lumber -= unitType.getLumberCost(); - this.gold -= unitType.getGoldCost(); - this.stateNotifier.lumberChanged(); - this.stateNotifier.goldChanged(); - } - - public boolean charge(final int gold, final int lumber) { - if ((this.lumber >= lumber) && (this.gold >= gold)) { - this.lumber -= lumber; - this.gold -= gold; - this.stateNotifier.lumberChanged(); - this.stateNotifier.goldChanged(); - return true; - } - return false; - } - - public void refundFor(final CUnitType unitType) { - this.lumber += unitType.getLumberCost(); - this.gold += unitType.getGoldCost(); - this.stateNotifier.lumberChanged(); - this.stateNotifier.goldChanged(); - } - - public void refund(final int gold, final int lumber) { - this.gold += gold; - this.lumber += lumber; - this.stateNotifier.lumberChanged(); - this.stateNotifier.goldChanged(); - } - - public void setUnitFoodUsed(final CUnit unit, final int foodUsed) { - this.foodUsed += unit.setFoodUsed(foodUsed); - this.stateNotifier.foodChanged(); - } - - public void setUnitFoodMade(final CUnit unit, final int foodMade) { - this.foodCap += unit.setFoodMade(foodMade); - this.stateNotifier.foodChanged(); - } - - public void onHeroDeath(final CUnit hero) { - this.stateNotifier.heroDeath(); - firePlayerUnitEvents(hero, CommonTriggerExecutionScope.playerHeroRevivableScope(hero), - JassGameEventsWar3.EVENT_PLAYER_HERO_REVIVABLE); - } - - private void firePlayerUnitEvents(final CUnit hero, final CommonTriggerExecutionScope eventScope, - final JassGameEventsWar3 eventType) { - final List eventList = getEventList(eventType); - if (eventList != null) { - for (final CPlayerEvent event : eventList) { - event.fire(hero, eventScope); - } - } - } - - public List getHeroes() { - return this.heroes; - } - - public void fireHeroLevelEvents(final CUnit hero) { - firePlayerUnitEvents(hero, CommonTriggerExecutionScope.playerHeroRevivableScope(hero), - JassGameEventsWar3.EVENT_PLAYER_HERO_LEVEL); - } - - private List getOrCreateEventList(final JassGameEventsWar3 eventType) { - List playerEvents = this.eventTypeToEvents.get(eventType); - if (playerEvents == null) { - playerEvents = new ArrayList<>(); - this.eventTypeToEvents.put(eventType, playerEvents); - } - return playerEvents; - } - - private List getEventList(final JassGameEventsWar3 eventType) { - return this.eventTypeToEvents.get(eventType); - } - - @Override - public RemovableTriggerEvent addEvent(final GlobalScope globalScope, final Trigger whichTrigger, - final JassGameEventsWar3 eventType) { - final CPlayerEvent playerEvent = new CPlayerEvent(globalScope, this, whichTrigger, eventType); - getOrCreateEventList(eventType).add(playerEvent); - return playerEvent; - } - - @Override - public void removeEvent(final CPlayerEvent playerEvent) { - final List eventList = getEventList(playerEvent.getEventType()); - if (eventList != null) { - eventList.remove(playerEvent); - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerColor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerColor.java deleted file mode 100644 index 20cfcf6e..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerColor.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -public enum CPlayerColor { - RED, - BLUE, - CYAN, - PURPLE, - YELLOW, - ORANGE, - GREEN, - PINK, - LIGHT_GRAY, - LIGHT_BLUE, - AQUA, - BROWN; - - public static CPlayerColor[] VALUES = values(); - - public static CPlayerColor getColorByIndex(final int index) { - if ((index >= 0) && (index < VALUES.length)) { - return VALUES[index]; - } - return null; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerEvent.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerEvent.java deleted file mode 100644 index ce67ff30..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerEvent.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.scope.trigger.RemovableTriggerEvent; -import com.etheller.interpreter.ast.scope.trigger.Trigger; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.JassGameEventsWar3; - -public class CPlayerEvent implements RemovableTriggerEvent { - private final GlobalScope globalScope; - private final CPlayerJass player; - private final Trigger trigger; - private final JassGameEventsWar3 eventType; - - public CPlayerEvent(final GlobalScope globalScope, final CPlayerJass player, final Trigger trigger, - final JassGameEventsWar3 eventType) { - this.globalScope = globalScope; - this.player = player; - this.trigger = trigger; - this.eventType = eventType; - } - - public Trigger getTrigger() { - return this.trigger; - } - - public JassGameEventsWar3 getEventType() { - return this.eventType; - } - - @Override - public void remove() { - this.player.removeEvent(this); - } - - public void fire(final CUnit hero, final TriggerExecutionScope scope) { - this.trigger.evaluate(this.globalScope, scope); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerGameResult.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerGameResult.java deleted file mode 100644 index e713d5cc..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerGameResult.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -public enum CPlayerGameResult { - VICTORY, - DEFEAT, - TIE, - NEUTRAL; - - public static CPlayerGameResult[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerJass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerJass.java deleted file mode 100644 index 3229ec57..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerJass.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.trigger.RemovableTriggerEvent; -import com.etheller.interpreter.ast.scope.trigger.Trigger; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.JassGameEventsWar3; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes.CPlayerSlotState; - -public interface CPlayerJass { - int getId(); - - void setTeam(int team); - - void setStartLocationIndex(int startLocIndex); - - void forceStartLocation(int startLocIndex); - - void setColor(int colorIndex); - - void setAlliance(int otherPlayerIndex, CAllianceType whichAllianceSetting, boolean value); - - boolean hasAlliance(int otherPlayerIndex, CAllianceType allianceType); - - void setTaxRate(int otherPlayerIndex, CPlayerState whichResource, int rate); - - void setRacePref(CRacePreference whichRacePreference); - - void setRaceSelectable(boolean selectable); - - void setController(CMapControl mapControl); - - void setName(String name); - - void setOnScoreScreen(boolean flag); - - int getTeam(); - - int getStartLocationIndex(); - - int getColor(); - - boolean isSelectable(); - - CMapControl getController(); - - CPlayerSlotState getSlotState(); - - int getTaxRate(int otherPlayerIndex, CPlayerState whichResource); - - boolean isRacePrefSet(CRacePreference pref); - - String getName(); - - RemovableTriggerEvent addEvent(final GlobalScope globalScope, final Trigger whichTrigger, - final JassGameEventsWar3 eventType); - - void removeEvent(CPlayerEvent playerEvent); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerScore.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerScore.java deleted file mode 100644 index f0950d8c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerScore.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -public enum CPlayerScore { - UNITS_TRAINED, - UNITS_KILLED, - STRUCT_BUILT, - STRUCT_RAZED, - TECH_PERCENT, - FOOD_MAXPROD, - FOOD_MAXUSED, - HEROES_KILLED, - ITEMS_GAINED, - MERCS_HIRED, - GOLD_MINED_TOTAL, - GOLD_MINED_UPKEEP, - GOLD_LOST_UPKEEP, - GOLD_LOST_TAX, - GOLD_GIVEN, - GOLD_RECEIVED, - LUMBER_TOTAL, - LUMBER_LOST_UPKEEP, - LUMBER_LOST_TAX, - LUMBER_GIVEN, - LUMBER_RECEIVED, - UNIT_TOTAL, - HERO_TOTAL, - RESOURCE_TOTAL, - TOTAL; - - public static CPlayerScore[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerState.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerState.java deleted file mode 100644 index 9965b4fa..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerState.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -public enum CPlayerState { - // current resource levels - // - RESOURCE_GOLD, - RESOURCE_LUMBER, - RESOURCE_HERO_TOKENS, - RESOURCE_FOOD_CAP, - RESOURCE_FOOD_USED, - FOOD_CAP_CEILING, - - GIVES_BOUNTY, - ALLIED_VICTORY, - PLACED, - OBSERVER_ON_DEATH, - OBSERVER, - UNFOLLOWABLE, - - // taxation rate for each resource - // - GOLD_UPKEEP_RATE, - LUMBER_UPKEEP_RATE, - - // cumulative resources collected by the player during the mission - // - GOLD_GATHERED, - LUMBER_GATHERED, - - UNKNOWN_STATE_17, - UNKNOWN_STATE_18, - UNKNOWN_STATE_19, - UNKNOWN_STATE_20, - UNKNOWN_STATE_21, - UNKNOWN_STATE_22, - UNKNOWN_STATE_23, - UNKNOWN_STATE_24, - - NO_CREEP_SLEEP; - - public static CPlayerState[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerUnitOrderExecutor.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerUnitOrderExecutor.java deleted file mode 100644 index f15b849f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerUnitOrderExecutor.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.behaviors.CBehaviorHoldPosition; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrderDropItemAtPoint; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrderNoTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrderTargetPoint; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrderTargetWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; - -public class CPlayerUnitOrderExecutor implements CPlayerUnitOrderListener { - private final CSimulation game; - private final int playerIndex; - - public CPlayerUnitOrderExecutor(final CSimulation game, final int playerIndex) { - this.game = game; - this.playerIndex = playerIndex; - } - - @Override - public void issueTargetOrder(final int unitHandleId, final int abilityHandleId, final int orderId, - final int targetHandleId, final boolean queue) { - final CUnit unit = this.game.getUnit(unitHandleId); - if (this.playerIndex == unit.getPlayerIndex()) { - unit.order(this.game, new COrderTargetWidget(abilityHandleId, orderId, targetHandleId, queue), queue); - } - } - - @Override - public void issueDropItemAtPointOrder(final int unitHandleId, final int abilityHandleId, final int orderId, - final int targetHandleId, final float x, final float y, final boolean queue) { - final CUnit unit = this.game.getUnit(unitHandleId); - if (this.playerIndex == unit.getPlayerIndex()) { - unit.order(this.game, new COrderDropItemAtPoint(abilityHandleId, orderId, targetHandleId, - new AbilityPointTarget(x, y), queue), queue); - } - } - - @Override - public void issuePointOrder(final int unitHandleId, final int abilityHandleId, final int orderId, final float x, - final float y, final boolean queue) { - final CUnit unit = this.game.getUnit(unitHandleId); - if (this.playerIndex == unit.getPlayerIndex()) { - unit.order(this.game, new COrderTargetPoint(abilityHandleId, orderId, new AbilityPointTarget(x, y), queue), - queue); - } - } - - @Override - public void issueImmediateOrder(final int unitHandleId, final int abilityHandleId, final int orderId, - final boolean queue) { - final CUnit unit = this.game.getUnit(unitHandleId); - if (this.playerIndex == unit.getPlayerIndex()) { - if (abilityHandleId == 0) { - if (orderId == OrderIds.stop) { - unit.order(this.game, null, queue); - } - else if (orderId == OrderIds.holdposition) { - unit.order(this.game, null, queue); - final CBehaviorHoldPosition holdPositionBehavior = unit.getHoldPositionBehavior(); - if (holdPositionBehavior != null) { - unit.setDefaultBehavior(holdPositionBehavior); - } - } - } - else { - unit.order(this.game, new COrderNoTarget(abilityHandleId, orderId, queue), queue); - } - } - } - - @Override - public void unitCancelTrainingItem(final int unitHandleId, final int cancelIndex) { - final CUnit unit = this.game.getUnit(unitHandleId); - if (this.playerIndex == unit.getPlayerIndex()) { - unit.cancelBuildQueueItem(this.game, cancelIndex); - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerUnitOrderListener.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerUnitOrderListener.java deleted file mode 100644 index 7cf6e323..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CPlayerUnitOrderListener.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -public interface CPlayerUnitOrderListener { - void issueTargetOrder(int unitHandleId, int abilityHandleId, int orderId, int targetHandleId, boolean queue); - - void issuePointOrder(int unitHandleId, int abilityHandleId, int orderId, float x, float y, boolean queue); - - void issueDropItemAtPointOrder(int unitHandleId, int abilityHandleId, int orderId, int targetHandleId, float x, - float y, final boolean queue); - - void issueImmediateOrder(int unitHandleId, int abilityHandleId, int orderId, boolean queue); - - void unitCancelTrainingItem(int unitHandleId, int cancelIndex); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRace.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRace.java deleted file mode 100644 index 9043d910..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRace.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -public enum CRace { - HUMAN(1), - ORC(2), - UNDEAD(3), - NIGHTELF(4), - DEMON(5), - OTHER(7); - - private int id; - - private CRace(final int id) { - this.id = id; - } - - public static CRace[] VALUES = values(); - - public int getId() { - return this.id; - } - - public static CRace parseRace(final int race) { - // TODO: this is bad time complexity (slow) but we're only doing it on startup - for (final CRace raceEnum : values()) { - if (raceEnum.getId() == race) { - return raceEnum; - } - } - return null; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRacePreference.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRacePreference.java deleted file mode 100644 index 24ff6ac8..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CRacePreference.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -public enum CRacePreference { - HUMAN, - ORC, - NIGHTELF, - UNDEAD, - DEMON, - RANDOM, - USER_SELECTABLE; - - public static CRacePreference[] VALUES = values(); - - public static CRacePreference getById(final int id) { - for (final CRacePreference type : VALUES) { - if ((type.getId()) == id) { - return type; - } - } - return null; - } - - public int getId() { - return 1 << ordinal(); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CStartLocPrio.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CStartLocPrio.java deleted file mode 100644 index 99d70082..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/players/CStartLocPrio.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.players; - -public enum CStartLocPrio { - LOW, - HIGH, - NOT; - - public static CStartLocPrio[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegion.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegion.java deleted file mode 100644 index 9c0562ab..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegion.java +++ /dev/null @@ -1,159 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.region; - -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.math.Rectangle; -import com.etheller.interpreter.ast.scope.trigger.RemovableTriggerEvent; - -public class CRegion { - private Rectangle currentBounds; - private boolean complexRegion; - private final List enterTriggers = new ArrayList<>(); - private final List leaveTriggers = new ArrayList<>(); - - public void addRect(final Rectangle rect, final CRegionManager regionManager) { - if (this.currentBounds == null) { - this.currentBounds = new Rectangle(rect); - regionManager.addRectForRegion(this, this.currentBounds); - } - else { - if (!this.complexRegion) { - convertToComplexRegionAndAddRect(rect, regionManager); - } - else { - complexRegionAddRect(rect, regionManager); - } - } - } - - public void clearRect(final Rectangle rect, final CRegionManager regionManager) { - if (this.currentBounds == null) { - return; - } - if (this.complexRegion) { - regionManager.removeRectForRegion(this, this.currentBounds); - regionManager.removeComplexRegionCells(this, rect); - regionManager.computeNewMinimumComplexRegionBounds(this, this.currentBounds); - regionManager.addRectForRegion(this, this.currentBounds); - } - else { - this.complexRegion = true; - regionManager.addComplexRegionCells(this, this.currentBounds); - regionManager.removeComplexRegionCells(this, rect); - } - } - - public void remove(final CRegionManager regionManager) { - if (this.currentBounds == null) { - return; - } - if (this.complexRegion) { - regionManager.removeComplexRegionCells(this, this.currentBounds); - } - regionManager.removeRectForRegion(this, this.currentBounds); - } - - public void addCell(final float x, final float y, final CRegionManager regionManager) { - if (this.currentBounds == null) { - this.complexRegion = true; - this.currentBounds = new Rectangle(x, y, 0, 0); - regionManager.addComplexRegionCell(this, x, y, this.currentBounds); - regionManager.addRectForRegion(this, this.currentBounds); - } - else { - regionManager.removeRectForRegion(this, this.currentBounds); - if (!this.complexRegion) { - regionManager.addComplexRegionCells(this, this.currentBounds); - this.complexRegion = true; - } - regionManager.addComplexRegionCell(this, x, y, this.currentBounds); - regionManager.addRectForRegion(this, this.currentBounds); - } - } - - public void clearCell(final float x, final float y, final CRegionManager regionManager) { - if (this.currentBounds == null) { - return; - } - else { - regionManager.removeRectForRegion(this, this.currentBounds); - if (!this.complexRegion) { - regionManager.addComplexRegionCells(this, this.currentBounds); - this.complexRegion = true; - } - regionManager.clearComplexRegionCell(this, x, y, this.currentBounds); - regionManager.addRectForRegion(this, this.currentBounds); - } - } - - private void complexRegionAddRect(final Rectangle rect, final CRegionManager regionManager) { - regionManager.removeRectForRegion(this, this.currentBounds); - regionManager.addComplexRegionCells(this, rect); - this.currentBounds = this.currentBounds.merge(rect); - regionManager.addRectForRegion(this, this.currentBounds); - } - - private void convertToComplexRegionAndAddRect(final Rectangle rect, final CRegionManager regionManager) { - regionManager.removeRectForRegion(this, this.currentBounds); - this.complexRegion = true; - regionManager.addComplexRegionCells(this, this.currentBounds); - regionManager.addComplexRegionCells(this, rect); - this.currentBounds = this.currentBounds.merge(rect); - regionManager.addRectForRegion(this, this.currentBounds); - } - - public Rectangle getCurrentBounds() { - return this.currentBounds; - } - - public void setCurrentBounds(final Rectangle currentBounds) { - this.currentBounds = currentBounds; - } - - public boolean isComplexRegion() { - return this.complexRegion; - } - - public void setComplexRegion(final boolean complexRegion) { - this.complexRegion = complexRegion; - } - - public boolean contains(final float x, final float y, final CRegionManager regionManager) { - if (this.currentBounds == null) { - return false; - } - if (this.complexRegion) { - return regionManager.isPointInComplexRegion(this, x, y); - } - return this.currentBounds.contains(x, y); - } - - public List getEnterTriggers() { - return this.enterTriggers; - } - - public List getLeaveTriggers() { - return this.leaveTriggers; - } - - public RemovableTriggerEvent add(final CRegionTriggerEnter triggerEnter) { - this.enterTriggers.add(triggerEnter); - return new RemovableTriggerEvent() { - @Override - public void remove() { - CRegion.this.enterTriggers.remove(triggerEnter); - } - }; - } - - public RemovableTriggerEvent add(final CRegionTriggerLeave leaveTrigger) { - this.leaveTriggers.add(leaveTrigger); - return new RemovableTriggerEvent() { - @Override - public void remove() { - CRegion.this.leaveTriggers.remove(leaveTrigger); - } - }; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionEnumFunction.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionEnumFunction.java deleted file mode 100644 index 8cf61352..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionEnumFunction.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.region; - -public interface CRegionEnumFunction { - /** - * Operates on a region, returning true if we should stop execution. - * - * @param region - * @return - */ - boolean call(CRegion region); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionManager.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionManager.java deleted file mode 100644 index 0078fe4c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionManager.java +++ /dev/null @@ -1,202 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.region; - -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.math.Rectangle; -import com.etheller.warsmash.util.Quadtree; -import com.etheller.warsmash.util.QuadtreeIntersector; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; - -public class CRegionManager { - private static Rectangle tempRect = new Rectangle(); - private final Quadtree regionTree; - private final RegionChecker regionChecker = new RegionChecker(); - private final List[][] cellRegions; - private final PathingGrid pathingGrid; - - public CRegionManager(final Rectangle entireMapBounds, final PathingGrid pathingGrid) { - this.regionTree = new Quadtree<>(entireMapBounds); - this.cellRegions = new List[pathingGrid.getHeight()][pathingGrid.getWidth()]; - this.pathingGrid = pathingGrid; - } - - public void addRectForRegion(final CRegion region, final Rectangle rect) { - this.regionTree.add(region, rect); - } - - public void removeRectForRegion(final CRegion region, final Rectangle rect) { - this.regionTree.remove(region, rect); - } - - /** - * Calls back on the enum function for every region that touches the given area. - * Sometimes, for performance, this algorithm is designed to call the enum - * function twice for the same region, because our expected use case is to store - * the regions in a set that guarantees uniqueness anyway (see CUnit and/or - * other uses of this method). - */ - public void checkRegions(final Rectangle area, final CRegionEnumFunction enumFunction) { - this.regionTree.intersect(area, this.regionChecker.reset(enumFunction)); - if (this.regionChecker.includesComplex) { - final int minX = this.pathingGrid.getCellX(area.x); - final int minY = this.pathingGrid.getCellY(area.y); - final int maxX = this.pathingGrid.getCellX(area.x + area.width); - final int maxY = this.pathingGrid.getCellY(area.y + area.height); - for (int x = minX; x <= maxX; x++) { - for (int y = minY; y <= maxY; y++) { - final List cellRegionsAtPoint = this.cellRegions[y][x]; - if (cellRegionsAtPoint != null) { - for (final CRegion region : cellRegionsAtPoint) { - if (enumFunction.call(region)) { - return; - } - } - } - } - } - } - } - - private static final class RegionChecker implements QuadtreeIntersector { - private CRegionEnumFunction delegate; - private boolean includesComplex = false; - - public RegionChecker reset(final CRegionEnumFunction delegate) { - this.delegate = delegate; - return this; - } - - @Override - public boolean onIntersect(final CRegion intersectingObject) { - if (intersectingObject.isComplexRegion()) { - this.includesComplex = true; - // handle this type of region differently - return false; - } - return this.delegate.call(intersectingObject); - } - - } - - public void addComplexRegionCells(final CRegion region, final Rectangle currentBounds) { - final int minX = this.pathingGrid.getCellX(currentBounds.x); - final int minY = this.pathingGrid.getCellY(currentBounds.y); - final int maxX = this.pathingGrid.getCellX(currentBounds.x + currentBounds.width); - final int maxY = this.pathingGrid.getCellY(currentBounds.y + currentBounds.height); - for (int x = minX; x <= maxX; x++) { - for (int y = minY; y <= maxY; y++) { - List list = this.cellRegions[y][x]; - if (list == null) { - this.cellRegions[y][x] = list = new ArrayList<>(); - } - list.add(region); - } - } - } - - public void removeComplexRegionCells(final CRegion region, final Rectangle currentBounds) { - final int minX = this.pathingGrid.getCellX(currentBounds.x); - final int minY = this.pathingGrid.getCellY(currentBounds.y); - final int maxX = this.pathingGrid.getCellX(currentBounds.x + currentBounds.width); - final int maxY = this.pathingGrid.getCellY(currentBounds.y + currentBounds.height); - for (int x = minX; x <= maxX; x++) { - for (int y = minY; y <= maxY; y++) { - final List list = this.cellRegions[y][x]; - if (list != null) { - list.remove(region); - } - } - } - } - - public void computeNewMinimumComplexRegionBounds(final CRegion region, final Rectangle complexRegionBounds) { - final int minX = this.pathingGrid.getCellX(complexRegionBounds.x); - final int minY = this.pathingGrid.getCellY(complexRegionBounds.y); - final int maxX = this.pathingGrid.getCellX(complexRegionBounds.x + complexRegionBounds.width); - final int maxY = this.pathingGrid.getCellY(complexRegionBounds.y + complexRegionBounds.height); - float newMinX = this.pathingGrid.getWorldX(this.pathingGrid.getWidth() - 1); - float newMaxX = this.pathingGrid.getWorldX(0); - float newMinY = this.pathingGrid.getWorldY(this.pathingGrid.getHeight() - 1); - float newMaxY = this.pathingGrid.getWorldY(0); - for (int x = minX; x <= maxX; x++) { - for (int y = minY; y <= maxY; y++) { - final List list = this.cellRegions[y][x]; - if (list != null) { - if (list.contains(region)) { - final float worldX = this.pathingGrid.getWorldX(x); - final float worldY = this.pathingGrid.getWorldY(y); - final float wMinX = worldX - 16f; - final float wMinY = worldY - 16f; - final float wMaxX = worldX + 15f; - final float wMaxY = worldY + 15f; - if (wMinX < newMinX) { - newMinX = wMinX; - } - if (wMinY < newMinY) { - newMinY = wMinY; - } - if (wMaxX > newMaxX) { - newMaxX = wMaxX; - } - if (wMaxY > newMaxY) { - newMaxY = wMaxY; - } - } - } - } - } - complexRegionBounds.set(newMinX, newMinY, newMaxX - newMinX, newMaxY - newMinY); - } - - public void addComplexRegionCell(final CRegion region, final float x, final float y, - final Rectangle boundsToUpdate) { - final int cellX = this.pathingGrid.getCellX(x); - final int cellY = this.pathingGrid.getCellY(y); - List list = this.cellRegions[cellY][cellX]; - if (list == null) { - this.cellRegions[cellY][cellX] = list = new ArrayList<>(); - } - list.add(region); - final float worldX = this.pathingGrid.getWorldX(cellX); - final float worldY = this.pathingGrid.getWorldY(cellY); - final float wMinX = worldX - 16f; - final float wMinY = worldY - 16f; - boundsToUpdate.merge(tempRect.set(wMinX, wMinY, 31f, 31f)); - } - - public void clearComplexRegionCell(final CRegion region, final float x, final float y, - final Rectangle boundsToUpdate) { - final int cellX = this.pathingGrid.getCellX(x); - final int cellY = this.pathingGrid.getCellY(y); - final List list = this.cellRegions[cellY][cellX]; - if (list != null) { - list.remove(region); - } - computeNewMinimumComplexRegionBounds(region, boundsToUpdate); - } - - public boolean isPointInComplexRegion(final CRegion region, final float x, final float y) { - final int cellX = this.pathingGrid.getCellX(x); - final int cellY = this.pathingGrid.getCellY(y); - final List list = this.cellRegions[cellY][cellX]; - if (list != null) { - return list.contains(region); - } - return false; - } - - public void onUnitEnterRegion(final CUnit unit, final CRegion region) { - for (final CRegionTriggerEnter enterTrigger : region.getEnterTriggers()) { - enterTrigger.fire(unit, region); - } - } - - public void onUnitLeaveRegion(final CUnit unit, final CRegion region) { - for (final CRegionTriggerLeave leaveTrigger : region.getLeaveTriggers()) { - leaveTrigger.fire(unit, region); - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionTriggerEnter.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionTriggerEnter.java deleted file mode 100644 index 7e187a95..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionTriggerEnter.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.region; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.scope.trigger.Trigger; -import com.etheller.interpreter.ast.scope.trigger.TriggerBooleanExpression; -import com.etheller.warsmash.parsers.jass.scope.CommonTriggerExecutionScope; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; - -public class CRegionTriggerEnter { - private final GlobalScope globalScope; - private final Trigger trigger; - private final TriggerBooleanExpression filter; - - public CRegionTriggerEnter(final GlobalScope globalScope, final Trigger trigger, - final TriggerBooleanExpression filter) { - this.globalScope = globalScope; - this.trigger = trigger; - this.filter = filter; - } - - public void fire(final CUnit unit, final CRegion region) { - if (this.filter.evaluate(this.globalScope, - CommonTriggerExecutionScope.filterScope(TriggerExecutionScope.EMPTY, unit))) { - final CommonTriggerExecutionScope eventScope = CommonTriggerExecutionScope - .unitEnterRegionScope(TriggerExecutionScope.EMPTY, unit, region); - if (this.trigger.evaluate(this.globalScope, eventScope)) { - this.trigger.execute(this.globalScope, eventScope); - } - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionTriggerLeave.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionTriggerLeave.java deleted file mode 100644 index 4b18f221..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/region/CRegionTriggerLeave.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.region; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.scope.trigger.Trigger; -import com.etheller.interpreter.ast.scope.trigger.TriggerBooleanExpression; -import com.etheller.warsmash.parsers.jass.scope.CommonTriggerExecutionScope; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; - -public class CRegionTriggerLeave { - private final GlobalScope globalScope; - private final Trigger trigger; - private final TriggerBooleanExpression filter; - - public CRegionTriggerLeave(final GlobalScope globalScope, final Trigger trigger, - final TriggerBooleanExpression filter) { - this.globalScope = globalScope; - this.trigger = trigger; - this.filter = filter; - } - - public void fire(final CUnit unit, final CRegion region) { - if (this.filter.evaluate(this.globalScope, - CommonTriggerExecutionScope.filterScope(TriggerExecutionScope.EMPTY, unit))) { - final CommonTriggerExecutionScope eventScope = CommonTriggerExecutionScope - .unitLeaveRegionScope(TriggerExecutionScope.EMPTY, unit, region); - if (this.trigger.evaluate(this.globalScope, eventScope)) { - this.trigger.execute(this.globalScope, eventScope); - } - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CGameState.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CGameState.java deleted file mode 100644 index 0cad6186..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CGameState.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.state; - -public enum CGameState { - DIVINE_INTERVENTION, - DISCONNECTED, - TIME_OF_DAY; - - public static CGameState[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CUnitState.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CUnitState.java deleted file mode 100644 index 2272ad4f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/state/CUnitState.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.state; - -public enum CUnitState { - LIFE, - MAX_LIFE, - MANA, - MAX_MANA; - - public static CUnitState[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimer.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimer.java deleted file mode 100644 index 917f44e2..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimer.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.timers; - -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; - -public abstract class CTimer { - private int engineFireTick; - private int scheduleTick; - private float timeoutTime; - private float remainingTimeAfterPause; - private boolean running = false; - private boolean repeats; - - public void setTimeoutTime(final float timeoutTime) { - this.timeoutTime = timeoutTime; - } - - public boolean isRepeats() { - return this.repeats; - } - - public boolean isRunning() { - return this.running; - } - - public float getTimeoutTime() { - return this.timeoutTime; - } - - /** - * @param simulation - */ - public void start(final CSimulation simulation) { - this.running = true; - final int currentTick = simulation.getGameTurnTick(); - this.scheduleTick = currentTick; - innerStart(this.timeoutTime, simulation, currentTick); - } - - private void innerStart(final float timeoutTime, final CSimulation simulation, final int currentTick) { - final int ticks = (int) (timeoutTime / WarsmashConstants.SIMULATION_STEP_TIME); - this.engineFireTick = currentTick + ticks; - simulation.registerTimer(this); - } - - public void pause(final CSimulation simulation) { - this.remainingTimeAfterPause = getRemaining(simulation); - simulation.unregisterTimer(this); - } - - public void resume(final CSimulation simulation) { - if (this.remainingTimeAfterPause == 0) { - start(simulation); - } - final int currentTick = simulation.getGameTurnTick(); - innerStart(this.remainingTimeAfterPause, simulation, currentTick); - this.remainingTimeAfterPause = 0; - } - - public float getElapsed(final CSimulation simulation) { - final int currentTick = simulation.getGameTurnTick(); - final int elapsedTicks = currentTick - this.scheduleTick; - return Math.max(elapsedTicks * WarsmashConstants.SIMULATION_STEP_TIME, this.timeoutTime); - - } - - public float getRemaining(final CSimulation simulation) { - return this.timeoutTime - getElapsed(simulation); - } - - public void setRepeats(final boolean repeats) { - this.repeats = repeats; - } - - public int getEngineFireTick() { - return this.engineFireTick; - } - - public abstract void onFire(); - - public void fire(final CSimulation simulation) { - // its implied that we will have "unregisterTimer" happen automatically - // before this is called - this.running = false; - if (this.repeats) { - start(simulation); - } - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimerJass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimerJass.java deleted file mode 100644 index 7a44665f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimerJass.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.timers; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.etheller.interpreter.ast.function.JassFunction; -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.trigger.Trigger; -import com.etheller.warsmash.parsers.jass.scope.CommonTriggerExecutionScope; - -public class CTimerJass extends CTimer { - private JassFunction handlerFunc; - private final GlobalScope jassGlobalScope; - private final List eventTriggers = new ArrayList<>(); - - public CTimerJass(final GlobalScope jassGlobalScope) { - this.jassGlobalScope = jassGlobalScope; - } - - public void setHandlerFunc(final JassFunction handlerFunc) { - this.handlerFunc = handlerFunc; - } - - @Override - public void onFire() { - final CommonTriggerExecutionScope executionScope = CommonTriggerExecutionScope.expiringTimer(this); - this.handlerFunc.call(Collections.emptyList(), this.jassGlobalScope, executionScope); - for (final Trigger trigger : this.eventTriggers) { - if (trigger.evaluate(this.jassGlobalScope, executionScope)) { - trigger.execute(this.jassGlobalScope, executionScope); - } - } - } - - public void addEvent(final Trigger trigger) { - this.eventTriggers.add(trigger); - } - - public void removeEvent(final Trigger trigger) { - this.eventTriggers.remove(trigger); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimerNativeEvent.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimerNativeEvent.java deleted file mode 100644 index 34df962c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/timers/CTimerNativeEvent.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.timers; - -import com.etheller.interpreter.ast.scope.GlobalScope; -import com.etheller.interpreter.ast.scope.TriggerExecutionScope; -import com.etheller.interpreter.ast.scope.trigger.Trigger; - -public class CTimerNativeEvent extends CTimer { - private final GlobalScope jassGlobalScope; - private final Trigger trigger; - - public CTimerNativeEvent(final GlobalScope jassGlobalScope, final Trigger trigger) { - this.jassGlobalScope = jassGlobalScope; - this.trigger = trigger; - } - - @Override - public void onFire() { - final TriggerExecutionScope triggerScope = new TriggerExecutionScope(this.trigger); - if (this.trigger.evaluate(this.jassGlobalScope, triggerScope)) { - this.trigger.execute(this.jassGlobalScope, triggerScope); - } - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/JassGameEventsWar3.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/JassGameEventsWar3.java deleted file mode 100644 index 03832014..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/JassGameEventsWar3.java +++ /dev/null @@ -1,248 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger; - -//=================================================== -//Game, Player and Unit Events -// -//When an event causes a trigger to fire these -//values allow the action code to determine which -//event was dispatched and therefore which set of -//native functions should be used to get information -//about the event. -// -//Do NOT change the order or value of these constants -//without insuring that the JASS_GAME_EVENTS_WAR3 enum -//is changed to match. -// -//=================================================== - -public enum JassGameEventsWar3 { - // =================================================== - // For use with TriggerRegisterGameEvent - // =================================================== - EVENT_GAME_VICTORY, - EVENT_GAME_END_LEVEL, - - EVENT_GAME_VARIABLE_LIMIT, - EVENT_GAME_STATE_LIMIT, - - EVENT_GAME_TIMER_EXPIRED, - - EVENT_GAME_ENTER_REGION, - EVENT_GAME_LEAVE_REGION, - - EVENT_GAME_TRACKABLE_HIT, - EVENT_GAME_TRACKABLE_TRACK, - - EVENT_GAME_SHOW_SKILL, - EVENT_GAME_BUILD_SUBMENU, - - // =================================================== - // For use with TriggerRegisterPlayerEvent - // =================================================== - EVENT_PLAYER_STATE_LIMIT, - EVENT_PLAYER_ALLIANCE_CHANGED, - - EVENT_PLAYER_DEFEAT, - EVENT_PLAYER_VICTORY, - EVENT_PLAYER_LEAVE, - EVENT_PLAYER_CHAT, - EVENT_PLAYER_END_CINEMATIC, - - // =================================================== - // For use with TriggerRegisterPlayerUnitEvent - // =================================================== - EVENT_PLAYER_UNIT_ATTACKED, - EVENT_PLAYER_UNIT_RESCUED, - - EVENT_PLAYER_UNIT_DEATH, - EVENT_PLAYER_UNIT_DECAY, - - EVENT_PLAYER_UNIT_DETECTED, - EVENT_PLAYER_UNIT_HIDDEN, - - EVENT_PLAYER_UNIT_SELECTED, - EVENT_PLAYER_UNIT_DESELECTED, - - EVENT_PLAYER_UNIT_CONSTRUCT_START, - EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL, - EVENT_PLAYER_UNIT_CONSTRUCT_FINISH, - - EVENT_PLAYER_UNIT_UPGRADE_START, - EVENT_PLAYER_UNIT_UPGRADE_CANCEL, - EVENT_PLAYER_UNIT_UPGRADE_FINISH, - - EVENT_PLAYER_UNIT_TRAIN_START, - EVENT_PLAYER_UNIT_TRAIN_CANCEL, - EVENT_PLAYER_UNIT_TRAIN_FINISH, - - EVENT_PLAYER_UNIT_RESEARCH_START, - EVENT_PLAYER_UNIT_RESEARCH_CANCEL, - EVENT_PLAYER_UNIT_RESEARCH_FINISH, - EVENT_PLAYER_UNIT_ISSUED_ORDER, - EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER, - EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, - - EVENT_PLAYER_HERO_LEVEL, - EVENT_PLAYER_HERO_SKILL, - - EVENT_PLAYER_HERO_REVIVABLE, - - EVENT_PLAYER_HERO_REVIVE_START, - EVENT_PLAYER_HERO_REVIVE_CANCEL, - EVENT_PLAYER_HERO_REVIVE_FINISH, - EVENT_PLAYER_UNIT_SUMMON, - EVENT_PLAYER_UNIT_DROP_ITEM, - EVENT_PLAYER_UNIT_PICKUP_ITEM, - EVENT_PLAYER_UNIT_USE_ITEM, - EVENT_PLAYER_UNIT_LOADED, - - // =================================================== - // For use with TriggerRegisterUnitEvent - // =================================================== - - EVENT_UNIT_DAMAGED, - EVENT_UNIT_DEATH, - EVENT_UNIT_DECAY, - EVENT_UNIT_DETECTED, - EVENT_UNIT_HIDDEN, - EVENT_UNIT_SELECTED, - EVENT_UNIT_DESELECTED, - - EVENT_UNIT_STATE_LIMIT, - - // Events which may have a filter for the "other unit" - // - EVENT_UNIT_ACQUIRED_TARGET, - EVENT_UNIT_TARGET_IN_RANGE, - EVENT_UNIT_ATTACKED, - EVENT_UNIT_RESCUED, - - EVENT_UNIT_CONSTRUCT_CANCEL, - EVENT_UNIT_CONSTRUCT_FINISH, - - EVENT_UNIT_UPGRADE_START, - EVENT_UNIT_UPGRADE_CANCEL, - EVENT_UNIT_UPGRADE_FINISH, - -// Events which involve the specified unit performing -// training of other units -// - EVENT_UNIT_TRAIN_START, - EVENT_UNIT_TRAIN_CANCEL, - EVENT_UNIT_TRAIN_FINISH, - - EVENT_UNIT_RESEARCH_START, - EVENT_UNIT_RESEARCH_CANCEL, - EVENT_UNIT_RESEARCH_FINISH, - - EVENT_UNIT_ISSUED_ORDER, - EVENT_UNIT_ISSUED_POINT_ORDER, - EVENT_UNIT_ISSUED_TARGET_ORDER, - - EVENT_UNIT_HERO_LEVEL, - EVENT_UNIT_HERO_SKILL, - - EVENT_UNIT_HERO_REVIVABLE, - EVENT_UNIT_HERO_REVIVE_START, - EVENT_UNIT_HERO_REVIVE_CANCEL, - EVENT_UNIT_HERO_REVIVE_FINISH, - - EVENT_UNIT_SUMMON, - - EVENT_UNIT_DROP_ITEM, - EVENT_UNIT_PICKUP_ITEM, - EVENT_UNIT_USE_ITEM, - - EVENT_UNIT_LOADED, - - EVENT_WIDGET_DEATH, - - EVENT_DIALOG_BUTTON_CLICK, - EVENT_DIALOG_CLICK, - - // =================================================== - // Frozen Throne Expansion Events - // Need to be added here to preserve compat - // =================================================== - - // =================================================== - // For use with TriggerRegisterGameEvent - // =================================================== - - EVENT_GAME_LOADED, - EVENT_GAME_TOURNAMENT_FINISH_SOON, - EVENT_GAME_TOURNAMENT_FINISH_NOW, - EVENT_GAME_SAVE, - - EVENT_UNKNOWN_TFT_CODE_260, - - // =================================================== - // For use with TriggerRegisterPlayerEvent - // =================================================== - - EVENT_PLAYER_ARROW_LEFT_DOWN, - EVENT_PLAYER_ARROW_LEFT_UP, - EVENT_PLAYER_ARROW_RIGHT_DOWN, - EVENT_PLAYER_ARROW_RIGHT_UP, - EVENT_PLAYER_ARROW_DOWN_DOWN, - EVENT_PLAYER_ARROW_DOWN_UP, - EVENT_PLAYER_ARROW_UP_DOWN, - EVENT_PLAYER_ARROW_UP_UP, - - // =================================================== - // For use with TriggerRegisterPlayerUnitEvent - // =================================================== - - EVENT_PLAYER_UNIT_SELL, - EVENT_PLAYER_UNIT_CHANGE_OWNER, - EVENT_PLAYER_UNIT_SELL_ITEM, - EVENT_PLAYER_UNIT_SPELL_CHANNEL, - EVENT_PLAYER_UNIT_SPELL_CAST, - EVENT_PLAYER_UNIT_SPELL_EFFECT, - EVENT_PLAYER_UNIT_SPELL_FINISH, - EVENT_PLAYER_UNIT_SPELL_ENDCAST, - EVENT_PLAYER_UNIT_PAWN_ITEM, - - EVENT_UNKNOWN_TFT_CODE_278, - EVENT_UNKNOWN_TFT_CODE_279, - EVENT_UNKNOWN_TFT_CODE_280, - EVENT_UNKNOWN_TFT_CODE_281, - EVENT_UNKNOWN_TFT_CODE_282, - EVENT_UNKNOWN_TFT_CODE_283, - EVENT_UNKNOWN_TFT_CODE_284, - EVENT_UNKNOWN_TFT_CODE_285, - - // =================================================== - // For use with TriggerRegisterUnitEvent - // =================================================== - - EVENT_UNIT_SELL, - EVENT_UNIT_CHANGE_OWNER, - EVENT_UNIT_SELL_ITEM, - EVENT_UNIT_SPELL_CHANNEL, - EVENT_UNIT_SPELL_CAST, - EVENT_UNIT_SPELL_EFFECT, - EVENT_UNIT_SPELL_FINISH, - EVENT_UNIT_SPELL_ENDCAST, - EVENT_UNIT_PAWN_ITEM,; - - private static final int TFT_CUTOFF = EVENT_GAME_LOADED.ordinal(); - - public static JassGameEventsWar3[] VALUES; - static { - final JassGameEventsWar3[] localValuesArray = values(); - final JassGameEventsWar3 endValue = localValuesArray[localValuesArray.length - 1]; - VALUES = new JassGameEventsWar3[endValue.getEventId() + 1]; - for (final JassGameEventsWar3 event : localValuesArray) { - VALUES[event.getEventId()] = event; - } - } - - public int getEventId() { - final int ordinal = ordinal(); - if (ordinal >= TFT_CUTOFF) { - return (ordinal - TFT_CUTOFF) + 256; - } - return ordinal; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CAttackTypeJass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CAttackTypeJass.java deleted file mode 100644 index 8fbd348b..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CAttackTypeJass.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; - -public enum CAttackTypeJass { - ; - public static CAttackType[] VALUES = { CAttackType.SPELLS, CAttackType.NORMAL, CAttackType.PIERCE, - CAttackType.SIEGE, CAttackType.MAGIC, CAttackType.CHAOS, CAttackType.HERO }; -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CBlendMode.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CBlendMode.java deleted file mode 100644 index 8ea22de9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CBlendMode.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CBlendMode { - NONE, - KEYALPHA, - BLEND, - ADDITIVE, - MODULATE, - MODULATE_2X; - - public static CBlendMode[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CCameraField.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CCameraField.java deleted file mode 100644 index b51f0a47..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CCameraField.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CCameraField { - TARGET_DISTANCE, - FARZ, - ANGLE_OF_ATTACK, - FIELD_OF_VIEW, - ROLL, - ROTATION, - ZOFFSET; - - public static CCameraField[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CDamageType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CDamageType.java deleted file mode 100644 index 2269db58..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CDamageType.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CDamageType { - UNKNOWN, - UNKNOWN_CODE_1, - UNKNOWN_CODE_2, - UNKNOWN_CODE_3, - NORMAL, - ENHANCED, - UNKNOWN_CODE_6, - UNKNOWN_CODE_7, - FIRE, - COLD, - LIGHTNING, - POISON, - DISEASE, - DIVINE, - MAGIC, - SONIC, - ACID, - FORCE, - DEATH, - MIND, - PLANT, - DEFENSIVE, - DEMOLITION, - SLOW_POISON, - SPIRIT_LINK, - SHADOW_STRIKE; - - public static CDamageType[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CEffectType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CEffectType.java deleted file mode 100644 index 1d02a970..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CEffectType.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CEffectType { - EFFECT, - TARGET, - CASTER, - SPECIAL, - AREA_EFFECT, - MISSILE, - LIGHTNING; - - public static CEffectType[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CFogState.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CFogState.java deleted file mode 100644 index 4e849f1f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CFogState.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CFogState { - MASKED, - FOGGED, - VISIBLE; - - public static CFogState[] VALUES = values(); - - public static CFogState getById(final int id) { - for (final CFogState type : VALUES) { - if ((type.getId()) == id) { - return type; - } - } - return null; - } - - public int getId() { - return 1 << ordinal(); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameSpeed.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameSpeed.java deleted file mode 100644 index ee44d836..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameSpeed.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CGameSpeed { - SLOWEST, - SLOW, - NORMAL, - FAST, - FASTEST; - - public static CGameSpeed[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameType.java deleted file mode 100644 index 6c068a30..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CGameType.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CGameType { - MELEE, - FFA, - USE_MAP_SETTINGS, - BLIZ, - ONE_ON_ONE, - TWO_TEAM_PLAY, - THREE_TEAM_PLAY, - FOUR_TEAM_PLAY; - - public static CGameType[] VALUES = values(); - - public static CGameType getById(final int id) { - for (final CGameType type : VALUES) { - if ((type.getId()) == id) { - return type; - } - } - return null; - } - - public int getId() { - return 1 << ordinal(); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDensity.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDensity.java deleted file mode 100644 index 0e270164..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDensity.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CMapDensity { - NONE, - LIGHT, - MEDIUM, - HEAVY; - - public static CMapDensity[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDifficulty.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDifficulty.java deleted file mode 100644 index 30b1e872..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CMapDifficulty.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CMapDifficulty { - EASY, - NORMAL, - HARD, - INSANE; - - public static CMapDifficulty[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPathingTypeJass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPathingTypeJass.java deleted file mode 100644 index 2e82cbed..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPathingTypeJass.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CPathingTypeJass { - ANY, - WALKABILITY, - FLYABILITY, - BUILDABILITY, - PEONHARVESTPATHING, - BLIGHTPATHING, - FLOATABILITY, - AMPHIBIOUSPATHING; - - public static CPathingTypeJass[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPlayerSlotState.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPlayerSlotState.java deleted file mode 100644 index e8c219f0..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CPlayerSlotState.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CPlayerSlotState { - EMPTY, - PLAYING, - LEFT; - - public static CPlayerSlotState[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CRarityControl.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CRarityControl.java deleted file mode 100644 index d67015d7..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CRarityControl.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CRarityControl { - FREQUENT, - RARE; - - public static CRarityControl[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundType.java deleted file mode 100644 index 14db5268..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundType.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CSoundType { - EFFECT, - EFFECT_LOOPED; - - public static CSoundType[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundVolumeGroup.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundVolumeGroup.java deleted file mode 100644 index 3f228812..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CSoundVolumeGroup.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CSoundVolumeGroup { - UNITMOVEMENT, - UNITSOUNDS, - COMBAT, - SPELLS, - UI, - MUSIC, - AMBIENTSOUNDS, - FIRE; - - public static CSoundVolumeGroup[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CTexMapFlags.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CTexMapFlags.java deleted file mode 100644 index 10dee18a..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CTexMapFlags.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CTexMapFlags { - NONE, - WRAP_U, - WRAP_V, - WRAP_UV; - - public static CTexMapFlags[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CVersion.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CVersion.java deleted file mode 100644 index 6e8cf227..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CVersion.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CVersion { - REIGN_OF_CHAOS, - FROZEN_THRONE; - - public static CVersion[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CWeaponSoundTypeJass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CWeaponSoundTypeJass.java deleted file mode 100644 index f3a6b8fe..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/enumtypes/CWeaponSoundTypeJass.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.enumtypes; - -public enum CWeaponSoundTypeJass { - WHOKNOWS(null), - METAL_LIGHT_CHOP("MetalLightChop"), - METAL_MEDIUM_CHOP("MetalMediumChop"), - METAL_HEAVY_CHOP("MetalHeavyChop"), - METAL_LIGHT_SLICE("MetalLightSlice"), - METAL_MEDIUM_SLICE("MetalMediumSlice"), - METAL_HEAVY_SLICE("MetalHeavySlice"), - METAL_MEDIUM_BASH("MetalMediumBash"), - METAL_HEAVY_BASH("MetalHeavyBash"), - METAL_MEDIUM_STAB("MetalMediumStab"), - METAL_HEAVY_STAB("MetalHeavyStab"), - WOOD_LIGHT_SLICE("WoodLightSlice"), - WOOD_MEDIUM_SLICE("WoodMediumSlice"), - WOOD_HEAVY_SLICE("WoodHeavySlice"), - WOOD_LIGHT_BASH("WoodLightBash"), - WOOD_MEDIUM_BASH("WoodMediumBash"), - WOOD_HEAVY_BASH("WoodHeavyBash"), - WOOD_LIGHT_STAB("WoodLightStab"), - WOOD_MEDIUM_STAB("WoodMediumStab"), - CLAW_LIGHT_SLICE("ClawLightSlice"), - CLAW_MEDIUM_SLICE("ClawMediumSlice"), - CLAW_HEAVY_SLICE("ClawHeavySlice"), - AXE_MEDIUM_CHOP("AxeMediumChop"), - ROCK_HEAVY_BASH("RockHeavyBash"); - - private final String soundKey; - - CWeaponSoundTypeJass(final String soundKey) { - this.soundKey = soundKey; - } - - public String getSoundKey() { - return this.soundKey; - } - - public static CWeaponSoundTypeJass[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/uidialog/JassUIDialog.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/uidialog/JassUIDialog.java deleted file mode 100644 index 52ae6dc6..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/uidialog/JassUIDialog.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.uidialog; - -import java.util.ArrayList; -import java.util.List; - -public class JassUIDialog { - private String title; - private final List buttons = new ArrayList<>(); - - public void setTitle(final String title) { - this.title = title; - } - - public String getTitle() { - return this.title; - } - - public void add(final JassUIDialogButton button) { - this.buttons.add(button); - } - - public boolean remove(final JassUIDialogButton button) { - return this.buttons.remove(button); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/uidialog/JassUIDialogButton.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/uidialog/JassUIDialogButton.java deleted file mode 100644 index 3da2b0af..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/trigger/uidialog/JassUIDialogButton.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.trigger.uidialog; - -public class JassUIDialogButton { - private String text; - - public String getText() { - return this.text; - } - - public void setText(final String text) { - this.text = text; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/unit/CUnitTypeJass.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/unit/CUnitTypeJass.java deleted file mode 100644 index 3092f37d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/unit/CUnitTypeJass.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.unit; - -public enum CUnitTypeJass { - HERO, - DEAD, - STRUCTURE, - - FLYING, - GROUND, - - ATTACKS_FLYING, - ATTACKS_GROUND, - - MELEE_ATTACKER, - RANGED_ATTACKER, - - GIANT, - SUMMONED, - STUNNED, - PLAGUED, - SNARED, - - UNDEAD, - MECHANICAL, - PEON, - SAPPER, - TOWNHALL, - ANCIENT, - - TAUREN, - POISONED, - POLYMORPHED, - SLEEPING, - RESISTANT, - ETHEREAL, - MAGIC_IMMUNE; - - public static CUnitTypeJass[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/AbilityActivationErrorHandler.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/AbilityActivationErrorHandler.java deleted file mode 100644 index fafc5b27..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/AbilityActivationErrorHandler.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util; - -import com.etheller.warsmash.viewer5.AudioContext; -import com.etheller.warsmash.viewer5.handlers.w3x.UnitSound; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandErrorListener; - -public class AbilityActivationErrorHandler { - private final String errorString; - private final UnitSound errorSound; - - public AbilityActivationErrorHandler(final String errorString, final UnitSound errorSound) { - this.errorString = errorString; - this.errorSound = errorSound; - } - - public void onClick(final CommandErrorListener commandErrorListener, final AudioContext worldSceneAudioContext, - final RenderUnit commandedUnit) { - commandErrorListener.showCommandError(this.errorString); - this.errorSound.playUnitResponse(worldSceneAudioContext, commandedUnit); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/AbilityActivationReceiver.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/AbilityActivationReceiver.java deleted file mode 100644 index 09d79a42..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/AbilityActivationReceiver.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util; - -import com.etheller.warsmash.util.War3ID; - -public interface AbilityActivationReceiver { - void useOk(); - - void notEnoughResources(ResourceType resource); - - void notAnActiveAbility(); - - void missingRequirement(War3ID type, int level); - - void casterMovementDisabled(); - - void cargoCapacityUnavailable(); - - void disabled(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/AbilityTargetCheckReceiver.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/AbilityTargetCheckReceiver.java deleted file mode 100644 index 6a4a8fc9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/AbilityTargetCheckReceiver.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util; - -public interface AbilityTargetCheckReceiver { - void targetOk(TARGET_TYPE target); - - void mustTargetTeamType(TeamType correctType); - - void mustTargetType(TargetType correctType); - - void mustTargetResources(); - - void targetOutsideRange(double howMuch); - - void notAnActiveAbility(); - - void targetNotVisible(); - - void targetTooComplicated(); - - void targetNotInPlayableMap(); - - void orderIdNotAccepted(); - - public static enum TeamType { - ALLIED, - ENEMY, - PLAYER_UNITS; - } - - public static enum TargetType { - UNIT, - POINT, - UNIT_OR_POINT, - NO_TARGET - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/BooleanAbilityActivationReceiver.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/BooleanAbilityActivationReceiver.java deleted file mode 100644 index b6ae3b72..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/BooleanAbilityActivationReceiver.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util; - -import com.etheller.warsmash.util.War3ID; - -public class BooleanAbilityActivationReceiver implements AbilityActivationReceiver { - public static final BooleanAbilityActivationReceiver INSTANCE = new BooleanAbilityActivationReceiver(); - private boolean ok; - - @Override - public void useOk() { - this.ok = true; - } - - @Override - public void notEnoughResources(final ResourceType resource) { - this.ok = false; - } - - @Override - public void notAnActiveAbility() { - this.ok = false; - } - - @Override - public void missingRequirement(final War3ID type, final int level) { - this.ok = false; - } - - @Override - public void casterMovementDisabled() { - this.ok = false; - } - - @Override - public void cargoCapacityUnavailable() { - this.ok = false; - } - - @Override - public void disabled() { - this.ok = false; - } - - public boolean isOk() { - return this.ok; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/BooleanAbilityTargetCheckReceiver.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/BooleanAbilityTargetCheckReceiver.java deleted file mode 100644 index bd652157..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/BooleanAbilityTargetCheckReceiver.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util; - -public final class BooleanAbilityTargetCheckReceiver implements AbilityTargetCheckReceiver { - private static final BooleanAbilityTargetCheckReceiver INSTANCE = new BooleanAbilityTargetCheckReceiver<>(); - - public static BooleanAbilityTargetCheckReceiver getInstance() { - return (BooleanAbilityTargetCheckReceiver) INSTANCE; - } - - private boolean targetable = false; - - public boolean isTargetable() { - return this.targetable; - } - - public BooleanAbilityTargetCheckReceiver reset() { - this.targetable = false; - return this; - } - - @Override - public void targetOk(final TARGET_TYPE target) { - this.targetable = true; - } - - @Override - public void mustTargetTeamType(final TeamType correctType) { - this.targetable = false; - } - - @Override - public void mustTargetType(final TargetType correctType) { - this.targetable = false; - } - - @Override - public void mustTargetResources() { - this.targetable = false; - } - - @Override - public void targetOutsideRange(final double howMuch) { - this.targetable = false; - } - - @Override - public void notAnActiveAbility() { - this.targetable = false; - } - - @Override - public void targetNotVisible() { - this.targetable = false; - } - - @Override - public void targetTooComplicated() { - this.targetable = false; - } - - @Override - public void targetNotInPlayableMap() { - this.targetable = false; - } - - @Override - public void orderIdNotAccepted() { - this.targetable = false; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/CWidgetAbilityTargetCheckReceiver.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/CWidgetAbilityTargetCheckReceiver.java deleted file mode 100644 index fb59f0b2..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/CWidgetAbilityTargetCheckReceiver.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; - -public class CWidgetAbilityTargetCheckReceiver implements AbilityTargetCheckReceiver { - public static final CWidgetAbilityTargetCheckReceiver INSTANCE = new CWidgetAbilityTargetCheckReceiver(); - - private CWidget target; - - public CWidgetAbilityTargetCheckReceiver reset() { - this.target = null; - return this; - } - - @Override - public void targetOk(final CWidget target) { - this.target = target; - } - - @Override - public void mustTargetTeamType(final TeamType correctType) { - this.target = null; - } - - @Override - public void mustTargetType(final TargetType correctType) { - this.target = null; - } - - @Override - public void mustTargetResources() { - this.target = null; - } - - @Override - public void targetOutsideRange(final double howMuch) { - this.target = null; - } - - @Override - public void notAnActiveAbility() { - this.target = null; - } - - @Override - public void targetNotVisible() { - this.target = null; - } - - @Override - public void targetTooComplicated() { - this.target = null; - } - - @Override - public void targetNotInPlayableMap() { - this.target = null; - } - - @Override - public void orderIdNotAccepted() { - this.target = null; - } - - public CWidget getTarget() { - return this.target; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/MeleeUIAbilityActivationReceiver.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/MeleeUIAbilityActivationReceiver.java deleted file mode 100644 index fe5420d0..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/MeleeUIAbilityActivationReceiver.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.AudioContext; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandErrorListener; - -public class MeleeUIAbilityActivationReceiver implements AbilityActivationReceiver { - private final AbilityActivationErrorHandler noGoldError; - private final AbilityActivationErrorHandler noLumberError; - private final AbilityActivationErrorHandler noFoodError; - private final AbilityActivationErrorHandler genericError; - - private boolean ok = false; - private CommandErrorListener commandErrorListener; - private AudioContext worldSceneAudioContext; - private RenderUnit commandedUnit; - - public MeleeUIAbilityActivationReceiver(final AbilityActivationErrorHandler noGoldError, - final AbilityActivationErrorHandler noLumberError, final AbilityActivationErrorHandler noFoodError, - final AbilityActivationErrorHandler genericError) { - this.noGoldError = noGoldError; - this.noLumberError = noLumberError; - this.noFoodError = noFoodError; - this.genericError = genericError; - } - - public MeleeUIAbilityActivationReceiver reset(final CommandErrorListener commandErrorListener, - final AudioContext worldSceneAudioContext, final RenderUnit commandedUnit) { - this.commandErrorListener = commandErrorListener; - this.worldSceneAudioContext = worldSceneAudioContext; - this.commandedUnit = commandedUnit; - this.ok = false; - return this; - } - - @Override - public void useOk() { - this.ok = true; - } - - @Override - public void notEnoughResources(final ResourceType resource) { - switch (resource) { - case GOLD: - this.noGoldError.onClick(this.commandErrorListener, this.worldSceneAudioContext, this.commandedUnit); - break; - case LUMBER: - this.noLumberError.onClick(this.commandErrorListener, this.worldSceneAudioContext, this.commandedUnit); - break; - case FOOD: - this.noFoodError.onClick(this.commandErrorListener, this.worldSceneAudioContext, this.commandedUnit); - break; - } - } - - @Override - public void notAnActiveAbility() { - this.genericError.onClick(this.commandErrorListener, this.worldSceneAudioContext, this.commandedUnit); - } - - @Override - public void missingRequirement(final War3ID type, final int level) { - this.genericError.onClick(this.commandErrorListener, this.worldSceneAudioContext, this.commandedUnit); - } - - @Override - public void casterMovementDisabled() { - this.genericError.onClick(this.commandErrorListener, this.worldSceneAudioContext, this.commandedUnit); - } - - @Override - public void cargoCapacityUnavailable() { - this.genericError.onClick(this.commandErrorListener, this.worldSceneAudioContext, this.commandedUnit); - } - - @Override - public void disabled() { - this.genericError.onClick(this.commandErrorListener, this.worldSceneAudioContext, this.commandedUnit); - } - - public boolean isUseOk() { - return this.ok; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/PointAbilityTargetCheckReceiver.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/PointAbilityTargetCheckReceiver.java deleted file mode 100644 index 0c830c9d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/PointAbilityTargetCheckReceiver.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; - -public class PointAbilityTargetCheckReceiver implements AbilityTargetCheckReceiver { - public static final PointAbilityTargetCheckReceiver INSTANCE = new PointAbilityTargetCheckReceiver(); - - private AbilityPointTarget target; - - public PointAbilityTargetCheckReceiver reset() { - this.target = null; - return this; - } - - @Override - public void targetOk(final AbilityPointTarget target) { - this.target = target; - } - - @Override - public void mustTargetTeamType(final TeamType correctType) { - this.target = null; - } - - @Override - public void mustTargetType(final TargetType correctType) { - this.target = null; - } - - @Override - public void mustTargetResources() { - this.target = null; - } - - @Override - public void targetOutsideRange(final double howMuch) { - this.target = null; - } - - @Override - public void notAnActiveAbility() { - this.target = null; - } - - @Override - public void targetNotVisible() { - this.target = null; - } - - @Override - public void targetTooComplicated() { - this.target = null; - } - - @Override - public void targetNotInPlayableMap() { - this.target = null; - } - - @Override - public void orderIdNotAccepted() { - this.target = null; - } - - public AbilityPointTarget getTarget() { - return this.target; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/ResourceType.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/ResourceType.java deleted file mode 100644 index 6e7977c5..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/ResourceType.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util; - -public enum ResourceType { - GOLD, - LUMBER, - FOOD; - - public static final ResourceType[] VALUES = values(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/SimulationRenderController.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/SimulationRenderController.java deleted file mode 100644 index 49fdf0c9..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/SimulationRenderController.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util; - -import java.awt.image.BufferedImage; - -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackInstant; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissile; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.projectile.CAttackProjectile; - -public interface SimulationRenderController { - CAttackProjectile createAttackProjectile(CSimulation simulation, float launchX, float launchY, float launchFacing, - CUnit source, CUnitAttackMissile attack, AbilityTarget target, float damage, int bounceIndex, - CUnitAttackListener attackListener); - - CUnit createUnit(CSimulation simulation, final War3ID typeId, final int playerIndex, final float x, final float y, - final float facing); - - void createInstantAttackEffect(CSimulation cSimulation, CUnit source, CUnitAttackInstant attack, CWidget target); - - void spawnDamageSound(CWidget damagedDestructable, String weaponSound, String armorType); - - void spawnUnitConstructionSound(CUnit constructingUnit, CUnit constructedStructure); - - void removeUnit(CUnit unit); - - void removeDestructable(CDestructable dest); - - BufferedImage getBuildingPathingPixelMap(War3ID rawcode); - - BufferedImage getDestructablePathingPixelMap(War3ID rawcode); - - BufferedImage getDestructablePathingDeathPixelMap(War3ID rawcode); - - void spawnUnitConstructionFinishSound(CUnit constructedStructure); - - void spawnBuildingDeathEffect(CUnit cUnit); - - void spawnGainLevelEffect(CUnit cUnit); - - void spawnUnitReadySound(CUnit trainedUnit); - - void unitRepositioned(CUnit cUnit); - - void spawnGainResourceTextTag(CUnit gainingUnit, ResourceType resourceType, int amount); - - void spawnEffectOnUnit(CUnit unit, String effectPath); - - void spawnSpellEffectOnUnit(CUnit unit, War3ID alias); - - void spawnUIUnitGetItemSound(CUnit cUnit, CItem item); - - void spawnUIUnitDropItemSound(CUnit cUnit, CItem item); - - void spawnAbilitySoundEffect(CUnit caster, War3ID alias); - - void unitPreferredSelectionReplacement(CUnit unit, CUnit newUnit); - - void heroRevived(CUnit trainedUnit); - - void heroDeathEvent(CUnit cUnit); - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/StringMsgAbilityActivationReceiver.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/StringMsgAbilityActivationReceiver.java deleted file mode 100644 index 5f8697c5..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/StringMsgAbilityActivationReceiver.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util; - -import com.etheller.warsmash.util.War3ID; - -public class StringMsgAbilityActivationReceiver implements AbilityActivationReceiver { - private String message; - private boolean useOk = false; - - public StringMsgAbilityActivationReceiver reset() { - this.message = null; - this.useOk = false; - return this; - } - - public String getMessage() { - return this.message; - } - - public boolean isUseOk() { - return this.useOk; - } - - @Override - public void useOk() { - this.useOk = true; - } - - @Override - public void notEnoughResources(final ResourceType resource) { - this.message = "NOTEXTERN: Requires more " + resource.name().toLowerCase() + "."; - } - - @Override - public void notAnActiveAbility() { - this.message = "NOTEXTERN: Not an active ability."; - } - - @Override - public void missingRequirement(final War3ID type, final int level) { - this.message = "NOTEXTERN: Requires " + type; - } - - @Override - public void cargoCapacityUnavailable() { - this.message = "NOTEXTERN: Cargo capacity unavailable."; - } - - @Override - public void casterMovementDisabled() { - this.message = "NOTEXTERN: Caster movement disabled."; - } - - @Override - public void disabled() { - this.message = "NOTEXTERN: Ability is disabled."; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/StringMsgTargetCheckReceiver.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/StringMsgTargetCheckReceiver.java deleted file mode 100644 index 15008bcc..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/simulation/util/StringMsgTargetCheckReceiver.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.simulation.util; - -public final class StringMsgTargetCheckReceiver implements AbilityTargetCheckReceiver { - private static final StringMsgTargetCheckReceiver INSTANCE = new StringMsgTargetCheckReceiver<>(); - - public static StringMsgTargetCheckReceiver getInstance() { - return (StringMsgTargetCheckReceiver) INSTANCE; - } - - private TARGET_TYPE target; - private String message; - - public TARGET_TYPE getTarget() { - return this.target; - } - - public String getMessage() { - return this.message; - } - - public StringMsgTargetCheckReceiver reset() { - this.target = null; - this.message = null; - return this; - } - - @Override - public void targetOk(final TARGET_TYPE target) { - this.target = target; - } - - @Override - public void mustTargetTeamType(final TeamType correctType) { - switch (correctType) { - case ALLIED: - this.message = "NOTEXTERN: Must target an allied unit."; - break; - case ENEMY: - this.message = "NOTEXTERN: Must target an enemy unit."; - break; - case PLAYER_UNITS: - this.message = "NOTEXTERN: Unable to target a unit you do not control."; - break; - default: - this.message = "NOTEXTERN: Must target team type: " + correctType; - } - } - - @Override - public void mustTargetType(final TargetType correctType) { - switch (correctType) { - case POINT: - this.message = "NOTEXTERN: Must target a point."; - break; - case UNIT: - this.message = "NOTEXTERN: Must target a unit."; - break; - case UNIT_OR_POINT: - this.message = "NOTEXTERN: Must target a unit or point."; - break; - default: - this.message = "NOTEXTERN: Must target type: " + correctType; - } - } - - @Override - public void mustTargetResources() { - this.message = "NOTEXTERN: Must target resources."; - } - - @Override - public void targetOutsideRange(final double howMuch) { - this.message = "NOTEXTERN: Target is outside range."; - } - - @Override - public void notAnActiveAbility() { - this.message = "NOTEXTERN: Not an active ability."; - } - - @Override - public void targetNotVisible() { - this.message = "NOTEXTERN: Target is not visible."; - } - - @Override - public void targetTooComplicated() { - this.message = "NOTEXTERN: Target is too complicated."; - } - - @Override - public void targetNotInPlayableMap() { - this.message = "NOTEXTERN: Target is not within the designed combat area."; - } - - @Override - public void orderIdNotAccepted() { - this.message = "NOTEXTERN: OrderID not accepted."; - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/CommandCardIcon.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/CommandCardIcon.java deleted file mode 100644 index fbfd12a3..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/CommandCardIcon.java +++ /dev/null @@ -1,240 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui; - -import com.badlogic.gdx.Input; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.frames.AbstractRenderableFrame; -import com.etheller.warsmash.parsers.fdf.frames.SpriteFrame; -import com.etheller.warsmash.parsers.fdf.frames.TextureFrame; -import com.etheller.warsmash.parsers.fdf.frames.UIFrame; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.ClickableActionFrame; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandCardCommandListener; - -public class CommandCardIcon extends AbstractRenderableFrame implements ClickableActionFrame { - - private TextureFrame iconFrame; - private TextureFrame activeHighlightFrame; - private SpriteFrame cooldownFrame; - private SpriteFrame autocastFrame; - private float defaultWidth; - private float defaultHeight; - private int abilityHandleId; - private int orderId; - private int autoCastOrderId; - private boolean autoCastActive; - private final CommandCardCommandListener commandCardCommandListener; - private boolean menuButton; - private String tip; - private String uberTip; - private int tipGoldCost; - private int tipLumberCost; - private int tipFoodCost; - private char hotkey; - - public CommandCardIcon(final String name, final UIFrame parent, - final CommandCardCommandListener commandCardCommandListener) { - super(name, parent); - this.commandCardCommandListener = commandCardCommandListener; - } - - public void set(final TextureFrame iconFrame, final TextureFrame activeHighlightFrame, - final SpriteFrame cooldownFrame, final SpriteFrame autocastFrame) { - this.iconFrame = iconFrame; - this.activeHighlightFrame = activeHighlightFrame; - this.cooldownFrame = cooldownFrame; - this.autocastFrame = autocastFrame; - } - - public void clear() { - this.iconFrame.setVisible(false); - if (this.activeHighlightFrame != null) { - this.activeHighlightFrame.setVisible(false); - } - this.cooldownFrame.setVisible(false); - if (this.autocastFrame != null) { - this.autocastFrame.setVisible(false); - } - setVisible(false); - this.hotkey = '\0'; - } - - public void setCommandButtonData(final Texture texture, final int abilityHandleId, final int orderId, - final int autoCastOrderId, final boolean active, final boolean autoCastActive, final boolean menuButton, - final String tip, final String uberTip, final char hotkey, final int goldCost, final int lumberCost, - final int foodCost) { - this.menuButton = menuButton; - this.hotkey = hotkey; - setVisible(true); - this.iconFrame.setVisible(true); - if (this.activeHighlightFrame != null) { - this.activeHighlightFrame.setVisible(active); - } - this.cooldownFrame.setVisible(false); - if (this.autocastFrame != null) { - this.autocastFrame.setVisible(autoCastOrderId != 0); - if (autoCastOrderId != 0) { - if (this.autoCastActive != autoCastActive) { - if (autoCastActive) { - this.autocastFrame.setSequence(PrimaryTag.STAND); - } - else { - this.autocastFrame.setSequence(-1); - } - } - this.autoCastActive = autoCastActive; - } - } - this.iconFrame.setTexture(texture); - this.abilityHandleId = abilityHandleId; - this.orderId = orderId; - this.autoCastOrderId = autoCastOrderId; - this.tip = tip; - this.uberTip = uberTip; - this.tipGoldCost = goldCost; - this.tipLumberCost = lumberCost; - this.tipFoodCost = foodCost; - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - this.iconFrame.positionBounds(gameUI, viewport); - if (this.activeHighlightFrame != null) { - this.activeHighlightFrame.positionBounds(gameUI, viewport); - } - this.cooldownFrame.positionBounds(gameUI, viewport); - if (this.autocastFrame != null) { - this.autocastFrame.positionBounds(gameUI, viewport); - } - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - this.iconFrame.render(batch, baseFont, glyphLayout); - if (this.activeHighlightFrame != null) { - this.activeHighlightFrame.render(batch, baseFont, glyphLayout); - } - this.cooldownFrame.render(batch, baseFont, glyphLayout); - if (this.autocastFrame != null) { - this.autocastFrame.render(batch, baseFont, glyphLayout); - } - } - - @Override - public UIFrame touchDown(final float screenX, final float screenY, final int button) { - if (isVisible() && this.renderBounds.contains(screenX, screenY)) { - if (((button == Input.Buttons.LEFT) && (this.orderId != 0)) - || ((button == Input.Buttons.RIGHT) && (this.autoCastOrderId != 0)) || this.menuButton) { - return this; - } - } - return super.touchDown(screenX, screenY, button); - } - - public boolean checkHotkey(final char c, final int keycode) { - if ((c == this.hotkey) || (Character.toUpperCase(c) == this.hotkey) - || ((this.hotkey == 0x7E) && (keycode == Input.Keys.ESCAPE))) { - onClick(Input.Buttons.LEFT); - return true; - } - return false; - } - - @Override - public UIFrame touchUp(final float screenX, final float screenY, final int button) { - if (isVisible() && this.renderBounds.contains(screenX, screenY)) { - return this; - } - return super.touchUp(screenX, screenY, button); - } - - public boolean isMenuButton() { - return this.menuButton; - } - - @Override - public void onClick(final int button) { - if (button == Input.Buttons.LEFT) { - if (this.menuButton) { - this.commandCardCommandListener.openMenu(this.orderId); - } - else { - this.commandCardCommandListener.onClick(this.abilityHandleId, this.orderId, false); - } - } - else if (button == Input.Buttons.RIGHT) { - this.commandCardCommandListener.onClick(this.abilityHandleId, this.autoCastOrderId, true); - } - } - - @Override - public void mouseDown(final GameUI gameUI, final Viewport uiViewport) { - this.iconFrame.setWidth(this.defaultWidth * 0.95f); - this.iconFrame.setHeight(this.defaultHeight * 0.95f); - positionBounds(gameUI, uiViewport); - } - - @Override - public void mouseUp(final GameUI gameUI, final Viewport uiViewport) { - this.iconFrame.setWidth(this.defaultWidth); - this.iconFrame.setHeight(this.defaultHeight); - positionBounds(gameUI, uiViewport); - } - - @Override - public void setWidth(final float width) { - this.defaultWidth = width; - super.setWidth(width); - } - - @Override - public void setHeight(final float height) { - this.defaultHeight = height; - super.setHeight(height); - } - - @Override - public void mouseEnter(final GameUI gameUI, final Viewport uiViewport) { - } - - @Override - public void mouseExit(final GameUI gameUI, final Viewport uiViewport) { - } - - @Override - public UIFrame getFrameChildUnderMouse(final float screenX, final float screenY) { - if (isVisible() && this.renderBounds.contains(screenX, screenY)) { - return this; - } - return null; - } - - @Override - public String getToolTip() { - return this.tip; - } - - @Override - public String getUberTip() { - return this.uberTip; - } - - @Override - public int getToolTipGoldCost() { - return this.tipGoldCost; - } - - @Override - public int getToolTipLumberCost() { - return this.tipLumberCost; - } - - @Override - public int getToolTipFoodCost() { - return this.tipFoodCost; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUI.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUI.java deleted file mode 100644 index 5a3fb5e1..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUI.java +++ /dev/null @@ -1,3317 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui; - -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Queue; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Input; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.Pixmap; -import com.badlogic.gdx.graphics.Pixmap.Blending; -import com.badlogic.gdx.graphics.Pixmap.Format; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter; -import com.badlogic.gdx.graphics.glutils.PixmapTextureData; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.math.Vector3; -import com.badlogic.gdx.math.collision.BoundingBox; -import com.badlogic.gdx.utils.TimeUtils; -import com.badlogic.gdx.utils.viewport.ExtendViewport; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.AnchorDefinition; -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; -import com.etheller.warsmash.parsers.fdf.datamodel.TextJustify; -import com.etheller.warsmash.parsers.fdf.datamodel.Vector4Definition; -import com.etheller.warsmash.parsers.fdf.frames.AbstractUIFrame; -import com.etheller.warsmash.parsers.fdf.frames.FilterModeTextureFrame; -import com.etheller.warsmash.parsers.fdf.frames.GlueTextButtonFrame; -import com.etheller.warsmash.parsers.fdf.frames.SetPoint; -import com.etheller.warsmash.parsers.fdf.frames.SimpleButtonFrame; -import com.etheller.warsmash.parsers.fdf.frames.SimpleFrame; -import com.etheller.warsmash.parsers.fdf.frames.SimpleStatusBarFrame; -import com.etheller.warsmash.parsers.fdf.frames.SpriteFrame; -import com.etheller.warsmash.parsers.fdf.frames.StringFrame; -import com.etheller.warsmash.parsers.fdf.frames.TextureFrame; -import com.etheller.warsmash.parsers.fdf.frames.UIFrame; -import com.etheller.warsmash.parsers.jass.Jass2.RootFrameListener; -import com.etheller.warsmash.units.Element; -import com.etheller.warsmash.units.manager.MutableObjectData; -import com.etheller.warsmash.util.FastNumberFormat; -import com.etheller.warsmash.util.ImageUtils; -import com.etheller.warsmash.util.RenderMathUtils; -import com.etheller.warsmash.util.War3ID; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.viewer5.Bounds; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.ViewerTextureRenderable; -import com.etheller.warsmash.viewer5.handlers.mdx.Attachment; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxComplexInstance; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxModel; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxNode; -import com.etheller.warsmash.viewer5.handlers.mdx.ReplaceableIds; -import com.etheller.warsmash.viewer5.handlers.mdx.SequenceLoopMode; -import com.etheller.warsmash.viewer5.handlers.tga.TgaFile; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.PrimaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.AnimationTokens.SecondaryTag; -import com.etheller.warsmash.viewer5.handlers.w3x.SequenceUtils; -import com.etheller.warsmash.viewer5.handlers.w3x.SplatModel; -import com.etheller.warsmash.viewer5.handlers.w3x.SplatModel.SplatMover; -import com.etheller.warsmash.viewer5.handlers.w3x.TextTag; -import com.etheller.warsmash.viewer5.handlers.w3x.UnitSound; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; -import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraPreset; -import com.etheller.warsmash.viewer5.handlers.w3x.camera.CameraRates; -import com.etheller.warsmash.viewer5.handlers.w3x.camera.GameCameraManager; -import com.etheller.warsmash.viewer5.handlers.w3x.camera.PortraitCameraManager; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid; -import com.etheller.warsmash.viewer5.handlers.w3x.environment.PathingGrid.PathingFlags; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.AbilityDataUI; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.IconUI; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.ItemUI; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.ability.UnitIconUI; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.commandbuttons.CommandButtonListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CDestructable; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CGameplayConstants; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItem; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CItemType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CPlayerStateListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit.QueueItemType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitClassification; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitEnumFunction; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitStateListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnitType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CWidgetFilterFunction; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityGeneric; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityMove; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityView; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.CAbilityVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.AbstractCAbilityBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityBuildInProgress; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityHumanBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNagaBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNeutralBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityNightElfBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityOrcBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.build.CAbilityUndeadBuild; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.combat.CAbilityColdArrows; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericNoIconAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.generic.GenericSingleIconActiveAbility; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CAbilityHero; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.hero.CPrimaryAttribute; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.inventory.CAbilityInventory; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityQueue; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityRally; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.queue.CAbilityReviveHero; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityPointTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTarget; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.abilities.targeting.AbilityTargetVisitor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CAttackType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CDefenseType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.CodeKeyType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttack; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.combat.attacks.CUnitAttackMissileSplash; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.COrder; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.orders.OrderIds; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.pathing.CBuildingPathingType; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerUnitOrderListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRace; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.AbilityActivationErrorHandler; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.BooleanAbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.BooleanAbilityTargetCheckReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.CWidgetAbilityTargetCheckReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.MeleeUIAbilityActivationReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.PointAbilityTargetCheckReceiver; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.util.ResourceType; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.ClickableActionFrame; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.ClickableFrame; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandCardCommandListener; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.CommandErrorListener; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.QueueIconListener; -import com.hiveworkshop.rms.parsers.mdlx.MdlxLayer.FilterMode; - -public class MeleeUI implements CUnitStateListener, CommandButtonListener, CommandCardCommandListener, - QueueIconListener, CommandErrorListener, CPlayerStateListener { - private static final long WORLD_FRAME_MESSAGE_FADEOUT_MILLIS = TimeUnit.SECONDS.toMillis(9); - private static final long WORLD_FRAME_MESSAGE_EXPIRE_MILLIS = TimeUnit.SECONDS.toMillis(10); - private static final long WORLD_FRAME_MESSAGE_FADE_DURATION = WORLD_FRAME_MESSAGE_EXPIRE_MILLIS - - WORLD_FRAME_MESSAGE_FADEOUT_MILLIS; - private static final String BUILDING_PATHING_PREVIEW_KEY = "buildingPathingPreview"; - public static final float DEFAULT_COMMAND_CARD_ICON_WIDTH = 0.039f; - public static final float DEFAULT_INVENTORY_ICON_WIDTH = 0.03125f; - private static final int COMMAND_CARD_WIDTH = 4; - private static final int COMMAND_CARD_HEIGHT = 3; - private static final int INVENTORY_WIDTH = 2; - private static final int INVENTORY_HEIGHT = 3; - - private static final Vector2 screenCoordsVector = new Vector2(); - private static final Vector3 clickLocationTemp = new Vector3(); - private static final AbilityPointTarget clickLocationTemp2 = new AbilityPointTarget(); - private final DataSource dataSource; - private final ExtendViewport uiViewport; - private final Scene uiScene; - private final Scene portraitScene; - private final GameCameraManager cameraManager; - private final War3MapViewer war3MapViewer; - private final RootFrameListener rootFrameListener; - private GameUI rootFrame; - private UIFrame consoleUI; - private UIFrame resourceBar; - private StringFrame resourceBarGoldText; - private StringFrame resourceBarLumberText; - private StringFrame resourceBarSupplyText; - private StringFrame resourceBarUpkeepText; - private SpriteFrame timeIndicator; - private UIFrame unitPortrait; - private StringFrame unitLifeText; - private StringFrame unitManaText; - private Portrait portrait; - private final Rectangle tempRect = new Rectangle(); - private final Vector2 projectionTemp1 = new Vector2(); - private final Vector2 projectionTemp2 = new Vector2(); - - // tooltip - private UIFrame tooltipFrame; - private StringFrame tooltipText; - private StringFrame tooltipUberTipText; - private UIFrame[] tooltipResourceFrames; - private TextureFrame[] tooltipResourceIconFrames; - private StringFrame[] tooltipResourceTextFrames; - - private UIFrame simpleInfoPanelUnitDetail; - private StringFrame simpleNameValue; - private StringFrame simpleClassValue; - private StringFrame simpleBuildingActionLabel; - private SimpleStatusBarFrame simpleBuildTimeIndicator; - private SimpleStatusBarFrame simpleHeroLevelBar; - - private UIFrame simpleInfoPanelBuildingDetail; - private StringFrame simpleBuildingNameValue; - private StringFrame simpleBuildingDescriptionValue; - private StringFrame simpleBuildingBuildingActionLabel; - private SimpleStatusBarFrame simpleBuildingBuildTimeIndicator; - private final QueueIcon[] queueIconFrames = new QueueIcon[WarsmashConstants.BUILD_QUEUE_SIZE]; - private QueueIcon selectWorkerInsideFrame; - private final QueueIcon[] selectedUnitFrames = new QueueIcon[WarsmashConstants.MAX_SELECTION_SIZE]; - - private UIFrame attack1Icon; - private TextureFrame attack1IconBackdrop; - private StringFrame attack1InfoPanelIconValue; - private StringFrame attack1InfoPanelIconLevel; - private UIFrame attack2Icon; - private TextureFrame attack2IconBackdrop; - private StringFrame attack2InfoPanelIconValue; - private StringFrame attack2InfoPanelIconLevel; - private UIFrame armorIcon; - private TextureFrame armorIconBackdrop; - private StringFrame armorInfoPanelIconValue; - private StringFrame armorInfoPanelIconLevel; - private InfoPanelIconBackdrops damageBackdrops; - private InfoPanelIconBackdrops defenseBackdrops; - - private UIFrame heroInfoPanel; - - private SimpleFrame inventoryBarFrame; - private StringFrame inventoryTitleFrame; - private final CommandCardIcon[][] inventoryIcons = new CommandCardIcon[INVENTORY_HEIGHT][INVENTORY_WIDTH]; - private Texture consoleInventoryNoCapacityTexture; - - private final CommandCardIcon[][] commandCard = new CommandCardIcon[COMMAND_CARD_HEIGHT][COMMAND_CARD_WIDTH]; - - private RenderUnit selectedUnit; - private final List subMenuOrderIdStack = new ArrayList<>(); - - // TODO remove this & replace with FDF - private final Texture activeButtonTexture; - private UIFrame inventoryCover; - private SpriteFrame cursorFrame; - private MeleeUIMinimap meleeUIMinimap; - private final CPlayerUnitOrderListener unitOrderListener; - private StringFrame errorMessageFrame; - private long lastErrorMessageExpireTime; - private long lastErrorMessageFadeTime; - - private MenuCursorState cursorState; - private CAbilityView activeCommand; - private int activeCommandOrderId; - private RenderUnit activeCommandUnit; - private MdxComplexInstance cursorModelInstance = null; - private MdxComplexInstance rallyPointInstance = null; - private BufferedImage cursorModelPathing; - private Pixmap cursorModelUnderneathPathingRedGreenPixmap; - private Texture cursorModelUnderneathPathingRedGreenPixmapTexture; - private PixmapTextureData cursorModelUnderneathPathingRedGreenPixmapTextureData; - private SplatModel cursorModelUnderneathPathingRedGreenSplatModel; - private CUnitType cursorBuildingUnitType; - private SplatMover placementCursor = null; - private final CursorTargetSetupVisitor cursorTargetSetupVisitor; - - private int selectedSoundCount = 0; - private final ActiveCommandUnitTargetFilter activeCommandUnitTargetFilter; - - // TODO these corrections are used for old hardcoded UI stuff, we should - // probably remove them later - private final float widthRatioCorrection; - private final float heightRatioCorrection; - private ClickableFrame mouseDownUIFrame; - private ClickableFrame mouseOverUIFrame; - private UIFrame smashSimpleInfoPanel; - private SimpleFrame smashAttack1IconWrapper; - private SimpleFrame smashAttack2IconWrapper; - private SimpleFrame smashArmorIconWrapper; - private final RallyPositioningVisitor rallyPositioningVisitor; - private final CPlayer localPlayer; - private MeleeUIAbilityActivationReceiver meleeUIAbilityActivationReceiver; - private MdxModel waypointModel; - private final List waypointModelInstances = new ArrayList<>(); - private List selectedUnits = Collections.emptyList(); - private Set dragSelectPreviewUnits = new HashSet<>(); - private Set dragSelectPreviewUnitsUpcoming = new HashSet<>(); - private BitmapFont textTagFont; - private SetPoint uberTipNoResourcesSetPoint; - private SetPoint uberTipWithResourcesSetPoint; - private TextureFrame primaryAttributeIcon; - private StringFrame strengthValue; - private StringFrame agilityValue; - private StringFrame intelligenceValue; - private SimpleFrame smashHeroInfoPanelWrapper; - - private final StringBuilder recycleStringBuilder = new StringBuilder(); - private CItem draggingItem; - private final ItemCommandCardCommandListener itemCommandCardCommandListener; - private SimpleButtonFrame questsButton; - private SimpleButtonFrame menuButton; - private SimpleButtonFrame alliesButton; - private SimpleButtonFrame chatButton; - private final Runnable exitGameRunnable; - private SimpleFrame smashEscMenu; - private RenderWidget mouseOverUnit; - private final Vector3 lastMouseDragStart = new Vector3(); - private final Vector3 lastMouseClickLocation = new Vector3(); - - private final List hpBarFrames = new ArrayList<>(); - private int hpBarFrameIndex = 0; - private boolean allowDrag; - private int currentlyDraggingPointer; - private final ShapeRenderer shapeRenderer = new ShapeRenderer(); - private final List multiSelectUnitStateListeners = new ArrayList<>(); - - public MeleeUI(final DataSource dataSource, final ExtendViewport uiViewport, final Scene uiScene, - final Scene portraitScene, final CameraPreset[] cameraPresets, final CameraRates cameraRates, - final War3MapViewer war3MapViewer, final RootFrameListener rootFrameListener, - final CPlayerUnitOrderListener unitOrderListener, final Runnable exitGameRunnable) { - this.dataSource = dataSource; - this.uiViewport = uiViewport; - this.uiScene = uiScene; - this.portraitScene = portraitScene; - this.war3MapViewer = war3MapViewer; - this.rootFrameListener = rootFrameListener; - this.unitOrderListener = unitOrderListener; - this.exitGameRunnable = exitGameRunnable; - - this.cameraManager = new GameCameraManager(cameraPresets, cameraRates); - - this.cameraManager.setupCamera(war3MapViewer.worldScene); - this.localPlayer = this.war3MapViewer.simulation.getPlayer(war3MapViewer.getLocalPlayerIndex()); - final float[] startLocation = this.localPlayer.getStartLocation(); - this.cameraManager.target.x = startLocation[0]; - this.cameraManager.target.y = startLocation[1]; - - this.activeButtonTexture = ImageUtils.getAnyExtensionTexture(war3MapViewer.mapMpq, - "UI\\Widgets\\Console\\Human\\CommandButton\\human-activebutton.blp"); - this.activeCommandUnitTargetFilter = new ActiveCommandUnitTargetFilter(); - this.widthRatioCorrection = this.uiViewport.getMinWorldWidth() / 1600f; - this.heightRatioCorrection = this.uiViewport.getMinWorldHeight() / 1200f; - this.rallyPositioningVisitor = new RallyPositioningVisitor(); - this.cursorTargetSetupVisitor = new CursorTargetSetupVisitor(); - - this.localPlayer.addStateListener(this); - - this.itemCommandCardCommandListener = new ItemCommandCardCommandListener(); - } - - private MeleeUIMinimap createMinimap(final War3MapViewer war3MapViewer) { - final Rectangle minimapDisplayArea = new Rectangle(18.75f * this.widthRatioCorrection, - 13.75f * this.heightRatioCorrection, 278.75f * this.widthRatioCorrection, - 276.25f * this.heightRatioCorrection); - Texture minimapTexture = null; - if (war3MapViewer.dataSource.has("war3mapMap.tga")) { - try { - minimapTexture = ImageUtils.getTextureNoColorCorrection(TgaFile.readTGA("war3mapMap.tga", - war3MapViewer.dataSource.getResourceAsStream("war3mapMap.tga"))); - } - catch (final IOException e) { - System.err.println("Could not load minimap TGA file"); - e.printStackTrace(); - } - } - else if (war3MapViewer.dataSource.has("war3mapMap.blp")) { - minimapTexture = ImageUtils.getAnyExtensionTexture(war3MapViewer.dataSource, "war3mapMap.blp"); - } - final Texture[] teamColors = new Texture[WarsmashConstants.MAX_PLAYERS]; - for (int i = 0; i < teamColors.length; i++) { - teamColors[i] = ImageUtils.getAnyExtensionTexture(war3MapViewer.dataSource, - "ReplaceableTextures\\" + ReplaceableIds.getPathString(1) + ReplaceableIds.getIdString(i) + ".blp"); - } - final Rectangle playableMapArea = war3MapViewer.terrain.getPlayableMapArea(); - return new MeleeUIMinimap(minimapDisplayArea, playableMapArea, minimapTexture, teamColors); - } - - /** - * Called "main" because this was originally written in JASS so that maps could - * override it, and I may convert it back to the JASS at some point. - */ - public void main() { - // ================================= - // Load skins and templates - // ================================= - final CRace race = this.localPlayer.getRace(); - final String racialSkinKey; - int racialCommandIndex; - if (race == null) { - racialSkinKey = "Human"; - racialCommandIndex = 0; - } - else { - switch (race) { - case HUMAN: - racialSkinKey = "Human"; - racialCommandIndex = 0; - break; - case ORC: - racialSkinKey = "Orc"; - racialCommandIndex = 1; - break; - case NIGHTELF: - racialSkinKey = "NightElf"; - racialCommandIndex = 3; - break; - case UNDEAD: - racialSkinKey = "Undead"; - racialCommandIndex = 2; - break; - case DEMON: - case OTHER: - default: - racialSkinKey = "Human"; - racialCommandIndex = 0; - break; - } - } - this.rootFrame = new GameUI(this.dataSource, GameUI.loadSkin(this.dataSource, racialSkinKey), this.uiViewport, - this.uiScene, this.war3MapViewer, racialCommandIndex, this.war3MapViewer.getAllObjectData().getWts()); - this.rootFrameListener.onCreate(this.rootFrame); - try { - this.rootFrame.loadTOCFile("UI\\FrameDef\\FrameDef.toc"); - } - catch (final IOException exc) { - throw new IllegalStateException("Unable to load FrameDef.toc", exc); - } - try { - this.rootFrame.loadTOCFile("UI\\FrameDef\\SmashFrameDef.toc"); - } - catch (final IOException exc) { - throw new IllegalStateException("Unable to load SmashFrameDef.toc", exc); - } - this.damageBackdrops = new InfoPanelIconBackdrops(CAttackType.values(), this.rootFrame, "Damage", "Neutral"); - this.defenseBackdrops = new InfoPanelIconBackdrops(CDefenseType.values(), this.rootFrame, "Armor", "Neutral"); - - // ================================= - // Load major UI components - // ================================= - // Console UI is the background with the racial theme - this.consoleUI = this.rootFrame.createSimpleFrame("ConsoleUI", this.rootFrame, 0); - this.consoleUI.setSetAllPoints(true); - - // Resource bar is a 3 part bar with Gold, Lumber, and Food. - // Its template does not specify where to put it, so we must - // put it in the "TOPRIGHT" corner. - this.resourceBar = this.rootFrame.createSimpleFrame("ResourceBarFrame", this.consoleUI, 0); - this.resourceBar.addSetPoint(new SetPoint(FramePoint.TOPRIGHT, this.consoleUI, FramePoint.TOPRIGHT, 0, 0)); - this.resourceBarGoldText = (StringFrame) this.rootFrame.getFrameByName("ResourceBarGoldText", 0); - goldChanged(); - this.resourceBarLumberText = (StringFrame) this.rootFrame.getFrameByName("ResourceBarLumberText", 0); - lumberChanged(); - this.resourceBarSupplyText = (StringFrame) this.rootFrame.getFrameByName("ResourceBarSupplyText", 0); - foodChanged(); - this.resourceBarUpkeepText = (StringFrame) this.rootFrame.getFrameByName("ResourceBarUpkeepText", 0); - upkeepChanged(); - - final UIFrame upperButtonBar = this.rootFrame.createSimpleFrame("UpperButtonBarFrame", this.consoleUI, 0); - upperButtonBar.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.consoleUI, FramePoint.TOPLEFT, 0, 0)); - - this.questsButton = (SimpleButtonFrame) this.rootFrame.getFrameByName("UpperButtonBarQuestsButton", 0); - this.questsButton.setEnabled(false); - this.menuButton = (SimpleButtonFrame) this.rootFrame.getFrameByName("UpperButtonBarMenuButton", 0); - this.alliesButton = (SimpleButtonFrame) this.rootFrame.getFrameByName("UpperButtonBarAlliesButton", 0); - this.alliesButton.setEnabled(false); - this.chatButton = (SimpleButtonFrame) this.rootFrame.getFrameByName("UpperButtonBarChatButton", 0); - this.chatButton.setEnabled(false); - - this.smashEscMenu = (SimpleFrame) this.rootFrame.createSimpleFrame("SmashEscMenu", this.rootFrame, 0); - this.smashEscMenu.addAnchor(new AnchorDefinition(FramePoint.TOP, 0, GameUI.convertY(this.uiViewport, -0.05f))); - final UIFrame escMenuBackdrop = this.rootFrame.createFrame("EscMenuBackdrop", this.smashEscMenu, 0, 0); - escMenuBackdrop.setVisible(false); - final UIFrame escMenuMainPanel = this.rootFrame.createFrame("EscMenuMainPanel", this.smashEscMenu, 0, 0); - escMenuMainPanel.setVisible(false); - this.smashEscMenu.add(escMenuBackdrop); - this.smashEscMenu.add(escMenuMainPanel); - - final UIFrame escMenuInnerMainPanel = this.rootFrame.getFrameByName("MainPanel", 0); - final GlueTextButtonFrame pauseButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("PauseButton", 0); - pauseButton.setEnabled(false); - final GlueTextButtonFrame saveGameButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("SaveGameButton", - 0); - saveGameButton.setEnabled(false); - final GlueTextButtonFrame loadGameButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("LoadGameButton", - 0); - loadGameButton.setEnabled(false); - final GlueTextButtonFrame optionsButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("OptionsButton", - 0); - optionsButton.setEnabled(false); - final GlueTextButtonFrame helpButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("HelpButton", 0); - helpButton.setEnabled(false); - final GlueTextButtonFrame tipsButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("TipsButton", 0); - tipsButton.setEnabled(false); - final GlueTextButtonFrame endGameButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("EndGameButton", - 0); - final GlueTextButtonFrame returnButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("ReturnButton", 0); - - final UIFrame escMenuInnerEndGamePanel = this.rootFrame.getFrameByName("EndGamePanel", 0); - final GlueTextButtonFrame endGamePreviousButton = (GlueTextButtonFrame) this.rootFrame - .getFrameByName("PreviousButton", 0); - final GlueTextButtonFrame endGameQuitButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("QuitButton", - 0); - final GlueTextButtonFrame endGameRestartButton = (GlueTextButtonFrame) this.rootFrame - .getFrameByName("RestartButton", 0); - endGameRestartButton.setEnabled(false); - final GlueTextButtonFrame endGameExitButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("ExitButton", - 0); - - final UIFrame escMenuInnerConfirmQuitPanel = this.rootFrame.getFrameByName("ConfirmQuitPanel", 0); - final GlueTextButtonFrame confirmQuitCancelButton = (GlueTextButtonFrame) this.rootFrame - .getFrameByName("ConfirmQuitCancelButton", 0); - final GlueTextButtonFrame confirmQuitQuitButton = (GlueTextButtonFrame) this.rootFrame - .getFrameByName("ConfirmQuitQuitButton", 0); - final UIFrame escMenuInnerHelpPanel = this.rootFrame.getFrameByName("HelpPanel", 0); - final UIFrame escMenuInnerTipsPanel = this.rootFrame.getFrameByName("TipsPanel", 0); - escMenuInnerMainPanel.setVisible(false); - escMenuInnerEndGamePanel.setVisible(false); - escMenuInnerConfirmQuitPanel.setVisible(false); - escMenuInnerHelpPanel.setVisible(false); - escMenuInnerTipsPanel.setVisible(false); - - this.menuButton.setOnClick(new Runnable() { - @Override - public void run() { - escMenuBackdrop.setVisible(true); - escMenuMainPanel.setVisible(true); - MeleeUI.this.smashEscMenu.setVisible(true); - escMenuInnerMainPanel.setVisible(true); - updateEscMenuCurrentPanel(escMenuBackdrop, escMenuMainPanel, escMenuInnerMainPanel); - } - }); - returnButton.setOnClick(new Runnable() { - @Override - public void run() { - escMenuBackdrop.setVisible(false); - escMenuMainPanel.setVisible(false); - MeleeUI.this.smashEscMenu.setVisible(false); - escMenuInnerMainPanel.setVisible(false); - } - }); - endGameButton.setOnClick(new Runnable() { - @Override - public void run() { - escMenuInnerMainPanel.setVisible(false); - escMenuInnerEndGamePanel.setVisible(true); - updateEscMenuCurrentPanel(escMenuBackdrop, escMenuMainPanel, escMenuInnerEndGamePanel); - } - }); - endGamePreviousButton.setOnClick(new Runnable() { - @Override - public void run() { - escMenuInnerEndGamePanel.setVisible(false); - escMenuInnerMainPanel.setVisible(true); - updateEscMenuCurrentPanel(escMenuBackdrop, escMenuMainPanel, escMenuInnerMainPanel); - } - }); - endGameQuitButton.setOnClick(new Runnable() { - @Override - public void run() { - escMenuInnerEndGamePanel.setVisible(false); - MeleeUI.this.exitGameRunnable.run(); - } - }); - endGameExitButton.setOnClick(new Runnable() { - @Override - public void run() { - escMenuInnerEndGamePanel.setVisible(false); - escMenuInnerConfirmQuitPanel.setVisible(true); - updateEscMenuCurrentPanel(escMenuBackdrop, escMenuMainPanel, escMenuInnerConfirmQuitPanel); - } - }); - confirmQuitCancelButton.setOnClick(new Runnable() { - @Override - public void run() { - escMenuInnerEndGamePanel.setVisible(true); - escMenuInnerConfirmQuitPanel.setVisible(false); - updateEscMenuCurrentPanel(escMenuBackdrop, escMenuMainPanel, escMenuInnerEndGamePanel); - } - }); - confirmQuitQuitButton.setOnClick(new Runnable() { - @Override - public void run() { - Gdx.app.exit(); - } - }); - - // Create the Time Indicator (clock) - this.timeIndicator = (SpriteFrame) this.rootFrame.createFrame("TimeOfDayIndicator", this.rootFrame, 0, 0); - this.timeIndicator.setSequence(0); // play the stand - this.timeIndicator.setAnimationSpeed(0.0f); // do not advance automatically - - // Create the unit portrait stuff - this.portrait = new Portrait(this.war3MapViewer, this.portraitScene); - positionPortrait(); - this.unitPortrait = this.rootFrame.createSimpleFrame("UnitPortrait", this.consoleUI, 0); - this.unitLifeText = (StringFrame) this.rootFrame.getFrameByName("UnitPortraitHitPointText", 0); - this.unitManaText = (StringFrame) this.rootFrame.getFrameByName("UnitPortraitManaPointText", 0); - - final float infoPanelUnitDetailWidth = GameUI.convertY(this.uiViewport, 0.180f); - final float infoPanelUnitDetailHeight = GameUI.convertY(this.uiViewport, 0.112f); - this.smashSimpleInfoPanel = this.rootFrame.createSimpleFrame("SmashSimpleInfoPanel", this.rootFrame, 0); - this.smashSimpleInfoPanel - .addAnchor(new AnchorDefinition(FramePoint.BOTTOM, 0, GameUI.convertY(this.uiViewport, 0.0f))); - this.smashSimpleInfoPanel.setWidth(infoPanelUnitDetailWidth); - this.smashSimpleInfoPanel.setHeight(infoPanelUnitDetailHeight); - - // Create Simple Info Unit Detail - this.simpleInfoPanelUnitDetail = this.rootFrame.createSimpleFrame("SimpleInfoPanelUnitDetail", - this.smashSimpleInfoPanel, 0); - this.simpleNameValue = (StringFrame) this.rootFrame.getFrameByName("SimpleNameValue", 0); - this.simpleClassValue = (StringFrame) this.rootFrame.getFrameByName("SimpleClassValue", 0); - this.simpleBuildingActionLabel = (StringFrame) this.rootFrame.getFrameByName("SimpleBuildingActionLabel", 0); - this.simpleBuildTimeIndicator = (SimpleStatusBarFrame) this.rootFrame.getFrameByName("SimpleBuildTimeIndicator", - 0); - final TextureFrame simpleBuildTimeIndicatorBar = this.simpleBuildTimeIndicator.getBarFrame(); - simpleBuildTimeIndicatorBar.setTexture("SimpleBuildTimeIndicator", this.rootFrame); - final TextureFrame simpleBuildTimeIndicatorBorder = this.simpleBuildTimeIndicator.getBorderFrame(); - simpleBuildTimeIndicatorBorder.setTexture("SimpleBuildTimeIndicatorBorder", this.rootFrame); - final float buildTimeIndicatorWidth = GameUI.convertX(this.uiViewport, 0.10538f); - final float buildTimeIndicatorHeight = GameUI.convertY(this.uiViewport, 0.0103f); - this.simpleBuildTimeIndicator.setWidth(buildTimeIndicatorWidth); - this.simpleBuildTimeIndicator.setHeight(buildTimeIndicatorHeight); - - this.simpleHeroLevelBar = (SimpleStatusBarFrame) this.rootFrame.getFrameByName("SimpleHeroLevelBar", 0); - final TextureFrame simpleHeroLevelBarBar = this.simpleHeroLevelBar.getBarFrame(); - simpleHeroLevelBarBar.setTexture("SimpleXpBarConsole", this.rootFrame); - simpleHeroLevelBarBar.setColor(new Color(138f / 255f, 0, 131f / 255f, 1f)); - final TextureFrame simpleHeroLevelBarBorder = this.simpleHeroLevelBar.getBorderFrame(); - simpleHeroLevelBarBorder.setTexture("SimpleXpBarBorder", this.rootFrame); - this.simpleHeroLevelBar.setWidth(infoPanelUnitDetailWidth); - - // Create Simple Info Panel Building Detail - this.simpleInfoPanelBuildingDetail = this.rootFrame.createSimpleFrame("SimpleInfoPanelBuildingDetail", - this.smashSimpleInfoPanel, 0); - this.simpleBuildingNameValue = (StringFrame) this.rootFrame.getFrameByName("SimpleBuildingNameValue", 0); - this.simpleBuildingDescriptionValue = (StringFrame) this.rootFrame - .getFrameByName("SimpleBuildingDescriptionValue", 0); - this.simpleBuildingBuildingActionLabel = (StringFrame) this.rootFrame - .getFrameByName("SimpleBuildingActionLabel", 0); - this.simpleBuildingBuildTimeIndicator = (SimpleStatusBarFrame) this.rootFrame - .getFrameByName("SimpleBuildTimeIndicator", 0); - final TextureFrame simpleBuildingBuildTimeIndicatorBar = this.simpleBuildingBuildTimeIndicator.getBarFrame(); - simpleBuildingBuildTimeIndicatorBar.setTexture("SimpleBuildTimeIndicator", this.rootFrame); - final TextureFrame simpleBuildingBuildTimeIndicatorBorder = this.simpleBuildingBuildTimeIndicator - .getBorderFrame(); - simpleBuildingBuildTimeIndicatorBorder.setTexture("SimpleBuildTimeIndicatorBorder", this.rootFrame); - this.simpleBuildingBuildTimeIndicator.setWidth(buildTimeIndicatorWidth); - this.simpleBuildingBuildTimeIndicator.setHeight(buildTimeIndicatorHeight); - this.simpleInfoPanelBuildingDetail.setVisible(false); - final TextureFrame simpleBuildQueueBackdrop = (TextureFrame) this.rootFrame - .getFrameByName("SimpleBuildQueueBackdrop", 0); - simpleBuildQueueBackdrop.setWidth(infoPanelUnitDetailWidth); - simpleBuildQueueBackdrop.setHeight(infoPanelUnitDetailWidth * 0.5f); - - this.queueIconFrames[0] = new QueueIcon("SmashBuildQueueIcon0", this.smashSimpleInfoPanel, this, 0); - final TextureFrame queueIconFrameBackdrop0 = new TextureFrame("SmashBuildQueueIcon0Backdrop", - this.queueIconFrames[0], false, new Vector4Definition(0, 1, 0, 1)); - queueIconFrameBackdrop0 - .addSetPoint(new SetPoint(FramePoint.CENTER, this.queueIconFrames[0], FramePoint.CENTER, 0, 0)); - this.queueIconFrames[0].set(queueIconFrameBackdrop0); - this.queueIconFrames[0] - .addSetPoint(new SetPoint(FramePoint.CENTER, this.smashSimpleInfoPanel, FramePoint.BOTTOMLEFT, - (infoPanelUnitDetailWidth * (15 + 19f)) / 256, (infoPanelUnitDetailWidth * (66 + 19f)) / 256)); - final float frontQueueIconWidth = (infoPanelUnitDetailWidth * 38) / 256; - this.queueIconFrames[0].setWidth(frontQueueIconWidth); - this.queueIconFrames[0].setHeight(frontQueueIconWidth); - queueIconFrameBackdrop0.setWidth(frontQueueIconWidth); - queueIconFrameBackdrop0.setHeight(frontQueueIconWidth); - this.rootFrame.add(this.queueIconFrames[0]); - - for (int i = 1; i < this.queueIconFrames.length; i++) { - this.queueIconFrames[i] = new QueueIcon("SmashBuildQueueIcon" + i, this.smashSimpleInfoPanel, this, i); - final TextureFrame queueIconFrameBackdrop = new TextureFrame("SmashBuildQueueIcon" + i + "Backdrop", - this.queueIconFrames[i], false, new Vector4Definition(0, 1, 0, 1)); - this.queueIconFrames[i].set(queueIconFrameBackdrop); - queueIconFrameBackdrop - .addSetPoint(new SetPoint(FramePoint.CENTER, this.queueIconFrames[i], FramePoint.CENTER, 0, 0)); - this.queueIconFrames[i].addSetPoint(new SetPoint(FramePoint.CENTER, this.smashSimpleInfoPanel, - FramePoint.BOTTOMLEFT, (infoPanelUnitDetailWidth * (13 + 14.5f + (40 * (i - 1)))) / 256, - (infoPanelUnitDetailWidth * (24 + 14.5f)) / 256)); - final float queueIconWidth = (infoPanelUnitDetailWidth * 29) / 256; - this.queueIconFrames[i].setWidth(queueIconWidth); - this.queueIconFrames[i].setHeight(queueIconWidth); - queueIconFrameBackdrop.setWidth(queueIconWidth); - queueIconFrameBackdrop.setHeight(queueIconWidth); - this.rootFrame.add(this.queueIconFrames[i]); - } - this.selectWorkerInsideFrame = new QueueIcon("SmashBuildQueueWorkerIcon", this.smashSimpleInfoPanel, this, 1); - final TextureFrame selectWorkerInsideIconFrameBackdrop = new TextureFrame("SmashBuildQueueWorkerIconBackdrop", - this.selectWorkerInsideFrame, false, new Vector4Definition(0, 1, 0, 1)); - this.selectWorkerInsideFrame.set(selectWorkerInsideIconFrameBackdrop); - selectWorkerInsideIconFrameBackdrop - .addSetPoint(new SetPoint(FramePoint.CENTER, this.selectWorkerInsideFrame, FramePoint.CENTER, 0, 0)); - this.selectWorkerInsideFrame - .addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.queueIconFrames[1], FramePoint.TOPLEFT, 0, 0)); - this.selectWorkerInsideFrame.setWidth(frontQueueIconWidth); - this.selectWorkerInsideFrame.setHeight(frontQueueIconWidth); - selectWorkerInsideIconFrameBackdrop.setWidth(frontQueueIconWidth); - selectWorkerInsideIconFrameBackdrop.setHeight(frontQueueIconWidth); - this.rootFrame.add(this.selectWorkerInsideFrame); - - for (int i = 0; i < this.selectedUnitFrames.length; i++) { - this.selectedUnitFrames[i] = new QueueIcon("SmashMultiSelectUnitIcon", this.smashSimpleInfoPanel, this, i); - final TextureFrame multiSelectUnitIconFrameBackdrop = new TextureFrame("SmashMultiSelectUnitIconBackdrop", - this.selectedUnitFrames[i], false, new Vector4Definition(0, 1, 0, 1)); - final TextureFrame selectedSubgroupHighlightBackdrop = new TextureFrame("SmashMultiSelectUnitIconBackdrop", - this.selectedUnitFrames[i], false, new Vector4Definition(0, 1, 0, 1)); - this.selectedUnitFrames[i].set(multiSelectUnitIconFrameBackdrop); - multiSelectUnitIconFrameBackdrop - .addSetPoint(new SetPoint(FramePoint.CENTER, this.selectedUnitFrames[i], FramePoint.CENTER, 0, 0)); - final int halfSelectionMaxSize = this.selectedUnitFrames.length / 2; - this.selectedUnitFrames[i] - .addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.smashSimpleInfoPanel, FramePoint.TOPLEFT, - (frontQueueIconWidth * .10f) + (frontQueueIconWidth * 1.10f * (i % halfSelectionMaxSize)), - (frontQueueIconWidth * -.5f) - (frontQueueIconWidth * 1.5f * (i / halfSelectionMaxSize)))); - this.selectedUnitFrames[i].setWidth(frontQueueIconWidth); - this.selectedUnitFrames[i].setHeight(frontQueueIconWidth); - multiSelectUnitIconFrameBackdrop.setWidth(frontQueueIconWidth); - multiSelectUnitIconFrameBackdrop.setHeight(frontQueueIconWidth); - this.rootFrame.add(this.selectedUnitFrames[i]); - this.selectedUnitFrames[i].setVisible(false); - } - - this.smashAttack1IconWrapper = (SimpleFrame) this.rootFrame.createSimpleFrame("SmashSimpleInfoPanelIconDamage", - this.simpleInfoPanelUnitDetail, 0); - this.smashAttack1IconWrapper.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, - FramePoint.TOPLEFT, 0, GameUI.convertY(this.uiViewport, -0.032f))); - this.smashAttack1IconWrapper.setWidth(GameUI.convertX(this.uiViewport, 0.1f)); - this.smashAttack1IconWrapper.setHeight(GameUI.convertY(this.uiViewport, 0.030125f)); - this.attack1Icon = this.rootFrame.createSimpleFrame("SimpleInfoPanelIconDamage", this.smashAttack1IconWrapper, - 0); - this.attack1IconBackdrop = (TextureFrame) this.rootFrame.getFrameByName("InfoPanelIconBackdrop", 0); - this.attack1InfoPanelIconValue = (StringFrame) this.rootFrame.getFrameByName("InfoPanelIconValue", 0); - this.attack1InfoPanelIconLevel = (StringFrame) this.rootFrame.getFrameByName("InfoPanelIconLevel", 0); - - this.smashAttack2IconWrapper = (SimpleFrame) this.rootFrame.createSimpleFrame("SmashSimpleInfoPanelIconDamage", - this.simpleInfoPanelUnitDetail, 0); - this.smashAttack2IconWrapper - .addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, FramePoint.TOPLEFT, - GameUI.convertX(this.uiViewport, 0.1f), GameUI.convertY(this.uiViewport, -0.03125f))); - this.smashAttack2IconWrapper.setWidth(GameUI.convertX(this.uiViewport, 0.1f)); - this.smashAttack2IconWrapper.setHeight(GameUI.convertY(this.uiViewport, 0.030125f)); - this.attack2Icon = this.rootFrame.createSimpleFrame("SimpleInfoPanelIconDamage", this.smashAttack2IconWrapper, - 1); - this.attack2IconBackdrop = (TextureFrame) this.rootFrame.getFrameByName("InfoPanelIconBackdrop", 1); - this.attack2InfoPanelIconValue = (StringFrame) this.rootFrame.getFrameByName("InfoPanelIconValue", 1); - this.attack2InfoPanelIconLevel = (StringFrame) this.rootFrame.getFrameByName("InfoPanelIconLevel", 1); - - this.smashArmorIconWrapper = (SimpleFrame) this.rootFrame.createSimpleFrame("SmashSimpleInfoPanelIconArmor", - this.simpleInfoPanelUnitDetail, 0); - this.smashArmorIconWrapper.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, - FramePoint.TOPLEFT, GameUI.convertX(this.uiViewport, 0f), GameUI.convertY(this.uiViewport, -0.0625f))); - this.smashArmorIconWrapper.setWidth(GameUI.convertX(this.uiViewport, 0.1f)); - this.smashArmorIconWrapper.setHeight(GameUI.convertY(this.uiViewport, 0.030125f)); - this.armorIcon = this.rootFrame.createSimpleFrame("SimpleInfoPanelIconArmor", this.smashArmorIconWrapper, 0); - this.armorIconBackdrop = (TextureFrame) this.rootFrame.getFrameByName("InfoPanelIconBackdrop", 0); - this.armorInfoPanelIconValue = (StringFrame) this.rootFrame.getFrameByName("InfoPanelIconValue", 0); - this.armorInfoPanelIconLevel = (StringFrame) this.rootFrame.getFrameByName("InfoPanelIconLevel", 0); - - this.smashHeroInfoPanelWrapper = (SimpleFrame) this.rootFrame.createSimpleFrame("SmashSimpleInfoPanelIconHero", - this.simpleInfoPanelUnitDetail, 0); - this.smashHeroInfoPanelWrapper.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, - FramePoint.TOPLEFT, GameUI.convertX(this.uiViewport, 0.1f), GameUI.convertY(this.uiViewport, -0.029f))); - this.smashHeroInfoPanelWrapper.setWidth(GameUI.convertX(this.uiViewport, 0.1f)); - this.smashHeroInfoPanelWrapper.setHeight(GameUI.convertY(this.uiViewport, 0.0625f)); - this.heroInfoPanel = this.rootFrame.createSimpleFrame("SimpleInfoPanelIconHero", this.smashHeroInfoPanelWrapper, - 0); - this.primaryAttributeIcon = (TextureFrame) this.rootFrame.getFrameByName("InfoPanelIconHeroIcon", 0); - this.strengthValue = (StringFrame) this.rootFrame.getFrameByName("InfoPanelIconHeroStrengthValue", 0); - this.agilityValue = (StringFrame) this.rootFrame.getFrameByName("InfoPanelIconHeroAgilityValue", 0); - this.intelligenceValue = (StringFrame) this.rootFrame.getFrameByName("InfoPanelIconHeroIntellectValue", 0); - - this.inventoryBarFrame = (SimpleFrame) this.rootFrame.createSimpleFrame("SmashSimpleInventoryBar", - this.rootFrame, 0); - this.inventoryBarFrame.setWidth(GameUI.convertX(this.uiViewport, 0.079f)); - this.inventoryBarFrame.setHeight(GameUI.convertY(this.uiViewport, 0.115f)); - this.inventoryBarFrame.addSetPoint(new SetPoint(FramePoint.BOTTOMRIGHT, this.consoleUI, FramePoint.BOTTOMLEFT, - GameUI.convertX(this.uiViewport, 0.591f), GameUI.convertY(this.uiViewport, 0.0f))); - - if (GameUI.DEBUG) { - final FilterModeTextureFrame placeholderPreview = new FilterModeTextureFrame(null, this.inventoryBarFrame, - false, null); - placeholderPreview.setFilterMode(FilterMode.ADDALPHA); - placeholderPreview.setTexture("ReplaceableTextures\\TeamColor\\TeamColor06.blp", this.rootFrame); - placeholderPreview.setSetAllPoints(true); - this.inventoryBarFrame.add(placeholderPreview); - } - - int commandButtonIndex = 0; - for (int j = 0; j < INVENTORY_HEIGHT; j++) { - for (int i = 0; i < INVENTORY_WIDTH; i++) { - final CommandCardIcon commandCardIcon = new CommandCardIcon( - "SmashInventoryButton_" + commandButtonIndex, this.inventoryBarFrame, - this.itemCommandCardCommandListener); - this.inventoryBarFrame.add(commandCardIcon); - final TextureFrame iconFrame = new TextureFrame( - "SmashInventoryButton_" + (commandButtonIndex) + "_Icon", this.rootFrame, false, null); - final SpriteFrame cooldownFrame = (SpriteFrame) this.rootFrame.createFrameByType("SPRITE", - "SmashInventoryButton_" + (commandButtonIndex) + "_Cooldown", this.rootFrame, "", 0); - commandCardIcon.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.inventoryBarFrame, FramePoint.TOPLEFT, - GameUI.convertX(this.uiViewport, 0.0037f + (0.04f * i)), - GameUI.convertY(this.uiViewport, -0.0021f - (0.03815f * j)))); - commandCardIcon.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_INVENTORY_ICON_WIDTH)); - commandCardIcon.setHeight(GameUI.convertY(this.uiViewport, DEFAULT_INVENTORY_ICON_WIDTH)); - iconFrame.addSetPoint(new SetPoint(FramePoint.CENTER, commandCardIcon, FramePoint.CENTER, 0, 0)); - iconFrame.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_INVENTORY_ICON_WIDTH)); - iconFrame.setHeight(GameUI.convertY(this.uiViewport, DEFAULT_INVENTORY_ICON_WIDTH)); - iconFrame.setTexture(ImageUtils.DEFAULT_ICON_PATH, this.rootFrame); - cooldownFrame.addSetPoint(new SetPoint(FramePoint.CENTER, commandCardIcon, FramePoint.CENTER, 0, 0)); - this.rootFrame.setSpriteFrameModel(cooldownFrame, this.rootFrame.getSkinField("CommandButtonCooldown")); - cooldownFrame.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_INVENTORY_ICON_WIDTH)); - cooldownFrame.setHeight(GameUI.convertY(this.uiViewport, DEFAULT_INVENTORY_ICON_WIDTH)); - commandCardIcon.set(iconFrame, null, cooldownFrame, null); - this.inventoryIcons[j][i] = commandCardIcon; - commandCardIcon.clear(); - commandButtonIndex++; - } - } - this.inventoryTitleFrame = this.rootFrame.createStringFrame("SmashInventoryText", this.inventoryBarFrame, - new Color(0xFCDE12FF), TextJustify.CENTER, TextJustify.MIDDLE, 0.0109f); - this.rootFrame.setText(this.inventoryTitleFrame, this.rootFrame.getTemplates().getDecoratedString("INVENTORY")); - this.inventoryTitleFrame - .addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.inventoryBarFrame, FramePoint.TOPLEFT, - GameUI.convertX(this.uiViewport, 0.004f), GameUI.convertY(this.uiViewport, 0.0165625f))); - this.inventoryTitleFrame.setWidth(GameUI.convertX(this.uiViewport, 0.071f)); - this.inventoryTitleFrame.setHeight(GameUI.convertX(this.uiViewport, 0.01125f)); - this.inventoryTitleFrame.setFontShadowColor(new Color(0f, 0f, 0f, 0.9f)); - this.inventoryTitleFrame.setFontShadowOffsetX(GameUI.convertX(this.uiViewport, 0.001f)); - this.inventoryTitleFrame.setFontShadowOffsetY(GameUI.convertY(this.uiViewport, -0.001f)); - this.consoleInventoryNoCapacityTexture = ImageUtils.getAnyExtensionTexture(this.dataSource, - this.rootFrame.getSkinField("ConsoleInventoryNoCapacity")); - - this.inventoryCover = this.rootFrame.createSimpleFrame("SmashConsoleInventoryCover", this.rootFrame, 0); - - final Element fontHeights = this.war3MapViewer.miscData.get("FontHeights"); - final float worldFrameMessageFontHeight = fontHeights.getFieldFloatValue("WorldFrameMessage"); - this.errorMessageFrame = this.rootFrame.createStringFrame("SmashErrorMessageFrame", this.rootFrame, - new Color(0xFFCC00FF), TextJustify.LEFT, TextJustify.MIDDLE, worldFrameMessageFontHeight); - this.errorMessageFrame.addAnchor(new AnchorDefinition(FramePoint.BOTTOMLEFT, - GameUI.convertX(this.uiViewport, 0.212f), GameUI.convertY(this.uiViewport, 0.182f))); - this.errorMessageFrame.setWidth(GameUI.convertX(this.uiViewport, 0.35f)); - this.errorMessageFrame.setHeight(GameUI.convertY(this.uiViewport, worldFrameMessageFontHeight)); - - this.errorMessageFrame.setFontShadowColor(new Color(0f, 0f, 0f, 0.9f)); - this.errorMessageFrame.setFontShadowOffsetX(GameUI.convertX(this.uiViewport, 0.001f)); - this.errorMessageFrame.setFontShadowOffsetY(GameUI.convertY(this.uiViewport, -0.001f)); - this.errorMessageFrame.setVisible(false); - - commandButtonIndex = 0; - for (int j = 0; j < COMMAND_CARD_HEIGHT; j++) { - for (int i = 0; i < COMMAND_CARD_WIDTH; i++) { - final CommandCardIcon commandCardIcon = new CommandCardIcon("SmashCommandButton_" + commandButtonIndex, - this.rootFrame, this); - this.rootFrame.add(commandCardIcon); - final TextureFrame iconFrame = new TextureFrame("SmashCommandButton_" + (commandButtonIndex) + "_Icon", - this.rootFrame, false, null); - final FilterModeTextureFrame activeHighlightFrame = new FilterModeTextureFrame( - "SmashCommandButton_" + (commandButtonIndex) + "_ActiveHighlight", this.rootFrame, true, null); - activeHighlightFrame.setFilterMode(FilterMode.ADDALPHA); - final SpriteFrame cooldownFrame = (SpriteFrame) this.rootFrame.createFrameByType("SPRITE", - "SmashCommandButton_" + (commandButtonIndex) + "_Cooldown", this.rootFrame, "", 0); - final SpriteFrame autocastFrame = (SpriteFrame) this.rootFrame.createFrameByType("SPRITE", - "SmashCommandButton_" + (commandButtonIndex) + "_Autocast", this.rootFrame, "", 0); - commandCardIcon.addAnchor(new AnchorDefinition(FramePoint.BOTTOMLEFT, - GameUI.convertX(this.uiViewport, 0.6175f + (0.0434f * i)), - GameUI.convertY(this.uiViewport, 0.095f - (0.044f * j)))); - commandCardIcon.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH)); - commandCardIcon.setHeight(GameUI.convertY(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH)); - iconFrame.addSetPoint(new SetPoint(FramePoint.CENTER, commandCardIcon, FramePoint.CENTER, 0, 0)); - iconFrame.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH)); - iconFrame.setHeight(GameUI.convertY(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH)); - iconFrame.setTexture(ImageUtils.DEFAULT_ICON_PATH, this.rootFrame); - activeHighlightFrame - .addSetPoint(new SetPoint(FramePoint.CENTER, commandCardIcon, FramePoint.CENTER, 0, 0)); - activeHighlightFrame.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH)); - activeHighlightFrame.setHeight(GameUI.convertY(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH)); - activeHighlightFrame.setTexture("CommandButtonActiveHighlight", this.rootFrame); - cooldownFrame.addSetPoint(new SetPoint(FramePoint.CENTER, commandCardIcon, FramePoint.CENTER, 0, 0)); - this.rootFrame.setSpriteFrameModel(cooldownFrame, this.rootFrame.getSkinField("CommandButtonCooldown")); - cooldownFrame.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH)); - cooldownFrame.setHeight(GameUI.convertY(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH)); - autocastFrame.addSetPoint(new SetPoint(FramePoint.CENTER, commandCardIcon, FramePoint.CENTER, 0, 0)); - this.rootFrame.setSpriteFrameModel(autocastFrame, this.rootFrame.getSkinField("CommandButtonAutocast")); - autocastFrame.setWidth(GameUI.convertX(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH)); - autocastFrame.setHeight(GameUI.convertY(this.uiViewport, DEFAULT_COMMAND_CARD_ICON_WIDTH)); - commandCardIcon.set(iconFrame, activeHighlightFrame, cooldownFrame, autocastFrame); - this.commandCard[j][i] = commandCardIcon; - commandCardIcon.clear(); - commandButtonIndex++; - } - } - - this.tooltipFrame = this.rootFrame.createFrame("SmashToolTip", this.rootFrame, 0, 0); - this.tooltipFrame.addAnchor(new AnchorDefinition(FramePoint.BOTTOMRIGHT, GameUI.convertX(this.uiViewport, 0.f), - GameUI.convertY(this.uiViewport, 0.176f))); - this.tooltipFrame.setWidth(GameUI.convertX(this.uiViewport, 0.280f)); - this.tooltipText = (StringFrame) this.rootFrame.getFrameByName("SmashToolTipText", 0); - this.tooltipText.setWidth(GameUI.convertX(this.uiViewport, 0.274f)); - this.tooltipText.addAnchor(new AnchorDefinition(FramePoint.TOPLEFT, GameUI.convertX(this.uiViewport, 0.003f), - GameUI.convertY(this.uiViewport, -0.003f))); - this.tooltipFrame.setVisible(false); - this.tooltipUberTipText = (StringFrame) this.rootFrame.getFrameByName("SmashUberTipText", 0); - this.tooltipUberTipText.setWidth(GameUI.convertX(this.uiViewport, 0.274f)); - this.uberTipNoResourcesSetPoint = new SetPoint(FramePoint.TOPLEFT, this.tooltipText, FramePoint.BOTTOMLEFT, 0, - GameUI.convertY(this.uiViewport, -0.004f)); - this.uberTipWithResourcesSetPoint = new SetPoint(FramePoint.TOPLEFT, this.tooltipText, FramePoint.BOTTOMLEFT, 0, - GameUI.convertY(this.uiViewport, -0.014f)); - this.tooltipUberTipText.addSetPoint(this.uberTipNoResourcesSetPoint); - this.tooltipResourceFrames = new UIFrame[ResourceType.VALUES.length]; - this.tooltipResourceIconFrames = new TextureFrame[ResourceType.VALUES.length]; - this.tooltipResourceTextFrames = new StringFrame[ResourceType.VALUES.length]; - for (int i = 0; i < this.tooltipResourceFrames.length; i++) { - this.tooltipResourceFrames[i] = this.rootFrame.createFrame("SmashToolTipIconResource", this.tooltipFrame, 0, - i); - this.tooltipResourceIconFrames[i] = (TextureFrame) this.rootFrame - .getFrameByName("SmashToolTipIconResourceBackdrop", i); - this.tooltipResourceTextFrames[i] = (StringFrame) this.rootFrame - .getFrameByName("SmashToolTipIconResourceLabel", i); - this.tooltipResourceFrames[i].addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.tooltipText, - FramePoint.BOTTOMLEFT, GameUI.convertX(this.uiViewport, 0.004f + (0.032f * i)), - GameUI.convertY(this.uiViewport, -0.001f))); - // have we really no better API than the below??? - ((AbstractUIFrame) this.tooltipFrame).add(this.tooltipResourceFrames[i]); - this.rootFrame.remove(this.tooltipResourceFrames[i]); - } -// this.tooltipFrame = this.rootFrame.createFrameByType("BACKDROP", "SmashToolTipBackdrop", this.rootFrame, "", 0); - - this.cursorFrame = (SpriteFrame) this.rootFrame.createFrameByType("SPRITE", "SmashCursorFrame", this.rootFrame, - "", 0); - this.rootFrame.setSpriteFrameModel(this.cursorFrame, this.rootFrame.getSkinField("Cursor")); - this.cursorFrame.setSequence("Normal"); - this.cursorFrame.setZDepth(-1.0f); - if (WarsmashConstants.CATCH_CURSOR) { - Gdx.input.setCursorCatched(true); - } - - this.meleeUIMinimap = createMinimap(this.war3MapViewer); - - this.meleeUIAbilityActivationReceiver = new MeleeUIAbilityActivationReceiver( - new AbilityActivationErrorHandler(this.rootFrame.getErrorString("NoGold"), - this.war3MapViewer.getUiSounds().getSound(this.rootFrame.getSkinField("NoGoldSound"))), - new AbilityActivationErrorHandler(this.rootFrame.getErrorString("NoLumber"), - this.war3MapViewer.getUiSounds().getSound(this.rootFrame.getSkinField("NoLumberSound"))), - new AbilityActivationErrorHandler(this.rootFrame.getErrorString("NoFood"), - this.war3MapViewer.getUiSounds().getSound(this.rootFrame.getSkinField("NoFoodSound"))), - new AbilityActivationErrorHandler("", this.war3MapViewer.getUiSounds().getSound("InterfaceError"))); - - final MdxModel rallyModel = (MdxModel) this.war3MapViewer.load( - War3MapViewer.mdx(this.rootFrame.getSkinField("RallyIndicatorDst")), this.war3MapViewer.mapPathSolver, - this.war3MapViewer.solverParams); - this.rallyPointInstance = (MdxComplexInstance) rallyModel.addInstance(); - this.rallyPointInstance.rotate(RenderUnit.tempQuat.setFromAxis(RenderMathUtils.VEC3_UNIT_Z, - this.war3MapViewer.simulation.getGameplayConstants().getBuildingAngle())); - this.rallyPointInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - SequenceUtils.randomStandSequence(this.rallyPointInstance); - this.rallyPointInstance.hide(); - this.waypointModel = (MdxModel) this.war3MapViewer.load( - War3MapViewer.mdx(this.rootFrame.getSkinField("WaypointIndicator")), this.war3MapViewer.mapPathSolver, - this.war3MapViewer.solverParams); - - final FreeTypeFontParameter fontParam = new FreeTypeFontParameter(); - fontParam.size = (int) GameUI.convertY(this.uiViewport, 0.012f); - this.textTagFont = this.rootFrame.getFontGenerator().generateFont(fontParam); - - this.rootFrame.positionBounds(this.rootFrame, this.uiViewport); - - selectUnit(null); - - } - - private void updateEscMenuCurrentPanel(final UIFrame escMenuBackdrop, final UIFrame escMenuMainPanel, - final UIFrame escMenuInnerMainPanel) { - this.smashEscMenu.setWidth(escMenuInnerMainPanel.getAssignedWidth()); - this.smashEscMenu.setHeight(escMenuInnerMainPanel.getAssignedHeight()); - escMenuBackdrop.setWidth(escMenuInnerMainPanel.getAssignedWidth()); - escMenuBackdrop.setHeight(escMenuInnerMainPanel.getAssignedHeight()); - this.smashEscMenu.positionBounds(this.rootFrame, this.uiViewport); - - } - - @Override - public void onClick(final int abilityHandleId, final int orderId, final boolean rightClick) { - if (this.selectedUnit == null) { - return; - } - if (orderId == 0) { - return; - } - // TODO not O(N) - CAbilityView abilityToUse = null; - for (final CAbility ability : this.selectedUnit.getSimulationUnit().getAbilities()) { - if (ability.getHandleId() == abilityHandleId) { - abilityToUse = ability; - break; - } - } - if (abilityToUse != null) { - abilityToUse.checkCanUse(this.war3MapViewer.simulation, this.selectedUnit.getSimulationUnit(), orderId, - this.meleeUIAbilityActivationReceiver.reset(this, this.war3MapViewer.worldScene.audioContext, - this.selectedUnit)); - if (this.meleeUIAbilityActivationReceiver.isUseOk()) { - final BooleanAbilityTargetCheckReceiver noTargetReceiver = BooleanAbilityTargetCheckReceiver - .getInstance().reset(); - abilityToUse.checkCanTargetNoTarget(this.war3MapViewer.simulation, - this.selectedUnit.getSimulationUnit(), orderId, noTargetReceiver); - if (noTargetReceiver.isTargetable()) { - final boolean shiftDown = isShiftDown(); - this.unitOrderListener.issueImmediateOrder(this.selectedUnit.getSimulationUnit().getHandleId(), - abilityHandleId, orderId, shiftDown); - if (this.selectedUnits.size() > 1) { - for (final RenderUnit otherSelectedUnit : this.selectedUnits) { - if (otherSelectedUnit != this.activeCommandUnit) { - abilityToUse = null; - for (final CAbility ability : otherSelectedUnit.getSimulationUnit().getAbilities()) { - final BooleanAbilityTargetCheckReceiver receiver = BooleanAbilityTargetCheckReceiver - .getInstance().reset(); - ability.checkCanTargetNoTarget(this.war3MapViewer.simulation, - otherSelectedUnit.getSimulationUnit(), this.activeCommandOrderId, receiver); - if (receiver.isTargetable()) { - abilityToUse = ability; - } - } - if (abilityToUse != null) { - this.unitOrderListener.issueImmediateOrder( - otherSelectedUnit.getSimulationUnit().getHandleId(), - abilityToUse.getHandleId(), this.activeCommandOrderId, shiftDown); - } - } - } - } - } - else { - this.activeCommand = abilityToUse; - this.activeCommandOrderId = orderId; - this.activeCommandUnit = this.selectedUnit; - clearAndRepopulateCommandCard(); - } - } - } - else { - this.unitOrderListener.issueImmediateOrder(this.selectedUnit.getSimulationUnit().getHandleId(), - abilityHandleId, orderId, isShiftDown()); - if (this.selectedUnits.size() > 1) { - for (final RenderUnit otherSelectedUnit : this.selectedUnits) { - if (otherSelectedUnit != this.activeCommandUnit) { - this.unitOrderListener.issueImmediateOrder(otherSelectedUnit.getSimulationUnit().getHandleId(), - abilityHandleId, orderId, isShiftDown()); - } - } - } - } - if (rightClick) { - this.war3MapViewer.getUiSounds().getSound("AutoCastButtonClick").play(this.uiScene.audioContext, 0, 0, 0); - } - } - - @Override - public void openMenu(final int orderId) { - if (orderId == 0) { - this.subMenuOrderIdStack.clear(); - this.activeCommandUnit = null; - this.activeCommand = null; - this.activeCommandOrderId = -1; - } - else { - this.subMenuOrderIdStack.add(orderId); - } - clearAndRepopulateCommandCard(); - } - - @Override - public void showCommandError(final String message) { - this.rootFrame.setText(this.errorMessageFrame, message); - this.errorMessageFrame.setVisible(true); - final long millis = TimeUtils.millis(); - this.lastErrorMessageExpireTime = millis + WORLD_FRAME_MESSAGE_EXPIRE_MILLIS; - this.lastErrorMessageFadeTime = millis + WORLD_FRAME_MESSAGE_FADEOUT_MILLIS; - this.errorMessageFrame.setAlpha(1.0f); - } - - @Override - public void showCantPlaceError() { - showCommandError(this.rootFrame.getErrorString("Cantplace")); - this.war3MapViewer.getUiSounds().getSound(this.rootFrame.getSkinField("CantPlaceSound")) - .play(this.uiScene.audioContext, 0, 0, 0); - } - - @Override - public void showNoFoodError() { - showCommandError(this.rootFrame.getErrorString("NoFood")); - this.war3MapViewer.getUiSounds().getSound(this.rootFrame.getSkinField("NoFoodSound")) - .play(this.uiScene.audioContext, 0, 0, 0); - } - - @Override - public void showUnableToFindCoupleTargetError() { - showCommandError(this.rootFrame.getErrorString("Cantfindcoupletarget")); - this.war3MapViewer.getUiSounds().getSound("InterfaceError").play(this.uiScene.audioContext, 0, 0, 0); - } - - @Override - public void showInventoryFullError() { - showCommandError(this.rootFrame.getErrorString("InventoryFull")); - this.war3MapViewer.getUiSounds().getSound(this.rootFrame.getSkinField("InventoryFullSound")) - .play(this.uiScene.audioContext, 0, 0, 0); - } - - public void update(final float deltaTime) { - this.portrait.update(); - - final int baseMouseX = Gdx.input.getX(); - int mouseX = baseMouseX; - final int baseMouseY = Gdx.input.getY(); - int mouseY = baseMouseY; - final int minX = this.uiViewport.getScreenX(); - final int maxX = minX + this.uiViewport.getScreenWidth(); - final int minY = this.uiViewport.getScreenY(); - final int maxY = minY + this.uiViewport.getScreenHeight(); - final boolean left = (mouseX <= (minX + 3)) && WarsmashConstants.CATCH_CURSOR; - final boolean right = (mouseX >= (maxX - 3)) && WarsmashConstants.CATCH_CURSOR; - final boolean up = (mouseY <= (minY + 3)) && WarsmashConstants.CATCH_CURSOR; - final boolean down = (mouseY >= (maxY - 3)) && WarsmashConstants.CATCH_CURSOR; - this.cameraManager.applyVelocity(deltaTime, up, down, left, right); - - mouseX = Math.max(minX, Math.min(maxX, mouseX)); - mouseY = Math.max(minY, Math.min(maxY, mouseY)); - if (Gdx.input.isCursorCatched()) { - if (WarsmashConstants.CATCH_CURSOR) { - Gdx.input.setCursorPosition(mouseX, mouseY); - } - } - this.hpBarFrameIndex = 0; - if (this.currentlyDraggingPointer == -1) { - if ((this.mouseOverUnit != null) && !this.mouseOverUnit.getSimulationWidget().isInvulnerable() - && this.mouseOverUnit.isSelectable() && !this.mouseOverUnit.getSimulationWidget().isDead()) { - final SimpleStatusBarFrame simpleStatusBarFrame = getHpBar(); - positionHealthBar(simpleStatusBarFrame, this.mouseOverUnit, 1.0f); - } - } - else if (this.currentlyDraggingPointer == Input.Buttons.LEFT) { - final float minDragX = Math.min(this.lastMouseClickLocation.x, this.lastMouseDragStart.x); - final float minDragY = Math.min(this.lastMouseClickLocation.y, this.lastMouseDragStart.y); - final float maxDragX = Math.max(this.lastMouseClickLocation.x, this.lastMouseDragStart.x); - final float maxDragY = Math.max(this.lastMouseClickLocation.y, this.lastMouseDragStart.y); - this.tempRect.set(minDragX, minDragY, maxDragX - minDragX, maxDragY - minDragY); - this.dragSelectPreviewUnitsUpcoming.clear(); - this.war3MapViewer.simulation.getWorldCollision().enumUnitsInRect(this.tempRect, new CUnitEnumFunction() { - @Override - public boolean call(final CUnit unit) { - final RenderUnit renderUnit = MeleeUI.this.war3MapViewer.getRenderPeer(unit); - if (!unit.isInvulnerable() && !unit.isDead() && renderUnit.isSelectable() - && MeleeUI.this.dragSelectPreviewUnitsUpcoming.add(renderUnit)) { - final SimpleStatusBarFrame simpleStatusBarFrame = getHpBar(); - positionHealthBar(simpleStatusBarFrame, renderUnit, 1.0f); - if (!MeleeUI.this.dragSelectPreviewUnits.contains(renderUnit)) { - MeleeUI.this.war3MapViewer.showUnitMouseOverHighlight(renderUnit); - } - } - return false; - } - }); - for (final RenderUnit unit : this.dragSelectPreviewUnits) { - if (!this.dragSelectPreviewUnitsUpcoming.contains(unit)) { - this.war3MapViewer.clearUnitMouseOverHighlight(unit); - } - } - final Set temp = this.dragSelectPreviewUnits; - this.dragSelectPreviewUnits = this.dragSelectPreviewUnitsUpcoming; - this.dragSelectPreviewUnitsUpcoming = temp; - } - if ((this.selectedUnits != null) && false) { - for (final RenderUnit unit : this.selectedUnits) { - final SimpleStatusBarFrame simpleStatusBarFrame = getHpBar(); - positionHealthBar(simpleStatusBarFrame, unit, 1.0f); - } - } - for (int i = this.hpBarFrameIndex; i < this.hpBarFrames.size(); i++) { - this.hpBarFrames.get(i).setVisible(false); - } - - screenCoordsVector.set(mouseX, mouseY); - this.uiViewport.unproject(screenCoordsVector); - this.cursorFrame.setFramePointX(FramePoint.LEFT, screenCoordsVector.x); - this.cursorFrame.setFramePointY(FramePoint.BOTTOM, screenCoordsVector.y); - - if (this.activeCommand != null) { - if (this.draggingItem != null) { - setCursorState(MenuCursorState.HOLD_ITEM); - } - else { - setCursorState(MenuCursorState.TARGET_CURSOR); - this.activeCommand.visit(this.cursorTargetSetupVisitor.reset(baseMouseX, baseMouseY)); - } - } - else { - if (this.cursorModelInstance != null) { - this.cursorModelInstance.detach(); - this.cursorModelInstance = null; - this.cursorFrame.setVisible(true); - } - if (this.placementCursor != null) { - this.placementCursor.destroy(Gdx.gl30, this.war3MapViewer.terrain.centerOffset); - this.placementCursor = null; - this.cursorFrame.setVisible(true); - } - if (this.cursorModelUnderneathPathingRedGreenSplatModel != null) { - this.war3MapViewer.terrain.removeSplatBatchModel(BUILDING_PATHING_PREVIEW_KEY); - this.cursorModelUnderneathPathingRedGreenSplatModel = null; - } - if (down) { - if (left) { - setCursorState(MenuCursorState.SCROLL_DOWN_LEFT); - } - else if (right) { - setCursorState(MenuCursorState.SCROLL_DOWN_RIGHT); - } - else { - setCursorState(MenuCursorState.SCROLL_DOWN); - } - } - else if (up) { - if (left) { - setCursorState(MenuCursorState.SCROLL_UP_LEFT); - } - else if (right) { - setCursorState(MenuCursorState.SCROLL_UP_RIGHT); - } - else { - setCursorState(MenuCursorState.SCROLL_UP); - } - } - else if (left) { - setCursorState(MenuCursorState.SCROLL_LEFT); - } - else if (right) { - setCursorState(MenuCursorState.SCROLL_RIGHT); - } - else { - setCursorState(MenuCursorState.NORMAL); - } - } - if (this.selectedUnit != null) { - if (this.simpleBuildTimeIndicator.isVisible()) { - this.simpleBuildTimeIndicator - .setValue(Math.min(this.selectedUnit.getSimulationUnit().getConstructionProgress() - / this.selectedUnit.getSimulationUnit().getUnitType().getBuildTime(), 0.99f)); - } - if (this.simpleBuildingBuildTimeIndicator.isVisible()) { - this.simpleBuildingBuildTimeIndicator - .setValue(Math.min( - this.selectedUnit.getSimulationUnit().getConstructionProgress() / this.selectedUnit - .getSimulationUnit().getBuildQueueTimeRemaining(this.war3MapViewer.simulation), - 0.99f)); - } - } - - final float groundHeight = Math.max( - this.war3MapViewer.terrain.getGroundHeight(this.cameraManager.target.x, this.cameraManager.target.y), - this.war3MapViewer.terrain.getWaterHeight(this.cameraManager.target.x, this.cameraManager.target.y)); - this.cameraManager.updateTargetZ(groundHeight); - this.cameraManager.updateCamera(); - final long currentMillis = TimeUtils.millis(); - if (currentMillis > this.lastErrorMessageExpireTime) { - this.errorMessageFrame.setVisible(false); - } - else if (currentMillis > this.lastErrorMessageFadeTime) { - final float fadeAlpha = (this.lastErrorMessageExpireTime - currentMillis) - / (float) WORLD_FRAME_MESSAGE_FADE_DURATION; - this.errorMessageFrame.setAlpha(fadeAlpha); - } - } - - private void positionHealthBar(final SimpleStatusBarFrame simpleStatusBarFrame, final RenderWidget unit, - final float alpha) { - simpleStatusBarFrame.setVisible(true); - clickLocationTemp.x = unit.getX(); - clickLocationTemp.y = unit.getY(); - clickLocationTemp.z = unit.getZ(); - final Bounds unitBounds = unit.getInstance().getBounds(); - if (unitBounds != null) { - final BoundingBox unitBoundsBox = unitBounds.getBoundingBox(); - if (unitBoundsBox != null) { - clickLocationTemp.z += unitBoundsBox.max.z; - } - } - this.war3MapViewer.worldScene.camera.worldToScreen(screenCoordsVector, clickLocationTemp); - simpleStatusBarFrame.getBarFrame().setTexture("SimpleHpBarConsole", this.rootFrame); - simpleStatusBarFrame.getBorderFrame().setTexture("Textures\\Black32.blp", this.rootFrame); - simpleStatusBarFrame.getBorderFrame().setColor(0f, 0f, 0f, alpha); - final float lifeRatioRemaining = unit.getSimulationWidget().getLife() / unit.getSimulationWidget().getMaxLife(); - simpleStatusBarFrame.getBarFrame().setColor(Math.min(1.0f, 2.0f - (lifeRatioRemaining * 2)), - Math.min(1.0f, lifeRatioRemaining * 2), 0, alpha); - final Vector2 unprojected = this.uiViewport.unproject(screenCoordsVector); - simpleStatusBarFrame.setWidth((unit.getSelectionScale() * 1.5f * Gdx.graphics.getWidth()) / 2560); - simpleStatusBarFrame.setHeight(16); - simpleStatusBarFrame.addSetPoint( - new SetPoint(FramePoint.CENTER, this.rootFrame, FramePoint.BOTTOMLEFT, unprojected.x, unprojected.y)); - simpleStatusBarFrame.setValue(lifeRatioRemaining); - simpleStatusBarFrame.positionBounds(this.rootFrame, this.uiViewport); - } - - private SimpleStatusBarFrame getHpBar() { - final SimpleStatusBarFrame simpleStatusBarFrame; - if (this.hpBarFrameIndex >= this.hpBarFrames.size()) { - simpleStatusBarFrame = new SimpleStatusBarFrame("SmashHpBar" + this.hpBarFrameIndex, this.rootFrame, true, - true, 3.0f); - this.rootFrame.add(simpleStatusBarFrame); - this.hpBarFrames.add(simpleStatusBarFrame); - } - else { - simpleStatusBarFrame = this.hpBarFrames.get(this.hpBarFrameIndex); - } - this.hpBarFrameIndex++; - return simpleStatusBarFrame; - } - - private void setCursorState(final MenuCursorState state) { - if (state != this.cursorState) { - if (state.getAnimationName() != null) { - this.cursorFrame.setSequence(state.getAnimationName()); - } - } - this.cursorState = state; - } - - public void render(final SpriteBatch batch, final GlyphLayout glyphLayout) { - final BitmapFont font = this.rootFrame.getFont(); - font.setColor(Color.YELLOW); - final String fpsString = "FPS: " + Gdx.graphics.getFramesPerSecond(); - glyphLayout.setText(font, fpsString); - font.draw(batch, fpsString, (this.uiViewport.getMinWorldWidth() - glyphLayout.width) / 2, - 1100 * this.heightRatioCorrection); - this.rootFrame.render(batch, this.rootFrame.getFont20(), glyphLayout); - if (this.selectedUnit != null) { - this.rootFrame.getFont20().setColor(Color.WHITE); - - } - - this.meleeUIMinimap.render(batch, this.war3MapViewer.units); - this.timeIndicator.setFrameByRatio(this.war3MapViewer.simulation.getGameTimeOfDay() - / this.war3MapViewer.simulation.getGameplayConstants().getGameDayHours()); - for (final TextTag textTag : this.war3MapViewer.textTags) { - this.war3MapViewer.worldScene.camera.worldToScreen(screenCoordsVector, textTag.getPosition()); - if (this.war3MapViewer.worldScene.camera.rect.contains(screenCoordsVector.x, - (Gdx.graphics.getHeight() - screenCoordsVector.y) + textTag.getScreenCoordsZHeight())) { - final Vector2 unprojected = this.uiViewport.unproject(screenCoordsVector); - final float remainingLife = textTag.getRemainingLife(); - final float alpha = (remainingLife > 1.0f ? 1.0f : remainingLife); - this.textTagFont.setColor(textTag.getColor().r, textTag.getColor().g, textTag.getColor().b, - textTag.getColor().a * alpha); - glyphLayout.setText(this.textTagFont, textTag.getText()); - this.textTagFont.draw(batch, textTag.getText(), unprojected.x - (glyphLayout.width / 2), - (unprojected.y - (glyphLayout.height / 2)) + textTag.getScreenCoordsZHeight()); - } - } - if (this.currentlyDraggingPointer == Input.Buttons.LEFT) { - batch.end(); - this.shapeRenderer.setProjectionMatrix(batch.getProjectionMatrix()); - this.shapeRenderer.setColor(Color.GREEN); - Gdx.gl.glLineWidth(2); - this.shapeRenderer.begin(ShapeType.Line); - this.cameraManager.camera.worldToScreen(screenCoordsVector, this.lastMouseDragStart); - final Vector2 unprojected = this.uiViewport.unproject(screenCoordsVector); - final float x = unprojected.x; - final float y = unprojected.y; - this.cameraManager.camera.worldToScreen(screenCoordsVector, this.lastMouseClickLocation); - final Vector2 unprojectedEnd = this.uiViewport.unproject(screenCoordsVector); - final float minX = Math.min(x, unprojectedEnd.x); - final float minY = Math.min(y, unprojectedEnd.y); - this.shapeRenderer.rect(minX, minY, Math.max(x, unprojectedEnd.x) - minX, - Math.max(y, unprojectedEnd.y) - minY); - this.shapeRenderer.end(); - Gdx.gl.glLineWidth(1); - batch.begin(); - } - } - - public void portraitTalk() { - this.portrait.talk(); - } - - private final class CursorTargetSetupVisitor implements CAbilityVisitor { - private int baseMouseX; - private int baseMouseY; - - private CursorTargetSetupVisitor reset(final int baseMouseX, final int baseMouseY) { - this.baseMouseX = baseMouseX; - this.baseMouseY = baseMouseY; - return this; - } - - @Override - public Void accept(final CAbilityAttack ability) { - if (MeleeUI.this.activeCommandOrderId == OrderIds.attackground) { - float radius = 0; - for (final CUnitAttack attack : MeleeUI.this.activeCommandUnit.getSimulationUnit().getAttacks()) { - if (attack.getWeaponType().isAttackGroundSupported()) { - if (attack instanceof CUnitAttackMissileSplash) { - final int areaOfEffectSmallDamage = ((CUnitAttackMissileSplash) attack) - .getAreaOfEffectSmallDamage(); - radius = areaOfEffectSmallDamage; - } - } - } - handlePlacementCursor(ability, radius); - } - else { - handleTargetCursor(ability); - } - return null; - } - - @Override - public Void accept(final CAbilityMove ability) { - handleTargetCursor(ability); - return null; - } - - @Override - public Void accept(final CAbilityOrcBuild ability) { - handleBuildCursor(ability); - return null; - } - - @Override - public Void accept(final CAbilityHumanBuild ability) { - handleBuildCursor(ability); - return null; - } - - @Override - public Void accept(final CAbilityUndeadBuild ability) { - handleBuildCursor(ability); - return null; - } - - @Override - public Void accept(final CAbilityNightElfBuild ability) { - handleBuildCursor(ability); - return null; - } - - @Override - public Void accept(final CAbilityGeneric ability) { - handleTargetCursor(ability); - return null; - } - - @Override - public Void accept(final CAbilityColdArrows ability) { - handleTargetCursor(ability); - return null; - } - - @Override - public Void accept(final CAbilityNagaBuild ability) { - handleBuildCursor(ability); - return null; - } - - @Override - public Void accept(final CAbilityNeutralBuild ability) { - handleBuildCursor(ability); - return null; - } - - @Override - public Void accept(final CAbilityBuildInProgress ability) { - handleTargetCursor(ability); - return null; - } - - @Override - public Void accept(final CAbilityQueue ability) { - handleTargetCursor(ability); - return null; - } - - @Override - public Void accept(final CAbilityReviveHero ability) { - handleTargetCursor(ability); - return null; - } - - @Override - public Void accept(final GenericSingleIconActiveAbility ability) { - handleTargetCursor(ability); - return null; - } - - @Override - public Void accept(final GenericNoIconAbility ability) { - // this should probably never happen - handleTargetCursor(ability); - return null; - } - - @Override - public Void accept(final CAbilityRally ability) { - handleTargetCursor(ability); - return null; - } - - @Override - public Void accept(final CAbilityHero ability) { - handleTargetCursor(ability); - return null; - } - - private void handleTargetCursor(final CAbility ability) { - if (MeleeUI.this.cursorModelInstance != null) { - MeleeUI.this.cursorModelInstance.detach(); - MeleeUI.this.cursorModelInstance = null; - MeleeUI.this.cursorFrame.setVisible(true); - } - MeleeUI.this.cursorFrame.setSequence("Target"); - } - - private void handleBuildCursor(final AbstractCAbilityBuild ability) { - boolean justLoaded = false; - final War3MapViewer viewer = MeleeUI.this.war3MapViewer; - if (MeleeUI.this.cursorModelInstance == null) { - final MutableObjectData unitData = viewer.getAllObjectData().getUnits(); - final War3ID buildingTypeId = new War3ID(MeleeUI.this.activeCommandOrderId); - MeleeUI.this.cursorBuildingUnitType = viewer.simulation.getUnitData().getUnitType(buildingTypeId); - final String unitModelPath = viewer.getUnitModelPath(unitData.get(buildingTypeId)); - final MdxModel model = (MdxModel) viewer.load(unitModelPath, viewer.mapPathSolver, viewer.solverParams); - MeleeUI.this.cursorModelInstance = (MdxComplexInstance) model.addInstance(); -// MeleeUI.this.cursorModelInstance.setVertexColor(new float[] { 1, 1, 1, 0.5f }); - final int playerColorIndex = viewer.simulation - .getPlayer(MeleeUI.this.activeCommandUnit.getSimulationUnit().getPlayerIndex()).getColor(); - MeleeUI.this.cursorModelInstance.setTeamColor(playerColorIndex); - MeleeUI.this.cursorModelInstance.rotate(RenderUnit.tempQuat.setFromAxis(RenderMathUtils.VEC3_UNIT_Z, - viewer.simulation.getGameplayConstants().getBuildingAngle())); - MeleeUI.this.cursorModelInstance.setAnimationSpeed(0f); - justLoaded = true; - final CUnitType buildingUnitType = MeleeUI.this.cursorBuildingUnitType; - MeleeUI.this.cursorModelPathing = buildingUnitType.getBuildingPathingPixelMap(); - - if (MeleeUI.this.cursorModelPathing != null) { - MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap = new Pixmap( - MeleeUI.this.cursorModelPathing.getWidth(), MeleeUI.this.cursorModelPathing.getHeight(), - Format.RGBA8888); - MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap.setBlending(Blending.None); - MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmapTextureData = new PixmapTextureData( - MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap, Format.RGBA8888, false, false); - MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmapTexture = new Texture( - MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmapTextureData); - final ViewerTextureRenderable greenPixmap = new ViewerTextureRenderable.GdxViewerTextureRenderable( - MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmapTexture); - MeleeUI.this.cursorModelUnderneathPathingRedGreenSplatModel = new SplatModel(Gdx.gl30, greenPixmap, - new ArrayList<>(), viewer.terrain.centerOffset, new ArrayList<>(), true, false, true); - MeleeUI.this.cursorModelUnderneathPathingRedGreenSplatModel.color[3] = 0.20f; - } - } - viewer.getClickLocation(clickLocationTemp, this.baseMouseX, Gdx.graphics.getHeight() - this.baseMouseY); - if (MeleeUI.this.cursorModelPathing != null) { - clickLocationTemp.x = (float) Math.floor(clickLocationTemp.x / 64f) * 64f; - clickLocationTemp.y = (float) Math.floor(clickLocationTemp.y / 64f) * 64f; - if (((MeleeUI.this.cursorModelPathing.getWidth() / 2) % 2) == 1) { - clickLocationTemp.x += 32f; - } - if (((MeleeUI.this.cursorModelPathing.getHeight() / 2) % 2) == 1) { - clickLocationTemp.y += 32f; - } - clickLocationTemp.z = viewer.terrain.getGroundHeight(clickLocationTemp.x, clickLocationTemp.y); - - final int cursorWidthCells = MeleeUI.this.cursorModelPathing.getWidth(); - final int halfCursorWidthCells = cursorWidthCells / 2; - final float halfRenderWidth = cursorWidthCells * 16; - final int cursorHeightCells = MeleeUI.this.cursorModelPathing.getHeight(); - final int halfCursorHeightCells = cursorHeightCells / 2; - final float halfRenderHeight = cursorHeightCells * 16; - final PathingGrid pathingGrid = viewer.simulation.getPathingGrid(); - boolean blockAll = false; - final int cellX = pathingGrid.getCellX(clickLocationTemp.x); - final int cellY = pathingGrid.getCellY(clickLocationTemp.y); - if ((cellX < halfCursorWidthCells) || (cellX > (pathingGrid.getWidth() - halfCursorWidthCells)) - || (cellY < halfCursorHeightCells) - || (cellY > (pathingGrid.getHeight() - halfCursorHeightCells))) { - blockAll = true; - } - if (blockAll) { - for (int i = 0; i < MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap.getWidth(); i++) { - for (int j = 0; j < MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap.getHeight(); j++) { - MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap.drawPixel(i, - MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap.getHeight() - 1 - j, - Color.rgba8888(1, 0, 0, 1.0f)); - } - } - } - else { - for (int i = 0; i < MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap.getWidth(); i++) { - for (int j = 0; j < MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap.getHeight(); j++) { - boolean blocked = false; - final short pathing = pathingGrid.getPathing( - (clickLocationTemp.x + (i * 32)) - halfRenderWidth, - (clickLocationTemp.y + (j * 32)) - halfRenderHeight); - for (final CBuildingPathingType preventedType : MeleeUI.this.cursorBuildingUnitType - .getPreventedPathingTypes()) { - if (PathingFlags.isPathingFlag(pathing, preventedType)) { - blocked = true; - } - } - for (final CBuildingPathingType requiredType : MeleeUI.this.cursorBuildingUnitType - .getRequiredPathingTypes()) { - if (!PathingFlags.isPathingFlag(pathing, requiredType)) { - blocked = true; - } - } - final int color = blocked ? Color.rgba8888(1, 0, 0, 1.0f) : Color.rgba8888(0, 1, 0, 1.0f); - MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap.drawPixel(i, - MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmap.getHeight() - 1 - j, color); - } - } - } - MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmapTexture - .load(MeleeUI.this.cursorModelUnderneathPathingRedGreenPixmapTextureData); - - if (justLoaded) { - viewer.terrain.addSplatBatchModel(BUILDING_PATHING_PREVIEW_KEY, - MeleeUI.this.cursorModelUnderneathPathingRedGreenSplatModel); - MeleeUI.this.placementCursor = MeleeUI.this.cursorModelUnderneathPathingRedGreenSplatModel.add( - clickLocationTemp.x - halfRenderWidth, clickLocationTemp.y - halfRenderHeight, - clickLocationTemp.x + halfRenderWidth, clickLocationTemp.y + halfRenderHeight, 10, - viewer.terrain.centerOffset); - } - MeleeUI.this.placementCursor.setLocation(clickLocationTemp.x, clickLocationTemp.y, - viewer.terrain.centerOffset); - } - MeleeUI.this.cursorModelInstance.setLocation(clickLocationTemp); - SequenceUtils.randomSequence(MeleeUI.this.cursorModelInstance, PrimaryTag.STAND); - MeleeUI.this.cursorFrame.setVisible(false); - if (justLoaded) { - MeleeUI.this.cursorModelInstance.setScene(viewer.worldScene); - } - } - - private void handlePlacementCursor(final CAbility ability, final float radius) { - final War3MapViewer viewer = MeleeUI.this.war3MapViewer; - viewer.getClickLocation(clickLocationTemp, this.baseMouseX, Gdx.graphics.getHeight() - this.baseMouseY); - if (MeleeUI.this.placementCursor == null) { - MeleeUI.this.placementCursor = viewer.terrain.addUberSplat( - MeleeUI.this.rootFrame.getSkinField("PlacementCursor"), clickLocationTemp.x, - clickLocationTemp.y, 10, radius, true, true, true); - } - MeleeUI.this.placementCursor.setLocation(clickLocationTemp.x, clickLocationTemp.y, - viewer.terrain.centerOffset); - MeleeUI.this.cursorFrame.setVisible(false); - } - } - - private final class RallyPositioningVisitor implements AbilityTargetVisitor { - private MdxComplexInstance rallyPointInstance = null; - - public RallyPositioningVisitor reset(final MdxComplexInstance rallyPointInstance) { - this.rallyPointInstance = rallyPointInstance; - return this; - } - - @Override - public Void accept(final AbilityPointTarget target) { - this.rallyPointInstance.setParent(null); - final float rallyPointX = target.getX(); - final float rallyPointY = target.getY(); - this.rallyPointInstance.setLocation(rallyPointX, rallyPointY, - MeleeUI.this.war3MapViewer.terrain.getGroundHeight(rallyPointX, rallyPointY)); - return null; - } - - @Override - public Void accept(final CUnit target) { - final RenderUnit renderUnit = MeleeUI.this.war3MapViewer.getRenderPeer(target); - final MdxModel model = (MdxModel) renderUnit.instance.model; - int index = -1; - for (int i = 0; i < model.attachments.size(); i++) { - final Attachment attachment = model.attachments.get(i); - if (attachment.getName().startsWith("sprite")) { - index = i; - break; - } - } - if (index == -1) { - for (int i = 0; i < model.attachments.size(); i++) { - final Attachment attachment = model.attachments.get(i); - if (attachment.getName().startsWith("overhead ref")) { - index = i; - } - } - } - if (index != -1) { - final MdxNode attachment = renderUnit.instance.getAttachment(index); - this.rallyPointInstance.setParent(attachment); - this.rallyPointInstance.setLocation(0, 0, 0); - } - else { - this.rallyPointInstance.setParent(null); - final float rallyPointX = target.getX(); - final float rallyPointY = target.getY(); - this.rallyPointInstance.setLocation(rallyPointX, rallyPointY, - MeleeUI.this.war3MapViewer.terrain.getGroundHeight(rallyPointX, rallyPointY)); - } - return null; - } - - @Override - public Void accept(final CDestructable target) { - this.rallyPointInstance.setParent(null); - final float rallyPointX = target.getX(); - final float rallyPointY = target.getY(); - this.rallyPointInstance.setLocation(rallyPointX, rallyPointY, - MeleeUI.this.war3MapViewer.terrain.getGroundHeight(rallyPointX, rallyPointY) + 192); - return null; - } - - @Override - public Void accept(final CItem target) { - this.rallyPointInstance.setParent(null); - final float rallyPointX = target.getX(); - final float rallyPointY = target.getY(); - this.rallyPointInstance.setLocation(rallyPointX, rallyPointY, - MeleeUI.this.war3MapViewer.terrain.getGroundHeight(rallyPointX, rallyPointY)); - return null; - } - } - - private final class ActiveCommandUnitTargetFilter implements CWidgetFilterFunction { - @Override - public boolean call(final CWidget unit) { - final BooleanAbilityTargetCheckReceiver targetReceiver = BooleanAbilityTargetCheckReceiver - .getInstance(); - MeleeUI.this.activeCommand.checkCanTarget(MeleeUI.this.war3MapViewer.simulation, - MeleeUI.this.activeCommandUnit.getSimulationUnit(), MeleeUI.this.activeCommandOrderId, unit, - targetReceiver); - return targetReceiver.isTargetable(); - } - } - - private static final class Portrait { - private MdxComplexInstance modelInstance; - private final PortraitCameraManager portraitCameraManager; - private final Scene portraitScene; - private final EnumSet recycleSet = EnumSet - .noneOf(AnimationTokens.SecondaryTag.class); - private RenderUnit unit; - - public Portrait(final War3MapViewer war3MapViewer, final Scene portraitScene) { - this.portraitScene = portraitScene; - this.portraitCameraManager = new PortraitCameraManager(); - this.portraitCameraManager.setupCamera(this.portraitScene); - this.portraitScene.camera.viewport(new Rectangle(100, 0, 6400, 48)); - } - - public void update() { - this.portraitCameraManager.updateCamera(); - if ((this.modelInstance != null) - && (this.modelInstance.sequenceEnded || (this.modelInstance.sequence == -1))) { - this.recycleSet.clear(); - this.recycleSet.addAll(this.unit.getSecondaryAnimationTags()); - SequenceUtils.randomSequence(this.modelInstance, PrimaryTag.PORTRAIT, this.recycleSet, true); - } - } - - public void talk() { - this.recycleSet.clear(); - this.recycleSet.addAll(this.unit.getSecondaryAnimationTags()); - this.recycleSet.add(SecondaryTag.TALK); - SequenceUtils.randomSequence(this.modelInstance, PrimaryTag.PORTRAIT, this.recycleSet, true); - } - - public void setSelectedUnit(final RenderUnit unit) { - if (this.unit != unit) { - this.unit = unit; - if (unit == null) { - if (this.modelInstance != null) { - this.portraitScene.removeInstance(this.modelInstance); - } - this.modelInstance = null; - this.portraitCameraManager.setModelInstance(null, null); - } - else { - final MdxModel portraitModel = unit.portraitModel; - if (portraitModel != null) { - if (this.modelInstance != null) { - this.portraitScene.removeInstance(this.modelInstance); - } - this.modelInstance = (MdxComplexInstance) portraitModel.addInstance(); - this.portraitCameraManager.setModelInstance(this.modelInstance, portraitModel); - this.modelInstance.setBlendTime(portraitModel.blendTime); - this.modelInstance.setSequenceLoopMode(SequenceLoopMode.NEVER_LOOP); - this.modelInstance.setScene(this.portraitScene); - this.modelInstance.setVertexColor(unit.instance.vertexColor); - this.modelInstance.setTeamColor(unit.playerIndex); - } - } - } - } - } - - public void setDraggingItem(final CItem itemInSlot) { - this.draggingItem = itemInSlot; - if (itemInSlot != null) { - final String iconPath = this.war3MapViewer.getAbilityDataUI().getItemUI(itemInSlot.getTypeId()) - .getItemIconPathForDragging(); - this.cursorFrame.setReplaceableId(21, this.war3MapViewer.blp(iconPath)); - - int index = 0; - final CAbilityInventory inventory = this.selectedUnit.getSimulationUnit().getInventoryData(); - for (int i = 0; i < INVENTORY_HEIGHT; i++) { - for (int j = 0; j < INVENTORY_WIDTH; j++) { - final CommandCardIcon inventoryIcon = this.inventoryIcons[i][j]; - final CItem item = inventory.getItemInSlot(index); - if (item == null) { - if (index < inventory.getItemCapacity()) { - inventoryIcon.setCommandButtonData(null, 0, 0, index + 1, true, false, false, null, null, - '\0', 0, 0, 0); - } - } - index++; - } - } - } - else { - if (this.selectedUnit != null) { - final CAbilityInventory inventory = this.selectedUnit.getSimulationUnit().getInventoryData(); - if (inventory != null) { - int index = 0; - for (int i = 0; i < INVENTORY_HEIGHT; i++) { - for (int j = 0; j < INVENTORY_WIDTH; j++) { - final CommandCardIcon inventoryIcon = this.inventoryIcons[i][j]; - final CItem item = inventory.getItemInSlot(index); - if (item == null) { - if (index < inventory.getItemCapacity()) { - inventoryIcon.clear(); - } - } - index++; - } - } - } - } - - } - } - - public void selectUnit(RenderUnit unit) { - this.subMenuOrderIdStack.clear(); - if ((unit != null) && unit.getSimulationUnit().isDead()) { - unit = null; - } - if (this.selectedUnit != null) { - this.selectedUnit.getSimulationUnit().removeStateListener(this); - } - this.portrait.setSelectedUnit(unit); - this.selectedUnit = unit; - setDraggingItem(null); - if (unit == null) { - clearCommandCard(); - this.rootFrame.setText(this.simpleNameValue, ""); - this.rootFrame.setText(this.unitLifeText, ""); - this.rootFrame.setText(this.unitManaText, ""); - this.rootFrame.setText(this.simpleClassValue, ""); - this.rootFrame.setText(this.simpleBuildingActionLabel, ""); - this.attack1Icon.setVisible(false); - this.attack2Icon.setVisible(false); - this.rootFrame.setText(this.attack1InfoPanelIconLevel, ""); - this.rootFrame.setText(this.attack2InfoPanelIconLevel, ""); - this.rootFrame.setText(this.simpleBuildingBuildingActionLabel, ""); - this.rootFrame.setText(this.simpleBuildingNameValue, ""); - this.armorIcon.setVisible(false); - this.rootFrame.setText(this.armorInfoPanelIconLevel, ""); - this.simpleBuildTimeIndicator.setVisible(false); - this.simpleHeroLevelBar.setVisible(false); - this.simpleBuildingBuildTimeIndicator.setVisible(false); - this.simpleInfoPanelBuildingDetail.setVisible(false); - this.simpleInfoPanelUnitDetail.setVisible(false); - for (final QueueIcon queueIconFrame : this.queueIconFrames) { - queueIconFrame.setVisible(false); - } - this.selectWorkerInsideFrame.setVisible(false); - this.heroInfoPanel.setVisible(false); - this.rallyPointInstance.hide(); - this.rallyPointInstance.detach(); - this.inventoryCover.setVisible(true); - this.inventoryBarFrame.setVisible(false); - for (final QueueIcon iconFrame : this.selectedUnitFrames) { - iconFrame.setVisible(false); - } - repositionWaypointFlags(null); - } - else { - unit.getSimulationUnit().addStateListener(this); - reloadSelectedUnitUI(unit); - } - } - - @Override - public void rallyPointChanged() { - if (this.selectedUnit != null) { - final CUnit simulationUnit = this.selectedUnit.getSimulationUnit(); - repositionRallyPoint(simulationUnit); - } - } - - private void repositionRallyPoint(final CUnit simulationUnit) { - final AbilityTarget rallyPoint = simulationUnit.getRallyPoint(); - if (rallyPoint != null) { - this.rallyPointInstance - .setTeamColor(this.war3MapViewer.simulation.getPlayer(simulationUnit.getPlayerIndex()).getColor()); - this.rallyPointInstance.show(); - this.rallyPointInstance.detach(); - rallyPoint.visit(this.rallyPositioningVisitor.reset(this.rallyPointInstance)); - this.rallyPointInstance.setScene(this.war3MapViewer.worldScene); - } - else { - this.rallyPointInstance.hide(); - this.rallyPointInstance.detach(); - } - } - - @Override - public void waypointsChanged() { - if (this.selectedUnit != null) { - final CUnit simulationUnit = this.selectedUnit.getSimulationUnit(); - repositionWaypointFlags(simulationUnit); - } - else { - repositionWaypointFlags(null); - } - } - - private void repositionWaypointFlags(final CUnit simulationUnit) { - final Iterator iterator; - int orderIndex = 0; - if (simulationUnit != null) { - final Queue orderQueue = simulationUnit.getOrderQueue(); - iterator = orderQueue.iterator(); - final COrder order = simulationUnit.getCurrentOrder(); - if ((order != null) && order.isQueued()) { - final MdxComplexInstance waypointModelInstance = getOrCreateWaypointIndicator(orderIndex); - final AbilityTarget target = order.getTarget(this.war3MapViewer.simulation); - if (target != null) { - waypointModelInstance.show(); - waypointModelInstance.detach(); - target.visit(this.rallyPositioningVisitor.reset(waypointModelInstance)); - waypointModelInstance.setScene(this.war3MapViewer.worldScene); - } - else { - waypointModelInstance.hide(); - waypointModelInstance.detach(); - } - orderIndex++; - } - } - else { - iterator = Collections.emptyIterator(); - } - for (; (orderIndex < this.waypointModelInstances.size()) || (iterator.hasNext()); orderIndex++) { - final MdxComplexInstance waypointModelInstance = getOrCreateWaypointIndicator(orderIndex); - if (iterator.hasNext()) { - final COrder order = iterator.next(); - final AbilityTarget target = order.getTarget(this.war3MapViewer.simulation); - if (target != null) { - waypointModelInstance.show(); - waypointModelInstance.detach(); - target.visit(this.rallyPositioningVisitor.reset(waypointModelInstance)); - waypointModelInstance.setScene(this.war3MapViewer.worldScene); - } - else { - waypointModelInstance.hide(); - waypointModelInstance.detach(); - } - } - else { - waypointModelInstance.hide(); - waypointModelInstance.detach(); - } - } - } - - private MdxComplexInstance getOrCreateWaypointIndicator(final int index) { - while (index >= this.waypointModelInstances.size()) { - final MdxComplexInstance waypointModelInstance = (MdxComplexInstance) this.waypointModel.addInstance(); - waypointModelInstance.rotate(RenderUnit.tempQuat.setFromAxis(RenderMathUtils.VEC3_UNIT_Z, - this.war3MapViewer.simulation.getGameplayConstants().getBuildingAngle())); - waypointModelInstance.setSequenceLoopMode(SequenceLoopMode.ALWAYS_LOOP); - SequenceUtils.randomStandSequence(waypointModelInstance); - waypointModelInstance.hide(); - this.waypointModelInstances.add(waypointModelInstance); - } - return this.waypointModelInstances.get(index); - } - - private void reloadSelectedUnitUI(final RenderUnit unit) { - if (unit == null) { - return; - } - final CUnit simulationUnit = unit.getSimulationUnit(); - final float lifeRatioRemaining = simulationUnit.getLife() / simulationUnit.getMaxLife(); - this.rootFrame.setText(this.unitLifeText, FastNumberFormat.formatWholeNumber(simulationUnit.getLife()) + " / " - + FastNumberFormat.formatWholeNumber(simulationUnit.getMaxLife())); - this.unitLifeText.setColor(new Color(Math.min(1.0f, 2.0f - (lifeRatioRemaining * 2)), - Math.min(1.0f, lifeRatioRemaining * 2), 0, 1.0f)); - final int maximumMana = simulationUnit.getMaximumMana(); - if (maximumMana > 0) { - this.rootFrame.setText(this.unitManaText, - FastNumberFormat.formatWholeNumber(simulationUnit.getMana()) + " / " + maximumMana); - } - else { - this.rootFrame.setText(this.unitManaText, ""); - } - final boolean multiSelect = this.selectedUnits.size() > 1; - repositionRallyPoint(simulationUnit); - repositionWaypointFlags(simulationUnit); - if (!multiSelect) { - for (int i = 0; i < this.selectedUnitFrames.length; i++) { - this.selectedUnitFrames[i].setVisible(false); - } - } - if ((simulationUnit.getBuildQueue()[0] != null) - && (simulationUnit.getPlayerIndex() == this.war3MapViewer.getLocalPlayerIndex())) { - for (int i = 0; i < this.queueIconFrames.length; i++) { - final QueueItemType queueItemType = simulationUnit.getBuildQueueTypes()[i]; - if (queueItemType == null) { - this.queueIconFrames[i].setVisible(false); - } - else { - this.queueIconFrames[i].setVisible(true); - switch (queueItemType) { - case RESEARCH: - final IconUI upgradeUI = this.war3MapViewer.getAbilityDataUI() - .getUpgradeUI(simulationUnit.getBuildQueue()[i], 0); - this.queueIconFrames[i].setTexture(upgradeUI.getIcon()); - this.queueIconFrames[i].setToolTip(upgradeUI.getToolTip()); - this.queueIconFrames[i].setUberTip(upgradeUI.getUberTip()); - break; - case HERO_REVIVE: { - final War3ID handleIdEncoded = simulationUnit.getBuildQueue()[i]; - final CUnit hero = this.war3MapViewer.simulation.getUnit(handleIdEncoded.getValue()); - final UnitIconUI unitUI = this.war3MapViewer.getAbilityDataUI().getUnitUI(hero.getTypeId()); - this.queueIconFrames[i].setTexture(unitUI.getIcon()); - this.queueIconFrames[i] - .setToolTip(unitUI.getReviveTip() + " - " + hero.getHeroData().getProperName()); - this.queueIconFrames[i].setUberTip(unitUI.getUberTip()); - break; - } - case UNIT: - default: { - final IconUI unitUI = this.war3MapViewer.getAbilityDataUI() - .getUnitUI(simulationUnit.getBuildQueue()[i]); - this.queueIconFrames[i].setTexture(unitUI.getIcon()); - this.queueIconFrames[i].setToolTip(unitUI.getToolTip()); - this.queueIconFrames[i].setUberTip(unitUI.getUberTip()); - break; - } - } - } - } - this.simpleInfoPanelBuildingDetail.setVisible(!multiSelect); - this.simpleInfoPanelUnitDetail.setVisible(false); - this.rootFrame.setText(this.simpleBuildingNameValue, simulationUnit.getUnitType().getName()); - this.rootFrame.setText(this.simpleBuildingDescriptionValue, ""); - - this.simpleBuildingBuildTimeIndicator.setVisible(true); - this.simpleBuildTimeIndicator.setVisible(false); - this.simpleHeroLevelBar.setVisible(false); - if (simulationUnit.getBuildQueueTypes()[0] == QueueItemType.UNIT) { - this.rootFrame.setText(this.simpleBuildingBuildingActionLabel, - this.rootFrame.getTemplates().getDecoratedString("TRAINING")); - } - else if (simulationUnit.getBuildQueueTypes()[0] == QueueItemType.HERO_REVIVE) { - this.rootFrame.setText(this.simpleBuildingBuildingActionLabel, - this.rootFrame.getTemplates().getDecoratedString("REVIVING")); - } - else { - this.rootFrame.setText(this.simpleBuildingBuildingActionLabel, - this.rootFrame.getTemplates().getDecoratedString("RESEARCHING")); - } - this.attack1Icon.setVisible(false); - this.attack2Icon.setVisible(false); - this.armorIcon.setVisible(false); - this.heroInfoPanel.setVisible(false); - this.selectWorkerInsideFrame.setVisible(false); - } - else if (multiSelect) { - for (int i = 0; i < this.queueIconFrames.length; i++) { - this.queueIconFrames[i].setVisible(false); - } - for (int i = 0; i < this.selectedUnitFrames.length; i++) { - final boolean useIcon = i < this.selectedUnits.size(); - this.selectedUnitFrames[i].setVisible(useIcon); - if (useIcon) { - final CUnitType unitType = this.selectedUnits.get(i).getSimulationUnit().getUnitType(); - final IconUI unitUI = this.war3MapViewer.getAbilityDataUI().getUnitUI(unitType.getTypeId()); - this.selectedUnitFrames[i].setTexture(unitUI.getIcon()); - this.selectedUnitFrames[i].setToolTip(unitUI.getToolTip()); - this.selectedUnitFrames[i].setUberTip(unitUI.getUberTip()); - } - } - this.simpleInfoPanelBuildingDetail.setVisible(false); - this.simpleInfoPanelUnitDetail.setVisible(false); - this.simpleBuildingBuildTimeIndicator.setVisible(false); - this.simpleBuildTimeIndicator.setVisible(false); - this.simpleHeroLevelBar.setVisible(false); - this.attack1Icon.setVisible(false); - this.attack2Icon.setVisible(false); - this.armorIcon.setVisible(false); - this.heroInfoPanel.setVisible(false); - this.selectWorkerInsideFrame.setVisible(false); - } - else { - for (final QueueIcon queueIconFrame : this.queueIconFrames) { - queueIconFrame.setVisible(false); - } - this.simpleInfoPanelBuildingDetail.setVisible(false); - this.simpleInfoPanelUnitDetail.setVisible(!multiSelect); - final String unitTypeName = simulationUnit.getUnitType().getName(); - - final boolean anyAttacks = simulationUnit.getAttacks().size() > 0; - final boolean constructing = simulationUnit.isConstructing(); - final UIFrame localArmorIcon = this.armorIcon; - final TextureFrame localArmorIconBackdrop = this.armorIconBackdrop; - final StringFrame localArmorInfoPanelIconValue = this.armorInfoPanelIconValue; - if (anyAttacks && !constructing) { - final CUnitAttack attackOne = simulationUnit.getAttacks().get(0); - this.attack1Icon.setVisible(attackOne.isShowUI()); - this.attack1IconBackdrop.setTexture(this.damageBackdrops.getTexture(attackOne.getAttackType())); - String attackOneDmgText = attackOne.getMinDamageDisplay() + " - " + attackOne.getMaxDamageDisplay(); - final int attackOneTemporaryDamageBonus = attackOne.getTemporaryDamageBonus(); - if (attackOneTemporaryDamageBonus != 0) { - attackOneDmgText += (attackOneTemporaryDamageBonus > 0 ? "|cFF00FF00 (+" : "|cFFFF0000 (+") - + attackOneTemporaryDamageBonus + ")"; - } - this.rootFrame.setText(this.attack1InfoPanelIconValue, attackOneDmgText); - if (simulationUnit.getAttacks().size() > 1) { - final CUnitAttack attackTwo = simulationUnit.getAttacks().get(1); - this.attack2Icon.setVisible(attackTwo.isShowUI()); - this.attack2IconBackdrop.setTexture(this.damageBackdrops.getTexture(attackTwo.getAttackType())); - String attackTwoDmgText = attackTwo.getMinDamage() + " - " + attackTwo.getMaxDamage(); - final int attackTwoTemporaryDamageBonus = attackTwo.getTemporaryDamageBonus(); - if (attackTwoTemporaryDamageBonus != 0) { - attackTwoDmgText += (attackTwoTemporaryDamageBonus > 0 ? "|cFF00FF00 (+" : "|cFFFF0000 (+") - + attackTwoTemporaryDamageBonus + ")"; - } - this.rootFrame.setText(this.attack2InfoPanelIconValue, attackTwoDmgText); - } - else { - this.attack2Icon.setVisible(false); - } - - this.smashArmorIconWrapper.addSetPoint( - new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, FramePoint.TOPLEFT, - GameUI.convertX(this.uiViewport, 0f), GameUI.convertY(this.uiViewport, -0.0625f))); - this.smashArmorIconWrapper.positionBounds(this.rootFrame, this.uiViewport); - this.armorIcon.positionBounds(this.rootFrame, this.uiViewport); - } - else { - this.attack1Icon.setVisible(false); - this.attack2Icon.setVisible(false); - - this.smashArmorIconWrapper.addSetPoint( - new SetPoint(FramePoint.TOPLEFT, this.simpleInfoPanelUnitDetail, FramePoint.TOPLEFT, - GameUI.convertX(this.uiViewport, 0f), GameUI.convertY(this.uiViewport, -0.032f))); - this.smashArmorIconWrapper.positionBounds(this.rootFrame, this.uiViewport); - this.armorIcon.positionBounds(this.rootFrame, this.uiViewport); - } - - final CAbilityHero heroData = simulationUnit.getHeroData(); - final boolean hero = heroData != null; - this.heroInfoPanel.setVisible(hero); - if (hero) { - final CPrimaryAttribute primaryAttribute = simulationUnit.getUnitType().getPrimaryAttribute(); - String iconKey; - switch (primaryAttribute) { - case AGILITY: - iconKey = "InfoPanelIconHeroIconAGI"; - break; - case INTELLIGENCE: - iconKey = "InfoPanelIconHeroIconINT"; - break; - default: - case STRENGTH: - iconKey = "InfoPanelIconHeroIconSTR"; - break; - } - this.primaryAttributeIcon.setTexture(iconKey, this.rootFrame); - - this.rootFrame.setText(this.strengthValue, heroData.getStrength().getDisplayText()); - this.rootFrame.setText(this.agilityValue, heroData.getAgility().getDisplayText()); - this.rootFrame.setText(this.intelligenceValue, heroData.getIntelligence().getDisplayText()); - final String infopanelLevelClass = this.rootFrame.getTemplates() - .getDecoratedString("INFOPANEL_LEVEL_CLASS").replace("%u", "%d"); // :( - final int heroLevel = heroData.getHeroLevel(); - this.simpleClassValue.setVisible(true); - this.rootFrame.setText(this.simpleClassValue, - String.format(infopanelLevelClass, heroLevel, unitTypeName)); - this.rootFrame.setText(this.simpleNameValue, heroData.getProperName()); - this.simpleHeroLevelBar.setVisible(true); - final CGameplayConstants gameplayConstants = this.war3MapViewer.simulation.getGameplayConstants(); - this.simpleHeroLevelBar.setValue((heroData.getXp() - gameplayConstants.getNeedHeroXPSum(heroLevel - 1)) - / (float) gameplayConstants.getNeedHeroXP(heroLevel)); - } - else { - this.simpleClassValue.setVisible(!simulationUnit.isBuilding()); - this.rootFrame.setText(this.simpleNameValue, unitTypeName); - String classText = null; - for (final CUnitClassification classification : simulationUnit.getClassifications()) { - if (classification.getDisplayName() != null) { - classText = classification.getDisplayName(); - } - } - if (classText != null) { - this.rootFrame.setText(this.simpleClassValue, classText); - } - else { - this.rootFrame.setText(this.simpleClassValue, ""); - } - this.simpleHeroLevelBar.setVisible(false); - } - - localArmorIcon.setVisible(!constructing); - this.simpleBuildTimeIndicator.setVisible(constructing); - this.simpleBuildingBuildTimeIndicator.setVisible(false); - if (constructing) { - this.rootFrame.setText(this.simpleBuildingActionLabel, - this.rootFrame.getTemplates().getDecoratedString("CONSTRUCTING")); - this.queueIconFrames[0].setVisible(true); - this.queueIconFrames[0].setTexture( - this.war3MapViewer.getAbilityDataUI().getUnitUI(simulationUnit.getTypeId()).getIcon()); - - if (simulationUnit.getWorkerInside() != null) { - this.selectWorkerInsideFrame.setVisible(true); - this.selectWorkerInsideFrame.setTexture(this.war3MapViewer.getAbilityDataUI() - .getUnitUI(simulationUnit.getWorkerInside().getTypeId()).getIcon()); - } - else { - this.selectWorkerInsideFrame.setVisible(false); - } - } - else { - this.rootFrame.setText(this.simpleBuildingActionLabel, ""); - this.selectWorkerInsideFrame.setVisible(false); - } - final Texture defenseTexture = this.defenseBackdrops - .getTexture(simulationUnit.getUnitType().getDefenseType()); - if (defenseTexture == null) { - throw new RuntimeException(simulationUnit.getUnitType().getDefenseType() + " can't find texture!"); - } - localArmorIconBackdrop.setTexture(defenseTexture); - - String defenseDisplayString; - if (simulationUnit.isInvulnerable()) { - defenseDisplayString = this.rootFrame.getTemplates().getDecoratedString("INVULNERABLE"); - } - else { - defenseDisplayString = Integer.toString(simulationUnit.getCurrentDefenseDisplay()); - final int temporaryDefenseBonus = simulationUnit.getTemporaryDefenseBonus(); - if (temporaryDefenseBonus != 0) { - if (temporaryDefenseBonus > 0) { - defenseDisplayString += "|cFF00FF00 (+" + temporaryDefenseBonus + ")"; - } - else { - defenseDisplayString += "|cFFFF0000 (+" + temporaryDefenseBonus + ")"; - } - } - } - this.rootFrame.setText(localArmorInfoPanelIconValue, defenseDisplayString); - } - final CAbilityInventory inventory = simulationUnit.getInventoryData(); - this.inventoryCover.setVisible(inventory == null); - if (inventory != null) { - this.inventoryBarFrame.setVisible(true); - int index = 0; - for (int i = 0; i < INVENTORY_HEIGHT; i++) { - for (int j = 0; j < INVENTORY_WIDTH; j++) { - final CommandCardIcon inventoryIcon = this.inventoryIcons[i][j]; - final CItem item = inventory.getItemInSlot(index); - if (item != null) { - final ItemUI itemUI = this.war3MapViewer.getAbilityDataUI().getItemUI(item.getTypeId()); - final IconUI iconUI = itemUI.getIconUI(); - final CItemType itemType = item.getItemType(); - // TODO: below we set menu=false, this is bad, item should be based on item abil - final boolean activelyUsed = itemType.isActivelyUsed(); - final boolean pawnable = itemType.isPawnable(); - final String uberTip = iconUI.getUberTip(); - this.recycleStringBuilder.setLength(0); - if (pawnable) { - this.recycleStringBuilder - .append(this.rootFrame.getTemplates().getDecoratedString("ITEM_PAWN_TOOLTIP")); - this.recycleStringBuilder.append("|n"); - } - if (activelyUsed) { - this.recycleStringBuilder - .append(this.rootFrame.getTemplates().getDecoratedString("ITEM_USE_TOOLTIP")); - this.recycleStringBuilder.append("|n"); - } - this.recycleStringBuilder.append(uberTip); - inventoryIcon.setCommandButtonData(iconUI.getIcon(), 0, - activelyUsed ? (OrderIds.itemuse00 + index) : 0, index + 1, activelyUsed, false, false, - itemUI.getName(), this.recycleStringBuilder.toString(), '\0', itemType.getGoldCost(), - itemType.getLumberCost(), 0); - } - else { - if (index >= inventory.getItemCapacity()) { - inventoryIcon.setCommandButtonData(this.consoleInventoryNoCapacityTexture, 0, 0, 0, false, - false, false, null, null, '\0', 0, 0, 0); - } - else { - if (this.draggingItem != null) { - inventoryIcon.setCommandButtonData(null, 0, 0, index + 1, true, false, false, null, - null, '\0', 0, 0, 0); - } - else { - inventoryIcon.clear(); - } - } - } - index++; - } - } - } - clearAndRepopulateCommandCard(); - } - - private void clearCommandCard() { - for (int j = 0; j < COMMAND_CARD_HEIGHT; j++) { - for (int i = 0; i < COMMAND_CARD_WIDTH; i++) { - this.commandCard[j][i].clear(); - } - } - } - - @Override - public void commandButton(final int buttonPositionX, final int buttonPositionY, final Texture icon, - final int abilityHandleId, final int orderId, final int autoCastId, final boolean active, - final boolean autoCastActive, final boolean menuButton, final String tip, final String uberTip, - final char hotkey, final int goldCost, final int lumberCost, final int foodCost) { - int x = Math.max(0, Math.min(COMMAND_CARD_WIDTH - 1, buttonPositionX)); - int y = Math.max(0, Math.min(COMMAND_CARD_HEIGHT - 1, buttonPositionY)); - while ((x < COMMAND_CARD_WIDTH) && (y < COMMAND_CARD_HEIGHT) && this.commandCard[y][x].isVisible()) { - x++; - if (x >= COMMAND_CARD_WIDTH) { - x = 0; - y++; - } - } - if ((x < COMMAND_CARD_WIDTH) && (y < COMMAND_CARD_HEIGHT)) { - this.commandCard[y][x].setCommandButtonData(icon, abilityHandleId, orderId, autoCastId, active, - autoCastActive, menuButton, tip, uberTip, hotkey, goldCost, lumberCost, foodCost); - } - } - - public void resize(final Rectangle viewport) { - this.cameraManager.resize(viewport); - positionPortrait(); - } - - public void positionPortrait() { - this.projectionTemp1.x = 422 * this.widthRatioCorrection; - this.projectionTemp1.y = 57 * this.heightRatioCorrection; - this.projectionTemp2.x = (422 + 167) * this.widthRatioCorrection; - this.projectionTemp2.y = (57 + 170) * this.heightRatioCorrection; - this.uiViewport.project(this.projectionTemp1); - this.uiViewport.project(this.projectionTemp2); - - this.tempRect.x = this.projectionTemp1.x + this.uiViewport.getScreenX(); - this.tempRect.y = this.projectionTemp1.y + this.uiViewport.getScreenY(); - this.tempRect.width = this.projectionTemp2.x - this.projectionTemp1.x; - this.tempRect.height = this.projectionTemp2.y - this.projectionTemp1.y; - this.portrait.portraitScene.camera.viewport(this.tempRect); - } - - private static final class InfoPanelIconBackdrops { - private final Texture[] damageBackdropTextures; - - public InfoPanelIconBackdrops(final CodeKeyType[] attackTypes, final GameUI gameUI, final String prefix, - final String suffix) { - this.damageBackdropTextures = new Texture[attackTypes.length]; - for (int index = 0; index < attackTypes.length; index++) { - final CodeKeyType attackType = attackTypes[index]; - String skinLookupKey = "InfoPanelIcon" + prefix + attackType.getCodeKey() + suffix; - final Texture suffixTexture = gameUI.loadTexture(gameUI.getSkinField(skinLookupKey)); - if (suffixTexture != null) { - this.damageBackdropTextures[index] = suffixTexture; - } - else { - skinLookupKey = "InfoPanelIcon" + prefix + attackType.getCodeKey(); - this.damageBackdropTextures[index] = gameUI.loadTexture(gameUI.getSkinField(skinLookupKey)); - } - } - } - - public Texture getTexture(final CodeKeyType attackType) { - if (attackType != null) { - final int ordinal = attackType.ordinal(); - if ((ordinal >= 0) && (ordinal < this.damageBackdropTextures.length)) { - return this.damageBackdropTextures[ordinal]; - } - } - return this.damageBackdropTextures[0]; - } - - private static String getSuffix(final CAttackType attackType) { - switch (attackType) { - case CHAOS: - return "Chaos"; - case HERO: - return "Hero"; - case MAGIC: - return "Magic"; - case NORMAL: - return "Normal"; - case PIERCE: - return "Pierce"; - case SIEGE: - return "Siege"; - case SPELLS: - return "Magic"; - case UNKNOWN: - return "Unknown"; - default: - throw new IllegalArgumentException("Unknown attack type: " + attackType); - } - - } - } - - @Override - public void lifeChanged() { - if (this.selectedUnit == null) { - return; - } - if (this.selectedUnit.getSimulationUnit().isDead()) { - final RenderUnit preferredSelectionReplacement = this.selectedUnit.getPreferredSelectionReplacement(); - final List newSelection; - newSelection = new ArrayList<>(this.selectedUnits); - newSelection.remove(this.selectedUnit); - if (preferredSelectionReplacement != null) { - newSelection.add(preferredSelectionReplacement); - } - selectWidgets(newSelection); - this.war3MapViewer.doSelectUnit(newSelection); - } - else { - final float lifeRatioRemaining = this.selectedUnit.getSimulationUnit().getLife() - / this.selectedUnit.getSimulationUnit().getMaxLife(); - this.rootFrame.setText(this.unitLifeText, - FastNumberFormat.formatWholeNumber(this.selectedUnit.getSimulationUnit().getLife()) + " / " - + FastNumberFormat.formatWholeNumber(this.selectedUnit.getSimulationUnit().getMaxLife())); - this.unitLifeText.setColor(new Color(Math.min(1.0f, 2.0f - (lifeRatioRemaining * 2)), - Math.min(1.0f, lifeRatioRemaining * 2), 0, 1.0f)); - } - } - - @Override - public void goldChanged() { - this.rootFrame.setText(this.resourceBarGoldText, Integer.toString(this.localPlayer.getGold())); - } - - @Override - public void lumberChanged() { - this.rootFrame.setText(this.resourceBarLumberText, Integer.toString(this.localPlayer.getLumber())); - } - - @Override - public void foodChanged() { - final int foodCap = this.localPlayer.getFoodCap(); - if (foodCap == 0) { - this.rootFrame.setText(this.resourceBarSupplyText, Integer.toString(this.localPlayer.getFoodUsed())); - this.resourceBarSupplyText.setColor(Color.WHITE); - } - else { - this.rootFrame.setText(this.resourceBarSupplyText, this.localPlayer.getFoodUsed() + "/" + foodCap); - this.resourceBarSupplyText.setColor(this.localPlayer.getFoodUsed() > foodCap ? Color.RED : Color.WHITE); - } - } - - @Override - public void upkeepChanged() { - this.rootFrame.setText(this.resourceBarUpkeepText, "Upkeep NYI"); - this.resourceBarUpkeepText.setColor(Color.CYAN); - } - - @Override - public void heroDeath() { - if (this.selectedUnit != null) { - if (this.selectedUnit.getSimulationUnit().getUnitType().isRevivesHeroes()) { - reloadSelectedUnitUI(this.selectedUnit); - } - } - } - - @Override - public void ordersChanged() { - reloadSelectedUnitUI(this.selectedUnit); - if (this.mouseOverUIFrame instanceof ClickableActionFrame) { - loadTooltip((ClickableActionFrame) this.mouseOverUIFrame); - } - } - - @Override - public void heroStatsChanged() { - reloadSelectedUnitUI(this.selectedUnit); - } - - @Override - public void inventoryChanged() { - reloadSelectedUnitUI(this.selectedUnit); - } - - @Override - public void queueChanged() { - reloadSelectedUnitUI(this.selectedUnit); - } - - private void clearAndRepopulateCommandCard() { - clearCommandCard(); - if (this.selectedUnit.getSimulationUnit().getPlayerIndex() == this.war3MapViewer.getLocalPlayerIndex()) { - final AbilityDataUI abilityDataUI = this.war3MapViewer.getAbilityDataUI(); - final int menuOrderId = getSubMenuOrderId(); - if ((this.activeCommand != null) && (this.draggingItem == null)) { - final IconUI cancelUI = abilityDataUI.getCancelUI(); - this.commandButton(cancelUI.getButtonPositionX(), cancelUI.getButtonPositionY(), cancelUI.getIcon(), 0, - menuOrderId, 0, false, false, true, cancelUI.getToolTip(), cancelUI.getUberTip(), - cancelUI.getHotkey(), 0, 0, 0); - } - else { - if (menuOrderId != 0) { - final int exitOrderId = this.subMenuOrderIdStack.size() > 1 - ? this.subMenuOrderIdStack.get(this.subMenuOrderIdStack.size() - 2) - : 0; - final IconUI cancelUI = abilityDataUI.getCancelUI(); - this.commandButton(cancelUI.getButtonPositionX(), cancelUI.getButtonPositionY(), cancelUI.getIcon(), - 0, exitOrderId, 0, false, false, true, cancelUI.getToolTip(), cancelUI.getUberTip(), - cancelUI.getHotkey(), 0, 0, 0); - } - this.selectedUnit.populateCommandCard(this.war3MapViewer.simulation, this.rootFrame, this, - abilityDataUI, menuOrderId, this.selectedUnits.size() > 1); - } - } - } - - private int getSubMenuOrderId() { - return this.subMenuOrderIdStack.isEmpty() ? 0 - : this.subMenuOrderIdStack.get(this.subMenuOrderIdStack.size() - 1); - } - - public RenderUnit getSelectedUnit() { - return this.selectedUnit; - } - - public boolean keyDown(final int keycode) { - if (WarsmashConstants.ENABLE_DEBUG) { - if (keycode == Input.Keys.Z) { - War3MapViewer.DEBUG_DEPTH++; - } - if (keycode == Input.Keys.X) { - War3MapViewer.DEBUG_DEPTH = 0; - } - } - final String keyString = Input.Keys.toString(keycode); - final char c = keyString.length() == 1 ? keyString.charAt(0) : ' '; - for (int j = 0; j < COMMAND_CARD_HEIGHT; j++) { - for (int i = 0; i < COMMAND_CARD_WIDTH; i++) { - if (this.commandCard[j][i].checkHotkey(c, keycode)) { - this.war3MapViewer.getUiSounds().getSound("InterfaceClick").play(this.uiScene.audioContext, 0, 0, - 0); - } - } - } - return this.cameraManager.keyDown(keycode); - } - - public boolean keyUp(final int keycode) { - return this.cameraManager.keyUp(keycode); - } - - public void scrolled(final int amount) { - this.cameraManager.scrolled(amount); - } - - public boolean touchDown(final int screenX, final int screenY, final float worldScreenY, final int button) { - this.allowDrag = false; - screenCoordsVector.set(screenX, screenY); - this.uiViewport.unproject(screenCoordsVector); - if (this.meleeUIMinimap.containsMouse(screenCoordsVector.x, screenCoordsVector.y)) { - final Vector2 worldPoint = this.meleeUIMinimap.getWorldPointFromScreen(screenCoordsVector.x, - screenCoordsVector.y); - this.cameraManager.target.x = worldPoint.x; - this.cameraManager.target.y = worldPoint.y; - return true; - } - final UIFrame clickedUIFrame = this.rootFrame.touchDown(screenCoordsVector.x, screenCoordsVector.y, button); - if (clickedUIFrame == null) { - // try to interact with world - if (this.activeCommand != null) { - if (button == Input.Buttons.RIGHT) { - this.activeCommandUnit = null; - this.activeCommand = null; - this.activeCommandOrderId = -1; - if (this.draggingItem != null) { - setDraggingItem(null); - } - clearAndRepopulateCommandCard(); - } - else { - final boolean shiftDown = isShiftDown(); - final RenderWidget rayPickUnit = this.war3MapViewer.rayPickUnit(screenX, worldScreenY, - this.activeCommandUnitTargetFilter); - if (rayPickUnit != null) { - this.unitOrderListener.issueTargetOrder( - this.activeCommandUnit.getSimulationUnit().getHandleId(), - this.activeCommand.getHandleId(), this.activeCommandOrderId, - rayPickUnit.getSimulationWidget().getHandleId(), shiftDown); - if (this.selectedUnits.size() > 1) { - for (final RenderUnit otherSelectedUnit : this.selectedUnits) { - if (otherSelectedUnit != this.activeCommandUnit) { - CAbility abilityToUse = null; - CWidget targetToUse = null; - for (final CAbility ability : otherSelectedUnit.getSimulationUnit() - .getAbilities()) { - final CWidgetAbilityTargetCheckReceiver receiver = CWidgetAbilityTargetCheckReceiver.INSTANCE - .reset(); - ability.checkCanTarget(this.war3MapViewer.simulation, - otherSelectedUnit.getSimulationUnit(), this.activeCommandOrderId, - rayPickUnit.getSimulationWidget(), receiver); - if (receiver.getTarget() != null) { - abilityToUse = ability; - targetToUse = receiver.getTarget(); - } - } - if (abilityToUse != null) { - this.unitOrderListener.issueTargetOrder( - otherSelectedUnit.getSimulationUnit().getHandleId(), - abilityToUse.getHandleId(), this.activeCommandOrderId, - targetToUse.getHandleId(), shiftDown); - } - } - } - } - final UnitSound yesSound = (this.activeCommand instanceof CAbilityAttack) - ? getSelectedUnit().soundset.yesAttack - : getSelectedUnit().soundset.yes; - if (yesSound.playUnitResponse(this.war3MapViewer.worldScene.audioContext, getSelectedUnit())) { - portraitTalk(); - } - this.selectedSoundCount = 0; - if (this.activeCommand instanceof CAbilityRally) { - this.war3MapViewer.getUiSounds().getSound("RallyPointPlace").play(this.uiScene.audioContext, - 0, 0, 0); - } - if (!shiftDown) { - this.subMenuOrderIdStack.clear(); - this.activeCommandUnit = null; - this.activeCommand = null; - this.activeCommandOrderId = -1; - clearAndRepopulateCommandCard(); - } - } - else { - this.war3MapViewer.getClickLocation(clickLocationTemp, screenX, (int) worldScreenY); - clickLocationTemp2.set(clickLocationTemp.x, clickLocationTemp.y); - - if (this.draggingItem != null) { - this.war3MapViewer.showConfirmation(clickLocationTemp, 0, 1, 0); - - this.unitOrderListener.issueDropItemAtPointOrder( - this.activeCommandUnit.getSimulationUnit().getHandleId(), - this.activeCommand.getHandleId(), this.activeCommandOrderId, - this.draggingItem.getHandleId(), clickLocationTemp2.x, clickLocationTemp2.y, - shiftDown); - if (getSelectedUnit().soundset.yes - .playUnitResponse(this.war3MapViewer.worldScene.audioContext, getSelectedUnit())) { - portraitTalk(); - } - this.activeCommandUnit = null; - this.activeCommand = null; - this.activeCommandOrderId = -1; - setDraggingItem(null); - clearAndRepopulateCommandCard(); - } - else { - this.activeCommand.checkCanTarget(this.war3MapViewer.simulation, - this.activeCommandUnit.getSimulationUnit(), this.activeCommandOrderId, - clickLocationTemp2, PointAbilityTargetCheckReceiver.INSTANCE); - final Vector2 target = PointAbilityTargetCheckReceiver.INSTANCE.getTarget(); - if (target != null) { - if ((this.activeCommand instanceof CAbilityAttack) - && (this.activeCommandOrderId == OrderIds.attack)) { - this.war3MapViewer.showConfirmation(clickLocationTemp, 1, 0, 0); - } - else { - this.war3MapViewer.showConfirmation(clickLocationTemp, 0, 1, 0); - } - this.unitOrderListener.issuePointOrder( - this.activeCommandUnit.getSimulationUnit().getHandleId(), - this.activeCommand.getHandleId(), this.activeCommandOrderId, - clickLocationTemp2.x, clickLocationTemp2.y, shiftDown); - if (this.selectedUnits.size() > 1) { - for (final RenderUnit otherSelectedUnit : this.selectedUnits) { - if (otherSelectedUnit != this.activeCommandUnit) { - CAbility abilityToUse = null; - AbilityPointTarget targetToUse = null; - for (final CAbility ability : otherSelectedUnit.getSimulationUnit() - .getAbilities()) { - final PointAbilityTargetCheckReceiver receiver = PointAbilityTargetCheckReceiver.INSTANCE - .reset(); - ability.checkCanTarget(this.war3MapViewer.simulation, - otherSelectedUnit.getSimulationUnit(), - this.activeCommandOrderId, clickLocationTemp2, receiver); - if (receiver.getTarget() != null) { - abilityToUse = ability; - targetToUse = receiver.getTarget(); - } - } - if (abilityToUse != null) { - this.unitOrderListener.issuePointOrder( - otherSelectedUnit.getSimulationUnit().getHandleId(), - abilityToUse.getHandleId(), this.activeCommandOrderId, - targetToUse.getX(), targetToUse.getY(), shiftDown); - } - } - } - } - if (getSelectedUnit().soundset.yes.playUnitResponse( - this.war3MapViewer.worldScene.audioContext, getSelectedUnit())) { - portraitTalk(); - } - this.selectedSoundCount = 0; - if (this.activeCommand instanceof AbstractCAbilityBuild) { - this.war3MapViewer.getUiSounds().getSound("PlaceBuildingDefault") - .play(this.uiScene.audioContext, 0, 0, 0); - } - else if (this.activeCommand instanceof CAbilityRally) { - this.war3MapViewer.getUiSounds().getSound("RallyPointPlace") - .play(this.uiScene.audioContext, 0, 0, 0); - } - if (!shiftDown) { - this.subMenuOrderIdStack.clear(); - this.activeCommandUnit = null; - this.activeCommand = null; - this.activeCommandOrderId = -1; - clearAndRepopulateCommandCard(); - } - - } - } - - } - } - } - else { - if (button == Input.Buttons.RIGHT) { - if ((getSelectedUnit() != null) && (getSelectedUnit().getSimulationUnit() - .getPlayerIndex() == this.war3MapViewer.getLocalPlayerIndex())) { - final RenderWidget rayPickUnit = this.war3MapViewer.rayPickUnit(screenX, worldScreenY); - if ((rayPickUnit != null) && !rayPickUnit.getSimulationWidget().isDead()) { - boolean ordered = false; - boolean rallied = false; - boolean attacked = false; - for (final RenderUnit unit : this.selectedUnits) { - CAbility abilityToUse = null; - CWidget targetToUse = null; - for (final CAbility ability : unit.getSimulationUnit().getAbilities()) { - ability.checkCanTarget(this.war3MapViewer.simulation, unit.getSimulationUnit(), - OrderIds.smart, rayPickUnit.getSimulationWidget(), - CWidgetAbilityTargetCheckReceiver.INSTANCE); - final CWidget targetWidget = CWidgetAbilityTargetCheckReceiver.INSTANCE.getTarget(); - if (targetWidget != null) { - abilityToUse = ability; - targetToUse = targetWidget; - } - } - if (abilityToUse != null) { - this.unitOrderListener.issueTargetOrder(unit.getSimulationUnit().getHandleId(), - abilityToUse.getHandleId(), OrderIds.smart, targetToUse.getHandleId(), - isShiftDown()); - rallied |= abilityToUse instanceof CAbilityRally; - attacked |= abilityToUse instanceof CAbilityAttack; - ordered = true; - } - } - if (ordered) { - final UnitSound yesSound = attacked ? getSelectedUnit().soundset.yesAttack - : getSelectedUnit().soundset.yes; - if (yesSound.playUnitResponse(this.war3MapViewer.worldScene.audioContext, - getSelectedUnit())) { - portraitTalk(); - } - if (rallied) { - this.war3MapViewer.getUiSounds().getSound("RallyPointPlace") - .play(this.uiScene.audioContext, 0, 0, 0); - } - this.selectedSoundCount = 0; - } - else { - rightClickMove(screenX, worldScreenY); - } - } - else { - rightClickMove(screenX, worldScreenY); - } - } - } - else { - this.war3MapViewer.getClickLocation(this.lastMouseClickLocation, screenX, (int) worldScreenY); - if (Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT)) { - final short pathing = this.war3MapViewer.simulation.getPathingGrid() - .getPathing(this.lastMouseClickLocation.x, this.lastMouseClickLocation.y); - System.out.println(Integer.toBinaryString(pathing)); - } - this.lastMouseDragStart.set(this.lastMouseClickLocation); - this.allowDrag = true; - } - } - } - else { - if (clickedUIFrame instanceof ClickableFrame) { - this.mouseDownUIFrame = (ClickableFrame) clickedUIFrame; - this.mouseDownUIFrame.mouseDown(this.rootFrame, this.uiViewport); - } - } - return false; - } - - private void rightClickMove(final int screenX, final float worldScreenY) { - this.war3MapViewer.getClickLocation(clickLocationTemp, screenX, (int) worldScreenY); - this.war3MapViewer.showConfirmation(clickLocationTemp, 0, 1, 0); - clickLocationTemp2.set(clickLocationTemp.x, clickLocationTemp.y); - - boolean ordered = false; - boolean rallied = false; - for (final RenderUnit unit : this.selectedUnits) { - if (unit.getSimulationUnit().getPlayerIndex() == this.war3MapViewer.getLocalPlayerIndex()) { - for (final CAbility ability : unit.getSimulationUnit().getAbilities()) { - ability.checkCanUse(this.war3MapViewer.simulation, unit.getSimulationUnit(), OrderIds.smart, - BooleanAbilityActivationReceiver.INSTANCE); - if (BooleanAbilityActivationReceiver.INSTANCE.isOk()) { - ability.checkCanTarget(this.war3MapViewer.simulation, unit.getSimulationUnit(), OrderIds.smart, - clickLocationTemp2, PointAbilityTargetCheckReceiver.INSTANCE); - final Vector2 target = PointAbilityTargetCheckReceiver.INSTANCE.getTarget(); - if (target != null) { - this.unitOrderListener.issuePointOrder(unit.getSimulationUnit().getHandleId(), - ability.getHandleId(), OrderIds.smart, clickLocationTemp2.x, clickLocationTemp2.y, - isShiftDown()); - rallied |= ability instanceof CAbilityRally; - ordered = true; - } - } - } - } - - } - - if (ordered) { - if (getSelectedUnit().soundset.yes.playUnitResponse(this.war3MapViewer.worldScene.audioContext, - getSelectedUnit())) { - portraitTalk(); - } - if (rallied) { - this.war3MapViewer.getUiSounds().getSound("RallyPointPlace").play(this.uiScene.audioContext, 0, 0, 0); - } - this.selectedSoundCount = 0; - } - } - - private void selectWidgets(final List selectedUnits) { - final List units = new ArrayList<>(); - for (final RenderWidget widget : selectedUnits) { - if (widget instanceof RenderUnit) { - units.add((RenderUnit) widget); - } - } - selectUnits(units); - } - - private void selectUnits(final List selectedUnits) { - final List prevSelectedUnits = this.selectedUnits; - this.selectedUnits = selectedUnits; - if (!selectedUnits.isEmpty()) { - final RenderUnit unit = selectedUnits.get(0); - boolean selectionChanged = (unit != this.selectedUnit) - || (prevSelectedUnits.size() != selectedUnits.size()); - for (int i = 0; (i < prevSelectedUnits.size()) && (i < selectedUnits.size()); i++) { - if (prevSelectedUnits.get(i) != selectedUnits.get(i)) { - selectionChanged = true; - } - } - boolean playedNewSound = false; - if (selectionChanged) { - this.selectedSoundCount = 0; - } - if (unit.getSimulationUnit().getPlayerIndex() == this.war3MapViewer.getLocalPlayerIndex()) { - if (unit.soundset != null) { - UnitSound ackSoundToPlay = unit.soundset.what; - int soundIndex; - final int pissedSoundCount = unit.soundset.pissed.getSoundCount(); - if (unit.getSimulationUnit().isConstructing()) { - ackSoundToPlay = this.war3MapViewer.getUiSounds() - .getSound(this.rootFrame.getSkinField("ConstructingBuilding")); - soundIndex = (int) (Math.random() * ackSoundToPlay.getSoundCount()); - } - else { - if ((this.selectedSoundCount >= 3) && (pissedSoundCount > 0)) { - soundIndex = this.selectedSoundCount - 3; - ackSoundToPlay = unit.soundset.pissed; - } - else { - soundIndex = (int) (Math.random() * ackSoundToPlay.getSoundCount()); - } - } - if ((ackSoundToPlay != null) && ackSoundToPlay - .playUnitResponse(this.war3MapViewer.worldScene.audioContext, unit, soundIndex)) { - this.selectedSoundCount++; - if ((this.selectedSoundCount - 3) >= pissedSoundCount) { - this.selectedSoundCount = 0; - } - playedNewSound = true; - } - } - } - else { - this.war3MapViewer.getUiSounds().getSound("InterfaceClick").play(this.uiScene.audioContext, 0, 0, 0); - } - if (selectionChanged) { - for (final MultiSelectUnitStateListener listener : this.multiSelectUnitStateListeners) { - listener.dispose(); - } - selectUnit(unit); - if (selectedUnits.size() > 1) { - for (final RenderUnit renderUnit : selectedUnits) { - final MultiSelectUnitStateListener multiSelectUnitStateListener = new MultiSelectUnitStateListener( - renderUnit); - renderUnit.getSimulationUnit().addStateListener(multiSelectUnitStateListener); - this.multiSelectUnitStateListeners.add(multiSelectUnitStateListener); - } - } - } - if (playedNewSound) { - portraitTalk(); - } - } - else { - selectUnit(null); - } - } - - public boolean touchUp(final int screenX, final int screenY, final float worldScreenY, final int button) { - this.currentlyDraggingPointer = -1; - screenCoordsVector.set(screenX, screenY); - this.uiViewport.unproject(screenCoordsVector); - final UIFrame clickedUIFrame = this.rootFrame.touchUp(screenCoordsVector.x, screenCoordsVector.y, button); - if (this.mouseDownUIFrame != null) { - if (clickedUIFrame == this.mouseDownUIFrame) { - this.mouseDownUIFrame.onClick(button); - if (this.mouseDownUIFrame instanceof ClickableActionFrame) { - this.war3MapViewer.getUiSounds().getSound("InterfaceClick").play(this.uiScene.audioContext, 0, 0, - 0); - } - else { - this.war3MapViewer.getUiSounds().getSound("MenuButtonClick").play(this.uiScene.audioContext, 0, 0, - 0); - } - } - this.mouseDownUIFrame.mouseUp(this.rootFrame, this.uiViewport); - } - else { - if (!this.dragSelectPreviewUnits.isEmpty()) { - final List selectedWidgets = new ArrayList<>(); - boolean foundGoal = false; - for (final RenderUnit unit : this.dragSelectPreviewUnits) { - if ((unit.getSimulationUnit().getPlayerIndex() == this.war3MapViewer.getLocalPlayerIndex()) - && !unit.getSimulationUnit().isBuilding()) { - foundGoal = true; - selectedWidgets.add(unit); - } - } - if (!foundGoal) { - selectedWidgets.addAll(this.dragSelectPreviewUnits); - } - final boolean shiftDown = isShiftDown(); - if (shiftDown) { - for (final RenderUnit unit : this.selectedUnits) { - if (!selectedWidgets.contains(unit)) { - selectedWidgets.add(unit); - } - } - } - Collections.sort(selectedWidgets, new Comparator() { - @Override - public int compare(final RenderWidget widget1, final RenderWidget widget2) { - return ((RenderUnit) widget2).getSimulationUnit().getUnitType().getPriority() - - ((RenderUnit) widget1).getSimulationUnit().getUnitType().getPriority(); - } - }); - - this.war3MapViewer.clearUnitMouseOverHighlight(); - - this.war3MapViewer.doSelectUnit(selectedWidgets); - selectWidgets(selectedWidgets); - this.dragSelectPreviewUnits.clear(); - } - else { - if ((button == Input.Buttons.LEFT) && (this.mouseOverUnit != null)) { - final List unitList = new ArrayList<>(); - final boolean shiftDown = isShiftDown(); - if (shiftDown) { - if (this.selectedUnits.contains(this.mouseOverUnit)) { - unitList.addAll(this.selectedUnits); - unitList.remove(this.mouseOverUnit); - } - else { - unitList.addAll(this.selectedUnits); - unitList.add(this.mouseOverUnit); - } - } - else { - unitList.add(this.mouseOverUnit); - } - this.war3MapViewer.doSelectUnit(unitList); - selectWidgets(unitList); - } - } - } - this.mouseDownUIFrame = null; - return false; - } - - private static boolean isShiftDown() { - return Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT) || Gdx.input.isKeyPressed(Input.Keys.SHIFT_RIGHT); - } - - public boolean touchDragged(final int screenX, final int screenY, final float worldScreenY, final int pointer) { - screenCoordsVector.set(screenX, screenY); - this.uiViewport.unproject(screenCoordsVector); - - if (this.meleeUIMinimap.containsMouse(screenCoordsVector.x, screenCoordsVector.y)) { - final Vector2 worldPoint = this.meleeUIMinimap.getWorldPointFromScreen(screenCoordsVector.x, - screenCoordsVector.y); - this.cameraManager.target.x = worldPoint.x; - this.cameraManager.target.y = worldPoint.y; - } - else { - if (this.allowDrag) { - if (null != this.mouseOverUnit) { - this.war3MapViewer.clearUnitMouseOverHighlight(); - this.dragSelectPreviewUnits.clear(); - this.mouseOverUnit = null; - } - - this.war3MapViewer.getClickLocation(clickLocationTemp, screenX, (int) worldScreenY); - this.currentlyDraggingPointer = pointer; - if (pointer == Input.Buttons.MIDDLE) { - this.cameraManager.target.add(this.lastMouseClickLocation.sub(clickLocationTemp).scl(-1)); - } - else if (pointer == Input.Buttons.LEFT) { - // update mouseover - } - this.lastMouseClickLocation.set(clickLocationTemp); - } - } - return false; - } - - public boolean mouseMoved(final int screenX, final int screenY, final float worldScreenY) { - screenCoordsVector.set(screenX, screenY); - this.uiViewport.unproject(screenCoordsVector); - final UIFrame mousedUIFrame = this.rootFrame.getFrameChildUnderMouse(screenCoordsVector.x, - screenCoordsVector.y); - if (mousedUIFrame != this.mouseOverUIFrame) { - if (this.mouseOverUIFrame != null) { - this.mouseOverUIFrame.mouseExit(this.rootFrame, this.uiViewport); - } - if (mousedUIFrame instanceof ClickableFrame) { - this.mouseOverUIFrame = (ClickableFrame) mousedUIFrame; - if (this.mouseOverUIFrame != null) { - this.mouseOverUIFrame.mouseEnter(this.rootFrame, this.uiViewport); - } - if (mousedUIFrame instanceof ClickableActionFrame) { - loadTooltip((ClickableActionFrame) mousedUIFrame); - } - } - else { - this.mouseOverUIFrame = null; - this.tooltipFrame.setVisible(false); - } - } - if (mousedUIFrame == null) { - final RenderWidget newMouseOverUnit = this.war3MapViewer.rayPickUnit(screenX, worldScreenY, - new CWidgetFilterFunction() { - @Override - public boolean call(final CWidget unit) { - final RenderWidget renderPeer = MeleeUI.this.war3MapViewer.getRenderPeer(unit); - return !unit.isDead() && renderPeer.isSelectable(); - } - }); - if (newMouseOverUnit != this.mouseOverUnit) { - this.war3MapViewer.clearUnitMouseOverHighlight(); - this.dragSelectPreviewUnits.clear(); - if (newMouseOverUnit != null) { - this.war3MapViewer.showUnitMouseOverHighlight(newMouseOverUnit); - } - this.mouseOverUnit = newMouseOverUnit; - } - } - return false; - } - - private void loadTooltip(final ClickableActionFrame mousedUIFrame) { - final int goldCost = mousedUIFrame.getToolTipGoldCost(); - final int lumberCost = mousedUIFrame.getToolTipLumberCost(); - final int foodCost = mousedUIFrame.getToolTipFoodCost(); - final String toolTip = mousedUIFrame.getToolTip(); - final String uberTip = mousedUIFrame.getUberTip(); - if ((toolTip == null) || (uberTip == null)) { - this.tooltipFrame.setVisible(false); - } - else { - this.rootFrame.setText(this.tooltipUberTipText, uberTip); - int resourceIndex = 0; - if (goldCost != 0) { - this.tooltipResourceFrames[resourceIndex].setVisible(true); - this.tooltipResourceIconFrames[resourceIndex].setTexture("ToolTipGoldIcon", this.rootFrame); - this.rootFrame.setText(this.tooltipResourceTextFrames[resourceIndex], Integer.toString(goldCost)); - resourceIndex++; - } - if (lumberCost != 0) { - this.tooltipResourceFrames[resourceIndex].setVisible(true); - this.tooltipResourceIconFrames[resourceIndex].setTexture("ToolTipLumberIcon", this.rootFrame); - this.rootFrame.setText(this.tooltipResourceTextFrames[resourceIndex], Integer.toString(lumberCost)); - resourceIndex++; - } - if (foodCost != 0) { - this.tooltipResourceFrames[resourceIndex].setVisible(true); - this.tooltipResourceIconFrames[resourceIndex].setTexture("ToolTipSupplyIcon", this.rootFrame); - this.rootFrame.setText(this.tooltipResourceTextFrames[resourceIndex], Integer.toString(foodCost)); - resourceIndex++; - } - for (int i = resourceIndex; i < this.tooltipResourceFrames.length; i++) { - this.tooltipResourceFrames[i].setVisible(false); - } - float resourcesHeight; - if (resourceIndex != 0) { - this.tooltipUberTipText.addSetPoint(this.uberTipWithResourcesSetPoint); - resourcesHeight = 0.014f; - } - else { - this.tooltipUberTipText.addSetPoint(this.uberTipNoResourcesSetPoint); - resourcesHeight = 0.004f; - } - this.rootFrame.setText(this.tooltipText, toolTip); - final float predictedViewportHeight = this.tooltipText.getPredictedViewportHeight() - + GameUI.convertY(this.uiViewport, resourcesHeight) - + this.tooltipUberTipText.getPredictedViewportHeight() + GameUI.convertY(this.uiViewport, 0.003f); - this.tooltipFrame.setHeight(predictedViewportHeight); - this.tooltipFrame.positionBounds(this.rootFrame, this.uiViewport); - this.tooltipFrame.setVisible(true); - } - } - - public float getHeightRatioCorrection() { - return this.heightRatioCorrection; - } - - @Override - public void queueIconClicked(final int index) { - final CUnit simulationUnit = this.selectedUnit.getSimulationUnit(); - if (simulationUnit.isConstructing()) { - switch (index) { - case 0: - for (final CAbility ability : simulationUnit.getAbilities()) { - ability.checkCanUse(this.war3MapViewer.simulation, simulationUnit, OrderIds.cancel, - BooleanAbilityActivationReceiver.INSTANCE); - if (BooleanAbilityActivationReceiver.INSTANCE.isOk()) { - - final BooleanAbilityTargetCheckReceiver targetCheckReceiver = BooleanAbilityTargetCheckReceiver - .getInstance().reset(); - ability.checkCanTargetNoTarget(this.war3MapViewer.simulation, simulationUnit, OrderIds.cancel, - targetCheckReceiver); - if (targetCheckReceiver.isTargetable()) { - this.unitOrderListener.issueImmediateOrder(simulationUnit.getHandleId(), - ability.getHandleId(), OrderIds.cancel, false); - } - } - } - break; - case 1: - final List unitList = Arrays.asList( - this.war3MapViewer.getRenderPeer(this.selectedUnit.getSimulationUnit().getWorkerInside())); - this.war3MapViewer.doSelectUnit(unitList); - selectWidgets(unitList); - break; - } - } - else { - this.unitOrderListener.unitCancelTrainingItem(simulationUnit.getHandleId(), index); - } - } - - public void dispose() { - if (this.rootFrame != null) { - this.rootFrame.dispose(); - } - } - - private class ItemCommandCardCommandListener implements CommandCardCommandListener { - @Override - public void onClick(final int abilityHandleId, final int orderId, final boolean rightClick) { - final RenderUnit selectedUnit2 = MeleeUI.this.selectedUnit; - final CUnit simulationUnit = selectedUnit2.getSimulationUnit(); - if (rightClick) { - final CAbilityInventory inventoryData = simulationUnit.getInventoryData(); - final int slot = orderId - 1; - final CItem itemInSlot = inventoryData.getItemInSlot(slot); - if (MeleeUI.this.draggingItem != null) { - final CUnit activeCmdSimUnit = MeleeUI.this.activeCommandUnit.getSimulationUnit(); - MeleeUI.this.unitOrderListener.issueTargetOrder(activeCmdSimUnit.getHandleId(), - activeCmdSimUnit.getInventoryData().getHandleId(), OrderIds.itemdrag00 + slot, - MeleeUI.this.draggingItem.getHandleId(), false); - setDraggingItem(null); - MeleeUI.this.activeCommand = null; - MeleeUI.this.activeCommandUnit = null; - } - else { - if (itemInSlot != null) { - setDraggingItem(itemInSlot); - MeleeUI.this.activeCommand = inventoryData; - MeleeUI.this.activeCommandUnit = selectedUnit2; - } - } - } - else { - final CSimulation game = MeleeUI.this.war3MapViewer.simulation; - final BooleanAbilityActivationReceiver receiver = BooleanAbilityActivationReceiver.INSTANCE; - final CAbilityInventory inventoryData = simulationUnit.getInventoryData(); - inventoryData.checkCanUse(game, simulationUnit, orderId, receiver); - if (receiver.isOk()) { - final BooleanAbilityTargetCheckReceiver targetReceiver = BooleanAbilityTargetCheckReceiver - .getInstance(); - targetReceiver.reset(); - inventoryData.checkCanTargetNoTarget(game, simulationUnit, orderId, targetReceiver); - if (targetReceiver.isTargetable()) { - MeleeUI.this.unitOrderListener.issueImmediateOrder(simulationUnit.getHandleId(), - inventoryData.getHandleId(), orderId, isShiftDown()); - } - } - } - } - - @Override - public void openMenu(final int orderId) { - MeleeUI.this.openMenu(orderId); - } - - } - - private final class MultiSelectUnitStateListener implements CUnitStateListener { - private final RenderUnit sourceUnit; - - public MultiSelectUnitStateListener(final RenderUnit sourceUnit) { - this.sourceUnit = sourceUnit; - } - - public void dispose() { - this.sourceUnit.getSimulationUnit().removeStateListener(this); - } - - @Override - public void lifeChanged() { - if (this.sourceUnit.getSimulationUnit().isDead()) { - MeleeUI.this.selectedUnits.remove(this.sourceUnit); - MeleeUI.this.war3MapViewer.doUnselectUnit(this.sourceUnit); - MeleeUI.this.multiSelectUnitStateListeners.remove(this); - dispose(); - } - } - - @Override - public void ordersChanged() { - - } - - @Override - public void queueChanged() { - - } - - @Override - public void rallyPointChanged() { - - } - - @Override - public void waypointsChanged() { - - } - - @Override - public void heroStatsChanged() { - - } - - @Override - public void inventoryChanged() { - - } - - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUIMinimap.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUIMinimap.java deleted file mode 100644 index c3af1694..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MeleeUIMinimap.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui; - -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector2; -import com.etheller.warsmash.viewer5.handlers.w3x.rendersim.RenderUnit; - -public class MeleeUIMinimap { - private final Rectangle minimap; - private final Rectangle minimapFilledArea; - private final Texture minimapTexture; - private final Rectangle playableMapArea; - private final Texture[] teamColors; - - public MeleeUIMinimap(final Rectangle displayArea, final Rectangle playableMapArea, final Texture minimapTexture, - final Texture[] teamColors) { - this.playableMapArea = playableMapArea; - this.minimapTexture = minimapTexture; - this.teamColors = teamColors; - this.minimap = displayArea; - final float worldWidth = playableMapArea.getWidth(); - final float worldHeight = playableMapArea.getHeight(); - final float worldSize = Math.max(worldWidth, worldHeight); - final float minimapFilledWidth = (worldWidth / worldSize) * this.minimap.width; - final float minimapFilledHeight = (worldHeight / worldSize) * this.minimap.height; - - this.minimapFilledArea = new Rectangle(this.minimap.x + ((this.minimap.width - minimapFilledWidth) / 2), - this.minimap.y + ((this.minimap.height - minimapFilledHeight) / 2), minimapFilledWidth, - minimapFilledHeight); - } - - public void render(final SpriteBatch batch, final Iterable units) { - batch.draw(this.minimapTexture, this.minimap.x, this.minimap.y, this.minimap.width, this.minimap.height); - - for (final RenderUnit unit : units) { - final Texture minimapIcon = this.teamColors[unit.getSimulationUnit().getPlayerIndex()]; - batch.draw(minimapIcon, - this.minimapFilledArea.x - + (((unit.location[0] - this.playableMapArea.getX()) / (this.playableMapArea.getWidth())) - * this.minimapFilledArea.width), - this.minimapFilledArea.y - + (((unit.location[1] - this.playableMapArea.getY()) / (this.playableMapArea.getHeight())) - * this.minimapFilledArea.height), - 4, 4); - } - } - - public Vector2 getWorldPointFromScreen(final float screenX, final float screenY) { - final Rectangle filledArea = this.minimapFilledArea; - final float clickX = (screenX - filledArea.x) / filledArea.width; - final float clickY = (screenY - filledArea.y) / filledArea.height; - final float worldX = (clickX * this.playableMapArea.width) + this.playableMapArea.x; - final float worldY = (clickY * this.playableMapArea.height) + this.playableMapArea.y; - return new Vector2(worldX, worldY); - - } - - public boolean containsMouse(final float x, final float y) { - return this.minimapFilledArea.contains(x, y); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MenuCursorState.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MenuCursorState.java deleted file mode 100644 index 60baa30f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MenuCursorState.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui; - -public enum MenuCursorState { - NORMAL("Normal"), - SCROLL_LEFT("Scroll Left"), - SCROLL_RIGHT("Scroll Right"), - SCROLL_DOWN("Scroll Down"), - SCROLL_UP("Scroll Up"), - SCROLL_DOWN_LEFT("Scroll Down Left"), - SCROLL_DOWN_RIGHT("Scroll Down Right"), - SCROLL_UP_LEFT("Scroll Up Left"), - SCROLL_UP_RIGHT("Scroll Up Right"), - TARGET_CURSOR(null), // handled specially - HOLD_ITEM("HoldItem"); - private String animationName; - - private MenuCursorState(final String animationName) { - this.animationName = animationName; - } - - public String getAnimationName() { - return this.animationName; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MenuUI.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MenuUI.java deleted file mode 100644 index aac34777..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/MenuUI.java +++ /dev/null @@ -1,1177 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui; - -import java.io.IOException; -import java.io.InputStream; -import java.net.InetAddress; -import java.net.UnknownHostException; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.math.Vector2; -import com.badlogic.gdx.utils.viewport.ExtendViewport; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.SingleModelScreen; -import com.etheller.warsmash.WarsmashGdxMapScreen; -import com.etheller.warsmash.WarsmashGdxMenuScreen; -import com.etheller.warsmash.WarsmashGdxMultiScreenGame; -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.networking.GameTurnManager; -import com.etheller.warsmash.networking.MultiplayerHack; -import com.etheller.warsmash.networking.WarsmashClient; -import com.etheller.warsmash.networking.WarsmashClientSendingOrderListener; -import com.etheller.warsmash.networking.WarsmashClientWriter; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; -import com.etheller.warsmash.parsers.fdf.frames.EditBoxFrame; -import com.etheller.warsmash.parsers.fdf.frames.GlueButtonFrame; -import com.etheller.warsmash.parsers.fdf.frames.GlueTextButtonFrame; -import com.etheller.warsmash.parsers.fdf.frames.ListBoxFrame; -import com.etheller.warsmash.parsers.fdf.frames.SetPoint; -import com.etheller.warsmash.parsers.fdf.frames.SimpleFrame; -import com.etheller.warsmash.parsers.fdf.frames.SpriteFrame; -import com.etheller.warsmash.parsers.fdf.frames.StringFrame; -import com.etheller.warsmash.parsers.fdf.frames.UIFrame; -import com.etheller.warsmash.parsers.jass.Jass2.RootFrameListener; -import com.etheller.warsmash.parsers.w3x.War3Map; -import com.etheller.warsmash.parsers.w3x.w3i.War3MapW3i; -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.units.Element; -import com.etheller.warsmash.units.custom.WTS; -import com.etheller.warsmash.util.StringBundle; -import com.etheller.warsmash.util.WarsmashConstants; -import com.etheller.warsmash.util.WorldEditStrings; -import com.etheller.warsmash.viewer5.Scene; -import com.etheller.warsmash.viewer5.handlers.mdx.MdxViewer; -import com.etheller.warsmash.viewer5.handlers.w3x.UnitSound; -import com.etheller.warsmash.viewer5.handlers.w3x.War3MapViewer; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.config.War3MapConfig; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerUnitOrderExecutor; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CPlayerUnitOrderListener; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.players.CRace; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.ClickableFrame; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.FocusableFrame; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.menu.CampaignMenuData; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.menu.CampaignMenuUI; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.menu.CampaignMission; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.sound.KeyedSounds; - -public class MenuUI { - private static final Vector2 screenCoordsVector = new Vector2(); - private static boolean ENABLE_NOT_YET_IMPLEMENTED_BUTTONS = false; - - private final DataSource dataSource; - private final Scene uiScene; - private final Viewport uiViewport; - private final MdxViewer viewer; - private final RootFrameListener rootFrameListener; - private final float widthRatioCorrection; - private final float heightRatioCorrection; - private GameUI rootFrame; - private SpriteFrame cursorFrame; - - private ClickableFrame mouseDownUIFrame; - private ClickableFrame mouseOverUIFrame; - private FocusableFrame focusUIFrame; - - private UIFrame mainMenuFrame; - - private SpriteFrame glueSpriteLayerTopRight; - - private SpriteFrame glueSpriteLayerTopLeft; - - private WorldEditStrings worldEditStrings; - - private DataTable uiSoundsTable; - - private KeyedSounds uiSounds; - - private GlueTextButtonFrame singlePlayerButton; - private GlueTextButtonFrame battleNetButton; - private GlueTextButtonFrame localAreaNetworkButton; - private GlueTextButtonFrame optionsButton; - private GlueTextButtonFrame creditsButton; - private GlueButtonFrame realmButton; - private GlueTextButtonFrame exitButton; - - private final boolean quitting = false; - - private MenuState menuState; - - private UIFrame singlePlayerMenu; - private UIFrame singlePlayerMainPanel; - - private UIFrame skirmish; - - private UIFrame profilePanel; - private EditBoxFrame newProfileEditBox; - - private GlueButtonFrame profileButton; - private GlueTextButtonFrame campaignButton; - private GlueTextButtonFrame loadSavedButton; - private GlueTextButtonFrame viewReplayButton; - private GlueTextButtonFrame customCampaignButton; - private GlueTextButtonFrame skirmishButton; - private GlueTextButtonFrame singlePlayerCancelButton; - private GlueButtonFrame editionButton; - - private GlueTextButtonFrame skirmishCancelButton; - - private final WarsmashGdxMultiScreenGame screenManager; - - private final DataTable warsmashIni; - - private UnitSound glueScreenLoop; - - private SpriteFrame warcraftIIILogo; - // Campaign - private UIFrame campaignMenu; - private SpriteFrame campaignFade; - private GlueTextButtonFrame campaignBackButton; - private UIFrame missionSelectFrame; - private UIFrame campaignSelectFrame; - private final DataTable campaignStrings; - private SpriteFrame campaignWarcraftIIILogo; - private final SingleModelScreen menuScreen; - - private CampaignMenuData currentCampaign; - private String[] campaignList; - private CampaignMenuData[] campaignDatas; - private UnitSound mainMenuGlueScreenLoop; - private GlueTextButtonFrame addProfileButton; - private GlueTextButtonFrame deleteProfileButton; - private GlueTextButtonFrame selectProfileButton; - private final PlayerProfileManager profileManager; - private StringFrame profileNameText; - private UIFrame confirmDialog; - private CampaignMenuUI campaignRootMenuUI; - private CampaignMenuUI currentMissionSelectMenuUI; - private UIFrame loadingFrame; - private UIFrame loadingCustomPanel; - private UIFrame loadingMeleePanel; - private StringFrame loadingTitleText; - private StringFrame loadingSubtitleText; - private StringFrame loadingText; - private SpriteFrame loadingBar; - private String mapFilepathToStart; - private LoadingMap loadingMap; - private SpriteFrame loadingBackground; - private boolean unifiedCampaignInfo = false; - - public MenuUI(final DataSource dataSource, final Viewport uiViewport, final Scene uiScene, final MdxViewer viewer, - final WarsmashGdxMultiScreenGame screenManager, final SingleModelScreen menuScreen, - final DataTable warsmashIni, final RootFrameListener rootFrameListener) { - this.dataSource = dataSource; - this.uiViewport = uiViewport; - this.uiScene = uiScene; - this.viewer = viewer; - this.screenManager = screenManager; - this.menuScreen = menuScreen; - this.warsmashIni = warsmashIni; - this.rootFrameListener = rootFrameListener; - - this.widthRatioCorrection = getMinWorldWidth() / 1600f; - this.heightRatioCorrection = getMinWorldHeight() / 1200f; - - this.campaignStrings = new DataTable(StringBundle.EMPTY); - final String campaignStringPath = "UI\\CampaignStrings" + (WarsmashConstants.GAME_VERSION == 1 ? "_exp" : "") - + ".txt"; - if (dataSource.has(campaignStringPath)) { - try (InputStream campaignStringStream = dataSource.getResourceAsStream(campaignStringPath)) { - this.campaignStrings.readTXT(campaignStringStream, true); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - else { - try (InputStream campaignStringStream = dataSource.getResourceAsStream("UI\\CampaignInfoClassic.txt")) { - this.campaignStrings.readTXT(campaignStringStream, true); - this.unifiedCampaignInfo = true; - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - this.profileManager = PlayerProfileManager.loadFromGdx(); - } - - public float getHeightRatioCorrection() { - return this.heightRatioCorrection; - } - - /** - * Called "main" because this was originally written in JASS so that maps could - * override it, and I may convert it back to the JASS at some point. - */ - public void main() { - // ================================= - // Load skins and templates - // ================================= - this.rootFrame = new GameUI(this.dataSource, GameUI.loadSkin(this.dataSource, WarsmashConstants.GAME_VERSION), - this.uiViewport, this.uiScene, this.viewer, 0, WTS.DO_NOTHING); - - this.rootFrameListener.onCreate(this.rootFrame); - try { - this.rootFrame.loadTOCFile("UI\\FrameDef\\FrameDef.toc"); - } - catch (final IOException exc) { - throw new IllegalStateException("Unable to load FrameDef.toc", exc); - } - try { - this.rootFrame.loadTOCFile("UI\\FrameDef\\SmashFrameDef.toc"); - } - catch (final IOException exc) { - throw new IllegalStateException("Unable to load SmashFrameDef.toc", exc); - } - - // Create main menu - this.mainMenuFrame = this.rootFrame.createFrame("MainMenuFrame", this.rootFrame, 0, 0); - - this.warcraftIIILogo = (SpriteFrame) this.rootFrame.getFrameByName("WarCraftIIILogo", 0); - this.rootFrame.setSpriteFrameModel(this.warcraftIIILogo, - this.rootFrame.getSkinField("MainMenuLogo_V" + WarsmashConstants.GAME_VERSION)); - this.warcraftIIILogo.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this.mainMenuFrame, FramePoint.TOPLEFT, - GameUI.convertX(this.uiViewport, 0.13f), GameUI.convertY(this.uiViewport, -0.08f))); - setMainMenuVisible(false); - this.rootFrame.getFrameByName("RealmSelect", 0).setVisible(false); - - this.glueSpriteLayerTopRight = (SpriteFrame) this.rootFrame.createFrameByType("SPRITE", - "SmashGlueSpriteLayerTopRight", this.rootFrame, "", 0); - this.glueSpriteLayerTopRight.setSetAllPoints(true); - final String topRightModel = this.rootFrame - .getSkinField("GlueSpriteLayerTopRight_V" + WarsmashConstants.GAME_VERSION); - this.rootFrame.setSpriteFrameModel(this.glueSpriteLayerTopRight, topRightModel); - this.glueSpriteLayerTopRight.setSequence("MainMenu Birth"); - - this.glueSpriteLayerTopLeft = (SpriteFrame) this.rootFrame.createFrameByType("SPRITE", - "SmashGlueSpriteLayerTopLeft", this.rootFrame, "", 0); - this.glueSpriteLayerTopLeft.setSetAllPoints(true); - final String topLeftModel = this.rootFrame - .getSkinField("GlueSpriteLayerTopLeft_V" + WarsmashConstants.GAME_VERSION); - this.rootFrame.setSpriteFrameModel(this.glueSpriteLayerTopLeft, topLeftModel); - this.glueSpriteLayerTopLeft.setSequence("MainMenu Birth"); - - this.cursorFrame = (SpriteFrame) this.rootFrame.createFrameByType("SPRITE", "SmashCursorFrame", this.rootFrame, - "", 0); - this.rootFrame.setSpriteFrameModel(this.cursorFrame, this.rootFrame.getSkinField("Cursor")); - this.cursorFrame.setSequence("Normal"); - this.cursorFrame.setZDepth(-1.0f); - if (WarsmashConstants.CATCH_CURSOR) { - Gdx.input.setCursorCatched(true); - } - - // Main Menu interactivity - this.singlePlayerButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("SinglePlayerButton", 0); - this.battleNetButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("BattleNetButton", 0); - this.realmButton = (GlueButtonFrame) this.rootFrame.getFrameByName("RealmButton", 0); - this.localAreaNetworkButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("LocalAreaNetworkButton", 0); - this.optionsButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("OptionsButton", 0); - this.creditsButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("CreditsButton", 0); - this.exitButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("ExitButton", 0); - this.editionButton = (GlueButtonFrame) this.rootFrame.getFrameByName("EditionButton", 0); - - if (this.editionButton != null) { - this.editionButton.setOnClick(new Runnable() { - @Override - public void run() { - WarsmashConstants.GAME_VERSION = (WarsmashConstants.GAME_VERSION == 1 ? 0 : 1); - MenuUI.this.glueSpriteLayerTopLeft.setSequence("MainMenu Death"); - MenuUI.this.glueSpriteLayerTopRight.setSequence("MainMenu Death"); - setMainMenuVisible(false); - MenuUI.this.menuState = MenuState.RESTARTING; - } - }); - } - - this.battleNetButton.setEnabled(false); - this.realmButton.setEnabled(false); - this.localAreaNetworkButton.setEnabled(false); - this.optionsButton.setEnabled(false); - this.creditsButton.setEnabled(false); - - this.exitButton.setOnClick(new Runnable() { - @Override - public void run() { - MenuUI.this.glueSpriteLayerTopLeft.setSequence("MainMenu Death"); - MenuUI.this.glueSpriteLayerTopRight.setSequence("MainMenu Death"); - setMainMenuVisible(false); - MenuUI.this.menuState = MenuState.QUITTING; - } - }); - - this.singlePlayerButton.setOnClick(new Runnable() { - @Override - public void run() { - MenuUI.this.glueSpriteLayerTopLeft.setSequence("MainMenu Death"); - MenuUI.this.glueSpriteLayerTopRight.setSequence("MainMenu Death"); - setMainMenuVisible(false); - MenuUI.this.menuState = MenuState.GOING_TO_SINGLE_PLAYER; - } - }); - - // Create single player - this.singlePlayerMenu = this.rootFrame.createFrame("SinglePlayerMenu", this.rootFrame, 0, 0); - this.singlePlayerMenu.setVisible(false); - - this.profilePanel = this.rootFrame.getFrameByName("ProfilePanel", 0); - this.profilePanel.setVisible(false); - - this.newProfileEditBox = (EditBoxFrame) this.rootFrame.getFrameByName("NewProfileEditBox", 0); - this.newProfileEditBox.setOnChange(new Runnable() { - @Override - public void run() { - MenuUI.this.addProfileButton - .setEnabled(!MenuUI.this.profileManager.hasProfile(MenuUI.this.newProfileEditBox.getText())); - } - }); - final StringFrame profileListText = (StringFrame) this.rootFrame.getFrameByName("ProfileListText", 0); - final SimpleFrame profileListContainer = (SimpleFrame) this.rootFrame.getFrameByName("ProfileListContainer", 0); - final ListBoxFrame profileListBox = (ListBoxFrame) this.rootFrame.createFrameByType("LISTBOX", "ListBoxWar3", - profileListContainer, "WITHCHILDREN", 0); - profileListBox.setSetAllPoints(true); - profileListBox.setFrameFont(profileListText.getFrameFont()); - for (final PlayerProfile profile : this.profileManager.getProfiles()) { - profileListBox.addItem(profile.getName(), this.rootFrame, this.uiViewport); - } - profileListContainer.add(profileListBox); - - this.addProfileButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("AddProfileButton", 0); - this.deleteProfileButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("DeleteProfileButton", 0); - this.selectProfileButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("SelectProfileButton", 0); - this.selectProfileButton.setEnabled(false); - this.deleteProfileButton.setEnabled(false); - this.addProfileButton.setOnClick(new Runnable() { - @Override - public void run() { - final String newProfileName = MenuUI.this.newProfileEditBox.getText(); - if (!newProfileName.isEmpty() && !MenuUI.this.profileManager.hasProfile(newProfileName)) { - MenuUI.this.profileManager.addProfile(newProfileName); - profileListBox.addItem(newProfileName, MenuUI.this.rootFrame, MenuUI.this.uiViewport); - MenuUI.this.addProfileButton.setEnabled(false); - } - } - }); - this.deleteProfileButton.setOnClick(new Runnable() { - @Override - public void run() { - final int selectedIndex = profileListBox.getSelectedIndex(); - final boolean validSelect = (selectedIndex >= 0) - && (selectedIndex < MenuUI.this.profileManager.getProfiles().size()); - if (validSelect) { - if (MenuUI.this.profileManager.getProfiles().size() > 1) { - final PlayerProfile profileToRemove = MenuUI.this.profileManager.getProfiles() - .get(selectedIndex); - final String removeProfileName = profileToRemove.getName(); - final boolean deletingCurrentProfile = removeProfileName - .equals(MenuUI.this.profileManager.getCurrentProfile()); - MenuUI.this.profileManager.removeProfile(profileToRemove); - profileListBox.removeItem(selectedIndex, MenuUI.this.rootFrame, MenuUI.this.uiViewport); - if (deletingCurrentProfile) { - setCurrentProfile(MenuUI.this.profileManager.getProfiles().get(0).getName()); - } - } - } - } - }); - this.selectProfileButton.setOnClick(new Runnable() { - @Override - public void run() { - final int selectedIndex = profileListBox.getSelectedIndex(); - final boolean validSelect = (selectedIndex >= 0) - && (selectedIndex < MenuUI.this.profileManager.getProfiles().size()); - if (validSelect) { - final PlayerProfile profileToSelect = MenuUI.this.profileManager.getProfiles().get(selectedIndex); - final String selectedProfileName = profileToSelect.getName(); - setCurrentProfile(selectedProfileName); - - MenuUI.this.glueSpriteLayerTopLeft.setSequence("RealmSelection Death"); - MenuUI.this.profilePanel.setVisible(false); - MenuUI.this.menuState = MenuState.SINGLE_PLAYER; - setSinglePlayerButtonsEnabled(false); - } - - } - - }); - profileListBox.setOnSelect(new Runnable() { - @Override - public void run() { - final int selectedIndex = profileListBox.getSelectedIndex(); - final boolean validSelect = (selectedIndex >= 0) - && (selectedIndex < MenuUI.this.profileManager.getProfiles().size()); - MenuUI.this.selectProfileButton.setEnabled(validSelect); - MenuUI.this.deleteProfileButton.setEnabled(validSelect); - } - }); - - this.singlePlayerMainPanel = this.rootFrame.getFrameByName("MainPanel", 0); - - // Single Player Interactivity - this.profileButton = (GlueButtonFrame) this.rootFrame.getFrameByName("ProfileButton", 0); - this.campaignButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("CampaignButton", 0); - this.loadSavedButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("LoadSavedButton", 0); - this.viewReplayButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("ViewReplayButton", 0); - this.customCampaignButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("CustomCampaignButton", 0); - this.skirmishButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("SkirmishButton", 0); - - this.singlePlayerCancelButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("CancelButton", 0); - - this.profileNameText = (StringFrame) this.rootFrame.getFrameByName("ProfileNameText", 0); - this.rootFrame.setText(this.profileNameText, this.profileManager.getCurrentProfile()); - - setSinglePlayerButtonsEnabled(true); - - this.profileButton.setOnClick(new Runnable() { - @Override - public void run() { - MenuUI.this.glueSpriteLayerTopLeft.setSequence("RealmSelection Birth"); - setSinglePlayerButtonsEnabled(false); - MenuUI.this.menuState = MenuState.SINGLE_PLAYER_PROFILE; - } - }); - - this.campaignButton.setOnClick(new Runnable() { - @Override - public void run() { - MenuUI.this.glueSpriteLayerTopLeft.setSequence("SinglePlayer Death"); - MenuUI.this.glueSpriteLayerTopRight.setSequence("SinglePlayer Death"); - MenuUI.this.singlePlayerMenu.setVisible(false); - MenuUI.this.profilePanel.setVisible(false); - MenuUI.this.menuState = MenuState.GOING_TO_CAMPAIGN; - } - }); - - this.skirmishButton.setOnClick(new Runnable() { - @Override - public void run() { - MenuUI.this.glueSpriteLayerTopLeft.setSequence("SinglePlayer Death"); - MenuUI.this.glueSpriteLayerTopRight.setSequence("SinglePlayer Death"); - MenuUI.this.singlePlayerMenu.setVisible(false); - MenuUI.this.profilePanel.setVisible(false); - MenuUI.this.menuState = MenuState.GOING_TO_SINGLE_PLAYER_SKIRMISH; - } - }); - - this.singlePlayerCancelButton.setOnClick(new Runnable() { - @Override - public void run() { - if (MenuUI.this.menuState == MenuState.SINGLE_PLAYER_PROFILE) { - MenuUI.this.glueSpriteLayerTopLeft.setSequence("RealmSelection Death"); - MenuUI.this.profilePanel.setVisible(false); - } - else { - MenuUI.this.glueSpriteLayerTopLeft.setSequence("SinglePlayer Death"); - } - MenuUI.this.glueSpriteLayerTopRight.setSequence("SinglePlayer Death"); - MenuUI.this.singlePlayerMenu.setVisible(false); - MenuUI.this.menuState = MenuState.GOING_TO_MAIN_MENU; - } - }); - - // Create skirmish UI - this.skirmish = this.rootFrame.createFrame("Skirmish", this.rootFrame, 0, 0); - this.skirmish.setVisible(false); - - this.skirmishCancelButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("CancelButton", 0); - this.skirmishCancelButton.setOnClick(new Runnable() { - @Override - public void run() { - MenuUI.this.glueSpriteLayerTopLeft.setSequence("SinglePlayerSkirmish Death"); - MenuUI.this.glueSpriteLayerTopRight.setSequence("SinglePlayerSkirmish Death"); - MenuUI.this.skirmish.setVisible(false); - MenuUI.this.menuState = MenuState.GOING_TO_SINGLE_PLAYER; - - } - }); - - // Create Campaign UI - - this.campaignMenu = this.rootFrame.createFrame("CampaignMenu", this.rootFrame, 0, 0); - this.campaignMenu.setVisible(false); - this.campaignFade = (SpriteFrame) this.rootFrame.getFrameByName("SlidingDoors", 0); - this.campaignFade.setVisible(false); - this.campaignBackButton = (GlueTextButtonFrame) this.rootFrame.getFrameByName("BackButton", 0); - this.campaignBackButton.setVisible(false); - this.missionSelectFrame = this.rootFrame.getFrameByName("MissionSelectFrame", 0); - this.missionSelectFrame.setVisible(false); - final StringFrame missionName = (StringFrame) this.rootFrame.getFrameByName("MissionName", 0); - final StringFrame missionNameHeader = (StringFrame) this.rootFrame.getFrameByName("MissionNameHeader", 0); - - this.campaignSelectFrame = this.rootFrame.getFrameByName("CampaignSelectFrame", 0); - this.campaignSelectFrame.setVisible(false); - - this.campaignWarcraftIIILogo = (SpriteFrame) this.rootFrame.getFrameByName("WarCraftIIILogo", 0); - this.rootFrame.setSpriteFrameModel(this.campaignWarcraftIIILogo, - this.rootFrame.getSkinField("MainMenuLogo_V" + WarsmashConstants.GAME_VERSION)); - this.campaignWarcraftIIILogo.setVisible(false); - this.campaignWarcraftIIILogo - .addSetPoint(new SetPoint(FramePoint.TOPRIGHT, this.campaignMenu, FramePoint.TOPRIGHT, - GameUI.convertX(this.uiViewport, -0.13f), GameUI.convertY(this.uiViewport, -0.08f))); - this.campaignRootMenuUI = new CampaignMenuUI(null, this.campaignMenu, this.rootFrame, this.uiViewport); - this.campaignRootMenuUI.setVisible(false); - this.campaignRootMenuUI.addSetPoint(new SetPoint(FramePoint.TOPRIGHT, this.campaignMenu, FramePoint.TOPRIGHT, - GameUI.convertX(this.uiViewport, -0.0f), GameUI.convertY(this.uiViewport, -0.12f))); - this.campaignRootMenuUI.setWidth(GameUI.convertX(this.uiViewport, 0.30f)); - this.campaignRootMenuUI.setHeight(GameUI.convertY(this.uiViewport, 0.42f)); - this.rootFrame.add(this.campaignRootMenuUI); - - this.campaignBackButton.setOnClick(new Runnable() { - @Override - public void run() { - if (MenuUI.this.currentMissionSelectMenuUI != null) { - MenuUI.this.currentMissionSelectMenuUI.setVisible(false); - MenuUI.this.missionSelectFrame.setVisible(false); - MenuUI.this.menuState = MenuState.CAMPAIGN; - MenuUI.this.currentMissionSelectMenuUI = null; - } - else { - MenuUI.this.campaignMenu.setVisible(false); - MenuUI.this.campaignBackButton.setVisible(false); - MenuUI.this.missionSelectFrame.setVisible(false); - MenuUI.this.campaignSelectFrame.setVisible(false); - MenuUI.this.campaignWarcraftIIILogo.setVisible(false); - MenuUI.this.campaignRootMenuUI.setVisible(false); - MenuUI.this.campaignFade.setSequence("Birth"); - MenuUI.this.menuState = MenuState.LEAVING_CAMPAIGN; - } - } - }); - final Element campaignIndex = this.campaignStrings.get("Index"); - this.campaignList = campaignIndex.getField("CampaignList").split(","); - this.campaignDatas = new CampaignMenuData[this.campaignList.length]; - for (int i = 0; i < this.campaignList.length; i++) { - final String campaign = this.campaignList[i]; - final Element campaignElement = this.campaignStrings.get(campaign); - if (campaignElement != null) { - final CampaignMenuData newCampaign = new CampaignMenuData(campaignElement); - this.campaignDatas[i] = newCampaign; - if (this.currentCampaign == null) { - this.currentCampaign = newCampaign; - } - - } - } - for (final CampaignMenuData campaign : this.campaignDatas) { - if (campaign != null) { - final CampaignMenuUI missionSelectMenuUI = new CampaignMenuUI(null, this.campaignMenu, this.rootFrame, - this.uiViewport); - missionSelectMenuUI.setVisible(false); - missionSelectMenuUI - .addSetPoint(new SetPoint(FramePoint.TOPRIGHT, this.campaignMenu, FramePoint.TOPRIGHT, - GameUI.convertX(this.uiViewport, -0.0f), GameUI.convertY(this.uiViewport, -0.12f))); - missionSelectMenuUI.setWidth(GameUI.convertX(this.uiViewport, 0.30f)); - missionSelectMenuUI.setHeight(GameUI.convertY(this.uiViewport, 0.42f)); - this.rootFrame.add(missionSelectMenuUI); - - for (final CampaignMission mission : campaign.getMissions()) { - missionSelectMenuUI.addButton(mission.getHeader(), mission.getMissionName(), new Runnable() { - @Override - public void run() { - MenuUI.this.campaignMenu.setVisible(false); - MenuUI.this.campaignBackButton.setVisible(false); - MenuUI.this.missionSelectFrame.setVisible(false); - MenuUI.this.campaignSelectFrame.setVisible(false); - MenuUI.this.campaignWarcraftIIILogo.setVisible(false); - MenuUI.this.campaignRootMenuUI.setVisible(false); - MenuUI.this.currentMissionSelectMenuUI.setVisible(false); - MenuUI.this.campaignFade.setSequence("Birth"); - MenuUI.this.mapFilepathToStart = mission.getMapFilename(); - } - }); - } - - this.campaignRootMenuUI.addButton(campaign.getHeader(), campaign.getName(), new Runnable() { - @Override - public void run() { - if (campaign != MenuUI.this.currentCampaign) { - MenuUI.this.campaignMenu.setVisible(false); - MenuUI.this.campaignBackButton.setVisible(false); - MenuUI.this.missionSelectFrame.setVisible(false); - MenuUI.this.campaignSelectFrame.setVisible(false); - MenuUI.this.campaignWarcraftIIILogo.setVisible(false); - MenuUI.this.campaignRootMenuUI.setVisible(false); - MenuUI.this.campaignFade.setSequence("Birth"); - MenuUI.this.currentCampaign = campaign; - MenuUI.this.currentMissionSelectMenuUI = missionSelectMenuUI; - MenuUI.this.menuState = MenuState.GOING_TO_MISSION_SELECT; - } - else { - MenuUI.this.campaignSelectFrame.setVisible(false); - MenuUI.this.campaignRootMenuUI.setVisible(false); - MenuUI.this.currentMissionSelectMenuUI.setVisible(true); - MenuUI.this.missionSelectFrame.setVisible(true); - MenuUI.this.menuState = MenuState.MISSION_SELECT; - } - MenuUI.this.rootFrame.setDecoratedText(missionName, campaign.getName()); - MenuUI.this.rootFrame.setDecoratedText(missionNameHeader, campaign.getHeader()); - } - }); - if (campaign == MenuUI.this.currentCampaign) { - MenuUI.this.currentMissionSelectMenuUI = missionSelectMenuUI; - } - } - } - - this.confirmDialog = this.rootFrame.createFrame("DialogWar3", this.rootFrame, 0, 0); - this.confirmDialog.setVisible(false); - - this.loadingFrame = this.rootFrame.createFrame("Loading", this.rootFrame, 0, 0); - this.loadingFrame.setVisible(false); - this.loadingCustomPanel = this.rootFrame.getFrameByName("LoadingCustomPanel", 0); - this.loadingCustomPanel.setVisible(false); - this.loadingTitleText = (StringFrame) this.rootFrame.getFrameByName("LoadingTitleText", 0); - this.loadingSubtitleText = (StringFrame) this.rootFrame.getFrameByName("LoadingSubtitleText", 0); - this.loadingText = (StringFrame) this.rootFrame.getFrameByName("LoadingText", 0); - this.loadingBar = (SpriteFrame) this.rootFrame.getFrameByName("LoadingBar", 0); - this.loadingBackground = (SpriteFrame) this.rootFrame.getFrameByName("LoadingBackground", 0); - - this.loadingMeleePanel = this.rootFrame.getFrameByName("LoadingMeleePanel", 0); - this.loadingMeleePanel.setVisible(false); - - // position all - this.rootFrame.positionBounds(this.rootFrame, this.uiViewport); - - this.menuState = MenuState.GOING_TO_MAIN_MENU; - - loadSounds(); - - final String glueLoopField = this.rootFrame.getSkinField("GlueScreenLoop_V" + WarsmashConstants.GAME_VERSION); - this.mainMenuGlueScreenLoop = this.uiSounds.getSound(glueLoopField); - this.glueScreenLoop = this.mainMenuGlueScreenLoop; - this.glueScreenLoop.play(this.uiScene.audioContext, 0f, 0f, 0f); - } - - private void internalStartMap(final String mapFilename) { - this.loadingFrame.setVisible(true); - this.loadingBar.setVisible(true); - this.loadingCustomPanel.setVisible(true); - final DataSource codebase = WarsmashGdxMapScreen.parseDataSources(this.warsmashIni); - final GameTurnManager turnManager; - if (MultiplayerHack.MULTIPLAYER_HACK_SERVER_ADDR != null) { - turnManager = GameTurnManager.PAUSED; - } - else { - turnManager = GameTurnManager.LOCAL; - } - final War3MapViewer viewer = new War3MapViewer(codebase, this.screenManager, - new War3MapConfig(WarsmashConstants.MAX_PLAYERS), turnManager); - - if (WarsmashGdxMapScreen.ENABLE_AUDIO) { - viewer.worldScene.enableAudio(); - viewer.enableAudio(); - } - try { - final War3Map map = viewer.beginLoadingMap(mapFilename); - final War3MapW3i mapInfo = map.readMapInformation(); - final DataTable worldEditData = viewer.loadWorldEditData(map); - final WTS wts = viewer.preloadWTS(map); - - final int loadingScreen = mapInfo.getLoadingScreen(); - System.out.println("LOADING SCREEN INT: " + loadingScreen); - final int campaignBackground = mapInfo.getCampaignBackground(); - final Element loadingScreens = worldEditData.get("LoadingScreens"); - final String key = String.format("%2s", Integer.toString(campaignBackground)).replace(' ', '0'); - final int animationSequenceIndex = loadingScreens.getFieldValue(key, 2); - final String campaignScreenModel = loadingScreens.getField(key, 3); - - this.menuScreen.setModel(null); - this.rootFrame.setSpriteFrameModel(this.loadingBackground, campaignScreenModel); - this.loadingBackground.setSequence(animationSequenceIndex); - this.rootFrame.setSpriteFrameModel(this.loadingBar, this.rootFrame.getSkinField("LoadingProgressBar")); - this.loadingBar.setSequence(0); - this.loadingBar.setFrameByRatio(0.5f); - this.loadingBar.setZDepth(1.0f); - this.rootFrame.setText(this.loadingTitleText, getStringWithWTS(wts, mapInfo.getLoadingScreenTitle())); - this.rootFrame.setText(this.loadingSubtitleText, getStringWithWTS(wts, mapInfo.getLoadingScreenSubtitle())); - this.rootFrame.setText(this.loadingText, getStringWithWTS(wts, mapInfo.getLoadingScreenText())); - this.loadingMap = new LoadingMap(viewer, map, mapInfo); - - } - catch (final IOException e) { - throw new RuntimeException(e); - } - } - - private static String getStringWithWTS(final WTS wts, String string) { - if (string.startsWith("TRIGSTR_")) { - string = wts.get(Integer.parseInt(string.substring(8))); - } - return string; - } - - public void startMap(final String mapFilename) { - this.mainMenuFrame.setVisible(false); - internalStartMap(mapFilename); - } - - private void setCurrentProfile(final String selectedProfileName) { - this.profileManager.setCurrentProfile(selectedProfileName); - this.rootFrame.setText(MenuUI.this.profileNameText, selectedProfileName); - } - - protected void setSinglePlayerButtonsEnabled(final boolean b) { - this.profileButton.setEnabled(b); - this.campaignButton.setEnabled(b); - this.loadSavedButton.setEnabled(b && ENABLE_NOT_YET_IMPLEMENTED_BUTTONS); - this.viewReplayButton.setEnabled(b && ENABLE_NOT_YET_IMPLEMENTED_BUTTONS); - this.customCampaignButton.setEnabled(b && ENABLE_NOT_YET_IMPLEMENTED_BUTTONS); - this.skirmishButton.setEnabled(b); - this.singlePlayerCancelButton.setEnabled(b); - } - - private void setMainMenuVisible(final boolean visible) { - this.mainMenuFrame.setVisible(visible); - this.warcraftIIILogo.setVisible(visible); - } - - public void resize() { - - } - - public void render(final SpriteBatch batch, final GlyphLayout glyphLayout) { - final BitmapFont font = this.rootFrame.getFont(); - final BitmapFont font20 = this.rootFrame.getFont20(); - font.setColor(Color.YELLOW); - final String fpsString = "FPS: " + Gdx.graphics.getFramesPerSecond(); - glyphLayout.setText(font, fpsString); - font.draw(batch, fpsString, (getMinWorldWidth() - glyphLayout.width) / 2, 1100 * this.heightRatioCorrection); - this.rootFrame.render(batch, font20, glyphLayout); - } - - private float getMinWorldWidth() { - if (this.uiViewport instanceof ExtendViewport) { - return ((ExtendViewport) this.uiViewport).getMinWorldWidth(); - } - return this.uiViewport.getWorldWidth(); - } - - private float getMinWorldHeight() { - if (this.uiViewport instanceof ExtendViewport) { - return ((ExtendViewport) this.uiViewport).getMinWorldHeight(); - } - return this.uiViewport.getWorldHeight(); - } - - public void update(final float deltaTime) { - if (this.mapFilepathToStart != null) { - this.campaignFade.setVisible(false); - internalStartMap(this.mapFilepathToStart); - this.mapFilepathToStart = null; - return; - } - else if (this.loadingMap != null) { - final int localPlayerIndex = MultiplayerHack.LP_VAL; - try { - this.loadingMap.viewer.loadMap(this.loadingMap.map, this.loadingMap.mapInfo, localPlayerIndex); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - // TODO not cast menu screen - CPlayerUnitOrderListener uiOrderListener; - final WarsmashClient warsmashClient; - if (MultiplayerHack.MULTIPLAYER_HACK_SERVER_ADDR != null) { - try { - warsmashClient = new WarsmashClient( - InetAddress.getByName(MultiplayerHack.MULTIPLAYER_HACK_SERVER_ADDR), - this.loadingMap.viewer); - } - catch (final UnknownHostException e) { - throw new RuntimeException(e); - } - catch (final IOException e) { - throw new RuntimeException(e); - } - final WarsmashClientWriter warsmashClientWriter = warsmashClient.getWriter(); - warsmashClientWriter.joinGame(); - warsmashClientWriter.send(); - uiOrderListener = new WarsmashClientSendingOrderListener(warsmashClientWriter); - } - else { - uiOrderListener = new CPlayerUnitOrderExecutor(this.loadingMap.viewer.simulation, localPlayerIndex); - warsmashClient = null; - } - - MenuUI.this.screenManager.setScreen(new WarsmashGdxMapScreen(this.loadingMap.viewer, this.screenManager, - (WarsmashGdxMenuScreen) this.menuScreen, uiOrderListener)); - this.loadingMap = null; - - this.loadingBar.setVisible(false); - this.loadingFrame.setVisible(false); - this.loadingBackground.setVisible(false); - if (MultiplayerHack.MULTIPLAYER_HACK_SERVER_ADDR != null) { - warsmashClient.startThread(); - } - return; - } - if ((this.focusUIFrame != null) && !this.focusUIFrame.isVisibleOnScreen()) { - setFocusFrame(getNextFocusFrame()); - } - - final int baseMouseX = Gdx.input.getX(); - int mouseX = baseMouseX; - final int baseMouseY = Gdx.input.getY(); - int mouseY = baseMouseY; - final int minX = this.uiViewport.getScreenX(); - final int maxX = minX + this.uiViewport.getScreenWidth(); - final int minY = this.uiViewport.getScreenY(); - final int maxY = minY + this.uiViewport.getScreenHeight(); - - mouseX = Math.max(minX, Math.min(maxX, mouseX)); - mouseY = Math.max(minY, Math.min(maxY, mouseY)); - if (Gdx.input.isCursorCatched()) { - if (WarsmashConstants.CATCH_CURSOR) { - Gdx.input.setCursorPosition(mouseX, mouseY); - } - } - - screenCoordsVector.set(mouseX, mouseY); - this.uiViewport.unproject(screenCoordsVector); - this.cursorFrame.setFramePointX(FramePoint.LEFT, screenCoordsVector.x); - this.cursorFrame.setFramePointY(FramePoint.BOTTOM, screenCoordsVector.y); - this.cursorFrame.setSequence("Normal"); - - if (this.glueSpriteLayerTopRight.isSequenceEnded() && this.glueSpriteLayerTopLeft.isSequenceEnded() - && (!this.campaignFade.isVisible() || this.campaignFade.isSequenceEnded())) { - switch (this.menuState) { - case GOING_TO_MAIN_MENU: - this.glueSpriteLayerTopLeft.setSequence("MainMenu Birth"); - this.glueSpriteLayerTopRight.setSequence("MainMenu Birth"); - this.menuState = MenuState.MAIN_MENU; - break; - case MAIN_MENU: - setMainMenuVisible(true); - this.glueSpriteLayerTopLeft.setSequence("MainMenu Stand"); - this.glueSpriteLayerTopRight.setSequence("MainMenu Stand"); - break; - case GOING_TO_SINGLE_PLAYER: - this.glueSpriteLayerTopLeft.setSequence("SinglePlayer Birth"); - this.glueSpriteLayerTopRight.setSequence("SinglePlayer Birth"); - this.menuState = MenuState.SINGLE_PLAYER; - break; - case LEAVING_CAMPAIGN: - this.glueSpriteLayerTopLeft.setSequence("Birth"); - this.glueSpriteLayerTopRight.setSequence("Birth"); - if (this.campaignFade.isVisible()) { - this.campaignFade.setSequence("Death"); - } - this.glueScreenLoop.stop(); - this.glueScreenLoop = this.mainMenuGlueScreenLoop; - this.glueScreenLoop.play(this.uiScene.audioContext, 0f, 0f, 0f); - this.menuScreen.setModel( - this.rootFrame.getSkinField("GlueSpriteLayerBackground_V" + WarsmashConstants.GAME_VERSION)); - this.rootFrame.setSpriteFrameModel(this.cursorFrame, this.rootFrame.getSkinField("Cursor")); - this.menuState = MenuState.GOING_TO_SINGLE_PLAYER; - break; - case SINGLE_PLAYER: - this.singlePlayerMenu.setVisible(true); - this.campaignFade.setVisible(false); - setSinglePlayerButtonsEnabled(true); - this.glueSpriteLayerTopLeft.setSequence("SinglePlayer Stand"); - this.glueSpriteLayerTopRight.setSequence("SinglePlayer Stand"); - break; - case GOING_TO_SINGLE_PLAYER_SKIRMISH: - this.glueSpriteLayerTopLeft.setSequence("SinglePlayerSkirmish Birth"); - this.glueSpriteLayerTopRight.setSequence("SinglePlayerSkirmish Birth"); - this.menuState = MenuState.SINGLE_PLAYER_SKIRMISH; - break; - case SINGLE_PLAYER_SKIRMISH: - this.skirmish.setVisible(true); - this.glueSpriteLayerTopLeft.setSequence("SinglePlayerSkirmish Stand"); - this.glueSpriteLayerTopRight.setSequence("SinglePlayerSkirmish Stand"); - break; - case GOING_TO_CAMPAIGN: - this.glueSpriteLayerTopLeft.setSequence("Death"); - this.glueSpriteLayerTopRight.setSequence("Death"); - this.campaignMenu.setVisible(true); - this.campaignFade.setVisible(true); - this.campaignFade.setSequence("Birth"); - this.menuState = MenuState.GOING_TO_CAMPAIGN_PART2; - break; - case GOING_TO_CAMPAIGN_PART2: { - final String currentCampaignBackgroundModel = getCurrentBackgroundModel(); - final String currentCampaignAmbientSound = this.rootFrame - .trySkinField(this.currentCampaign.getAmbientSound()); - this.menuScreen.setModel(currentCampaignBackgroundModel); - this.glueScreenLoop.stop(); - this.glueScreenLoop = this.uiSounds.getSound(currentCampaignAmbientSound); - this.glueScreenLoop.play(this.uiScene.audioContext, 0f, 0f, 0f); - final DataTable skinData = this.rootFrame.getSkinData(); - final String cursorSkin = CRace.VALUES[this.currentCampaign.getCursor()].name(); - this.rootFrame.setSpriteFrameModel(this.cursorFrame, skinData.get(cursorSkin).getField("Cursor")); - - this.campaignFade.setSequence("Death"); - this.menuState = MenuState.CAMPAIGN; - break; - } - case CAMPAIGN: - this.campaignMenu.setVisible(true); - this.campaignBackButton.setVisible(true); - this.campaignWarcraftIIILogo.setVisible(true); - this.campaignSelectFrame.setVisible(true); - this.campaignRootMenuUI.setVisible(true); - break; - case GOING_TO_MISSION_SELECT: { - final String currentCampaignBackgroundModel = getCurrentBackgroundModel(); - final String currentCampaignAmbientSound = this.rootFrame - .trySkinField(this.currentCampaign.getAmbientSound()); - this.menuScreen.setModel(currentCampaignBackgroundModel); - this.glueScreenLoop.stop(); - this.glueScreenLoop = this.uiSounds.getSound(currentCampaignAmbientSound); - this.glueScreenLoop.play(this.uiScene.audioContext, 0f, 0f, 0f); - final DataTable skinData = this.rootFrame.getSkinData(); - final String cursorSkin = CRace.VALUES[this.currentCampaign.getCursor()].name(); - this.rootFrame.setSpriteFrameModel(this.cursorFrame, skinData.get(cursorSkin).getField("Cursor")); - - this.campaignFade.setSequence("Death"); - this.menuState = MenuState.MISSION_SELECT; - break; - } - case MISSION_SELECT: - this.campaignMenu.setVisible(true); - this.campaignBackButton.setVisible(true); - this.campaignWarcraftIIILogo.setVisible(true); - this.currentMissionSelectMenuUI.setVisible(true); - this.missionSelectFrame.setVisible(true); - break; - case GOING_TO_SINGLE_PLAYER_PROFILE: - this.glueSpriteLayerTopLeft.setSequence("RealmSelection Birth"); - this.menuState = MenuState.SINGLE_PLAYER_PROFILE; - break; - case SINGLE_PLAYER_PROFILE: - this.profilePanel.setVisible(true); - setSinglePlayerButtonsEnabled(true); - this.glueSpriteLayerTopLeft.setSequence("RealmSelection Stand"); - // TODO the below should probably be some generic focusing thing when we enter a - // new view? - if ((this.newProfileEditBox != null) && this.newProfileEditBox.isFocusable()) { - setFocusFrame(this.newProfileEditBox); - } - break; - case QUITTING: - Gdx.app.exit(); - break; - case RESTARTING: - MenuUI.this.screenManager - .setScreen(new WarsmashGdxMenuScreen(MenuUI.this.warsmashIni, this.screenManager)); - break; - default: - break; - } - } - - } - - private FocusableFrame getNextFocusFrame() { - return this.rootFrame.getNextFocusFrame(); - } - - public boolean touchDown(final int screenX, final int screenY, final float worldScreenY, final int button) { - screenCoordsVector.set(screenX, screenY); - this.uiViewport.unproject(screenCoordsVector); - final UIFrame clickedUIFrame = this.rootFrame.touchDown(screenCoordsVector.x, screenCoordsVector.y, button); - if (clickedUIFrame != null) { - if (clickedUIFrame instanceof ClickableFrame) { - this.mouseDownUIFrame = (ClickableFrame) clickedUIFrame; - this.mouseDownUIFrame.mouseDown(this.rootFrame, this.uiViewport); - } - if (clickedUIFrame instanceof FocusableFrame) { - final FocusableFrame clickedFocusableFrame = (FocusableFrame) clickedUIFrame; - if (clickedFocusableFrame.isFocusable()) { - setFocusFrame(clickedFocusableFrame); - } - } - } - return false; - } - - private void setFocusFrame(final FocusableFrame clickedFocusableFrame) { - if (this.focusUIFrame != null) { - this.focusUIFrame.onFocusLost(); - } - this.focusUIFrame = clickedFocusableFrame; - if (this.focusUIFrame != null) { - this.focusUIFrame.onFocusGained(); - } - } - - public boolean touchUp(final int screenX, final int screenY, final float worldScreenY, final int button) { - screenCoordsVector.set(screenX, screenY); - this.uiViewport.unproject(screenCoordsVector); - final UIFrame clickedUIFrame = this.rootFrame.touchUp(screenCoordsVector.x, screenCoordsVector.y, button); - if (this.mouseDownUIFrame != null) { - if (clickedUIFrame == this.mouseDownUIFrame) { - this.mouseDownUIFrame.onClick(button); - this.uiSounds.getSound("GlueScreenClick").play(this.uiScene.audioContext, 0, 0, 0); - } - this.mouseDownUIFrame.mouseUp(this.rootFrame, this.uiViewport); - } - this.mouseDownUIFrame = null; - return false; - } - - public boolean touchDragged(final int screenX, final int screenY, final float worldScreenY, final int pointer) { - mouseMoved(screenX, screenY, worldScreenY); - return false; - } - - public boolean mouseMoved(final int screenX, final int screenY, final float worldScreenY) { - screenCoordsVector.set(screenX, screenY); - this.uiViewport.unproject(screenCoordsVector); - final UIFrame mousedUIFrame = this.rootFrame.getFrameChildUnderMouse(screenCoordsVector.x, - screenCoordsVector.y); - if (mousedUIFrame != this.mouseOverUIFrame) { - if (this.mouseOverUIFrame != null) { - this.mouseOverUIFrame.mouseExit(this.rootFrame, this.uiViewport); - } - if (mousedUIFrame instanceof ClickableFrame) { - this.mouseOverUIFrame = (ClickableFrame) mousedUIFrame; - if (this.mouseOverUIFrame != null) { - this.mouseOverUIFrame.mouseEnter(this.rootFrame, this.uiViewport); - } - } - else { - this.mouseOverUIFrame = null; - } - } - return false; - } - - private void loadSounds() { - this.worldEditStrings = new WorldEditStrings(this.dataSource); - this.uiSoundsTable = new DataTable(this.worldEditStrings); - try { - try (InputStream miscDataTxtStream = this.dataSource.getResourceAsStream("UI\\SoundInfo\\UISounds.slk")) { - this.uiSoundsTable.readSLK(miscDataTxtStream); - } - try (InputStream miscDataTxtStream = this.dataSource - .getResourceAsStream("UI\\SoundInfo\\AmbienceSounds.slk")) { - this.uiSoundsTable.readSLK(miscDataTxtStream); - } - } - catch (final IOException e) { - e.printStackTrace(); - } - this.uiSounds = new KeyedSounds(this.uiSoundsTable, this.dataSource); - } - - public KeyedSounds getUiSounds() { - return this.uiSounds; - } - - private static enum MenuState { - GOING_TO_MAIN_MENU, - MAIN_MENU, - GOING_TO_SINGLE_PLAYER, - LEAVING_CAMPAIGN, - SINGLE_PLAYER, - GOING_TO_SINGLE_PLAYER_SKIRMISH, - SINGLE_PLAYER_SKIRMISH, - GOING_TO_CAMPAIGN, - GOING_TO_CAMPAIGN_PART2, - GOING_TO_MISSION_SELECT, - MISSION_SELECT, - CAMPAIGN, - GOING_TO_SINGLE_PLAYER_PROFILE, - SINGLE_PLAYER_PROFILE, - GOING_TO_LOADING_SCREEN, - QUITTING, - RESTARTING; - } - - public void hide() { - this.glueScreenLoop.stop(); - } - - public void dispose() { - if (this.rootFrame != null) { - this.rootFrame.dispose(); - } - } - - public boolean keyDown(final int keycode) { - if (this.focusUIFrame != null) { - this.focusUIFrame.keyDown(keycode); - } - return false; - } - - public boolean keyUp(final int keycode) { - if (this.focusUIFrame != null) { - this.focusUIFrame.keyUp(keycode); - } - return false; - } - - public boolean keyTyped(final char character) { - if (this.focusUIFrame != null) { - this.focusUIFrame.keyTyped(character); - } - return false; - } - - public void onReturnFromGame() { -// MenuUI.this.campaignMenu.setVisible(true); -// MenuUI.this.campaignBackButton.setVisible(true); -// MenuUI.this.missionSelectFrame.setVisible(true); -// MenuUI.this.campaignSelectFrame.setVisible(false); -// MenuUI.this.campaignWarcraftIIILogo.setVisible(true); -// MenuUI.this.campaignRootMenuUI.setVisible(false); -// MenuUI.this.currentMissionSelectMenuUI.setVisible(true); - switch (this.menuState) { - default: - case GOING_TO_MAIN_MENU: - case MAIN_MENU: - this.glueScreenLoop.stop(); - this.glueScreenLoop = this.mainMenuGlueScreenLoop; - this.glueScreenLoop.play(this.uiScene.audioContext, 0f, 0f, 0f); - this.menuScreen.setModel( - this.rootFrame.getSkinField("GlueSpriteLayerBackground_V" + WarsmashConstants.GAME_VERSION)); - this.rootFrame.setSpriteFrameModel(this.cursorFrame, this.rootFrame.getSkinField("Cursor")); - break; - case CAMPAIGN: - case MISSION_SELECT: - final String currentCampaignBackgroundModel = getCurrentBackgroundModel(); - final String currentCampaignAmbientSound = this.rootFrame - .trySkinField(this.currentCampaign.getAmbientSound()); - this.menuScreen.setModel(currentCampaignBackgroundModel); - this.glueScreenLoop.stop(); - this.glueScreenLoop = this.uiSounds.getSound(currentCampaignAmbientSound); - this.glueScreenLoop.play(this.uiScene.audioContext, 0f, 0f, 0f); - final DataTable skinData = this.rootFrame.getSkinData(); - final String cursorSkin = CRace.VALUES[this.currentCampaign.getCursor()].name(); - this.rootFrame.setSpriteFrameModel(this.cursorFrame, skinData.get(cursorSkin).getField("Cursor")); - break; - } -// MenuUI.this.campaignFade.setSequence("Death"); -// this.campaignFade.setVisible(true); -// this.menuState = MenuState.MISSION_SELECT; - } - - private String getCurrentBackgroundModel() { - final String background = this.currentCampaign.getBackground(); - final String versionedBackground = background + "_V" + WarsmashConstants.GAME_VERSION; - if (this.rootFrame.hasSkinField(versionedBackground)) { - return this.rootFrame.getSkinField(versionedBackground); - } - return this.rootFrame.getSkinField(background); - } - - private static final class LoadingMap { - - private final War3MapViewer viewer; - private final War3Map map; - private final War3MapW3i mapInfo; - - public LoadingMap(final War3MapViewer viewer, final War3Map map, final War3MapW3i mapInfo) { - this.viewer = viewer; - this.map = map; - this.mapInfo = mapInfo; - } - - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/PlayerProfile.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/PlayerProfile.java deleted file mode 100644 index 932da41c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/PlayerProfile.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui; - -public class PlayerProfile { - private final String name; - - public PlayerProfile(final String name) { - this.name = name; - } - - public String getName() { - return this.name; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/PlayerProfileManager.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/PlayerProfileManager.java deleted file mode 100644 index 5314e747..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/PlayerProfileManager.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui; - -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Preferences; - -public class PlayerProfileManager { - private static final String CURRENT_PROFILE = "CurrentProfile"; - private static final String PROFILE_COUNT = "ProfileCount"; - private final Preferences preferences; - private final List profiles; - private String currentProfile; - - public static PlayerProfileManager loadFromGdx() { - final Preferences preferences = Gdx.app.getPreferences("WarsmashWC3Engine"); - final int profileCount = preferences.getInteger(PROFILE_COUNT); - final List profiles = new ArrayList<>(); - for (int i = 0; i < profileCount; i++) { - final String name = preferences.getString("Profile" + i + "_Name"); - profiles.add(new PlayerProfile(name)); - } - final String currentProfile = preferences.getString(CURRENT_PROFILE, "WorldEdit"); - if (profiles.isEmpty()) { - final PlayerProfile worldEditDefaultProfile = new PlayerProfile("WorldEdit"); - saveProfile(preferences, profiles.size(), worldEditDefaultProfile); - profiles.add(worldEditDefaultProfile); - preferences.putInteger(PROFILE_COUNT, profiles.size()); - preferences.flush(); - } - return new PlayerProfileManager(preferences, profiles, currentProfile); - } - - public PlayerProfileManager(final Preferences preferences, final List profiles, - final String currentProfile) { - this.preferences = preferences; - this.profiles = profiles; - this.currentProfile = currentProfile; - } - - public List getProfiles() { - return this.profiles; - } - - public PlayerProfile addProfile(final String name) { - final PlayerProfile playerProfile = new PlayerProfile(name); - saveProfile(this.preferences, this.profiles.size(), playerProfile); - this.profiles.add(playerProfile); - this.preferences.putInteger(PROFILE_COUNT, this.profiles.size()); - this.preferences.flush(); - return playerProfile; - } - - public void setCurrentProfile(final String currentProfile) { - this.currentProfile = currentProfile; - this.preferences.putString(CURRENT_PROFILE, this.currentProfile); - this.preferences.flush(); - } - - public String getCurrentProfile() { - return this.currentProfile; - } - - public void saveAll() { - final int size = this.profiles.size(); - this.preferences.putInteger(PROFILE_COUNT, size); - this.preferences.putString(CURRENT_PROFILE, this.currentProfile); - for (int i = 0; i < size; i++) { - final PlayerProfile playerProfile = this.profiles.get(i); - saveProfile(this.preferences, i, playerProfile); - } - this.preferences.flush(); - } - - private static void saveProfile(final Preferences preferences, final int i, final PlayerProfile playerProfile) { - preferences.putString("Profile" + i + "_Name", playerProfile.getName()); - } - - public boolean hasProfile(final String text) { - for (final PlayerProfile profile : this.profiles) { - if (profile.getName().equals(text)) { - return true; - } - } - return false; - } - - public void removeProfile(final PlayerProfile profileToRemove) { - this.profiles.remove(profileToRemove); - saveAll(); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/QueueIcon.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/QueueIcon.java deleted file mode 100644 index fe090d2c..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/QueueIcon.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui; - -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.GlyphLayout; -import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.frames.AbstractRenderableFrame; -import com.etheller.warsmash.parsers.fdf.frames.TextureFrame; -import com.etheller.warsmash.parsers.fdf.frames.UIFrame; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.ClickableActionFrame; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.QueueIconListener; - -public class QueueIcon extends AbstractRenderableFrame implements ClickableActionFrame { - - private TextureFrame iconFrame; - private final QueueIconListener clickListener; - private float defaultWidth; - private float defaultHeight; - private final int queueIconIndexId; - - private String toolTip; - private String uberTip; - - public QueueIcon(final String name, final UIFrame parent, final QueueIconListener clickListener, - final int queueIconIndexId) { - super(name, parent); - this.clickListener = clickListener; - this.queueIconIndexId = queueIconIndexId; - } - - public void set(final TextureFrame iconFrame) { - this.iconFrame = iconFrame; - setVisible(true); - } - - public void clear() { - setVisible(false); - } - - public void setTexture(final Texture texture) { - this.iconFrame.setTexture(texture); - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - this.iconFrame.positionBounds(gameUI, viewport); - } - - @Override - protected void internalRender(final SpriteBatch batch, final BitmapFont baseFont, final GlyphLayout glyphLayout) { - this.iconFrame.render(batch, baseFont, glyphLayout); - } - - @Override - public UIFrame touchDown(final float screenX, final float screenY, final int button) { - if (isVisible() && this.renderBounds.contains(screenX, screenY)) { - return this; - } - return super.touchDown(screenX, screenY, button); - } - - @Override - public UIFrame touchUp(final float screenX, final float screenY, final int button) { - if (isVisible() && this.renderBounds.contains(screenX, screenY)) { - return this; - } - return super.touchUp(screenX, screenY, button); - } - - @Override - public void onClick(final int button) { - this.clickListener.queueIconClicked(this.queueIconIndexId); - } - - @Override - public void setWidth(final float width) { - this.defaultWidth = width; - super.setWidth(width); - } - - @Override - public void setHeight(final float height) { - this.defaultHeight = height; - super.setHeight(height); - } - - @Override - public void mouseDown(final GameUI gameUI, final Viewport uiViewport) { - this.iconFrame.setWidth(this.defaultWidth * 0.95f); - this.iconFrame.setHeight(this.defaultHeight * 0.95f); - positionBounds(gameUI, uiViewport); - } - - @Override - public void mouseUp(final GameUI gameUI, final Viewport uiViewport) { - this.iconFrame.setWidth(this.defaultWidth); - this.iconFrame.setHeight(this.defaultHeight); - positionBounds(gameUI, uiViewport); - } - - @Override - public void mouseEnter(final GameUI gameUI, final Viewport uiViewport) { - } - - @Override - public void mouseExit(final GameUI gameUI, final Viewport uiViewport) { - } - - @Override - public UIFrame getFrameChildUnderMouse(final float screenX, final float screenY) { - if (isVisible() && this.renderBounds.contains(screenX, screenY)) { - return this; - } - return null; - } - - public void setToolTip(final String toolTip) { - this.toolTip = toolTip; - } - - public void setUberTip(final String uberTip) { - this.uberTip = uberTip; - } - - @Override - public String getToolTip() { - return this.toolTip; - } - - @Override - public String getUberTip() { - return this.uberTip; - } - - @Override - public int getToolTipFoodCost() { - return 0; - } - - @Override - public int getToolTipGoldCost() { - return 0; - } - - @Override - public int getToolTipLumberCost() { - return 0; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/ActiveCommand.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/ActiveCommand.java deleted file mode 100644 index 269d9bde..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/ActiveCommand.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui.command; - -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CSimulation; -import com.etheller.warsmash.viewer5.handlers.w3x.simulation.CUnit; - -public interface ActiveCommand { - boolean finish(CSimulation simulation, CUnit selectedUnit, float mouseScreenX, float mouseScreenY); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/ClickableActionFrame.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/ClickableActionFrame.java deleted file mode 100644 index 25f1110f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/ClickableActionFrame.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui.command; - -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; - -public interface ClickableActionFrame extends ClickableFrame { - @Override - void mouseDown(final GameUI gameUI, final Viewport uiViewport); - - @Override - void mouseUp(final GameUI gameUI, final Viewport uiViewport); - - @Override - void onClick(int button); - - String getToolTip(); - - String getUberTip(); - - int getToolTipGoldCost(); - - int getToolTipLumberCost(); - - int getToolTipFoodCost(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/ClickableFrame.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/ClickableFrame.java deleted file mode 100644 index 15e90e93..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/ClickableFrame.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui.command; - -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.frames.UIFrame; - -public interface ClickableFrame extends UIFrame { - void mouseDown(final GameUI gameUI, final Viewport uiViewport); - - void mouseUp(final GameUI gameUI, final Viewport uiViewport); - - void mouseEnter(final GameUI gameUI, final Viewport uiViewport); - - void mouseExit(final GameUI gameUI, final Viewport uiViewport); - - void onClick(int button); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/CommandCardCommandListener.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/CommandCardCommandListener.java deleted file mode 100644 index fe003ab5..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/CommandCardCommandListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui.command; - -public interface CommandCardCommandListener { - void onClick(int abilityHandleId, int orderId, boolean rightClick); - - void openMenu(int orderId); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/CommandErrorListener.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/CommandErrorListener.java deleted file mode 100644 index d9b97fd3..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/CommandErrorListener.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui.command; - -public interface CommandErrorListener { - void showCommandError(String message); - - void showCantPlaceError(); - - void showNoFoodError(); - - void showInventoryFullError(); - - void showUnableToFindCoupleTargetError(); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/FocusableFrame.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/FocusableFrame.java deleted file mode 100644 index 0300fc3f..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/FocusableFrame.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui.command; - -import com.etheller.warsmash.parsers.fdf.frames.UIFrame; - -public interface FocusableFrame extends UIFrame { - boolean isFocusable(); - - void onFocusGained(); - - void onFocusLost(); - - boolean keyDown(int keycode); - - boolean keyUp(int keycode); - - boolean keyTyped(char character); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/QueueIconListener.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/QueueIconListener.java deleted file mode 100644 index b6a1537d..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/QueueIconListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui.command; - -public interface QueueIconListener { - void queueIconClicked(int index); -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/SettableCommandErrorListener.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/SettableCommandErrorListener.java deleted file mode 100644 index adeabcfa..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/command/SettableCommandErrorListener.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui.command; - -public class SettableCommandErrorListener implements CommandErrorListener { - private CommandErrorListener delegate; - - @Override - public void showCommandError(final String message) { - this.delegate.showCommandError(message); - } - - @Override - public void showCantPlaceError() { - this.delegate.showCantPlaceError(); - } - - @Override - public void showNoFoodError() { - this.delegate.showNoFoodError(); - } - - @Override - public void showInventoryFullError() { - this.delegate.showInventoryFullError(); - } - - public void setDelegate(final CommandErrorListener delegate) { - this.delegate = delegate; - } - - @Override - public void showUnableToFindCoupleTargetError() { - this.delegate.showUnableToFindCoupleTargetError(); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignButtonUI.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignButtonUI.java deleted file mode 100644 index becd2b10..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignButtonUI.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui.menu; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.frames.AbstractUIFrame; -import com.etheller.warsmash.parsers.fdf.frames.GlueButtonFrame; -import com.etheller.warsmash.parsers.fdf.frames.StringFrame; -import com.etheller.warsmash.parsers.fdf.frames.UIFrame; -import com.etheller.warsmash.viewer5.handlers.w3x.ui.command.ClickableFrame; - -public class CampaignButtonUI extends AbstractUIFrame implements ClickableFrame { - - private GlueButtonFrame buttonArt; - private boolean enabled = true; - private StringFrame headerText; - private StringFrame nameText; - private Color defaultNameColor; - private Color defaultHeaderColor; - private boolean artHighlight; - - public CampaignButtonUI(final String name, final UIFrame parent) { - super(name, parent); - } - - public void setButtonArt(final GlueButtonFrame buttonArt) { - this.buttonArt = buttonArt; - } - - public void setEnabled(final boolean enabled) { - this.enabled = enabled; - this.buttonArt.setEnabled(enabled); - } - - public void setOnClick(final Runnable onClick) { - this.buttonArt.setOnClick(onClick); - } - - @Override - public UIFrame touchUp(final float screenX, final float screenY, final int button) { - if (isVisible() && this.enabled && this.renderBounds.contains(screenX, screenY)) { - return this; - } - return super.touchUp(screenX, screenY, button); - } - - @Override - public UIFrame touchDown(final float screenX, final float screenY, final int button) { - if (isVisible() && this.enabled && this.renderBounds.contains(screenX, screenY)) { - return this; - } - return super.touchDown(screenX, screenY, button); - } - - @Override - public UIFrame getFrameChildUnderMouse(final float screenX, final float screenY) { - if (isVisible() && this.enabled && this.renderBounds.contains(screenX, screenY)) { - final UIFrame childResult = this.buttonArt.getFrameChildUnderMouse(screenX, screenY); - if (childResult != null) { - return childResult; - } - return this; - } - return super.getFrameChildUnderMouse(screenX, screenY); - } - - @Override - public void mouseDown(final GameUI gameUI, final Viewport uiViewport) { - this.buttonArt.mouseDown(gameUI, uiViewport); - } - - @Override - public void mouseUp(final GameUI gameUI, final Viewport uiViewport) { - this.buttonArt.mouseUp(gameUI, uiViewport); - } - - @Override - public void mouseEnter(final GameUI gameUI, final Viewport uiViewport) { - this.headerText.setColor(Color.WHITE); - this.nameText.setColor(Color.WHITE); - } - - @Override - public void mouseExit(final GameUI gameUI, final Viewport uiViewport) { - this.headerText.setColor(this.defaultHeaderColor); - this.nameText.setColor(this.defaultNameColor); - } - - @Override - public void onClick(final int button) { - this.buttonArt.onClick(button); - } - - public void setHeaderText(final StringFrame headerText) { - this.headerText = headerText; - this.defaultHeaderColor = headerText.getColor(); - } - - public void setNameText(final StringFrame nameText) { - this.nameText = nameText; - this.defaultNameColor = nameText.getColor(); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignMenuData.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignMenuData.java deleted file mode 100644 index f92d18e0..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignMenuData.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui.menu; - -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.graphics.Color; -import com.etheller.warsmash.units.Element; - -public class CampaignMenuData { - private final String header; - private final String name; - private final boolean defaultOpen; - private final String background; - private final int backgroundFogStyle; - private final Color backgroundFogColor; - private final float backgroundFogDensity; - private final float backgroundFogStart; - private final float backgroundFogEnd; - private final int cursor; - private final String ambientSound; - private final CampaignMission introCinematic; - private final CampaignMission openCinematic; - private final CampaignMission endCinematic; - private final List missions = new ArrayList<>(); - - public CampaignMenuData(final Element element) { - this.header = element.getField("Header"); - this.name = element.getField("Name"); - this.defaultOpen = element.getFieldValue("DefaultOpen") == 1; - this.background = element.getField("Background"); - this.backgroundFogStyle = element.getFieldValue("BackgroundFogStyle"); - this.backgroundFogColor = new Color(element.getFieldFloatValue("BackgroundFogColor", 1) / 255f, - element.getFieldFloatValue("BackgroundFogColor", 2) / 255f, - element.getFieldFloatValue("BackgroundFogColor", 3) / 255f, - element.getFieldFloatValue("BackgroundFogColor", 0) / 255f); - this.backgroundFogDensity = element.getFieldFloatValue("BackgroundFogDensity"); - this.backgroundFogStart = element.getFieldFloatValue("BackgroundFogStart"); - this.backgroundFogEnd = element.getFieldFloatValue("BackgroundFogEnd"); - this.cursor = element.getFieldValue("Cursor"); - this.ambientSound = element.getField("AmbientSound"); - this.introCinematic = readMission(element, "IntroCinematic"); - this.openCinematic = readMission(element, "OpenCinematic"); - this.endCinematic = readMission(element, "EndCinematic"); - int missionIndex = 0; - CampaignMission currentMission; - while ((currentMission = readMission(element, "Mission" + missionIndex)) != null) { - this.missions.add(currentMission); - missionIndex++; - } - } - - public String getHeader() { - return this.header; - } - - public String getName() { - return this.name; - } - - public boolean isDefaultOpen() { - return this.defaultOpen; - } - - public String getBackground() { - return this.background; - } - - public int getBackgroundFogStyle() { - return this.backgroundFogStyle; - } - - public Color getBackgroundFogColor() { - return this.backgroundFogColor; - } - - public float getBackgroundFogDensity() { - return this.backgroundFogDensity; - } - - public float getBackgroundFogStart() { - return this.backgroundFogStart; - } - - public float getBackgroundFogEnd() { - return this.backgroundFogEnd; - } - - public int getCursor() { - return this.cursor; - } - - public String getAmbientSound() { - return this.ambientSound; - } - - public CampaignMission getIntroCinematic() { - return this.introCinematic; - } - - public CampaignMission getOpenCinematic() { - return this.openCinematic; - } - - public CampaignMission getEndCinematic() { - return this.endCinematic; - } - - public List getMissions() { - return this.missions; - } - - private static CampaignMission readMission(final Element element, final String field) { - if ("".equals(element.getField(field, 0))) { - return null; - } - return new CampaignMission(element.getField(field, 0), element.getField(field, 1), element.getField(field, 2)); - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignMenuUI.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignMenuUI.java deleted file mode 100644 index a669eb65..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignMenuUI.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui.menu; - -import java.util.ArrayList; -import java.util.List; - -import com.badlogic.gdx.utils.viewport.Viewport; -import com.etheller.warsmash.parsers.fdf.GameUI; -import com.etheller.warsmash.parsers.fdf.datamodel.FramePoint; -import com.etheller.warsmash.parsers.fdf.frames.SetPoint; -import com.etheller.warsmash.parsers.fdf.frames.SimpleFrame; -import com.etheller.warsmash.parsers.fdf.frames.StringFrame; -import com.etheller.warsmash.parsers.fdf.frames.TextButtonFrame; -import com.etheller.warsmash.parsers.fdf.frames.UIFrame; - -public class CampaignMenuUI extends SimpleFrame { - private final GameUI rootFrame; - private final Viewport uiViewport; - private final List buttonUIs = new ArrayList<>(); - - public CampaignMenuUI(final String name, final UIFrame parent, final GameUI rootFrame, final Viewport uiViewport) { - super(name, parent); - this.rootFrame = rootFrame; - this.uiViewport = uiViewport; - } - - public void addButton(final String header, final String name, final Runnable onClick) { - final CampaignButtonUI campaignButtonUI = new CampaignButtonUI(null, this); - final TextButtonFrame campaignArrowButton = (TextButtonFrame) this.rootFrame - .createFrame("CampaignArrowButtonTemplate", campaignButtonUI, 0, 0); - campaignButtonUI.setButtonArt(campaignArrowButton); - campaignButtonUI.add(campaignArrowButton); - campaignArrowButton.addSetPoint(new SetPoint(FramePoint.TOPLEFT, campaignButtonUI, FramePoint.TOPLEFT, 0, 0)); - campaignArrowButton.setOnClick(onClick); - - final StringFrame headerText = (StringFrame) this.rootFrame.createFrame("StandardSmallTextTemplate", - campaignButtonUI, 0, 0); - this.rootFrame.setDecoratedText(headerText, header); - campaignButtonUI.add(headerText); - final StringFrame nameText = (StringFrame) this.rootFrame.createFrame("StandardValueTextTemplate", - campaignButtonUI, 0, 0); - this.rootFrame.setDecoratedText(nameText, name); - headerText.addSetPoint(new SetPoint(FramePoint.TOPLEFT, campaignArrowButton, FramePoint.TOPRIGHT, 0, 0)); - nameText.addSetPoint(new SetPoint(FramePoint.TOPLEFT, headerText, FramePoint.BOTTOMLEFT, 0, 0)); - campaignButtonUI.add(nameText); - campaignButtonUI.setHeaderText(headerText); - campaignButtonUI.setNameText(nameText); - campaignButtonUI.setHeight(GameUI.convertY(this.uiViewport, 0.032f)); - - add(campaignButtonUI); - this.buttonUIs.add(campaignButtonUI); - - } - - @Override - protected void innerPositionBounds(final GameUI gameUI, final Viewport viewport) { - super.innerPositionBounds(gameUI, viewport); - final float myHeight = this.renderBounds.height; - final int buttonCount = this.buttonUIs.size(); - final float buttonSpacing = Math.min(myHeight / buttonCount, GameUI.convertY(this.uiViewport, 0.056f)); - final float buttonsHeight = buttonSpacing * buttonCount; - final float expectedHeight = Math.min(buttonsHeight, myHeight); - final float yOffset = (myHeight - expectedHeight) / 2; - - UIFrame lastButton = null; - for (final CampaignButtonUI campaignButtonUI : this.buttonUIs) { - if (lastButton == null) { - campaignButtonUI.addSetPoint(new SetPoint(FramePoint.TOPLEFT, this, FramePoint.TOPLEFT, 0, -yOffset)); - campaignButtonUI.addSetPoint(new SetPoint(FramePoint.TOPRIGHT, this, FramePoint.TOPRIGHT, 0, -yOffset)); - } - else { - campaignButtonUI.addSetPoint( - new SetPoint(FramePoint.TOPLEFT, lastButton, FramePoint.TOPLEFT, 0, -buttonSpacing)); - campaignButtonUI.addSetPoint( - new SetPoint(FramePoint.TOPRIGHT, lastButton, FramePoint.TOPRIGHT, 0, -buttonSpacing)); - } - lastButton = campaignButtonUI; - } - super.innerPositionBounds(gameUI, viewport); - } - -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignMission.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignMission.java deleted file mode 100644 index d69f1491..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/menu/CampaignMission.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui.menu; - -public class CampaignMission { - private final String header; - private final String missionName; - private final String mapFilename; - - public CampaignMission(final String header, final String missionName, final String mapFilename) { - this.header = header; - this.missionName = missionName; - this.mapFilename = mapFilename; - } - - public String getHeader() { - return this.header; - } - - public String getMissionName() { - return this.missionName; - } - - public String getMapFilename() { - return this.mapFilename; - } -} diff --git a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/sound/KeyedSounds.java b/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/sound/KeyedSounds.java deleted file mode 100644 index ee8fab38..00000000 --- a/core/src/com/etheller/warsmash/viewer5/handlers/w3x/ui/sound/KeyedSounds.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.etheller.warsmash.viewer5.handlers.w3x.ui.sound; - -import java.util.HashMap; -import java.util.Map; - -import com.etheller.warsmash.datasources.DataSource; -import com.etheller.warsmash.units.DataTable; -import com.etheller.warsmash.viewer5.handlers.w3x.UnitSound; - -public class KeyedSounds { - private final DataTable uiSoundsTable; - private final DataSource dataSource; - private final Map keyToSound; - - public KeyedSounds(final DataTable uiSoundsTable, final DataSource dataSource) { - this.uiSoundsTable = uiSoundsTable; - this.dataSource = dataSource; - this.keyToSound = new HashMap<>(); - } - - public UnitSound getSound(final String key) { - UnitSound sound = this.keyToSound.get(key); - if (sound == null) { - sound = UnitSound.create(this.dataSource, this.uiSoundsTable, key, ""); - this.keyToSound.put(key, sound); - } - return sound; - } -} diff --git a/core/src/com/hiveworkshop/ReteraCASCUtils.java b/core/src/com/hiveworkshop/ReteraCASCUtils.java deleted file mode 100644 index 8599c371..00000000 --- a/core/src/com/hiveworkshop/ReteraCASCUtils.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.hiveworkshop; - -public class ReteraCASCUtils { - - public static boolean arraysEquals(final byte[] a, final int aFromIndex, final int aToIndex, final byte[] b, - final int bFromIndex, final int bToIndex) { - if (a == null) { - if (b == null) { - return true; - } else { - return false; - } - } - if (b == null) { - return false; - } - if ((aToIndex - aFromIndex) != (bToIndex - bFromIndex)) { - return false; - } - int j = bFromIndex; - for (int i = aFromIndex; i < aToIndex; i++) { - if (a[i] != b[j++]) { - return false; - } - } - return true; - } - - public static int arraysCompareUnsigned(final byte[] a, final int aFromIndex, final int aToIndex, final byte[] b, - final int bFromIndex, final int bToIndex) { - final int i = arraysMismatch(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex); - if ((i >= 0) && (i < Math.min(aToIndex - aFromIndex, bToIndex - bFromIndex))) { - return byteCompareUnsigned(a[aFromIndex + i], b[bFromIndex + i]); - } - return (aToIndex - aFromIndex) - (bToIndex - bFromIndex); - } - - private static int byteCompareUnsigned(final byte b, final byte c) { - return Integer.compare(b & 0xFF, c & 0xFF); - } - - private static int arraysMismatch(final byte[] a, final int aFromIndex, final int aToIndex, final byte[] b, - final int bFromIndex, final int bToIndex) { - final int aLength = aToIndex - aFromIndex; - final int bLength = bToIndex - bFromIndex; - for (int i = 0; (i < aLength) && (i < bLength); i++) { - if (a[aFromIndex + i] != b[bFromIndex + i]) { - return i; - } - } - return Math.min(aLength, bLength); - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/ConfigurationFile.java b/core/src/com/hiveworkshop/blizzard/casc/ConfigurationFile.java deleted file mode 100644 index a5f56dfd..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/ConfigurationFile.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.hiveworkshop.blizzard.casc; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.Map; -import java.util.Scanner; - -import com.hiveworkshop.blizzard.casc.nio.MalformedCASCStructureException; -import com.hiveworkshop.nio.ByteBufferInputStream; - -/** - * File containing CASC configuration information. This is basically a - * collection of keys with their assigned value. What the values mean depends on - * the purpose of the key. - */ -public class ConfigurationFile { - /** - * The name of the data folder containing the configuration files. - */ - public static final String CONFIGURATION_FOLDER_NAME = "config"; - - /** - * Character encoding used by configuration files. - */ - public static final Charset FILE_ENCODING = Charset.forName("UTF8"); - - /** - * Length of the configuration bucket folder names. - */ - public static final int BUCKET_NAME_LENGTH = 2; - - /** - * Number of configuration bucket folder tiers. - */ - public static final int BUCKET_TIERS = 2; - - /** - * Retrieve a configuration file from the data folder by its key. - * - * @param dataFolder Path of the CASC data folder. - * @param keyHex Key for configuration file as a hexadecimal string. - * @return The requested configuration file. - * @throws IOException If an exception occurs when retrieving the file. - */ - public static ConfigurationFile lookupConfigurationFile(final Path dataFolder, final String keyHex) - throws IOException { - Path file = dataFolder.resolve(CONFIGURATION_FOLDER_NAME); - for (int tier = 0; tier < BUCKET_TIERS; tier += 1) { - final int keyOffset = tier * BUCKET_NAME_LENGTH; - final String bucketFolderName = keyHex.substring(keyOffset, keyOffset + BUCKET_NAME_LENGTH); - file = file.resolve(bucketFolderName); - } - - file = file.resolve(keyHex); - - final ByteBuffer fileBuffer = ByteBuffer.wrap(Files.readAllBytes(file)); - - return new ConfigurationFile(fileBuffer); - } - - /** - * Underlying map holding the configuration data. - */ - private final Map configuration = new HashMap<>(); - - /** - * Construct a configuration file by decoding a file buffer. - * - * @param fileBuffer File buffer to decode from. - * @throws IOException If one or more IO errors occur. - */ - public ConfigurationFile(final ByteBuffer fileBuffer) throws IOException { - try (final ByteBufferInputStream fileStream = new ByteBufferInputStream(fileBuffer); - final Scanner lineScanner = new Scanner(new InputStreamReader(fileStream, FILE_ENCODING))) { - while (lineScanner.hasNextLine()) { - final String line = lineScanner.nextLine().trim(); - final int lineLength = line.indexOf('#'); - final String record; - if (lineLength != -1) { - record = line.substring(0, lineLength); - } else { - record = line; - } - - if (!record.equals("")) { - final int assignmentIndex = record.indexOf('='); - if (assignmentIndex == -1) { - throw new MalformedCASCStructureException( - "configuration file line contains record with no assignment"); - } - - final String key = record.substring(0, assignmentIndex).trim(); - final String value = record.substring(assignmentIndex + 1).trim(); - - if (configuration.putIfAbsent(key, value) != null) { - throw new MalformedCASCStructureException( - "configuration file contains duplicate key declarations"); - } - } - } - } - } - - /** - * Get the configuration defined by the file. - * - * @return Configuration map. - */ - public Map getConfiguration() { - return configuration; - } - -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/Key.java b/core/src/com/hiveworkshop/blizzard/casc/Key.java deleted file mode 100644 index 1a3f00c5..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/Key.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.hiveworkshop.blizzard.casc; - -import com.hiveworkshop.ReteraCASCUtils; -import com.hiveworkshop.lang.Hex; - -/** - * Class representing a CASC related key such as an encoding key. - *

- * When testing equality and comparing the length of the shortest key is used. - */ -public final class Key implements Comparable { - /** - * Key array. - */ - private final byte[] key; - - /** - * Wraps a byte array into a key. The array is used directly so must not be - * modified. - * - * @param key Key array. - */ - public Key(final byte[] key) { - this.key = key; - } - - /** - * Constructs a key from a hexadecimal key string. Bytes are order in the order - * they appear in the string, which can be considered big endian. - * - * @param keyString hexadecimal key form of key. - */ - public Key(final CharSequence key) { - this.key = Hex.decodeHex(key); - } - - @Override - public int compareTo(final Key o) { - final int commonLength = Math.min(key.length, o.key.length); - return ReteraCASCUtils.arraysCompareUnsigned(key, 0, commonLength, o.key, 0, commonLength); - } - - @Override - public boolean equals(final Object obj) { - if ((obj == null) || !(obj instanceof Key)) { - return false; - } - - final Key otherKey = (Key) obj; - final int commonLength = Math.min(key.length, otherKey.key.length); - if (!ReteraCASCUtils.arraysEquals(key, 0, commonLength, otherKey.key, 0, commonLength)) { - return false; - } - - return true; - } - - /** - * Return the wrapped key array for low level interaction. - * - * @return Key array. - */ - public byte[] getKey() { - return key.clone(); - } - - @Override - public int hashCode() { - throw new UnsupportedOperationException("key hash code not safe to use due to variable sizes between systems"); - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder((key.length + 1)); - Hex.stringBufferAppendHex(builder, key); - return builder.toString(); - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/StorageReference.java b/core/src/com/hiveworkshop/blizzard/casc/StorageReference.java deleted file mode 100644 index e0c76e67..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/StorageReference.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.hiveworkshop.blizzard.casc; - -import java.util.Map; - -/** - * A reference to a file extracted from a configuration file. - */ -public class StorageReference { - /** - * Suffix for sizes mapping entry in configuration files. - */ - private static final String SIZES_SUFFIX = "-size"; - - private final long storedSize; - private final long size; - private final Key encodingKey; - private final Key contentKey; - - /** - * Decodes a storage reference from a configuration file. - * - * @param name Name of reference. - * @param configuration Map of configuration file content. - */ - public StorageReference(final String name, final Map configuration) { - final String keys = configuration.get(name); - if (keys == null) { - throw new IllegalArgumentException("name does not exist in configuration"); - } - final String sizes = configuration.get(name + SIZES_SUFFIX); - if (sizes == null) { - throw new IllegalArgumentException("size missing in configuration"); - } - - final String[] keyStrings = keys.split(" "); - contentKey = new Key(keyStrings[0]); - encodingKey = new Key(keyStrings[1]); - - final String[] sizeStrings = sizes.split(" "); - size = Long.parseLong(sizeStrings[0]); - storedSize = Long.parseLong(sizeStrings[1]); - } - - /** - * Content key? - * - * @return Content key. - */ - public Key getContentKey() { - return contentKey; - } - - /** - * Encoding key used to lookup the file from CASC storage. - * - * @return Encoding key. - */ - public Key getEncodingKey() { - return encodingKey; - } - - /** - * File size. - * - * @return File size in bytes of the file. - */ - public long getSize() { - return size; - } - - /** - * Size of file content in CASC storage. - * - * @return Approximate byte usage of file in CASC storage. - */ - public long getStoredSize() { - return storedSize; - } - -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/info/FieldDataType.java b/core/src/com/hiveworkshop/blizzard/casc/info/FieldDataType.java deleted file mode 100644 index bd5cb54f..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/info/FieldDataType.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.hiveworkshop.blizzard.casc.info; - -/** - * Field data types to help with decoding values. - */ -public enum FieldDataType { - /** - * Field contains textual data. Size ignored. - */ - STRING, - /** - * Field is a decimal number. Size determines number of bytes used to represent - * it. - */ - DEC, - /** - * Field is a hexadecimal string. Size is number of bytes used to represent it - * with every 2 characters representing 1 byte. - */ - HEX, - /** - * This field type is currently not supported. - */ - UNSUPPORTED -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/info/FieldDescriptor.java b/core/src/com/hiveworkshop/blizzard/casc/info/FieldDescriptor.java deleted file mode 100644 index 599e20fa..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/info/FieldDescriptor.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.hiveworkshop.blizzard.casc.info; - -public class FieldDescriptor { - private static final int NAME_TERMINATOR = '!'; - private static final int DATA_TYPE_TERMINATOR = ':'; - - private final String name; - private FieldDataType dataType; - private final int size; - - /** - * Constructs a field descriptor from a field declaration string. - * - * @param encoded Field declaration string. - */ - public FieldDescriptor(final String encoded) { - final int nameEnd = encoded.indexOf(NAME_TERMINATOR); - if (nameEnd == -1) { - throw new IllegalArgumentException("missing name terminator"); - } - final int dataTypeEnd = encoded.indexOf(DATA_TYPE_TERMINATOR, nameEnd + 1); - if (dataTypeEnd == -1) { - throw new IllegalArgumentException("missing data type terminator"); - } - - name = encoded.substring(0, nameEnd); - - try { - dataType = FieldDataType.valueOf(encoded.substring(nameEnd + 1, dataTypeEnd)); - } catch (final IllegalArgumentException e) { - dataType = FieldDataType.UNSUPPORTED; - } - - size = Integer.parseInt(encoded.substring(dataTypeEnd + 1)); - } - - /** - * Get the field name. - * - * @return Name of the field. - */ - public String getName() { - return name; - } - - /** - * Get the field data type. - * - * @return Field data type. - */ - public FieldDataType getDataType() { - return dataType; - } - - /** - * Get the field size. Field size is the number of bytes required to represent - * the field in native form. A value of 0 means the field is variable length. - * - * @return Field size in bytes. - */ - public int getSize() { - return size; - } - -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/info/Info.java b/core/src/com/hiveworkshop/blizzard/casc/info/Info.java deleted file mode 100644 index 24bdaab7..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/info/Info.java +++ /dev/null @@ -1,149 +0,0 @@ -package com.hiveworkshop.blizzard.casc.info; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.NoSuchElementException; -import java.util.Scanner; - -import com.hiveworkshop.blizzard.casc.nio.MalformedCASCStructureException; -import com.hiveworkshop.nio.ByteBufferInputStream; - -/** - * Top level CASC information file containing configuration information and - * entry point references. - */ -public class Info { - /** - * Name of the CASC build info file located in the install root (parent of the - * data folder). - */ - public static final String BUILD_INFO_FILE_NAME = ".build.info"; - - /** - * Character encoding used by info files. - */ - public static final Charset FILE_ENCODING = Charset.forName("UTF8"); - - /** - * Field separator used by CASC info files. - */ - private static final String FIELD_SEPARATOR_REGEX = "\\|"; - - /** - * Helper method to separate a single line of info file into separate field - * strings. - * - * @param encodedLine Line of info file. - * @return Array of separate fields. - */ - private static String[] separateFields(final String encodedLine) { - return encodedLine.split(FIELD_SEPARATOR_REGEX); - } - - private final ArrayList fieldDescriptors = new ArrayList<>(); - - private final ArrayList> records = new ArrayList<>(); - - /** - * Construct an info file from an array of encoded lines. - * - * @param encodedLines Encoded lines. - * @throws IOException - */ - public Info(final ByteBuffer fileBuffer) throws IOException { - try (final ByteBufferInputStream fileStream = new ByteBufferInputStream(fileBuffer); - final Scanner lineScanner = new Scanner(new InputStreamReader(fileStream, FILE_ENCODING))) { - final String[] encodedFieldDescriptors = separateFields(lineScanner.nextLine()); - for (final String encodedFieldDescriptor : encodedFieldDescriptors) { - fieldDescriptors.add(new FieldDescriptor(encodedFieldDescriptor)); - } - - while (lineScanner.hasNextLine()) { - records.add(new ArrayList<>(Arrays.asList(separateFields(lineScanner.nextLine())))); - } - } catch (final NoSuchElementException e) { - throw new MalformedCASCStructureException("missing headers"); - } - } - - /** - * Retrieves a specific field of a record. - * - * @param recordIndex Record index to lookup. - * @param fieldIndex Field index to retrieve of record. - * @return Field value. - * @throws IndexOutOfBoundsException When recordIndex or fieldIndex are out of - * bounds. - */ - public String getField(final int recordIndex, final int fieldIndex) { - return records.get(recordIndex).get(fieldIndex); - } - - /** - * Retrieves a specific field of a record. - * - * @param recordIndex Record index to lookup. - * @param fieldName Field name to retrieve of record. - * @return Field value, or null if field does not exist. - * @throws IndexOutOfBoundsException When recordIndex is out of bounds. - */ - public String getField(final int recordIndex, final String fieldName) { - // resolve field - final int fieldIndex = getFieldIndex(fieldName); - if (fieldIndex == -1) { - // field does not exist - return null; - } - - return getField(recordIndex, fieldIndex); - } - - /** - * Get the number of fields that make up each record. - * - * @return Field count. - */ - public int getFieldCount() { - return fieldDescriptors.size(); - } - - /** - * Retrieve the field descriptor of a field index. - * - * @param fieldIndex Field index to retrieve descriptor from. - * @return Field descriptor for field index. - */ - public FieldDescriptor getFieldDescriptor(final int fieldIndex) { - return fieldDescriptors.get(fieldIndex); - } - - /** - * Lookup the index of a named field. Returns the field index for the field name - * if found, otherwise returns -1. - * - * @param name Name of the field to find. - * @return Field index of field. - */ - public int getFieldIndex(final String name) { - for (int i = 0; i < fieldDescriptors.size(); i += 1) { - if (fieldDescriptors.get(i).getName().equals(name)) { - return i; - } - } - - return -1; - } - - /** - * Get the number of records in this file. - * - * @return Record count. - */ - public int getRecordCount() { - return records.size(); - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/io/WarcraftIIICASC.java b/core/src/com/hiveworkshop/blizzard/casc/io/WarcraftIIICASC.java deleted file mode 100644 index 2dbd8a54..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/io/WarcraftIIICASC.java +++ /dev/null @@ -1,291 +0,0 @@ -package com.hiveworkshop.blizzard.casc.io; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -import com.hiveworkshop.blizzard.casc.ConfigurationFile; -import com.hiveworkshop.blizzard.casc.info.Info; -import com.hiveworkshop.blizzard.casc.nio.MalformedCASCStructureException; -import com.hiveworkshop.blizzard.casc.storage.Storage; -import com.hiveworkshop.blizzard.casc.vfs.VirtualFileSystem; -import com.hiveworkshop.blizzard.casc.vfs.VirtualFileSystem.PathResult; - -/** - * A convenient access to locally stored Warcraft III data files. Intended for - * use with CASC versions of Warcraft III including classic and Reforged. - */ -public class WarcraftIIICASC implements AutoCloseable { - /** - * File system view for accessing files from file paths. - */ - public class FileSystem { - /** - * Private constructor, currently not used. - */ - private FileSystem() { - - } - - /** - * Enumerate all file paths contained in this file system. - *

- * This operation might be quite slow. - * - * @return A list containing all file paths contained in this file system. - * @throws IOException In an exception occurs when resolving files. - */ - public List enumerateFiles() throws IOException { - final List pathResults = vfs.getAllFiles(); - final ArrayList filePathStrings = new ArrayList(pathResults.size()); - - for (final PathResult pathResult : pathResults) { - filePathStrings.add(pathResult.getPath()); - } - - return filePathStrings; - } - - /** - * Test if the specified file path is a file. - * - * @param filePath Path of file to test. - * @return True if path represents a file, otherwise false. - * @throws IOException In an exception occurs when resolving files. - */ - public boolean isFile(final String filePath) throws IOException { - final byte[][] pathFragments = VirtualFileSystem.convertFilePath(filePath); - try { - final PathResult resolveResult = vfs.resolvePath(pathFragments); - return resolveResult.isFile(); - } catch (final FileNotFoundException e) { - return false; - } - } - - /** - * Test if the specified file path is available from local storage. - * - * @param filePath Path of file to test. - * @return True if path represents a file inside local storage, otherwise false. - * @throws IOException In an exception occurs when resolving files. - */ - public boolean isFileAvailable(final String filePath) throws IOException { - final byte[][] pathFragments = VirtualFileSystem.convertFilePath(filePath); - final PathResult resolveResult = vfs.resolvePath(pathFragments); - return resolveResult.existsInStorage(); - } - - /** - * Test if the specified file path is a nested file system. - *

- * If true a file system can be resolved from the file path which files can be - * resolved from more efficiently than from higher up file systems. - *

- * Support for this feature is not yet implemented. Please resolve everything - * from the root. - * - * @param filePath Path of file to test. - * @return True if file is a nested file system, otherwise false. - * @throws IOException In an exception occurs when resolving files. - */ - public boolean isNestedFileSystem(final String filePath) throws IOException { - final byte[][] pathFragments = VirtualFileSystem.convertFilePath(filePath); - try { - final PathResult resolveResult = vfs.resolvePath(pathFragments); - return resolveResult.isTVFS(); - } catch (final FileNotFoundException e) { - return false; - } - } - - /** - * Fully read the file at the specified file path into memory. - * - * @param filePath File path of file to read. - * @return Buffer containing file data. - * @throws IOException If an error occurs when reading the file. - */ - public ByteBuffer readFileData(final String filePath) throws IOException { - final byte[][] pathFragments = VirtualFileSystem.convertFilePath(filePath); - final PathResult resolveResult = vfs.resolvePath(pathFragments); - - if (!resolveResult.isFile()) { - throw new FileNotFoundException("the specified file path does not resolve to a file"); - } else if (!resolveResult.existsInStorage()) { - throw new FileNotFoundException("the specified file is not in local storage"); - } - - final ByteBuffer fileBuffer = resolveResult.readFile(null); - fileBuffer.flip(); - return fileBuffer; - } - } - - /** - * Name of the CASC data folder used by Warcraft III. - */ - private static final String WC3_DATA_FOLDER_NAME = "Data"; - - /** - * Warcraft III build information. - */ - private final Info buildInfo; - - /** - * Detected active build information record. - */ - private final int activeInfoRecord; - - /** - * Warcraft III build configuration. - */ - private final ConfigurationFile buildConfiguration; - - /** - * Warcraft III CASC data folder path. - */ - private final Path dataPath; - - /** - * Warcraft III local storage. - */ - private final Storage localStorage; - - /** - * TVFS file system to resolve file paths. - */ - private final VirtualFileSystem vfs; - - /** - * Construct an interface to the CASC local storage used by Warcraft III. Can be - * used to read data files from the local storage. - *

- * The active build record is used for local storage details. - *

- * Install folder is the Warcraft III installation folder where the - * .build.info file is located. For example - * C:\Program Files (x86)\Warcraft III. - *

- * Memory mapped IO can be used instead of conventional channel based IO. This - * should improve IO performance considerably by avoiding excessive memory copy - * operations and system calls. However it may place considerable strain on the - * Java VM application virtual memory address space. As such memory mapping - * should only be used with large address aware VMs. - * - * @param installFolder Warcraft III installation folder. - * @param useMemoryMapping If memory mapped IO should be used to read file data. - * @throws IOException If an exception occurs while mounting. - */ - public WarcraftIIICASC(final Path installFolder, final boolean useMemoryMapping) throws IOException { - final Path infoFilePath = installFolder.resolve(Info.BUILD_INFO_FILE_NAME); - buildInfo = new Info(ByteBuffer.wrap(Files.readAllBytes(infoFilePath))); - - final int recordCount = buildInfo.getRecordCount(); - if (recordCount < 1) { - throw new MalformedCASCStructureException("build info contains no records"); - } - - // resolve the active record - final int activeFiledIndex = buildInfo.getFieldIndex("Active"); - if (activeFiledIndex == -1) { - throw new MalformedCASCStructureException("build info contains no active field"); - } - int recordIndex = 0; - for (; recordIndex < recordCount; recordIndex += 1) { - if (Integer.parseInt(buildInfo.getField(recordIndex, activeFiledIndex)) == 1) { - break; - } - } - if (recordIndex == recordCount) { - throw new MalformedCASCStructureException("build info contains no active record"); - } - activeInfoRecord = recordIndex; - - // resolve build configuration file - final int buildKeyFieldIndex = buildInfo.getFieldIndex("Build Key"); - if (buildKeyFieldIndex == -1) { - throw new MalformedCASCStructureException("build info contains no build key field"); - } - final String buildKey = buildInfo.getField(activeInfoRecord, buildKeyFieldIndex); - - // resolve data folder - dataPath = installFolder.resolve(WC3_DATA_FOLDER_NAME); - if (!Files.isDirectory(dataPath)) { - throw new MalformedCASCStructureException("data folder is missing"); - } - - // resolve build configuration file - buildConfiguration = ConfigurationFile.lookupConfigurationFile(dataPath, buildKey); - - // mounting local storage - localStorage = new Storage(dataPath, false, useMemoryMapping); - - // mounting virtual file system - VirtualFileSystem vfs = null; - try { - vfs = new VirtualFileSystem(localStorage, buildConfiguration.getConfiguration()); - } finally { - if (vfs == null) { - // storage must be closed to prevent resource leaks - localStorage.close(); - } - } - this.vfs = vfs; - } - - @Override - public void close() throws IOException { - localStorage.close(); - } - - /** - * Returns the active record index of the build information. This is the index - * of the record that is mounted. - * - * @return Active record index of build information. - */ - public int getActiveRecordIndex() { - return activeInfoRecord; - } - - /** - * Returns the active branch name which is currently mounted. - *

- * This might reflect the locale that has been cached to local storage. - * - * @return Branch name. - * @throws IOException If no branch information is available. - */ - public String getBranch() throws IOException { - // resolve branch - final int branchFieldIndex = buildInfo.getFieldIndex("Branch"); - if (branchFieldIndex == -1) { - throw new MalformedCASCStructureException("build info contains no branch field"); - } - return buildInfo.getField(activeInfoRecord, branchFieldIndex); - } - - /** - * Returns the build information of the archive. - * - * @return Build information. - */ - public Info getBuildInfo() { - return buildInfo; - } - - /** - * Get the root file system of Warcraft III. From this all locally stored data - * files can be accessed. - * - * @return Root file system containing all files. - */ - public FileSystem getRootFileSystem() { - return new FileSystem(); - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/io/package-info.java b/core/src/com/hiveworkshop/blizzard/casc/io/package-info.java deleted file mode 100644 index bbc9c075..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/io/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * High level APIs for CASC file system interaction. - *

- * These are intended for ease of use, dealing away with many of the low level details required to work with CASC. - */ -package com.hiveworkshop.blizzard.casc.io; \ No newline at end of file diff --git a/core/src/com/hiveworkshop/blizzard/casc/nio/HashMismatchException.java b/core/src/com/hiveworkshop/blizzard/casc/nio/HashMismatchException.java deleted file mode 100644 index dbba7c3a..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/nio/HashMismatchException.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.hiveworkshop.blizzard.casc.nio; - -import java.io.IOException; - -public class HashMismatchException extends IOException { - private static final long serialVersionUID = -7133950344327038673L; - - public HashMismatchException() { - } - - public HashMismatchException(String message) { - super(message); - } - -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/nio/LittleHashBlockProcessor.java b/core/src/com/hiveworkshop/blizzard/casc/nio/LittleHashBlockProcessor.java deleted file mode 100644 index fbbf2951..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/nio/LittleHashBlockProcessor.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.hiveworkshop.blizzard.casc.nio; - -import java.io.IOException; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -public class LittleHashBlockProcessor { - - /** - * - * @param encoded - * @return The size of the block - * @throws MalformedCASCStructureException If file is malformed. - */ - public int processBlock(final ByteBuffer encoded) throws MalformedCASCStructureException { - encoded.order(ByteOrder.LITTLE_ENDIAN); - final int length; - final int expectedHash; - try { - length = encoded.getInt(); - expectedHash = encoded.getInt(); - } catch (final BufferUnderflowException e) { - throw new MalformedCASCStructureException("little hash block header out of bounds"); - } - - final int actualHash = expectedHash; // TODO generate actual hash - - if (actualHash != expectedHash) { - return -length; - } - - return length; - } - - /** - * Get a little hash guarded block from the source buffer. - * - * @param sourceBuffer Buffer to retrieve block from. - * @return Guarded block. - * @throws MalformedCASCStructureException If the file is malformed. - * @throws HashMismatchException If the block is corrupt. - */ - public ByteBuffer getBlock(final ByteBuffer sourceBuffer) throws IOException { - final ByteBuffer workingBuffer = sourceBuffer.slice(); - - workingBuffer.order(ByteOrder.LITTLE_ENDIAN); - final int length; - final int expectedHash; - try { - length = workingBuffer.getInt(); - expectedHash = workingBuffer.getInt(); - } catch (final BufferUnderflowException e) { - throw new MalformedCASCStructureException("little hash block header out of bounds"); - } - - if (workingBuffer.remaining() < length) { - throw new MalformedCASCStructureException("little hash block out of bounds"); - } - - workingBuffer.limit(workingBuffer.position() + length); - final ByteBuffer blockBuffer = workingBuffer.slice(); - workingBuffer.position(workingBuffer.limit()); - workingBuffer.limit(workingBuffer.capacity()); - - final int actualHash = expectedHash; // TODO generate actual hash - - if (actualHash != expectedHash) { - throw new HashMismatchException("little hash block"); - } - - sourceBuffer.position(sourceBuffer.position() + workingBuffer.position()); - - return blockBuffer; - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/nio/MalformedCASCStructureException.java b/core/src/com/hiveworkshop/blizzard/casc/nio/MalformedCASCStructureException.java deleted file mode 100644 index 0e0db775..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/nio/MalformedCASCStructureException.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.hiveworkshop.blizzard.casc.nio; - -import java.io.IOException; - -public class MalformedCASCStructureException extends IOException { - private static final long serialVersionUID = -5323382445554597608L; - - public MalformedCASCStructureException(String message) { - super(message); - } - - public MalformedCASCStructureException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/storage/BLTEContent.java b/core/src/com/hiveworkshop/blizzard/casc/storage/BLTEContent.java deleted file mode 100644 index e2d84268..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/storage/BLTEContent.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.hiveworkshop.blizzard.casc.storage; - -import java.io.IOException; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import com.hiveworkshop.blizzard.casc.nio.MalformedCASCStructureException; -import com.hiveworkshop.lang.Hex; - -/** - * BLTE content entry, used to decode BLTE file data that follows it. - */ -public class BLTEContent { - /** - * BLTE content identifier. - */ - private static final ByteBuffer IDENTIFIER = ByteBuffer.wrap(new byte[] { 'B', 'L', 'T', 'E' }); - - /** - * Hash length in bytes. Should be fetched from appropriate digest length. - */ - private static final int HASH_LENGTH = 16; - - private final long compressedSize; - private final long decompressedSize; - private final byte[] hash = new byte[HASH_LENGTH]; - - public BLTEContent(final ByteBuffer blteBuffer) { - compressedSize = Integer.toUnsignedLong(blteBuffer.getInt()); - decompressedSize = Integer.toUnsignedLong(blteBuffer.getInt()); - blteBuffer.get(hash); - } - - public static BLTEContent[] decodeContent(final ByteBuffer storageBuffer) throws IOException { - final ByteBuffer contentBuffer = storageBuffer.slice(); - - // check identifier - - if ((contentBuffer.remaining() < IDENTIFIER.remaining()) - || !contentBuffer.limit(IDENTIFIER.remaining()).equals(IDENTIFIER)) { - throw new MalformedCASCStructureException("missing BLTE identifier"); - } - - // decode header - - contentBuffer.limit(contentBuffer.capacity()); - contentBuffer.position(contentBuffer.position() + IDENTIFIER.remaining()); - contentBuffer.order(ByteOrder.BIG_ENDIAN); - - final long headerSize; - try { - headerSize = Integer.toUnsignedLong(contentBuffer.getInt()); - } catch (final BufferUnderflowException e) { - throw new MalformedCASCStructureException("header preamble goes out of bounds"); - } - - if (headerSize == 0L) { - storageBuffer.position(storageBuffer.position() + contentBuffer.position()); - return new BLTEContent[0]; - } else if (headerSize > contentBuffer.capacity()) { - throw new MalformedCASCStructureException("BLTE header extends beyond storage buffer bounds"); - } - - contentBuffer.limit((int) headerSize); - final ByteBuffer blteBuffer = contentBuffer.slice(); - blteBuffer.order(ByteOrder.BIG_ENDIAN); - contentBuffer.position(contentBuffer.limit()); - contentBuffer.limit(contentBuffer.capacity()); - - final byte flags; - final int entryCount; - try { - flags = blteBuffer.get(); - if (flags != 0xF) { - throw new MalformedCASCStructureException("unknown flags"); - } - // BE24 read - final int be24Bytes = 3; - final ByteBuffer be24Buffer = ByteBuffer.allocate(Integer.BYTES); - be24Buffer.order(ByteOrder.BIG_ENDIAN); - blteBuffer.get(be24Buffer.array(), Integer.BYTES - be24Bytes, be24Bytes); - entryCount = be24Buffer.getInt(0); - if (entryCount == 0) { - throw new MalformedCASCStructureException("explicit zero entry count"); - } - } catch (final BufferUnderflowException e) { - throw new MalformedCASCStructureException("header goes out of bounds"); - } - - final BLTEContent[] content = new BLTEContent[entryCount]; - - for (int index = 0; index < content.length; index += 1) { - content[index] = new BLTEContent(blteBuffer); - } - - if (blteBuffer.hasRemaining()) { - throw new MalformedCASCStructureException("unprocessed BLTE bytes"); - } - - storageBuffer.position(storageBuffer.position() + contentBuffer.position()); - - return content; - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("BLTEChunk{compressedSize="); - builder.append(compressedSize); - builder.append(", decompressedSize="); - builder.append(decompressedSize); - builder.append(", hash="); - Hex.stringBufferAppendHex(builder, hash); - builder.append("}"); - - return builder.toString(); - } - - public long getCompressedSize() { - return compressedSize; - } - - public long getDecompressedSize() { - return decompressedSize; - } - - public byte[] getHash() { - return hash.clone(); - } - -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/storage/BankStream.java b/core/src/com/hiveworkshop/blizzard/casc/storage/BankStream.java deleted file mode 100644 index c7b67f8b..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/storage/BankStream.java +++ /dev/null @@ -1,185 +0,0 @@ -package com.hiveworkshop.blizzard.casc.storage; - -import java.io.EOFException; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.nio.BufferOverflowException; -import java.nio.ByteBuffer; -import java.util.zip.DataFormatException; -import java.util.zip.Inflater; - -import com.hiveworkshop.blizzard.casc.Key; -import com.hiveworkshop.blizzard.casc.nio.MalformedCASCStructureException; - -/** - * Allows high level access to stored file data banks. These data banks can be - * assembled using higher level logic into a continuous file. - */ -public class BankStream { - private final StorageContainer container; - private final BLTEContent[] content; - private final ByteBuffer streamBuffer; - private int bank = 0; - private boolean hasBanks; - - /** - * Constructs a bank steam from the given buffer. An optional key can be used to - * verify the right file is being processed. If a key is provided it is assumed - * the remaining size of the buffer exactly matches the container size. - * - * @param storageBuffer Storage buffer, as specified by an index file. - * @param key File encoding key to check contents with, or null if no - * such check is required. - * @throws IOException If an exception occurs during decoding of the - * storageBuffer. - */ - public BankStream(final ByteBuffer storageBuffer, final Key encodingKey) throws IOException { - ByteBuffer streamBuffer = storageBuffer.slice(); - container = new StorageContainer(streamBuffer); - if ((encodingKey != null) && !container.getKey().equals(encodingKey)) { - throw new MalformedCASCStructureException("container encoding key mismatch"); - } - - final int storageSize = (int) container.getSize(); - final int storageSizeDiff = Integer.compare(streamBuffer.capacity(), storageSize); - - if (storageSizeDiff < 0) { - throw new MalformedCASCStructureException("container buffer smaller than container"); - } else if ((encodingKey != null) && (storageSizeDiff != 0)) { - throw new MalformedCASCStructureException("container buffer size mismatch"); - } else if (storageSizeDiff > 0) { - // resize buffer to match file - final int streamPos = streamBuffer.position(); - streamBuffer.limit(storageSize); - streamBuffer.position(0); - streamBuffer = streamBuffer.slice(); - streamBuffer.position(streamPos); - } - - if (streamBuffer.hasRemaining()) { - content = BLTEContent.decodeContent(streamBuffer); - hasBanks = true; - } else { - content = null; - hasBanks = false; - } - - this.streamBuffer = streamBuffer; - storageBuffer.position(storageBuffer.position() + streamBuffer.capacity()); - } - - /** - * Get the length of the next bank in bytes. - * - * @return Length of bank in bytes. - * @throws EOFException If there are no more banks in this stream. - */ - public long getNextBankLength() throws EOFException { - if (!hasNextBank()) { - throw new EOFException("no more banks to decode"); - } - - return content.length != 0 ? content[bank].getDecompressedSize() : streamBuffer.remaining(); - } - - /** - * Decode a bank from the stream. The bank buffer must be large enough to - * receive the bank data as specified by getNextBankLength. A null buffer will - * automatically allocate one large enough. The position of the bank buffer will - * be advanced as appropriate, potentially allowing for many banks to be fetched - * in sequence. - * - * @param bankBuffer Buffer to receive bank data. - * @return If null then a new suitable buffer, otherwise bankBuffer. - * @throws IOException If something goes wrong during bank extraction. - * @throws EOFException If there are no more banks in this stream. - */ - public ByteBuffer getBank(ByteBuffer bankBuffer) throws IOException { - if (!hasNextBank()) { - throw new EOFException("no more banks to decode"); - } - - if (content.length != 0) { - final BLTEContent blteEntry = content[bank]; - final long encodedSize = blteEntry.getCompressedSize(); - final long decodedSize = blteEntry.getDecompressedSize(); - - if (streamBuffer.remaining() < encodedSize) { - throw new MalformedCASCStructureException("encoded data beyond end of file"); - } else if (bankBuffer == null) { - if (decodedSize > Integer.MAX_VALUE) { - throw new MalformedCASCStructureException("bank too large for Java to manipulate"); - } - bankBuffer = ByteBuffer.allocate((int) decodedSize); - } else if (bankBuffer.remaining() < decodedSize) { - throw new BufferOverflowException(); - } - - final ByteBuffer encodedBuffer = ((ByteBuffer) streamBuffer.slice().limit((int) encodedSize)).slice(); - final ByteBuffer decodedBuffer = ((ByteBuffer) bankBuffer.slice().limit((int) decodedSize)).slice(); - final byte[] intermediateEncodedCopy = new byte[encodedBuffer.remaining()]; - final byte[] intermediateDecodedCopy = new byte[decodedBuffer.remaining()]; - - final char encodingMode = (char) encodedBuffer.get(); - switch (encodingMode) { - case 'N': - // uncompressed data - if (encodedBuffer.remaining() != decodedSize) { - throw new MalformedCASCStructureException("not enough uncompressed bytes"); - } - decodedBuffer.put(encodedBuffer); - break; - case 'Z': - // zlib compressed data - final Inflater zlib = new Inflater(); - encodedBuffer.get(intermediateEncodedCopy, 0, encodedBuffer.remaining()); - zlib.setInput(intermediateEncodedCopy); - final int resultSize; - try { - resultSize = zlib.inflate(intermediateDecodedCopy); - decodedBuffer.put(intermediateDecodedCopy, 0, resultSize); - } catch (final DataFormatException e) { - throw new MalformedCASCStructureException("zlib inflate exception", e); - } - if (resultSize != decodedSize) { - throw new MalformedCASCStructureException("not enough bytes generated: " + resultSize + "B"); - } else if (!zlib.finished()) { - throw new MalformedCASCStructureException("unfinished inflate operation"); - } - break; - default: - throw new UnsupportedEncodingException("unsupported encoding mode: " + encodingMode); - } - - streamBuffer.position(streamBuffer.position() + encodedBuffer.position()); - bankBuffer.position(bankBuffer.position() + decodedBuffer.position()); - - bank += 1; - if (bank == content.length) { - hasBanks = false; - } - } else { - // this logic is guessed and requires confirmation - if (bankBuffer == null) { - bankBuffer = ByteBuffer.allocate(streamBuffer.remaining()); - } else if (bankBuffer.remaining() < streamBuffer.remaining()) { - throw new MalformedCASCStructureException("bank buffer too small"); - } - - bankBuffer.put(streamBuffer); - hasBanks = false; - } - - return bankBuffer; - } - - /** - * Returns true while one or more banks are remaining to be streamed. Only valid - * if hasBanks returns true. - * - * @return True if another bank can be decoded, otherwise false. - */ - public boolean hasNextBank() { - return hasBanks; - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/storage/IndexEntry.java b/core/src/com/hiveworkshop/blizzard/casc/storage/IndexEntry.java deleted file mode 100644 index 02ff05cc..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/storage/IndexEntry.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.hiveworkshop.blizzard.casc.storage; - -import com.hiveworkshop.blizzard.casc.Key; - -public class IndexEntry { - /** - * Index encoding key. - */ - private final Key key; - - /** - * Logical offset of storage container. - */ - private final long dataOffset; - - /** - * Size of storage container. - */ - private final long fileSize; - - public IndexEntry(final byte[] key, final long dataOffset, final long fileSize) { - this.key = new Key(key); - this.dataOffset = dataOffset; - this.fileSize = fileSize; - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("IndexEntry{key="); - builder.append(key); - builder.append(", dataOffset="); - builder.append(dataOffset); - builder.append(", fileSize="); - builder.append(fileSize); - builder.append("}"); - - return builder.toString(); - } - - public long getDataOffset() { - return dataOffset; - } - - public long getFileSize() { - return fileSize; - } - - public String getKeyString() { - return key.toString(); - } - - public Key getKey() { - return key; - } - - public int compareKey(final Key otherKey) { - return otherKey.compareTo(key); - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/storage/IndexFile.java b/core/src/com/hiveworkshop/blizzard/casc/storage/IndexFile.java deleted file mode 100644 index e61d9b66..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/storage/IndexFile.java +++ /dev/null @@ -1,159 +0,0 @@ -package com.hiveworkshop.blizzard.casc.storage; - -import java.io.IOException; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.ArrayList; -import java.util.Collections; - -import com.hiveworkshop.blizzard.casc.Key; -import com.hiveworkshop.blizzard.casc.nio.HashMismatchException; -import com.hiveworkshop.blizzard.casc.nio.LittleHashBlockProcessor; -import com.hiveworkshop.blizzard.casc.nio.MalformedCASCStructureException; - -public class IndexFile { - /** - * Alignment of the index entry block in bytes. - */ - private static final int ENTRY_BLOCK_ALIGNMENT = 16; - - private int bucketIndex; - - private int fileSizeLength; - - private int dataOffsetLength; - - private int encodingKeyLength; - - private int dataFileSizeBits; - - private long dataSizeMaximum; - - private final ArrayList entries = new ArrayList<>(); - - public IndexFile(final ByteBuffer fileBuffer) throws IOException { - decode(fileBuffer); - } - - private void decode(final ByteBuffer fileBuffer) throws IOException { - final ByteBuffer sourceBuffer = fileBuffer.slice(); - - // decode header - - final LittleHashBlockProcessor hashBlockProcessor = new LittleHashBlockProcessor(); - - final ByteBuffer headerBuffer; - try { - headerBuffer = hashBlockProcessor.getBlock(sourceBuffer); - } catch (final HashMismatchException e) { - throw new MalformedCASCStructureException("header block corrupt", e); - } - - headerBuffer.order(ByteOrder.LITTLE_ENDIAN); - - try { - if (headerBuffer.getShort() != 7) { - // possibly malformed - } - bucketIndex = Byte.toUnsignedInt(headerBuffer.get()); - if (headerBuffer.get() != 0) { - // possibly malformed - } - fileSizeLength = Byte.toUnsignedInt(headerBuffer.get()); - dataOffsetLength = Byte.toUnsignedInt(headerBuffer.get()); - encodingKeyLength = Byte.toUnsignedInt(headerBuffer.get()); - dataFileSizeBits = Byte.toUnsignedInt(headerBuffer.get()); - dataSizeMaximum = headerBuffer.getLong(); - } catch (final BufferUnderflowException e) { - throw new MalformedCASCStructureException("header block too small"); - } - - // decode entries - - final int entriesAlignmentMask = ENTRY_BLOCK_ALIGNMENT - 1; - sourceBuffer.position((sourceBuffer.position() + entriesAlignmentMask) & ~entriesAlignmentMask); - - final ByteBuffer entryBuffer; - try { - entryBuffer = hashBlockProcessor.getBlock(sourceBuffer); - } catch (final HashMismatchException e) { - throw new MalformedCASCStructureException("entries block corrupt", e); - } - - final int entryLength = fileSizeLength + dataOffsetLength + encodingKeyLength; - final int entryCount = entryBuffer.remaining() / entryLength; - - entries.ensureCapacity(entryCount); - - final ByteBuffer decodeDataOffsetBuffer = ByteBuffer.allocate(Long.BYTES); - final int decodeDataOffsetOffset = Long.BYTES - dataOffsetLength; - final ByteBuffer decodeFileSizeBuffer = ByteBuffer.allocate(Long.BYTES); - decodeFileSizeBuffer.order(ByteOrder.LITTLE_ENDIAN); - for (int i = 0; i < entryCount; i += 1) { - final byte[] key = new byte[encodingKeyLength]; - entryBuffer.get(key); - - entryBuffer.get(decodeDataOffsetBuffer.array(), decodeDataOffsetOffset, dataOffsetLength); - final long dataOffset = decodeDataOffsetBuffer.getLong(0); - - entryBuffer.get(decodeFileSizeBuffer.array(), 0, fileSizeLength); - final long fileSize = decodeFileSizeBuffer.getLong(0); - - // this can be used to detect special cross linking entries - // if (getIndexNumber(entry.key, entry.key.length) != bucketIndex); - // System.out.println("Bad key index: index=" + i + ", entry=" + entry + ", - // bucket=" + getIndexNumber(entry.key, entry.key.length)); - - entries.add(new IndexEntry(key, dataOffset, fileSize)); - } - - if (entryBuffer.hasRemaining()) { - throw new MalformedCASCStructureException("unable to fully process entries block"); - } - - fileBuffer.position(fileBuffer.position() + sourceBuffer.position()); - } - - public int getBucketIndex() { - return bucketIndex; - } - - public int getStoreIndex(final long dataOffset) { - return (int) (dataOffset >>> dataFileSizeBits); - } - - public long getStoreOffset(final long dataOffset) { - return dataOffset & ((1L << dataFileSizeBits) - 1L); - } - - public long getDataSizeMaximum() { - return dataSizeMaximum; - } - - public IndexEntry getEntry(final Key encodingKey) { - final int index = Collections.binarySearch(entries, encodingKey, (left, right) -> { - if ((left instanceof IndexEntry) && (right instanceof Key)) { - final IndexEntry entry = (IndexEntry) left; - final Key ekey = (Key) right; - return entry.getKey().compareTo(ekey); - } - throw new IllegalArgumentException("binary search comparing in inverted order"); - }); - - return index >= 0 ? entries.get(index) : null; - } - - public IndexEntry getEntry(final int index) { - return entries.get(index); - } - - public int getEntryCount() { - return entries.size(); - } - - public int getEncodingKeyLength() { - return encodingKeyLength; - } - -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/storage/Storage.java b/core/src/com/hiveworkshop/blizzard/casc/storage/Storage.java deleted file mode 100644 index a5b75d27..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/storage/Storage.java +++ /dev/null @@ -1,334 +0,0 @@ -package com.hiveworkshop.blizzard.casc.storage; - -import java.io.EOFException; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.MappedByteBuffer; -import java.nio.channels.ClosedChannelException; -import java.nio.channels.FileChannel; -import java.nio.channels.FileChannel.MapMode; -import java.nio.file.DirectoryStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; - -import com.hiveworkshop.blizzard.casc.Key; -import com.hiveworkshop.blizzard.casc.nio.MalformedCASCStructureException; - -/** - * Main data storage of a CASC archive. It consists of index files which point - * to storage containers in data files. - */ -public class Storage implements AutoCloseable { - /** - * The name of the data folder containing the configuration files. - */ - public static final String DATA_FOLDER_NAME = "data"; - - /** - * Number of index files used by a data store. - */ - private static final int INDEX_COUNT = 16; - - /** - * Usual number of copies of a specific index located in the folder. This is an - * estimate only used to increase search performance and will not effect - * results. - */ - private static final int INDEX_COPIES = 2; - - /** - * File extension used by storage index files. - */ - public static final String INDEX_FILE_EXTENSION = "idx"; - - /** - * File name of data files. 3 character extension is the index. - */ - public static final String DATA_FILE_NAME = "data"; - - /** - * Largest permitted data file index. - */ - public static final int DATA_FILE_INDEX_MAXIMUM = 999; - - /** - * Extension length used by data files. Defined by the length needed to store - * DATA_FILE_INDEX_MAXIMUM as a decimal string. - */ - public static final int DATA_FILE_EXTENSION_LENGTH = 3; - - /** - * Converts an encoding key into an index file number. - * - * @param encodingKey Input encoding key. - * @param keyLength Length of key to be processed. - * @return Index number. - */ - public static int getBucketIndex(final byte[] encodingKey, final int keyLength) { - int accumulator = 0; - for (int i = 0; i < keyLength; i += 1) { - accumulator ^= encodingKey[i]; - } - final int nibbleMask = (1 << 4) - 1; - return (accumulator & nibbleMask) ^ ((accumulator >> 4) & nibbleMask); - } - - private Path folder; - - private final HashMap channelMap = new HashMap<>(); - - private final IndexFile[] indicies = new IndexFile[INDEX_COUNT]; - - /** - * Index file versions loaded. Possibly useful for debugging. - */ - private final long[] idxVersions = new long[INDEX_COUNT]; - - /** - * Used to track closed status of the store. - */ - private boolean closed = false; - - private boolean useMemoryMapping; - - private int encodingKeyLength; - - /** - * Construct a storage object from the provided data folder. - *

- * Using memory mapping should give the best performance. However some platforms - * or file systems might not support it. - * - * @param dataFolder Path of the CASC data folder. - * @param useOld Use other (old?) version of index files. - * @param useMemoryMapping If IO should be memory mapped. - * @throws IOException If there was a problem loading from the data folder. - */ - public Storage(final Path dataFolder, final boolean useOld, final boolean useMemoryMapping) throws IOException { - folder = dataFolder.resolve(DATA_FOLDER_NAME); - this.useMemoryMapping = useMemoryMapping; - - final ArrayList indexFiles = new ArrayList(INDEX_COUNT * INDEX_COPIES); - try (final DirectoryStream indexFileIterator = Files.newDirectoryStream(folder, - "*." + INDEX_FILE_EXTENSION)) { - for (final Path indexFile : indexFileIterator) { - indexFiles.add(indexFile); - } - } - - class IndexFileNameMeta { - private Path filePath; - private int index; - private long version; - } - - final HashMap> metaMap = new HashMap>( - INDEX_COUNT); - - for (final Path indexFile : indexFiles) { - final String fileName = indexFile.getFileName().toString(); - - final IndexFileNameMeta fileMeta = new IndexFileNameMeta(); - fileMeta.filePath = indexFile; - fileMeta.index = Integer.parseUnsignedInt(fileName.substring(0, 2), 16); - fileMeta.version = Long.parseUnsignedLong(fileName.substring(2, 10), 16); - - ArrayList bucketList = metaMap.get(fileMeta.index); - if (bucketList == null) { - bucketList = new ArrayList<>(); - metaMap.put(fileMeta.index, bucketList); - } - - bucketList.add(fileMeta); - } - - Comparator bucketOrder = (left, right) -> { - return (int) (left.version - right.version); - }; - if (!useOld) { - bucketOrder = Collections.reverseOrder(bucketOrder); - } - - for (int index = 0; index < indicies.length; index += 1) { - final ArrayList bucketList = metaMap.get(index); - if (bucketList == null) { - throw new MalformedCASCStructureException("storage index file missing"); - } - - Collections.sort(bucketList, bucketOrder); - - final IndexFileNameMeta fileMeta = bucketList.get(0); - idxVersions[index] = fileMeta.version; - indicies[index] = new IndexFile(loadFileFully(fileMeta.filePath)); - } - - // resolve index key length being used - int index = 0; - encodingKeyLength = indicies[index++].getEncodingKeyLength(); - for (; index < indicies.length; index += 1) { - if (encodingKeyLength != indicies[index].getEncodingKeyLength()) { - throw new MalformedCASCStructureException("inconsistent encoding key length between index files"); - } - } - } - - @Override - public synchronized void close() throws IOException { - if (closed) { - return; - } - - IOException exception = null; - for (final Map.Entry channelEntry : channelMap.entrySet()) { - try { - channelEntry.getValue().close(); - } catch (final IOException e) { - if (exception != null) { - exception.addSuppressed(e); - } else { - exception = e; - } - } - } - - closed = true; - - if (exception != null) { - throw new IOException("IOExceptions occured during closure", exception); - } - } - - public boolean hasBanks(final Key encodingKey) { - final int bucketIndex = getBucketIndex(encodingKey.getKey(), encodingKeyLength); - final IndexFile index = indicies[bucketIndex]; - final IndexEntry indexEntry = index.getEntry(encodingKey); - - return indexEntry != null; - } - - public BankStream getBanks(final Key encodingKey) throws IOException { - final int bucketIndex = getBucketIndex(encodingKey.getKey(), encodingKeyLength); - final IndexFile index = indicies[bucketIndex]; - final IndexEntry indexEntry = index.getEntry(encodingKey); - - if (indexEntry == null) { - throw new FileNotFoundException("encoding key not in store indicies"); - } - - final long dataOffset = indexEntry.getDataOffset(); - final int storeIndex = index.getStoreIndex(dataOffset); - final long storeOffset = index.getStoreOffset(dataOffset); - - final ByteBuffer storageBuffer = getStorageBuffer(storeIndex, storeOffset, indexEntry.getFileSize()); - - return new BankStream(storageBuffer, indexEntry.getKey()); - } - - private synchronized FileChannel getDataFileChannel(final int index) throws IOException { - if (closed) { - throw new ClosedChannelException(); - } - - FileChannel fileChannel = channelMap.get(index); - if (fileChannel == null) { - if (index > DATA_FILE_INDEX_MAXIMUM) { - throw new MalformedCASCStructureException("storage data file index too large"); - } - - final StringBuilder builder = new StringBuilder(); - builder.append(DATA_FILE_NAME); - builder.append('.'); - final String extensionNumber = Integer.toUnsignedString(index); - final int extensionZeroCount = DATA_FILE_EXTENSION_LENGTH - extensionNumber.length(); - for (int i = 0; i < extensionZeroCount; i += 1) { - builder.append('0'); - } - builder.append(extensionNumber); - - final Path filePath = folder.resolve(builder.toString()); - fileChannel = FileChannel.open(filePath, StandardOpenOption.READ); - channelMap.put(index, fileChannel); - } - - return fileChannel; - } - - /** - * Fetch a buffer from storage. - * - * @param index Data file index. - * @param offset Data file offset. - * @param length Requested buffer length. - * @return Storage buffer. - * @throws IOException If a problem occurs when preparing the storage buffer. - */ - private ByteBuffer getStorageBuffer(final int index, final long offset, final long length) throws IOException { - final FileChannel fileChannel = getDataFileChannel(index); - if (length > Integer.MAX_VALUE) { - throw new MalformedCASCStructureException("data buffer too large to process"); - } - - final ByteBuffer storageBuffer; - if (useMemoryMapping) { - final MappedByteBuffer mappedBuffer = fileChannel.map(MapMode.READ_ONLY, offset, length); - mappedBuffer.load(); - storageBuffer = mappedBuffer; - } else { - storageBuffer = ByteBuffer.allocate((int) length); - while (storageBuffer.hasRemaining() - && (fileChannel.read(storageBuffer, offset + storageBuffer.position()) != -1)) { - ; - } - - if (storageBuffer.hasRemaining()) { - throw new EOFException("unexpected end of file"); - } - storageBuffer.clear(); - } - - return storageBuffer; - } - - /** - * Loads a file fully into memory. Memory mapping is used if allowed. - * - * @param file Path of file to load into memory. - * @return File buffered into memory. - * @throws IOException If an IO exception occurs. - */ - private ByteBuffer loadFileFully(final Path file) throws IOException { - final ByteBuffer fileBuffer; - try (final FileChannel channel = FileChannel.open(file, StandardOpenOption.READ)) { - final long fileLength = channel.size(); - if (fileLength > Integer.MAX_VALUE) { - throw new MalformedCASCStructureException("file too large to process"); - } - - if (useMemoryMapping) { - final MappedByteBuffer mappedBuffer = channel.map(MapMode.READ_ONLY, 0, fileLength); - mappedBuffer.load(); - fileBuffer = mappedBuffer; - } else { - fileBuffer = ByteBuffer.allocate((int) fileLength); - while (fileBuffer.hasRemaining() && (channel.read(fileBuffer, fileBuffer.position()) != -1)) { - ; - } - - if (fileBuffer.hasRemaining()) { - throw new EOFException("unexpected end of file"); - } - fileBuffer.clear(); - } - } - - return fileBuffer; - } - -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/storage/StorageContainer.java b/core/src/com/hiveworkshop/blizzard/casc/storage/StorageContainer.java deleted file mode 100644 index 8bd08851..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/storage/StorageContainer.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.hiveworkshop.blizzard.casc.storage; - -import java.io.IOException; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -import com.hiveworkshop.blizzard.casc.Key; -import com.hiveworkshop.blizzard.casc.nio.HashMismatchException; -import com.hiveworkshop.blizzard.casc.nio.MalformedCASCStructureException; - -/** - * High level storage container representing a storage entry. - */ -public class StorageContainer { - /** - * Size of storage encoding key in bytes. - */ - private static final int ENCODING_KEY_SIZE = 16; - - /** - * Container encoding key. - */ - private Key key; - private long size; - private short flags; - - public StorageContainer(final ByteBuffer storageBuffer) throws IOException { - final ByteBuffer containerBuffer = storageBuffer.slice(); - containerBuffer.order(ByteOrder.LITTLE_ENDIAN); - - // key is in reversed byte order - final int checksumA; - final int checksumB; - try { - final byte[] keyArray = new byte[ENCODING_KEY_SIZE]; - final int keyEnd = containerBuffer.position() + keyArray.length; - for (int writeIndex = 0, readIndex = keyEnd - - 1; writeIndex < keyArray.length; writeIndex += 1, readIndex -= 1) { - keyArray[writeIndex] = containerBuffer.get(readIndex); - } - containerBuffer.position(keyEnd); - - key = new Key(keyArray); - size = Integer.toUnsignedLong(containerBuffer.getInt()); - flags = containerBuffer.getShort(); - - checksumA = containerBuffer.getInt(); - checksumB = containerBuffer.getInt(); - } catch (final BufferUnderflowException e) { - throw new MalformedCASCStructureException("storage buffer too small"); - } - - final int computedA = checksumA; // TODO compute this - final int computedB = checksumB; // TODO compute this - if (checksumA != computedA) { - throw new HashMismatchException("container checksum A mismatch"); - } - if (checksumB != computedB) { - throw new HashMismatchException("container checksum B mismatch"); - } - - storageBuffer.position(storageBuffer.position() + containerBuffer.position()); - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("FileEntry{key="); - builder.append(key); - builder.append(", size="); - builder.append(size); - builder.append(", flags="); - builder.append(Integer.toBinaryString(flags)); - builder.append("}"); - - return builder.toString(); - } - - public long getSize() { - return size; - } - - public short getFlags() { - return flags; - } - - public Key getKey() { - return key; - } - -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/trash/LocalDataFiles.java b/core/src/com/hiveworkshop/blizzard/casc/trash/LocalDataFiles.java deleted file mode 100644 index 51f348c1..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/trash/LocalDataFiles.java +++ /dev/null @@ -1,343 +0,0 @@ -package com.hiveworkshop.blizzard.casc.trash; - -import java.io.Closeable; -import java.io.EOFException; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.channels.FileChannel; -import java.nio.file.DirectoryStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.zip.DataFormatException; -import java.util.zip.Inflater; - -import com.hiveworkshop.blizzard.casc.nio.HashMismatchException; -import com.hiveworkshop.blizzard.casc.nio.MalformedCASCStructureException; -import com.hiveworkshop.lang.Hex; - -public class LocalDataFiles implements Closeable { - private static final int FRAGMENTATION_SIZE_BITS = 30; - - private static final int FILE_ENTRY_HEADER_SIZE = 30; - - private static final byte[] BLTE_MIME = new byte[] { 'B', 'L', 'T', 'E' }; - - private final HashMap dataFiles = new HashMap(); - - public LocalDataFiles(final Path dataPath) throws IOException { - mountDataFiles(dataPath); - } - - public void mountDataFiles(final Path dataPath) throws IOException { - try (final DirectoryStream dataFileIterator = Files.newDirectoryStream(dataPath, "data.*")) { - for (final Path dataFile : dataFileIterator) { - System.out.println(dataFile); - final String fileName = dataFile.getFileName().toString(); - final int number = Integer.parseInt(fileName.substring(5, 8)); - dataFiles.put(number, FileChannel.open(dataFile, StandardOpenOption.READ)); - } - - } catch (final Exception e) { - close(); - } - } - - @Override - public void close() throws IOException { - IOException exception = null; - for (final Map.Entry dataFileEntry : dataFiles.entrySet()) { - try { - dataFileEntry.getValue().close(); - } catch (final IOException e) { - exception = e; - } - } - - if (exception != null) { - throw new IOException("one or more IOExceptions occured during closure", exception); - } - } - - public FileEntry getFileEntry(final LocalIndexFile.IndexEntry indexEntry) throws IOException { - final ByteBuffer fileHeader = ByteBuffer.allocate(FILE_ENTRY_HEADER_SIZE); - - final long dataOffset = indexEntry.getDataOffset(); - final int dataFile = (int) (dataOffset >>> FRAGMENTATION_SIZE_BITS); - final long fileOffset = dataOffset & (1L << FRAGMENTATION_SIZE_BITS) - 1L; - final FileChannel channel = dataFiles.get(dataFile); - if (channel.read(fileHeader, fileOffset) != fileHeader.limit()) { - throw new EOFException("unexpected incomplete read"); - } - fileHeader.flip(); - - fileHeader.order(ByteOrder.LITTLE_ENDIAN); - final FileEntry fileEntry = new FileEntry(); - fileEntry.dataFile = dataFile; - fileEntry.fileOffset = fileOffset; - - // key is in reversed byte order - final byte[] key = new byte[16]; - int keyPos = fileHeader.position() + key.length; - fileHeader.position(keyPos); - for (int i = 0; i < key.length; i++) { - key[i] = fileHeader.get(--keyPos); - } - if (!indexEntry.compareKey(key)) { - throw new HashMismatchException("file entry does not match index entry"); - } - fileEntry.key = key; - - fileEntry.size = Integer.toUnsignedLong(fileHeader.getInt()); - fileEntry.flags = fileHeader.getShort(); - - // TODO actually check these - final int ChecksumA = fileHeader.getInt(); - final int ChecksumB = fileHeader.getInt(); - - return fileEntry; - } - - public BLTEChunk[] getBLTEChunks(final FileEntry file) throws IOException { - final FileChannel channel = dataFiles.get(file.dataFile); - final ByteBuffer blteDeclareHeader = ByteBuffer.allocate(8); - - final long blteOffset = file.fileOffset + FILE_ENTRY_HEADER_SIZE; - long currentOffset = blteOffset; - final long blteLimit = file.fileOffset + file.size; - if (blteLimit - currentOffset < blteDeclareHeader.capacity()) { - throw new MalformedCASCStructureException("BLTE header extends beyond file limits"); - } - - currentOffset += channel.read(blteDeclareHeader, currentOffset); - if (blteDeclareHeader.hasRemaining()) { - throw new EOFException("unexpected incomplete read"); - } - blteDeclareHeader.flip(); - - blteDeclareHeader.order(ByteOrder.BIG_ENDIAN); - final byte[] mime = new byte[BLTE_MIME.length]; - blteDeclareHeader.get(mime); - if (!Arrays.equals(mime, BLTE_MIME)) { - throw new MalformedCASCStructureException("expected BLTE mime"); - } - final long headerSize = Integer.toUnsignedLong(blteDeclareHeader.getInt()); - - BLTEChunk[] chunks; - if (headerSize > 0) { - final long headerBodySize = headerSize - blteDeclareHeader.capacity(); - - if (headerBodySize > Integer.MAX_VALUE) { - throw new MalformedCASCStructureException("BLTE header too large to process"); - } else if (blteOffset + headerBodySize > blteLimit) { - throw new MalformedCASCStructureException("BLTE header extends beyond file limits"); - } - - final ByteBuffer blteHeaderBody = ByteBuffer.allocate((int) headerBodySize); - - currentOffset += channel.read(blteHeaderBody, currentOffset); - if (blteHeaderBody.hasRemaining()) { - throw new EOFException("unexpected incomplete read"); - } - blteHeaderBody.flip(); - - blteHeaderBody.order(ByteOrder.BIG_ENDIAN); - blteHeaderBody.mark(); - final byte flags = blteHeaderBody.get(); - if (flags != 0xF) { - throw new MalformedCASCStructureException("unknown BLTE flags"); - } - // BE24 read - blteHeaderBody.reset(); - blteHeaderBody.put((byte) 0); - blteHeaderBody.reset(); - - final int chunkCount = blteHeaderBody.getInt(); - if (chunkCount < 0) { - throw new MalformedCASCStructureException("BLTE chunk count too large to process"); - } else if (chunkCount == 0) { - throw new MalformedCASCStructureException("invalid BLTE chunk count"); - } - - chunks = new BLTEChunk[chunkCount]; - long decompressedOffset = 0; - long compressedOffset = currentOffset - file.fileOffset; - for (int i = 0; i < chunks.length; i += 1) { - final long compressedSize = Integer.toUnsignedLong(blteHeaderBody.getInt()); - final long decompressedSize = Integer.toUnsignedLong(blteHeaderBody.getInt()); - final byte[] checksumHash = new byte[16]; - blteHeaderBody.get(checksumHash); - - final BLTEChunk chunk = new BLTEChunk(); - chunk.compressedOffset = compressedOffset; - chunk.compressedSize = compressedSize; - chunk.decompressedOffset = decompressedOffset; - chunk.decompressedSize = decompressedSize; - chunk.checksumHash = checksumHash; - chunks[i] = chunk; - - compressedOffset += compressedSize; - decompressedOffset += decompressedSize; - } - } else { - chunks = new BLTEChunk[1]; - final BLTEChunk chunk = new BLTEChunk(); - chunk.compressedOffset = currentOffset - file.fileOffset; - chunk.compressedSize = blteLimit - currentOffset; - chunk.decompressedOffset = 0; - - // unknown values, needs experimentation - chunk.decompressedSize = chunk.compressedSize; - chunk.checksumHash = null; - chunks[0] = chunk; - } - return chunks; - } - - public ByteBuffer getBLTEData(final FileEntry file, final BLTEChunk chunk, ByteBuffer blteDataBuffer) - throws IOException { - if (chunk.compressedSize + chunk.compressedOffset > file.size) { - throw new MalformedCASCStructureException("BLTE data extends beyond file data"); - } - - if (blteDataBuffer == null || blteDataBuffer.remaining() < chunk.compressedSize) { - blteDataBuffer = ByteBuffer.allocate((int) chunk.compressedSize); - } - - final int blteDataBufferLimit = blteDataBuffer.limit(); - blteDataBuffer.limit(blteDataBuffer.position() + (int) chunk.compressedSize); - try { - final FileChannel channel = dataFiles.get(file.dataFile); - channel.read(blteDataBuffer, file.fileOffset + chunk.compressedOffset); - if (blteDataBuffer.hasRemaining()) { - throw new EOFException("unexpected incomplete read"); - } - } finally { - blteDataBuffer.position(blteDataBuffer.limit()); - blteDataBuffer.limit(blteDataBufferLimit); - } - - return blteDataBuffer; - } - - public ByteBuffer getFileData(final BLTEChunk chunk, final ByteBuffer blteDataBuffer, ByteBuffer fileDataBuffer) - throws IOException { - if (blteDataBuffer.remaining() < chunk.compressedSize) { - throw new MalformedCASCStructureException("BLTE data too small"); - } - - if (fileDataBuffer == null || fileDataBuffer.remaining() < chunk.decompressedSize) { - fileDataBuffer = ByteBuffer.allocate((int) chunk.decompressedSize); - } - - final int blteDataBufferLimit = blteDataBuffer.limit(); - final int fileDataBufferLimit = fileDataBuffer.limit(); - blteDataBuffer.limit(blteDataBuffer.position() + (int) chunk.compressedSize); - fileDataBuffer.limit(fileDataBuffer.position() + (int) chunk.decompressedSize); - try { - final char encodingMode = (char) blteDataBuffer.get(); - switch (encodingMode) { - case 'N': - if (blteDataBuffer.remaining() != chunk.decompressedSize) { - throw new MalformedCASCStructureException("not enough uncompressed bytes"); - } - fileDataBuffer.put(blteDataBuffer); - break; - case 'Z': - final Inflater zlib = new Inflater(); - zlib.setInput(blteDataBuffer.array(), blteDataBuffer.position(), blteDataBuffer.remaining()); - int resultSize; - try { - resultSize = zlib.inflate(fileDataBuffer.array(), fileDataBuffer.position(), - fileDataBuffer.remaining()); - } catch (final DataFormatException e) { - throw new MalformedCASCStructureException("zlib inflate exception", e); - } - if (resultSize != chunk.decompressedSize) { - throw new MalformedCASCStructureException("not enough bytes generated: " + resultSize + "B"); - } else if (!zlib.finished()) { - throw new MalformedCASCStructureException("unfinished inflate operation"); - } - break; - default: - throw new UnsupportedEncodingException("unsupported encoding mode: " + encodingMode); - } - } finally { - blteDataBuffer.position(blteDataBuffer.limit()); - blteDataBuffer.limit(blteDataBufferLimit); - fileDataBuffer.position(fileDataBuffer.limit()); - fileDataBuffer.limit(fileDataBufferLimit); - } - - return fileDataBuffer; - } - - public static class FileEntry { - private byte[] key; - private int dataFile; - private long fileOffset; - private long size; - private short flags; - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("FileEntry{key=0x"); - Hex.stringBufferAppendHex(builder, key); - builder.append(", dataFile="); - builder.append(dataFile); - builder.append(", fileOffset="); - builder.append(fileOffset); - builder.append(", size="); - builder.append(size); - builder.append(", flags="); - builder.append(Integer.toBinaryString(flags)); - builder.append("}"); - - return builder.toString(); - } - - public boolean hasBLTE() { - return size > FILE_ENTRY_HEADER_SIZE; - } - } - - public static class BLTEChunk { - private long compressedOffset; - private long compressedSize; - private long decompressedOffset; - private long decompressedSize; - private byte[] checksumHash; - - public long getSize() { - return decompressedSize; - } - - public long getOffset() { - return decompressedOffset; - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("BLTEChunk{compressedSize="); - builder.append(compressedSize); - builder.append(", decompressedSize="); - builder.append(decompressedSize); - builder.append(", compressedOffset="); - builder.append(compressedOffset); - builder.append(", decompressedOffset="); - builder.append(decompressedOffset); - builder.append(", checksumHash=0x"); - Hex.stringBufferAppendHex(builder, checksumHash); - builder.append("}"); - - return builder.toString(); - } - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/trash/LocalIndexFile.java b/core/src/com/hiveworkshop/blizzard/casc/trash/LocalIndexFile.java deleted file mode 100644 index d0ae1365..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/trash/LocalIndexFile.java +++ /dev/null @@ -1,171 +0,0 @@ -package com.hiveworkshop.blizzard.casc.trash; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.ArrayList; - -import com.hiveworkshop.ReteraCASCUtils; -import com.hiveworkshop.blizzard.casc.nio.HashMismatchException; -import com.hiveworkshop.blizzard.casc.nio.LittleHashBlockProcessor; -import com.hiveworkshop.lang.Hex; - -public class LocalIndexFile { - private byte bucketIndex; - - private byte entryFileSizeLength; - - private byte entryDataOffsetLength; - - private byte entryKeyLength; - - private byte dataFileSizeBits; - - private long dataSizeMaximum; - - private final ArrayList entries = new ArrayList<>(); - - public static int getIndexNumber(final byte[] key, final int keyLength) { - int accumulator = 0; - for (int i = 0; i < keyLength; i += 1) { - accumulator ^= key[i]; - } - final int nibbleMask = (1 << 4) - 1; - return accumulator & nibbleMask ^ accumulator >> 4 & nibbleMask; - } - - public LocalIndexFile(final ByteBuffer encodedFileBuffer) throws IOException { - decode(encodedFileBuffer); - } - - public void decode(final ByteBuffer encodedFileBuffer) throws IOException { - final LittleHashBlockProcessor hashBlockProcessor = new LittleHashBlockProcessor(); - final int fileLength = encodedFileBuffer.limit(); - - final int headerLength = hashBlockProcessor.processBlock(encodedFileBuffer); - if (headerLength < 0) { - throw new HashMismatchException("index header corrupt"); - } - - encodedFileBuffer.limit(encodedFileBuffer.position() + headerLength); - encodedFileBuffer.order(ByteOrder.LITTLE_ENDIAN); - - if (encodedFileBuffer.getShort() != 7) { - // possibly malformed - } - bucketIndex = encodedFileBuffer.get(); - if (encodedFileBuffer.get() != 0) { - // possibly malformed - } - entryFileSizeLength = encodedFileBuffer.get(); - entryDataOffsetLength = encodedFileBuffer.get(); - entryKeyLength = encodedFileBuffer.get(); - dataFileSizeBits = encodedFileBuffer.get(); - dataSizeMaximum = encodedFileBuffer.getLong(); - - encodedFileBuffer.limit(fileLength); - final int entriesAlignmentMask = (1 << 4) - 1; - encodedFileBuffer.position((encodedFileBuffer.position() + entriesAlignmentMask) & ~entriesAlignmentMask); - - final int entriesLength = hashBlockProcessor.processBlock(encodedFileBuffer); - if (entriesLength < 0) { - throw new HashMismatchException("index entries corrupt"); - } - - encodedFileBuffer.limit(encodedFileBuffer.position() + entriesLength); - final int entryLength = entryFileSizeLength + entryDataOffsetLength + entryKeyLength; - final int entryCount = encodedFileBuffer.remaining() / entryLength; - - entries.ensureCapacity(entryCount); - - final ByteBuffer decodeDataOffsetBuffer = ByteBuffer.allocate(Long.BYTES); - final int decodeDataOffsetOffset = Long.BYTES - entryDataOffsetLength; - final ByteBuffer decodeFileSizeBuffer = ByteBuffer.allocate(Long.BYTES); - decodeFileSizeBuffer.order(ByteOrder.LITTLE_ENDIAN); - for (int i = 0; i < entryCount; i += 1) { - final IndexEntry entry = new IndexEntry(); - - entry.key = new byte[entryKeyLength]; - encodedFileBuffer.get(entry.key); - - encodedFileBuffer.get(decodeDataOffsetBuffer.array(), decodeDataOffsetOffset, entryDataOffsetLength); - entry.dataOffset = decodeDataOffsetBuffer.getLong(0); - - encodedFileBuffer.get(decodeFileSizeBuffer.array(), 0, entryFileSizeLength); - entry.fileSize = decodeFileSizeBuffer.getLong(0); - - // this can be used to detect special cross linking entries - // if (getIndexNumber(entry.key, entry.key.length) != bucketIndex); - // System.out.println("Bad key index: index=" + i + ", entry=" + entry + ", - // bucket=" + getIndexNumber(entry.key, entry.key.length)); - - entries.add(entry); - } - - encodedFileBuffer.limit(fileLength); - } - - public IndexEntry getEntry(final byte[] key) { - for (final LocalIndexFile.IndexEntry indexEntry : entries) { - if (ReteraCASCUtils.arraysEquals(indexEntry.key, 0, entryKeyLength, key, 0, entryKeyLength)) { - return indexEntry; - } - } - - return null; - } - - public IndexEntry getEntry(final int index) { - return entries.get(index); - } - - public int getEntryCount() { - return entries.size(); - } - - public long getDataFileOffset(final long dataOffset) { - return dataOffset & (1L << dataFileSizeBits) - 1L; - } - - public int getDataFileNumber(final long dataOffset) { - return (int) (dataOffset >>> dataFileSizeBits); - } - - public static class IndexEntry { - private byte[] key; - private long dataOffset; - private long fileSize; - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("IndexEntry{key=0x"); - Hex.stringBufferAppendHex(builder, key); - builder.append(", dataOffset="); - builder.append(dataOffset); - builder.append(", fileSize="); - builder.append(fileSize); - builder.append("}"); - - return builder.toString(); - } - - public long getDataOffset() { - return dataOffset; - } - - public long getFileSize() { - return fileSize; - } - - public String getKeyString() { - final StringBuilder builder = new StringBuilder(); - Hex.stringBufferAppendHex(builder, key); - return builder.toString(); - } - - public boolean compareKey(final byte[] otherKey) { - return ReteraCASCUtils.arraysEquals(key, 0, key.length, otherKey, 0, key.length); - } - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/trash/VirtualFileSystem.java b/core/src/com/hiveworkshop/blizzard/casc/trash/VirtualFileSystem.java deleted file mode 100644 index c83c48ae..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/trash/VirtualFileSystem.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.hiveworkshop.blizzard.casc.trash; - -import java.io.IOException; -import java.io.PrintStream; -import java.nio.ByteBuffer; - -import com.hiveworkshop.blizzard.casc.nio.MalformedCASCStructureException; -//import com.hiveworkshop.blizzard.casc.vfs.path.Container; -//import com.hiveworkshop.blizzard.casc.vfs.path.FileFactory; -//import com.hiveworkshop.blizzard.casc.vfs.path.Node; - -public class VirtualFileSystem { - - private static final ByteBuffer IDENTIFIER = ByteBuffer.wrap(new byte[] { 'T', 'V', 'F', 'S' }); - - // private final ArrayList root; - - public VirtualFileSystem(final ByteBuffer fileBuffer) throws IOException { - final ByteBuffer localBuffer = fileBuffer.slice(); - - // check identifier - - if (localBuffer.remaining() < IDENTIFIER.remaining() - || !localBuffer.limit(IDENTIFIER.remaining()).equals(IDENTIFIER)) { - throw new MalformedCASCStructureException("missing TVFS identifier"); - } - - // decode header - - localBuffer.limit(localBuffer.capacity()); - localBuffer.position(IDENTIFIER.remaining()); - - final byte version = localBuffer.get(); - if (version != 1) { - throw new UnsupportedOperationException("unsupported vfs version: " + version); - } - final int headerSize = Byte.toUnsignedInt(localBuffer.get()); - if (headerSize < 0x26) { - throw new MalformedCASCStructureException("vfs header too small"); - } - localBuffer.limit(headerSize); - - final int encodingKeySize = Byte.toUnsignedInt(localBuffer.get()); - final int patchKeySize = Byte.toUnsignedInt(localBuffer.get()); - - final int flags = localBuffer.getInt(); - - final int pathOffset = localBuffer.getInt(); - final int pathSize = localBuffer.getInt(); - final int fileReferenceOffset = localBuffer.getInt(); - final int fileReferenceSize = localBuffer.getInt(); - final int contentOffset = localBuffer.getInt(); - final int contentSize = localBuffer.getInt(); - - final int maximumPathDepth = Short.toUnsignedInt(localBuffer.getShort()); - - final int containerTableOffsetSize = Math.max(1, - Integer.BYTES - Integer.numberOfLeadingZeros(contentSize) / Byte.SIZE); - - localBuffer.limit(pathOffset + pathSize); - localBuffer.position(pathOffset); - final ByteBuffer pathBuffer = localBuffer.slice(); - localBuffer.clear(); - - localBuffer.limit(fileReferenceOffset + fileReferenceSize); - localBuffer.position(fileReferenceOffset); - final ByteBuffer fileReferenceBuffer = localBuffer.slice(); - localBuffer.clear(); - - localBuffer.limit(contentOffset + contentSize); - localBuffer.position(contentOffset); - final ByteBuffer contentBuffer = localBuffer.slice(); - localBuffer.clear(); - - // final var fileFactory = new FileFactory(fileReferenceBuffer, contentBuffer, - // encodingKeySize, containerTableOffsetSize); - - // root = Container.decodeContainer(pathBuffer, fileFactory); - } - - public void printPaths(final PrintStream out) { - /* - * for (final var node : root) { node.printPaths(out, ""); } - */ - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/vfs/FileNode.java b/core/src/com/hiveworkshop/blizzard/casc/vfs/FileNode.java deleted file mode 100644 index a7c3fd9d..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/vfs/FileNode.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.hiveworkshop.blizzard.casc.vfs; - -import java.util.List; - -/** - * A file system node containing a logical file. - */ -public class FileNode extends PathNode { - private final StorageReference[] references; - - protected FileNode(final List pathFragments, final List references) { - super(pathFragments); - this.references = references.toArray(new StorageReference[0]); - } - - public int getFileReferenceCount() { - return references.length; - } - - public StorageReference getFileReference(final int index) { - return references[index]; - } - -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/vfs/PathNode.java b/core/src/com/hiveworkshop/blizzard/casc/vfs/PathNode.java deleted file mode 100644 index 007b9d30..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/vfs/PathNode.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.hiveworkshop.blizzard.casc.vfs; - -import java.util.List; - -/** - * Represents a path node. Path nodes can either be prefix nodes or file nodes. - */ -public abstract class PathNode { - /** - * Array of path fragments. Each fragment represents part of a path string. Due - * to the potential for multi byte encoding, one cannot assume that each - * fragment can be assembled into a valid string. - */ - private final byte[][] pathFragments; - - protected PathNode(final List pathFragments) { - this.pathFragments = pathFragments.toArray(new byte[0][]); - } - - public int getPathFragmentCount() { - return pathFragments.length; - } - - public byte[] getFragment(final int index) { - return pathFragments[index]; - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/vfs/PrefixNode.java b/core/src/com/hiveworkshop/blizzard/casc/vfs/PrefixNode.java deleted file mode 100644 index 938dd938..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/vfs/PrefixNode.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.hiveworkshop.blizzard.casc.vfs; - -import java.util.List; - -/** - * Prefix nodes generate a path prefix for other nodes. - */ -public class PrefixNode extends PathNode { - /** - * Array of child node that this node forms a prefix of. - */ - private final PathNode[] nodes; - - protected PrefixNode(final List pathFragments, final List nodes) { - super(pathFragments); - this.nodes = nodes.toArray(new PathNode[0]); - } - - public int getNodeCount() { - return nodes.length; - } - - public PathNode getNode(final int index) { - return nodes[index]; - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/vfs/StorageReference.java b/core/src/com/hiveworkshop/blizzard/casc/vfs/StorageReference.java deleted file mode 100644 index aeeef6a6..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/vfs/StorageReference.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.hiveworkshop.blizzard.casc.vfs; - -import com.hiveworkshop.blizzard.casc.Key; - -/** - * A reference to a file in CASC storage. - */ -public class StorageReference { - /** - * Logical offset of this chunk. - */ - private long offset = 0; - - /** - * Logical size of this chunk. - */ - private long size = 0; - - /** - * Encoding key of chunk. - */ - private Key encodingKey = null; - - /** - * Physical size of stored data. - */ - private long physicalSize = 0; - - /** - * Total size of all decompressed data banks. - */ - private long actualSize = 0; - - public StorageReference(final long offset, final long size, final Key encodingKey, final int physicalSize, - final int actualSize) { - this.offset = offset; - this.size = size; - this.encodingKey = encodingKey; - this.physicalSize = physicalSize; - this.actualSize = actualSize; - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("FileReference{encodingKey="); - builder.append(encodingKey); - builder.append(", offset="); - builder.append(offset); - builder.append(", size="); - builder.append(size); - builder.append(", physicalSize="); - builder.append(physicalSize); - builder.append(", actualSize="); - builder.append(actualSize); - builder.append("}"); - - return builder.toString(); - } - - public long getOffset() { - return offset; - } - - public long getSize() { - return size; - } - - public Key getEncodingKey() { - return encodingKey; - } - - public long getPhysicalSize() { - return physicalSize; - } - - public long getActualSize() { - return actualSize; - } - -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/vfs/TVFSDecoder.java b/core/src/com/hiveworkshop/blizzard/casc/vfs/TVFSDecoder.java deleted file mode 100644 index a3395b66..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/vfs/TVFSDecoder.java +++ /dev/null @@ -1,254 +0,0 @@ -package com.hiveworkshop.blizzard.casc.vfs; - -import java.io.IOException; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.hiveworkshop.blizzard.casc.Key; -import com.hiveworkshop.blizzard.casc.nio.MalformedCASCStructureException; - -/** - * Decodes file data for file value nodes. - *

- * This is done by collating together data. First the file is resolved from the - * file buffer then the data describing its contents is resolved from the - * contents buffer. - */ -public class TVFSDecoder { - /** - * TVFS file identifier located at start of TVFS files. - */ - private static final ByteBuffer IDENTIFIER = ByteBuffer.wrap(new byte[] { 'T', 'V', 'F', 'S' }); - - /** - * Flag for container values. If set inside a value then the value is a - * container of other nodes otherwise it is a file. - */ - private static final int VALUE_CONTAINER_FLAG = 0x80000000; - - /** - * Specifier for path node value. If path string length is this then value - * follows. - */ - private static final int VALUE_PATH_STRING_LENGTH = 0xFF; - - private byte version = 0; - private int flags = 0; - private int encodingKeySize = 0; - private int patchKeySize = 0; - private int pathOffset = 0; - private int pathSize = 0; - private int fileReferenceOffset = 0; - private int fileReferenceSize = 0; - private int cascReferenceOffset = 0; - private int cascReferenceSize = 0; - private int maximumPathDepth = 0; - - private int contentsOffsetSize = 0; - private ByteBuffer pathBuffer = null; - private ByteBuffer logicalBuffer = null; - private ByteBuffer storageBuffer = null; - - /** - * The offset into the content buffer is a special type that uses the minimum - * number of bytes to hold the largest offset. Hence non-standard types such as - * 3 bytes long big-endian integer are possible so a special buffer is needed to - * decode these numbers. - */ - private final ByteBuffer contentsOffsetDecoder; - - public TVFSDecoder() { - contentsOffsetDecoder = ByteBuffer.allocate(Integer.BYTES); - } - - public List decodeContainer() throws MalformedCASCStructureException { - return decodeContainer(pathBuffer); - } - - private List decodeContainer(final ByteBuffer pathBuffer) throws MalformedCASCStructureException { - final ArrayList nodes = new ArrayList(); - - while (pathBuffer.hasRemaining()) { - final PathNode node = decodeNode(pathBuffer); - nodes.add(node); - } - - return nodes; - } - - private PathNode decodeNode(final ByteBuffer pathBuffer) throws MalformedCASCStructureException { - final ArrayList pathFragments = new ArrayList(); - - PathNode node; - try { - int pathStringLength; - while ((pathStringLength = Byte.toUnsignedInt(pathBuffer.get())) != VALUE_PATH_STRING_LENGTH) { - final byte[] pathFragment = new byte[pathStringLength]; - pathBuffer.get(pathFragment); - pathFragments.add(pathFragment); - } - - final int value = pathBuffer.getInt(); - if ((value & VALUE_CONTAINER_FLAG) != 0) { - // prefix node - final int containerSize = value & ~VALUE_CONTAINER_FLAG; - pathBuffer.position(pathBuffer.position() - Integer.BYTES); - - if (containerSize > pathBuffer.remaining()) { - throw new MalformedCASCStructureException("prefix node container extends beyond path container"); - } - - pathBuffer.limit(pathBuffer.position() + containerSize); - - final ByteBuffer containerBuffer = pathBuffer.slice(); - - pathBuffer.position(pathBuffer.limit()); - pathBuffer.limit(pathBuffer.capacity()); - - containerBuffer.position(Integer.BYTES); - - final List nodes = decodeContainer(containerBuffer); - - node = new PrefixNode(pathFragments, nodes); - } else { - // file value - final StorageReference[] fileReferences = getFileReferences(value); - - node = new FileNode(pathFragments, Arrays.asList(fileReferences)); - } - } catch (final BufferUnderflowException e) { - throw new MalformedCASCStructureException("path stream goes beyond path container"); - } - - return node; - } - - private StorageReference[] getFileReferences(final int fileOffset) throws MalformedCASCStructureException { - if (fileOffset > logicalBuffer.limit()) { - throw new MalformedCASCStructureException("logical offset beyond file reference chunk"); - } - logicalBuffer.position(fileOffset); - - StorageReference[] references; - - try { - final int referenceCount = Byte.toUnsignedInt(logicalBuffer.get()); - references = new StorageReference[referenceCount]; - for (int i = 0; i < referenceCount; i += 1) { - final long offset = Integer.toUnsignedLong(logicalBuffer.getInt()); - final long size = Integer.toUnsignedLong(logicalBuffer.getInt()); - - logicalBuffer.get(contentsOffsetDecoder.array(), Integer.BYTES - contentsOffsetSize, - contentsOffsetSize); - final int cascReferenceOffset = contentsOffsetDecoder.getInt(0); - - if (cascReferenceOffset > storageBuffer.limit()) { - throw new MalformedCASCStructureException("storage offset beyond casc reference chunk"); - } - storageBuffer.position(cascReferenceOffset); - - try { - final byte[] encodingKeyDecoder = new byte[encodingKeySize]; - storageBuffer.get(encodingKeyDecoder); - - final int physicalSize = storageBuffer.getInt(); - storageBuffer.get(); - final int actualSize = storageBuffer.getInt(); - - final StorageReference reference = new StorageReference(offset, size, new Key(encodingKeyDecoder), - physicalSize, actualSize); - references[i] = reference; - } catch (final BufferUnderflowException e) { - throw new MalformedCASCStructureException("storage goes out of bounds"); - } - } - } catch (final BufferUnderflowException e) { - throw new MalformedCASCStructureException("logical reference goes out of bounds"); - } - - return references; - } - - public TVFSFile loadFile(final ByteBuffer fileBuffer) throws IOException { - final ByteBuffer localBuffer = fileBuffer.slice(); - - // check identifier - - if ((localBuffer.remaining() < IDENTIFIER.remaining()) - || !localBuffer.limit(IDENTIFIER.remaining()).equals(IDENTIFIER)) { - throw new MalformedCASCStructureException("missing TVFS identifier"); - } - - // decode header - - localBuffer.limit(localBuffer.capacity()); - localBuffer.position(IDENTIFIER.remaining()); - - try { - version = localBuffer.get(); - if (version != 1) { - throw new UnsupportedOperationException("unsupported TVFS version: " + version); - } - final int headerSize = Byte.toUnsignedInt(localBuffer.get()); - if (headerSize > localBuffer.capacity()) { - throw new MalformedCASCStructureException("TVFS header extends past end of file"); - } - localBuffer.limit(headerSize); - - encodingKeySize = Byte.toUnsignedInt(localBuffer.get()); - patchKeySize = Byte.toUnsignedInt(localBuffer.get()); - flags = localBuffer.getInt(); - - pathOffset = localBuffer.getInt(); - pathSize = localBuffer.getInt(); - if ((Integer.toUnsignedLong(pathOffset) + Integer.toUnsignedLong(pathSize)) > localBuffer.capacity()) { - throw new MalformedCASCStructureException("path stream extends past end of file"); - } - - fileReferenceOffset = localBuffer.getInt(); - fileReferenceSize = localBuffer.getInt(); - if ((Integer.toUnsignedLong(fileReferenceOffset) + Integer.toUnsignedLong(fileReferenceSize)) > localBuffer - .capacity()) { - throw new MalformedCASCStructureException("logical data extends past end of file"); - } - - cascReferenceOffset = localBuffer.getInt(); - cascReferenceSize = localBuffer.getInt(); - if ((Integer.toUnsignedLong(cascReferenceOffset) + Integer.toUnsignedLong(cascReferenceSize)) > localBuffer - .capacity()) { - throw new MalformedCASCStructureException("storage data extends past end of file"); - } - - maximumPathDepth = Short.toUnsignedInt(localBuffer.getShort()); - } catch (final BufferUnderflowException e) { - throw new MalformedCASCStructureException("header goes out of bounds"); - } - - contentsOffsetSize = Math.max(1, Integer.BYTES - (Integer.numberOfLeadingZeros(cascReferenceSize) / Byte.SIZE)); - contentsOffsetDecoder.putInt(0, 0); - - localBuffer.limit(pathOffset + pathSize); - localBuffer.position(pathOffset); - pathBuffer = localBuffer.slice(); - localBuffer.clear(); - - localBuffer.limit(fileReferenceOffset + fileReferenceSize); - localBuffer.position(fileReferenceOffset); - logicalBuffer = localBuffer.slice(); - localBuffer.clear(); - - localBuffer.limit(cascReferenceOffset + cascReferenceSize); - localBuffer.position(cascReferenceOffset); - storageBuffer = localBuffer.slice(); - localBuffer.clear(); - - final List rootNodes = decodeContainer(); - final TVFSFile tvfsFile = new TVFSFile(version, flags, encodingKeySize, patchKeySize, maximumPathDepth, - rootNodes); - - return tvfsFile; - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/vfs/TVFSFile.java b/core/src/com/hiveworkshop/blizzard/casc/vfs/TVFSFile.java deleted file mode 100644 index 6d76f27d..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/vfs/TVFSFile.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.hiveworkshop.blizzard.casc.vfs; - -import java.util.List; - -/** - * TVFS file containing file system path nodes. - */ -public class TVFSFile { - private final byte version; - private final int flags; - private final int encodingKeySize; - private final int patchKeySize; - private final int maximumPathDepth; - - private final PathNode[] rootNodes; - - public TVFSFile(final byte version, final int flags, final int encodingKeySize, final int patchKeySize, final int maximumPathDepth, - final List rootNodeList) { - this.version = version; - this.flags = flags; - this.encodingKeySize = encodingKeySize; - this.patchKeySize = patchKeySize; - this.maximumPathDepth = maximumPathDepth; - this.rootNodes = rootNodeList.toArray(new PathNode[0]); - } - - public int getEncodingKeySize() { - return encodingKeySize; - } - - public int getFlags() { - return flags; - } - - public int getMaximumPathDepth() { - return maximumPathDepth; - } - - public int getPatchKeySize() { - return patchKeySize; - } - - public PathNode getRootNode(final int index) { - return rootNodes[index]; - } - - public int getRootNodeCount() { - return rootNodes.length; - } - - public byte getVersion() { - return version; - } -} diff --git a/core/src/com/hiveworkshop/blizzard/casc/vfs/VirtualFileSystem.java b/core/src/com/hiveworkshop/blizzard/casc/vfs/VirtualFileSystem.java deleted file mode 100644 index 037162b2..00000000 --- a/core/src/com/hiveworkshop/blizzard/casc/vfs/VirtualFileSystem.java +++ /dev/null @@ -1,681 +0,0 @@ -package com.hiveworkshop.blizzard.casc.vfs; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.BufferOverflowException; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharacterCodingException; -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; -import java.nio.charset.CodingErrorAction; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.TreeMap; - -import com.hiveworkshop.ReteraCASCUtils; -import com.hiveworkshop.blizzard.casc.Key; -import com.hiveworkshop.blizzard.casc.nio.MalformedCASCStructureException; -import com.hiveworkshop.blizzard.casc.storage.BankStream; -import com.hiveworkshop.blizzard.casc.storage.Storage; - -/** - * High level file system API using TVFS directories to extract files from a - * store. - */ -public final class VirtualFileSystem { - /** - * A result of a file path lookup operation in a TVFS file system. - *

- * Can be used to fetch the data of a file. - */ - public final class PathResult { - private final PathNode node; - private final byte[][] pathFragments; - - /** - * Internal constructor for path results. - * - * @param node Resolved node. - * @param pathFragments Path of resolved node. - */ - private PathResult(final PathNode node, final byte[][] pathFragments) { - this.node = node; - this.pathFragments = pathFragments; - } - - /** - * Returns true if this file completely exists in storage. - *

- * The virtual file system structure lists all files, even ones that may not be - * in storage. Only files that are in storage can have their file buffer read. - *

- * If this result is not a file then it exists in storage as it has no storage - * footprint. - * - * @return True if the file exists in storage. - */ - public boolean existsInStorage() { - boolean exists = true; - - if (isFile()) { - final FileNode fileNode = (FileNode) node; - final int fileReferenceCount = fileNode.getFileReferenceCount(); - for (int fileReferenceIndex = 0; fileReferenceIndex < fileReferenceCount; fileReferenceIndex += 1) { - final StorageReference fileReference = fileNode.getFileReference(fileReferenceIndex); - exists = exists && storage.hasBanks(fileReference.getEncodingKey()); - } - } - - return exists; - } - - /** - * Get the size of the file in bytes. - *

- * If this result is not a file a value of 0 is returned. - * - * @return File size in bytes. - */ - public long getFileSize() { - long size = 0L; - - if (isFile()) { - final FileNode fileNode = (FileNode) node; - final int fileReferenceCount = fileNode.getFileReferenceCount(); - for (int fileReferenceIndex = 0; fileReferenceIndex < fileReferenceCount; fileReferenceIndex += 1) { - final StorageReference fileReference = fileNode.getFileReference(fileReferenceIndex); - size = Math.max(size, fileReference.getOffset() + fileReference.getSize()); - } - } - - return size; - } - - public String getPath() throws CharacterCodingException { - return convertPathFragments(pathFragments); - } - - public byte[][] getPathFragments() { - return pathFragments; - } - - public boolean isFile() { - return node instanceof FileNode; - } - - /** - * Returns if this path result represents a TVFS file node used by this file - * system. - *

- * Such nodes logically act as folders in the file path but also contain file - * data used by this file system. Such behaviour may be incompatible with - * standard file systems which do not support both a folder and file at the same - * path. - *

- * Results that are not files cannot be a TVFS file. - * - * @return If this node is a TVFS file used by this file system. - */ - public boolean isTVFS() { - if (!isFile()) { - return false; - } - - final FileNode fileNode = (FileNode) node; - final StorageReference fileReference = fileNode.getFileReference(0); - return tvfsStorageReferences.containsKey(fileReference.getEncodingKey()); - } - - /** - * Fully read this file into the specified destination buffer. If no buffer is - * specified a new one will be allocated. - *

- * The specified buffer must have at least getFileSize bytes remaining. - * - * @param destBuffer Buffer to be written to. - * @return Buffer that was written to. - * @throws IOException If an error occurs during reading. - * @throws OutOfMemoryError If no buffer is specified and the file is too big - * for a single buffer. - */ - public ByteBuffer readFile(ByteBuffer destBuffer) throws IOException { - if (!isFile()) { - throw new FileNotFoundException("result is not a file"); - } - - final long fileSize = getFileSize(); - if (fileSize > Integer.MAX_VALUE) { - throw new OutOfMemoryError("file too big to process"); - } - - if (destBuffer == null) { - destBuffer = ByteBuffer.allocate((int) fileSize); - } else if (destBuffer.remaining() < fileSize) { - throw new BufferOverflowException(); - } - - final ByteBuffer fileBuffer = destBuffer.slice(); - - final FileNode fileNode = (FileNode) node; - final int fileReferenceCount = fileNode.getFileReferenceCount(); - for (int fileReferenceIndex = 0; fileReferenceIndex < fileReferenceCount; fileReferenceIndex += 1) { - final StorageReference fileReference = fileNode.getFileReference(fileReferenceIndex); - - final long logicalSize = fileReference.getSize(); - if (logicalSize != fileReference.getActualSize()) { - throw new MalformedCASCStructureException("inconsistent size"); - } - final long logicalOffset = fileReference.getOffset(); - - final BankStream bankStream = storage.getBanks(fileReference.getEncodingKey()); - // TODO test if compressed and logical sizes match stored sizes. - - fileBuffer.limit((int) (logicalOffset + logicalSize)); - fileBuffer.position((int) logicalOffset); - while (bankStream.hasNextBank()) { - bankStream.getBank(fileBuffer); - } - } - - destBuffer.position(destBuffer.position() + (int) fileSize); - return destBuffer; - } - } - - /** - * VFS storage reference key prefix. - */ - public static final String CONFIGURATION_KEY_PREFIX = "vfs-"; - - /** - * Root VFS storage reference. - */ - public static final String ROOT_KEY = "root"; - - /** - * Character encoding used internally by file paths. - */ - public static final Charset PATH_ENCODING = Charset.forName("UTF8"); - - /** - * Path separator used by path strings. - */ - public static final String PATH_SEPERATOR = "\\"; - - /** - * Compares the path fragments of a node with a section of file path fragments. - * This is useful for performing a binary search on a node's children. - *

- * A return value of 0 does not mean that the node is in the path fragments. - * Only that if it were, it would be this node. This is because the children of - * a node all have unique first fragment sequences so only the first fragment is - * tested. - * - * @param pathFragments Path fragments of a file path. - * @param fragmentIndex Index of fragment where to start comparing at. - * @param fragmentOffset Offset into fragment to start comparing at. - * @param node Node which is being compared. - * @return Similar to standard comparator value (see above). - */ - private static int compareNodePathFragments(final byte[][] pathFragments, final int fragmentIndex, - final int fragmentOffset, final PathNode node) { - final int nodeFragmentCount = node.getPathFragmentCount(); - if (nodeFragmentCount == 0) { - // nodes without fragments have no path fragment presence so always match - return 0; - } - - final byte[] nodeFragment = node.getFragment(0); - final byte[] fragment = pathFragments[fragmentIndex]; - if ((nodeFragment.length == 0) && ((fragment.length - fragmentOffset) > 0)) { - // node with termination fragment are always before all other child nodes - return 1; - } - return ReteraCASCUtils.arraysCompareUnsigned(fragment, fragmentOffset, - Math.min(fragmentOffset + nodeFragment.length, fragment.length), nodeFragment, 0, nodeFragment.length); - } - - /** - * Convert a path string into path fragments for resolution in the VFS. - * - * @param filePath Path string to convert. - * @return Path fragments. - * @throws CharacterCodingException If the path string cannot be encoded into - * fragments. - */ - public static byte[][] convertFilePath(final String filePath) throws CharacterCodingException { - final String[] fragmentStrings = filePath.toLowerCase(Locale.ROOT).split("\\" + PATH_SEPERATOR); - final byte[][] pathFragments = new byte[fragmentStrings.length][]; - - final CharsetEncoder encoder = PATH_ENCODING.newEncoder(); - encoder.onMalformedInput(CodingErrorAction.REPORT); - encoder.onUnmappableCharacter(CodingErrorAction.REPORT); - for (int index = 0; index < fragmentStrings.length; index += 1) { - final ByteBuffer fragmentBuffer = encoder.encode(CharBuffer.wrap(fragmentStrings[index])); - if (fragmentBuffer.hasArray() && (fragmentBuffer.limit() == fragmentBuffer.capacity()) - && (fragmentBuffer.position() == 0)) { - // can use underlying array - pathFragments[index] = fragmentBuffer.array(); - } else { - // copy into array - final byte[] pathFragment = new byte[fragmentBuffer.remaining()]; - fragmentBuffer.get(pathFragment); - pathFragments[index] = pathFragment; - } - } - - return pathFragments; - } - - /** - * Convert path fragments used internally by VFS into a path string. - * - * @param pathFragments Path fragments to convert. - * @return Path string. - * @throws CharacterCodingException If the path fragments cannot be decoded into - * a valid String. - */ - public static String convertPathFragments(final byte[][] pathFragments) throws CharacterCodingException { - final String[] fragmentStrings = new String[pathFragments.length]; - - final CharsetDecoder decoder = PATH_ENCODING.newDecoder(); - decoder.onMalformedInput(CodingErrorAction.REPORT); - decoder.onUnmappableCharacter(CodingErrorAction.REPORT); - - for (int index = 0; index < fragmentStrings.length; index += 1) { - fragmentStrings[index] = decoder.decode(ByteBuffer.wrap(pathFragments[index])).toString(); - } - - return String.join(PATH_SEPERATOR, fragmentStrings); - } - - /** - * Test the path fragments of a node form a section of file path fragments. - * - * @param pathFragments Path fragments of a file path. - * @param fragmentIndex Index of fragment where to start testing at. - * @param fragmentOffset Offset into fragment to start testing at. - * @param node Node which is being tested. - * @return True if the node is contained in the path fragments, otherwise false. - */ - private static boolean equalNodePathFragments(final byte[][] pathFragments, final int fragmentIndex, - int fragmentOffset, final PathNode node) { - final int nodeFragmentCount = node.getPathFragmentCount(); - if (nodeFragmentCount == 0) { - // nodes without fragments have no path fragment presence so always match - return true; - } - - if ((nodeFragmentCount == 1) && (node.getFragment(0).length == 0)) { - // node with termination fragment - return fragmentOffset == pathFragments[fragmentIndex].length; - } else if (pathFragments.length < (fragmentIndex + nodeFragmentCount)) { - // fragment too short - return false; - } - - boolean result = true; - int nodeFragmentIndex = 0; - while (result && (nodeFragmentIndex < nodeFragmentCount)) { - final byte[] fragment = pathFragments[fragmentIndex + nodeFragmentIndex]; - final byte[] nodeFragment = node.getFragment(nodeFragmentIndex); - result = result && ReteraCASCUtils.arraysEquals(fragment, fragmentOffset, - Math.min(fragmentOffset + nodeFragment.length, fragment.length), nodeFragment, 0, - nodeFragment.length); - fragmentOffset = 0; - nodeFragmentIndex += 1; - } - - return result; - } - - /** - * Local CASC storage. Used to retrieve file data. - */ - private final Storage storage; - - /** - * Decoder used to load TVFS files in the TVFS tree. - */ - private final TVFSDecoder decoder = new TVFSDecoder(); - - /** - * TVFS file containing the root directory for the file system. - */ - private final TVFSFile tvfsRoot; - - /** - * TVFS file cache. Holds all loaded TVFS files for this file system. This - * allows the TVFS files to be loaded lazily which could potentially reduce - * loading times and memory usage when only some branches of the TVFS file tree - * are accessed. - */ - private final TreeMap tvfsCache = new TreeMap<>(); - - /** - * Map of all TVFS files used by the TVFS file tree. Keys that are not in this - * map are treated as leaf files rather than a nested TVFS file. - */ - private final TreeMap tvfsStorageReferences = new TreeMap<>(); - - /** - * Construct a TVFS file system from a CASC local storage and build - * configuration. - * - * @param storage CASC local storage to source files from. - * @param buildConfiguration Build configuration of CASC archive. - * @throws IOException If an exception occurs when loading the file system. - */ - public VirtualFileSystem(final Storage storage, final Map buildConfiguration) throws IOException { - this.storage = storage; - - int vfsNumber = 0; - String configurationKey; - while (buildConfiguration - .containsKey(configurationKey = CONFIGURATION_KEY_PREFIX + Integer.toUnsignedString(++vfsNumber))) { - final com.hiveworkshop.blizzard.casc.StorageReference storageReference = new com.hiveworkshop.blizzard.casc.StorageReference( - configurationKey, buildConfiguration); - tvfsStorageReferences.put(storageReference.getEncodingKey(), storageReference); - } - - final com.hiveworkshop.blizzard.casc.StorageReference rootReference = new com.hiveworkshop.blizzard.casc.StorageReference( - CONFIGURATION_KEY_PREFIX + ROOT_KEY, buildConfiguration); - final ByteBuffer rootBuffer = fetchStoredBuffer(rootReference); - tvfsRoot = decoder.loadFile(rootBuffer); - - tvfsCache.put(rootReference.getEncodingKey(), tvfsRoot); - } - - /** - * Resolves a TVFS storage reference into a data buffer from the local storage. - * - * @param storageReference TVFS storage reference. - * @return Data buffer containing refered content. - * @throws IOException If an exception occurs when fetching the data buffer. - */ - private ByteBuffer fetchStoredBuffer(final com.hiveworkshop.blizzard.casc.StorageReference storageReference) - throws IOException { - final long size = storageReference.getSize(); - if (size > Integer.MAX_VALUE) { - throw new MalformedCASCStructureException("stored data too large to process"); - } - - final BankStream bankStream = storage.getBanks(storageReference.getEncodingKey()); - final ByteBuffer storedBuffer = ByteBuffer.allocate((int) size); - try { - while (bankStream.hasNextBank()) { - bankStream.getBank(storedBuffer); - } - } catch (final BufferOverflowException e) { - throw new MalformedCASCStructureException("stored data is bigger than expected"); - } - - if (storedBuffer.hasRemaining()) { - throw new MalformedCASCStructureException("stored data is smaller than expected"); - } - - storedBuffer.rewind(); - return storedBuffer; - } - - /** - * Method to get all files in the file system. - * - * @return List of file path results for every file in the file system. - * @throws IOException If an exception is thrown when loading a TVFS file or - * decoding path fragments into a path string. - */ - public List getAllFiles() throws IOException { - final ArrayList pathStringList = new ArrayList(); - - final int rootCount = tvfsRoot.getRootNodeCount(); - for (int rootIndex = 0; rootIndex < rootCount; rootIndex += 1) { - final PathNode root = tvfsRoot.getRootNode(rootIndex); - recursiveFilePathRetrieve(new byte[1][0], pathStringList, root); - } - - return pathStringList; - } - - /** - * Recursive function to traverse the TVFS tree and resolve all files in the - * file system. - * - * @param parentPathFragments Path fragments of parent node. - * @param resultList Result list. - * @param currentNode The child node to process. - * @throws IOException If an exception occurs when processing the node. - */ - private void recursiveFilePathRetrieve(final byte[][] parentPathFragments, final ArrayList resultList, - final PathNode currentNode) throws IOException { - byte[][] currentPathFragments = parentPathFragments; - - // process path fragments - final int fragmentCount = currentNode.getPathFragmentCount(); - if (fragmentCount > 0) { - int fragmentIndex = 0; - final byte[] fragment = currentNode.getFragment(fragmentIndex++); - - // expand path fragment array - int basePathFragmentsIndex = currentPathFragments.length; - if ((fragmentCount > 1) || (fragment.length > 0)) { - // first fragment of the node gets merged with last path fragment - basePathFragmentsIndex -= 1; - } - currentPathFragments = Arrays.copyOf(currentPathFragments, basePathFragmentsIndex + fragmentCount); - - // merge fragment - final byte[] sourceFragment = currentPathFragments[basePathFragmentsIndex]; - byte[] joinedFragment = fragment; - if (sourceFragment != null) { - joinedFragment = sourceFragment; - if (fragment.length != 0) { - final int joinOffset = sourceFragment.length; - joinedFragment = Arrays.copyOf(sourceFragment, joinOffset + fragment.length); - System.arraycopy(fragment, 0, joinedFragment, joinOffset, fragment.length); - } - } - - // append path fragments - currentPathFragments[basePathFragmentsIndex] = joinedFragment; - for (; fragmentIndex < fragmentCount; fragmentIndex += 1) { - currentPathFragments[basePathFragmentsIndex + fragmentIndex] = currentNode.getFragment(fragmentIndex); - } - } - - if (currentNode instanceof PrefixNode) { - final PrefixNode prefixNode = (PrefixNode) currentNode; - - final int childCount = prefixNode.getNodeCount(); - for (int index = 0; index < childCount; index += 1) { - recursiveFilePathRetrieve(currentPathFragments, resultList, prefixNode.getNode(index)); - } - } else if (currentNode instanceof FileNode) { - final FileNode fileNode = (FileNode) currentNode; - - final int fileReferenceCount = fileNode.getFileReferenceCount(); - if (fileReferenceCount == 1) { - // check if nested VFS - final Key encodingKey = fileNode.getFileReference(0).getEncodingKey(); - final TVFSFile tvfsFile = resolveTVFS(encodingKey); - - if (tvfsFile != null) { - // file is also a folder - final byte[][] folderPathFragments = Arrays.copyOf(currentPathFragments, - currentPathFragments.length + 1); - folderPathFragments[currentPathFragments.length] = new byte[0]; - - final int rootCount = tvfsFile.getRootNodeCount(); - for (int rootIndex = 0; rootIndex < rootCount; rootIndex += 1) { - final PathNode root = tvfsFile.getRootNode(rootIndex); - recursiveFilePathRetrieve(folderPathFragments, resultList, root); - } - } - - resultList.add(new PathResult(currentNode, currentPathFragments)); - } - } else { - throw new IllegalArgumentException("unsupported node type"); - } - } - - /** - * Recursive function to resolve a file node in a TVFS tree from path fragments - * representing a file system file path. - * - * @param pathFragments Path fragments of a file path. - * @param fragmentIndex Index of fragment where currently testing. - * @param fragmentOffset Offset into fragment where currently testing. - * @param node Node which is being tested. - * @return Resolved file node. - * @throws IOException If an exception occurs when testing the node. - */ - private FileNode recursiveResolvePathFragments(final byte[][] pathFragments, int fragmentIndex, int fragmentOffset, - final PathNode node) throws IOException { - if (!equalNodePathFragments(pathFragments, fragmentIndex, fragmentOffset, node)) { - // node not on path - return null; - } - - // advance fragment position - final int nodeFragmentCount = node.getPathFragmentCount(); - if (nodeFragmentCount == 1) { - final byte[] nodeFragment = node.getFragment(0); - if (nodeFragment.length == 0) { - // node with termination fragment - fragmentIndex += 1; - fragmentOffset = 0; - } else { - // node with less than a whole fragment - fragmentOffset += nodeFragment.length; - } - - } else if (nodeFragmentCount > 1) { - // node which completes 1 or more fragments. - fragmentIndex += nodeFragmentCount - 1; - fragmentOffset = node.getFragment(nodeFragmentCount - 1).length; - } - - // process node - if (node instanceof PrefixNode) { - // apply binary search to prefix node to find next node - final PrefixNode prefixNode = (PrefixNode) node; - final int childCount = prefixNode.getNodeCount(); - - int low = 0; - int high = childCount - 1; - while (low <= high) { - final int middle = (low + high) / 2; - final PathNode searchNode = prefixNode.getNode(middle); - final int result = compareNodePathFragments(pathFragments, fragmentIndex, fragmentOffset, searchNode); - - if (result == 0) { - // possible match - return recursiveResolvePathFragments(pathFragments, fragmentIndex, fragmentOffset, searchNode); - } else if (result < 0) { - high = middle - 1; - } else { - low = middle + 1; - } - } - - } else if (node instanceof FileNode) { - final FileNode fileNode = (FileNode) node; - - if ((fragmentIndex == (pathFragments.length - 1)) - && (fragmentOffset == pathFragments[pathFragments.length - 1].length)) { - // file found - return fileNode; - } else if (fragmentOffset == pathFragments[fragmentIndex].length) { - // nested TVFS file - final int fileReferenceCount = fileNode.getFileReferenceCount(); - if (fileReferenceCount == 1) { - // check if nested VFS - final Key encodingKey = fileNode.getFileReference(0).getEncodingKey(); - final TVFSFile tvfsFile = resolveTVFS(encodingKey); - - if (tvfsFile != null) { - // TVFS file to recursively resolve - if (tvfsFile.getRootNodeCount() != 1) { - throw new MalformedCASCStructureException("logic only defined for 1 TVFS root node"); - } - - fragmentIndex += 1; - fragmentOffset = 0; - return recursiveResolvePathFragments(pathFragments, fragmentIndex, fragmentOffset, - tvfsFile.getRootNode(0)); - } - } - } - - } else { - throw new IllegalArgumentException("unsupported node type"); - } - - // file not found - return null; - } - - /** - * Resolves a file from the specified path fragments representing a file system - * file path. - * - * @param pathFragments File path fragments. - * @return Path result for a file. - * @throws FileNotFoundException If the file does not exist in the file system. - * @throws IOException If an exception occurs when resolving the path - * fragments. - * - */ - public PathResult resolvePath(final byte[][] pathFragments) throws IOException { - if (pathFragments.length == 0) { - throw new IllegalArgumentException("pathFragments.length must be greater than 0"); - } - - if (tvfsRoot.getRootNodeCount() != 1) { - throw new MalformedCASCStructureException("logic only defined for 1 root node"); - } - - final FileNode result = recursiveResolvePathFragments(pathFragments, 0, 0, tvfsRoot.getRootNode(0)); - if (result == null) { - throw new FileNotFoundException("path not in storage"); - } - - return new PathResult(result, pathFragments); - } - - /** - * Resolves a TVFS file from an encoding key. The key is checked if it is a TVFS - * file in this file system and then resolved in local storage. The resulting - * file is then decoded as a TVFS file and returned. Decoded TVFS files are - * cached for improved performance. This method can be called concurrently. - * - * @param encodingKey Encoding key of TVFS file to resolve. - * @return The resolved TVFS file, or null if the encoding key is not for a TVFS - * file of this file system. - * @throws IOException If an error occurs when resolving the TVFS file. - */ - private TVFSFile resolveTVFS(final Key encodingKey) throws IOException { - TVFSFile tvfsFile = null; - final com.hiveworkshop.blizzard.casc.StorageReference storageReference = tvfsStorageReferences.get(encodingKey); - if (storageReference != null) { - // is a TVFS file of this file system - synchronized (this) { - tvfsFile = tvfsCache.get(encodingKey); - if (tvfsFile == null) { - // decode TVFS from storage - final ByteBuffer rootBuffer = fetchStoredBuffer(storageReference); - tvfsFile = decoder.loadFile(rootBuffer); - - tvfsCache.put(storageReference.getEncodingKey(), tvfsFile); - } - } - } - return tvfsFile; - } -} diff --git a/core/src/com/hiveworkshop/json/JSONArray.java b/core/src/com/hiveworkshop/json/JSONArray.java deleted file mode 100644 index 906d7b3a..00000000 --- a/core/src/com/hiveworkshop/json/JSONArray.java +++ /dev/null @@ -1,1458 +0,0 @@ -package com.hiveworkshop.json; - -/* - Copyright (c) 2002 JSON.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - The Software shall be used for Good, not Evil. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.Array; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - - -/** - * A JSONArray is an ordered sequence of values. Its external text form is a - * string wrapped in square brackets with commas separating the values. The - * internal form is an object having get and opt - * methods for accessing the values by index, and put methods for - * adding or replacing values. The values can be any of these types: - * Boolean, JSONArray, JSONObject, - * Number, String, or the - * JSONObject.NULL object. - *

- * The constructor can convert a JSON text into a Java object. The - * toString method converts to JSON text. - *

- * A get method returns a value if one can be found, and throws an - * exception if one cannot be found. An opt method returns a - * default value instead of throwing an exception, and so is useful for - * obtaining optional values. - *

- * The generic get() and opt() methods return an - * object which you can cast or query for type. There are also typed - * get and opt methods that do type checking and type - * coercion for you. - *

- * The texts produced by the toString methods strictly conform to - * JSON syntax rules. The constructors are more forgiving in the texts they will - * accept: - *

    - *
  • An extra , (comma) may appear just - * before the closing bracket.
  • - *
  • The null value will be inserted when there is , - *  (comma) elision.
  • - *
  • Strings may be quoted with ' (single - * quote).
  • - *
  • Strings do not need to be quoted at all if they do not begin with a quote - * or single quote, and if they do not contain leading or trailing spaces, and - * if they do not contain any of these characters: - * { } [ ] / \ : , # and if they do not look like numbers and - * if they are not the reserved words true, false, or - * null.
  • - *
- * - * @author JSON.org - * @version 2016-08/15 - */ -public class JSONArray implements Iterable { - - /** - * The arrayList where the JSONArray's properties are kept. - */ - private final ArrayList myArrayList; - - /** - * Construct an empty JSONArray. - */ - public JSONArray() { - this.myArrayList = new ArrayList(); - } - - /** - * Construct a JSONArray from a JSONTokener. - * - * @param x - * A JSONTokener - * @throws JSONException - * If there is a syntax error. - */ - public JSONArray(JSONTokener x) throws JSONException { - this(); - if (x.nextClean() != '[') { - throw x.syntaxError("A JSONArray text must start with '['"); - } - - char nextChar = x.nextClean(); - if (nextChar == 0) { - // array is unclosed. No ']' found, instead EOF - throw x.syntaxError("Expected a ',' or ']'"); - } - if (nextChar != ']') { - x.back(); - for (;;) { - if (x.nextClean() == ',') { - x.back(); - this.myArrayList.add(JSONObject.NULL); - } else { - x.back(); - this.myArrayList.add(x.nextValue()); - } - switch (x.nextClean()) { - case 0: - // array is unclosed. No ']' found, instead EOF - throw x.syntaxError("Expected a ',' or ']'"); - case ',': - nextChar = x.nextClean(); - if (nextChar == 0) { - // array is unclosed. No ']' found, instead EOF - throw x.syntaxError("Expected a ',' or ']'"); - } - if (nextChar == ']') { - return; - } - x.back(); - break; - case ']': - return; - default: - throw x.syntaxError("Expected a ',' or ']'"); - } - } - } - } - - /** - * Construct a JSONArray from a source JSON text. - * - * @param source - * A string that begins with [ (left - * bracket) and ends with ] - *  (right bracket). - * @throws JSONException - * If there is a syntax error. - */ - public JSONArray(String source) throws JSONException { - this(new JSONTokener(source)); - } - - /** - * Construct a JSONArray from a Collection. - * - * @param collection - * A Collection. - */ - public JSONArray(Collection collection) { - if (collection == null) { - this.myArrayList = new ArrayList(); - } else { - this.myArrayList = new ArrayList(collection.size()); - for (Object o: collection){ - this.myArrayList.add(JSONObject.wrap(o)); - } - } - } - - /** - * Construct a JSONArray from an array. - * - * @param array - * Array. If the parameter passed is null, or not an array, an - * exception will be thrown. - * - * @throws JSONException - * If not an array or if an array value is non-finite number. - * @throws NullPointerException - * Thrown if the array parameter is null. - */ - public JSONArray(Object array) throws JSONException { - this(); - if (array.getClass().isArray()) { - int length = Array.getLength(array); - this.myArrayList.ensureCapacity(length); - for (int i = 0; i < length; i += 1) { - this.put(JSONObject.wrap(Array.get(array, i))); - } - } else { - throw new JSONException( - "JSONArray initial value should be a string or collection or array."); - } - } - - @Override - public Iterator iterator() { - return this.myArrayList.iterator(); - } - - /** - * Get the object value associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. - * @return An object value. - * @throws JSONException - * If there is no value for the index. - */ - public Object get(int index) throws JSONException { - Object object = this.opt(index); - if (object == null) { - throw new JSONException("JSONArray[" + index + "] not found."); - } - return object; - } - - /** - * Get the boolean value associated with an index. The string values "true" - * and "false" are converted to boolean. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The truth. - * @throws JSONException - * If there is no value for the index or if the value is not - * convertible to boolean. - */ - public boolean getBoolean(int index) throws JSONException { - Object object = this.get(index); - if (object.equals(Boolean.FALSE) - || (object instanceof String && ((String) object) - .equalsIgnoreCase("false"))) { - return false; - } else if (object.equals(Boolean.TRUE) - || (object instanceof String && ((String) object) - .equalsIgnoreCase("true"))) { - return true; - } - throw new JSONException("JSONArray[" + index + "] is not a boolean."); - } - - /** - * Get the double value associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - * @throws JSONException - * If the key is not found or if the value cannot be converted - * to a number. - */ - public double getDouble(int index) throws JSONException { - return this.getNumber(index).doubleValue(); - } - - /** - * Get the float value associated with a key. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The numeric value. - * @throws JSONException - * if the key is not found or if the value is not a Number - * object and cannot be converted to a number. - */ - public float getFloat(int index) throws JSONException { - return this.getNumber(index).floatValue(); - } - - /** - * Get the Number value associated with a key. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The numeric value. - * @throws JSONException - * if the key is not found or if the value is not a Number - * object and cannot be converted to a number. - */ - public Number getNumber(int index) throws JSONException { - Object object = this.get(index); - try { - if (object instanceof Number) { - return (Number)object; - } - return JSONObject.stringToNumber(object.toString()); - } catch (Exception e) { - throw new JSONException("JSONArray[" + index + "] is not a number.", e); - } - } - - /** - * Get the enum value associated with an index. - * - * @param - * Enum Type - * @param clazz - * The type of enum to retrieve. - * @param index - * The index must be between 0 and length() - 1. - * @return The enum value at the index location - * @throws JSONException - * if the key is not found or if the value cannot be converted - * to an enum. - */ - public > E getEnum(Class clazz, int index) throws JSONException { - E val = optEnum(clazz, index); - if(val==null) { - // JSONException should really take a throwable argument. - // If it did, I would re-implement this with the Enum.valueOf - // method and place any thrown exception in the JSONException - throw new JSONException("JSONArray[" + index + "] is not an enum of type " - + JSONObject.quote(clazz.getSimpleName()) + "."); - } - return val; - } - - /** - * Get the BigDecimal value associated with an index. If the value is float - * or double, the the {@link BigDecimal#BigDecimal(double)} constructor - * will be used. See notes on the constructor for conversion issues that - * may arise. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - * @throws JSONException - * If the key is not found or if the value cannot be converted - * to a BigDecimal. - */ - public BigDecimal getBigDecimal (int index) throws JSONException { - Object object = this.get(index); - BigDecimal val = JSONObject.objectToBigDecimal(object, null); - if(val == null) { - throw new JSONException("JSONArray[" + index + - "] could not convert to BigDecimal ("+ object + ")."); - } - return val; - } - - /** - * Get the BigInteger value associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - * @throws JSONException - * If the key is not found or if the value cannot be converted - * to a BigInteger. - */ - public BigInteger getBigInteger (int index) throws JSONException { - Object object = this.get(index); - BigInteger val = JSONObject.objectToBigInteger(object, null); - if(val == null) { - throw new JSONException("JSONArray[" + index + - "] could not convert to BigDecimal ("+ object + ")."); - } - return val; - } - - /** - * Get the int value associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - * @throws JSONException - * If the key is not found or if the value is not a number. - */ - public int getInt(int index) throws JSONException { - return this.getNumber(index).intValue(); - } - - /** - * Get the JSONArray associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. - * @return A JSONArray value. - * @throws JSONException - * If there is no value for the index. or if the value is not a - * JSONArray - */ - public JSONArray getJSONArray(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof JSONArray) { - return (JSONArray) object; - } - throw new JSONException("JSONArray[" + index + "] is not a JSONArray."); - } - - /** - * Get the JSONObject associated with an index. - * - * @param index - * subscript - * @return A JSONObject value. - * @throws JSONException - * If there is no value for the index or if the value is not a - * JSONObject - */ - public JSONObject getJSONObject(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof JSONObject) { - return (JSONObject) object; - } - throw new JSONException("JSONArray[" + index + "] is not a JSONObject."); - } - - /** - * Get the long value associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - * @throws JSONException - * If the key is not found or if the value cannot be converted - * to a number. - */ - public long getLong(int index) throws JSONException { - return this.getNumber(index).longValue(); - } - - /** - * Get the string associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. - * @return A string value. - * @throws JSONException - * If there is no string value for the index. - */ - public String getString(int index) throws JSONException { - Object object = this.get(index); - if (object instanceof String) { - return (String) object; - } - throw new JSONException("JSONArray[" + index + "] not a string."); - } - - /** - * Determine if the value is null. - * - * @param index - * The index must be between 0 and length() - 1. - * @return true if the value at the index is null, or if there is no value. - */ - public boolean isNull(int index) { - return JSONObject.NULL.equals(this.opt(index)); - } - - /** - * Make a string from the contents of this JSONArray. The - * separator string is inserted between each element. Warning: - * This method assumes that the data structure is acyclical. - * - * @param separator - * A string that will be inserted between the elements. - * @return a string. - * @throws JSONException - * If the array contains an invalid number. - */ - public String join(String separator) throws JSONException { - int len = this.length(); - if (len == 0) { - return ""; - } - - StringBuilder sb = new StringBuilder( - JSONObject.valueToString(this.myArrayList.get(0))); - - for (int i = 1; i < len; i++) { - sb.append(separator) - .append(JSONObject.valueToString(this.myArrayList.get(i))); - } - return sb.toString(); - } - - /** - * Get the number of elements in the JSONArray, included nulls. - * - * @return The length (or size). - */ - public int length() { - return this.myArrayList.size(); - } - - /** - * Get the optional object value associated with an index. - * - * @param index - * The index must be between 0 and length() - 1. If not, null is returned. - * @return An object value, or null if there is no object at that index. - */ - public Object opt(int index) { - return (index < 0 || index >= this.length()) ? null : this.myArrayList - .get(index); - } - - /** - * Get the optional boolean value associated with an index. It returns false - * if there is no value at that index, or if the value is not Boolean.TRUE - * or the String "true". - * - * @param index - * The index must be between 0 and length() - 1. - * @return The truth. - */ - public boolean optBoolean(int index) { - return this.optBoolean(index, false); - } - - /** - * Get the optional boolean value associated with an index. It returns the - * defaultValue if there is no value at that index or if it is not a Boolean - * or the String "true" or "false" (case insensitive). - * - * @param index - * The index must be between 0 and length() - 1. - * @param defaultValue - * A boolean default. - * @return The truth. - */ - public boolean optBoolean(int index, boolean defaultValue) { - try { - return this.getBoolean(index); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get the optional double value associated with an index. NaN is returned - * if there is no value for the index, or if the value is not a number and - * cannot be converted to a number. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - */ - public double optDouble(int index) { - return this.optDouble(index, Double.NaN); - } - - /** - * Get the optional double value associated with an index. The defaultValue - * is returned if there is no value for the index, or if the value is not a - * number and cannot be converted to a number. - * - * @param index - * subscript - * @param defaultValue - * The default value. - * @return The value. - */ - public double optDouble(int index, double defaultValue) { - final Number val = this.optNumber(index, null); - if (val == null) { - return defaultValue; - } - final double doubleValue = val.doubleValue(); - // if (Double.isNaN(doubleValue) || Double.isInfinite(doubleValue)) { - // return defaultValue; - // } - return doubleValue; - } - - /** - * Get the optional float value associated with an index. NaN is returned - * if there is no value for the index, or if the value is not a number and - * cannot be converted to a number. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - */ - public float optFloat(int index) { - return this.optFloat(index, Float.NaN); - } - - /** - * Get the optional float value associated with an index. The defaultValue - * is returned if there is no value for the index, or if the value is not a - * number and cannot be converted to a number. - * - * @param index - * subscript - * @param defaultValue - * The default value. - * @return The value. - */ - public float optFloat(int index, float defaultValue) { - final Number val = this.optNumber(index, null); - if (val == null) { - return defaultValue; - } - final float floatValue = val.floatValue(); - // if (Float.isNaN(floatValue) || Float.isInfinite(floatValue)) { - // return floatValue; - // } - return floatValue; - } - - /** - * Get the optional int value associated with an index. Zero is returned if - * there is no value for the index, or if the value is not a number and - * cannot be converted to a number. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - */ - public int optInt(int index) { - return this.optInt(index, 0); - } - - /** - * Get the optional int value associated with an index. The defaultValue is - * returned if there is no value for the index, or if the value is not a - * number and cannot be converted to a number. - * - * @param index - * The index must be between 0 and length() - 1. - * @param defaultValue - * The default value. - * @return The value. - */ - public int optInt(int index, int defaultValue) { - final Number val = this.optNumber(index, null); - if (val == null) { - return defaultValue; - } - return val.intValue(); - } - - /** - * Get the enum value associated with a key. - * - * @param - * Enum Type - * @param clazz - * The type of enum to retrieve. - * @param index - * The index must be between 0 and length() - 1. - * @return The enum value at the index location or null if not found - */ - public > E optEnum(Class clazz, int index) { - return this.optEnum(clazz, index, null); - } - - /** - * Get the enum value associated with a key. - * - * @param - * Enum Type - * @param clazz - * The type of enum to retrieve. - * @param index - * The index must be between 0 and length() - 1. - * @param defaultValue - * The default in case the value is not found - * @return The enum value at the index location or defaultValue if - * the value is not found or cannot be assigned to clazz - */ - public > E optEnum(Class clazz, int index, E defaultValue) { - try { - Object val = this.opt(index); - if (JSONObject.NULL.equals(val)) { - return defaultValue; - } - if (clazz.isAssignableFrom(val.getClass())) { - // we just checked it! - @SuppressWarnings("unchecked") - E myE = (E) val; - return myE; - } - return Enum.valueOf(clazz, val.toString()); - } catch (IllegalArgumentException e) { - return defaultValue; - } catch (NullPointerException e) { - return defaultValue; - } - } - - /** - * Get the optional BigInteger value associated with an index. The - * defaultValue is returned if there is no value for the index, or if the - * value is not a number and cannot be converted to a number. - * - * @param index - * The index must be between 0 and length() - 1. - * @param defaultValue - * The default value. - * @return The value. - */ - public BigInteger optBigInteger(int index, BigInteger defaultValue) { - Object val = this.opt(index); - return JSONObject.objectToBigInteger(val, defaultValue); - } - - /** - * Get the optional BigDecimal value associated with an index. The - * defaultValue is returned if there is no value for the index, or if the - * value is not a number and cannot be converted to a number. If the value - * is float or double, the the {@link BigDecimal#BigDecimal(double)} - * constructor will be used. See notes on the constructor for conversion - * issues that may arise. - * - * @param index - * The index must be between 0 and length() - 1. - * @param defaultValue - * The default value. - * @return The value. - */ - public BigDecimal optBigDecimal(int index, BigDecimal defaultValue) { - Object val = this.opt(index); - return JSONObject.objectToBigDecimal(val, defaultValue); - } - - /** - * Get the optional JSONArray associated with an index. - * - * @param index - * subscript - * @return A JSONArray value, or null if the index has no value, or if the - * value is not a JSONArray. - */ - public JSONArray optJSONArray(int index) { - Object o = this.opt(index); - return o instanceof JSONArray ? (JSONArray) o : null; - } - - /** - * Get the optional JSONObject associated with an index. Null is returned if - * the key is not found, or null if the index has no value, or if the value - * is not a JSONObject. - * - * @param index - * The index must be between 0 and length() - 1. - * @return A JSONObject value. - */ - public JSONObject optJSONObject(int index) { - Object o = this.opt(index); - return o instanceof JSONObject ? (JSONObject) o : null; - } - - /** - * Get the optional long value associated with an index. Zero is returned if - * there is no value for the index, or if the value is not a number and - * cannot be converted to a number. - * - * @param index - * The index must be between 0 and length() - 1. - * @return The value. - */ - public long optLong(int index) { - return this.optLong(index, 0); - } - - /** - * Get the optional long value associated with an index. The defaultValue is - * returned if there is no value for the index, or if the value is not a - * number and cannot be converted to a number. - * - * @param index - * The index must be between 0 and length() - 1. - * @param defaultValue - * The default value. - * @return The value. - */ - public long optLong(int index, long defaultValue) { - final Number val = this.optNumber(index, null); - if (val == null) { - return defaultValue; - } - return val.longValue(); - } - - /** - * Get an optional {@link Number} value associated with a key, or null - * if there is no such key or if the value is not a number. If the value is a string, - * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method - * would be used in cases where type coercion of the number value is unwanted. - * - * @param index - * The index must be between 0 and length() - 1. - * @return An object which is the value. - */ - public Number optNumber(int index) { - return this.optNumber(index, null); - } - - /** - * Get an optional {@link Number} value associated with a key, or the default if there - * is no such key or if the value is not a number. If the value is a string, - * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method - * would be used in cases where type coercion of the number value is unwanted. - * - * @param index - * The index must be between 0 and length() - 1. - * @param defaultValue - * The default. - * @return An object which is the value. - */ - public Number optNumber(int index, Number defaultValue) { - Object val = this.opt(index); - if (JSONObject.NULL.equals(val)) { - return defaultValue; - } - if (val instanceof Number){ - return (Number) val; - } - - if (val instanceof String) { - try { - return JSONObject.stringToNumber((String) val); - } catch (Exception e) { - return defaultValue; - } - } - return defaultValue; - } - - /** - * Get the optional string value associated with an index. It returns an - * empty string if there is no value at that index. If the value is not a - * string and is not null, then it is converted to a string. - * - * @param index - * The index must be between 0 and length() - 1. - * @return A String value. - */ - public String optString(int index) { - return this.optString(index, ""); - } - - /** - * Get the optional string associated with an index. The defaultValue is - * returned if the key is not found. - * - * @param index - * The index must be between 0 and length() - 1. - * @param defaultValue - * The default value. - * @return A String value. - */ - public String optString(int index, String defaultValue) { - Object object = this.opt(index); - return JSONObject.NULL.equals(object) ? defaultValue : object - .toString(); - } - - /** - * Append a boolean value. This increases the array's length by one. - * - * @param value - * A boolean value. - * @return this. - */ - public JSONArray put(boolean value) { - return this.put(value ? Boolean.TRUE : Boolean.FALSE); - } - - /** - * Put a value in the JSONArray, where the value will be a JSONArray which - * is produced from a Collection. - * - * @param value - * A Collection value. - * @return this. - * @throws JSONException - * If the value is non-finite number. - */ - public JSONArray put(Collection value) { - return this.put(new JSONArray(value)); - } - - /** - * Append a double value. This increases the array's length by one. - * - * @param value - * A double value. - * @return this. - * @throws JSONException - * if the value is not finite. - */ - public JSONArray put(double value) throws JSONException { - return this.put(Double.valueOf(value)); - } - - /** - * Append a float value. This increases the array's length by one. - * - * @param value - * A float value. - * @return this. - * @throws JSONException - * if the value is not finite. - */ - public JSONArray put(float value) throws JSONException { - return this.put(Float.valueOf(value)); - } - - /** - * Append an int value. This increases the array's length by one. - * - * @param value - * An int value. - * @return this. - */ - public JSONArray put(int value) { - return this.put(Integer.valueOf(value)); - } - - /** - * Append an long value. This increases the array's length by one. - * - * @param value - * A long value. - * @return this. - */ - public JSONArray put(long value) { - return this.put(Long.valueOf(value)); - } - - /** - * Put a value in the JSONArray, where the value will be a JSONObject which - * is produced from a Map. - * - * @param value - * A Map value. - * @return this. - * @throws JSONException - * If a value in the map is non-finite number. - * @throws NullPointerException - * If a key in the map is null - */ - public JSONArray put(Map value) { - return this.put(new JSONObject(value)); - } - - /** - * Append an object value. This increases the array's length by one. - * - * @param value - * An object value. The value should be a Boolean, Double, - * Integer, JSONArray, JSONObject, Long, or String, or the - * JSONObject.NULL object. - * @return this. - * @throws JSONException - * If the value is non-finite number. - */ - public JSONArray put(Object value) { - JSONObject.testValidity(value); - this.myArrayList.add(value); - return this; - } - - /** - * Put or replace a boolean value in the JSONArray. If the index is greater - * than the length of the JSONArray, then null elements will be added as - * necessary to pad it out. - * - * @param index - * The subscript. - * @param value - * A boolean value. - * @return this. - * @throws JSONException - * If the index is negative. - */ - public JSONArray put(int index, boolean value) throws JSONException { - return this.put(index, value ? Boolean.TRUE : Boolean.FALSE); - } - - /** - * Put a value in the JSONArray, where the value will be a JSONArray which - * is produced from a Collection. - * - * @param index - * The subscript. - * @param value - * A Collection value. - * @return this. - * @throws JSONException - * If the index is negative or if the value is non-finite. - */ - public JSONArray put(int index, Collection value) throws JSONException { - return this.put(index, new JSONArray(value)); - } - - /** - * Put or replace a double value. If the index is greater than the length of - * the JSONArray, then null elements will be added as necessary to pad it - * out. - * - * @param index - * The subscript. - * @param value - * A double value. - * @return this. - * @throws JSONException - * If the index is negative or if the value is non-finite. - */ - public JSONArray put(int index, double value) throws JSONException { - return this.put(index, Double.valueOf(value)); - } - - /** - * Put or replace a float value. If the index is greater than the length of - * the JSONArray, then null elements will be added as necessary to pad it - * out. - * - * @param index - * The subscript. - * @param value - * A float value. - * @return this. - * @throws JSONException - * If the index is negative or if the value is non-finite. - */ - public JSONArray put(int index, float value) throws JSONException { - return this.put(index, Float.valueOf(value)); - } - - /** - * Put or replace an int value. If the index is greater than the length of - * the JSONArray, then null elements will be added as necessary to pad it - * out. - * - * @param index - * The subscript. - * @param value - * An int value. - * @return this. - * @throws JSONException - * If the index is negative. - */ - public JSONArray put(int index, int value) throws JSONException { - return this.put(index, Integer.valueOf(value)); - } - - /** - * Put or replace a long value. If the index is greater than the length of - * the JSONArray, then null elements will be added as necessary to pad it - * out. - * - * @param index - * The subscript. - * @param value - * A long value. - * @return this. - * @throws JSONException - * If the index is negative. - */ - public JSONArray put(int index, long value) throws JSONException { - return this.put(index, Long.valueOf(value)); - } - - /** - * Put a value in the JSONArray, where the value will be a JSONObject that - * is produced from a Map. - * - * @param index - * The subscript. - * @param value - * The Map value. - * @return this. - * @throws JSONException - * If the index is negative or if the the value is an invalid - * number. - * @throws NullPointerException - * If a key in the map is null - */ - public JSONArray put(int index, Map value) throws JSONException { - this.put(index, new JSONObject(value)); - return this; - } - - /** - * Put or replace an object value in the JSONArray. If the index is greater - * than the length of the JSONArray, then null elements will be added as - * necessary to pad it out. - * - * @param index - * The subscript. - * @param value - * The value to put into the array. The value should be a - * Boolean, Double, Integer, JSONArray, JSONObject, Long, or - * String, or the JSONObject.NULL object. - * @return this. - * @throws JSONException - * If the index is negative or if the the value is an invalid - * number. - */ - public JSONArray put(int index, Object value) throws JSONException { - if (index < 0) { - throw new JSONException("JSONArray[" + index + "] not found."); - } - if (index < this.length()) { - JSONObject.testValidity(value); - this.myArrayList.set(index, value); - return this; - } - if(index == this.length()){ - // simple append - return this.put(value); - } - // if we are inserting past the length, we want to grow the array all at once - // instead of incrementally. - this.myArrayList.ensureCapacity(index + 1); - while (index != this.length()) { - // we don't need to test validity of NULL objects - this.myArrayList.add(JSONObject.NULL); - } - return this.put(value); - } - - /** - * Creates a JSONPointer using an initialization string and tries to - * match it to an item within this JSONArray. For example, given a - * JSONArray initialized with this document: - *
-     * [
-     *     {"b":"c"}
-     * ]
-     * 
- * and this JSONPointer string: - *
-     * "/0/b"
-     * 
- * Then this method will return the String "c" - * A JSONPointerException may be thrown from code called by this method. - * - * @param jsonPointer string that can be used to create a JSONPointer - * @return the item matched by the JSONPointer, otherwise null - */ - public Object query(String jsonPointer) { - return query(new JSONPointer(jsonPointer)); - } - - /** - * Uses a user initialized JSONPointer and tries to - * match it to an item within this JSONArray. For example, given a - * JSONArray initialized with this document: - *
-     * [
-     *     {"b":"c"}
-     * ]
-     * 
- * and this JSONPointer: - *
-     * "/0/b"
-     * 
- * Then this method will return the String "c" - * A JSONPointerException may be thrown from code called by this method. - * - * @param jsonPointer string that can be used to create a JSONPointer - * @return the item matched by the JSONPointer, otherwise null - */ - public Object query(JSONPointer jsonPointer) { - return jsonPointer.queryFrom(this); - } - - /** - * Queries and returns a value from this object using {@code jsonPointer}, or - * returns null if the query fails due to a missing key. - * - * @param jsonPointer the string representation of the JSON pointer - * @return the queried value or {@code null} - * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax - */ - public Object optQuery(String jsonPointer) { - return optQuery(new JSONPointer(jsonPointer)); - } - - /** - * Queries and returns a value from this object using {@code jsonPointer}, or - * returns null if the query fails due to a missing key. - * - * @param jsonPointer The JSON pointer - * @return the queried value or {@code null} - * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax - */ - public Object optQuery(JSONPointer jsonPointer) { - try { - return jsonPointer.queryFrom(this); - } catch (JSONPointerException e) { - return null; - } - } - - /** - * Remove an index and close the hole. - * - * @param index - * The index of the element to be removed. - * @return The value that was associated with the index, or null if there - * was no value. - */ - public Object remove(int index) { - return index >= 0 && index < this.length() - ? this.myArrayList.remove(index) - : null; - } - - /** - * Determine if two JSONArrays are similar. - * They must contain similar sequences. - * - * @param other The other JSONArray - * @return true if they are equal - */ - public boolean similar(Object other) { - if (!(other instanceof JSONArray)) { - return false; - } - int len = this.length(); - if (len != ((JSONArray)other).length()) { - return false; - } - for (int i = 0; i < len; i += 1) { - Object valueThis = this.myArrayList.get(i); - Object valueOther = ((JSONArray)other).myArrayList.get(i); - if(valueThis == valueOther) { - continue; - } - if(valueThis == null) { - return false; - } - if (valueThis instanceof JSONObject) { - if (!((JSONObject)valueThis).similar(valueOther)) { - return false; - } - } else if (valueThis instanceof JSONArray) { - if (!((JSONArray)valueThis).similar(valueOther)) { - return false; - } - } else if (!valueThis.equals(valueOther)) { - return false; - } - } - return true; - } - - /** - * Produce a JSONObject by combining a JSONArray of names with the values of - * this JSONArray. - * - * @param names - * A JSONArray containing a list of key strings. These will be - * paired with the values. - * @return A JSONObject, or null if there are no names or if this JSONArray - * has no values. - * @throws JSONException - * If any of the names are null. - */ - public JSONObject toJSONObject(JSONArray names) throws JSONException { - if (names == null || names.isEmpty() || this.isEmpty()) { - return null; - } - JSONObject jo = new JSONObject(names.length()); - for (int i = 0; i < names.length(); i += 1) { - jo.put(names.getString(i), this.opt(i)); - } - return jo; - } - - /** - * Make a JSON text of this JSONArray. For compactness, no unnecessary - * whitespace is added. If it is not possible to produce a syntactically - * correct JSON text then null will be returned instead. This could occur if - * the array contains an invalid number. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * - * @return a printable, displayable, transmittable representation of the - * array. - */ - @Override - public String toString() { - try { - return this.toString(0); - } catch (Exception e) { - return null; - } - } - - /** - * Make a pretty-printed JSON text of this JSONArray. - * - *

If indentFactor > 0 and the {@link JSONArray} has only - * one element, then the array will be output on a single line: - *

{@code [1]}
- * - *

If an array has 2 or more elements, then it will be output across - * multiple lines:

{@code
-     * [
-     * 1,
-     * "value 2",
-     * 3
-     * ]
-     * }
- *

- * Warning: This method assumes that the data structure is acyclical. - * - * - * @param indentFactor - * The number of spaces to add to each level of indentation. - * @return a printable, displayable, transmittable representation of the - * object, beginning with [ (left - * bracket) and ending with ] - *  (right bracket). - * @throws JSONException - */ - public String toString(int indentFactor) throws JSONException { - StringWriter sw = new StringWriter(); - synchronized (sw.getBuffer()) { - return this.write(sw, indentFactor, 0).toString(); - } - } - - /** - * Write the contents of the JSONArray as JSON text to a writer. For - * compactness, no whitespace is added. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * - * @return The writer. - * @throws JSONException - */ - public Writer write(Writer writer) throws JSONException { - return this.write(writer, 0, 0); - } - - /** - * Write the contents of the JSONArray as JSON text to a writer. - * - *

If indentFactor > 0 and the {@link JSONArray} has only - * one element, then the array will be output on a single line: - *

{@code [1]}
- * - *

If an array has 2 or more elements, then it will be output across - * multiple lines:

{@code
-     * [
-     * 1,
-     * "value 2",
-     * 3
-     * ]
-     * }
- *

- * Warning: This method assumes that the data structure is acyclical. - * - * - * @param writer - * Writes the serialized JSON - * @param indentFactor - * The number of spaces to add to each level of indentation. - * @param indent - * The indentation of the top level. - * @return The writer. - * @throws JSONException - */ - public Writer write(Writer writer, int indentFactor, int indent) - throws JSONException { - try { - boolean commanate = false; - int length = this.length(); - writer.write('['); - - if (length == 1) { - try { - JSONObject.writeValue(writer, this.myArrayList.get(0), - indentFactor, indent); - } catch (Exception e) { - throw new JSONException("Unable to write JSONArray value at index: 0", e); - } - } else if (length != 0) { - final int newindent = indent + indentFactor; - - for (int i = 0; i < length; i += 1) { - if (commanate) { - writer.write(','); - } - if (indentFactor > 0) { - writer.write('\n'); - } - JSONObject.indent(writer, newindent); - try { - JSONObject.writeValue(writer, this.myArrayList.get(i), - indentFactor, newindent); - } catch (Exception e) { - throw new JSONException("Unable to write JSONArray value at index: " + i, e); - } - commanate = true; - } - if (indentFactor > 0) { - writer.write('\n'); - } - JSONObject.indent(writer, indent); - } - writer.write(']'); - return writer; - } catch (IOException e) { - throw new JSONException(e); - } - } - - /** - * Returns a java.util.List containing all of the elements in this array. - * If an element in the array is a JSONArray or JSONObject it will also - * be converted. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return a java.util.List containing the elements of this array - */ - public List toList() { - List results = new ArrayList(this.myArrayList.size()); - for (Object element : this.myArrayList) { - if (element == null || JSONObject.NULL.equals(element)) { - results.add(null); - } else if (element instanceof JSONArray) { - results.add(((JSONArray) element).toList()); - } else if (element instanceof JSONObject) { - results.add(((JSONObject) element).toMap()); - } else { - results.add(element); - } - } - return results; - } - - /** - * Check if JSONArray is empty. - * - * @return true if JSONArray is empty, otherwise false. - */ - public boolean isEmpty() { - return this.myArrayList.isEmpty(); - } - -} diff --git a/core/src/com/hiveworkshop/json/JSONException.java b/core/src/com/hiveworkshop/json/JSONException.java deleted file mode 100644 index f924fb54..00000000 --- a/core/src/com/hiveworkshop/json/JSONException.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.hiveworkshop.json; - -/** - * The JSONException is thrown by the JSON.org classes when things are amiss. - * - * @author JSON.org - * @version 2015-12-09 - */ -public class JSONException extends RuntimeException { - /** Serialization ID */ - private static final long serialVersionUID = 0; - - /** - * Constructs a JSONException with an explanatory message. - * - * @param message - * Detail about the reason for the exception. - */ - public JSONException(final String message) { - super(message); - } - - /** - * Constructs a JSONException with an explanatory message and cause. - * - * @param message - * Detail about the reason for the exception. - * @param cause - * The cause. - */ - public JSONException(final String message, final Throwable cause) { - super(message, cause); - } - - /** - * Constructs a new JSONException with the specified cause. - * - * @param cause - * The cause. - */ - public JSONException(final Throwable cause) { - super(cause.getMessage(), cause); - } - -} diff --git a/core/src/com/hiveworkshop/json/JSONObject.java b/core/src/com/hiveworkshop/json/JSONObject.java deleted file mode 100644 index 3bfd26ce..00000000 --- a/core/src/com/hiveworkshop/json/JSONObject.java +++ /dev/null @@ -1,2551 +0,0 @@ -package com.hiveworkshop.json; - -import java.io.Closeable; - -/* - Copyright (c) 2002 JSON.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - The Software shall be used for Good, not Evil. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import java.util.ResourceBundle; -import java.util.Set; -import java.util.regex.Pattern; - -/** - * A JSONObject is an unordered collection of name/value pairs. Its external - * form is a string wrapped in curly braces with colons between the names and - * values, and commas between the values and names. The internal form is an - * object having get and opt methods for accessing - * the values by name, and put methods for adding or replacing - * values by name. The values can be any of these types: Boolean, - * JSONArray, JSONObject, Number, - * String, or the JSONObject.NULL object. A - * JSONObject constructor can be used to convert an external form JSON text - * into an internal form whose values can be retrieved with the - * get and opt methods, or to convert values into a - * JSON text using the put and toString methods. A - * get method returns a value if one can be found, and throws an - * exception if one cannot be found. An opt method returns a - * default value instead of throwing an exception, and so is useful for - * obtaining optional values. - *

- * The generic get() and opt() methods return an - * object, which you can cast or query for type. There are also typed - * get and opt methods that do type checking and type - * coercion for you. The opt methods differ from the get methods in that they - * do not throw. Instead, they return a specified value, such as null. - *

- * The put methods add or replace values in an object. For - * example, - * - *

- * myString = new JSONObject()
- *         .put("JSON", "Hello, World!").toString();
- * 
- * - * produces the string {"JSON": "Hello, World"}. - *

- * The texts produced by the toString methods strictly conform to - * the JSON syntax rules. The constructors are more forgiving in the texts they - * will accept: - *

    - *
  • An extra , (comma) may appear just - * before the closing brace.
  • - *
  • Strings may be quoted with ' (single - * quote).
  • - *
  • Strings do not need to be quoted at all if they do not begin with a - * quote or single quote, and if they do not contain leading or trailing - * spaces, and if they do not contain any of these characters: - * { } [ ] / \ : , # and if they do not look like numbers and - * if they are not the reserved words true, false, - * or null.
  • - *
- * - * @author JSON.org - * @version 2016-08-15 - */ -public class JSONObject { - /** - * JSONObject.NULL is equivalent to the value that JavaScript calls null, - * whilst Java's null is equivalent to the value that JavaScript calls - * undefined. - */ - private static final class Null { - - /** - * There is only intended to be a single instance of the NULL object, - * so the clone method returns itself. - * - * @return NULL. - */ - @Override - protected final Object clone() { - return this; - } - - /** - * A Null object is equal to the null value and to itself. - * - * @param object - * An object to test for nullness. - * @return true if the object parameter is the JSONObject.NULL object or - * null. - */ - @Override - public boolean equals(Object object) { - return object == null || object == this; - } - /** - * A Null object is equal to the null value and to itself. - * - * @return always returns 0. - */ - @Override - public int hashCode() { - return 0; - } - - /** - * Get the "null" string value. - * - * @return The string "null". - */ - @Override - public String toString() { - return "null"; - } - } - - /** - * Regular Expression Pattern that matches JSON Numbers. This is primarily used for - * output to guarantee that we are always writing valid JSON. - */ - static final Pattern NUMBER_PATTERN = Pattern.compile("-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?"); - - /** - * The map where the JSONObject's properties are kept. - */ - private final Map map; - - /** - * It is sometimes more convenient and less ambiguous to have a - * NULL object than to use Java's null value. - * JSONObject.NULL.equals(null) returns true. - * JSONObject.NULL.toString() returns "null". - */ - public static final Object NULL = new Null(); - - /** - * Construct an empty JSONObject. - */ - public JSONObject() { - // HashMap is used on purpose to ensure that elements are unordered by - // the specification. - // JSON tends to be a portable transfer format to allows the container - // implementations to rearrange their items for a faster element - // retrieval based on associative access. - // Therefore, an implementation mustn't rely on the order of the item. - this.map = new HashMap(); - } - - /** - * Construct a JSONObject from a subset of another JSONObject. An array of - * strings is used to identify the keys that should be copied. Missing keys - * are ignored. - * - * @param jo - * A JSONObject. - * @param names - * An array of strings. - */ - public JSONObject(JSONObject jo, String[] names) { - this(names.length); - for (int i = 0; i < names.length; i += 1) { - try { - this.putOnce(names[i], jo.opt(names[i])); - } catch (Exception ignore) { - } - } - } - - /** - * Construct a JSONObject from a JSONTokener. - * - * @param x - * A JSONTokener object containing the source string. - * @throws JSONException - * If there is a syntax error in the source string or a - * duplicated key. - */ - public JSONObject(JSONTokener x) throws JSONException { - this(); - char c; - String key; - - if (x.nextClean() != '{') { - throw x.syntaxError("A JSONObject text must begin with '{'"); - } - for (;;) { - c = x.nextClean(); - switch (c) { - case 0: - throw x.syntaxError("A JSONObject text must end with '}'"); - case '}': - return; - default: - x.back(); - key = x.nextValue().toString(); - } - - // The key is followed by ':'. - - c = x.nextClean(); - if (c != ':') { - throw x.syntaxError("Expected a ':' after a key"); - } - - // Use syntaxError(..) to include error location - - if (key != null) { - // Check if key exists - if (this.opt(key) != null) { - // key already exists - throw x.syntaxError("Duplicate key \"" + key + "\""); - } - // Only add value if non-null - Object value = x.nextValue(); - if (value!=null) { - this.put(key, value); - } - } - - // Pairs are separated by ','. - - switch (x.nextClean()) { - case ';': - case ',': - if (x.nextClean() == '}') { - return; - } - x.back(); - break; - case '}': - return; - default: - throw x.syntaxError("Expected a ',' or '}'"); - } - } - } - - /** - * Construct a JSONObject from a Map. - * - * @param m - * A map object that can be used to initialize the contents of - * the JSONObject. - * @throws JSONException - * If a value in the map is non-finite number. - * @throws NullPointerException - * If a key in the map is null - */ - public JSONObject(Map m) { - if (m == null) { - this.map = new HashMap(); - } else { - this.map = new HashMap(m.size()); - for (final Entry e : m.entrySet()) { - if(e.getKey() == null) { - throw new NullPointerException("Null key."); - } - final Object value = e.getValue(); - if (value != null) { - this.map.put(String.valueOf(e.getKey()), wrap(value)); - } - } - } - } - - /** - * Construct a JSONObject from an Object using bean getters. It reflects on - * all of the public methods of the object. For each of the methods with no - * parameters and a name starting with "get" or - * "is" followed by an uppercase letter, the method is invoked, - * and a key and the value returned from the getter method are put into the - * new JSONObject. - *

- * The key is formed by removing the "get" or "is" - * prefix. If the second remaining character is not upper case, then the - * first character is converted to lower case. - *

- * Methods that are static, return void, - * have parameters, or are "bridge" methods, are ignored. - *

- * For example, if an object has a method named "getName", and - * if the result of calling object.getName() is - * "Larry Fine", then the JSONObject will contain - * "name": "Larry Fine". - *

- * The {@link JSONPropertyName} annotation can be used on a bean getter to - * override key name used in the JSONObject. For example, using the object - * above with the getName method, if we annotated it with: - *

-     * @JSONPropertyName("FullName")
-     * public String getName() { return this.name; }
-     * 
- * The resulting JSON object would contain "FullName": "Larry Fine" - *

- * Similarly, the {@link JSONPropertyName} annotation can be used on non- - * get and is methods. We can also override key - * name used in the JSONObject as seen below even though the field would normally - * be ignored: - *

-     * @JSONPropertyName("FullName")
-     * public String fullName() { return this.name; }
-     * 
- * The resulting JSON object would contain "FullName": "Larry Fine" - *

- * The {@link JSONPropertyIgnore} annotation can be used to force the bean property - * to not be serialized into JSON. If both {@link JSONPropertyIgnore} and - * {@link JSONPropertyName} are defined on the same method, a depth comparison is - * performed and the one closest to the concrete class being serialized is used. - * If both annotations are at the same level, then the {@link JSONPropertyIgnore} - * annotation takes precedent and the field is not serialized. - * For example, the following declaration would prevent the getName - * method from being serialized: - *

-     * @JSONPropertyName("FullName")
-     * @JSONPropertyIgnore 
-     * public String getName() { return this.name; }
-     * 
- *

- * - * @param bean - * An object that has getter methods that should be used to make - * a JSONObject. - */ - public JSONObject(Object bean) { - this(); - this.populateMap(bean); - } - - /** - * Construct a JSONObject from an Object, using reflection to find the - * public members. The resulting JSONObject's keys will be the strings from - * the names array, and the values will be the field values associated with - * those keys in the object. If a key is not found or not visible, then it - * will not be copied into the new JSONObject. - * - * @param object - * An object that has fields that should be used to make a - * JSONObject. - * @param names - * An array of strings, the names of the fields to be obtained - * from the object. - */ - public JSONObject(Object object, String names[]) { - this(names.length); - Class c = object.getClass(); - for (int i = 0; i < names.length; i += 1) { - String name = names[i]; - try { - this.putOpt(name, c.getField(name).get(object)); - } catch (Exception ignore) { - } - } - } - - /** - * Construct a JSONObject from a source JSON text string. This is the most - * commonly used JSONObject constructor. - * - * @param source - * A string beginning with { (left - * brace) and ending with } - *  (right brace). - * @exception JSONException - * If there is a syntax error in the source string or a - * duplicated key. - */ - public JSONObject(String source) throws JSONException { - this(new JSONTokener(source)); - } - - /** - * Construct a JSONObject from a ResourceBundle. - * - * @param baseName - * The ResourceBundle base name. - * @param locale - * The Locale to load the ResourceBundle for. - * @throws JSONException - * If any JSONExceptions are detected. - */ - public JSONObject(String baseName, Locale locale) throws JSONException { - this(); - ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale, - Thread.currentThread().getContextClassLoader()); - -// Iterate through the keys in the bundle. - - Enumeration keys = bundle.getKeys(); - while (keys.hasMoreElements()) { - Object key = keys.nextElement(); - if (key != null) { - -// Go through the path, ensuring that there is a nested JSONObject for each -// segment except the last. Add the value using the last segment's name into -// the deepest nested JSONObject. - - String[] path = ((String) key).split("\\."); - int last = path.length - 1; - JSONObject target = this; - for (int i = 0; i < last; i += 1) { - String segment = path[i]; - JSONObject nextTarget = target.optJSONObject(segment); - if (nextTarget == null) { - nextTarget = new JSONObject(); - target.put(segment, nextTarget); - } - target = nextTarget; - } - target.put(path[last], bundle.getString((String) key)); - } - } - } - - /** - * Constructor to specify an initial capacity of the internal map. Useful for library - * internal calls where we know, or at least can best guess, how big this JSONObject - * will be. - * - * @param initialCapacity initial capacity of the internal map. - */ - protected JSONObject(int initialCapacity){ - this.map = new HashMap(initialCapacity); - } - - /** - * Accumulate values under a key. It is similar to the put method except - * that if there is already an object stored under the key then a JSONArray - * is stored under the key to hold all of the accumulated values. If there - * is already a JSONArray, then the new value is appended to it. In - * contrast, the put method replaces the previous value. - * - * If only one value is accumulated that is not a JSONArray, then the result - * will be the same as using put. But if multiple values are accumulated, - * then the result will be like append. - * - * @param key - * A key string. - * @param value - * An object to be accumulated under the key. - * @return this. - * @throws JSONException - * If the value is non-finite number. - * @throws NullPointerException - * If the key is null. - */ - public JSONObject accumulate(String key, Object value) throws JSONException { - testValidity(value); - Object object = this.opt(key); - if (object == null) { - this.put(key, - value instanceof JSONArray ? new JSONArray().put(value) - : value); - } else if (object instanceof JSONArray) { - ((JSONArray) object).put(value); - } else { - this.put(key, new JSONArray().put(object).put(value)); - } - return this; - } - - /** - * Append values to the array under a key. If the key does not exist in the - * JSONObject, then the key is put in the JSONObject with its value being a - * JSONArray containing the value parameter. If the key was already - * associated with a JSONArray, then the value parameter is appended to it. - * - * @param key - * A key string. - * @param value - * An object to be accumulated under the key. - * @return this. - * @throws JSONException - * If the value is non-finite number or if the current value associated with - * the key is not a JSONArray. - * @throws NullPointerException - * If the key is null. - */ - public JSONObject append(String key, Object value) throws JSONException { - testValidity(value); - Object object = this.opt(key); - if (object == null) { - this.put(key, new JSONArray().put(value)); - } else if (object instanceof JSONArray) { - this.put(key, ((JSONArray) object).put(value)); - } else { - throw new JSONException("JSONObject[" + key - + "] is not a JSONArray."); - } - return this; - } - - /** - * Produce a string from a double. The string "null" will be returned if the - * number is not finite. - * - * @param d - * A double. - * @return A String. - */ - public static String doubleToString(double d) { - if (Double.isInfinite(d) || Double.isNaN(d)) { - return "null"; - } - -// Shave off trailing zeros and decimal point, if possible. - - String string = Double.toString(d); - if (string.indexOf('.') > 0 && string.indexOf('e') < 0 - && string.indexOf('E') < 0) { - while (string.endsWith("0")) { - string = string.substring(0, string.length() - 1); - } - if (string.endsWith(".")) { - string = string.substring(0, string.length() - 1); - } - } - return string; - } - - /** - * Get the value object associated with a key. - * - * @param key - * A key string. - * @return The object associated with the key. - * @throws JSONException - * if the key is not found. - */ - public Object get(String key) throws JSONException { - if (key == null) { - throw new JSONException("Null key."); - } - Object object = this.opt(key); - if (object == null) { - throw new JSONException("JSONObject[" + quote(key) + "] not found."); - } - return object; - } - - /** - * Get the enum value associated with a key. - * - * @param - * Enum Type - * @param clazz - * The type of enum to retrieve. - * @param key - * A key string. - * @return The enum value associated with the key - * @throws JSONException - * if the key is not found or if the value cannot be converted - * to an enum. - */ - public > E getEnum(Class clazz, String key) throws JSONException { - E val = optEnum(clazz, key); - if(val==null) { - // JSONException should really take a throwable argument. - // If it did, I would re-implement this with the Enum.valueOf - // method and place any thrown exception in the JSONException - throw new JSONException("JSONObject[" + quote(key) - + "] is not an enum of type " + quote(clazz.getSimpleName()) - + "."); - } - return val; - } - - /** - * Get the boolean value associated with a key. - * - * @param key - * A key string. - * @return The truth. - * @throws JSONException - * if the value is not a Boolean or the String "true" or - * "false". - */ - public boolean getBoolean(String key) throws JSONException { - Object object = this.get(key); - if (object.equals(Boolean.FALSE) - || (object instanceof String && ((String) object) - .equalsIgnoreCase("false"))) { - return false; - } else if (object.equals(Boolean.TRUE) - || (object instanceof String && ((String) object) - .equalsIgnoreCase("true"))) { - return true; - } - throw new JSONException("JSONObject[" + quote(key) - + "] is not a Boolean."); - } - - /** - * Get the BigInteger value associated with a key. - * - * @param key - * A key string. - * @return The numeric value. - * @throws JSONException - * if the key is not found or if the value cannot - * be converted to BigInteger. - */ - public BigInteger getBigInteger(String key) throws JSONException { - Object object = this.get(key); - BigInteger ret = objectToBigInteger(object, null); - if (ret != null) { - return ret; - } - throw new JSONException("JSONObject[" + quote(key) - + "] could not be converted to BigInteger (" + object + ")."); - } - - /** - * Get the BigDecimal value associated with a key. If the value is float or - * double, the the {@link BigDecimal#BigDecimal(double)} constructor will - * be used. See notes on the constructor for conversion issues that may - * arise. - * - * @param key - * A key string. - * @return The numeric value. - * @throws JSONException - * if the key is not found or if the value - * cannot be converted to BigDecimal. - */ - public BigDecimal getBigDecimal(String key) throws JSONException { - Object object = this.get(key); - BigDecimal ret = objectToBigDecimal(object, null); - if (ret != null) { - return ret; - } - throw new JSONException("JSONObject[" + quote(key) - + "] could not be converted to BigDecimal (" + object + ")."); - } - - /** - * Get the double value associated with a key. - * - * @param key - * A key string. - * @return The numeric value. - * @throws JSONException - * if the key is not found or if the value is not a Number - * object and cannot be converted to a number. - */ - public double getDouble(String key) throws JSONException { - return this.getNumber(key).doubleValue(); - } - - /** - * Get the float value associated with a key. - * - * @param key - * A key string. - * @return The numeric value. - * @throws JSONException - * if the key is not found or if the value is not a Number - * object and cannot be converted to a number. - */ - public float getFloat(String key) throws JSONException { - return this.getNumber(key).floatValue(); - } - - /** - * Get the Number value associated with a key. - * - * @param key - * A key string. - * @return The numeric value. - * @throws JSONException - * if the key is not found or if the value is not a Number - * object and cannot be converted to a number. - */ - public Number getNumber(String key) throws JSONException { - Object object = this.get(key); - try { - if (object instanceof Number) { - return (Number)object; - } - return stringToNumber(object.toString()); - } catch (Exception e) { - throw new JSONException("JSONObject[" + quote(key) - + "] is not a number.", e); - } - } - - /** - * Get the int value associated with a key. - * - * @param key - * A key string. - * @return The integer value. - * @throws JSONException - * if the key is not found or if the value cannot be converted - * to an integer. - */ - public int getInt(String key) throws JSONException { - return this.getNumber(key).intValue(); - } - - /** - * Get the JSONArray value associated with a key. - * - * @param key - * A key string. - * @return A JSONArray which is the value. - * @throws JSONException - * if the key is not found or if the value is not a JSONArray. - */ - public JSONArray getJSONArray(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof JSONArray) { - return (JSONArray) object; - } - throw new JSONException("JSONObject[" + quote(key) - + "] is not a JSONArray."); - } - - /** - * Get the JSONObject value associated with a key. - * - * @param key - * A key string. - * @return A JSONObject which is the value. - * @throws JSONException - * if the key is not found or if the value is not a JSONObject. - */ - public JSONObject getJSONObject(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof JSONObject) { - return (JSONObject) object; - } - throw new JSONException("JSONObject[" + quote(key) - + "] is not a JSONObject."); - } - - /** - * Get the long value associated with a key. - * - * @param key - * A key string. - * @return The long value. - * @throws JSONException - * if the key is not found or if the value cannot be converted - * to a long. - */ - public long getLong(String key) throws JSONException { - return this.getNumber(key).longValue(); - } - - /** - * Get an array of field names from a JSONObject. - * - * @param jo - * JSON object - * @return An array of field names, or null if there are no names. - */ - public static String[] getNames(JSONObject jo) { - if (jo.isEmpty()) { - return null; - } - return jo.keySet().toArray(new String[jo.length()]); - } - - /** - * Get an array of public field names from an Object. - * - * @param object - * object to read - * @return An array of field names, or null if there are no names. - */ - public static String[] getNames(Object object) { - if (object == null) { - return null; - } - Class klass = object.getClass(); - Field[] fields = klass.getFields(); - int length = fields.length; - if (length == 0) { - return null; - } - String[] names = new String[length]; - for (int i = 0; i < length; i += 1) { - names[i] = fields[i].getName(); - } - return names; - } - - /** - * Get the string associated with a key. - * - * @param key - * A key string. - * @return A string which is the value. - * @throws JSONException - * if there is no string value for the key. - */ - public String getString(String key) throws JSONException { - Object object = this.get(key); - if (object instanceof String) { - return (String) object; - } - throw new JSONException("JSONObject[" + quote(key) + "] not a string."); - } - - /** - * Determine if the JSONObject contains a specific key. - * - * @param key - * A key string. - * @return true if the key exists in the JSONObject. - */ - public boolean has(String key) { - return this.map.containsKey(key); - } - - /** - * Increment a property of a JSONObject. If there is no such property, - * create one with a value of 1. If there is such a property, and if it is - * an Integer, Long, Double, or Float, then add one to it. - * - * @param key - * A key string. - * @return this. - * @throws JSONException - * If there is already a property with this name that is not an - * Integer, Long, Double, or Float. - */ - public JSONObject increment(String key) throws JSONException { - Object value = this.opt(key); - if (value == null) { - this.put(key, 1); - } else if (value instanceof BigInteger) { - this.put(key, ((BigInteger)value).add(BigInteger.ONE)); - } else if (value instanceof BigDecimal) { - this.put(key, ((BigDecimal)value).add(BigDecimal.ONE)); - } else if (value instanceof Integer) { - this.put(key, ((Integer) value).intValue() + 1); - } else if (value instanceof Long) { - this.put(key, ((Long) value).longValue() + 1L); - } else if (value instanceof Double) { - this.put(key, ((Double) value).doubleValue() + 1.0d); - } else if (value instanceof Float) { - this.put(key, ((Float) value).floatValue() + 1.0f); - } else { - throw new JSONException("Unable to increment [" + quote(key) + "]."); - } - return this; - } - - /** - * Determine if the value associated with the key is null or if there is no - * value. - * - * @param key - * A key string. - * @return true if there is no value associated with the key or if the value - * is the JSONObject.NULL object. - */ - public boolean isNull(String key) { - return JSONObject.NULL.equals(this.opt(key)); - } - - /** - * Get an enumeration of the keys of the JSONObject. Modifying this key Set will also - * modify the JSONObject. Use with caution. - * - * @see Set#iterator() - * - * @return An iterator of the keys. - */ - public Iterator keys() { - return this.keySet().iterator(); - } - - /** - * Get a set of keys of the JSONObject. Modifying this key Set will also modify the - * JSONObject. Use with caution. - * - * @see Map#keySet() - * - * @return A keySet. - */ - public Set keySet() { - return this.map.keySet(); - } - - /** - * Get a set of entries of the JSONObject. These are raw values and may not - * match what is returned by the JSONObject get* and opt* functions. Modifying - * the returned EntrySet or the Entry objects contained therein will modify the - * backing JSONObject. This does not return a clone or a read-only view. - * - * Use with caution. - * - * @see Map#entrySet() - * - * @return An Entry Set - */ - protected Set> entrySet() { - return this.map.entrySet(); - } - - /** - * Get the number of keys stored in the JSONObject. - * - * @return The number of keys in the JSONObject. - */ - public int length() { - return this.map.size(); - } - - /** - * Check if JSONObject is empty. - * - * @return true if JSONObject is empty, otherwise false. - */ - public boolean isEmpty() { - return this.map.isEmpty(); - } - - /** - * Produce a JSONArray containing the names of the elements of this - * JSONObject. - * - * @return A JSONArray containing the key strings, or null if the JSONObject - * is empty. - */ - public JSONArray names() { - if(this.map.isEmpty()) { - return null; - } - return new JSONArray(this.map.keySet()); - } - - /** - * Produce a string from a Number. - * - * @param number - * A Number - * @return A String. - * @throws JSONException - * If n is a non-finite number. - */ - public static String numberToString(Number number) throws JSONException { - if (number == null) { - throw new JSONException("Null pointer"); - } - testValidity(number); - - // Shave off trailing zeros and decimal point, if possible. - - String string = number.toString(); - if (string.indexOf('.') > 0 && string.indexOf('e') < 0 - && string.indexOf('E') < 0) { - while (string.endsWith("0")) { - string = string.substring(0, string.length() - 1); - } - if (string.endsWith(".")) { - string = string.substring(0, string.length() - 1); - } - } - return string; - } - - /** - * Get an optional value associated with a key. - * - * @param key - * A key string. - * @return An object which is the value, or null if there is no value. - */ - public Object opt(String key) { - return key == null ? null : this.map.get(key); - } - - /** - * Get the enum value associated with a key. - * - * @param - * Enum Type - * @param clazz - * The type of enum to retrieve. - * @param key - * A key string. - * @return The enum value associated with the key or null if not found - */ - public > E optEnum(Class clazz, String key) { - return this.optEnum(clazz, key, null); - } - - /** - * Get the enum value associated with a key. - * - * @param - * Enum Type - * @param clazz - * The type of enum to retrieve. - * @param key - * A key string. - * @param defaultValue - * The default in case the value is not found - * @return The enum value associated with the key or defaultValue - * if the value is not found or cannot be assigned to clazz - */ - public > E optEnum(Class clazz, String key, E defaultValue) { - try { - Object val = this.opt(key); - if (NULL.equals(val)) { - return defaultValue; - } - if (clazz.isAssignableFrom(val.getClass())) { - // we just checked it! - @SuppressWarnings("unchecked") - E myE = (E) val; - return myE; - } - return Enum.valueOf(clazz, val.toString()); - } catch (IllegalArgumentException e) { - return defaultValue; - } catch (NullPointerException e) { - return defaultValue; - } - } - - /** - * Get an optional boolean associated with a key. It returns false if there - * is no such key, or if the value is not Boolean.TRUE or the String "true". - * - * @param key - * A key string. - * @return The truth. - */ - public boolean optBoolean(String key) { - return this.optBoolean(key, false); - } - - /** - * Get an optional boolean associated with a key. It returns the - * defaultValue if there is no such key, or if it is not a Boolean or the - * String "true" or "false" (case insensitive). - * - * @param key - * A key string. - * @param defaultValue - * The default. - * @return The truth. - */ - public boolean optBoolean(String key, boolean defaultValue) { - Object val = this.opt(key); - if (NULL.equals(val)) { - return defaultValue; - } - if (val instanceof Boolean){ - return ((Boolean) val).booleanValue(); - } - try { - // we'll use the get anyway because it does string conversion. - return this.getBoolean(key); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get an optional BigDecimal associated with a key, or the defaultValue if - * there is no such key or if its value is not a number. If the value is a - * string, an attempt will be made to evaluate it as a number. If the value - * is float or double, then the {@link BigDecimal#BigDecimal(double)} - * constructor will be used. See notes on the constructor for conversion - * issues that may arise. - * - * @param key - * A key string. - * @param defaultValue - * The default. - * @return An object which is the value. - */ - public BigDecimal optBigDecimal(String key, BigDecimal defaultValue) { - Object val = this.opt(key); - return objectToBigDecimal(val, defaultValue); - } - - /** - * @param val value to convert - * @param defaultValue default value to return is the conversion doesn't work or is null. - * @return BigDecimal conversion of the original value, or the defaultValue if unable - * to convert. - */ - static BigDecimal objectToBigDecimal(Object val, BigDecimal defaultValue) { - if (NULL.equals(val)) { - return defaultValue; - } - if (val instanceof BigDecimal){ - return (BigDecimal) val; - } - if (val instanceof BigInteger){ - return new BigDecimal((BigInteger) val); - } - if (val instanceof Double || val instanceof Float){ - final double d = ((Number) val).doubleValue(); - if(Double.isNaN(d)) { - return defaultValue; - } - return new BigDecimal(((Number) val).doubleValue()); - } - if (val instanceof Long || val instanceof Integer - || val instanceof Short || val instanceof Byte){ - return new BigDecimal(((Number) val).longValue()); - } - // don't check if it's a string in case of unchecked Number subclasses - try { - return new BigDecimal(val.toString()); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get an optional BigInteger associated with a key, or the defaultValue if - * there is no such key or if its value is not a number. If the value is a - * string, an attempt will be made to evaluate it as a number. - * - * @param key - * A key string. - * @param defaultValue - * The default. - * @return An object which is the value. - */ - public BigInteger optBigInteger(String key, BigInteger defaultValue) { - Object val = this.opt(key); - return objectToBigInteger(val, defaultValue); - } - - /** - * @param val value to convert - * @param defaultValue default value to return is the conversion doesn't work or is null. - * @return BigInteger conversion of the original value, or the defaultValue if unable - * to convert. - */ - static BigInteger objectToBigInteger(Object val, BigInteger defaultValue) { - if (NULL.equals(val)) { - return defaultValue; - } - if (val instanceof BigInteger){ - return (BigInteger) val; - } - if (val instanceof BigDecimal){ - return ((BigDecimal) val).toBigInteger(); - } - if (val instanceof Double || val instanceof Float){ - final double d = ((Number) val).doubleValue(); - if(Double.isNaN(d)) { - return defaultValue; - } - return new BigDecimal(d).toBigInteger(); - } - if (val instanceof Long || val instanceof Integer - || val instanceof Short || val instanceof Byte){ - return BigInteger.valueOf(((Number) val).longValue()); - } - // don't check if it's a string in case of unchecked Number subclasses - try { - // the other opt functions handle implicit conversions, i.e. - // jo.put("double",1.1d); - // jo.optInt("double"); -- will return 1, not an error - // this conversion to BigDecimal then to BigInteger is to maintain - // that type cast support that may truncate the decimal. - final String valStr = val.toString(); - if(isDecimalNotation(valStr)) { - return new BigDecimal(valStr).toBigInteger(); - } - return new BigInteger(valStr); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get an optional double associated with a key, or NaN if there is no such - * key or if its value is not a number. If the value is a string, an attempt - * will be made to evaluate it as a number. - * - * @param key - * A string which is the key. - * @return An object which is the value. - */ - public double optDouble(String key) { - return this.optDouble(key, Double.NaN); - } - - /** - * Get an optional double associated with a key, or the defaultValue if - * there is no such key or if its value is not a number. If the value is a - * string, an attempt will be made to evaluate it as a number. - * - * @param key - * A key string. - * @param defaultValue - * The default. - * @return An object which is the value. - */ - public double optDouble(String key, double defaultValue) { - Number val = this.optNumber(key); - if (val == null) { - return defaultValue; - } - final double doubleValue = val.doubleValue(); - // if (Double.isNaN(doubleValue) || Double.isInfinite(doubleValue)) { - // return defaultValue; - // } - return doubleValue; - } - - /** - * Get the optional double value associated with an index. NaN is returned - * if there is no value for the index, or if the value is not a number and - * cannot be converted to a number. - * - * @param key - * A key string. - * @return The value. - */ - public float optFloat(String key) { - return this.optFloat(key, Float.NaN); - } - - /** - * Get the optional double value associated with an index. The defaultValue - * is returned if there is no value for the index, or if the value is not a - * number and cannot be converted to a number. - * - * @param key - * A key string. - * @param defaultValue - * The default value. - * @return The value. - */ - public float optFloat(String key, float defaultValue) { - Number val = this.optNumber(key); - if (val == null) { - return defaultValue; - } - final float floatValue = val.floatValue(); - // if (Float.isNaN(floatValue) || Float.isInfinite(floatValue)) { - // return defaultValue; - // } - return floatValue; - } - - /** - * Get an optional int value associated with a key, or zero if there is no - * such key or if the value is not a number. If the value is a string, an - * attempt will be made to evaluate it as a number. - * - * @param key - * A key string. - * @return An object which is the value. - */ - public int optInt(String key) { - return this.optInt(key, 0); - } - - /** - * Get an optional int value associated with a key, or the default if there - * is no such key or if the value is not a number. If the value is a string, - * an attempt will be made to evaluate it as a number. - * - * @param key - * A key string. - * @param defaultValue - * The default. - * @return An object which is the value. - */ - public int optInt(String key, int defaultValue) { - final Number val = this.optNumber(key, null); - if (val == null) { - return defaultValue; - } - return val.intValue(); - } - - /** - * Get an optional JSONArray associated with a key. It returns null if there - * is no such key, or if its value is not a JSONArray. - * - * @param key - * A key string. - * @return A JSONArray which is the value. - */ - public JSONArray optJSONArray(String key) { - Object o = this.opt(key); - return o instanceof JSONArray ? (JSONArray) o : null; - } - - /** - * Get an optional JSONObject associated with a key. It returns null if - * there is no such key, or if its value is not a JSONObject. - * - * @param key - * A key string. - * @return A JSONObject which is the value. - */ - public JSONObject optJSONObject(String key) { - Object object = this.opt(key); - return object instanceof JSONObject ? (JSONObject) object : null; - } - - /** - * Get an optional long value associated with a key, or zero if there is no - * such key or if the value is not a number. If the value is a string, an - * attempt will be made to evaluate it as a number. - * - * @param key - * A key string. - * @return An object which is the value. - */ - public long optLong(String key) { - return this.optLong(key, 0); - } - - /** - * Get an optional long value associated with a key, or the default if there - * is no such key or if the value is not a number. If the value is a string, - * an attempt will be made to evaluate it as a number. - * - * @param key - * A key string. - * @param defaultValue - * The default. - * @return An object which is the value. - */ - public long optLong(String key, long defaultValue) { - final Number val = this.optNumber(key, null); - if (val == null) { - return defaultValue; - } - - return val.longValue(); - } - - /** - * Get an optional {@link Number} value associated with a key, or null - * if there is no such key or if the value is not a number. If the value is a string, - * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method - * would be used in cases where type coercion of the number value is unwanted. - * - * @param key - * A key string. - * @return An object which is the value. - */ - public Number optNumber(String key) { - return this.optNumber(key, null); - } - - /** - * Get an optional {@link Number} value associated with a key, or the default if there - * is no such key or if the value is not a number. If the value is a string, - * an attempt will be made to evaluate it as a number. This method - * would be used in cases where type coercion of the number value is unwanted. - * - * @param key - * A key string. - * @param defaultValue - * The default. - * @return An object which is the value. - */ - public Number optNumber(String key, Number defaultValue) { - Object val = this.opt(key); - if (NULL.equals(val)) { - return defaultValue; - } - if (val instanceof Number){ - return (Number) val; - } - - try { - return stringToNumber(val.toString()); - } catch (Exception e) { - return defaultValue; - } - } - - /** - * Get an optional string associated with a key. It returns an empty string - * if there is no such key. If the value is not a string and is not null, - * then it is converted to a string. - * - * @param key - * A key string. - * @return A string which is the value. - */ - public String optString(String key) { - return this.optString(key, ""); - } - - /** - * Get an optional string associated with a key. It returns the defaultValue - * if there is no such key. - * - * @param key - * A key string. - * @param defaultValue - * The default. - * @return A string which is the value. - */ - public String optString(String key, String defaultValue) { - Object object = this.opt(key); - return NULL.equals(object) ? defaultValue : object.toString(); - } - - /** - * Populates the internal map of the JSONObject with the bean properties. The - * bean can not be recursive. - * - * @see JSONObject#JSONObject(Object) - * - * @param bean - * the bean - */ - private void populateMap(Object bean) { - Class klass = bean.getClass(); - - // If klass is a System class then set includeSuperClass to false. - - boolean includeSuperClass = klass.getClassLoader() != null; - - Method[] methods = includeSuperClass ? klass.getMethods() : klass.getDeclaredMethods(); - for (final Method method : methods) { - final int modifiers = method.getModifiers(); - if (Modifier.isPublic(modifiers) - && !Modifier.isStatic(modifiers) - && method.getParameterTypes().length == 0 - && !method.isBridge() - && method.getReturnType() != Void.TYPE - && isValidMethodName(method.getName())) { - final String key = getKeyNameFromMethod(method); - if (key != null && !key.isEmpty()) { - try { - final Object result = method.invoke(bean); - if (result != null) { - this.map.put(key, wrap(result)); - // we don't use the result anywhere outside of wrap - // if it's a resource we should be sure to close it - // after calling toString - if (result instanceof Closeable) { - try { - ((Closeable) result).close(); - } catch (IOException ignore) { - } - } - } - } catch (IllegalAccessException ignore) { - } catch (IllegalArgumentException ignore) { - } catch (InvocationTargetException ignore) { - } - } - } - } - } - - private boolean isValidMethodName(String name) { - return !"getClass".equals(name) && !"getDeclaringClass".equals(name); - } - - private String getKeyNameFromMethod(Method method) { - final int ignoreDepth = getAnnotationDepth(method, JSONPropertyIgnore.class); - if (ignoreDepth > 0) { - final int forcedNameDepth = getAnnotationDepth(method, JSONPropertyName.class); - if (forcedNameDepth < 0 || ignoreDepth <= forcedNameDepth) { - // the hierarchy asked to ignore, and the nearest name override - // was higher or non-existent - return null; - } - } - JSONPropertyName annotation = getAnnotation(method, JSONPropertyName.class); - if (annotation != null && annotation.value() != null && !annotation.value().isEmpty()) { - return annotation.value(); - } - String key; - final String name = method.getName(); - if (name.startsWith("get") && name.length() > 3) { - key = name.substring(3); - } else if (name.startsWith("is") && name.length() > 2) { - key = name.substring(2); - } else { - return null; - } - // if the first letter in the key is not uppercase, then skip. - // This is to maintain backwards compatibility before PR406 - // (https://github.com/stleary/JSON-java/pull/406/) - if (Character.isLowerCase(key.charAt(0))) { - return null; - } - if (key.length() == 1) { - key = key.toLowerCase(Locale.ROOT); - } else if (!Character.isUpperCase(key.charAt(1))) { - key = key.substring(0, 1).toLowerCase(Locale.ROOT) + key.substring(1); - } - return key; - } - - /** - * Searches the class hierarchy to see if the method or it's super - * implementations and interfaces has the annotation. - * - * @param - * type of the annotation - * - * @param m - * method to check - * @param annotationClass - * annotation to look for - * @return the {@link Annotation} if the annotation exists on the current method - * or one of it's super class definitions - */ - private static A getAnnotation(final Method m, final Class annotationClass) { - // if we have invalid data the result is null - if (m == null || annotationClass == null) { - return null; - } - - if (m.isAnnotationPresent(annotationClass)) { - return m.getAnnotation(annotationClass); - } - - // if we've already reached the Object class, return null; - Class c = m.getDeclaringClass(); - if (c.getSuperclass() == null) { - return null; - } - - // check directly implemented interfaces for the method being checked - for (Class i : c.getInterfaces()) { - try { - Method im = i.getMethod(m.getName(), m.getParameterTypes()); - return getAnnotation(im, annotationClass); - } catch (final SecurityException ex) { - continue; - } catch (final NoSuchMethodException ex) { - continue; - } - } - - try { - return getAnnotation( - c.getSuperclass().getMethod(m.getName(), m.getParameterTypes()), - annotationClass); - } catch (final SecurityException ex) { - return null; - } catch (final NoSuchMethodException ex) { - return null; - } - } - - /** - * Searches the class hierarchy to see if the method or it's super - * implementations and interfaces has the annotation. Returns the depth of the - * annotation in the hierarchy. - * - * @param - * type of the annotation - * - * @param m - * method to check - * @param annotationClass - * annotation to look for - * @return Depth of the annotation or -1 if the annotation is not on the method. - */ - private static int getAnnotationDepth(final Method m, final Class annotationClass) { - // if we have invalid data the result is -1 - if (m == null || annotationClass == null) { - return -1; - } - - if (m.isAnnotationPresent(annotationClass)) { - return 1; - } - - // if we've already reached the Object class, return -1; - Class c = m.getDeclaringClass(); - if (c.getSuperclass() == null) { - return -1; - } - - // check directly implemented interfaces for the method being checked - for (Class i : c.getInterfaces()) { - try { - Method im = i.getMethod(m.getName(), m.getParameterTypes()); - int d = getAnnotationDepth(im, annotationClass); - if (d > 0) { - // since the annotation was on the interface, add 1 - return d + 1; - } - } catch (final SecurityException ex) { - continue; - } catch (final NoSuchMethodException ex) { - continue; - } - } - - try { - int d = getAnnotationDepth( - c.getSuperclass().getMethod(m.getName(), m.getParameterTypes()), - annotationClass); - if (d > 0) { - // since the annotation was on the superclass, add 1 - return d + 1; - } - return -1; - } catch (final SecurityException ex) { - return -1; - } catch (final NoSuchMethodException ex) { - return -1; - } - } - - /** - * Put a key/boolean pair in the JSONObject. - * - * @param key - * A key string. - * @param value - * A boolean which is the value. - * @return this. - * @throws JSONException - * If the value is non-finite number. - * @throws NullPointerException - * If the key is null. - */ - public JSONObject put(String key, boolean value) throws JSONException { - return this.put(key, value ? Boolean.TRUE : Boolean.FALSE); - } - - /** - * Put a key/value pair in the JSONObject, where the value will be a - * JSONArray which is produced from a Collection. - * - * @param key - * A key string. - * @param value - * A Collection value. - * @return this. - * @throws JSONException - * If the value is non-finite number. - * @throws NullPointerException - * If the key is null. - */ - public JSONObject put(String key, Collection value) throws JSONException { - return this.put(key, new JSONArray(value)); - } - - /** - * Put a key/double pair in the JSONObject. - * - * @param key - * A key string. - * @param value - * A double which is the value. - * @return this. - * @throws JSONException - * If the value is non-finite number. - * @throws NullPointerException - * If the key is null. - */ - public JSONObject put(String key, double value) throws JSONException { - return this.put(key, Double.valueOf(value)); - } - - /** - * Put a key/float pair in the JSONObject. - * - * @param key - * A key string. - * @param value - * A float which is the value. - * @return this. - * @throws JSONException - * If the value is non-finite number. - * @throws NullPointerException - * If the key is null. - */ - public JSONObject put(String key, float value) throws JSONException { - return this.put(key, Float.valueOf(value)); - } - - /** - * Put a key/int pair in the JSONObject. - * - * @param key - * A key string. - * @param value - * An int which is the value. - * @return this. - * @throws JSONException - * If the value is non-finite number. - * @throws NullPointerException - * If the key is null. - */ - public JSONObject put(String key, int value) throws JSONException { - return this.put(key, Integer.valueOf(value)); - } - - /** - * Put a key/long pair in the JSONObject. - * - * @param key - * A key string. - * @param value - * A long which is the value. - * @return this. - * @throws JSONException - * If the value is non-finite number. - * @throws NullPointerException - * If the key is null. - */ - public JSONObject put(String key, long value) throws JSONException { - return this.put(key, Long.valueOf(value)); - } - - /** - * Put a key/value pair in the JSONObject, where the value will be a - * JSONObject which is produced from a Map. - * - * @param key - * A key string. - * @param value - * A Map value. - * @return this. - * @throws JSONException - * If the value is non-finite number. - * @throws NullPointerException - * If the key is null. - */ - public JSONObject put(String key, Map value) throws JSONException { - return this.put(key, new JSONObject(value)); - } - - /** - * Put a key/value pair in the JSONObject. If the value is null, then the - * key will be removed from the JSONObject if it is present. - * - * @param key - * A key string. - * @param value - * An object which is the value. It should be of one of these - * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, - * String, or the JSONObject.NULL object. - * @return this. - * @throws JSONException - * If the value is non-finite number. - * @throws NullPointerException - * If the key is null. - */ - public JSONObject put(String key, Object value) throws JSONException { - if (key == null) { - throw new NullPointerException("Null key."); - } - if (value != null) { - testValidity(value); - this.map.put(key, value); - } else { - this.remove(key); - } - return this; - } - - /** - * Put a key/value pair in the JSONObject, but only if the key and the value - * are both non-null, and only if there is not already a member with that - * name. - * - * @param key - * key to insert into - * @param value - * value to insert - * @return this. - * @throws JSONException - * if the key is a duplicate - */ - public JSONObject putOnce(String key, Object value) throws JSONException { - if (key != null && value != null) { - if (this.opt(key) != null) { - throw new JSONException("Duplicate key \"" + key + "\""); - } - return this.put(key, value); - } - return this; - } - - /** - * Put a key/value pair in the JSONObject, but only if the key and the value - * are both non-null. - * - * @param key - * A key string. - * @param value - * An object which is the value. It should be of one of these - * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, - * String, or the JSONObject.NULL object. - * @return this. - * @throws JSONException - * If the value is a non-finite number. - */ - public JSONObject putOpt(String key, Object value) throws JSONException { - if (key != null && value != null) { - return this.put(key, value); - } - return this; - } - - /** - * Creates a JSONPointer using an initialization string and tries to - * match it to an item within this JSONObject. For example, given a - * JSONObject initialized with this document: - *

-     * {
-     *     "a":{"b":"c"}
-     * }
-     * 
- * and this JSONPointer string: - *
-     * "/a/b"
-     * 
- * Then this method will return the String "c". - * A JSONPointerException may be thrown from code called by this method. - * - * @param jsonPointer string that can be used to create a JSONPointer - * @return the item matched by the JSONPointer, otherwise null - */ - public Object query(String jsonPointer) { - return query(new JSONPointer(jsonPointer)); - } - /** - * Uses a user initialized JSONPointer and tries to - * match it to an item within this JSONObject. For example, given a - * JSONObject initialized with this document: - *
-     * {
-     *     "a":{"b":"c"}
-     * }
-     * 
- * and this JSONPointer: - *
-     * "/a/b"
-     * 
- * Then this method will return the String "c". - * A JSONPointerException may be thrown from code called by this method. - * - * @param jsonPointer string that can be used to create a JSONPointer - * @return the item matched by the JSONPointer, otherwise null - */ - public Object query(JSONPointer jsonPointer) { - return jsonPointer.queryFrom(this); - } - - /** - * Queries and returns a value from this object using {@code jsonPointer}, or - * returns null if the query fails due to a missing key. - * - * @param jsonPointer the string representation of the JSON pointer - * @return the queried value or {@code null} - * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax - */ - public Object optQuery(String jsonPointer) { - return optQuery(new JSONPointer(jsonPointer)); - } - - /** - * Queries and returns a value from this object using {@code jsonPointer}, or - * returns null if the query fails due to a missing key. - * - * @param jsonPointer The JSON pointer - * @return the queried value or {@code null} - * @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax - */ - public Object optQuery(JSONPointer jsonPointer) { - try { - return jsonPointer.queryFrom(this); - } catch (JSONPointerException e) { - return null; - } - } - - /** - * Produce a string in double quotes with backslash sequences in all the - * right places. A backslash will be inserted within </, producing - * <\/, allowing JSON text to be delivered in HTML. In JSON text, a - * string cannot contain a control character or an unescaped quote or - * backslash. - * - * @param string - * A String - * @return A String correctly formatted for insertion in a JSON text. - */ - public static String quote(String string) { - StringWriter sw = new StringWriter(); - synchronized (sw.getBuffer()) { - try { - return quote(string, sw).toString(); - } catch (IOException ignored) { - // will never happen - we are writing to a string writer - return ""; - } - } - } - - public static Writer quote(String string, Writer w) throws IOException { - if (string == null || string.isEmpty()) { - w.write("\"\""); - return w; - } - - char b; - char c = 0; - String hhhh; - int i; - int len = string.length(); - - w.write('"'); - for (i = 0; i < len; i += 1) { - b = c; - c = string.charAt(i); - switch (c) { - case '\\': - case '"': - w.write('\\'); - w.write(c); - break; - case '/': - if (b == '<') { - w.write('\\'); - } - w.write(c); - break; - case '\b': - w.write("\\b"); - break; - case '\t': - w.write("\\t"); - break; - case '\n': - w.write("\\n"); - break; - case '\f': - w.write("\\f"); - break; - case '\r': - w.write("\\r"); - break; - default: - if (c < ' ' || (c >= '\u0080' && c < '\u00a0') - || (c >= '\u2000' && c < '\u2100')) { - w.write("\\u"); - hhhh = Integer.toHexString(c); - w.write("0000", 0, 4 - hhhh.length()); - w.write(hhhh); - } else { - w.write(c); - } - } - } - w.write('"'); - return w; - } - - /** - * Remove a name and its value, if present. - * - * @param key - * The name to be removed. - * @return The value that was associated with the name, or null if there was - * no value. - */ - public Object remove(String key) { - return this.map.remove(key); - } - - /** - * Determine if two JSONObjects are similar. - * They must contain the same set of names which must be associated with - * similar values. - * - * @param other The other JSONObject - * @return true if they are equal - */ - public boolean similar(Object other) { - try { - if (!(other instanceof JSONObject)) { - return false; - } - if (!this.keySet().equals(((JSONObject)other).keySet())) { - return false; - } - for (final Entry entry : this.entrySet()) { - String name = entry.getKey(); - Object valueThis = entry.getValue(); - Object valueOther = ((JSONObject)other).get(name); - if(valueThis == valueOther) { - continue; - } - if(valueThis == null) { - return false; - } - if (valueThis instanceof JSONObject) { - if (!((JSONObject)valueThis).similar(valueOther)) { - return false; - } - } else if (valueThis instanceof JSONArray) { - if (!((JSONArray)valueThis).similar(valueOther)) { - return false; - } - } else if (!valueThis.equals(valueOther)) { - return false; - } - } - return true; - } catch (Throwable exception) { - return false; - } - } - - /** - * Tests if the value should be tried as a decimal. It makes no test if there are actual digits. - * - * @param val value to test - * @return true if the string is "-0" or if it contains '.', 'e', or 'E', false otherwise. - */ - protected static boolean isDecimalNotation(final String val) { - return val.indexOf('.') > -1 || val.indexOf('e') > -1 - || val.indexOf('E') > -1 || "-0".equals(val); - } - - /** - * Converts a string to a number using the narrowest possible type. Possible - * returns for this function are BigDecimal, Double, BigInteger, Long, and Integer. - * When a Double is returned, it should always be a valid Double and not NaN or +-infinity. - * - * @param val value to convert - * @return Number representation of the value. - * @throws NumberFormatException thrown if the value is not a valid number. A public - * caller should catch this and wrap it in a {@link JSONException} if applicable. - */ - protected static Number stringToNumber(final String val) throws NumberFormatException { - char initial = val.charAt(0); - if ((initial >= '0' && initial <= '9') || initial == '-') { - // decimal representation - if (isDecimalNotation(val)) { - // quick dirty way to see if we need a BigDecimal instead of a Double - // this only handles some cases of overflow or underflow - if (val.length()>14) { - return new BigDecimal(val); - } - final Double d = Double.valueOf(val); - if (d.isInfinite() || d.isNaN()) { - // if we can't parse it as a double, go up to BigDecimal - // this is probably due to underflow like 4.32e-678 - // or overflow like 4.65e5324. The size of the string is small - // but can't be held in a Double. - return new BigDecimal(val); - } - return d; - } - // integer representation. - // This will narrow any values to the smallest reasonable Object representation - // (Integer, Long, or BigInteger) - - // string version - // The compare string length method reduces GC, - // but leads to smaller integers being placed in larger wrappers even though not - // needed. i.e. 1,000,000,000 -> Long even though it's an Integer - // 1,000,000,000,000,000,000 -> BigInteger even though it's a Long - //if(val.length()<=9){ - // return Integer.valueOf(val); - //} - //if(val.length()<=18){ - // return Long.valueOf(val); - //} - //return new BigInteger(val); - - // BigInteger version: We use a similar bitLenth compare as - // BigInteger#intValueExact uses. Increases GC, but objects hold - // only what they need. i.e. Less runtime overhead if the value is - // long lived. Which is the better tradeoff? This is closer to what's - // in stringToValue. - BigInteger bi = new BigInteger(val); - if(bi.bitLength()<=31){ - return Integer.valueOf(bi.intValue()); - } - if(bi.bitLength()<=63){ - return Long.valueOf(bi.longValue()); - } - return bi; - } - throw new NumberFormatException("val ["+val+"] is not a valid number."); - } - - /** - * Try to convert a string into a number, boolean, or null. If the string - * can't be converted, return the string. - * - * @param string - * A String. can not be null. - * @return A simple JSON value. - * @throws NullPointerException - * Thrown if the string is null. - */ - // Changes to this method must be copied to the corresponding method in - // the XML class to keep full support for Android - public static Object stringToValue(String string) { - if ("".equals(string)) { - return string; - } - - // check JSON key words true/false/null - if ("true".equalsIgnoreCase(string)) { - return Boolean.TRUE; - } - if ("false".equalsIgnoreCase(string)) { - return Boolean.FALSE; - } - if ("null".equalsIgnoreCase(string)) { - return JSONObject.NULL; - } - - /* - * If it might be a number, try converting it. If a number cannot be - * produced, then the value will just be a string. - */ - - char initial = string.charAt(0); - if ((initial >= '0' && initial <= '9') || initial == '-') { - try { - // if we want full Big Number support the contents of this - // `try` block can be replaced with: - // return stringToNumber(string); - if (isDecimalNotation(string)) { - Double d = Double.valueOf(string); - if (!d.isInfinite() && !d.isNaN()) { - return d; - } - } else { - Long myLong = Long.valueOf(string); - if (string.equals(myLong.toString())) { - if (myLong.longValue() == myLong.intValue()) { - return Integer.valueOf(myLong.intValue()); - } - return myLong; - } - } - } catch (Exception ignore) { - } - } - return string; - } - - /** - * Throw an exception if the object is a NaN or infinite number. - * - * @param o - * The object to test. - * @throws JSONException - * If o is a non-finite number. - */ - public static void testValidity(Object o) throws JSONException { - if (o != null) { - if (o instanceof Double) { - if (((Double) o).isInfinite() || ((Double) o).isNaN()) { - throw new JSONException( - "JSON does not allow non-finite numbers."); - } - } else if (o instanceof Float) { - if (((Float) o).isInfinite() || ((Float) o).isNaN()) { - throw new JSONException( - "JSON does not allow non-finite numbers."); - } - } - } - } - - /** - * Produce a JSONArray containing the values of the members of this - * JSONObject. - * - * @param names - * A JSONArray containing a list of key strings. This determines - * the sequence of the values in the result. - * @return A JSONArray of values. - * @throws JSONException - * If any of the values are non-finite numbers. - */ - public JSONArray toJSONArray(JSONArray names) throws JSONException { - if (names == null || names.isEmpty()) { - return null; - } - JSONArray ja = new JSONArray(); - for (int i = 0; i < names.length(); i += 1) { - ja.put(this.opt(names.getString(i))); - } - return ja; - } - - /** - * Make a JSON text of this JSONObject. For compactness, no whitespace is - * added. If this would not result in a syntactically correct JSON text, - * then null will be returned instead. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * - * @return a printable, displayable, portable, transmittable representation - * of the object, beginning with { (left - * brace) and ending with } (right - * brace). - */ - @Override - public String toString() { - try { - return this.toString(0); - } catch (Exception e) { - return null; - } - } - - /** - * Make a pretty-printed JSON text of this JSONObject. - * - *

If indentFactor > 0 and the {@link JSONObject} - * has only one key, then the object will be output on a single line: - *

{@code {"key": 1}}
- * - *

If an object has 2 or more keys, then it will be output across - * multiple lines:

{
-     *  "key1": 1,
-     *  "key2": "value 2",
-     *  "key3": 3
-     * }
- *

- * Warning: This method assumes that the data structure is acyclical. - * - * - * @param indentFactor - * The number of spaces to add to each level of indentation. - * @return a printable, displayable, portable, transmittable representation - * of the object, beginning with { (left - * brace) and ending with } (right - * brace). - * @throws JSONException - * If the object contains an invalid number. - */ - public String toString(int indentFactor) throws JSONException { - StringWriter w = new StringWriter(); - synchronized (w.getBuffer()) { - return this.write(w, indentFactor, 0).toString(); - } - } - - /** - * Make a JSON text of an Object value. If the object has an - * value.toJSONString() method, then that method will be used to produce the - * JSON text. The method is required to produce a strictly conforming text. - * If the object does not contain a toJSONString method (which is the most - * common case), then a text will be produced by other means. If the value - * is an array or Collection, then a JSONArray will be made from it and its - * toJSONString method will be called. If the value is a MAP, then a - * JSONObject will be made from it and its toJSONString method will be - * called. Otherwise, the value's toString method will be called, and the - * result will be quoted. - * - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @param value - * The value to be serialized. - * @return a printable, displayable, transmittable representation of the - * object, beginning with { (left - * brace) and ending with } (right - * brace). - * @throws JSONException - * If the value is or contains an invalid number. - */ - public static String valueToString(Object value) throws JSONException { - // moves the implementation to JSONWriter as: - // 1. It makes more sense to be part of the writer class - // 2. For Android support this method is not available. By implementing it in the Writer - // Android users can use the writer with the built in Android JSONObject implementation. - return JSONWriter.valueToString(value); - } - - /** - * Wrap an object, if necessary. If the object is null, return the NULL - * object. If it is an array or collection, wrap it in a JSONArray. If it is - * a map, wrap it in a JSONObject. If it is a standard property (Double, - * String, et al) then it is already wrapped. Otherwise, if it comes from - * one of the java packages, turn it into a string. And if it doesn't, try - * to wrap it in a JSONObject. If the wrapping fails, then null is returned. - * - * @param object - * The object to wrap - * @return The wrapped value - */ - public static Object wrap(Object object) { - try { - if (object == null) { - return NULL; - } - if (object instanceof JSONObject || object instanceof JSONArray - || NULL.equals(object) || object instanceof JSONString - || object instanceof Byte || object instanceof Character - || object instanceof Short || object instanceof Integer - || object instanceof Long || object instanceof Boolean - || object instanceof Float || object instanceof Double - || object instanceof String || object instanceof BigInteger - || object instanceof BigDecimal || object instanceof Enum) { - return object; - } - - if (object instanceof Collection) { - Collection coll = (Collection) object; - return new JSONArray(coll); - } - if (object.getClass().isArray()) { - return new JSONArray(object); - } - if (object instanceof Map) { - Map map = (Map) object; - return new JSONObject(map); - } - Package objectPackage = object.getClass().getPackage(); - String objectPackageName = objectPackage != null ? objectPackage - .getName() : ""; - if (objectPackageName.startsWith("java.") - || objectPackageName.startsWith("javax.") - || object.getClass().getClassLoader() == null) { - return object.toString(); - } - return new JSONObject(object); - } catch (Exception exception) { - return null; - } - } - - /** - * Write the contents of the JSONObject as JSON text to a writer. For - * compactness, no whitespace is added. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * - * @return The writer. - * @throws JSONException - */ - public Writer write(Writer writer) throws JSONException { - return this.write(writer, 0, 0); - } - - static final Writer writeValue(Writer writer, Object value, - int indentFactor, int indent) throws JSONException, IOException { - if (value == null || value.equals(null)) { - writer.write("null"); - } else if (value instanceof JSONString) { - Object o; - try { - o = ((JSONString) value).toJSONString(); - } catch (Exception e) { - throw new JSONException(e); - } - writer.write(o != null ? o.toString() : quote(value.toString())); - } else if (value instanceof Number) { - // not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary - final String numberAsString = numberToString((Number) value); - if(NUMBER_PATTERN.matcher(numberAsString).matches()) { - writer.write(numberAsString); - } else { - // The Number value is not a valid JSON number. - // Instead we will quote it as a string - quote(numberAsString, writer); - } - } else if (value instanceof Boolean) { - writer.write(value.toString()); - } else if (value instanceof Enum) { - writer.write(quote(((Enum)value).name())); - } else if (value instanceof JSONObject) { - ((JSONObject) value).write(writer, indentFactor, indent); - } else if (value instanceof JSONArray) { - ((JSONArray) value).write(writer, indentFactor, indent); - } else if (value instanceof Map) { - Map map = (Map) value; - new JSONObject(map).write(writer, indentFactor, indent); - } else if (value instanceof Collection) { - Collection coll = (Collection) value; - new JSONArray(coll).write(writer, indentFactor, indent); - } else if (value.getClass().isArray()) { - new JSONArray(value).write(writer, indentFactor, indent); - } else { - quote(value.toString(), writer); - } - return writer; - } - - static final void indent(Writer writer, int indent) throws IOException { - for (int i = 0; i < indent; i += 1) { - writer.write(' '); - } - } - - /** - * Write the contents of the JSONObject as JSON text to a writer. - * - *

If indentFactor > 0 and the {@link JSONObject} - * has only one key, then the object will be output on a single line: - *

{@code {"key": 1}}
- * - *

If an object has 2 or more keys, then it will be output across - * multiple lines:

{
-     *  "key1": 1,
-     *  "key2": "value 2",
-     *  "key3": 3
-     * }
- *

- * Warning: This method assumes that the data structure is acyclical. - * - * - * @param writer - * Writes the serialized JSON - * @param indentFactor - * The number of spaces to add to each level of indentation. - * @param indent - * The indentation of the top level. - * @return The writer. - * @throws JSONException - */ - public Writer write(Writer writer, int indentFactor, int indent) - throws JSONException { - try { - boolean commanate = false; - final int length = this.length(); - writer.write('{'); - - if (length == 1) { - final Entry entry = this.entrySet().iterator().next(); - final String key = entry.getKey(); - writer.write(quote(key)); - writer.write(':'); - if (indentFactor > 0) { - writer.write(' '); - } - try{ - writeValue(writer, entry.getValue(), indentFactor, indent); - } catch (Exception e) { - throw new JSONException("Unable to write JSONObject value for key: " + key, e); - } - } else if (length != 0) { - final int newindent = indent + indentFactor; - for (final Entry entry : this.entrySet()) { - if (commanate) { - writer.write(','); - } - if (indentFactor > 0) { - writer.write('\n'); - } - indent(writer, newindent); - final String key = entry.getKey(); - writer.write(quote(key)); - writer.write(':'); - if (indentFactor > 0) { - writer.write(' '); - } - try { - writeValue(writer, entry.getValue(), indentFactor, newindent); - } catch (Exception e) { - throw new JSONException("Unable to write JSONObject value for key: " + key, e); - } - commanate = true; - } - if (indentFactor > 0) { - writer.write('\n'); - } - indent(writer, indent); - } - writer.write('}'); - return writer; - } catch (IOException exception) { - throw new JSONException(exception); - } - } - - /** - * Returns a java.util.Map containing all of the entries in this object. - * If an entry in the object is a JSONArray or JSONObject it will also - * be converted. - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @return a java.util.Map containing the entries of this object - */ - public Map toMap() { - Map results = new HashMap(); - for (Entry entry : this.entrySet()) { - Object value; - if (entry.getValue() == null || NULL.equals(entry.getValue())) { - value = null; - } else if (entry.getValue() instanceof JSONObject) { - value = ((JSONObject) entry.getValue()).toMap(); - } else if (entry.getValue() instanceof JSONArray) { - value = ((JSONArray) entry.getValue()).toList(); - } else { - value = entry.getValue(); - } - results.put(entry.getKey(), value); - } - return results; - } -} diff --git a/core/src/com/hiveworkshop/json/JSONPointer.java b/core/src/com/hiveworkshop/json/JSONPointer.java deleted file mode 100644 index fb13323f..00000000 --- a/core/src/com/hiveworkshop/json/JSONPointer.java +++ /dev/null @@ -1,293 +0,0 @@ -package com.hiveworkshop.json; - -import static java.lang.String.format; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -/** - * A JSON Pointer is a simple query language defined for JSON documents by - * RFC 6901. - * - * In a nutshell, JSONPointer allows the user to navigate into a JSON document - * using strings, and retrieve targeted objects, like a simple form of XPATH. - * Path segments are separated by the '/' char, which signifies the root of - * the document when it appears as the first char of the string. Array - * elements are navigated using ordinals, counting from 0. JSONPointer strings - * may be extended to any arbitrary number of segments. If the navigation - * is successful, the matched item is returned. A matched item may be a - * JSONObject, a JSONArray, or a JSON value. If the JSONPointer string building - * fails, an appropriate exception is thrown. If the navigation fails to find - * a match, a JSONPointerException is thrown. - * - * @author JSON.org - * @version 2016-05-14 - */ -public class JSONPointer { - - // used for URL encoding and decoding - private static final String ENCODING = "utf-8"; - - /** - * This class allows the user to build a JSONPointer in steps, using - * exactly one segment in each step. - */ - public static class Builder { - - // Segments for the eventual JSONPointer string - private final List refTokens = new ArrayList(); - - /** - * Creates a {@code JSONPointer} instance using the tokens previously set using the - * {@link #append(String)} method calls. - */ - public JSONPointer build() { - return new JSONPointer(this.refTokens); - } - - /** - * Adds an arbitrary token to the list of reference tokens. It can be any non-null value. - * - * Unlike in the case of JSON string or URI fragment representation of JSON pointers, the - * argument of this method MUST NOT be escaped. If you want to query the property called - * {@code "a~b"} then you should simply pass the {@code "a~b"} string as-is, there is no - * need to escape it as {@code "a~0b"}. - * - * @param token the new token to be appended to the list - * @return {@code this} - * @throws NullPointerException if {@code token} is null - */ - public Builder append(String token) { - if (token == null) { - throw new NullPointerException("token cannot be null"); - } - this.refTokens.add(token); - return this; - } - - /** - * Adds an integer to the reference token list. Although not necessarily, mostly this token will - * denote an array index. - * - * @param arrayIndex the array index to be added to the token list - * @return {@code this} - */ - public Builder append(int arrayIndex) { - this.refTokens.add(String.valueOf(arrayIndex)); - return this; - } - } - - /** - * Static factory method for {@link Builder}. Example usage: - * - *


-     * JSONPointer pointer = JSONPointer.builder()
-     *       .append("obj")
-     *       .append("other~key").append("another/key")
-     *       .append("\"")
-     *       .append(0)
-     *       .build();
-     * 
- * - * @return a builder instance which can be used to construct a {@code JSONPointer} instance by chained - * {@link Builder#append(String)} calls. - */ - public static Builder builder() { - return new Builder(); - } - - // Segments for the JSONPointer string - private final List refTokens; - - /** - * Pre-parses and initializes a new {@code JSONPointer} instance. If you want to - * evaluate the same JSON Pointer on different JSON documents then it is recommended - * to keep the {@code JSONPointer} instances due to performance considerations. - * - * @param pointer the JSON String or URI Fragment representation of the JSON pointer. - * @throws IllegalArgumentException if {@code pointer} is not a valid JSON pointer - */ - public JSONPointer(final String pointer) { - if (pointer == null) { - throw new NullPointerException("pointer cannot be null"); - } - if (pointer.isEmpty() || pointer.equals("#")) { - this.refTokens = Collections.emptyList(); - return; - } - String refs; - if (pointer.startsWith("#/")) { - refs = pointer.substring(2); - try { - refs = URLDecoder.decode(refs, ENCODING); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } else if (pointer.startsWith("/")) { - refs = pointer.substring(1); - } else { - throw new IllegalArgumentException("a JSON pointer should start with '/' or '#/'"); - } - this.refTokens = new ArrayList(); - int slashIdx = -1; - int prevSlashIdx = 0; - do { - prevSlashIdx = slashIdx + 1; - slashIdx = refs.indexOf('/', prevSlashIdx); - if(prevSlashIdx == slashIdx || prevSlashIdx == refs.length()) { - // found 2 slashes in a row ( obj//next ) - // or single slash at the end of a string ( obj/test/ ) - this.refTokens.add(""); - } else if (slashIdx >= 0) { - final String token = refs.substring(prevSlashIdx, slashIdx); - this.refTokens.add(unescape(token)); - } else { - // last item after separator, or no separator at all. - final String token = refs.substring(prevSlashIdx); - this.refTokens.add(unescape(token)); - } - } while (slashIdx >= 0); - // using split does not take into account consecutive separators or "ending nulls" - //for (String token : refs.split("/")) { - // this.refTokens.add(unescape(token)); - //} - } - - public JSONPointer(List refTokens) { - this.refTokens = new ArrayList(refTokens); - } - - private String unescape(String token) { - return token.replace("~1", "/").replace("~0", "~") - .replace("\\\"", "\"") - .replace("\\\\", "\\"); - } - - /** - * Evaluates this JSON Pointer on the given {@code document}. The {@code document} - * is usually a {@link JSONObject} or a {@link JSONArray} instance, but the empty - * JSON Pointer ({@code ""}) can be evaluated on any JSON values and in such case the - * returned value will be {@code document} itself. - * - * @param document the JSON document which should be the subject of querying. - * @return the result of the evaluation - * @throws JSONPointerException if an error occurs during evaluation - */ - public Object queryFrom(Object document) throws JSONPointerException { - if (this.refTokens.isEmpty()) { - return document; - } - Object current = document; - for (String token : this.refTokens) { - if (current instanceof JSONObject) { - current = ((JSONObject) current).opt(unescape(token)); - } else if (current instanceof JSONArray) { - current = readByIndexToken(current, token); - } else { - throw new JSONPointerException(format( - "value [%s] is not an array or object therefore its key %s cannot be resolved", current, - token)); - } - } - return current; - } - - /** - * Matches a JSONArray element by ordinal position - * @param current the JSONArray to be evaluated - * @param indexToken the array index in string form - * @return the matched object. If no matching item is found a - * @throws JSONPointerException is thrown if the index is out of bounds - */ - private Object readByIndexToken(Object current, String indexToken) throws JSONPointerException { - try { - int index = Integer.parseInt(indexToken); - JSONArray currentArr = (JSONArray) current; - if (index >= currentArr.length()) { - throw new JSONPointerException(format("index %s is out of bounds - the array has %d elements", indexToken, - Integer.valueOf(currentArr.length()))); - } - try { - return currentArr.get(index); - } catch (JSONException e) { - throw new JSONPointerException("Error reading value at index position " + index, e); - } - } catch (NumberFormatException e) { - throw new JSONPointerException(format("%s is not an array index", indexToken), e); - } - } - - /** - * Returns a string representing the JSONPointer path value using string - * representation - */ - @Override - public String toString() { - StringBuilder rval = new StringBuilder(""); - for (String token: this.refTokens) { - rval.append('/').append(escape(token)); - } - return rval.toString(); - } - - /** - * Escapes path segment values to an unambiguous form. - * The escape char to be inserted is '~'. The chars to be escaped - * are ~, which maps to ~0, and /, which maps to ~1. Backslashes - * and double quote chars are also escaped. - * @param token the JSONPointer segment value to be escaped - * @return the escaped value for the token - */ - private String escape(String token) { - return token.replace("~", "~0") - .replace("/", "~1") - .replace("\\", "\\\\") - .replace("\"", "\\\""); - } - - /** - * Returns a string representing the JSONPointer path value using URI - * fragment identifier representation - */ - public String toURIFragment() { - try { - StringBuilder rval = new StringBuilder("#"); - for (String token : this.refTokens) { - rval.append('/').append(URLEncoder.encode(token, ENCODING)); - } - return rval.toString(); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/core/src/com/hiveworkshop/json/JSONPointerException.java b/core/src/com/hiveworkshop/json/JSONPointerException.java deleted file mode 100644 index 10d746f1..00000000 --- a/core/src/com/hiveworkshop/json/JSONPointerException.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.hiveworkshop.json; - -/* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -/** - * The JSONPointerException is thrown by {@link JSONPointer} if an error occurs - * during evaluating a pointer. - * - * @author JSON.org - * @version 2016-05-13 - */ -public class JSONPointerException extends JSONException { - private static final long serialVersionUID = 8872944667561856751L; - - public JSONPointerException(String message) { - super(message); - } - - public JSONPointerException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/core/src/com/hiveworkshop/json/JSONPropertyIgnore.java b/core/src/com/hiveworkshop/json/JSONPropertyIgnore.java deleted file mode 100644 index cf0b4286..00000000 --- a/core/src/com/hiveworkshop/json/JSONPropertyIgnore.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.hiveworkshop.json; - -/* -Copyright (c) 2018 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -@Documented -@Retention(RUNTIME) -@Target({METHOD}) -/** - * Use this annotation on a getter method to override the Bean name - * parser for Bean -> JSONObject mapping. If this annotation is - * present at any level in the class hierarchy, then the method will - * not be serialized from the bean into the JSONObject. - */ -public @interface JSONPropertyIgnore { } diff --git a/core/src/com/hiveworkshop/json/JSONPropertyName.java b/core/src/com/hiveworkshop/json/JSONPropertyName.java deleted file mode 100644 index 22d10ad0..00000000 --- a/core/src/com/hiveworkshop/json/JSONPropertyName.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.hiveworkshop.json; - -/* -Copyright (c) 2018 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -@Documented -@Retention(RUNTIME) -@Target({METHOD}) -/** - * Use this annotation on a getter method to override the Bean name - * parser for Bean -> JSONObject mapping. A value set to empty string "" - * will have the Bean parser fall back to the default field name processing. - */ -public @interface JSONPropertyName { - /** - * @return The name of the property as to be used in the JSON Object. - */ - String value(); -} diff --git a/core/src/com/hiveworkshop/json/JSONString.java b/core/src/com/hiveworkshop/json/JSONString.java deleted file mode 100644 index 444bc8a3..00000000 --- a/core/src/com/hiveworkshop/json/JSONString.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.hiveworkshop.json; -/** - * The JSONString interface allows a toJSONString() - * method so that a class can change the behavior of - * JSONObject.toString(), JSONArray.toString(), - * and JSONWriter.value(Object). The - * toJSONString method will be used instead of the default behavior - * of using the Object's toString() method and quoting the result. - */ -public interface JSONString { - /** - * The toJSONString method allows a class to produce its own JSON - * serialization. - * - * @return A strictly syntactically correct JSON text. - */ - public String toJSONString(); -} diff --git a/core/src/com/hiveworkshop/json/JSONStringer.java b/core/src/com/hiveworkshop/json/JSONStringer.java deleted file mode 100644 index 7330d409..00000000 --- a/core/src/com/hiveworkshop/json/JSONStringer.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.hiveworkshop.json; - -/* -Copyright (c) 2006 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -import java.io.StringWriter; - -/** - * JSONStringer provides a quick and convenient way of producing JSON text. - * The texts produced strictly conform to JSON syntax rules. No whitespace is - * added, so the results are ready for transmission or storage. Each instance of - * JSONStringer can produce one JSON text. - *

- * A JSONStringer instance provides a value method for appending - * values to the - * text, and a key - * method for adding keys before values in objects. There are array - * and endArray methods that make and bound array values, and - * object and endObject methods which make and bound - * object values. All of these methods return the JSONWriter instance, - * permitting cascade style. For example,

- * myString = new JSONStringer()
- *     .object()
- *         .key("JSON")
- *         .value("Hello, World!")
- *     .endObject()
- *     .toString();
which produces the string
- * {"JSON":"Hello, World!"}
- *

- * The first method called must be array or object. - * There are no methods for adding commas or colons. JSONStringer adds them for - * you. Objects and arrays can be nested up to 20 levels deep. - *

- * This can sometimes be easier than using a JSONObject to build a string. - * @author JSON.org - * @version 2015-12-09 - */ -public class JSONStringer extends JSONWriter { - /** - * Make a fresh JSONStringer. It can be used to build one JSON text. - */ - public JSONStringer() { - super(new StringWriter()); - } - - /** - * Return the JSON text. This method is used to obtain the product of the - * JSONStringer instance. It will return null if there was a - * problem in the construction of the JSON text (such as the calls to - * array were not properly balanced with calls to - * endArray). - * @return The JSON text. - */ - @Override - public String toString() { - return this.mode == 'd' ? this.writer.toString() : null; - } -} diff --git a/core/src/com/hiveworkshop/json/JSONTokener.java b/core/src/com/hiveworkshop/json/JSONTokener.java deleted file mode 100644 index 5d78054c..00000000 --- a/core/src/com/hiveworkshop/json/JSONTokener.java +++ /dev/null @@ -1,531 +0,0 @@ -package com.hiveworkshop.json; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; - -/* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ - -/** - * A JSONTokener takes a source string and extracts characters and tokens from - * it. It is used by the JSONObject and JSONArray constructors to parse - * JSON source strings. - * @author JSON.org - * @version 2014-05-03 - */ -public class JSONTokener { - /** current read character position on the current line. */ - private long character; - /** flag to indicate if the end of the input has been found. */ - private boolean eof; - /** current read index of the input. */ - private long index; - /** current line of the input. */ - private long line; - /** previous character read from the input. */ - private char previous; - /** Reader for the input. */ - private final Reader reader; - /** flag to indicate that a previous character was requested. */ - private boolean usePrevious; - /** the number of characters read in the previous line. */ - private long characterPreviousLine; - - - /** - * Construct a JSONTokener from a Reader. The caller must close the Reader. - * - * @param reader A reader. - */ - public JSONTokener(Reader reader) { - this.reader = reader.markSupported() - ? reader - : new BufferedReader(reader); - this.eof = false; - this.usePrevious = false; - this.previous = 0; - this.index = 0; - this.character = 1; - this.characterPreviousLine = 0; - this.line = 1; - } - - - /** - * Construct a JSONTokener from an InputStream. The caller must close the input stream. - * @param inputStream The source. - */ - public JSONTokener(InputStream inputStream) { - this(new InputStreamReader(inputStream)); - } - - - /** - * Construct a JSONTokener from a string. - * - * @param s A source string. - */ - public JSONTokener(String s) { - this(new StringReader(s)); - } - - - /** - * Back up one character. This provides a sort of lookahead capability, - * so that you can test for a digit or letter before attempting to parse - * the next number or identifier. - * @throws JSONException Thrown if trying to step back more than 1 step - * or if already at the start of the string - */ - public void back() throws JSONException { - if (this.usePrevious || this.index <= 0) { - throw new JSONException("Stepping back two steps is not supported"); - } - this.decrementIndexes(); - this.usePrevious = true; - this.eof = false; - } - - /** - * Decrements the indexes for the {@link #back()} method based on the previous character read. - */ - private void decrementIndexes() { - this.index--; - if(this.previous=='\r' || this.previous == '\n') { - this.line--; - this.character=this.characterPreviousLine ; - } else if(this.character > 0){ - this.character--; - } - } - - /** - * Get the hex value of a character (base16). - * @param c A character between '0' and '9' or between 'A' and 'F' or - * between 'a' and 'f'. - * @return An int between 0 and 15, or -1 if c was not a hex digit. - */ - public static int dehexchar(char c) { - if (c >= '0' && c <= '9') { - return c - '0'; - } - if (c >= 'A' && c <= 'F') { - return c - ('A' - 10); - } - if (c >= 'a' && c <= 'f') { - return c - ('a' - 10); - } - return -1; - } - - /** - * Checks if the end of the input has been reached. - * - * @return true if at the end of the file and we didn't step back - */ - public boolean end() { - return this.eof && !this.usePrevious; - } - - - /** - * Determine if the source string still contains characters that next() - * can consume. - * @return true if not yet at the end of the source. - * @throws JSONException thrown if there is an error stepping forward - * or backward while checking for more data. - */ - public boolean more() throws JSONException { - if(this.usePrevious) { - return true; - } - try { - this.reader.mark(1); - } catch (IOException e) { - throw new JSONException("Unable to preserve stream position", e); - } - try { - // -1 is EOF, but next() can not consume the null character '\0' - if(this.reader.read() <= 0) { - this.eof = true; - return false; - } - this.reader.reset(); - } catch (IOException e) { - throw new JSONException("Unable to read the next character from the stream", e); - } - return true; - } - - - /** - * Get the next character in the source string. - * - * @return The next character, or 0 if past the end of the source string. - * @throws JSONException Thrown if there is an error reading the source string. - */ - public char next() throws JSONException { - int c; - if (this.usePrevious) { - this.usePrevious = false; - c = this.previous; - } else { - try { - c = this.reader.read(); - } catch (IOException exception) { - throw new JSONException(exception); - } - } - if (c <= 0) { // End of stream - this.eof = true; - return 0; - } - this.incrementIndexes(c); - this.previous = (char) c; - return this.previous; - } - - /** - * Increments the internal indexes according to the previous character - * read and the character passed as the current character. - * @param c the current character read. - */ - private void incrementIndexes(int c) { - if(c > 0) { - this.index++; - if(c=='\r') { - this.line++; - this.characterPreviousLine = this.character; - this.character=0; - }else if (c=='\n') { - if(this.previous != '\r') { - this.line++; - this.characterPreviousLine = this.character; - } - this.character=0; - } else { - this.character++; - } - } - } - - /** - * Consume the next character, and check that it matches a specified - * character. - * @param c The character to match. - * @return The character. - * @throws JSONException if the character does not match. - */ - public char next(char c) throws JSONException { - char n = this.next(); - if (n != c) { - if(n > 0) { - throw this.syntaxError("Expected '" + c + "' and instead saw '" + - n + "'"); - } - throw this.syntaxError("Expected '" + c + "' and instead saw ''"); - } - return n; - } - - - /** - * Get the next n characters. - * - * @param n The number of characters to take. - * @return A string of n characters. - * @throws JSONException - * Substring bounds error if there are not - * n characters remaining in the source string. - */ - public String next(int n) throws JSONException { - if (n == 0) { - return ""; - } - - char[] chars = new char[n]; - int pos = 0; - - while (pos < n) { - chars[pos] = this.next(); - if (this.end()) { - throw this.syntaxError("Substring bounds error"); - } - pos += 1; - } - return new String(chars); - } - - - /** - * Get the next char in the string, skipping whitespace. - * @throws JSONException Thrown if there is an error reading the source string. - * @return A character, or 0 if there are no more characters. - */ - public char nextClean() throws JSONException { - for (;;) { - char c = this.next(); - if (c == 0 || c > ' ') { - return c; - } - } - } - - - /** - * Return the characters up to the next close quote character. - * Backslash processing is done. The formal JSON format does not - * allow strings in single quotes, but an implementation is allowed to - * accept them. - * @param quote The quoting character, either - * " (double quote) or - * ' (single quote). - * @return A String. - * @throws JSONException Unterminated string. - */ - public String nextString(char quote) throws JSONException { - char c; - StringBuilder sb = new StringBuilder(); - for (;;) { - c = this.next(); - switch (c) { - case 0: - case '\n': - case '\r': - throw this.syntaxError("Unterminated string"); - case '\\': - c = this.next(); - switch (c) { - case 'b': - sb.append('\b'); - break; - case 't': - sb.append('\t'); - break; - case 'n': - sb.append('\n'); - break; - case 'f': - sb.append('\f'); - break; - case 'r': - sb.append('\r'); - break; - case 'u': - try { - sb.append((char)Integer.parseInt(this.next(4), 16)); - } catch (NumberFormatException e) { - throw this.syntaxError("Illegal escape.", e); - } - break; - case '"': - case '\'': - case '\\': - case '/': - sb.append(c); - break; - default: - throw this.syntaxError("Illegal escape."); - } - break; - default: - if (c == quote) { - return sb.toString(); - } - sb.append(c); - } - } - } - - - /** - * Get the text up but not including the specified character or the - * end of line, whichever comes first. - * @param delimiter A delimiter character. - * @return A string. - * @throws JSONException Thrown if there is an error while searching - * for the delimiter - */ - public String nextTo(char delimiter) throws JSONException { - StringBuilder sb = new StringBuilder(); - for (;;) { - char c = this.next(); - if (c == delimiter || c == 0 || c == '\n' || c == '\r') { - if (c != 0) { - this.back(); - } - return sb.toString().trim(); - } - sb.append(c); - } - } - - - /** - * Get the text up but not including one of the specified delimiter - * characters or the end of line, whichever comes first. - * @param delimiters A set of delimiter characters. - * @return A string, trimmed. - * @throws JSONException Thrown if there is an error while searching - * for the delimiter - */ - public String nextTo(String delimiters) throws JSONException { - char c; - StringBuilder sb = new StringBuilder(); - for (;;) { - c = this.next(); - if (delimiters.indexOf(c) >= 0 || c == 0 || - c == '\n' || c == '\r') { - if (c != 0) { - this.back(); - } - return sb.toString().trim(); - } - sb.append(c); - } - } - - - /** - * Get the next value. The value can be a Boolean, Double, Integer, - * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object. - * @throws JSONException If syntax error. - * - * @return An object. - */ - public Object nextValue() throws JSONException { - char c = this.nextClean(); - String string; - - switch (c) { - case '"': - case '\'': - return this.nextString(c); - case '{': - this.back(); - return new JSONObject(this); - case '[': - this.back(); - return new JSONArray(this); - } - - /* - * Handle unquoted text. This could be the values true, false, or - * null, or it can be a number. An implementation (such as this one) - * is allowed to also accept non-standard forms. - * - * Accumulate characters until we reach the end of the text or a - * formatting character. - */ - - StringBuilder sb = new StringBuilder(); - while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) { - sb.append(c); - c = this.next(); - } - if (!this.eof) { - this.back(); - } - - string = sb.toString().trim(); - if ("".equals(string)) { - throw this.syntaxError("Missing value"); - } - return JSONObject.stringToValue(string); - } - - - /** - * Skip characters until the next character is the requested character. - * If the requested character is not found, no characters are skipped. - * @param to A character to skip to. - * @return The requested character, or zero if the requested character - * is not found. - * @throws JSONException Thrown if there is an error while searching - * for the to character - */ - public char skipTo(char to) throws JSONException { - char c; - try { - long startIndex = this.index; - long startCharacter = this.character; - long startLine = this.line; - this.reader.mark(1000000); - do { - c = this.next(); - if (c == 0) { - // in some readers, reset() may throw an exception if - // the remaining portion of the input is greater than - // the mark size (1,000,000 above). - this.reader.reset(); - this.index = startIndex; - this.character = startCharacter; - this.line = startLine; - return 0; - } - } while (c != to); - this.reader.mark(1); - } catch (IOException exception) { - throw new JSONException(exception); - } - this.back(); - return c; - } - - /** - * Make a JSONException to signal a syntax error. - * - * @param message The error message. - * @return A JSONException object, suitable for throwing - */ - public JSONException syntaxError(String message) { - return new JSONException(message + this.toString()); - } - - /** - * Make a JSONException to signal a syntax error. - * - * @param message The error message. - * @param causedBy The throwable that caused the error. - * @return A JSONException object, suitable for throwing - */ - public JSONException syntaxError(String message, Throwable causedBy) { - return new JSONException(message + this.toString(), causedBy); - } - - /** - * Make a printable string of this JSONTokener. - * - * @return " at {index} [character {character} line {line}]" - */ - @Override - public String toString() { - return " at " + this.index + " [character " + this.character + " line " + - this.line + "]"; - } -} diff --git a/core/src/com/hiveworkshop/json/JSONWriter.java b/core/src/com/hiveworkshop/json/JSONWriter.java deleted file mode 100644 index 44bfdebe..00000000 --- a/core/src/com/hiveworkshop/json/JSONWriter.java +++ /dev/null @@ -1,413 +0,0 @@ -package com.hiveworkshop.json; - -import java.io.IOException; -import java.util.Collection; -import java.util.Map; - -/* -Copyright (c) 2006 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -/** - * JSONWriter provides a quick and convenient way of producing JSON text. - * The texts produced strictly conform to JSON syntax rules. No whitespace is - * added, so the results are ready for transmission or storage. Each instance of - * JSONWriter can produce one JSON text. - *

- * A JSONWriter instance provides a value method for appending - * values to the - * text, and a key - * method for adding keys before values in objects. There are array - * and endArray methods that make and bound array values, and - * object and endObject methods which make and bound - * object values. All of these methods return the JSONWriter instance, - * permitting a cascade style. For example,

- * new JSONWriter(myWriter)
- *     .object()
- *         .key("JSON")
- *         .value("Hello, World!")
- *     .endObject();
which writes
- * {"JSON":"Hello, World!"}
- *

- * The first method called must be array or object. - * There are no methods for adding commas or colons. JSONWriter adds them for - * you. Objects and arrays can be nested up to 200 levels deep. - *

- * This can sometimes be easier than using a JSONObject to build a string. - * @author JSON.org - * @version 2016-08-08 - */ -public class JSONWriter { - private static final int maxdepth = 200; - - /** - * The comma flag determines if a comma should be output before the next - * value. - */ - private boolean comma; - - /** - * The current mode. Values: - * 'a' (array), - * 'd' (done), - * 'i' (initial), - * 'k' (key), - * 'o' (object). - */ - protected char mode; - - /** - * The object/array stack. - */ - private final JSONObject stack[]; - - /** - * The stack top index. A value of 0 indicates that the stack is empty. - */ - private int top; - - /** - * The writer that will receive the output. - */ - protected Appendable writer; - - /** - * Make a fresh JSONWriter. It can be used to build one JSON text. - */ - public JSONWriter(Appendable w) { - this.comma = false; - this.mode = 'i'; - this.stack = new JSONObject[maxdepth]; - this.top = 0; - this.writer = w; - } - - /** - * Append a value. - * @param string A string value. - * @return this - * @throws JSONException If the value is out of sequence. - */ - private JSONWriter append(String string) throws JSONException { - if (string == null) { - throw new JSONException("Null pointer"); - } - if (this.mode == 'o' || this.mode == 'a') { - try { - if (this.comma && this.mode == 'a') { - this.writer.append(','); - } - this.writer.append(string); - } catch (IOException e) { - // Android as of API 25 does not support this exception constructor - // however we won't worry about it. If an exception is happening here - // it will just throw a "Method not found" exception instead. - throw new JSONException(e); - } - if (this.mode == 'o') { - this.mode = 'k'; - } - this.comma = true; - return this; - } - throw new JSONException("Value out of sequence."); - } - - /** - * Begin appending a new array. All values until the balancing - * endArray will be appended to this array. The - * endArray method must be called to mark the array's end. - * @return this - * @throws JSONException If the nesting is too deep, or if the object is - * started in the wrong place (for example as a key or after the end of the - * outermost array or object). - */ - public JSONWriter array() throws JSONException { - if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') { - this.push(null); - this.append("["); - this.comma = false; - return this; - } - throw new JSONException("Misplaced array."); - } - - /** - * End something. - * @param m Mode - * @param c Closing character - * @return this - * @throws JSONException If unbalanced. - */ - private JSONWriter end(char m, char c) throws JSONException { - if (this.mode != m) { - throw new JSONException(m == 'a' - ? "Misplaced endArray." - : "Misplaced endObject."); - } - this.pop(m); - try { - this.writer.append(c); - } catch (IOException e) { - // Android as of API 25 does not support this exception constructor - // however we won't worry about it. If an exception is happening here - // it will just throw a "Method not found" exception instead. - throw new JSONException(e); - } - this.comma = true; - return this; - } - - /** - * End an array. This method most be called to balance calls to - * array. - * @return this - * @throws JSONException If incorrectly nested. - */ - public JSONWriter endArray() throws JSONException { - return this.end('a', ']'); - } - - /** - * End an object. This method most be called to balance calls to - * object. - * @return this - * @throws JSONException If incorrectly nested. - */ - public JSONWriter endObject() throws JSONException { - return this.end('k', '}'); - } - - /** - * Append a key. The key will be associated with the next value. In an - * object, every value must be preceded by a key. - * @param string A key string. - * @return this - * @throws JSONException If the key is out of place. For example, keys - * do not belong in arrays or if the key is null. - */ - public JSONWriter key(String string) throws JSONException { - if (string == null) { - throw new JSONException("Null key."); - } - if (this.mode == 'k') { - try { - JSONObject topObject = this.stack[this.top - 1]; - // don't use the built in putOnce method to maintain Android support - if(topObject.has(string)) { - throw new JSONException("Duplicate key \"" + string + "\""); - } - topObject.put(string, true); - if (this.comma) { - this.writer.append(','); - } - this.writer.append(JSONObject.quote(string)); - this.writer.append(':'); - this.comma = false; - this.mode = 'o'; - return this; - } catch (IOException e) { - // Android as of API 25 does not support this exception constructor - // however we won't worry about it. If an exception is happening here - // it will just throw a "Method not found" exception instead. - throw new JSONException(e); - } - } - throw new JSONException("Misplaced key."); - } - - - /** - * Begin appending a new object. All keys and values until the balancing - * endObject will be appended to this object. The - * endObject method must be called to mark the object's end. - * @return this - * @throws JSONException If the nesting is too deep, or if the object is - * started in the wrong place (for example as a key or after the end of the - * outermost array or object). - */ - public JSONWriter object() throws JSONException { - if (this.mode == 'i') { - this.mode = 'o'; - } - if (this.mode == 'o' || this.mode == 'a') { - this.append("{"); - this.push(new JSONObject()); - this.comma = false; - return this; - } - throw new JSONException("Misplaced object."); - - } - - - /** - * Pop an array or object scope. - * @param c The scope to close. - * @throws JSONException If nesting is wrong. - */ - private void pop(char c) throws JSONException { - if (this.top <= 0) { - throw new JSONException("Nesting error."); - } - char m = this.stack[this.top - 1] == null ? 'a' : 'k'; - if (m != c) { - throw new JSONException("Nesting error."); - } - this.top -= 1; - this.mode = this.top == 0 - ? 'd' - : this.stack[this.top - 1] == null - ? 'a' - : 'k'; - } - - /** - * Push an array or object scope. - * @param jo The scope to open. - * @throws JSONException If nesting is too deep. - */ - private void push(JSONObject jo) throws JSONException { - if (this.top >= maxdepth) { - throw new JSONException("Nesting too deep."); - } - this.stack[this.top] = jo; - this.mode = jo == null ? 'a' : 'k'; - this.top += 1; - } - - /** - * Make a JSON text of an Object value. If the object has an - * value.toJSONString() method, then that method will be used to produce the - * JSON text. The method is required to produce a strictly conforming text. - * If the object does not contain a toJSONString method (which is the most - * common case), then a text will be produced by other means. If the value - * is an array or Collection, then a JSONArray will be made from it and its - * toJSONString method will be called. If the value is a MAP, then a - * JSONObject will be made from it and its toJSONString method will be - * called. Otherwise, the value's toString method will be called, and the - * result will be quoted. - * - *

- * Warning: This method assumes that the data structure is acyclical. - * - * @param value - * The value to be serialized. - * @return a printable, displayable, transmittable representation of the - * object, beginning with { (left - * brace) and ending with } (right - * brace). - * @throws JSONException - * If the value is or contains an invalid number. - */ - public static String valueToString(Object value) throws JSONException { - if (value == null || value.equals(null)) { - return "null"; - } - if (value instanceof JSONString) { - String object; - try { - object = ((JSONString) value).toJSONString(); - } catch (Exception e) { - throw new JSONException(e); - } - if (object != null) { - return object; - } - throw new JSONException("Bad value from toJSONString: " + object); - } - if (value instanceof Number) { - // not all Numbers may match actual JSON Numbers. i.e. Fractions or Complex - final String numberAsString = JSONObject.numberToString((Number) value); - if(JSONObject.NUMBER_PATTERN.matcher(numberAsString).matches()) { - // Close enough to a JSON number that we will return it unquoted - return numberAsString; - } - // The Number value is not a valid JSON number. - // Instead we will quote it as a string - return JSONObject.quote(numberAsString); - } - if (value instanceof Boolean || value instanceof JSONObject - || value instanceof JSONArray) { - return value.toString(); - } - if (value instanceof Map) { - Map map = (Map) value; - return new JSONObject(map).toString(); - } - if (value instanceof Collection) { - Collection coll = (Collection) value; - return new JSONArray(coll).toString(); - } - if (value.getClass().isArray()) { - return new JSONArray(value).toString(); - } - if(value instanceof Enum){ - return JSONObject.quote(((Enum)value).name()); - } - return JSONObject.quote(value.toString()); - } - - /** - * Append either the value true or the value - * false. - * @param b A boolean. - * @return this - * @throws JSONException - */ - public JSONWriter value(boolean b) throws JSONException { - return this.append(b ? "true" : "false"); - } - - /** - * Append a double value. - * @param d A double. - * @return this - * @throws JSONException If the number is not finite. - */ - public JSONWriter value(double d) throws JSONException { - return this.value(Double.valueOf(d)); - } - - /** - * Append a long value. - * @param l A long. - * @return this - * @throws JSONException - */ - public JSONWriter value(long l) throws JSONException { - return this.append(Long.toString(l)); - } - - - /** - * Append an object value. - * @param object The object to append. It can be null, or a Boolean, Number, - * String, JSONObject, or JSONArray, or an object that implements JSONString. - * @return this - * @throws JSONException If the value is out of sequence. - */ - public JSONWriter value(Object object) throws JSONException { - return this.append(valueToString(object)); - } -} diff --git a/core/src/com/hiveworkshop/lang/Hex.java b/core/src/com/hiveworkshop/lang/Hex.java deleted file mode 100644 index 8dfd0244..00000000 --- a/core/src/com/hiveworkshop/lang/Hex.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.hiveworkshop.lang; - -import java.util.Arrays; - -public abstract class Hex { - private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', - 'E', 'F' }; - - public static final int RADIX_SIZE = 4; - - public static final int RADIX = HEX_DIGITS.length; - - private static final byte NO_VALUE = -1; - - private static final int DECIMAL_CHARACTERS = 10; - - private static final byte[] CHAR_VALUES = new byte[1 << Byte.SIZE]; - static { - Arrays.fill(CHAR_VALUES, NO_VALUE); - int value = 0; - for (; value < DECIMAL_CHARACTERS; value += 1) { - CHAR_VALUES['0' + value] = (byte) value; - } - for (; value < RADIX; value += 1) { - CHAR_VALUES[('a' - DECIMAL_CHARACTERS) + value] = (byte) value; - CHAR_VALUES[('A' - DECIMAL_CHARACTERS) + value] = (byte) value; - } - } - - /** - * Hexadecimal prefix string. - */ - public static final String HEX_PREFIX = "0x"; - - private static int NIBBLE_MASK = 0b1111; - - public static byte decodeNibble(final int codePoint) { - if (codePoint > CHAR_VALUES.length) { - return NO_VALUE; - } else { - return CHAR_VALUES[codePoint]; - } - } - - public static byte[] decodeHex(final CharSequence hex) { - final int nibbleCount = hex.length(); - int valueNibbleShift = ((nibbleCount - 1) % (Byte.SIZE / RADIX_SIZE)) * RADIX_SIZE; - final byte[] values = new byte[(nibbleCount + 1) >> 1]; - int valueIndex = 0; - int value = 0; - - for (int nibbleIndex = 0; nibbleIndex < nibbleCount; nibbleIndex += 1) { - final byte nibble = decodeNibble(hex.charAt(nibbleIndex)); - if (nibble == NO_VALUE) { - throw new NumberFormatException("non-hex character"); - } - - value |= nibble << valueNibbleShift; - - if (valueNibbleShift == 0) { - valueNibbleShift = Byte.SIZE; - values[valueIndex++] = (byte) value; - value = 0; - } - - valueNibbleShift -= RADIX_SIZE; - } - - return values; - } - - public static void stringBufferAppendHex(final StringBuilder builder, final byte hex) { - builder.append(HEX_DIGITS[(hex >> 4) & NIBBLE_MASK]); - builder.append(HEX_DIGITS[hex & NIBBLE_MASK]); - } - - public static void stringBufferAppendHex(final StringBuilder builder, final byte[] hex) { - for (int i = 0; i < hex.length; i += 1) { - stringBufferAppendHex(builder, hex[i]); - } - } -} diff --git a/core/src/com/hiveworkshop/nio/ByteBufferInputStream.java b/core/src/com/hiveworkshop/nio/ByteBufferInputStream.java deleted file mode 100644 index f7eff2ae..00000000 --- a/core/src/com/hiveworkshop/nio/ByteBufferInputStream.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.hiveworkshop.nio; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; - -/** - * Simple InputStream wrapper for ByteBuffer. - *

- * This class is not thread safe. - *

- * https://stackoverflow.com/questions/4332264/wrapping-a-bytebuffer-with-an-inputstream - */ -public class ByteBufferInputStream extends InputStream { - - ByteBuffer buf; - - public ByteBufferInputStream(ByteBuffer buf) { - this.buf = buf; - } - - public int read() throws IOException { - if (!buf.hasRemaining()) { - return -1; - } - return buf.get() & 0xFF; - } - - public int read(byte[] bytes, int off, int len) - throws IOException { - if (!buf.hasRemaining()) { - return -1; - } - - len = Math.min(len, buf.remaining()); - buf.get(bytes, off, len); - return len; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/AnimationMap.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/AnimationMap.java deleted file mode 100644 index 9e883013..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/AnimationMap.java +++ /dev/null @@ -1,266 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import java.util.HashMap; -import java.util.Map; - -import com.etheller.warsmash.util.War3ID; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; - -/** - * A map from MDX animation tags to their equivalent MDL tokens, and the - * implementation objects. - * - *

- * Based on the works of Chananya Freiman. - */ -public enum AnimationMap { - // Layer - /** - * Layer texture ID - */ - KMTF(MdlUtils.TOKEN_TEXTURE_ID, MdlxTimelineDescriptor.UINT32_TIMELINE), - /** - * Layer alpha - */ - KMTA(MdlUtils.TOKEN_ALPHA, MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Layer emissive gain - */ - KMTE("EmissiveGain", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Layer fresnel color - */ - KFC3("FresnelColor", MdlxTimelineDescriptor.VECTOR3_TIMELINE), - /** - * Layer fresnel opacity - */ - KFCA("FresnelOpacity", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Layer fresnel team color - */ - KFTC("FresnelTeamColor", MdlxTimelineDescriptor.UINT32_TIMELINE), - // TextureAnimation - /** - * Texture animation translation - */ - KTAT(MdlUtils.TOKEN_TRANSLATION, MdlxTimelineDescriptor.VECTOR3_TIMELINE), - /** - * Texture animation rotation - */ - KTAR(MdlUtils.TOKEN_ROTATION, MdlxTimelineDescriptor.VECTOR4_TIMELINE), - /** - * Texture animation scaling - */ - KTAS(MdlUtils.TOKEN_SCALING, MdlxTimelineDescriptor.VECTOR3_TIMELINE), - // GeosetAnimation - /** - * Geoset animation alpha - */ - KGAO(MdlUtils.TOKEN_ALPHA, MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Geoset animation color - */ - KGAC(MdlUtils.TOKEN_COLOR, MdlxTimelineDescriptor.VECTOR3_TIMELINE), - // Light - /** - * Light attenuation start - */ - KLAS(MdlUtils.TOKEN_ATTENUATION_START, MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Light attenuation end - */ - KLAE(MdlUtils.TOKEN_ATTENUATION_END, MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Light color - */ - KLAC(MdlUtils.TOKEN_COLOR, MdlxTimelineDescriptor.VECTOR3_TIMELINE), - /** - * Light intensity - */ - KLAI(MdlUtils.TOKEN_INTENSITY, MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Light ambient intensity - */ - KLBI(MdlUtils.TOKEN_AMB_INTENSITY, MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Light ambient color - */ - KLBC(MdlUtils.TOKEN_AMB_COLOR, MdlxTimelineDescriptor.VECTOR3_TIMELINE), - /** - * Light visibility - */ - KLAV(MdlUtils.TOKEN_VISIBILITY, MdlxTimelineDescriptor.FLOAT_TIMELINE), - // Attachment - /** - * Attachment visibility - */ - KATV(MdlUtils.TOKEN_VISIBILITY, MdlxTimelineDescriptor.FLOAT_TIMELINE), - // ParticleEmitter - /** - * Particle emitter emission rate - */ - KPEE(MdlUtils.TOKEN_EMISSION_RATE, MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Particle emitter gravity - */ - KPEG(MdlUtils.TOKEN_GRAVITY, MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Particle emitter longitude - */ - KPLN(MdlUtils.TOKEN_LONGITUDE, MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Particle emitter latitude - */ - KPLT(MdlUtils.TOKEN_LATITUDE, MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Particle emitter lifespan - */ - KPEL(MdlUtils.TOKEN_LIFE_SPAN, MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Particle emitter initial velocity - */ - KPES(MdlUtils.TOKEN_INIT_VELOCITY, MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Particle emitter visibility - */ - KPEV(MdlUtils.TOKEN_VISIBILITY, MdlxTimelineDescriptor.FLOAT_TIMELINE), - // ParticleEmitter2 - /** - * Particle emitter 2 speed - */ - KP2S("Speed", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Particle emitter 2 variation - */ - KP2R("Variation", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Particle emitter 2 latitude - */ - KP2L("Latitude", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Particle emitter 2 gravity - */ - KP2G("Gravity", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Particle emitter 2 emission rate - */ - KP2E("EmissionRate", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Particle emitter 2 length - */ - KP2N("Length", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Particle emitter 2 width - */ - KP2W("Width", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Particle emitter 2 visibility - */ - KP2V("Visibility", MdlxTimelineDescriptor.FLOAT_TIMELINE), - // ParticleEmitterCorn - /** - * Popcorn emitter alpha - */ - KPPA("Alpha", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Popcorn emitter color - */ - KPPC("Color", MdlxTimelineDescriptor.VECTOR3_TIMELINE), - /** - * Popcorn emitter emission rate - */ - KPPE("EmissionRate", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Popcorn emitter lifespan - */ - KPPL("LifeSpan", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Popcorn emitter speed - */ - KPPS("Speed", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Popcorn emitter visibility - */ - KPPV("Visibility", MdlxTimelineDescriptor.FLOAT_TIMELINE), - // RibbonEmitter - /** - * Ribbon emitter height above - */ - KRHA("HeightAbove", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Ribbon emitter height below - */ - KRHB("HeightBelow", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Ribbon emitter alpha - */ - KRAL("Alpha", MdlxTimelineDescriptor.FLOAT_TIMELINE), - /** - * Ribbon emitter color - */ - KRCO("Color", MdlxTimelineDescriptor.VECTOR3_TIMELINE), - /** - * Ribbon emitter texture slot - */ - KRTX("TextureSlot", MdlxTimelineDescriptor.UINT32_TIMELINE), - /** - * Ribbon emitter visibility - */ - KRVS("Visibility", MdlxTimelineDescriptor.FLOAT_TIMELINE), - // Camera - /** - * Camera source translation - */ - KCTR(MdlUtils.TOKEN_TRANSLATION, MdlxTimelineDescriptor.VECTOR3_TIMELINE), - /** - * Camera target translation - */ - KTTR(MdlUtils.TOKEN_TRANSLATION, MdlxTimelineDescriptor.VECTOR3_TIMELINE), - /** - * Camera source rotation - */ - KCRL(MdlUtils.TOKEN_ROTATION, MdlxTimelineDescriptor.FLOAT_TIMELINE), - // GenericObject - /** - * Generic object translation - */ - KGTR(MdlUtils.TOKEN_TRANSLATION, MdlxTimelineDescriptor.VECTOR3_TIMELINE), - /** - * Generic object rotation - */ - KGRT(MdlUtils.TOKEN_ROTATION, MdlxTimelineDescriptor.VECTOR4_TIMELINE), - /** - * Generic object scaling - */ - KGSC(MdlUtils.TOKEN_SCALING, MdlxTimelineDescriptor.VECTOR3_TIMELINE); - - private final String mdlToken; - private final MdlxTimelineDescriptor implementation; - private final War3ID war3id; - - AnimationMap(final String mdlToken, final MdlxTimelineDescriptor implementation) { - this.mdlToken = mdlToken; - this.implementation = implementation; - this.war3id = War3ID.fromString(name()); - } - - public String getMdlToken() { - return this.mdlToken; - } - - public MdlxTimelineDescriptor getImplementation() { - return this.implementation; - } - - public War3ID getWar3id() { - return this.war3id; - } - - public static final Map ID_TO_TAG = new HashMap<>(); - - static { - for (final AnimationMap tag : AnimationMap.values()) { - ID_TO_TAG.put(tag.getWar3id(), tag); - } - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/InterpolationType.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/InterpolationType.java deleted file mode 100644 index 3856a185..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/InterpolationType.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -public enum InterpolationType { - DONT_INTERP("DontInterp"), LINEAR("Linear"), HERMITE("Hermite"), BEZIER("Bezier"); - - public static final InterpolationType[] VALUES = values(); - - private final String token; - - InterpolationType(final String token) { - this.token = token; - } - - public static InterpolationType getType(final int whichValue) { - return VALUES[whichValue]; - } - - public boolean tangential() { - return ordinal() > 1; - } - - @Override - public String toString() { - return token; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxAnimatedObject.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxAnimatedObject.java deleted file mode 100644 index 16e94606..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxAnimatedObject.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxTimeline; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -/** - * Based on the works of Chananya Freiman. - */ -public abstract class MdlxAnimatedObject implements MdlxChunk, MdlxBlock { - public final List> timelines = new ArrayList<>(); - - public void readTimelines(final BinaryReader reader, long size) { - while (size > 0) { - final War3ID name = new War3ID(reader.readTag()); - final MdlxTimeline timeline = AnimationMap.ID_TO_TAG.get(name).getImplementation().createTimeline(); - - timeline.readMdx(reader, name); - - size -= timeline.getByteLength(); - - this.timelines.add(timeline); - } - } - - public void writeTimelines(final BinaryWriter writer) { - for (final MdlxTimeline timeline : this.timelines) { - timeline.writeMdx(writer); - } - } - - public Iterator readAnimatedBlock(final MdlTokenInputStream stream) { - return new TransformedAnimatedBlockIterator(stream.readBlock().iterator()); - } - - public void readTimeline(final MdlTokenInputStream stream, final AnimationMap name) { - final MdlxTimeline timeline = name.getImplementation().createTimeline(); - - timeline.readMdl(stream, name.getWar3id()); - - this.timelines.add(timeline); - } - - public boolean writeTimeline(final MdlTokenOutputStream stream, final AnimationMap name) { - for (final MdlxTimeline timeline : this.timelines) { - if (timeline.name.equals(name.getWar3id())) { - timeline.writeMdl(stream); - return true; - } - } - return false; - } - - @Override - public long getByteLength(final int version) { - long size = 0; - for (final MdlxTimeline timeline : this.timelines) { - size += timeline.getByteLength(); - } - return size; - } - - public List> getTimelines() { - return this.timelines; - } - - /** - * TODO: This code uses StringBuilder implicitly during string concat. This - * should be upgraded for performance. - * - * @author micro - */ - private static final class TransformedAnimatedBlockIterator implements Iterator { - private final Iterator delegate; - - public TransformedAnimatedBlockIterator(final Iterator delegate) { - this.delegate = delegate; - } - - @Override - public boolean hasNext() { - return this.delegate.hasNext(); - } - - @Override - public String next() { - final String token = this.delegate.next(); - if (token.equals(MdlUtils.TOKEN_STATIC) && hasNext()) { - return MdlUtils.TOKEN_STATIC + " " + this.delegate.next(); - } - return token; - } - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxAttachment.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxAttachment.java deleted file mode 100644 index 28a23fea..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxAttachment.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxAttachment extends MdlxGenericObject { - public String path = ""; - public int attachmentId = 0; - - public MdlxAttachment() { - super(0x800); - } - - @Override - public void readMdx(final BinaryReader reader, final int version) { - final int position = reader.position(); - final long size = reader.readUInt32(); - - super.readMdx(reader, version); - - this.path = reader.read(260); - this.attachmentId = reader.readInt32(); - - readTimelines(reader, size - (reader.position() - position)); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeUInt32(getByteLength(version)); - - super.writeMdx(writer, version); - - writer.writeWithNulls(this.path, 260); - writer.writeInt32(this.attachmentId); - - writeNonGenericAnimationChunks(writer); - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - for (final String token : super.readMdlGeneric(stream)) { - if (MdlUtils.TOKEN_ATTACHMENT_ID.equals(token)) { - this.attachmentId = stream.readInt(); - } - else if (MdlUtils.TOKEN_PATH.equals(token)) { - this.path = stream.read(); - } - else if (MdlUtils.TOKEN_VISIBILITY.equals(token)) { - readTimeline(stream, AnimationMap.KATV); - } - else { - throw new RuntimeException("Unknown token in Attachment " + this.name + ": " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startObjectBlock(MdlUtils.TOKEN_ATTACHMENT, this.name); - writeGenericHeader(stream); - - // flowtsohg asks in his JS: - // Is this needed? MDX supplies it, but MdlxConv does not use it. - // Retera: - // I tried to preserve it when it was shown, but omit it when it was omitted - // for MDL in Matrix Eater. Matrix Eater's MDL -> MDX is generating them - // and discarding what was read from the MDL. The Matrix Eater is notably - // buggy from a cursory read through, and would always omit AttachmentID 0 - // in MDL output. - stream.writeAttrib(MdlUtils.TOKEN_ATTACHMENT_ID, this.attachmentId); - - if ((this.path != null) && (this.path.length() > 0)) { - stream.writeStringAttrib(MdlUtils.TOKEN_PATH, this.path); - } - - writeTimeline(stream, AnimationMap.KATV); - - writeGenericTimelines(stream); - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - return 268 + super.getByteLength(version); - } - - public String getPath() { - return this.path; - } - - public int getAttachmentId() { - return this.attachmentId; - } - - public void setPath(final String path) { - this.path = path; - } - - public void setAttachmentId(final int attachmentId) { - this.attachmentId = attachmentId; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxBlock.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxBlock.java deleted file mode 100644 index 08d92a7d..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxBlock.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public interface MdlxBlock { - void readMdx(final BinaryReader reader, final int version); - - void writeMdx(final BinaryWriter writer, final int version); - - void readMdl(final MdlTokenInputStream stream, final int version); - - void writeMdl(final MdlTokenOutputStream stream, final int version); -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxBlockDescriptor.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxBlockDescriptor.java deleted file mode 100644 index a45ae6df..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxBlockDescriptor.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.util.Descriptor; - -public interface MdlxBlockDescriptor extends Descriptor { - - MdlxBlockDescriptor ATTACHMENT = MdlxAttachment::new; - - MdlxBlockDescriptor BONE = MdlxBone::new; - - MdlxBlockDescriptor CAMERA = MdlxCamera::new; - - MdlxBlockDescriptor COLLISION_SHAPE = MdlxCollisionShape::new; - - MdlxBlockDescriptor EVENT_OBJECT = MdlxEventObject::new; - - MdlxBlockDescriptor GEOSET = MdlxGeoset::new; - - MdlxBlockDescriptor GEOSET_ANIMATION = MdlxGeosetAnimation::new; - - MdlxBlockDescriptor HELPER = MdlxHelper::new; - - MdlxBlockDescriptor LIGHT = MdlxLight::new; - - MdlxBlockDescriptor LAYER = MdlxLayer::new; - - MdlxBlockDescriptor MATERIAL = MdlxMaterial::new; - - MdlxBlockDescriptor PARTICLE_EMITTER = MdlxParticleEmitter::new; - - MdlxBlockDescriptor PARTICLE_EMITTER2 = MdlxParticleEmitter2::new; - - MdlxBlockDescriptor PARTICLE_EMITTER_POPCORN = MdlxParticleEmitterPopcorn::new; - - MdlxBlockDescriptor RIBBON_EMITTER = MdlxRibbonEmitter::new; - - MdlxBlockDescriptor SEQUENCE = MdlxSequence::new; - - MdlxBlockDescriptor TEXTURE = MdlxTexture::new; - - MdlxBlockDescriptor TEXTURE_ANIMATION = MdlxTextureAnimation::new; - - MdlxBlockDescriptor FACE_EFFECT = MdlxFaceEffect::new; -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxBone.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxBone.java deleted file mode 100644 index 3bc443a9..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxBone.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxBone extends MdlxGenericObject { - public int geosetId = -1; - public int geosetAnimationId = -1; - - public MdlxBone() { - super(0x100); - } - - @Override - public void readMdx(final BinaryReader reader, final int version) { - super.readMdx(reader, version); - - this.geosetId = reader.readInt32(); - this.geosetAnimationId = reader.readInt32(); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - super.writeMdx(writer, version); - - writer.writeInt32(this.geosetId); - writer.writeInt32(this.geosetAnimationId); - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - for (String token : super.readMdlGeneric(stream)) { - if (MdlUtils.TOKEN_GEOSETID.equals(token)) { - token = stream.read(); - - if (MdlUtils.TOKEN_MULTIPLE.equals(token)) { - this.geosetId = -1; - } - else { - this.geosetId = Integer.parseInt(token); - } - } - else if (MdlUtils.TOKEN_GEOSETANIMID.equals(token)) { - token = stream.read(); - - if (MdlUtils.TOKEN_NONE.equals(token)) { - this.geosetAnimationId = -1; - } - else { - this.geosetAnimationId = Integer.parseInt(token); - } - } - else { - throw new RuntimeException("Unknown token in Bone " + this.name + ": " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startObjectBlock(MdlUtils.TOKEN_BONE, this.name); - writeGenericHeader(stream); - - if (this.geosetId == -1) { - stream.writeAttrib(MdlUtils.TOKEN_GEOSETID, MdlUtils.TOKEN_MULTIPLE); - } - else { - stream.writeAttrib(MdlUtils.TOKEN_GEOSETID, this.geosetId); - } - if (this.geosetAnimationId == -1) { - stream.writeAttrib(MdlUtils.TOKEN_GEOSETANIMID, MdlUtils.TOKEN_NONE); - } - else { - stream.writeAttrib(MdlUtils.TOKEN_GEOSETANIMID, this.geosetAnimationId); - } - - writeGenericTimelines(stream); - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - return 8 + super.getByteLength(version); - } - - public int getGeosetId() { - return this.geosetId; - } - - public int getGeosetAnimationId() { - return this.geosetAnimationId; - } - - public void setGeosetId(final int geosetId) { - this.geosetId = geosetId; - } - - public void setGeosetAnimationId(final int geosetAnimationId) { - this.geosetAnimationId = geosetAnimationId; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxCamera.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxCamera.java deleted file mode 100644 index 3d257a0c..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxCamera.java +++ /dev/null @@ -1,160 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxCamera extends MdlxAnimatedObject { - public String name = ""; - public float[] position = new float[3]; - public float fieldOfView = 0; - public float farClippingPlane = 0; - public float nearClippingPlane = 0; - public float[] targetPosition = new float[3]; - - @Override - public void readMdx(final BinaryReader reader, final int version) { - final long size = reader.readUInt32(); - - this.name = reader.read(80); - reader.readFloat32Array(this.position); - this.fieldOfView = reader.readFloat32(); - this.farClippingPlane = reader.readFloat32(); - this.nearClippingPlane = reader.readFloat32(); - reader.readFloat32Array(this.targetPosition); - - readTimelines(reader, size - 120); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeUInt32(getByteLength(version)); - writer.writeWithNulls(this.name, 80); - writer.writeFloat32Array(this.position); - writer.writeFloat32(this.fieldOfView); - writer.writeFloat32(this.farClippingPlane); - writer.writeFloat32(this.nearClippingPlane); - writer.writeFloat32Array(this.targetPosition); - - writeTimelines(writer); - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - this.name = stream.read(); - - for (final String token : stream.readBlock()) { - switch (token) { - case MdlUtils.TOKEN_POSITION: - stream.readFloatArray(this.position); - break; - case MdlUtils.TOKEN_TRANSLATION: - readTimeline(stream, AnimationMap.KCTR); - break; - case MdlUtils.TOKEN_ROTATION: - readTimeline(stream, AnimationMap.KCRL); - break; - case MdlUtils.TOKEN_FIELDOFVIEW: - this.fieldOfView = stream.readFloat(); - break; - case MdlUtils.TOKEN_FARCLIP: - this.farClippingPlane = stream.readFloat(); - break; - case MdlUtils.TOKEN_NEARCLIP: - this.nearClippingPlane = stream.readFloat(); - break; - case MdlUtils.TOKEN_TARGET: - for (final String subToken : stream.readBlock()) { - switch (subToken) { - case MdlUtils.TOKEN_POSITION: - stream.readFloatArray(this.targetPosition); - break; - case MdlUtils.TOKEN_TRANSLATION: - readTimeline(stream, AnimationMap.KTTR); - break; - default: - throw new IllegalStateException( - "Unknown token in Camera " + this.name + "'s Target: " + subToken); - } - } - break; - default: - throw new RuntimeException("Unknown token in Camera " + this.name + ": " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startObjectBlock(MdlUtils.TOKEN_CAMERA, this.name); - - stream.writeFloatArrayAttrib(MdlUtils.TOKEN_POSITION, this.position); - writeTimeline(stream, AnimationMap.KCTR); - writeTimeline(stream, AnimationMap.KCRL); - stream.writeFloatAttrib(MdlUtils.TOKEN_FIELDOFVIEW, this.fieldOfView); - stream.writeFloatAttrib(MdlUtils.TOKEN_FARCLIP, this.farClippingPlane); - stream.writeFloatAttrib(MdlUtils.TOKEN_NEARCLIP, this.nearClippingPlane); - - stream.startBlock(MdlUtils.TOKEN_TARGET); - stream.writeFloatArrayAttrib(MdlUtils.TOKEN_POSITION, this.targetPosition); - writeTimeline(stream, AnimationMap.KTTR); - stream.endBlock(); - - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - return 120 + super.getByteLength(version); - } - - public String getName() { - return this.name; - } - - public float[] getPosition() { - return this.position; - } - - public float getFieldOfView() { - return this.fieldOfView; - } - - public float getFarClippingPlane() { - return this.farClippingPlane; - } - - public float getNearClippingPlane() { - return this.nearClippingPlane; - } - - public float[] getTargetPosition() { - return this.targetPosition; - } - - public void setName(final String name) { - this.name = name; - } - - public void setPosition(final float[] position) { - this.position = position; - } - - public void setFieldOfView(final float fieldOfView) { - this.fieldOfView = fieldOfView; - } - - public void setFarClippingPlane(final float farClippingPlane) { - this.farClippingPlane = farClippingPlane; - } - - public void setNearClippingPlane(final float nearClippingPlane) { - this.nearClippingPlane = nearClippingPlane; - } - - public void setTargetPosition(final float[] targetPosition) { - this.targetPosition = targetPosition; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxChunk.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxChunk.java deleted file mode 100644 index 3a2b79bd..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxChunk.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -public interface MdlxChunk { - long getByteLength(int version); -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxCollisionShape.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxCollisionShape.java deleted file mode 100644 index 840301fb..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxCollisionShape.java +++ /dev/null @@ -1,187 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxCollisionShape extends MdlxGenericObject { - public enum Type { - BOX, - PLANE, - SPHERE, - CYLINDER; - - private static final Type[] VALUES = values(); - - private final boolean boundsRadius; - - Type() { - this.boundsRadius = false; - } - - Type(final boolean boundsRadius) { - this.boundsRadius = boundsRadius; - } - - public boolean isBoundsRadius() { - return this.boundsRadius; - } - - public static Type from(final int index) { - return VALUES[index]; - } - } - - public MdlxCollisionShape.Type type = Type.SPHERE; - public final float[][] vertices = { new float[3], new float[3] }; - public float boundsRadius = 0; - - public MdlxCollisionShape() { - super(0x2000); - } - - @Override - public void readMdx(final BinaryReader reader, final int version) { - super.readMdx(reader, version); - - this.type = MdlxCollisionShape.Type.from(reader.readInt32()); - reader.readFloat32Array(this.vertices[0]); - - if (this.type != Type.SPHERE) { - reader.readFloat32Array(this.vertices[1]); - } - - if ((this.type == Type.SPHERE) || (this.type == Type.CYLINDER)) { - this.boundsRadius = reader.readFloat32(); - } - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - super.writeMdx(writer, version); - - writer.writeInt32(this.type.ordinal()); - writer.writeFloat32Array(this.vertices[0]); - - if (this.type != MdlxCollisionShape.Type.SPHERE) { - writer.writeFloat32Array(this.vertices[1]); - } - - if ((this.type == Type.SPHERE) || (this.type == Type.CYLINDER)) { - writer.writeFloat32(this.boundsRadius); - } - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - for (final String token : super.readMdlGeneric(stream)) { - switch (token) { - case MdlUtils.TOKEN_BOX: - this.type = Type.BOX; - break; - case MdlUtils.TOKEN_PLANE: - this.type = Type.PLANE; - break; - case MdlUtils.TOKEN_SPHERE: - this.type = Type.SPHERE; - break; - case MdlUtils.TOKEN_CYLINDER: - this.type = Type.CYLINDER; - break; - case MdlUtils.TOKEN_VERTICES: { - final int count = stream.readInt(); - stream.read(); // { - stream.readFloatArray(this.vertices[0]); - if (count == 2) { - stream.readFloatArray(this.vertices[1]); - } - stream.read(); // } - } - break; - case MdlUtils.TOKEN_BOUNDSRADIUS: - this.boundsRadius = stream.readFloat(); - break; - default: - throw new RuntimeException("Unknown token in CollisionShape " + this.name + ": " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startObjectBlock(MdlUtils.TOKEN_COLLISION_SHAPE, this.name); - writeGenericHeader(stream); - final String type; - int vertices = 2; - switch (this.type) { - case BOX: - type = MdlUtils.TOKEN_BOX; - break; - case PLANE: - type = MdlUtils.TOKEN_PLANE; - break; - case SPHERE: { - type = MdlUtils.TOKEN_SPHERE; - vertices = 1; - } - break; - case CYLINDER: - type = MdlUtils.TOKEN_CYLINDER; - break; - default: - throw new IllegalStateException("Invalid type in CollisionShape " + this.name + ": " + this.type); - } - - stream.writeFlag(type); - stream.startBlock(MdlUtils.TOKEN_VERTICES, vertices); - stream.writeFloatArray(this.vertices[0]); - if (vertices == 2) { - stream.writeFloatArray(this.vertices[1]); - } - stream.endBlock(); - - if (this.type.boundsRadius) { - stream.writeFloatAttrib(MdlUtils.TOKEN_BOUNDSRADIUS, this.boundsRadius); - } - - writeGenericTimelines(stream); - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - long size = 16 + super.getByteLength(version); - - if (this.type != Type.SPHERE) { - size += 12; - } - - if ((this.type == Type.SPHERE) || (this.type == Type.CYLINDER)) { - size += 4; - } - - return size; - } - - public MdlxCollisionShape.Type getType() { - return this.type; - } - - public float[][] getVertices() { - return this.vertices; - } - - public float getBoundsRadius() { - return this.boundsRadius; - } - - public void setType(final MdlxCollisionShape.Type type) { - this.type = type; - } - - public void setBoundsRadius(final float boundsRadius) { - this.boundsRadius = boundsRadius; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxEventObject.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxEventObject.java deleted file mode 100644 index fa209966..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxEventObject.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.etheller.warsmash.util.War3ID; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxEventObject extends MdlxGenericObject { - private static final War3ID KEVT = War3ID.fromString("KEVT"); - - public int globalSequenceId = -1; - public long[] keyFrames = { 1 }; - - public MdlxEventObject() { - super(0x400); - } - - @Override - public void readMdx(final BinaryReader reader, final int version) { - super.readMdx(reader, version); - - reader.readInt32(); // KEVT skipped - - final long count = reader.readUInt32(); - - this.globalSequenceId = reader.readInt32(); - - this.keyFrames = new long[(int) count]; - - for (int i = 0; i < count; i++) { - this.keyFrames[i] = reader.readInt32(); - } - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - super.writeMdx(writer, version); - - writer.writeTag(KEVT.getValue()); - writer.writeUInt32(this.keyFrames.length); - writer.writeInt32(this.globalSequenceId); - - for (final long keyFrame : this.keyFrames) { - writer.writeUInt32(keyFrame); - } - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - for (final String token : super.readMdlGeneric(stream)) { - if (MdlUtils.TOKEN_EVENT_TRACK.equals(token)) { - this.keyFrames = new long[stream.readInt()]; - stream.readIntArray(this.keyFrames); - } - else { - throw new RuntimeException("Unknown token in EventObject " + this.name + ": " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startObjectBlock(MdlUtils.TOKEN_EVENT_OBJECT, this.name); - writeGenericHeader(stream); - stream.startBlock(MdlUtils.TOKEN_EVENT_TRACK, this.keyFrames.length); - - for (final long keyFrame : this.keyFrames) { - stream.writeFlagUInt32(keyFrame); - } - - stream.endBlock(); - - writeGenericTimelines(stream); - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - return 12 + (this.keyFrames.length * 4) + super.getByteLength(version); - } - - public int getGlobalSequenceId() { - return this.globalSequenceId; - } - - public long[] getKeyFrames() { - return this.keyFrames; - } - - public void setGlobalSequenceId(final int globalSequenceId) { - this.globalSequenceId = globalSequenceId; - } - - public void setKeyFrames(final long[] keyFrames) { - this.keyFrames = keyFrames; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxExtent.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxExtent.java deleted file mode 100644 index 1dd590d4..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxExtent.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxExtent { - public float boundsRadius = 0; - public float[] min = new float[3]; - public float[] max = new float[3]; - - public void readMdx(final BinaryReader reader) { - this.boundsRadius = reader.readFloat32(); - reader.readFloat32Array(this.min); - reader.readFloat32Array(this.max); - } - - public void writeMdx(final BinaryWriter writer) { - writer.writeFloat32(this.boundsRadius); - writer.writeFloat32Array(this.min); - writer.writeFloat32Array(this.max); - } - - public void writeMdl(final MdlTokenOutputStream stream) { - if ((this.min[0] != 0) || (this.min[1] != 0) || (this.min[2] != 0)) { - stream.writeFloatArrayAttrib(MdlUtils.TOKEN_MINIMUM_EXTENT, this.min); - } - - if ((this.max[0] != 0) || (this.max[1] != 0) || (this.max[2] != 0)) { - stream.writeFloatArrayAttrib(MdlUtils.TOKEN_MAXIMUM_EXTENT, this.max); - } - - if (this.boundsRadius != 0) { - stream.writeFloatAttrib(MdlUtils.TOKEN_BOUNDSRADIUS, this.boundsRadius); - } - } - - public float getBoundsRadius() { - return this.boundsRadius; - } - - public float[] getMin() { - return this.min; - } - - public float[] getMax() { - return this.max; - } - - public void setBoundsRadius(final float boundsRadius) { - this.boundsRadius = boundsRadius; - } - - public void setMin(final float[] min) { - this.min = min; - } - - public void setMax(final float[] max) { - this.max = max; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxFaceEffect.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxFaceEffect.java deleted file mode 100644 index 47cb82b0..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxFaceEffect.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxFaceEffect implements MdlxBlock { - public String type = ""; - public String path = ""; - - @Override - public void readMdx(final BinaryReader reader, final int version) { - type = reader.read(80); - path = reader.read(260); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeWithNulls(type, 80); - writer.writeWithNulls(path, 260); - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - type = stream.read(); - - for (final String token : stream.readBlock()) { - if (token.equals("Path")) { - path = stream.read(); - } else { - throw new IllegalStateException("Unknown token in MdlxFaceEffect: " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startObjectBlock("FaceFX", type); - - stream.writeStringAttrib("Path", path); - - stream.endBlock(); - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxGenericObject.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxGenericObject.java deleted file mode 100644 index 12e9ee23..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxGenericObject.java +++ /dev/null @@ -1,278 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import java.util.Iterator; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxTimeline; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -/** - * A generic object. - *

- * The parent class for all objects that exist in the world, and may contain - * spatial animations. This includes bones, particle emitters, and many other - * things. - *

- * Based on the works of Chananya Freiman. - */ -public abstract class MdlxGenericObject extends MdlxAnimatedObject { - public String name = ""; - public int objectId = -1; - public int parentId = -1; - public int flags = 0; - - public MdlxGenericObject(final int flags) { - this.flags = flags; - } - - @Override - public void readMdx(final BinaryReader reader, final int version) { - final long size = reader.readUInt32(); - - this.name = reader.read(80); - this.objectId = reader.readInt32(); - this.parentId = reader.readInt32(); - this.flags = reader.readInt32(); - - readTimelines(reader, size - 96); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeUInt32(getGenericByteLength(version)); - writer.writeWithNulls(this.name, 80); - writer.writeInt32(this.objectId); - writer.writeInt32(this.parentId); - writer.writeInt32(this.flags); - - for (final MdlxTimeline timeline : this.timelines) { - if (isGeneric(timeline)) { - timeline.writeMdx(writer); - } - } - } - - public void writeNonGenericAnimationChunks(final BinaryWriter writer) { - for (final MdlxTimeline timeline : this.timelines) { - if (!isGeneric(timeline)) { - timeline.writeMdx(writer); - } - } - } - - protected final Iterable readMdlGeneric(final MdlTokenInputStream stream) { - this.name = stream.read(); - return () -> new WrappedMdlTokenIterator(readAnimatedBlock(stream), MdlxGenericObject.this, stream); - } - - public void writeGenericHeader(final MdlTokenOutputStream stream) { - stream.writeAttrib(MdlUtils.TOKEN_OBJECTID, this.objectId); - - if (this.parentId != -1) { - stream.writeAttrib("Parent", this.parentId); - } - - if ((this.flags & 0x40) != 0) { - stream.writeFlag(MdlUtils.TOKEN_BILLBOARDED_LOCK_Z); - } - - if ((this.flags & 0x20) != 0) { - stream.writeFlag(MdlUtils.TOKEN_BILLBOARDED_LOCK_Y); - } - - if ((this.flags & 0x10) != 0) { - stream.writeFlag(MdlUtils.TOKEN_BILLBOARDED_LOCK_X); - } - - if ((this.flags & 0x8) != 0) { - stream.writeFlag(MdlUtils.TOKEN_BILLBOARDED); - } - - if ((this.flags & 0x80) != 0) { - stream.writeFlag(MdlUtils.TOKEN_CAMERA_ANCHORED); - } - - if ((this.flags & 0x2) != 0) { - stream.writeFlag(MdlUtils.TOKEN_DONT_INHERIT + " { " + MdlUtils.TOKEN_ROTATION + " }"); - } - - if ((this.flags & 0x1) != 0) { - stream.writeFlag(MdlUtils.TOKEN_DONT_INHERIT + " { " + MdlUtils.TOKEN_TRANSLATION + " }"); - } - - if ((this.flags & 0x4) != 0) { - stream.writeFlag(MdlUtils.TOKEN_DONT_INHERIT + " { " + MdlUtils.TOKEN_SCALING + " }"); - } - } - - public void writeGenericTimelines(final MdlTokenOutputStream stream) { - writeTimeline(stream, AnimationMap.KGTR); - writeTimeline(stream, AnimationMap.KGRT); - writeTimeline(stream, AnimationMap.KGSC); - } - - public long getGenericByteLength(final int version) { - long size = 96; - - for (final MdlxTimeline timeline : this.timelines) { - if (isGeneric(timeline)) { - size += timeline.getByteLength(); - } - } - - return size; - } - - public boolean isGeneric(final MdlxTimeline timeline) { - final AnimationMap type = AnimationMap.ID_TO_TAG.get(timeline.name); - - return (type == AnimationMap.KGTR) || (type == AnimationMap.KGRT) || (type == AnimationMap.KGSC); - } - - @Override - public long getByteLength(final int version) { - return 96 + super.getByteLength(version); - } - - public String getName() { - return this.name; - } - - public int getObjectId() { - return this.objectId; - } - - public int getParentId() { - return this.parentId; - } - - public int getFlags() { - return this.flags; - } - - public void setName(final String name) { - this.name = name; - } - - public void setObjectId(final int objectId) { - this.objectId = objectId; - } - - public void setParentId(final int parentId) { - this.parentId = parentId; - } - - public void setFlags(final int flags) { - this.flags = flags; - } - - private static final class WrappedMdlTokenIterator implements Iterator { - private final Iterator delegate; - private final MdlxGenericObject updatingObject; - private final MdlTokenInputStream stream; - private String next; - private boolean hasLoaded = false; - - public WrappedMdlTokenIterator(final Iterator delegate, final MdlxGenericObject updatingObject, - final MdlTokenInputStream stream) { - this.delegate = delegate; - this.updatingObject = updatingObject; - this.stream = stream; - } - - @Override - public boolean hasNext() { - if (this.delegate.hasNext()) { - this.next = read(); - this.hasLoaded = true; - return this.next != null; - } - return false; - } - - @Override - public String next() { - if (!this.hasLoaded) { - this.next = read(); - } - this.hasLoaded = false; - return this.next; - } - - private String read() { - String token; - InteriorParsing: do { - token = this.delegate.next(); - if (token == null) { - break; - } - switch (token) { - case MdlUtils.TOKEN_OBJECTID: - this.updatingObject.objectId = Integer.parseInt(this.delegate.next()); - token = null; - break; - case MdlUtils.TOKEN_PARENT: - this.updatingObject.parentId = Integer.parseInt(this.delegate.next()); - token = null; - break; - case MdlUtils.TOKEN_BILLBOARDED_LOCK_Z: - this.updatingObject.flags |= 0x40; - token = null; - break; - case MdlUtils.TOKEN_BILLBOARDED_LOCK_Y: - this.updatingObject.flags |= 0x20; - token = null; - break; - case MdlUtils.TOKEN_BILLBOARDED_LOCK_X: - this.updatingObject.flags |= 0x10; - token = null; - break; - case MdlUtils.TOKEN_BILLBOARDED: - this.updatingObject.flags |= 0x8; - token = null; - break; - case MdlUtils.TOKEN_CAMERA_ANCHORED: - this.updatingObject.flags |= 0x80; - token = null; - break; - case MdlUtils.TOKEN_DONT_INHERIT: - for (final String subToken : this.stream.readBlock()) { - switch (subToken) { - case MdlUtils.TOKEN_ROTATION: - this.updatingObject.flags |= 0x2; - break; - case MdlUtils.TOKEN_TRANSLATION: - this.updatingObject.flags |= 0x1; - break; - case MdlUtils.TOKEN_SCALING: - this.updatingObject.flags |= 0x0; - break; - } - } - token = null; - break; - case MdlUtils.TOKEN_TRANSLATION: - this.updatingObject.readTimeline(this.stream, AnimationMap.KGTR); - token = null; - break; - case MdlUtils.TOKEN_ROTATION: - this.updatingObject.readTimeline(this.stream, AnimationMap.KGRT); - token = null; - break; - case MdlUtils.TOKEN_SCALING: - this.updatingObject.readTimeline(this.stream, AnimationMap.KGSC); - token = null; - break; - default: - break InteriorParsing; - } - } - while (this.delegate.hasNext()); - return token; - } - - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxGeoset.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxGeoset.java deleted file mode 100644 index 8a0d198a..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxGeoset.java +++ /dev/null @@ -1,592 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxGeoset implements MdlxBlock, MdlxChunk { - private static final War3ID VRTX = War3ID.fromString("VRTX"); - private static final War3ID NRMS = War3ID.fromString("NRMS"); - private static final War3ID PTYP = War3ID.fromString("PTYP"); - private static final War3ID PCNT = War3ID.fromString("PCNT"); - private static final War3ID PVTX = War3ID.fromString("PVTX"); - private static final War3ID GNDX = War3ID.fromString("GNDX"); - private static final War3ID MTGC = War3ID.fromString("MTGC"); - private static final War3ID MATS = War3ID.fromString("MATS"); - private static final War3ID TANG = War3ID.fromString("TANG"); - private static final War3ID SKIN = War3ID.fromString("SKIN"); - private static final War3ID UVAS = War3ID.fromString("UVAS"); - private static final War3ID UVBS = War3ID.fromString("UVBS"); - - public float[] vertices; - public float[] normals; - public long[] faceTypeGroups; // unsigned int[] - public long[] faceGroups; // unsigned int[] - public int[] faces; // unsigned short[] - public short[] vertexGroups; // unsigned byte[] - public long[] matrixGroups; // unsigned int[] - public long[] matrixIndices; // unsigned int[] - public long materialId = 0; - public long selectionGroup = 0; - public long selectionFlags = 0; - /** - * @since 900 - */ - public int lod = 0; - /** - * @since 900 - */ - public String lodName = ""; - public MdlxExtent extent = new MdlxExtent(); - public List sequenceExtents = new ArrayList<>(); - /** - * @since 900 - */ - public float[] tangents; - /** - * @since 900 - */ - public short[] skin; - public float[][] uvSets; - - @Override - public void readMdx(final BinaryReader reader, final int version) { - final long size = reader.readUInt32(); - - reader.readInt32(); // skip VRTX - this.vertices = reader.readFloat32Array(reader.readInt32() * 3); - reader.readInt32(); // skip NRMS - this.normals = reader.readFloat32Array(reader.readInt32() * 3); - reader.readInt32(); // skip PTYP - this.faceTypeGroups = reader.readUInt32Array(reader.readInt32()); - reader.readInt32(); // skip PCNT - this.faceGroups = reader.readUInt32Array(reader.readInt32()); - reader.readInt32(); // skip PVTX - this.faces = reader.readUInt16Array(reader.readInt32()); - reader.readInt32(); // skip GNDX - this.vertexGroups = reader.readUInt8Array(reader.readInt32()); - reader.readInt32(); // skip MTGC - this.matrixGroups = reader.readUInt32Array(reader.readInt32()); - reader.readInt32(); // skip MATS - this.matrixIndices = reader.readUInt32Array(reader.readInt32()); - this.materialId = reader.readUInt32(); - this.selectionGroup = reader.readUInt32(); - this.selectionFlags = reader.readUInt32(); - - if (version > 800) { - this.lod = reader.readInt32(); - this.lodName = reader.read(80); - } - - this.extent.readMdx(reader); - - final long numExtents = reader.readUInt32(); - - for (int i = 0; i < numExtents; i++) { - final MdlxExtent extent = new MdlxExtent(); - extent.readMdx(reader); - this.sequenceExtents.add(extent); - } - - int id = reader.readTag(); // TANG or SKIN or UVAS - - if ((version > 800) && (id != UVAS.getValue())) { - if (id == TANG.getValue()) { - this.tangents = reader.readFloat32Array(reader.readInt32() * 4); - - id = reader.readTag(); // SKIN or UVAS - } - - if (id == SKIN.getValue()) { - this.skin = reader.readUInt8Array(reader.readInt32()); - - id = reader.readInt32(); // UVAS - } - } - - final long numUVLayers = reader.readUInt32(); - this.uvSets = new float[(int) numUVLayers][]; - for (int i = 0; i < numUVLayers; i++) { - reader.readInt32(); // skip UVBS - this.uvSets[i] = reader.readFloat32Array(reader.readInt32() * 2); - } - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeUInt32(getByteLength(version)); - writer.writeTag(VRTX.getValue()); - writer.writeUInt32(this.vertices.length / 3); - writer.writeFloat32Array(this.vertices); - writer.writeTag(NRMS.getValue()); - writer.writeUInt32(this.normals.length / 3); - writer.writeFloat32Array(this.normals); - writer.writeTag(PTYP.getValue()); - writer.writeUInt32(this.faceTypeGroups.length); - writer.writeUInt32Array(this.faceTypeGroups); - writer.writeTag(PCNT.getValue()); - writer.writeUInt32(this.faceGroups.length); - writer.writeUInt32Array(this.faceGroups); - writer.writeTag(PVTX.getValue()); - writer.writeUInt32(this.faces.length); - writer.writeUInt16Array(this.faces); - writer.writeTag(GNDX.getValue()); - writer.writeUInt32(this.vertexGroups.length); - writer.writeUInt8Array(this.vertexGroups); - writer.writeTag(MTGC.getValue()); - writer.writeUInt32(this.matrixGroups.length); - writer.writeUInt32Array(this.matrixGroups); - writer.writeTag(MATS.getValue()); - writer.writeUInt32(this.matrixIndices.length); - writer.writeUInt32Array(this.matrixIndices); - writer.writeUInt32(this.materialId); - writer.writeUInt32(this.selectionGroup); - writer.writeUInt32(this.selectionFlags); - - if (version > 800) { - writer.writeInt32(this.lod); - writer.writeWithNulls(this.lodName, 80); - } - - this.extent.writeMdx(writer); - writer.writeUInt32(this.sequenceExtents.size()); - - for (final MdlxExtent sequenceExtent : this.sequenceExtents) { - sequenceExtent.writeMdx(writer); - } - - if (version > 800) { - if (this.tangents != null) { - writer.writeTag(TANG.getValue()); - writer.writeUInt32(this.tangents.length / 4); - writer.writeFloat32Array(this.tangents); - } - - if (this.skin != null) { - writer.writeTag(SKIN.getValue()); - writer.writeUInt32(this.skin.length); - writer.writeUInt8Array(this.skin); - } - } - - writer.writeTag(UVAS.getValue()); - writer.writeUInt32(this.uvSets.length); - - for (final float[] uvSet : this.uvSets) { - writer.writeTag(UVBS.getValue()); - writer.writeUInt32(uvSet.length / 2); - writer.writeFloat32Array(uvSet); - } - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - this.uvSets = new float[0][]; - - for (final String token : stream.readBlock()) { - // For now hardcoded for triangles, until I see a model with something - // different. - switch (token) { - case MdlUtils.TOKEN_VERTICES: - this.vertices = stream.readVectorArray(new float[stream.readInt() * 3], 3); - break; - case MdlUtils.TOKEN_NORMALS: - this.normals = stream.readVectorArray(new float[stream.readInt() * 3], 3); - break; - case MdlUtils.TOKEN_TVERTICES: { - this.uvSets = Arrays.copyOf(this.uvSets, this.uvSets.length + 1); - this.uvSets[this.uvSets.length - 1] = stream.readVectorArray(new float[stream.readInt() * 2], 2); - } - break; - case MdlUtils.TOKEN_VERTEX_GROUP: { - // Vertex groups are stored in a block with no count, can't allocate the buffer - // yet. - final List vertexGroups = new ArrayList<>(); - for (final String vertexGroup : stream.readBlock()) { - vertexGroups.add(Short.valueOf(vertexGroup)); - } - - this.vertexGroups = new short[vertexGroups.size()]; - int i = 0; - for (final Short vertexGroup : vertexGroups) { - this.vertexGroups[i++] = vertexGroup; - } - } - break; - case "Tangents": { - final int tansCount = (int) stream.readUInt32(); - this.tangents = new float[tansCount * 4]; - stream.readVectorArray(this.tangents, 4); - } - break; - case "SkinWeights": { - final int skinCount = (int) stream.readUInt32(); - this.skin = new short[skinCount * 8]; - stream.readUInt8Array(this.skin); - } - break; - case MdlUtils.TOKEN_FACES: { - this.faceTypeGroups = new long[] { 4L }; - stream.readInt(); // number of groups - final int count = stream.readInt(); - stream.read(); // { - stream.read(); // Triangles - stream.read(); // { - this.faces = stream.readUInt16Array(new int[count]); - this.faceGroups = new long[] { count }; - stream.read(); // } - stream.read(); // } - } - break; - case MdlUtils.TOKEN_GROUPS: { - final List indices = new ArrayList<>(); - final List groups = new ArrayList<>(); - - stream.readInt(); // matrices count - stream.readInt(); // total indices - - // eslint-disable-next-line no-unused-vars - for (final String matrix : stream.readBlock()) { - int size = 0; - - for (final String index : stream.readBlock()) { - indices.add(Integer.valueOf(index)); - size += 1; - } - groups.add(size); - } - - this.matrixIndices = new long[indices.size()]; - int i = 0; - for (final Integer index : indices) { - this.matrixIndices[i++] = index; - } - this.matrixGroups = new long[groups.size()]; - i = 0; - for (final Integer group : groups) { - this.matrixGroups[i++] = group; - } - } - break; - case MdlUtils.TOKEN_MINIMUM_EXTENT: - stream.readFloatArray(this.extent.min); - break; - case MdlUtils.TOKEN_MAXIMUM_EXTENT: - stream.readFloatArray(this.extent.max); - break; - case MdlUtils.TOKEN_BOUNDSRADIUS: - this.extent.boundsRadius = stream.readFloat(); - break; - case MdlUtils.TOKEN_ANIM: { - final MdlxExtent extent = new MdlxExtent(); - for (final String subToken : stream.readBlock()) { - switch (subToken) { - case MdlUtils.TOKEN_MINIMUM_EXTENT: - stream.readFloatArray(extent.min); - break; - case MdlUtils.TOKEN_MAXIMUM_EXTENT: - stream.readFloatArray(extent.max); - break; - case MdlUtils.TOKEN_BOUNDSRADIUS: - extent.boundsRadius = stream.readFloat(); - break; - } - } - this.sequenceExtents.add(extent); - } - break; - case MdlUtils.TOKEN_MATERIAL_ID: - this.materialId = stream.readInt(); - break; - case MdlUtils.TOKEN_SELECTION_GROUP: - this.selectionGroup = stream.readInt(); - break; - case MdlUtils.TOKEN_UNSELECTABLE: - this.selectionFlags = 4; - break; - case "LevelOfDetail": - this.lod = stream.readInt(); - break; - case "Name": - this.lodName = stream.read(); - break; - default: - throw new RuntimeException("Unknown token in Geoset: " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startBlock(MdlUtils.TOKEN_GEOSET); - - stream.writeVectorArray(MdlUtils.TOKEN_VERTICES, this.vertices, 3); - stream.writeVectorArray(MdlUtils.TOKEN_NORMALS, this.normals, 3); - - for (final float[] uvSet : this.uvSets) { - stream.writeVectorArray(MdlUtils.TOKEN_TVERTICES, uvSet, 2); - } - - if (version <= 800) { - stream.startBlock(MdlUtils.TOKEN_VERTEX_GROUP); - for (final short vertexGroup : this.vertexGroups) { - stream.writeLine(vertexGroup + ","); - } - stream.endBlock(); - } - - if (version > 800) { - - stream.startBlock(MdlUtils.TOKEN_VERTEX_GROUP); - if (this.skin == null) { - for (final short vertexGroup : this.vertexGroups) { - stream.writeLine(vertexGroup + ","); - } - } - stream.endBlock(); - - if (this.tangents != null) { - stream.startBlock("Tangents", this.tangents.length / 4); - - for (int i = 0, l = this.tangents.length; i < l; i += 4) { - stream.writeFloatArray(Arrays.copyOfRange(this.tangents, i, i + 4)); - } - - stream.endBlock(); - } - - if (this.skin != null) { - stream.startBlock("SkinWeights", this.skin.length / 8); - - for (int i = 0, l = this.skin.length; i < l; i += 8) { - stream.writeShortArrayRaw(Arrays.copyOfRange(this.skin, i, i + 8)); - } - - stream.endBlock(); - } - } - - // For now hardcoded for triangles, until I see a model with something - // different. - stream.startBlock(MdlUtils.TOKEN_FACES, 1, this.faces.length); - stream.startBlock(MdlUtils.TOKEN_TRIANGLES); - final StringBuilder facesBuffer = new StringBuilder(); - for (final int faceValue : this.faces) { - if (facesBuffer.length() > 0) { - facesBuffer.append(", "); - } - facesBuffer.append(faceValue); - } - stream.writeLine("{ " + facesBuffer.toString() + " },"); - stream.endBlock(); - stream.endBlock(); - - stream.startBlock(MdlUtils.TOKEN_GROUPS, this.matrixGroups.length, this.matrixIndices.length); - int index = 0; - for (final long groupSize : this.matrixGroups) { - stream.writeLongSubArrayAttrib(MdlUtils.TOKEN_MATRICES, this.matrixIndices, index, - (int) (index + groupSize)); - index += groupSize; - } - stream.endBlock(); - - this.extent.writeMdl(stream); - - for (final MdlxExtent sequenceExtent : this.sequenceExtents) { - stream.startBlock(MdlUtils.TOKEN_ANIM); - sequenceExtent.writeMdl(stream); - stream.endBlock(); - } - - stream.writeAttribUInt32("MaterialID", this.materialId); - stream.writeAttribUInt32("SelectionGroup", this.selectionGroup); - if (this.selectionFlags == 4) { - stream.writeFlag("Unselectable"); - } - - if (version > 800) { - stream.writeAttrib("LevelOfDetail", this.lod); - - if (this.lodName.length() > 0) { - stream.writeStringAttrib("Name", this.lodName); - } - } - - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - long size = 120 + (this.vertices.length * 4) + (this.normals.length * 4) + (this.faceTypeGroups.length * 4) - + (this.faceGroups.length * 4) + (this.faces.length * 2) + this.vertexGroups.length - + (this.matrixGroups.length * 4) + (this.matrixIndices.length * 4) + (this.sequenceExtents.size() * 28); - for (final float[] uvSet : this.uvSets) { - size += 8 + (uvSet.length * 4); - } - - if (version > 800) { - size += 84; - - if (this.tangents != null) { - size += 8 + (this.tangents.length * 4); - } - - if (this.skin != null) { - size += 8 + this.skin.length; - } - } - - return size; - } - - public float[] getVertices() { - return this.vertices; - } - - public float[] getNormals() { - return this.normals; - } - - public long[] getFaceTypeGroups() { - return this.faceTypeGroups; - } - - public long[] getFaceGroups() { - return this.faceGroups; - } - - public int[] getFaces() { - return this.faces; - } - - public short[] getVertexGroups() { - return this.vertexGroups; - } - - public long[] getMatrixGroups() { - return this.matrixGroups; - } - - public long[] getMatrixIndices() { - return this.matrixIndices; - } - - public long getMaterialId() { - return this.materialId; - } - - public long getSelectionGroup() { - return this.selectionGroup; - } - - public long getSelectionFlags() { - return this.selectionFlags; - } - - public int getLod() { - return this.lod; - } - - public String getLodName() { - return this.lodName; - } - - public MdlxExtent getExtent() { - return this.extent; - } - - public List getSequenceExtents() { - return this.sequenceExtents; - } - - public float[] getTangents() { - return this.tangents; - } - - public short[] getSkin() { - return this.skin; - } - - public float[][] getUvSets() { - return this.uvSets; - } - - public void setVertices(final float[] vertices) { - this.vertices = vertices; - } - - public void setNormals(final float[] normals) { - this.normals = normals; - } - - public void setFaceTypeGroups(final long[] faceTypeGroups) { - this.faceTypeGroups = faceTypeGroups; - } - - public void setFaceGroups(final long[] faceGroups) { - this.faceGroups = faceGroups; - } - - public void setFaces(final int[] faces) { - this.faces = faces; - } - - public void setVertexGroups(final short[] vertexGroups) { - this.vertexGroups = vertexGroups; - } - - public void setMatrixGroups(final long[] matrixGroups) { - this.matrixGroups = matrixGroups; - } - - public void setMatrixIndices(final long[] matrixIndices) { - this.matrixIndices = matrixIndices; - } - - public void setMaterialId(final long materialId) { - this.materialId = materialId; - } - - public void setSelectionGroup(final long selectionGroup) { - this.selectionGroup = selectionGroup; - } - - public void setSelectionFlags(final long selectionFlags) { - this.selectionFlags = selectionFlags; - } - - public void setLod(final int lod) { - this.lod = lod; - } - - public void setLodName(final String lodName) { - this.lodName = lodName; - } - - public void setExtent(final MdlxExtent extent) { - this.extent = extent; - } - - public void setSequenceExtents(final List sequenceExtents) { - this.sequenceExtents = sequenceExtents; - } - - public void setTangents(final float[] tangents) { - this.tangents = tangents; - } - - public void setSkin(final short[] skin) { - this.skin = skin; - } - - public void setUvSets(final float[][] uvSets) { - this.uvSets = uvSets; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxGeosetAnimation.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxGeosetAnimation.java deleted file mode 100644 index cf18f92f..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxGeosetAnimation.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import java.util.Iterator; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxGeosetAnimation extends MdlxAnimatedObject { - public float alpha = 1; - public int flags = 0; - public float[] color = { 1, 1, 1 }; - public int geosetId = -1; - - @Override - public void readMdx(final BinaryReader reader, final int version) { - final long size = reader.readUInt32(); - - this.alpha = reader.readFloat32(); - this.flags = reader.readInt32(); - reader.readFloat32Array(this.color); - this.geosetId = reader.readInt32(); - - readTimelines(reader, size - 28); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeUInt32(getByteLength(version)); - writer.writeFloat32(this.alpha); - writer.writeInt32(this.flags); - writer.writeFloat32Array(this.color); - writer.writeInt32(this.geosetId); - - writeTimelines(writer); - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - final Iterator blockIterator = readAnimatedBlock(stream); - while (blockIterator.hasNext()) { - final String token = blockIterator.next(); - switch (token) { - case MdlUtils.TOKEN_DROP_SHADOW: - this.flags |= 0x1; - break; - case MdlUtils.TOKEN_STATIC_ALPHA: - this.alpha = stream.readFloat(); - break; - case MdlUtils.TOKEN_ALPHA: - readTimeline(stream, AnimationMap.KGAO); - break; - case MdlUtils.TOKEN_STATIC_COLOR: { - this.flags |= 0x2; - stream.readColor(this.color); - } - break; - case MdlUtils.TOKEN_COLOR: { - this.flags |= 0x2; - readTimeline(stream, AnimationMap.KGAC); - } - break; - case MdlUtils.TOKEN_GEOSETID: - this.geosetId = stream.readInt(); - break; - default: - throw new RuntimeException("Unknown token in GeosetAnimation: " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startBlock(MdlUtils.TOKEN_GEOSETANIM); - - if ((this.flags & 0x1) != 0) { - stream.writeFlag(MdlUtils.TOKEN_DROP_SHADOW); - } - - if (!writeTimeline(stream, AnimationMap.KGAO)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_ALPHA, this.alpha); - } - - if ((this.flags & 0x2) != 0) { - if (!writeTimeline(stream, AnimationMap.KGAC) - && ((this.color[0] != 0) || (this.color[1] != 0) || (this.color[2] != 0))) { - stream.writeColor(MdlUtils.TOKEN_STATIC_COLOR, this.color); - } - } - - if (this.geosetId != -1) { // TODO Retera added -1 check here, why wasn't it there before in JS??? - stream.writeAttrib(MdlUtils.TOKEN_GEOSETID, this.geosetId); - } - - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - return 28 + super.getByteLength(version); - } - - public float getAlpha() { - return this.alpha; - } - - public int getFlags() { - return this.flags; - } - - public float[] getColor() { - return this.color; - } - - public int getGeosetId() { - return this.geosetId; - } - - public void setAlpha(final float alpha) { - this.alpha = alpha; - } - - public void setFlags(final int flags) { - this.flags = flags; - } - - public void setColor(final float[] color) { - this.color = color; - } - - public void setGeosetId(final int geosetId) { - this.geosetId = geosetId; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxHelper.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxHelper.java deleted file mode 100644 index 962b020a..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxHelper.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; - -public class MdlxHelper extends MdlxGenericObject { - public MdlxHelper() { - super(0x0); // NOTE: ghostwolf JS didn't pass the 0x1 flag???? - // ANOTHER NOTE: setting the 0x1 flag causes other fan programs to spam error - // messages - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - for (final String token : readMdlGeneric(stream)) { - throw new RuntimeException("Unknown token in Helper: " + token); - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startObjectBlock(MdlUtils.TOKEN_HELPER, name); - writeGenericHeader(stream); - writeGenericTimelines(stream); - stream.endBlock(); - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxLayer.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxLayer.java deleted file mode 100644 index 0f54476a..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxLayer.java +++ /dev/null @@ -1,369 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import java.util.Iterator; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxLayer extends MdlxAnimatedObject { - public enum FilterMode { - NONE("None"), - TRANSPARENT("Transparent"), - BLEND("Blend"), - ADDITIVE("Additive"), - ADDALPHA("AddAlpha"), - MODULATE("Modulate"), - MODULATE2X("Modulate2x"); - - String token; - - FilterMode(final String token) { - this.token = token; - } - - public static FilterMode fromId(final int id) { - return values()[id]; - } - - public static int nameToId(final String name) { - for (final FilterMode mode : values()) { - if (mode.token.equals(name)) { - return mode.ordinal(); - } - } - return -1; - } - - public static FilterMode nameToFilter(final String name) { - for (final FilterMode mode : values()) { - if (mode.token.equals(name)) { - return mode; - } - } - return null; - } - - @Override - public String toString() { - return this.token; - } - } - - public FilterMode filterMode = FilterMode.NONE; - public int flags = 0; - public int textureId = -1; - public int textureAnimationId = -1; - public long coordId = 0; - public float alpha = 1; - /** - * @since 900 - */ - public float emissiveGain = 1; - /** - * @since 1000 - */ - public float[] fresnelColor = new float[] { 1, 1, 1 }; - /** - * @since 1000 - */ - public float fresnelOpacity = 0; - /** - * @since 1000 - */ - public float fresnelTeamColor = 0; - - @Override - public void readMdx(final BinaryReader reader, final int version) { - final int position = reader.position(); - final long size = reader.readUInt32(); - - this.filterMode = FilterMode.fromId(reader.readInt32()); - this.flags = reader.readInt32(); // UInt32 in JS - this.textureId = reader.readInt32(); - this.textureAnimationId = reader.readInt32(); - this.coordId = reader.readInt32(); - this.alpha = reader.readFloat32(); - - if (version > 800) { - this.emissiveGain = reader.readFloat32(); - - if (version > 900) { - reader.readFloat32Array(this.fresnelColor); - this.fresnelOpacity = reader.readFloat32(); - this.fresnelTeamColor = reader.readFloat32(); - } - } - - readTimelines(reader, size - (reader.position() - position)); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeUInt32(getByteLength(version)); - writer.writeUInt32(this.filterMode.ordinal()); - writer.writeUInt32(this.flags); - writer.writeInt32(this.textureId); - writer.writeInt32(this.textureAnimationId); - writer.writeUInt32(this.coordId); - writer.writeFloat32(this.alpha); - - if (version > 800) { - writer.writeFloat32(this.emissiveGain); - - if (version > 900) { - writer.writeFloat32Array(this.fresnelColor); - writer.writeFloat32(this.fresnelOpacity); - writer.writeFloat32(this.fresnelTeamColor); - } - } - - writeTimelines(writer); - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - final Iterator iterator = readAnimatedBlock(stream); - while (iterator.hasNext()) { - final String token = iterator.next(); - switch (token) { - case MdlUtils.TOKEN_FILTER_MODE: - this.filterMode = FilterMode.fromId(FilterMode.nameToId(stream.read())); - break; - case MdlUtils.TOKEN_UNSHADED: - this.flags |= 0x1; - break; - case MdlUtils.TOKEN_SPHERE_ENV_MAP: - this.flags |= 0x2; - break; - case MdlUtils.TOKEN_TWO_SIDED: - this.flags |= 0x10; - break; - case MdlUtils.TOKEN_UNFOGGED: - this.flags |= 0x20; - break; - case MdlUtils.TOKEN_NO_DEPTH_TEST: - this.flags |= 0x40; - break; - case MdlUtils.TOKEN_NO_DEPTH_SET: - this.flags |= 0x80; - break; - case "Unlit": - this.flags |= 0x100; - case MdlUtils.TOKEN_STATIC_TEXTURE_ID: - this.textureId = stream.readInt(); - break; - case MdlUtils.TOKEN_TEXTURE_ID: - readTimeline(stream, AnimationMap.KMTF); - break; - case MdlUtils.TOKEN_TVERTEX_ANIM_ID: - this.textureAnimationId = stream.readInt(); - break; - case MdlUtils.TOKEN_COORD_ID: - this.coordId = stream.readInt(); - break; - case MdlUtils.TOKEN_STATIC_ALPHA: - this.alpha = stream.readFloat(); - break; - case MdlUtils.TOKEN_ALPHA: - readTimeline(stream, AnimationMap.KMTA); - break; - case "static EmissiveGain": - this.emissiveGain = stream.readFloat(); - break; - case "EmissiveGain": - readTimeline(stream, AnimationMap.KMTE); - break; - case "static FresnelColor": - stream.readColor(this.fresnelColor); - break; - case "FresnelColor": - readTimeline(stream, AnimationMap.KFC3); - break; - case "static FresnelOpacity": - this.fresnelOpacity = stream.readFloat(); - break; - case "FresnelOpacity": - readTimeline(stream, AnimationMap.KFCA); - break; - case "static FresnelTeamColor": - this.fresnelTeamColor = stream.readFloat(); - break; - case "FresnelTeamColor": - readTimeline(stream, AnimationMap.KFTC); - break; - default: - throw new RuntimeException("Unknown token in Layer: " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startBlock(MdlUtils.TOKEN_LAYER); - - stream.writeAttrib(MdlUtils.TOKEN_FILTER_MODE, this.filterMode.toString()); - - if ((this.flags & 0x1) != 0) { - stream.writeFlag(MdlUtils.TOKEN_UNSHADED); - } - - if ((this.flags & 0x2) != 0) { - stream.writeFlag(MdlUtils.TOKEN_SPHERE_ENV_MAP); - } - - if ((this.flags & 0x10) != 0) { - stream.writeFlag(MdlUtils.TOKEN_TWO_SIDED); - } - - if ((this.flags & 0x20) != 0) { - stream.writeFlag(MdlUtils.TOKEN_UNFOGGED); - } - - if ((this.flags & 0x40) != 0) { - stream.writeFlag(MdlUtils.TOKEN_NO_DEPTH_TEST); - } - - if ((this.flags & 0x100) != 0) { - stream.writeFlag(MdlUtils.TOKEN_NO_DEPTH_SET); - } - - if ((version > 800) && ((this.flags & 0x100) != 0)) { - stream.writeFlag("Unlit"); - } - - if (!writeTimeline(stream, AnimationMap.KMTF)) { - stream.writeAttrib(MdlUtils.TOKEN_STATIC_TEXTURE_ID, this.textureId); - } - - if (this.textureAnimationId != -1) { - stream.writeAttrib(MdlUtils.TOKEN_TVERTEX_ANIM_ID, this.textureAnimationId); - } - - if (this.coordId != 0) { - stream.writeAttribUInt32(MdlUtils.TOKEN_COORD_ID, this.coordId); - } - - if (!writeTimeline(stream, AnimationMap.KMTA) && (this.alpha != 1)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_ALPHA, this.alpha); - } - - if (version > 800) { - if (!writeTimeline(stream, AnimationMap.KMTE) && (this.emissiveGain != 1)) { - stream.writeFloatAttrib("static EmissiveGain", this.emissiveGain); - } - - if (!writeTimeline(stream, AnimationMap.KFC3) - && ((this.fresnelColor[0] != 1) || (this.fresnelColor[1] != 1) || (this.fresnelColor[2] != 1))) { - stream.writeFloatArrayAttrib("static FresnelColor", this.fresnelColor); - } - - if (!writeTimeline(stream, AnimationMap.KFCA) && (this.fresnelOpacity != 0)) { - stream.writeFloatAttrib("static FresnelOpacity", this.fresnelOpacity); - } - - if (!writeTimeline(stream, AnimationMap.KFTC) && (this.fresnelTeamColor != 0)) { - stream.writeFloatAttrib("static FresnelTeamColor", this.fresnelTeamColor); - } - } - - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - long byteLength = 28 + super.getByteLength(version); - - if (version > 800) { - byteLength += 4; - - if (version > 900) { - byteLength += 20; - } - } - - return byteLength; - } - - public FilterMode getFilterMode() { - return this.filterMode; - } - - public int getFlags() { - return this.flags; - } - - public int getTextureId() { - return this.textureId; - } - - public int getTextureAnimationId() { - return this.textureAnimationId; - } - - public long getCoordId() { - return this.coordId; - } - - public float getAlpha() { - return this.alpha; - } - - public float getEmissiveGain() { - return this.emissiveGain; - } - - public float[] getFresnelColor() { - return this.fresnelColor; - } - - public float getFresnelOpacity() { - return this.fresnelOpacity; - } - - public float getFresnelTeamColor() { - return this.fresnelTeamColor; - } - - public void setFilterMode(final FilterMode filterMode) { - this.filterMode = filterMode; - } - - public void setFlags(final int flags) { - this.flags = flags; - } - - public void setTextureId(final int textureId) { - this.textureId = textureId; - } - - public void setTextureAnimationId(final int textureAnimationId) { - this.textureAnimationId = textureAnimationId; - } - - public void setCoordId(final long coordId) { - this.coordId = coordId; - } - - public void setAlpha(final float alpha) { - this.alpha = alpha; - } - - public void setEmissiveGain(final float emissiveGain) { - this.emissiveGain = emissiveGain; - } - - public void setFresnelColor(final float[] fresnelColor) { - this.fresnelColor = fresnelColor; - } - - public void setFresnelOpacity(final float fresnelOpacity) { - this.fresnelOpacity = fresnelOpacity; - } - - public void setFresnelTeamColor(final float fresnelTeamColor) { - this.fresnelTeamColor = fresnelTeamColor; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxLight.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxLight.java deleted file mode 100644 index 1a656855..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxLight.java +++ /dev/null @@ -1,222 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxLight extends MdlxGenericObject { - public enum Type { - OMNIDIRECTIONAL("Omnidirectional"), - DIRECTIONAL("Directional"), - AMBIENT("Ambient"); - - String token; - - Type(final String token) { - this.token = token; - } - - public static Type fromId(final int id) { - return values()[id]; - } - - @Override - public String toString() { - return this.token; - } - } - - public Type type = Type.OMNIDIRECTIONAL; - public float[] attenuation = new float[2]; - public float[] color = new float[3]; - public float intensity = 0; - public float[] ambientColor = new float[3]; - public float ambientIntensity = 0; - - public MdlxLight() { - super(0x200); - } - - @Override - public void readMdx(final BinaryReader reader, final int version) { - final int position = reader.position(); - final long size = reader.readUInt32(); - - super.readMdx(reader, version); - - this.type = Type.fromId(reader.readInt32()); - reader.readFloat32Array(this.attenuation); - reader.readFloat32Array(this.color); - this.intensity = reader.readFloat32(); - reader.readFloat32Array(this.ambientColor); - this.ambientIntensity = reader.readFloat32(); - - readTimelines(reader, size - (reader.position() - position)); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeUInt32(getByteLength(version)); - - super.writeMdx(writer, version); - - writer.writeUInt32(this.type.ordinal()); - writer.writeFloat32Array(this.attenuation); - writer.writeFloat32Array(this.color); - writer.writeFloat32(this.intensity); - writer.writeFloat32Array(this.ambientColor); - writer.writeFloat32(this.ambientIntensity); - - writeNonGenericAnimationChunks(writer); - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - for (final String token : super.readMdlGeneric(stream)) { - switch (token) { - case MdlUtils.TOKEN_OMNIDIRECTIONAL: - this.type = Type.OMNIDIRECTIONAL; - break; - case MdlUtils.TOKEN_DIRECTIONAL: - this.type = Type.DIRECTIONAL; - break; - case MdlUtils.TOKEN_AMBIENT: - this.type = Type.AMBIENT; - break; - case MdlUtils.TOKEN_STATIC_ATTENUATION_START: - this.attenuation[0] = stream.readFloat(); - break; - case MdlUtils.TOKEN_ATTENUATION_START: - readTimeline(stream, AnimationMap.KLAS); - break; - case MdlUtils.TOKEN_STATIC_ATTENUATION_END: - this.attenuation[1] = stream.readFloat(); - break; - case MdlUtils.TOKEN_ATTENUATION_END: - readTimeline(stream, AnimationMap.KLAE); - break; - case MdlUtils.TOKEN_STATIC_INTENSITY: - this.intensity = stream.readFloat(); - break; - case MdlUtils.TOKEN_INTENSITY: - readTimeline(stream, AnimationMap.KLAI); - break; - case MdlUtils.TOKEN_STATIC_COLOR: - stream.readColor(this.color); - break; - case MdlUtils.TOKEN_COLOR: - readTimeline(stream, AnimationMap.KLAC); - break; - case MdlUtils.TOKEN_STATIC_AMB_INTENSITY: - this.ambientIntensity = stream.readFloat(); - break; - case MdlUtils.TOKEN_AMB_INTENSITY: - readTimeline(stream, AnimationMap.KLBI); - break; - case MdlUtils.TOKEN_STATIC_AMB_COLOR: - stream.readColor(this.ambientColor); - break; - case MdlUtils.TOKEN_AMB_COLOR: - readTimeline(stream, AnimationMap.KLBC); - break; - case MdlUtils.TOKEN_VISIBILITY: - readTimeline(stream, AnimationMap.KLAV); - break; - default: - throw new RuntimeException("Unknown token in Light: " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startObjectBlock(MdlUtils.TOKEN_LIGHT, this.name); - writeGenericHeader(stream); - - stream.writeFlag(this.type.toString()); - - if (!writeTimeline(stream, AnimationMap.KLAS)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_ATTENUATION_START, this.attenuation[0]); - } - - if (!writeTimeline(stream, AnimationMap.KLAE)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_ATTENUATION_END, this.attenuation[1]); - } - - if (!writeTimeline(stream, AnimationMap.KLAI)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_INTENSITY, this.intensity); - } - - if (!writeTimeline(stream, AnimationMap.KLAC)) { - stream.writeColor(MdlUtils.TOKEN_STATIC_COLOR, this.color); - } - - if (!writeTimeline(stream, AnimationMap.KLBI)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_AMB_INTENSITY, this.ambientIntensity); - } - - if (!writeTimeline(stream, AnimationMap.KLBC)) { - stream.writeColor(MdlUtils.TOKEN_STATIC_AMB_COLOR, this.ambientColor); - } - - writeTimeline(stream, AnimationMap.KLAV); - - writeGenericTimelines(stream); - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - return 48 + super.getByteLength(version); - } - - public Type getType() { - return this.type; - } - - public float[] getAttenuation() { - return this.attenuation; - } - - public float[] getColor() { - return this.color; - } - - public float getIntensity() { - return this.intensity; - } - - public float[] getAmbientColor() { - return this.ambientColor; - } - - public float getAmbientIntensity() { - return this.ambientIntensity; - } - - public void setType(final Type type) { - this.type = type; - } - - public void setAttenuation(final float[] attenuation) { - this.attenuation = attenuation; - } - - public void setColor(final float[] color) { - this.color = color; - } - - public void setIntensity(final float intensity) { - this.intensity = intensity; - } - - public void setAmbientColor(final float[] ambientColor) { - this.ambientColor = ambientColor; - } - - public void setAmbientIntensity(final float ambientIntensity) { - this.ambientIntensity = ambientIntensity; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxMaterial.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxMaterial.java deleted file mode 100644 index e7e013b4..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxMaterial.java +++ /dev/null @@ -1,173 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxMaterial implements MdlxBlock, MdlxChunk { - public static final War3ID LAYS = War3ID.fromString("LAYS"); - public int priorityPlane = 0; - public int flags; - /** - * @since 900 - */ - public String shader = ""; - public final List layers = new ArrayList<>(); - - @Override - public void readMdx(final BinaryReader reader, final int version) { - reader.readUInt32(); // Don't care about the size - - this.priorityPlane = reader.readInt32(); - this.flags = reader.readInt32(); - - if (version > 800) { - this.shader = reader.read(80); - } - - reader.readInt32(); // skip LAYS - - final long layerCount = reader.readUInt32(); - for (int i = 0; i < layerCount; i++) { - final MdlxLayer layer = new MdlxLayer(); - layer.readMdx(reader, version); - this.layers.add(layer); - } - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeUInt32(getByteLength(version)); - writer.writeInt32(this.priorityPlane); - writer.writeInt32(this.flags); - - if (version > 800) { - writer.writeWithNulls(this.shader, 80); - } - - writer.writeTag(LAYS.getValue()); - writer.writeUInt32(this.layers.size()); - - for (final MdlxLayer layer : this.layers) { - layer.writeMdx(writer, version); - } - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - for (final String token : stream.readBlock()) { - switch (token) { - case MdlUtils.TOKEN_CONSTANT_COLOR: - this.flags |= 0x1; - break; - case MdlUtils.TOKEN_SORT_PRIMS_NEAR_Z: - this.flags |= 0x8; - break; - case MdlUtils.TOKEN_SORT_PRIMS_FAR_Z: - this.flags |= 0x10; - break; - case MdlUtils.TOKEN_FULL_RESOLUTION: - this.flags |= 0x20; - break; - case MdlUtils.TOKEN_PRIORITY_PLANE: - this.priorityPlane = stream.readInt(); - break; - case "Shader": - this.shader = stream.read(); - break; - case MdlUtils.TOKEN_LAYER: { - final MdlxLayer layer = new MdlxLayer(); - layer.readMdl(stream, version); - this.layers.add(layer); - } - break; - default: - throw new RuntimeException("Unknown token in Material: " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startBlock(MdlUtils.TOKEN_MATERIAL); - - if ((this.flags & 0x1) != 0) { - stream.writeFlag(MdlUtils.TOKEN_CONSTANT_COLOR); - } - - if ((this.flags & 0x8) != 0) { - stream.writeFlag(MdlUtils.TOKEN_SORT_PRIMS_NEAR_Z); - } - - if ((this.flags & 0x10) != 0) { - stream.writeFlag(MdlUtils.TOKEN_SORT_PRIMS_FAR_Z); - } - - if ((this.flags & 0x20) != 0) { - stream.writeFlag(MdlUtils.TOKEN_FULL_RESOLUTION); - } - - if (this.priorityPlane != 0) { - stream.writeAttrib(MdlUtils.TOKEN_PRIORITY_PLANE, this.priorityPlane); - } - - if (version > 800) { - stream.writeStringAttrib("Shader", this.shader); - } - - for (final MdlxLayer layer : this.layers) { - layer.writeMdl(stream, version); - } - - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - long size = 20; - - if (version > 800) { - size += 80; - } - - for (final MdlxLayer layer : this.layers) { - size += layer.getByteLength(version); - } - - return size; - } - - public int getPriorityPlane() { - return this.priorityPlane; - } - - public int getFlags() { - return this.flags; - } - - public String getShader() { - return this.shader; - } - - public List getLayers() { - return this.layers; - } - - public void setPriorityPlane(final int priorityPlane) { - this.priorityPlane = priorityPlane; - } - - public void setFlags(final int flags) { - this.flags = flags; - } - - public void setShader(final String shader) { - this.shader = shader; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxModel.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxModel.java deleted file mode 100644 index 01511eb4..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxModel.java +++ /dev/null @@ -1,967 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; - -import com.etheller.warsmash.util.War3ID; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -/** - * A Warcraft 3 model. Supports loading from and saving to both the binary MDX - * and text MDL file formats. - */ -public class MdlxModel { - // Below, these can't call a function on a string to make their value - // because - // switch/case statements require the value to be compile-time defined in - // order - // to be legal, and it appears to only allow basic binary operators for - // that. - // I would love a clearer way to just type 'MDLX' in a character constant in - // Java for this - private static final int MDLX = ('M' << 24) | ('D' << 16) | ('L' << 8) | ('X');// War3ID.fromString("MDLX").getValue(); - private static final int VERS = ('V' << 24) | ('E' << 16) | ('R' << 8) | ('S');// War3ID.fromString("VERS").getValue(); - private static final int MODL = ('M' << 24) | ('O' << 16) | ('D' << 8) | ('L');// War3ID.fromString("MODL").getValue(); - private static final int SEQS = ('S' << 24) | ('E' << 16) | ('Q' << 8) | ('S');// War3ID.fromString("SEQS").getValue(); - private static final int GLBS = ('G' << 24) | ('L' << 16) | ('B' << 8) | ('S');// War3ID.fromString("GLBS").getValue(); - private static final int MTLS = ('M' << 24) | ('T' << 16) | ('L' << 8) | ('S');// War3ID.fromString("MTLS").getValue(); - private static final int TEXS = ('T' << 24) | ('E' << 16) | ('X' << 8) | ('S');// War3ID.fromString("TEXS").getValue(); - private static final int TXAN = ('T' << 24) | ('X' << 16) | ('A' << 8) | ('N');// War3ID.fromString("TXAN").getValue(); - private static final int GEOS = ('G' << 24) | ('E' << 16) | ('O' << 8) | ('S');// War3ID.fromString("GEOS").getValue(); - private static final int GEOA = ('G' << 24) | ('E' << 16) | ('O' << 8) | ('A');// War3ID.fromString("GEOA").getValue(); - private static final int BONE = ('B' << 24) | ('O' << 16) | ('N' << 8) | ('E');// War3ID.fromString("BONE").getValue(); - private static final int LITE = ('L' << 24) | ('I' << 16) | ('T' << 8) | ('E');// War3ID.fromString("LITE").getValue(); - private static final int HELP = ('H' << 24) | ('E' << 16) | ('L' << 8) | ('P');// War3ID.fromString("HELP").getValue(); - private static final int ATCH = ('A' << 24) | ('T' << 16) | ('C' << 8) | ('H');// War3ID.fromString("ATCH").getValue(); - private static final int PIVT = ('P' << 24) | ('I' << 16) | ('V' << 8) | ('T');// War3ID.fromString("PIVT").getValue(); - private static final int PREM = ('P' << 24) | ('R' << 16) | ('E' << 8) | ('M');// War3ID.fromString("PREM").getValue(); - private static final int PRE2 = ('P' << 24) | ('R' << 16) | ('E' << 8) | ('2');// War3ID.fromString("PRE2").getValue(); - private static final int CORN = ('C' << 24) | ('O' << 16) | ('R' << 8) | ('N');// War3ID.fromString("CORN").getValue(); - private static final int RIBB = ('R' << 24) | ('I' << 16) | ('B' << 8) | ('B');// War3ID.fromString("RIBB").getValue(); - private static final int CAMS = ('C' << 24) | ('A' << 16) | ('M' << 8) | ('S');// War3ID.fromString("CAMS").getValue(); - private static final int EVTS = ('E' << 24) | ('V' << 16) | ('T' << 8) | ('S');// War3ID.fromString("EVTS").getValue(); - private static final int CLID = ('C' << 24) | ('L' << 16) | ('I' << 8) | ('D');// War3ID.fromString("CLID").getValue(); - private static final int FAFX = ('F' << 24) | ('A' << 16) | ('F' << 8) | ('X');// War3ID.fromString("FAFX").getValue(); - private static final int BPOS = ('B' << 24) | ('P' << 16) | ('O' << 8) | ('S');// War3ID.fromString("BPOS").getValue(); - - public int version = 800; - public String name = ""; - /** - * (Comment copied from Ghostwolf JS) To the best of my knowledge, this should - * always be left empty. This is probably a leftover from the Warcraft 3 beta. - * (WS game note: No, I never saw any animation files in the RoC 2001-2002 Beta. - * So it must be from the Alpha) - * - * @member {string} - */ - public String animationFile = ""; - public MdlxExtent extent = new MdlxExtent(); - public long blendTime = 0; - public List sequences = new ArrayList<>(); - public List globalSequences = new ArrayList<>(); - public List materials = new ArrayList<>(); - public List textures = new ArrayList<>(); - public List textureAnimations = new ArrayList<>(); - public List geosets = new ArrayList<>(); - public List geosetAnimations = new ArrayList<>(); - public List bones = new ArrayList<>(); - public List lights = new ArrayList<>(); - public List helpers = new ArrayList<>(); - public List attachments = new ArrayList<>(); - public List pivotPoints = new ArrayList<>(); - public List particleEmitters = new ArrayList<>(); - public List particleEmitters2 = new ArrayList<>(); - public List particleEmittersPopcorn = new ArrayList<>(); - public List ribbonEmitters = new ArrayList<>(); - public List cameras = new ArrayList<>(); - public List eventObjects = new ArrayList<>(); - public List collisionShapes = new ArrayList<>(); - /** - * @since 900 - */ - public List faceEffects = new ArrayList<>(); - /** - * @since 900 - */ - public List bindPose = new ArrayList<>(); - public List unknownChunks = new ArrayList<>(); - - public MdlxModel() { - - } - - public MdlxModel(final ByteBuffer buffer) { - load(buffer); - } - - public void load(final ByteBuffer buffer) { - // MDX files start with "MDLX". - if ((buffer.get(0) == 77) && (buffer.get(1) == 68) && (buffer.get(2) == 76) && (buffer.get(3) == 88)) { - loadMdx(buffer); - } - else { - loadMdl(buffer); - } - } - - public void loadMdx(final ByteBuffer buffer) { - final BinaryReader reader = new BinaryReader(buffer); - - if (reader.readTag() != MDLX) { - throw new IllegalStateException("WrongMagicNumber"); - } - - while (reader.remaining() > 0) { - final int tag = reader.readTag(); - final int size = reader.readInt32(); - - switch (tag) { - case VERS: - loadVersionChunk(reader); - break; - case MODL: - loadModelChunk(reader); - break; - case SEQS: - loadStaticObjects(this.sequences, MdlxBlockDescriptor.SEQUENCE, reader, size / 132); - break; - case GLBS: - loadGlobalSequenceChunk(reader, size); - break; - case MTLS: - loadDynamicObjects(this.materials, MdlxBlockDescriptor.MATERIAL, reader, size); - break; - case TEXS: - loadStaticObjects(this.textures, MdlxBlockDescriptor.TEXTURE, reader, size / 268); - break; - case TXAN: - loadDynamicObjects(this.textureAnimations, MdlxBlockDescriptor.TEXTURE_ANIMATION, reader, size); - break; - case GEOS: - loadDynamicObjects(this.geosets, MdlxBlockDescriptor.GEOSET, reader, size); - break; - case GEOA: - loadDynamicObjects(this.geosetAnimations, MdlxBlockDescriptor.GEOSET_ANIMATION, reader, size); - break; - case BONE: - loadDynamicObjects(this.bones, MdlxBlockDescriptor.BONE, reader, size); - break; - case LITE: - loadDynamicObjects(this.lights, MdlxBlockDescriptor.LIGHT, reader, size); - break; - case HELP: - loadDynamicObjects(this.helpers, MdlxBlockDescriptor.HELPER, reader, size); - break; - case ATCH: - loadDynamicObjects(this.attachments, MdlxBlockDescriptor.ATTACHMENT, reader, size); - break; - case PIVT: - loadPivotPointChunk(reader, size); - break; - case PREM: - loadDynamicObjects(this.particleEmitters, MdlxBlockDescriptor.PARTICLE_EMITTER, reader, size); - break; - case PRE2: - loadDynamicObjects(this.particleEmitters2, MdlxBlockDescriptor.PARTICLE_EMITTER2, reader, size); - break; - case CORN: - loadDynamicObjects(this.particleEmittersPopcorn, MdlxBlockDescriptor.PARTICLE_EMITTER_POPCORN, reader, - size); - break; - case RIBB: - loadDynamicObjects(this.ribbonEmitters, MdlxBlockDescriptor.RIBBON_EMITTER, reader, size); - break; - case CAMS: - loadDynamicObjects(this.cameras, MdlxBlockDescriptor.CAMERA, reader, size); - break; - case EVTS: - loadDynamicObjects(this.eventObjects, MdlxBlockDescriptor.EVENT_OBJECT, reader, size); - break; - case CLID: - loadDynamicObjects(this.collisionShapes, MdlxBlockDescriptor.COLLISION_SHAPE, reader, size); - break; - case FAFX: - loadStaticObjects(this.faceEffects, MdlxBlockDescriptor.FACE_EFFECT, reader, size / 340); - break; - case BPOS: - loadBindPoseChunk(reader, size); - break; - default: - this.unknownChunks.add(new MdlxUnknownChunk(reader, size, new War3ID(tag))); - break; - } - } - } - - private void loadVersionChunk(final BinaryReader reader) { - this.version = reader.readInt32(); - } - - private void loadModelChunk(final BinaryReader reader) { - this.name = reader.read(80); - this.animationFile = reader.read(260); - this.extent.readMdx(reader); - this.blendTime = reader.readInt32(); - } - - private void loadStaticObjects(final List out, final MdlxBlockDescriptor constructor, - final BinaryReader reader, final long count) { - for (int i = 0; i < count; i++) { - final E object = constructor.create(); - - object.readMdx(reader, this.version); - - out.add(object); - } - } - - private void loadGlobalSequenceChunk(final BinaryReader reader, final long size) { - for (long i = 0, l = size / 4; i < l; i++) { - this.globalSequences.add(reader.readUInt32()); - } - } - - private void loadDynamicObjects(final List out, - final MdlxBlockDescriptor constructor, final BinaryReader reader, final long size) { - long totalSize = 0; - while (totalSize < size) { - final E object = constructor.create(); - - object.readMdx(reader, this.version); - - totalSize += object.getByteLength(this.version); - - out.add(object); - } - } - - private void loadPivotPointChunk(final BinaryReader reader, final long size) { - for (long i = 0, l = size / 12; i < l; i++) { - this.pivotPoints.add(reader.readFloat32Array(3)); - } - } - - private void loadBindPoseChunk(final BinaryReader reader, final long size) { - for (int i = 0, l = reader.readInt32(); i < l; i++) { - this.bindPose.add(reader.readFloat32Array(12)); - } - } - - public ByteBuffer saveMdx() { - final BinaryWriter writer = new BinaryWriter(getByteLength()); - - writer.writeTag(MDLX); - saveVersionChunk(writer); - saveModelChunk(writer); - saveStaticObjectChunk(writer, SEQS, this.sequences, 132); - saveGlobalSequenceChunk(writer); - saveDynamicObjectChunk(writer, MTLS, this.materials); - saveStaticObjectChunk(writer, TEXS, this.textures, 268); - saveDynamicObjectChunk(writer, TXAN, this.textureAnimations); - saveDynamicObjectChunk(writer, GEOS, this.geosets); - saveDynamicObjectChunk(writer, GEOA, this.geosetAnimations); - saveDynamicObjectChunk(writer, BONE, this.bones); - saveDynamicObjectChunk(writer, LITE, this.lights); - saveDynamicObjectChunk(writer, HELP, this.helpers); - saveDynamicObjectChunk(writer, ATCH, this.attachments); - savePivotPointChunk(writer); - saveDynamicObjectChunk(writer, PREM, this.particleEmitters); - saveDynamicObjectChunk(writer, PRE2, this.particleEmitters2); - - if (this.version > 800) { - saveDynamicObjectChunk(writer, CORN, this.particleEmittersPopcorn); - } - - saveDynamicObjectChunk(writer, RIBB, this.ribbonEmitters); - saveDynamicObjectChunk(writer, CAMS, this.cameras); - saveDynamicObjectChunk(writer, EVTS, this.eventObjects); - saveDynamicObjectChunk(writer, CLID, this.collisionShapes); - - if (this.version > 800) { - saveStaticObjectChunk(writer, FAFX, this.faceEffects, 340); - saveBindPoseChunk(writer); - } - - for (final MdlxUnknownChunk chunk : this.unknownChunks) { - chunk.writeMdx(writer, this.version); - } - - return writer.buffer; - } - - private void saveVersionChunk(final BinaryWriter writer) { - writer.writeTag(VERS); - writer.writeUInt32(4); - writer.writeUInt32(this.version); - } - - private void saveModelChunk(final BinaryWriter writer) { - writer.writeTag(MODL); - writer.writeUInt32(372); - writer.writeWithNulls(this.name, 80); - writer.writeWithNulls(this.animationFile, 260); - this.extent.writeMdx(writer); - writer.writeUInt32(this.blendTime); - } - - private void saveStaticObjectChunk(final BinaryWriter writer, final int name, - final List objects, final long size) { - if (!objects.isEmpty()) { - writer.writeTag(name); - writer.writeUInt32(objects.size() * size); - - for (final E object : objects) { - object.writeMdx(writer, this.version); - } - } - } - - private void saveGlobalSequenceChunk(final BinaryWriter writer) { - if (!this.globalSequences.isEmpty()) { - writer.writeTag(GLBS); - writer.writeUInt32(this.globalSequences.size() * 4); - - for (final Long globalSequence : this.globalSequences) { - writer.writeUInt32(globalSequence); - } - } - } - - private void saveDynamicObjectChunk(final BinaryWriter writer, final int name, - final List objects) { - if (!objects.isEmpty()) { - writer.writeTag(name); - writer.writeUInt32(getObjectsByteLength(objects)); - - for (final E object : objects) { - object.writeMdx(writer, this.version); - } - } - } - - private void savePivotPointChunk(final BinaryWriter writer) { - if (this.pivotPoints.size() > 0) { - writer.writeTag(PIVT); - writer.writeUInt32(this.pivotPoints.size() * 12); - - for (final float[] pivotPoint : this.pivotPoints) { - writer.writeFloat32Array(pivotPoint); - } - } - } - - private void saveBindPoseChunk(final BinaryWriter writer) { - if (this.bindPose.size() > 0) { - writer.writeTag(BPOS); - writer.writeUInt32(4 + (this.bindPose.size() * 48)); - writer.writeUInt32(this.bindPose.size()); - - for (final float[] matrix : this.bindPose) { - writer.writeFloat32Array(matrix); - } - } - } - - public void loadMdl(final ByteBuffer buffer) { - String token; - final MdlTokenInputStream stream = new MdlTokenInputStream(buffer); - - while ((token = stream.read()) != null) { - switch (token) { - case MdlUtils.TOKEN_VERSION: - loadVersionBlock(stream); - break; - case MdlUtils.TOKEN_MODEL: - loadModelBlock(stream); - break; - case MdlUtils.TOKEN_SEQUENCES: - loadNumberedObjectBlock(this.sequences, MdlxBlockDescriptor.SEQUENCE, MdlUtils.TOKEN_ANIM, stream); - break; - case MdlUtils.TOKEN_GLOBAL_SEQUENCES: - loadGlobalSequenceBlock(stream); - break; - case MdlUtils.TOKEN_TEXTURES: - loadNumberedObjectBlock(this.textures, MdlxBlockDescriptor.TEXTURE, MdlUtils.TOKEN_BITMAP, stream); - break; - case MdlUtils.TOKEN_MATERIALS: - loadNumberedObjectBlock(this.materials, MdlxBlockDescriptor.MATERIAL, MdlUtils.TOKEN_MATERIAL, stream); - break; - case MdlUtils.TOKEN_TEXTURE_ANIMS: - loadNumberedObjectBlock(this.textureAnimations, MdlxBlockDescriptor.TEXTURE_ANIMATION, - MdlUtils.TOKEN_TVERTEX_ANIM, stream); - break; - case MdlUtils.TOKEN_GEOSET: - loadObject(this.geosets, MdlxBlockDescriptor.GEOSET, stream); - break; - case MdlUtils.TOKEN_GEOSETANIM: - loadObject(this.geosetAnimations, MdlxBlockDescriptor.GEOSET_ANIMATION, stream); - break; - case MdlUtils.TOKEN_BONE: - loadObject(this.bones, MdlxBlockDescriptor.BONE, stream); - break; - case MdlUtils.TOKEN_LIGHT: - loadObject(this.lights, MdlxBlockDescriptor.LIGHT, stream); - break; - case MdlUtils.TOKEN_HELPER: - loadObject(this.helpers, MdlxBlockDescriptor.HELPER, stream); - break; - case MdlUtils.TOKEN_ATTACHMENT: - loadObject(this.attachments, MdlxBlockDescriptor.ATTACHMENT, stream); - break; - case MdlUtils.TOKEN_PIVOT_POINTS: - loadPivotPointBlock(stream); - break; - case MdlUtils.TOKEN_PARTICLE_EMITTER: - loadObject(this.particleEmitters, MdlxBlockDescriptor.PARTICLE_EMITTER, stream); - break; - case MdlUtils.TOKEN_PARTICLE_EMITTER2: - loadObject(this.particleEmitters2, MdlxBlockDescriptor.PARTICLE_EMITTER2, stream); - break; - case "ParticleEmitterPopcorn": - loadObject(this.particleEmittersPopcorn, MdlxBlockDescriptor.PARTICLE_EMITTER_POPCORN, stream); - break; - case MdlUtils.TOKEN_RIBBON_EMITTER: - loadObject(this.ribbonEmitters, MdlxBlockDescriptor.RIBBON_EMITTER, stream); - break; - case MdlUtils.TOKEN_CAMERA: - loadObject(this.cameras, MdlxBlockDescriptor.CAMERA, stream); - break; - case MdlUtils.TOKEN_EVENT_OBJECT: - loadObject(this.eventObjects, MdlxBlockDescriptor.EVENT_OBJECT, stream); - break; - case MdlUtils.TOKEN_COLLISION_SHAPE: - loadObject(this.collisionShapes, MdlxBlockDescriptor.COLLISION_SHAPE, stream); - break; - case "FaceFX": - loadObject(this.faceEffects, MdlxBlockDescriptor.FACE_EFFECT, stream); - break; - case "BindPose": - loadBindPoseBlock(stream); - break; - default: - throw new IllegalStateException("Unsupported block: " + token); - } - } - } - - private void loadVersionBlock(final MdlTokenInputStream stream) { - for (final String token : stream.readBlock()) { - if (MdlUtils.TOKEN_FORMAT_VERSION.equals(token)) { - this.version = stream.readInt(); - } - else { - throw new IllegalStateException("Unknown token in Version: " + token); - } - } - } - - private void loadModelBlock(final MdlTokenInputStream stream) { - this.name = stream.read(); - for (final String token : stream.readBlock()) { - if (token.startsWith("Num")) { - /*- - * Don't care about the number of things, the arrays will grow as they wish. - * This includes: - * NumGeosets - * NumGeosetAnims - * NumHelpers - * NumLights - * NumBones - * NumAttachments - * NumParticleEmitters - * NumParticleEmitters2 - * NumRibbonEmitters - * NumEvents - */ - stream.read(); - } - else { - switch (token) { - case MdlUtils.TOKEN_BLEND_TIME: - this.blendTime = stream.readUInt32(); - break; - case MdlUtils.TOKEN_MINIMUM_EXTENT: - stream.readFloatArray(this.extent.min); - break; - case MdlUtils.TOKEN_MAXIMUM_EXTENT: - stream.readFloatArray(this.extent.max); - break; - case MdlUtils.TOKEN_BOUNDSRADIUS: - this.extent.boundsRadius = stream.readFloat(); - break; - default: - throw new IllegalStateException("Unknown token in Model: " + token); - } - } - } - } - - private void loadNumberedObjectBlock(final List out, - final MdlxBlockDescriptor constructor, final String name, final MdlTokenInputStream stream) { - stream.read(); // Don't care about the number, the array will grow - - for (final String token : stream.readBlock()) { - if (token.equals(name)) { - final E object = constructor.create(); - - object.readMdl(stream, this.version); - - out.add(object); - } - else { - throw new IllegalStateException("Unknown token in " + name + ": " + token); - } - } - } - - private void loadGlobalSequenceBlock(final MdlTokenInputStream stream) { - stream.read(); // Don't care about the number, the array will grow - - for (final String token : stream.readBlock()) { - if (token.equals(MdlUtils.TOKEN_DURATION)) { - this.globalSequences.add(stream.readUInt32()); - } - else { - throw new IllegalStateException("Unknown token in GlobalSequences: " + token); - } - } - } - - private void loadObject(final List out, final MdlxBlockDescriptor descriptor, - final MdlTokenInputStream stream) { - final E object = descriptor.create(); - - object.readMdl(stream, this.version); - - out.add(object); - } - - private void loadPivotPointBlock(final MdlTokenInputStream stream) { - final int count = stream.readInt(); - - stream.read(); // { - - for (int i = 0; i < count; i++) { - this.pivotPoints.add(stream.readFloatArray(new float[3])); - } - - stream.read(); // } - } - - private void loadBindPoseBlock(final MdlTokenInputStream stream) { - for (final String token : stream.readBlock()) { - if (token.equals("Matrices")) { - final int matrices = stream.readInt(); - - stream.read(); // { - - for (int i = 0; i < matrices; i++) { - this.bindPose.add(stream.readFloatArray(new float[12])); - } - - stream.read(); // } - } - else { - throw new IllegalStateException("Unknown token in BindPose: " + token); - } - } - } - - public ByteBuffer saveMdl() { - final MdlTokenOutputStream stream = new MdlTokenOutputStream(); - - saveVersionBlock(stream); - saveModelBlock(stream); - saveStaticObjectsBlock(stream, MdlUtils.TOKEN_SEQUENCES, this.sequences); - saveGlobalSequenceBlock(stream); - saveStaticObjectsBlock(stream, MdlUtils.TOKEN_TEXTURES, this.textures); - saveStaticObjectsBlock(stream, MdlUtils.TOKEN_MATERIALS, this.materials); - saveStaticObjectsBlock(stream, MdlUtils.TOKEN_TEXTURE_ANIMS, this.textureAnimations); - saveObjects(stream, this.geosets); - saveObjects(stream, this.geosetAnimations); - saveObjects(stream, this.bones); - saveObjects(stream, this.lights); - saveObjects(stream, this.helpers); - saveObjects(stream, this.attachments); - savePivotPointBlock(stream); - saveObjects(stream, this.particleEmitters); - saveObjects(stream, this.particleEmitters2); - - if (this.version > 800) { - saveObjects(stream, this.particleEmittersPopcorn); - } - - saveObjects(stream, this.ribbonEmitters); - saveObjects(stream, this.cameras); - saveObjects(stream, this.eventObjects); - saveObjects(stream, this.collisionShapes); - - if (this.version > 800) { - saveObjects(stream, this.faceEffects); - saveBindPoseBlock(stream); - } - - return ByteBuffer.wrap(stream.buffer.toString().getBytes()); - } - - private void saveVersionBlock(final MdlTokenOutputStream stream) { - stream.startBlock(MdlUtils.TOKEN_VERSION); - stream.writeAttrib(MdlUtils.TOKEN_FORMAT_VERSION, this.version); - stream.endBlock(); - } - - private void saveModelBlock(final MdlTokenOutputStream stream) { - stream.startObjectBlock(MdlUtils.TOKEN_MODEL, this.name); - stream.writeAttribUInt32(MdlUtils.TOKEN_BLEND_TIME, this.blendTime); - this.extent.writeMdl(stream); - stream.endBlock(); - } - - private void saveStaticObjectsBlock(final MdlTokenOutputStream stream, final String name, - final List objects) { - if (!objects.isEmpty()) { - stream.startBlock(name, objects.size()); - - for (final MdlxBlock object : objects) { - object.writeMdl(stream, this.version); - } - - stream.endBlock(); - } - } - - private void saveGlobalSequenceBlock(final MdlTokenOutputStream stream) { - if (!this.globalSequences.isEmpty()) { - stream.startBlock(MdlUtils.TOKEN_GLOBAL_SEQUENCES, this.globalSequences.size()); - - for (final Long globalSequence : this.globalSequences) { - stream.writeAttribUInt32(MdlUtils.TOKEN_DURATION, globalSequence); - } - - stream.endBlock(); - } - } - - private void saveObjects(final MdlTokenOutputStream stream, final List objects) { - for (final MdlxBlock object : objects) { - object.writeMdl(stream, this.version); - } - } - - private void savePivotPointBlock(final MdlTokenOutputStream stream) { - if (!this.pivotPoints.isEmpty()) { - stream.startBlock(MdlUtils.TOKEN_PIVOT_POINTS, this.pivotPoints.size()); - - for (final float[] pivotPoint : this.pivotPoints) { - stream.writeFloatArray(pivotPoint); - } - - stream.endBlock(); - } - } - - private void saveBindPoseBlock(final MdlTokenOutputStream stream) { - if (!this.bindPose.isEmpty()) { - stream.startBlock("BindPose"); - - stream.startBlock("Matrices", this.bindPose.size()); - - for (final float[] matrix : this.bindPose) { - stream.writeFloatArray(matrix); - } - - stream.endBlock(); - - stream.endBlock(); - } - } - - public int getByteLength() { - int size = 396; - - size += getStaticObjectsChunkByteLength(this.sequences, 132); - size += getStaticObjectsChunkByteLength(this.globalSequences, 4); - size += getDynamicObjectsChunkByteLength(this.materials); - size += getStaticObjectsChunkByteLength(this.textures, 268); - size += getDynamicObjectsChunkByteLength(this.textureAnimations); - size += getDynamicObjectsChunkByteLength(this.geosets); - size += getDynamicObjectsChunkByteLength(this.geosetAnimations); - size += getDynamicObjectsChunkByteLength(this.bones); - size += getDynamicObjectsChunkByteLength(this.lights); - size += getDynamicObjectsChunkByteLength(this.helpers); - size += getDynamicObjectsChunkByteLength(this.attachments); - size += getStaticObjectsChunkByteLength(this.pivotPoints, 12); - size += getDynamicObjectsChunkByteLength(this.particleEmitters); - size += getDynamicObjectsChunkByteLength(this.particleEmitters2); - - if (this.version > 800) { - size += getDynamicObjectsChunkByteLength(this.particleEmittersPopcorn); - } - - size += getDynamicObjectsChunkByteLength(this.ribbonEmitters); - size += getDynamicObjectsChunkByteLength(this.cameras); - size += getDynamicObjectsChunkByteLength(this.eventObjects); - size += getDynamicObjectsChunkByteLength(this.collisionShapes); - size += getObjectsByteLength(this.unknownChunks); - - if (this.version > 800) { - size += getStaticObjectsChunkByteLength(this.faceEffects, 340); - size += getBindPoseChunkByteLength(); - } - - return size; - } - - private long getObjectsByteLength(final List objects) { - long size = 0; - for (final E object : objects) { - size += object.getByteLength(this.version); - } - return size; - } - - private long getDynamicObjectsChunkByteLength(final List objects) { - if (!objects.isEmpty()) { - return 8 + getObjectsByteLength(objects); - } - - return 0; - } - - private long getStaticObjectsChunkByteLength(final List objects, final long size) { - if (!objects.isEmpty()) { - return 8 + (objects.size() * size); - } - - return 0; - } - - private long getBindPoseChunkByteLength() { - if (this.bindPose.size() > 0) { - return 12 + (this.bindPose.size() * 48); - } - - return 0; - } - - public List getGeosets() { - return this.geosets; - } - - public int getVersion() { - return this.version; - } - - public String getName() { - return this.name; - } - - public String getAnimationFile() { - return this.animationFile; - } - - public MdlxExtent getExtent() { - return this.extent; - } - - public long getBlendTime() { - return this.blendTime; - } - - public List getSequences() { - return this.sequences; - } - - public List getGlobalSequences() { - return this.globalSequences; - } - - public List getMaterials() { - return this.materials; - } - - public List getTextures() { - return this.textures; - } - - public List getTextureAnimations() { - return this.textureAnimations; - } - - public List getGeosetAnimations() { - return this.geosetAnimations; - } - - public List getBones() { - return this.bones; - } - - public List getLights() { - return this.lights; - } - - public List getHelpers() { - return this.helpers; - } - - public List getAttachments() { - return this.attachments; - } - - public List getPivotPoints() { - return this.pivotPoints; - } - - public List getParticleEmitters() { - return this.particleEmitters; - } - - public List getParticleEmitters2() { - return this.particleEmitters2; - } - - public List getParticleEmittersPopcorn() { - return this.particleEmittersPopcorn; - } - - public List getRibbonEmitters() { - return this.ribbonEmitters; - } - - public List getCameras() { - return this.cameras; - } - - public List getEventObjects() { - return this.eventObjects; - } - - public List getCollisionShapes() { - return this.collisionShapes; - } - - public List getFaceEffects() { - return this.faceEffects; - } - - public List getBindPose() { - return this.bindPose; - } - - public List getUnknownChunks() { - return this.unknownChunks; - } - - public void setVersion(final int version) { - this.version = version; - } - - public void setName(final String name) { - this.name = name; - } - - public void setAnimationFile(final String animationFile) { - this.animationFile = animationFile; - } - - public void setExtent(final MdlxExtent extent) { - this.extent = extent; - } - - public void setBlendTime(final long blendTime) { - this.blendTime = blendTime; - } - - public void setSequences(final List sequences) { - this.sequences = sequences; - } - - public void setGlobalSequences(final List globalSequences) { - this.globalSequences = globalSequences; - } - - public void setMaterials(final List materials) { - this.materials = materials; - } - - public void setTextures(final List textures) { - this.textures = textures; - } - - public void setTextureAnimations(final List textureAnimations) { - this.textureAnimations = textureAnimations; - } - - public void setGeosets(final List geosets) { - this.geosets = geosets; - } - - public void setGeosetAnimations(final List geosetAnimations) { - this.geosetAnimations = geosetAnimations; - } - - public void setBones(final List bones) { - this.bones = bones; - } - - public void setLights(final List lights) { - this.lights = lights; - } - - public void setHelpers(final List helpers) { - this.helpers = helpers; - } - - public void setAttachments(final List attachments) { - this.attachments = attachments; - } - - public void setPivotPoints(final List pivotPoints) { - this.pivotPoints = pivotPoints; - } - - public void setParticleEmitters(final List particleEmitters) { - this.particleEmitters = particleEmitters; - } - - public void setParticleEmitters2(final List particleEmitters2) { - this.particleEmitters2 = particleEmitters2; - } - - public void setParticleEmittersPopcorn(final List particleEmittersPopcorn) { - this.particleEmittersPopcorn = particleEmittersPopcorn; - } - - public void setRibbonEmitters(final List ribbonEmitters) { - this.ribbonEmitters = ribbonEmitters; - } - - public void setCameras(final List cameras) { - this.cameras = cameras; - } - - public void setEventObjects(final List eventObjects) { - this.eventObjects = eventObjects; - } - - public void setCollisionShapes(final List collisionShapes) { - this.collisionShapes = collisionShapes; - } - - public void setFaceEffects(final List faceEffects) { - this.faceEffects = faceEffects; - } - - public void setBindPose(final List bindPose) { - this.bindPose = bindPose; - } - - public void setUnknownChunks(final List unknownChunks) { - this.unknownChunks = unknownChunks; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxParticleEmitter.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxParticleEmitter.java deleted file mode 100644 index d4d4ca59..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxParticleEmitter.java +++ /dev/null @@ -1,241 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import java.util.Iterator; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxParticleEmitter extends MdlxGenericObject { - public float emissionRate = 0; - public float gravity = 0; - public float longitude = 0; - public float latitude = 0; - public String path = ""; - public float lifeSpan = 0; - public float speed = 0; - - public MdlxParticleEmitter() { - super(0x1000); - } - - @Override - public void readMdx(final BinaryReader reader, final int version) { - final int position = reader.position(); - final long size = reader.readUInt32(); - - super.readMdx(reader, version); - - this.emissionRate = reader.readFloat32(); - this.gravity = reader.readFloat32(); - this.longitude = reader.readFloat32(); - this.latitude = reader.readFloat32(); - this.path = reader.read(260); - this.lifeSpan = reader.readFloat32(); - this.speed = reader.readFloat32(); - - readTimelines(reader, size - (reader.position() - position)); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeUInt32(getByteLength(version)); - - super.writeMdx(writer, version); - - writer.writeFloat32(this.emissionRate); - writer.writeFloat32(this.gravity); - writer.writeFloat32(this.longitude); - writer.writeFloat32(this.latitude); - writer.writeWithNulls(this.path, 260); - writer.writeFloat32(this.lifeSpan); - writer.writeFloat32(this.speed); - - writeNonGenericAnimationChunks(writer); - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - for (final String token : super.readMdlGeneric(stream)) { - switch (token) { - case MdlUtils.TOKEN_EMITTER_USES_MDL: - this.flags |= 0x8000; - break; - case MdlUtils.TOKEN_EMITTER_USES_TGA: - this.flags |= 0x10000; - break; - case MdlUtils.TOKEN_STATIC_EMISSION_RATE: - this.emissionRate = stream.readFloat(); - break; - case MdlUtils.TOKEN_EMISSION_RATE: - readTimeline(stream, AnimationMap.KPEE); - break; - case MdlUtils.TOKEN_STATIC_GRAVITY: - this.gravity = stream.readFloat(); - break; - case MdlUtils.TOKEN_GRAVITY: - readTimeline(stream, AnimationMap.KPEG); - break; - case MdlUtils.TOKEN_STATIC_LONGITUDE: - this.longitude = stream.readFloat(); - break; - case MdlUtils.TOKEN_LONGITUDE: - readTimeline(stream, AnimationMap.KPLN); - break; - case MdlUtils.TOKEN_STATIC_LATITUDE: - this.latitude = stream.readFloat(); - break; - case MdlUtils.TOKEN_LATITUDE: - readTimeline(stream, AnimationMap.KPLT); - break; - case MdlUtils.TOKEN_VISIBILITY: - readTimeline(stream, AnimationMap.KPEV); - break; - case MdlUtils.TOKEN_PARTICLE: { - final Iterator iterator = readAnimatedBlock(stream); - while (iterator.hasNext()) { - final String subToken = iterator.next(); - switch (subToken) { - case MdlUtils.TOKEN_STATIC_LIFE_SPAN: - this.lifeSpan = stream.readFloat(); - break; - case MdlUtils.TOKEN_LIFE_SPAN: - readTimeline(stream, AnimationMap.KPEL); - break; - case MdlUtils.TOKEN_STATIC_INIT_VELOCITY: - this.speed = stream.readFloat(); - break; - case MdlUtils.TOKEN_INIT_VELOCITY: - readTimeline(stream, AnimationMap.KPES); - break; - case MdlUtils.TOKEN_PATH: - this.path = stream.read(); - break; - default: - throw new RuntimeException( - "Unknown token in ParticleEmitter " + this.name + "'s Particle: " + subToken); - } - } - } - break; - default: - throw new RuntimeException("Unknown token in ParticleEmitter " + this.name + ": " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startObjectBlock(MdlUtils.TOKEN_PARTICLE_EMITTER, this.name); - writeGenericHeader(stream); - - if ((this.flags & 0x8000) != 0) { - stream.writeFlag(MdlUtils.TOKEN_EMITTER_USES_MDL); - } - - if ((this.flags & 0x10000) != 0) { - stream.writeFlag(MdlUtils.TOKEN_EMITTER_USES_TGA); - } - - if (!writeTimeline(stream, AnimationMap.KPEE)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_EMISSION_RATE, this.emissionRate); - } - - if (!writeTimeline(stream, AnimationMap.KPEG)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_GRAVITY, this.gravity); - } - - if (!writeTimeline(stream, AnimationMap.KPLN)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_LONGITUDE, this.longitude); - } - - if (!writeTimeline(stream, AnimationMap.KPLT)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_LATITUDE, this.latitude); - } - - writeTimeline(stream, AnimationMap.KPEV); - - stream.startBlock(MdlUtils.TOKEN_PARTICLE); - - if (!writeTimeline(stream, AnimationMap.KPEL)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_LIFE_SPAN, this.lifeSpan); - } - - if (!writeTimeline(stream, AnimationMap.KPES)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_INIT_VELOCITY, this.speed); - } - - if (((this.flags & 0x8000) != 0) || ((this.flags & 0x10000) != 0)) { - stream.writeAttrib(MdlUtils.TOKEN_PATH, this.path); - } - - stream.endBlock(); - - writeGenericTimelines(stream); - - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - return 288 + super.getByteLength(version); - } - - public float getEmissionRate() { - return this.emissionRate; - } - - public float getGravity() { - return this.gravity; - } - - public float getLongitude() { - return this.longitude; - } - - public float getLatitude() { - return this.latitude; - } - - public String getPath() { - return this.path; - } - - public float getLifeSpan() { - return this.lifeSpan; - } - - public float getSpeed() { - return this.speed; - } - - public void setEmissionRate(final float emissionRate) { - this.emissionRate = emissionRate; - } - - public void setGravity(final float gravity) { - this.gravity = gravity; - } - - public void setLongitude(final float longitude) { - this.longitude = longitude; - } - - public void setLatitude(final float latitude) { - this.latitude = latitude; - } - - public void setPath(final String path) { - this.path = path; - } - - public void setLifeSpan(final float lifeSpan) { - this.lifeSpan = lifeSpan; - } - - public void setSpeed(final float speed) { - this.speed = speed; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxParticleEmitter2.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxParticleEmitter2.java deleted file mode 100644 index aceb85e3..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxParticleEmitter2.java +++ /dev/null @@ -1,622 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxParticleEmitter2 extends MdlxGenericObject { - public enum FilterMode { - BLEND("Blend"), - ADDITIVE("Additive"), - MODULATE("Modulate"), - MODULATE2X("Modulate2x"), - ALPHAKEY("AlphaKey"); - - String token; - - FilterMode(final String token) { - this.token = token; - } - - public static FilterMode fromId(final int id) { - return values()[id]; - } - - public static int nameToId(final String name) { - for (final FilterMode mode : values()) { - if (mode.token.equals(name)) { - return mode.ordinal(); - } - } - return -1; - } - - @Override - public String toString() { - return this.token; - } - } - - public enum HeadOrTail { - HEAD("Head", true, false), - TAIL("Tail", false, true), - BOTH("Both", true, true); - - String token; - boolean includesHead; - boolean includesTail; - - private HeadOrTail(final String token, final boolean includesHead, final boolean includesTail) { - this.token = token; - this.includesHead = includesHead; - this.includesTail = includesTail; - } - - public static HeadOrTail fromId(final int id) { - return values()[id]; - } - - public static int nameToId(final String name) { - for (final HeadOrTail mode : values()) { - if (mode.token.equals(name)) { - return mode.ordinal(); - } - } - - return -1; - } - - @Override - public String toString() { - return this.token; - } - - public boolean isIncludesHead() { - return this.includesHead; - } - - public boolean isIncludesTail() { - return this.includesTail; - } - } - - public float speed = 0; - public float variation = 0; - public float latitude = 0; - public float gravity = 0; - public float lifeSpan = 0; - public float emissionRate = 0; - public float length = 0; - public float width = 0; - public FilterMode filterMode = FilterMode.BLEND; - public long rows = 0; - public long columns = 0; - public HeadOrTail headOrTail = HeadOrTail.HEAD; - public float tailLength = 0; - public float timeMiddle = 0; - public final float[][] segmentColors = new float[3][3]; - public short[] segmentAlphas = new short[3]; // unsigned byte[] - public float[] segmentScaling = new float[3]; - public long[][] headIntervals = new long[2][3]; - public long[][] tailIntervals = new long[2][3]; - public int textureId = -1; - public long squirt = 0; - public int priorityPlane = 0; - public long replaceableId = 0; - - public MdlxParticleEmitter2() { - super(0x1000); - } - - @Override - public void readMdx(final BinaryReader reader, final int version) { - final int position = reader.position(); - final long size = reader.readUInt32(); - - super.readMdx(reader, version); - - this.speed = reader.readFloat32(); - this.variation = reader.readFloat32(); - this.latitude = reader.readFloat32(); - this.gravity = reader.readFloat32(); - this.lifeSpan = reader.readFloat32(); - this.emissionRate = reader.readFloat32(); - this.length = reader.readFloat32(); - this.width = reader.readFloat32(); - this.filterMode = FilterMode.fromId(reader.readInt32()); - this.rows = reader.readUInt32(); - this.columns = reader.readUInt32(); - this.headOrTail = HeadOrTail.fromId(reader.readInt32()); - this.tailLength = reader.readFloat32(); - this.timeMiddle = reader.readFloat32(); - reader.readFloat32Array(this.segmentColors[0]); - reader.readFloat32Array(this.segmentColors[1]); - reader.readFloat32Array(this.segmentColors[2]); - reader.readUInt8Array(this.segmentAlphas); - reader.readFloat32Array(this.segmentScaling); - reader.readUInt32Array(this.headIntervals[0]); - reader.readUInt32Array(this.headIntervals[1]); - reader.readUInt32Array(this.tailIntervals[0]); - reader.readUInt32Array(this.tailIntervals[1]); - this.textureId = reader.readInt32(); - this.squirt = reader.readUInt32(); - this.priorityPlane = reader.readInt32(); - this.replaceableId = reader.readUInt32(); - - readTimelines(reader, size - (reader.position() - position)); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeUInt32(getByteLength(version)); - - super.writeMdx(writer, version); - - writer.writeFloat32(this.speed); - writer.writeFloat32(this.variation); - writer.writeFloat32(this.latitude); - writer.writeFloat32(this.gravity); - writer.writeFloat32(this.lifeSpan); - writer.writeFloat32(this.emissionRate); - writer.writeFloat32(this.length); - writer.writeFloat32(this.width); - writer.writeInt32(this.filterMode.ordinal()); - writer.writeUInt32(this.rows); - writer.writeUInt32(this.columns); - writer.writeInt32(this.headOrTail.ordinal()); - writer.writeFloat32(this.tailLength); - writer.writeFloat32(this.timeMiddle); - writer.writeFloat32Array(this.segmentColors[0]); - writer.writeFloat32Array(this.segmentColors[1]); - writer.writeFloat32Array(this.segmentColors[2]); - writer.writeUInt8Array(this.segmentAlphas); - writer.writeFloat32Array(this.segmentScaling); - writer.writeUInt32Array(this.headIntervals[0]); - writer.writeUInt32Array(this.headIntervals[1]); - writer.writeUInt32Array(this.tailIntervals[0]); - writer.writeUInt32Array(this.tailIntervals[1]); - writer.writeInt32(this.textureId); - writer.writeUInt32(this.squirt); - writer.writeInt32(this.priorityPlane); - writer.writeUInt32(this.replaceableId); - - writeNonGenericAnimationChunks(writer); - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - for (final String token : super.readMdlGeneric(stream)) { - switch (token) { - case MdlUtils.TOKEN_SORT_PRIMS_FAR_Z: - this.flags |= 0x10000; - break; - case MdlUtils.TOKEN_UNSHADED: - this.flags |= 0x8000; - break; - case MdlUtils.TOKEN_LINE_EMITTER: - this.flags |= 0x20000; - break; - case MdlUtils.TOKEN_UNFOGGED: - this.flags |= 0x40000; - break; - case MdlUtils.TOKEN_MODEL_SPACE: - this.flags |= 0x80000; - break; - case MdlUtils.TOKEN_XY_QUAD: - this.flags |= 0x100000; - break; - case MdlUtils.TOKEN_STATIC_SPEED: - this.speed = stream.readFloat(); - break; - case MdlUtils.TOKEN_SPEED: - readTimeline(stream, AnimationMap.KP2S); - break; - case MdlUtils.TOKEN_STATIC_VARIATION: - this.variation = stream.readFloat(); - break; - case MdlUtils.TOKEN_VARIATION: - readTimeline(stream, AnimationMap.KP2R); - break; - case MdlUtils.TOKEN_STATIC_LATITUDE: - this.latitude = stream.readFloat(); - break; - case MdlUtils.TOKEN_LATITUDE: - readTimeline(stream, AnimationMap.KP2L); - break; - case MdlUtils.TOKEN_STATIC_GRAVITY: - this.gravity = stream.readFloat(); - break; - case MdlUtils.TOKEN_GRAVITY: - readTimeline(stream, AnimationMap.KP2G); - break; - case MdlUtils.TOKEN_VISIBILITY: - readTimeline(stream, AnimationMap.KP2V); - break; - case MdlUtils.TOKEN_SQUIRT: - this.squirt = 1; - break; - case MdlUtils.TOKEN_LIFE_SPAN: - this.lifeSpan = stream.readFloat(); - break; - case MdlUtils.TOKEN_STATIC_EMISSION_RATE: - this.emissionRate = stream.readFloat(); - break; - case MdlUtils.TOKEN_EMISSION_RATE: - readTimeline(stream, AnimationMap.KP2E); - break; - case MdlUtils.TOKEN_STATIC_WIDTH: - this.width = stream.readFloat(); - break; - case MdlUtils.TOKEN_WIDTH: - readTimeline(stream, AnimationMap.KP2W); - break; - case MdlUtils.TOKEN_STATIC_LENGTH: - this.length = stream.readFloat(); - break; - case MdlUtils.TOKEN_LENGTH: - readTimeline(stream, AnimationMap.KP2N); - break; - case MdlUtils.TOKEN_BLEND: - this.filterMode = FilterMode.BLEND; - break; - case MdlUtils.TOKEN_ADDITIVE: - this.filterMode = FilterMode.ADDITIVE; - break; - case MdlUtils.TOKEN_MODULATE: - this.filterMode = FilterMode.MODULATE; - break; - case MdlUtils.TOKEN_MODULATE2X: - this.filterMode = FilterMode.MODULATE2X; - break; - case MdlUtils.TOKEN_ALPHAKEY: - this.filterMode = FilterMode.ALPHAKEY; - break; - case MdlUtils.TOKEN_ROWS: - this.rows = stream.readUInt32(); - break; - case MdlUtils.TOKEN_COLUMNS: - this.columns = stream.readUInt32(); - break; - case MdlUtils.TOKEN_HEAD: - this.headOrTail = HeadOrTail.HEAD; - break; - case MdlUtils.TOKEN_TAIL: - this.headOrTail = HeadOrTail.TAIL; - break; - case MdlUtils.TOKEN_BOTH: - this.headOrTail = HeadOrTail.BOTH; - break; - case MdlUtils.TOKEN_TAIL_LENGTH: - this.tailLength = stream.readFloat(); - break; - case MdlUtils.TOKEN_TIME: - this.timeMiddle = stream.readFloat(); - break; - case MdlUtils.TOKEN_SEGMENT_COLOR: { - stream.read(); // { - for (int i = 0; i < 3; i++) { - stream.read(); // Color - stream.readColor(this.segmentColors[i]); - } - stream.read(); // } - } - break; - case MdlUtils.TOKEN_ALPHA: - stream.readUInt8Array(this.segmentAlphas); - break; - case MdlUtils.TOKEN_PARTICLE_SCALING: - stream.readFloatArray(this.segmentScaling); - break; - case MdlUtils.TOKEN_LIFE_SPAN_UV_ANIM: - stream.readIntArray(this.headIntervals[0]); - break; - case MdlUtils.TOKEN_DECAY_UV_ANIM: - stream.readIntArray(this.headIntervals[1]); - break; - case MdlUtils.TOKEN_TAIL_UV_ANIM: - stream.readIntArray(this.tailIntervals[0]); - break; - case MdlUtils.TOKEN_TAIL_DECAY_UV_ANIM: - stream.readIntArray(this.tailIntervals[1]); - break; - case MdlUtils.TOKEN_TEXTURE_ID: - this.textureId = stream.readInt(); - break; - case MdlUtils.TOKEN_REPLACEABLE_ID: - this.replaceableId = stream.readUInt32(); - break; - case MdlUtils.TOKEN_PRIORITY_PLANE: - this.priorityPlane = stream.readInt(); - break; - default: - throw new RuntimeException("Unknown token in ParticleEmitter2 " + this.name + ": " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startObjectBlock(MdlUtils.TOKEN_PARTICLE_EMITTER2, this.name); - writeGenericHeader(stream); - - if ((this.flags & 0x10000) != 0) { - stream.writeFlag(MdlUtils.TOKEN_SORT_PRIMS_FAR_Z); - } - - if ((this.flags & 0x8000) != 0) { - stream.writeFlag(MdlUtils.TOKEN_UNSHADED); - } - - if ((this.flags & 0x20000) != 0) { - stream.writeFlag(MdlUtils.TOKEN_LINE_EMITTER); - } - - if ((this.flags & 0x40000) != 0) { - stream.writeFlag(MdlUtils.TOKEN_UNFOGGED); - } - - if ((this.flags & 0x80000) != 0) { - stream.writeFlag(MdlUtils.TOKEN_MODEL_SPACE); - } - - if ((this.flags & 0x100000) != 0) { - stream.writeFlag(MdlUtils.TOKEN_XY_QUAD); - } - - if (!writeTimeline(stream, AnimationMap.KP2S)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_SPEED, this.speed); - } - - if (!writeTimeline(stream, AnimationMap.KP2R)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_VARIATION, this.variation); - } - - if (!writeTimeline(stream, AnimationMap.KP2L)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_LATITUDE, this.latitude); - } - - if (!writeTimeline(stream, AnimationMap.KP2G)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_GRAVITY, this.gravity); - } - - writeTimeline(stream, AnimationMap.KP2V); - - if (this.squirt != 0) { - stream.writeFlag(MdlUtils.TOKEN_SQUIRT); - } - - stream.writeFloatAttrib(MdlUtils.TOKEN_LIFE_SPAN, this.lifeSpan); - - if (!writeTimeline(stream, AnimationMap.KP2E)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_EMISSION_RATE, this.emissionRate); - } - - if (!writeTimeline(stream, AnimationMap.KP2W)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_WIDTH, this.width); - } - - if (!writeTimeline(stream, AnimationMap.KP2N)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_LENGTH, this.length); - } - - stream.writeFlag(this.filterMode.toString()); - stream.writeAttribUInt32(MdlUtils.TOKEN_ROWS, this.rows); - stream.writeAttribUInt32(MdlUtils.TOKEN_COLUMNS, this.columns); - stream.writeFlag(this.headOrTail.toString()); - stream.writeFloatAttrib(MdlUtils.TOKEN_TAIL_LENGTH, this.tailLength); - stream.writeFloatAttrib(MdlUtils.TOKEN_TIME, this.timeMiddle); - - stream.startBlock(MdlUtils.TOKEN_SEGMENT_COLOR); - stream.writeColor(MdlUtils.TOKEN_COLOR, this.segmentColors[0]); - stream.writeColor(MdlUtils.TOKEN_COLOR, this.segmentColors[1]); - stream.writeColor(MdlUtils.TOKEN_COLOR, this.segmentColors[2]); - stream.endBlockComma(); - - stream.writeArrayAttrib(MdlUtils.TOKEN_ALPHA, this.segmentAlphas); - stream.writeFloatArrayAttrib(MdlUtils.TOKEN_PARTICLE_SCALING, this.segmentScaling); - stream.writeArrayAttrib(MdlUtils.TOKEN_LIFE_SPAN_UV_ANIM, this.headIntervals[0]); - stream.writeArrayAttrib(MdlUtils.TOKEN_DECAY_UV_ANIM, this.headIntervals[1]); - stream.writeArrayAttrib(MdlUtils.TOKEN_TAIL_UV_ANIM, this.tailIntervals[0]); - stream.writeArrayAttrib(MdlUtils.TOKEN_TAIL_DECAY_UV_ANIM, this.tailIntervals[1]); - stream.writeAttrib(MdlUtils.TOKEN_TEXTURE_ID, this.textureId); - - if (this.replaceableId != 0) { - stream.writeAttribUInt32(MdlUtils.TOKEN_REPLACEABLE_ID, this.replaceableId); - } - - if (this.priorityPlane != 0) { - stream.writeAttrib(MdlUtils.TOKEN_PRIORITY_PLANE, this.priorityPlane); - } - - writeGenericTimelines(stream); - - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - return 175 + super.getByteLength(version); - } - - public float getSpeed() { - return this.speed; - } - - public float getVariation() { - return this.variation; - } - - public float getLatitude() { - return this.latitude; - } - - public float getGravity() { - return this.gravity; - } - - public float getLifeSpan() { - return this.lifeSpan; - } - - public float getEmissionRate() { - return this.emissionRate; - } - - public float getLength() { - return this.length; - } - - public float getWidth() { - return this.width; - } - - public FilterMode getFilterMode() { - return this.filterMode; - } - - public long getRows() { - return this.rows; - } - - public long getColumns() { - return this.columns; - } - - public HeadOrTail getHeadOrTail() { - return this.headOrTail; - } - - public float getTailLength() { - return this.tailLength; - } - - public float getTimeMiddle() { - return this.timeMiddle; - } - - public float[][] getSegmentColors() { - return this.segmentColors; - } - - public short[] getSegmentAlphas() { - return this.segmentAlphas; - } - - public float[] getSegmentScaling() { - return this.segmentScaling; - } - - public long[][] getHeadIntervals() { - return this.headIntervals; - } - - public long[][] getTailIntervals() { - return this.tailIntervals; - } - - public int getTextureId() { - return this.textureId; - } - - public long getSquirt() { - return this.squirt; - } - - public int getPriorityPlane() { - return this.priorityPlane; - } - - public long getReplaceableId() { - return this.replaceableId; - } - - public void setSpeed(final float speed) { - this.speed = speed; - } - - public void setVariation(final float variation) { - this.variation = variation; - } - - public void setLatitude(final float latitude) { - this.latitude = latitude; - } - - public void setGravity(final float gravity) { - this.gravity = gravity; - } - - public void setLifeSpan(final float lifeSpan) { - this.lifeSpan = lifeSpan; - } - - public void setEmissionRate(final float emissionRate) { - this.emissionRate = emissionRate; - } - - public void setLength(final float length) { - this.length = length; - } - - public void setWidth(final float width) { - this.width = width; - } - - public void setFilterMode(final FilterMode filterMode) { - this.filterMode = filterMode; - } - - public void setRows(final long rows) { - this.rows = rows; - } - - public void setColumns(final long columns) { - this.columns = columns; - } - - public void setHeadOrTail(final HeadOrTail headOrTail) { - this.headOrTail = headOrTail; - } - - public void setTailLength(final float tailLength) { - this.tailLength = tailLength; - } - - public void setTimeMiddle(final float timeMiddle) { - this.timeMiddle = timeMiddle; - } - - public void setSegmentAlphas(final short[] segmentAlphas) { - this.segmentAlphas = segmentAlphas; - } - - public void setSegmentScaling(final float[] segmentScaling) { - this.segmentScaling = segmentScaling; - } - - public void setHeadIntervals(final long[][] headIntervals) { - this.headIntervals = headIntervals; - } - - public void setTailIntervals(final long[][] tailIntervals) { - this.tailIntervals = tailIntervals; - } - - public void setTextureId(final int textureId) { - this.textureId = textureId; - } - - public void setSquirt(final long squirt) { - this.squirt = squirt; - } - - public void setPriorityPlane(final int priorityPlane) { - this.priorityPlane = priorityPlane; - } - - public void setReplaceableId(final long replaceableId) { - this.replaceableId = replaceableId; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxParticleEmitterPopcorn.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxParticleEmitterPopcorn.java deleted file mode 100644 index f48f4ff3..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxParticleEmitterPopcorn.java +++ /dev/null @@ -1,180 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxParticleEmitterPopcorn extends MdlxGenericObject { - public float lifeSpan = 0; - public float emissionRate = 0; - public float speed = 0; - public float[] color = new float[] { 1, 1, 1 }; - public float alpha = 0; - public int replaceableId = 0; - public String path = ""; - public String animationVisiblityGuide = ""; - - public MdlxParticleEmitterPopcorn() { - super(0); - } - - @Override - public void readMdx(final BinaryReader reader, final int version) { - final int position = reader.position(); - final long size = reader.readUInt32(); - - super.readMdx(reader, version); - - this.lifeSpan = reader.readFloat32(); - this.emissionRate = reader.readFloat32(); - this.speed = reader.readFloat32(); - reader.readFloat32Array(this.color); - this.alpha = reader.readFloat32(); - this.replaceableId = reader.readInt32(); - this.path = reader.read(260); - this.animationVisiblityGuide = reader.read(260); - - readTimelines(reader, size - (reader.position() - position)); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeUInt32(getByteLength(version)); - - super.writeMdx(writer, version); - - writer.writeFloat32(this.lifeSpan); - writer.writeFloat32(this.emissionRate); - writer.writeFloat32(this.speed); - writer.writeFloat32Array(this.color); - writer.writeFloat32(this.alpha); - writer.writeInt32(this.replaceableId); - writer.writeWithNulls(this.path, 260); - writer.writeWithNulls(this.animationVisiblityGuide, 260); - - writeNonGenericAnimationChunks(writer); - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - for (final String token : super.readMdlGeneric(stream)) { - switch (token) { - case "SortPrimsFarZ": - this.flags |= 0x10000; - break; - case "Unshaded": - this.flags |= 0x8000; - break; - case "Unfogged": - this.flags |= 0x40000; - break; - case "static LifeSpan": - this.lifeSpan = stream.readFloat(); - break; - case "LifeSpan": - readTimeline(stream, AnimationMap.KPPL); - break; - case "static EmissionRate": - this.emissionRate = stream.readFloat(); - break; - case "EmissionRate": - readTimeline(stream, AnimationMap.KPPE); - break; - case "static Speed": - this.speed = stream.readFloat(); - break; - case "Speed": - readTimeline(stream, AnimationMap.KPPS); - break; - case "static Color": - stream.readColor(this.color); - break; - case "Color": - readTimeline(stream, AnimationMap.KPPC); - break; - case "static Alpha": - this.alpha = stream.readFloat(); - break; - case "Alpha": - readTimeline(stream, AnimationMap.KPPA); - break; - case "Visibility": - readTimeline(stream, AnimationMap.KPPV); - break; - case "ReplaceableId": - this.replaceableId = stream.readInt(); - break; - case "Path": - this.path = stream.read(); - break; - case "AnimVisibilityGuide": - this.animationVisiblityGuide = stream.read(); - break; - default: - throw new RuntimeException("Unknown token in MdlxParticleEmitterPopcorn " + this.name + ": " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startObjectBlock(MdlUtils.TOKEN_PARTICLE_EMITTER2, this.name); - writeGenericHeader(stream); - - if ((this.flags & 0x10000) != 0) { - stream.writeFlag("SortPrimsFarZ"); - } - - if ((this.flags & 0x8000) != 0) { - stream.writeFlag("Unshaded"); - } - - if ((this.flags & 0x40000) != 0) { - stream.writeFlag("Unfogged"); - } - - if (!writeTimeline(stream, AnimationMap.KPPL)) { - stream.writeFloatAttrib("static LifeSpan", this.lifeSpan); - } - - if (!writeTimeline(stream, AnimationMap.KPPE)) { - stream.writeFloatAttrib("static EmissionRate", this.emissionRate); - } - - if (!writeTimeline(stream, AnimationMap.KPPS)) { - stream.writeFloatAttrib("static Speed", this.speed); - } - - if (!writeTimeline(stream, AnimationMap.KPPC)) { - stream.writeFloatArrayAttrib("static Color", this.color); - } - - if (!writeTimeline(stream, AnimationMap.KPPA)) { - stream.writeFloatAttrib("static Alpha", this.alpha); - } - - writeTimeline(stream, AnimationMap.KPPV); - - if (this.replaceableId != 0) { - stream.writeAttrib("ReplaceableId", this.replaceableId); - } - - if (this.path.length() != 0) { - stream.writeStringAttrib("Path", this.path); - } - - if (this.animationVisiblityGuide.length() != 0) { - stream.writeStringAttrib("AnimVisibilityGuide", this.animationVisiblityGuide); - } - - writeGenericTimelines(stream); - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - return 556 + super.getByteLength(version); - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxRibbonEmitter.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxRibbonEmitter.java deleted file mode 100644 index c5046211..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxRibbonEmitter.java +++ /dev/null @@ -1,264 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxRibbonEmitter extends MdlxGenericObject { - public float heightAbove = 0; - public float heightBelow = 0; - public float alpha = 0; - public float[] color = new float[3]; - public float lifeSpan = 0; - public long textureSlot = 0; - public long emissionRate = 0; - public long rows = 0; - public long columns = 0; - public int materialId = 0; - public float gravity = 0; - - public MdlxRibbonEmitter() { - super(0x4000); - } - - @Override - public void readMdx(final BinaryReader reader, final int version) { - final int position = reader.position(); - final long size = reader.readUInt32(); - - super.readMdx(reader, version); - - this.heightAbove = reader.readFloat32(); - this.heightBelow = reader.readFloat32(); - this.alpha = reader.readFloat32(); - reader.readFloat32Array(this.color); - this.lifeSpan = reader.readFloat32(); - this.textureSlot = reader.readUInt32(); - this.emissionRate = reader.readUInt32(); - this.rows = reader.readUInt32(); - this.columns = reader.readUInt32(); - this.materialId = reader.readInt32(); - this.gravity = reader.readFloat32(); - - readTimelines(reader, size - (reader.position() - position)); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeUInt32(getByteLength(version)); - - super.writeMdx(writer, version); - - writer.writeFloat32(this.heightAbove); - writer.writeFloat32(this.heightBelow); - writer.writeFloat32(this.alpha); - writer.writeFloat32Array(this.color); - writer.writeFloat32(this.lifeSpan); - writer.writeUInt32(this.textureSlot); - writer.writeUInt32(this.emissionRate); - writer.writeUInt32(this.rows); - writer.writeUInt32(this.columns); - writer.writeInt32(this.materialId); - writer.writeFloat32(this.gravity); - - writeNonGenericAnimationChunks(writer); - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - for (final String token : super.readMdlGeneric(stream)) { - switch (token) { - case MdlUtils.TOKEN_STATIC_HEIGHT_ABOVE: - this.heightAbove = stream.readFloat(); - break; - case MdlUtils.TOKEN_HEIGHT_ABOVE: - readTimeline(stream, AnimationMap.KRHA); - break; - case MdlUtils.TOKEN_STATIC_HEIGHT_BELOW: - this.heightBelow = stream.readFloat(); - break; - case MdlUtils.TOKEN_HEIGHT_BELOW: - readTimeline(stream, AnimationMap.KRHB); - break; - case MdlUtils.TOKEN_STATIC_ALPHA: - this.alpha = stream.readFloat(); - break; - case MdlUtils.TOKEN_ALPHA: - readTimeline(stream, AnimationMap.KRAL); - break; - case MdlUtils.TOKEN_STATIC_COLOR: - stream.readColor(this.color); - break; - case MdlUtils.TOKEN_COLOR: - readTimeline(stream, AnimationMap.KRCO); - break; - case MdlUtils.TOKEN_STATIC_TEXTURE_SLOT: - this.textureSlot = stream.readUInt32(); - break; - case MdlUtils.TOKEN_TEXTURE_SLOT: - readTimeline(stream, AnimationMap.KRTX); - break; - case MdlUtils.TOKEN_VISIBILITY: - readTimeline(stream, AnimationMap.KRVS); - break; - case MdlUtils.TOKEN_EMISSION_RATE: - this.emissionRate = stream.readUInt32(); - break; - case MdlUtils.TOKEN_LIFE_SPAN: - this.lifeSpan = stream.readFloat(); - break; - case MdlUtils.TOKEN_GRAVITY: - this.gravity = stream.readFloat(); - break; - case MdlUtils.TOKEN_ROWS: - this.rows = stream.readUInt32(); - break; - case MdlUtils.TOKEN_COLUMNS: - this.columns = stream.readUInt32(); - break; - case MdlUtils.TOKEN_MATERIAL_ID: - this.materialId = stream.readInt(); - break; - default: - throw new RuntimeException("Unknown token in RibbonEmitter " + this.name + ": " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startObjectBlock(MdlUtils.TOKEN_RIBBON_EMITTER, this.name); - writeGenericHeader(stream); - - if (!writeTimeline(stream, AnimationMap.KRHA)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_HEIGHT_ABOVE, this.heightAbove); - } - - if (!writeTimeline(stream, AnimationMap.KRHB)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_HEIGHT_BELOW, this.heightBelow); - } - - if (!writeTimeline(stream, AnimationMap.KRAL)) { - stream.writeFloatAttrib(MdlUtils.TOKEN_STATIC_ALPHA, this.alpha); - } - - if (!writeTimeline(stream, AnimationMap.KRCO)) { - stream.writeColor(MdlUtils.TOKEN_STATIC_COLOR, this.color); - } - - if (!writeTimeline(stream, AnimationMap.KRTX)) { - stream.writeAttribUInt32(MdlUtils.TOKEN_STATIC_TEXTURE_SLOT, this.textureSlot); - } - - writeTimeline(stream, AnimationMap.KRVS); - - stream.writeAttribUInt32(MdlUtils.TOKEN_EMISSION_RATE, this.emissionRate); - stream.writeFloatAttrib(MdlUtils.TOKEN_LIFE_SPAN, this.lifeSpan); - - if (this.gravity != 0) { - stream.writeFloatAttrib(MdlUtils.TOKEN_GRAVITY, this.gravity); - } - - stream.writeAttribUInt32(MdlUtils.TOKEN_ROWS, this.rows); - stream.writeAttribUInt32(MdlUtils.TOKEN_COLUMNS, this.columns); - stream.writeAttrib(MdlUtils.TOKEN_MATERIAL_ID, this.materialId); - - writeGenericTimelines(stream); - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - return 56 + super.getByteLength(version); - } - - public float getHeightAbove() { - return this.heightAbove; - } - - public float getHeightBelow() { - return this.heightBelow; - } - - public float getAlpha() { - return this.alpha; - } - - public float[] getColor() { - return this.color; - } - - public float getLifeSpan() { - return this.lifeSpan; - } - - public long getTextureSlot() { - return this.textureSlot; - } - - public long getEmissionRate() { - return this.emissionRate; - } - - public long getRows() { - return this.rows; - } - - public long getColumns() { - return this.columns; - } - - public int getMaterialId() { - return this.materialId; - } - - public float getGravity() { - return this.gravity; - } - - public void setHeightAbove(final float heightAbove) { - this.heightAbove = heightAbove; - } - - public void setHeightBelow(final float heightBelow) { - this.heightBelow = heightBelow; - } - - public void setAlpha(final float alpha) { - this.alpha = alpha; - } - - public void setColor(final float[] color) { - this.color = color; - } - - public void setLifeSpan(final float lifeSpan) { - this.lifeSpan = lifeSpan; - } - - public void setTextureSlot(final long textureSlot) { - this.textureSlot = textureSlot; - } - - public void setEmissionRate(final long emissionRate) { - this.emissionRate = emissionRate; - } - - public void setRows(final long rows) { - this.rows = rows; - } - - public void setColumns(final long columns) { - this.columns = columns; - } - - public void setMaterialId(final int materialId) { - this.materialId = materialId; - } - - public void setGravity(final float gravity) { - this.gravity = gravity; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxSequence.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxSequence.java deleted file mode 100644 index 9f0b3c88..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxSequence.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxSequence implements MdlxBlock { - public String name = ""; - public long[] interval = new long[2]; - public float moveSpeed = 0; - public int flags = 0; - public float rarity = 0; - public long syncPoint = 0; - public MdlxExtent extent = new MdlxExtent(); - - @Override - public void readMdx(final BinaryReader reader, final int version) { - this.name = reader.read(80); - reader.readUInt32Array(this.interval); - this.moveSpeed = reader.readFloat32(); - this.flags = reader.readInt32(); - this.rarity = reader.readFloat32(); - this.syncPoint = reader.readUInt32(); - this.extent.readMdx(reader); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeWithNulls(this.name, 80); - writer.writeUInt32Array(this.interval); - writer.writeFloat32(this.moveSpeed); - writer.writeUInt32(this.flags); - writer.writeFloat32(this.rarity); - writer.writeUInt32(this.syncPoint); - this.extent.writeMdx(writer); - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - this.name = stream.read(); - - for (final String token : stream.readBlock()) { - switch (token) { - case MdlUtils.TOKEN_INTERVAL: - stream.readIntArray(this.interval); - break; - case MdlUtils.TOKEN_NONLOOPING: - this.flags = 1; - break; - case MdlUtils.TOKEN_MOVESPEED: - this.moveSpeed = stream.readFloat(); - break; - case MdlUtils.TOKEN_RARITY: - this.rarity = stream.readFloat(); - break; - case MdlUtils.TOKEN_MINIMUM_EXTENT: - stream.readFloatArray(this.extent.min); - break; - case MdlUtils.TOKEN_MAXIMUM_EXTENT: - stream.readFloatArray(this.extent.max); - break; - case MdlUtils.TOKEN_BOUNDSRADIUS: - this.extent.boundsRadius = stream.readFloat(); - break; - default: - throw new IllegalStateException("Unknown token in Sequence \"" + this.name + "\": " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startObjectBlock(MdlUtils.TOKEN_ANIM, this.name); - stream.writeArrayAttrib(MdlUtils.TOKEN_INTERVAL, this.interval); - - if (this.flags == 1) { - stream.writeFlag(MdlUtils.TOKEN_NONLOOPING); - } - - if (this.moveSpeed != 0) { - stream.writeFloatAttrib(MdlUtils.TOKEN_MOVESPEED, this.moveSpeed); - } - - if (this.rarity != 0) { - stream.writeFloatAttrib(MdlUtils.TOKEN_RARITY, this.rarity); - } - - this.extent.writeMdl(stream); - stream.endBlock(); - } - - public String getName() { - return this.name; - } - - public long[] getInterval() { - return this.interval; - } - - public float getMoveSpeed() { - return this.moveSpeed; - } - - public int getFlags() { - return this.flags; - } - - public float getRarity() { - return this.rarity; - } - - public long getSyncPoint() { - return this.syncPoint; - } - - public MdlxExtent getExtent() { - return this.extent; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxTexture.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxTexture.java deleted file mode 100644 index 657eb5f1..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxTexture.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxTexture implements MdlxBlock { - public enum WrapMode { - REPEAT_BOTH(false, false), - WRAP_WIDTH(true, false), - WRAP_HEIGHT(false, true), - WRAP_BOTH(true, true); - - private final boolean wrapWidth; - private final boolean wrapHeight; - - public static WrapMode fromId(final int id) { - return values()[id]; - } - - private WrapMode(final boolean wrapWidth, final boolean wrapHeight) { - this.wrapWidth = wrapWidth; - this.wrapHeight = wrapHeight; - } - - public boolean isWrapWidth() { - return this.wrapWidth; - } - - public boolean isWrapHeight() { - return this.wrapHeight; - } - } - - public int replaceableId = 0; - public String path = ""; - public WrapMode wrapMode = WrapMode.REPEAT_BOTH; - - @Override - public void readMdx(final BinaryReader reader, final int version) { - this.replaceableId = reader.readInt32(); - this.path = reader.read(260); - this.wrapMode = WrapMode.fromId(reader.readInt32()); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeInt32(this.replaceableId); - writer.writeWithNulls(this.path, 260); - writer.writeInt32(this.wrapMode.ordinal()); - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - for (final String token : stream.readBlock()) { - switch (token) { - case MdlUtils.TOKEN_IMAGE: - this.path = stream.read(); - break; - case MdlUtils.TOKEN_REPLACEABLE_ID: - this.replaceableId = stream.readInt(); - break; - case MdlUtils.TOKEN_WRAP_WIDTH: - this.wrapMode = WrapMode.fromId(this.wrapMode.ordinal() + 0x1); - break; - case MdlUtils.TOKEN_WRAP_HEIGHT: - this.wrapMode = WrapMode.fromId(this.wrapMode.ordinal() + 0x2); - break; - default: - throw new RuntimeException("Unknown token in Texture: " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startBlock(MdlUtils.TOKEN_BITMAP); - stream.writeStringAttrib(MdlUtils.TOKEN_IMAGE, this.path); - - if (this.replaceableId != 0) { - stream.writeAttrib(MdlUtils.TOKEN_REPLACEABLE_ID, this.replaceableId); - } - - if ((this.wrapMode == WrapMode.WRAP_WIDTH) || (this.wrapMode == WrapMode.WRAP_BOTH)) { - stream.writeFlag(MdlUtils.TOKEN_WRAP_WIDTH); - } - - if ((this.wrapMode == WrapMode.WRAP_HEIGHT) || (this.wrapMode == WrapMode.WRAP_BOTH)) { - stream.writeFlag(MdlUtils.TOKEN_WRAP_HEIGHT); - } - - stream.endBlock(); - } - - public int getReplaceableId() { - return this.replaceableId; - } - - public String getPath() { - return this.path; - } - - public WrapMode getWrapMode() { - return this.wrapMode; - } - - public void setReplaceableId(final int replaceableId) { - this.replaceableId = replaceableId; - } - - public void setPath(final String path) { - this.path = path; - } - - public void setWrapMode(final WrapMode wrapMode) { - this.wrapMode = wrapMode; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxTextureAnimation.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxTextureAnimation.java deleted file mode 100644 index acbc8894..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxTextureAnimation.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxTextureAnimation extends MdlxAnimatedObject { - @Override - public void readMdx(final BinaryReader reader, final int version) { - final long size = reader.readUInt32(); - - readTimelines(reader, size - 4); - } - - @Override - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeUInt32(getByteLength(version)); - - writeTimelines(writer); - } - - @Override - public void readMdl(final MdlTokenInputStream stream, final int version) { - for (final String token : stream.readBlock()) { - switch (token) { - case MdlUtils.TOKEN_TRANSLATION: - readTimeline(stream, AnimationMap.KTAT); - break; - case MdlUtils.TOKEN_ROTATION: - readTimeline(stream, AnimationMap.KTAR); - break; - case MdlUtils.TOKEN_SCALING: - readTimeline(stream, AnimationMap.KTAS); - break; - default: - throw new RuntimeException("Unknown token in TextureAnimation: " + token); - } - } - } - - @Override - public void writeMdl(final MdlTokenOutputStream stream, final int version) { - stream.startBlock(MdlUtils.TOKEN_TVERTEX_ANIM); - writeTimeline(stream, AnimationMap.KTAT); - writeTimeline(stream, AnimationMap.KTAR); - writeTimeline(stream, AnimationMap.KTAS); - stream.endBlock(); - } - - @Override - public long getByteLength(final int version) { - return 4 + super.getByteLength(version); - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxTimelineDescriptor.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxTimelineDescriptor.java deleted file mode 100644 index b413cfca..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxTimelineDescriptor.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxFloatArrayTimeline; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxFloatTimeline; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxTimeline; -import com.hiveworkshop.rms.parsers.mdlx.timeline.MdlxUInt32Timeline; - -public interface MdlxTimelineDescriptor { - MdlxTimeline createTimeline(); - - MdlxTimelineDescriptor UINT32_TIMELINE = MdlxUInt32Timeline::new; - - MdlxTimelineDescriptor FLOAT_TIMELINE = MdlxFloatTimeline::new; - - MdlxTimelineDescriptor VECTOR3_TIMELINE = () -> new MdlxFloatArrayTimeline(3); - - MdlxTimelineDescriptor VECTOR4_TIMELINE = () -> new MdlxFloatArrayTimeline(4); -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxUnknownChunk.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxUnknownChunk.java deleted file mode 100644 index e4787877..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/MdlxUnknownChunk.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx; - -import com.etheller.warsmash.util.War3ID; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public class MdlxUnknownChunk implements MdlxChunk { - public final short[] chunk; - public final War3ID tag; - - public MdlxUnknownChunk(final BinaryReader reader, final long size, final War3ID tag) { - System.err.println("Loading unknown chunk: " + tag); - this.chunk = reader.readUInt8Array((int) size); - this.tag = tag; - } - - public void writeMdx(final BinaryWriter writer, final int version) { - writer.writeTag(this.tag.getValue()); - // Below: Byte.BYTES used because it's mean as a UInt8 array. This is - // not using Short.BYTES, deliberately, despite using a short[] as the - // type for the array. This is a Java problem that did not exist in the original - // JavaScript implementation by Ghostwolf - writer.writeUInt32(this.chunk.length * Byte.BYTES); - writer.writeUInt8Array(this.chunk); - } - - @Override - public long getByteLength(final int version) { - return 8 + (this.chunk.length * Byte.BYTES); - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/mdl/MdlTokenInputStream.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/mdl/MdlTokenInputStream.java deleted file mode 100644 index bdba2769..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/mdl/MdlTokenInputStream.java +++ /dev/null @@ -1,208 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx.mdl; - -import java.nio.ByteBuffer; -import java.util.Iterator; - -public class MdlTokenInputStream { - private final ByteBuffer buffer; - private int index; - - public MdlTokenInputStream(final ByteBuffer buffer) { - this.buffer = buffer; - this.index = 0; - } - - public String read() { - boolean inComment = false; - boolean inString = false; - final StringBuilder token = new StringBuilder(); - final int length = this.buffer.remaining(); - - while (this.index < length) { - // Note: cast from 'byte' to 'char' will cause Java incompatibility with Chinese - // and Russian/Cyrillic and others - final char c = (char) this.buffer.get(this.buffer.position() + this.index++); - - if (inComment) { - if (c == '\n') { - inComment = false; - } - } - else if (inString) { - if (c == '"') { - return token.toString(); - } - else { - token.append(c); - } - } - else if ((c == ' ') || (c == ',') || (c == '\t') || (c == '\n') || (c == ':') || (c == '\r')) { - if (token.length() > 0) { - return token.toString(); - } - } - else if ((c == '{') || (c == '}')) { - if (token.length() > 0) { - this.index--; - return token.toString(); - } - else { - return Character.toString(c); - } - } - else if ((c == '/') && (this.buffer.get(this.buffer.position() + this.index) == '/')) { - if (token.length() > 0) { - this.index--; - return token.toString(); - } - else { - inComment = true; - } - } - else if (c == '"') { - if (token.length() > 0) { - this.index--; - return token.toString(); - } - else { - inString = true; - } - } - else { - token.append(c); - } - } - return null; - } - - public String peek() { - final int index = this.index; - final String value = read(); - - this.index = index; - return value; - } - - public long readUInt32() { - return Long.parseLong(read()); - } - - public int readInt() { - return Integer.parseInt(read()); - } - - public float readFloat() { - return Float.parseFloat(read()); - } - - public void readIntArray(final long[] values) { - read(); // { - - for (int i = 0, l = values.length; i < l; i++) { - values[i] = readInt(); - } - - read(); // } - } - - public float[] readFloatArray(final float[] values) { - read(); // { - - for (int i = 0, l = values.length; i < l; i++) { - values[i] = readFloat(); - } - - read(); // } - return values; - } - - /** - * Read an MDL keyframe value. If the value is a scalar, it is just the number. - * If the value is a vector, it is enclosed with curly braces. - * - * @param values {Float32Array|Uint32Array} - */ - public void readKeyframe(final float[] values) { - if (values.length == 1) { - values[0] = readFloat(); - } - else { - readFloatArray(values); - } - } - - public float[] readVectorArray(final float[] array, final int vectorLength) { - read(); // { - - for (int i = 0, l = array.length / vectorLength; i < l; i++) { - read(); // { - - for (int j = 0; j < vectorLength; j++) { - array[(i * vectorLength) + j] = readFloat(); - } - - read(); // } - } - - read(); // } - return array; - } - - public Iterable readBlock() { - read(); // { - return () -> new Iterator() { - String current; - private boolean hasLoaded = false; - - @Override - public String next() { - if (!this.hasLoaded) { - hasNext(); - } - this.hasLoaded = false; - return this.current; - } - - @Override - public boolean hasNext() { - this.current = read(); - this.hasLoaded = true; - return (this.current != null) && !this.current.equals("}"); - } - }; - } - - public int[] readUInt16Array(final int[] values) { - read(); // { - - for (int i = 0, l = values.length; i < l; i++) { - values[i] = readInt(); - } - - read(); // } - - return values; - } - - public short[] readUInt8Array(final short[] values) { - read(); // { - - for (int i = 0, l = values.length; i < l; i++) { - values[i] = Short.parseShort(read()); - } - - read(); // } - - return values; - } - - public void readColor(final float[] color) { - read(); // { - - color[2] = readFloat(); - color[1] = readFloat(); - color[0] = readFloat(); - - read(); // } - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/mdl/MdlTokenOutputStream.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/mdl/MdlTokenOutputStream.java deleted file mode 100644 index 8d35bfc6..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/mdl/MdlTokenOutputStream.java +++ /dev/null @@ -1,220 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx.mdl; - -public class MdlTokenOutputStream { - public final StringBuilder buffer = new StringBuilder(); - public int ident = 0; - public int fractionDigits = 6; - - public void writeKeyframe(final String prefix, final long uInt32Value) { - writeAttribUInt32(prefix, uInt32Value); - } - - public void writeKeyframe(final String prefix, final float floatValue) { - writeFloatAttrib(prefix, floatValue); - } - - public void writeKeyframe(final String prefix, final float[] floatArrayValues) { - writeFloatArrayAttrib(prefix, floatArrayValues); - } - - public void indent() { - this.ident += 1; - } - - public void unindent() { - this.ident -= 1; - } - - public void startObjectBlock(final String name, final String objectName) { - writeLine(name + " \"" + objectName + "\" {"); - this.ident += 1; - } - - public void startBlock(final String name, final int blockSize) { - writeLine(name + " " + blockSize + " {" + ""); - this.ident += 1; - } - - public void startBlock(final String name) { - writeLine(name + " {" + ""); - this.ident += 1; - } - - public void writeFlag(final String token) { - writeLine(token + ","); - } - - public void writeFlagUInt32(final long flag) { - writeLine(flag + ","); - } - - public void writeAttrib(final String string, final int globalSequenceId) { - writeLine(string + " " + globalSequenceId + ","); - } - - public void writeAttribUInt32(final String attribName, final long uInt) { - writeLine(attribName + " " + uInt + ","); - } - - public void writeAttrib(final String string, final String value) { - writeLine(string + " " + value + ","); - } - - public void writeFloatAttrib(final String attribName, final float value) { - writeLine(attribName + " " + value + ","); - } - - public void writeStringAttrib(final String attribName, final String value) { - writeLine(attribName + " \"" + value + "\","); - - } - - public void writeFloatArrayAttrib(final String attribName, final float[] floatArray) { - writeLine(attribName + " { " + formatFloatArray(floatArray) + " },"); - } - - public void writeLongSubArrayAttrib(final String attribName, final long[] array, final int startIndexInclusive, - final int endIndexExclusive) { - writeLine(attribName + " { " + formatLongSubArray(array, startIndexInclusive, endIndexExclusive) + " },"); - } - - public void writeFloatArray(final float[] floatArray) { - writeLine("{ " + formatFloatArray(floatArray) + " },"); - } - - public void writeShortArrayRaw(final short[] shortArray) { - writeLine(formatShortArray(shortArray) + ","); - } - - public void writeFloatSubArray(final float[] floatArray, final int startIndexInclusive, - final int endIndexExclusive) { - writeLine("{ " + formatFloatSubArray(floatArray, startIndexInclusive, endIndexExclusive) + " },"); - } - - public void writeVectorArray(final String token, final float[] vectors, final int vectorLength) { - startBlock(token, vectors.length / vectorLength); - - for (int i = 0, l = vectors.length; i < l; i += vectorLength) { - writeFloatSubArray(vectors, i, i + vectorLength); - } - - endBlock(); - } - - public void endBlock() { - this.ident -= 1; - writeLine("}"); - } - - public void endBlockComma() { - this.ident -= 1; - writeLine("},"); - } - - public void writeLine(final String string) { - for (int i = 0; i < this.ident; i++) { - this.buffer.append("\t"); - } - this.buffer.append(string); - this.buffer.append('\n'); - } - - public void startBlock(final String tokenFaces, final int sizeNumberProbably, final int length) { - writeLine(tokenFaces + " " + sizeNumberProbably + " " + length + " {" + ""); - this.ident += 1; - } - - public void writeColor(final String tokenStaticColor, final float[] color) { - writeLine(tokenStaticColor + " { " + color[2] + ", " + color[1] + ", " + color[0] + " },"); - } - - public void writeArrayAttrib(final String tokenAlpha, final short[] uint8Array) { - writeLine(tokenAlpha + " { " + formatShortArray(uint8Array) + " },"); - } - - public void writeArrayAttrib(final String tokenAlpha, final int[] uint16Array) { - writeLine(tokenAlpha + " { " + formatIntArray(uint16Array) + " },"); - } - - public void writeArrayAttrib(final String tokenAlpha, final long[] uint32Array) { - writeLine(tokenAlpha + " { " + formatLongArray(uint32Array) + " },"); - } - - private String formatFloat(final float value) { - final String s = Float.toString(value); - final String f = String.format("%." + this.fractionDigits + "f", value); - if (s.length() > f.length()) { - return f; - } - else { - return s; - } - } - - private String formatFloatArray(final float[] value) { - final StringBuilder stringBuilder = new StringBuilder(); - for (final float v : value) { - if (stringBuilder.length() > 0) { - stringBuilder.append(", "); - } - stringBuilder.append(formatFloat(v)); - } - return stringBuilder.toString(); - } - - private String formatLongArray(final long[] value) { - final StringBuilder stringBuilder = new StringBuilder(); - for (final long item : value) { - if (stringBuilder.length() > 0) { - stringBuilder.append(", "); - } - stringBuilder.append(item); - } - return stringBuilder.toString(); - } - - private String formatShortArray(final short[] value) { - final StringBuilder stringBuilder = new StringBuilder(); - for (final short item : value) { - if (stringBuilder.length() > 0) { - stringBuilder.append(", "); - } - stringBuilder.append(item); - } - return stringBuilder.toString(); - } - - private String formatIntArray(final int[] value) { - final StringBuilder stringBuilder = new StringBuilder(); - for (final int j : value) { - if (stringBuilder.length() > 0) { - stringBuilder.append(", "); - } - stringBuilder.append(j); - } - return stringBuilder.toString(); - } - - private String formatLongSubArray(final long[] value, final int startIndexInclusive, final int endIndexExclusive) { - final StringBuilder stringBuilder = new StringBuilder(); - for (int i = startIndexInclusive; i < endIndexExclusive; i++) { - if (stringBuilder.length() > 0) { - stringBuilder.append(", "); - } - stringBuilder.append(value[i]); - } - return stringBuilder.toString(); - } - - private String formatFloatSubArray(final float[] value, final int startIndexInclusive, - final int endIndexExclusive) { - final StringBuilder stringBuilder = new StringBuilder(); - for (int i = startIndexInclusive; i < endIndexExclusive; i++) { - if (stringBuilder.length() > 0) { - stringBuilder.append(", "); - } - stringBuilder.append(formatFloat(value[i])); - } - return stringBuilder.toString(); - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/mdl/MdlUtils.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/mdl/MdlUtils.java deleted file mode 100644 index 5f3f4fa1..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/mdl/MdlUtils.java +++ /dev/null @@ -1,203 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx.mdl; - -/** - * Constants for the tokens were used to prevent typos in token literals. It - * would be very easy for me to type "Interval" in one place and "Intreval" in - * another by mistake. With this paradigm, that mistake causes a compile error, - * since TOKEN_INTREVAL does not exist. - */ -public class MdlUtils { - public static final String TOKEN_VERSION = "Version"; - - public static final String TOKEN_MODEL = "Model"; - - public static final String TOKEN_SEQUENCES = "Sequences"; - - public static final String TOKEN_GLOBAL_SEQUENCES = "GlobalSequences"; - - public static final String TOKEN_INTERVAL = "Interval"; - public static final String TOKEN_NONLOOPING = "NonLooping"; - public static final String TOKEN_MOVESPEED = "MoveSpeed"; - public static final String TOKEN_RARITY = "Rarity"; - - public static final String TOKEN_FORMAT_VERSION = "FormatVersion"; - public static final String TOKEN_BLEND_TIME = "BlendTime"; - public static final String TOKEN_DURATION = "Duration"; - - public static final String TOKEN_IMAGE = "Image"; - public static final String TOKEN_WRAP_WIDTH = "WrapWidth"; - public static final String TOKEN_WRAP_HEIGHT = "WrapHeight"; - public static final String TOKEN_BITMAP = "Bitmap"; - - public static final String TOKEN_TVERTEX_ANIM = "TVertexAnim"; - - public static final String TOKEN_DONT_INTERP = "DontInterp"; - public static final String TOKEN_LINEAR = "Linear"; - public static final String TOKEN_HERMITE = "Hermite"; - public static final String TOKEN_BEZIER = "Bezier"; - public static final String TOKEN_GLOBAL_SEQ_ID = "GlobalSeqId"; - - public static final String TOKEN_PLANE = "Plane"; - public static final String TOKEN_BOX = "Box"; - public static final String TOKEN_SPHERE = "Sphere"; - public static final String TOKEN_CYLINDER = "Cylinder"; - - public static final String TOKEN_GEOSETID = "GeosetId"; - public static final String TOKEN_MULTIPLE = "Multiple"; - public static final String TOKEN_GEOSETANIMID = "GeosetAnimId"; - public static final String TOKEN_NONE = "None"; - public static final String TOKEN_OBJECTID = "ObjectId"; - public static final String TOKEN_PARENT = "Parent"; - public static final String TOKEN_BILLBOARDED_LOCK_Z = "BillboardedLockZ"; - public static final String TOKEN_BILLBOARDED_LOCK_Y = "BillboardedLockY"; - public static final String TOKEN_BILLBOARDED_LOCK_X = "BillboardedLockX"; - public static final String TOKEN_BILLBOARDED = "Billboarded"; - public static final String TOKEN_CAMERA_ANCHORED = "CameraAnchored"; - public static final String TOKEN_DONT_INHERIT = "DontInherit"; - public static final String TOKEN_ROTATION = "Rotation"; - public static final String TOKEN_TRANSLATION = "Translation"; - public static final String TOKEN_SCALING = "Scaling"; - public static final String TOKEN_STATIC = "static"; - public static final String TOKEN_ATTACHMENT_ID = "AttachmentID"; - public static final String TOKEN_PATH = "Path"; - public static final String TOKEN_VISIBILITY = "Visibility"; - public static final String TOKEN_POSITION = "Position"; - public static final String TOKEN_FIELDOFVIEW = "FieldOfView"; - public static final String TOKEN_FARCLIP = "FarClip"; - public static final String TOKEN_NEARCLIP = "NearClip"; - public static final String TOKEN_TARGET = "Target"; - public static final String TOKEN_VERTICES = "Vertices"; - public static final String TOKEN_BOUNDSRADIUS = "BoundsRadius"; - public static final String TOKEN_EVENT_TRACK = "EventTrack"; - public static final String TOKEN_MAXIMUM_EXTENT = "MaximumExtent"; - public static final String TOKEN_MINIMUM_EXTENT = "MinimumExtent"; - public static final String TOKEN_NORMALS = "Normals"; - public static final String TOKEN_TVERTICES = "TVertices"; - public static final String TOKEN_VERTEX_GROUP = "VertexGroup"; - public static final String TOKEN_FACES = "Faces"; - public static final String TOKEN_GROUPS = "Groups"; - public static final String TOKEN_ANIM = "Anim"; - public static final String TOKEN_MATERIAL_ID = "MaterialID"; - public static final String TOKEN_SELECTION_GROUP = "SelectionGroup"; - public static final String TOKEN_UNSELECTABLE = "Unselectable"; - public static final String TOKEN_TRIANGLES = "Triangles"; - public static final String TOKEN_MATRICES = "Matrices"; - public static final String TOKEN_DROP_SHADOW = "DropShadow"; - public static final String TOKEN_ALPHA = "Alpha"; - public static final String TOKEN_COLOR = "Color"; - public static final String TOKEN_STATIC_ALPHA = TOKEN_STATIC + " " + TOKEN_ALPHA; - public static final String TOKEN_STATIC_COLOR = TOKEN_STATIC + " " + TOKEN_COLOR; - public static final String TOKEN_FILTER_MODE = "FilterMode"; - public static final String TOKEN_UNSHADED = "Unshaded"; - public static final String TOKEN_SPHERE_ENV_MAP = "SphereEnvMap"; - public static final String TOKEN_TWO_SIDED = "TwoSided"; - public static final String TOKEN_UNFOGGED = "Unfogged"; - public static final String TOKEN_NO_DEPTH_TEST = "NoDepthTest"; - public static final String TOKEN_NO_DEPTH_SET = "NoDepthSet"; - public static final String TOKEN_TEXTURE_ID = "TextureID"; - public static final String TOKEN_STATIC_TEXTURE_ID = TOKEN_STATIC + " " + TOKEN_TEXTURE_ID; - public static final String TOKEN_TVERTEX_ANIM_ID = "TVertexAnimId"; - public static final String TOKEN_COORD_ID = "CoordId"; - - public static final String TOKEN_OMNIDIRECTIONAL = "Omnidirectional"; - public static final String TOKEN_DIRECTIONAL = "Directional"; - public static final String TOKEN_AMBIENT = "Ambient"; - public static final String TOKEN_ATTENUATION_START = "AttenuationStart"; - public static final String TOKEN_STATIC_ATTENUATION_START = TOKEN_STATIC + " " + TOKEN_ATTENUATION_START; - public static final String TOKEN_ATTENUATION_END = "AttenuationEnd"; - public static final String TOKEN_STATIC_ATTENUATION_END = TOKEN_STATIC + " " + TOKEN_ATTENUATION_END; - public static final String TOKEN_INTENSITY = "Intensity"; - public static final String TOKEN_STATIC_INTENSITY = TOKEN_STATIC + " " + TOKEN_INTENSITY; - public static final String TOKEN_AMB_INTENSITY = "AmbIntensity"; - public static final String TOKEN_STATIC_AMB_INTENSITY = TOKEN_STATIC + " " + TOKEN_AMB_INTENSITY; - public static final String TOKEN_AMB_COLOR = "AmbColor"; - public static final String TOKEN_STATIC_AMB_COLOR = TOKEN_STATIC + " " + TOKEN_AMB_COLOR; - - public static final String TOKEN_CONSTANT_COLOR = "ConstantColor"; - public static final String TOKEN_SORT_PRIMS_NEAR_Z = "SortPrimsNearZ"; - public static final String TOKEN_SORT_PRIMS_FAR_Z = "SortPrimsFarZ"; - public static final String TOKEN_FULL_RESOLUTION = "FullResolution"; - public static final String TOKEN_PRIORITY_PLANE = "PriorityPlane"; - - public static final String TOKEN_EMITTER_USES_MDL = "EmitterUsesMDL"; - public static final String TOKEN_EMITTER_USES_TGA = "EmitterUsesTGA"; - public static final String TOKEN_EMISSION_RATE = "EmissionRate"; - public static final String TOKEN_STATIC_EMISSION_RATE = TOKEN_STATIC + " " + TOKEN_EMISSION_RATE; - public static final String TOKEN_GRAVITY = "Gravity"; - public static final String TOKEN_STATIC_GRAVITY = TOKEN_STATIC + " " + TOKEN_GRAVITY; - public static final String TOKEN_LONGITUDE = "Longitude"; - public static final String TOKEN_STATIC_LONGITUDE = TOKEN_STATIC + " " + TOKEN_LONGITUDE; - public static final String TOKEN_LATITUDE = "Latitude"; - public static final String TOKEN_STATIC_LATITUDE = TOKEN_STATIC + " " + TOKEN_LATITUDE; - public static final String TOKEN_PARTICLE = "Particle"; - public static final String TOKEN_LIFE_SPAN = "LifeSpan"; - public static final String TOKEN_STATIC_LIFE_SPAN = TOKEN_STATIC + " " + TOKEN_LIFE_SPAN; - public static final String TOKEN_INIT_VELOCITY = "InitVelocity"; - public static final String TOKEN_STATIC_INIT_VELOCITY = TOKEN_STATIC + " " + TOKEN_INIT_VELOCITY; - - public static final String TOKEN_LINE_EMITTER = "LineEmitter"; - public static final String TOKEN_MODEL_SPACE = "ModelSpace"; - public static final String TOKEN_XY_QUAD = "XYQuad"; - public static final String TOKEN_SPEED = "Speed"; - public static final String TOKEN_STATIC_SPEED = TOKEN_STATIC + " " + TOKEN_SPEED; - public static final String TOKEN_VARIATION = "Variation"; - public static final String TOKEN_STATIC_VARIATION = TOKEN_STATIC + " " + TOKEN_VARIATION; - public static final String TOKEN_SQUIRT = "Squirt"; - public static final String TOKEN_WIDTH = "Width"; - public static final String TOKEN_STATIC_WIDTH = TOKEN_STATIC + " " + TOKEN_WIDTH; - public static final String TOKEN_LENGTH = "Length"; - public static final String TOKEN_STATIC_LENGTH = TOKEN_STATIC + " " + TOKEN_LENGTH; - public static final String TOKEN_ROWS = "Rows"; - public static final String TOKEN_COLUMNS = "Columns"; - public static final String TOKEN_HEAD = "Head"; - public static final String TOKEN_TAIL = "Tail"; - public static final String TOKEN_BOTH = "Both"; - public static final String TOKEN_TAIL_LENGTH = "TailLength"; - public static final String TOKEN_TIME = "Time"; - public static final String TOKEN_SEGMENT_COLOR = "SegmentColor"; - public static final String TOKEN_PARTICLE_SCALING = "ParticleScaling"; - public static final String TOKEN_LIFE_SPAN_UV_ANIM = "LifeSpanUVAnim"; - public static final String TOKEN_DECAY_UV_ANIM = "DecayUVAnim"; - public static final String TOKEN_TAIL_UV_ANIM = "TailUVAnim"; - public static final String TOKEN_TAIL_DECAY_UV_ANIM = "TailDecayUVAnim"; - public static final String TOKEN_REPLACEABLE_ID = "ReplaceableId"; - public static final String TOKEN_BLEND = "Blend";// ParticleEmitter2.FilterMode.BLEND.getMdlText(); - public static final String TOKEN_ADDITIVE = "Additive";// ParticleEmitter2.FilterMode.ADDITIVE.getMdlText(); - public static final String TOKEN_MODULATE = "Modulate";// ParticleEmitter2.FilterMode.MODULATE.getMdlText(); - public static final String TOKEN_MODULATE2X = "Modulate2x";// ParticleEmitter2.FilterMode.MODULATE2X.getMdlText(); - public static final String TOKEN_ALPHAKEY = "AlphaKey";// ParticleEmitter2.FilterMode.ALPHAKEY.getMdlText(); - - public static final String TOKEN_HEIGHT_ABOVE = "HeightAbove"; - public static final String TOKEN_STATIC_HEIGHT_ABOVE = TOKEN_STATIC + " " + TOKEN_HEIGHT_ABOVE; - public static final String TOKEN_HEIGHT_BELOW = "HeightBelow"; - public static final String TOKEN_STATIC_HEIGHT_BELOW = TOKEN_STATIC + " " + TOKEN_HEIGHT_BELOW; - public static final String TOKEN_TEXTURE_SLOT = "TextureSlot"; - public static final String TOKEN_STATIC_TEXTURE_SLOT = TOKEN_STATIC + " " + TOKEN_TEXTURE_SLOT; - - public static final String TOKEN_TEXTURES = "Textures"; - public static final String TOKEN_MATERIALS = "Materials"; - public static final String TOKEN_TEXTURE_ANIMS = "TextureAnims"; - public static final String TOKEN_PIVOT_POINTS = "PivotPoints"; - - public static final String TOKEN_ATTACHMENT = "Attachment"; - public static final String TOKEN_BONE = "Bone"; - public static final String TOKEN_CAMERA = "Camera"; - public static final String TOKEN_COLLISION_SHAPE = "CollisionShape"; - public static final String TOKEN_EVENT_OBJECT = "EventObject"; - public static final String TOKEN_GEOSET = "Geoset"; - public static final String TOKEN_GEOSETANIM = "GeosetAnim"; - public static final String TOKEN_HELPER = "Helper"; - public static final String TOKEN_LAYER = "Layer"; - public static final String TOKEN_LIGHT = "Light"; - public static final String TOKEN_MATERIAL = "Material"; - public static final String TOKEN_PARTICLE_EMITTER = "ParticleEmitter"; - public static final String TOKEN_PARTICLE_EMITTER2 = "ParticleEmitter2"; - public static final String TOKEN_RIBBON_EMITTER = "RibbonEmitter"; - - // > 800 - - public static final String TOKEN_EMISSIVE_GAIN = "EmissiveGain"; - public static final String TOKEN_FRESNEL_COLOR = "FresnelColor"; - public static final String TOKEN_FRESNEL_OPACITY = "FresnelOpacity"; - public static final String TOKEN_FRESNEL_TEAM_COLOR = "FresnelTeamColor"; -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxFloatArrayTimeline.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxFloatArrayTimeline.java deleted file mode 100644 index d877dd44..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxFloatArrayTimeline.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx.timeline; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public final class MdlxFloatArrayTimeline extends MdlxTimeline { - private final int arraySize; - - public MdlxFloatArrayTimeline(final int arraySize) { - this.arraySize = arraySize; - } - - @Override - protected int size() { - return arraySize; - } - - @Override - protected float[] readMdxValue(final BinaryReader reader) { - return reader.readFloat32Array(arraySize); - } - - @Override - protected float[] readMdlValue(final MdlTokenInputStream stream) { - final float[] output = new float[arraySize]; - stream.readKeyframe(output); - return output; - } - - @Override - protected void writeMdxValue(final BinaryWriter writer, final float[] value) { - writer.writeFloat32Array(value); - } - - @Override - protected void writeMdlValue(final MdlTokenOutputStream stream, final String prefix, final float[] value) { - stream.writeKeyframe(prefix, value); - } - - public int getArraySize() { - return arraySize; - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxFloatTimeline.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxFloatTimeline.java deleted file mode 100644 index ad5ac52b..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxFloatTimeline.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx.timeline; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public final class MdlxFloatTimeline extends MdlxTimeline { - @Override - protected int size() { - return 1; - } - - @Override - protected float[] readMdxValue(final BinaryReader reader) { - return new float[] { reader.readFloat32() }; - } - - @Override - protected float[] readMdlValue(final MdlTokenInputStream stream) { - return new float[] { stream.readFloat() }; - } - - @Override - protected void writeMdxValue(final BinaryWriter writer, final float[] value) { - writer.writeFloat32(value[0]); - } - - @Override - protected void writeMdlValue(final MdlTokenOutputStream stream, final String prefix, final float[] value) { - stream.writeKeyframe(prefix, value[0]); - } -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxTimeline.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxTimeline.java deleted file mode 100644 index a6777913..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxTimeline.java +++ /dev/null @@ -1,216 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx.timeline; - -import com.etheller.warsmash.util.War3ID; -import com.hiveworkshop.rms.parsers.mdlx.AnimationMap; -import com.hiveworkshop.rms.parsers.mdlx.InterpolationType; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlUtils; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public abstract class MdlxTimeline { - public War3ID name; - public InterpolationType interpolationType; - public int globalSequenceId = -1; - - public long[] frames; - public TYPE[] values; - public TYPE[] inTans; - public TYPE[] outTans; - - /** - * Restricts us to only be able to parse models on one thread at a time, in - * return for high performance. - */ - private static final StringBuffer STRING_BUFFER_HEAP = new StringBuffer(); - - public MdlxTimeline() { - - } - - public void readMdx(final BinaryReader reader, final War3ID name) { - this.name = name; - - final long keyFrameCount = reader.readUInt32(); - - this.interpolationType = InterpolationType.getType(reader.readInt32()); - this.globalSequenceId = reader.readInt32(); - - this.frames = new long[(int) keyFrameCount]; - this.values = (TYPE[]) new Object[(int) keyFrameCount]; - if (this.interpolationType.tangential()) { - this.inTans = (TYPE[]) new Object[(int) keyFrameCount]; - this.outTans = (TYPE[]) new Object[(int) keyFrameCount]; - } - - for (int i = 0; i < keyFrameCount; i++) { - this.frames[i] = reader.readInt32(); - this.values[i] = (readMdxValue(reader)); - - if (this.interpolationType.tangential()) { - this.inTans[i] = (readMdxValue(reader)); - this.outTans[i] = (readMdxValue(reader)); - } - } - } - - public void writeMdx(final BinaryWriter writer) { - writer.writeTag(this.name.getValue()); - - final int keyframeCount = this.frames.length; - - writer.writeInt32(keyframeCount); - writer.writeInt32(this.interpolationType.ordinal()); - writer.writeInt32(this.globalSequenceId); - - for (int i = 0; i < keyframeCount; i++) { - writer.writeInt32((int) this.frames[i]); - writeMdxValue(writer, this.values[i]); - - if (this.interpolationType.tangential()) { - writeMdxValue(writer, this.inTans[i]); - writeMdxValue(writer, this.outTans[i]); - } - } - } - - public void readMdl(final MdlTokenInputStream stream, final War3ID name) { - this.name = name; - - final int keyFrameCount = stream.readInt(); - - stream.read(); // { - - final String token = stream.read(); - final InterpolationType interpolationType; - switch (token) { - case MdlUtils.TOKEN_DONT_INTERP: - interpolationType = InterpolationType.DONT_INTERP; - break; - case MdlUtils.TOKEN_LINEAR: - interpolationType = InterpolationType.LINEAR; - break; - case MdlUtils.TOKEN_HERMITE: - interpolationType = InterpolationType.HERMITE; - break; - case MdlUtils.TOKEN_BEZIER: - interpolationType = InterpolationType.BEZIER; - break; - default: - interpolationType = InterpolationType.DONT_INTERP; - break; - } - ; - - this.interpolationType = interpolationType; - - if (stream.peek().equals(MdlUtils.TOKEN_GLOBAL_SEQ_ID)) { - stream.read(); - this.globalSequenceId = stream.readInt(); - } - else { - this.globalSequenceId = -1; - } - - this.frames = new long[keyFrameCount]; - this.values = (TYPE[]) new Object[keyFrameCount]; - if (this.interpolationType.tangential()) { - this.inTans = (TYPE[]) new Object[keyFrameCount]; - this.outTans = (TYPE[]) new Object[keyFrameCount]; - } - for (int i = 0; i < keyFrameCount; i++) { - this.frames[i] = (stream.readInt()); - this.values[i] = (readMdlValue(stream)); - if (interpolationType.tangential()) { - stream.read(); // InTan - this.inTans[i] = (readMdlValue(stream)); - stream.read(); // OutTan - this.outTans[i] = (readMdlValue(stream)); - } - } - - stream.read(); // } - } - - public void writeMdl(final MdlTokenOutputStream stream) { - final int tracksCount = this.frames.length; - stream.startBlock(AnimationMap.ID_TO_TAG.get(this.name).getMdlToken(), tracksCount); - - stream.writeFlag(this.interpolationType.toString()); - - if (this.globalSequenceId != -1) { - stream.writeAttrib(MdlUtils.TOKEN_GLOBAL_SEQ_ID, this.globalSequenceId); - } - - for (int i = 0; i < tracksCount; i++) { - STRING_BUFFER_HEAP.setLength(0); - STRING_BUFFER_HEAP.append(this.frames[i]); - STRING_BUFFER_HEAP.append(':'); - writeMdlValue(stream, STRING_BUFFER_HEAP.toString(), this.values[i]); - if (this.interpolationType.tangential()) { - stream.indent(); - writeMdlValue(stream, "InTan", this.inTans[i]); - writeMdlValue(stream, "OutTan", this.outTans[i]); - stream.unindent(); - } - } - - stream.endBlock(); - } - - public long getByteLength() { - final int tracksCount = this.frames.length; - int size = 16; - - if (tracksCount > 0) { - final int bytesPerValue = size() * 4; - int valuesPerTrack = 1; - if (this.interpolationType.tangential()) { - valuesPerTrack = 3; - } - - size += (4 + (valuesPerTrack * bytesPerValue)) * tracksCount; - } - return size; - } - - protected abstract int size(); - - protected abstract TYPE readMdxValue(BinaryReader reader); - - protected abstract TYPE readMdlValue(MdlTokenInputStream stream); - - protected abstract void writeMdxValue(BinaryWriter writer, TYPE value); - - protected abstract void writeMdlValue(MdlTokenOutputStream stream, String prefix, TYPE value); - - public War3ID getName() { - return this.name; - } - - public InterpolationType getInterpolationType() { - return this.interpolationType; - } - - public int getGlobalSequenceId() { - return this.globalSequenceId; - } - - public long[] getFrames() { - return this.frames; - } - - public TYPE[] getValues() { - return this.values; - } - - public TYPE[] getInTans() { - return this.inTans; - } - - public TYPE[] getOutTans() { - return this.outTans; - } - -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxUInt32Timeline.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxUInt32Timeline.java deleted file mode 100644 index a80c197f..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/timeline/MdlxUInt32Timeline.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx.timeline; - -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenInputStream; -import com.hiveworkshop.rms.parsers.mdlx.mdl.MdlTokenOutputStream; -import com.hiveworkshop.rms.util.BinaryReader; -import com.hiveworkshop.rms.util.BinaryWriter; - -public final class MdlxUInt32Timeline extends MdlxTimeline { - @Override - protected int size() { - return 1; - } - - @Override - protected long[] readMdxValue(final BinaryReader reader) { - return new long[]{reader.readUInt32()}; - } - - @Override - protected long[] readMdlValue(final MdlTokenInputStream stream) { - return new long[]{stream.readUInt32()}; - } - - @Override - protected void writeMdxValue(final BinaryWriter writer, final long[] uint32) { - writer.writeUInt32(uint32[0]); - } - - @Override - protected void writeMdlValue(final MdlTokenOutputStream stream, final String prefix, final long[] uint32) { - stream.writeKeyframe(prefix, uint32[0]); - } - -} diff --git a/core/src/com/hiveworkshop/rms/parsers/mdlx/util/MdxUtils.java b/core/src/com/hiveworkshop/rms/parsers/mdlx/util/MdxUtils.java deleted file mode 100644 index db031f57..00000000 --- a/core/src/com/hiveworkshop/rms/parsers/mdlx/util/MdxUtils.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.hiveworkshop.rms.parsers.mdlx.util; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.ByteBuffer; - -import org.apache.commons.compress.utils.IOUtils; - -import com.hiveworkshop.rms.parsers.mdlx.MdlxModel; - -public class MdxUtils { - public static MdlxModel loadMdlx(final InputStream inputStream) throws IOException { - return new MdlxModel(ByteBuffer.wrap(IOUtils.toByteArray(inputStream))); - } - - public static void saveMdx(final MdlxModel model, final OutputStream outputStream) throws IOException { - outputStream.write(model.saveMdx().array()); - } - - public static void saveMdl(final MdlxModel model, final OutputStream outputStream) throws IOException { - outputStream.write(model.saveMdl().array()); - } - - public static void saveMdl(final MdlxModel model, final File file) throws IOException { - saveMdl(model, new FileOutputStream(file)); - } - -} diff --git a/core/src/com/hiveworkshop/rms/util/BinaryReader.java b/core/src/com/hiveworkshop/rms/util/BinaryReader.java deleted file mode 100644 index eb6affdd..00000000 --- a/core/src/com/hiveworkshop/rms/util/BinaryReader.java +++ /dev/null @@ -1,216 +0,0 @@ -package com.hiveworkshop.rms.util; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -public class BinaryReader { - ByteBuffer buffer; - - public BinaryReader(final ByteBuffer buffer) { - buffer.order(ByteOrder.LITTLE_ENDIAN); - buffer.position(0); - - this.buffer = buffer; - } - - public int remaining() { - return this.buffer.remaining(); - } - - public int position() { - return this.buffer.position(); - } - - public void position(final int newPosition) { - this.buffer.position(newPosition); - } - - public void move(final int offset) { - this.buffer.position(this.buffer.position() + offset); - } - - public String read(final int count) { - final StringBuilder value = new StringBuilder(); - - for (int i = 0; i < count; i++) { - final byte b = this.buffer.get(); - - if (b != 0) { - value.append((char) (b & 0xFF)); - } - } - - return value.toString(); - } - - public String readBytes(final int count) { - final StringBuilder value = new StringBuilder(); - - for (int i = 0; i < count; i++) { - value.append((char) (this.buffer.get() & 0xFF)); - } - - return value.toString(); - } - - public String readUntilNull() { - final StringBuilder value = new StringBuilder(); - byte b = this.buffer.get(); - - while (b != 0) { - value.append((char) (b & 0xFF)); - - b = this.buffer.get(); - } - - return value.toString(); - } - - public byte readInt8() { - return this.buffer.get(); - } - - public short readInt16() { - return this.buffer.getShort(); - } - - public int readInt32() { - return this.buffer.getInt(); - } - - public long readInt64() { - return this.buffer.getLong(); - } - - public short readUInt8() { - return (short) Byte.toUnsignedInt(this.buffer.get()); - } - - public int readUInt16() { - return Short.toUnsignedInt(this.buffer.getShort()); - } - - public long readUInt32() { - return Integer.toUnsignedLong(this.buffer.getInt()); - } - - public float readFloat32() { - return this.buffer.getFloat(); - } - - public double readFloat64() { - return this.buffer.getDouble(); - } - - public byte[] readInt8Array(final byte[] out) { - for (int i = 0, l = out.length; i < l; i++) { - out[i] = readInt8(); - } - - return out; - } - - public byte[] readInt8Array(final int count) { - return readInt8Array(new byte[count]); - } - - public short[] readInt16Array(final short[] out) { - for (int i = 0, l = out.length; i < l; i++) { - out[i] = readInt16(); - } - - return out; - } - - public short[] readInt16Array(final int count) { - return readInt16Array(new short[count]); - } - - public int[] readInt32Array(final int[] out) { - for (int i = 0, l = out.length; i < l; i++) { - out[i] = readInt32(); - } - - return out; - } - - public int[] readInt32Array(final int count) { - return readInt32Array(new int[count]); - } - - public long[] readInt64Array(final long[] out) { - for (int i = 0, l = out.length; i < l; i++) { - out[i] = readInt64(); - } - - return out; - } - - public long[] readInt64Array(final int count) { - return readInt64Array(new long[count]); - } - - public short[] readUInt8Array(final short[] out) { - for (int i = 0, l = out.length; i < l; i++) { - out[i] = readUInt8(); - } - - return out; - } - - public short[] readUInt8Array(final int count) { - return readUInt8Array(new short[count]); - } - - public int[] readUInt16Array(final int[] out) { - for (int i = 0, l = out.length; i < l; i++) { - out[i] = readUInt16(); - } - - return out; - } - - public int[] readUInt16Array(final int count) { - return readUInt16Array(new int[count]); - } - - public long[] readUInt32Array(final long[] out) { - for (int i = 0, l = out.length; i < l; i++) { - out[i] = readUInt32(); - } - - return out; - } - - public long[] readUInt32Array(final int count) { - return readUInt32Array(new long[count]); - } - - public float[] readFloat32Array(final float[] out) { - for (int i = 0, l = out.length; i < l; i++) { - out[i] = readFloat32(); - } - - return out; - } - - public float[] readFloat32Array(final int count) { - return readFloat32Array(new float[count]); - } - - public double[] readFloat64Array(final double[] out) { - for (int i = 0, l = out.length; i < l; i++) { - out[i] = readFloat64(); - } - - return out; - } - - public double[] readFloat64Array(final int count) { - return readFloat64Array(new double[count]); - } - - public int readTag() { - return Integer.reverseBytes(readInt32()); - } -} diff --git a/core/src/com/hiveworkshop/rms/util/BinaryWriter.java b/core/src/com/hiveworkshop/rms/util/BinaryWriter.java deleted file mode 100644 index a56277c7..00000000 --- a/core/src/com/hiveworkshop/rms/util/BinaryWriter.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.hiveworkshop.rms.util; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -public class BinaryWriter { - public ByteBuffer buffer; - - public BinaryWriter(final int capacity) { - this.buffer = ByteBuffer.allocate(capacity); - this.buffer.order(ByteOrder.LITTLE_ENDIAN); - } - - public int remaining() { - return this.buffer.remaining(); - } - - public int position() { - return this.buffer.position(); - } - - public void position(final int newPosition) { - this.buffer.position(newPosition); - } - - public void move(final int offset) { - this.buffer.position(this.buffer.position() + offset); - } - - public void write(final String value) { - writeInt8Array(value.getBytes()); - } - - public void writeWithNulls(final String value, final int length) { - final byte[] bytes = value.getBytes(); - final int nulls = length - bytes.length; - - writeInt8Array(bytes); - - if (nulls > 0) { - for (int i = 0; i < nulls; i++) { - writeInt8((byte) 0); - } - } - } - - public void writeInt8(final byte value) { - this.buffer.put(value); - } - - public void writeInt16(final short value) { - this.buffer.putShort(value); - } - - public void writeInt32(final int value) { - this.buffer.putInt(value); - } - - public void writeInt64(final long value) { - this.buffer.putLong(value); - } - - public void writeUInt8(final short value) { - this.buffer.put((byte) value); - } - - public void writeUInt16(final int value) { - this.buffer.putShort((short) value); - } - - public void writeUInt32(final long value) { - this.buffer.putInt((int) value); - } - - public void writeFloat32(final float value) { - this.buffer.putFloat(value); - } - - public void writeFloat64(final double value) { - this.buffer.putDouble(value); - } - - public void writeInt8Array(final byte[] values) { - for (final byte value : values) { - writeInt8(value); - } - } - - public void writeInt16Array(final short[] values) { - for (final short value : values) { - writeInt16(value); - } - } - - public void writeInt32Array(final int[] values) { - for (final int value : values) { - writeInt32(value); - } - } - - public void writeInt64Array(final long[] values) { - for (final long value : values) { - writeInt64(value); - } - } - - public void writeUInt8Array(final short[] values) { - for (final short value : values) { - writeUInt8(value); - } - } - - public void writeUInt16Array(final int[] values) { - for (final int value : values) { - writeUInt16(value); - } - } - - public void writeUInt32Array(final long[] values) { - for (final long value : values) { - writeUInt32(value); - } - } - - public void writeFloat32Array(final float[] values) { - for (final float value : values) { - writeFloat32(value); - } - } - - public void writeFloat64Array(final double[] values) { - for (final double value : values) { - writeFloat64(value); - } - } - - public void writeTag(final int tag) { - writeInt32(Integer.reverseBytes(tag)); - } -} diff --git a/core/src/com/hiveworkshop/rms/util/Descriptor.java b/core/src/com/hiveworkshop/rms/util/Descriptor.java deleted file mode 100644 index 654533c3..00000000 --- a/core/src/com/hiveworkshop/rms/util/Descriptor.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.hiveworkshop.rms.util; - -public interface Descriptor { - E create(); - -} diff --git a/core/src/mpq/ArchivedFile.java b/core/src/mpq/ArchivedFile.java deleted file mode 100644 index 39fa3fd5..00000000 --- a/core/src/mpq/ArchivedFile.java +++ /dev/null @@ -1,132 +0,0 @@ -package mpq; - -import java.io.IOException; -import java.io.Serializable; -import java.nio.ByteBuffer; -import java.nio.channels.SeekableByteChannel; - -import mpq.data.RawArrays; -import mpq.util.Cryption; - -public class ArchivedFile implements Serializable { - private static final long serialVersionUID = 5033693351138253083L; - - // CRC is Adler? - // CRC requires version safety check. - // Specification is unclear when [CRC block size > archive block size]. Assuming this never happens. May need to handle as special case. - // Specification is unclear when [(file is single unit) equals TRUE AND (file uses CRC) equals TRUE]. Assuming flag is ignored. - // Single Unit requires version safety check. - - public boolean ready; - public final int blockShift; - public final int compressedSize; - public final int fileSize; - public final int flags; - public final long fileOffset; - public final int[] blockOffsets; - public int[] blockChecksums = null; - public final int key; - public final byte compression; - - public ArchivedFile( MPQArchive archive, HashLookup search, BlockTable.Entry file ) throws MPQException{ - // *** load simple values - compressedSize = file.compressedSize; - fileSize = file.fileSize; - flags = file.flags; - fileOffset = file.filePosition + archive.getArchiveOffset(); - - // *** load complex values - if( hasFlag(BlockTable.FLAG_SINGLE_UNIT) ) blockShift = -fileSize; - else blockShift = archive.getBlockShift(); - - if( hasFlag(BlockTable.FLAG_ENCRYPTED) ){ - int key = Cryption.HashString(search.lookup, Cryption.MPQ_HASH_FILE_KEY); - if( hasFlag(BlockTable.FLAG_FIX_KEY) ){ - key = Cryption.adjustFileDecryptKey(key, file.getFilePosition(), file.getFileSize()); - } - this.key = key; - }else - key = 0; - - if( hasFlag(BlockTable.FLAG_COMPRESS | BlockTable.FLAG_IMPLODE) ){ - // blocks cannot be both compressed and imploded - if( hasFlag(BlockTable.FLAG_COMPRESS) && hasFlag(BlockTable.FLAG_IMPLODE) ) throw new MPQException("invalid block: a block is both compressed and imploded"); - - // determine the type of sector compression to use - if( hasFlag(BlockTable.FLAG_COMPRESS) ){ - if( archive.getVersion() > 1 ) compression = 3; - else compression = 2; - }else{ - compression = 1; - } - - // all compressed files use sector tables for standardization - // single unit files have a known table - if( hasFlag(BlockTable.FLAG_SINGLE_UNIT) ){ - - blockOffsets = new int[2]; - blockOffsets[1] = compressedSize; - blockChecksums = null; - ready = true; - // table will need to be looked up - }else{ - int blockn = (fileSize + (512 << blockShift) - 1) / (512 << blockShift); - - // if CRC is used, there is an additional checksum sector with checksums for all other sectors. - if( hasFlag(BlockTable.FLAG_SECTOR_CRC) ) blockn+= 1; - - blockOffsets = new int[blockn+1]; - ready = false; - } - }else{ - compression = 0; - blockOffsets = null; - ready = true; - } - } - - public void loadOffsets( SeekableByteChannel in ) throws IOException, MPQException{ - // read sector table from file - ByteBuffer temp = ByteBuffer.allocate(blockOffsets.length * 4); - in.position( fileOffset ); - while( temp.hasRemaining() ) - if( in.read(temp) == -1 ) - break; - temp.rewind(); - - // decrypt if required - if( hasFlag(BlockTable.FLAG_ENCRYPTED) ){ - Cryption.decryptData(temp, temp, key - 1); - } - - // interpret sector table - RawArrays.getArray(temp, blockOffsets); - - // validate offsets in case of corruption - if( blockOffsets[0] >= 0 && blockOffsets[0] < blockOffsets.length * 4 || - blockOffsets[0] < 0 && blockOffsets[blockOffsets.length - 1] > 0 ) throw new MPQException("block sector intersects sector offset table"); - else if( blockOffsets[0] < 0 || blockOffsets[0] > blockOffsets.length * 4 ) - System.err.printf("block at %X has detached sectors starting at %X (%d bytes from end of sector table)%n", - fileOffset, fileOffset + blockOffsets[0], blockOffsets[0] - blockOffsets.length * 4); - if( fileOffset + blockOffsets[0] < 0 || fileOffset + blockOffsets[blockOffsets.length - 1] > in.size() ) - throw new MPQException("block sector located outside channel"); - for( int i = 1, prevoff = blockOffsets[0] ; i < blockOffsets.length ; i+= 1){ - int curroff = blockOffsets[i]; - if( curroff < prevoff ) throw new MPQException("block sector with negative size"); - prevoff = curroff; - } - - // load CRC sector if present - if( hasFlag(BlockTable.FLAG_SECTOR_CRC) && blockOffsets[blockOffsets.length - 1] != blockOffsets[blockOffsets.length - 2] ){ - System.err.println("block sector CRC reading currently not supported"); - } - - ready = true; - } - - public boolean hasFlag(int flag){ - return (flags & flag) != 0; - } -} - - diff --git a/core/src/mpq/ArchivedFileExtractor.java b/core/src/mpq/ArchivedFileExtractor.java deleted file mode 100644 index 7703f610..00000000 --- a/core/src/mpq/ArchivedFileExtractor.java +++ /dev/null @@ -1,66 +0,0 @@ -package mpq; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.SeekableByteChannel; - -import mpq.compression.Compression; -import mpq.util.Cryption; - -public class ArchivedFileExtractor { - private Compression decompress = new Compression(); - - public ByteBuffer readBlock(ByteBuffer bufferold, SeekableByteChannel in, ArchivedFile file, int block) throws IOException, MPQException{ - // *** calculate the current block size - int currentSize; - if( file.fileSize < (block + 1) * bufferold.capacity() ) - currentSize = file.fileSize % bufferold.capacity(); - else - currentSize = bufferold.capacity(); - - // *** read block - if( file.blockOffsets != null ){ - // use block offset table - if( !file.ready ){ - file.loadOffsets(in); - } - bufferold.limit(file.blockOffsets[block+1] - file.blockOffsets[block]); - in.position(file.fileOffset + file.blockOffsets[block]); - }else{ - // compute offset - bufferold.limit(currentSize); - in.position(file.fileOffset + bufferold.capacity() * block); - } - while( bufferold.hasRemaining() ) - if( in.read(bufferold) == -1 ) - break; - bufferold.rewind(); - - // *** decrypt if required - if( file.key != 0 ){ - Cryption.decryptData(bufferold, bufferold, file.key + block); - } - - // *** CRC check goes here - if( file.blockChecksums != null ){ - // TODO add support for CRC - System.err.println("block sector CRC validation currently not supported"); - } - - // *** decompress if required - if( file.compression > 0 ){ - // only decompress if block is compressed - if( bufferold.limit() < currentSize ){ - // decompress block - if( file.compression >= 3 ){ - bufferold = decompress.blockDecompress3(bufferold, file.blockShift); - }else if( file.compression == 2 ){ - bufferold = decompress.blockDecompress2(bufferold, file.blockShift); - }else{ - bufferold = decompress.blockDecompress1(bufferold, file.blockShift); - } - } - } - return bufferold; - } -} diff --git a/core/src/mpq/ArchivedFileStream.java b/core/src/mpq/ArchivedFileStream.java deleted file mode 100644 index 3776105f..00000000 --- a/core/src/mpq/ArchivedFileStream.java +++ /dev/null @@ -1,131 +0,0 @@ -package mpq; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.ClosedChannelException; -import java.nio.channels.NonWritableChannelException; -import java.nio.channels.SeekableByteChannel; - -public class ArchivedFileStream implements SeekableByteChannel{ - private boolean open; - private SeekableByteChannel from; - private ByteBuffer buffer; - private ArchivedFile file; - private ArchivedFileExtractor extractor; - private long position; - private int currentBlock; - - public ArchivedFileStream(SeekableByteChannel in, ArchivedFileExtractor extractor, ArchivedFile file){ - from = in; - this.extractor = extractor; - this.file = file; - if( file.hasFlag(BlockTable.FLAG_SINGLE_UNIT) ){ - buffer = ByteBuffer.allocate(file.fileSize); - }else{ - buffer = ByteBuffer.allocate(512 << file.blockShift); - } - position = 0; - currentBlock = -1; - open = true; - } - - @Override - public void close() throws IOException { - from = null; - buffer = null; - open = false; - } - - @Override - public boolean isOpen() { - return open; - } - - @Override - public long position() throws IOException { - return position; - } - - @Override - public SeekableByteChannel position(long newPosition) - throws IOException { - // *** argument validation as described by SeekableByteChannel interface - if( newPosition < 0 ) throw new IllegalArgumentException("files cannot have a negative positon"); - - // update stream position - position = newPosition; - // try and update the buffer position of loaded sectors - if( currentBlock != -1 ){ - if( currentBlock != newPosition / buffer.capacity() ) - currentBlock = -1; - else - buffer.position((int) (newPosition % buffer.capacity())); - } - - // *** return value as described by SeekableByteChannel interface - return this; - } - - @Override - public int read(ByteBuffer dst) throws IOException { - // closed - if( !open ) throw new ClosedChannelException(); - // end of stream - if( position >= file.fileSize ) return -1; - - // load current block if no block is currently loaded - if( currentBlock == -1 ){ - currentBlock = (int) (position / buffer.capacity()); - buffer.clear(); - try { - buffer = extractor.readBlock(buffer, from, file, currentBlock); - } catch (MPQException e) { - throw new IOException(e); - } - buffer.position((int) (position % buffer.capacity())); - - } - - long positionstart = position; - while( dst.hasRemaining() ){ - if( buffer.remaining() > dst.remaining() ){ - int limit = buffer.limit(); - buffer.limit(buffer.position() + dst.remaining()); - position+= buffer.remaining(); - dst.put(buffer); - buffer.limit(limit); - }else{ - position+= buffer.remaining(); - dst.put(buffer); - if(position < file.fileSize){ - currentBlock = (int) (position / buffer.capacity()); - buffer.clear(); - try { - buffer = extractor.readBlock(buffer, from, file, currentBlock); - } catch (MPQException e) { - throw new IOException(e); - } - }else{ - break; - } - } - } - - return (int) (position - positionstart); - } - - @Override - public long size() throws IOException { - return file.fileSize; - } - - @Override - public SeekableByteChannel truncate(long size) throws IOException { - throw new NonWritableChannelException(); - } - - @Override - public int write(ByteBuffer src) throws IOException { - throw new NonWritableChannelException(); - } -} diff --git a/core/src/mpq/BlockTable.java b/core/src/mpq/BlockTable.java deleted file mode 100644 index 6d8f64f7..00000000 --- a/core/src/mpq/BlockTable.java +++ /dev/null @@ -1,78 +0,0 @@ -package mpq; - -import mpq.data.BlockTableEntry; - -public class BlockTable { - public static final int FLAG_IMPLODE = 0x00000100; - public static final int FLAG_COMPRESS = 0x00000200; - public static final int FLAG_ENCRYPTED = 0x00010000; - public static final int FLAG_FIX_KEY = 0x00020000; - public static final int FLAG_PATCH_FILE = 0x00100000; - public static final int FLAG_SINGLE_UNIT = 0x01000000; - public static final int FLAG_DELETE_MARKER = 0x02000000; - public static final int FLAG_SECTOR_CRC = 0x04000000; - public static final int FLAG_EXISTS = 0x80000000; - - private Entry[] tableArray; - - // raw constructor, expects all entries to be non-null. - public BlockTable(Entry[] entries){ - tableArray = entries; - } - - public Entry lookupEntry(int entry){ - return tableArray[entry]; - } - - public static String flagsToString(int source){ - return ( (source&FLAG_IMPLODE) != 0 ? "IMPLODE " : "" )+ - ( (source&FLAG_COMPRESS) != 0 ? "COMPRESS " : "" )+ - ( (source&FLAG_ENCRYPTED) != 0 ? "ENCRYPTED " : "" )+ - ( (source&FLAG_FIX_KEY) != 0 ? "FIX_KEY " : "" )+ - ( (source&FLAG_PATCH_FILE) != 0 ? "PATCH_FILE " : "" )+ - ( (source&FLAG_SINGLE_UNIT) != 0 ? "SINGLE_UNIT " : "" )+ - ( (source&FLAG_DELETE_MARKER) != 0 ? "DELETE_MARKER " : "" )+ - ( (source&FLAG_SECTOR_CRC) != 0 ? "SECTOR_CRC " : "" )+ - ( (source&FLAG_EXISTS) != 0 ? "EXISTS " : "" ); - } - - - public static class Entry{ - public long filePosition; - public int compressedSize; - public int fileSize; - public int flags; - - public Entry(BlockTableEntry source){ - filePosition = source.getFilePosition(); - compressedSize = source.getCompressedSize(); - fileSize = source.getFileSize(); - flags = source.getFlags(); - } - - // raw constructor for data field - public Entry(){ - } - - public int getFilePosition() { - return (int) filePosition; - } - - public int getCompressedSize() { - return compressedSize; - } - - public int getFileSize() { - return fileSize; - } - - public int getFlags() { - return flags; - } - - public boolean hasFlag(int flag){ - return (flags & flag) != 0; - } - - } -} diff --git a/core/src/mpq/HashLookup.java b/core/src/mpq/HashLookup.java deleted file mode 100644 index 33a384cb..00000000 --- a/core/src/mpq/HashLookup.java +++ /dev/null @@ -1,35 +0,0 @@ -package mpq; - -import java.io.Serializable; - -import mpq.util.Cryption; - -public class HashLookup implements Serializable { - private static final long serialVersionUID = -731458056988218435L; - - public final byte[] lookup; - public final long hash; - public final int index; - - public HashLookup(String path){ - // *** convert string to 8 bit ascii - byte[] raw = Cryption.stringToHashable(path); - - // *** generate hashtable lookup arguments - hash = Cryption.HashString(raw, Cryption.MPQ_HASH_NAME_A) & 0xFFFFFFFFL | (long)Cryption.HashString(raw, Cryption.MPQ_HASH_NAME_B)<<32; - index = Cryption.HashString(raw, Cryption.MPQ_HASH_TABLE_OFFSET); - - // *** find file name - int index = 0; - for( int i = raw.length ; --i >= 0 ; ){ - if( raw[i] == (byte) '\\' || raw[i] == (byte) '/' ){ - index = i + 1; - break; - } - } - - // *** save raw ascii file name in-case file is encrypted - lookup = new byte[raw.length - index]; - System.arraycopy(raw, index, lookup, 0, lookup.length); - } -} diff --git a/core/src/mpq/HashTable.java b/core/src/mpq/HashTable.java deleted file mode 100644 index aa0174ff..00000000 --- a/core/src/mpq/HashTable.java +++ /dev/null @@ -1,82 +0,0 @@ -package mpq; - -import mpq.data.HashTableEntry; - -public class HashTable { - public static final int BLOCK_EMPTY_ALWAYS = 0xFFFFFFFF; - public static final int BLOCK_EMPTY_NOW = 0xFFFFFFFE; - private Entry[] bucketArray; - - // raw constructor, assumes every entry is not null and the array is a power of 2 - public HashTable(Entry[] entries){ - bucketArray = entries; - } - - public int lookupBlock(HashLookup what) throws MPQException{ - int mask = bucketArray.length-1; - int index = what.index & mask; - for(int pos = index ; ; ){ - Entry temp = bucketArray[pos]; - if(temp.blockIndex == BLOCK_EMPTY_ALWAYS) break; - if(temp.getHash() == what.hash) return temp.blockIndex; - pos = ( pos + 1 ) & mask; - if(pos == index) break; - } - throw new MPQException("lookup not found"); - } - - /*public static int lookupBlock(Entry[] hashtable, byte[] file) throws FileNotFoundException{ - int mask = hashtable.length-1; - int index = Cryption.HashString(file, Cryption.MPQ_HASH_TABLE_OFFSET) & mask; - long hash = Cryption.HashString(file, Cryption.MPQ_HASH_NAME_A) & 0xFFFFFFFFL | (long)Cryption.HashString(file, Cryption.MPQ_HASH_NAME_B)<<32; - for(int pos = index ; ; ){ - Entry temp = hashtable[pos]; - if(temp.getBlockIndex() == BLOCK_EMPTY_ALWAYS) break; - if(temp.getHash() == hash) return temp.getBlockIndex(); - pos = ( pos + 1 ) & mask; - if(pos == index) break; - } - throw new FileNotFoundException("hash not in hashtable"); - }*/ - - /*public static int lookupBlock(Entry[] hashtable, String file) throws FileNotFoundException{ - return lookupBlock(hashtable, Cryption.stringToHashable(file)); - }*/ - - // entry is an internal data type and as such performs no safety checks - public static class Entry{ - public long hash; - public short locale; - public short platform; - public int blockIndex; - - // raw constructor - public Entry(){ - } - - public Entry(HashTableEntry source){ - hash = source.getHash(); - locale = source.getLocale(); - platform = source.getPlatform(); - blockIndex = source.getBlockIndex(); - } - - public long getHash() { - return hash; - } - - public short getLocale() { - return locale; - } - - public short getPlatform() { - return platform; - } - - public int getBlockIndex() { - return blockIndex; - } - - - } -} diff --git a/core/src/mpq/MPQArchive.java b/core/src/mpq/MPQArchive.java deleted file mode 100644 index db05042f..00000000 --- a/core/src/mpq/MPQArchive.java +++ /dev/null @@ -1,291 +0,0 @@ -package mpq; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.SeekableByteChannel; - -import mpq.compression.Compression; -import mpq.data.BlockTableEntry; -import mpq.data.FileHeader; -import mpq.data.HashTableEntry; -import mpq.data.ArchiveHeader; -import mpq.data.RawArrays; -import mpq.data.UserDataHeader; -import mpq.util.Cryption; - -public class MPQArchive { - private long archiveOffset; - private short blockShift; - private HashTable hashTable; - private BlockTable blockTable; - private short version; - private long archiveSize; - - // locates the archive header from within a SeekableByteChannel - private ArchiveHeader locateArchive(SeekableByteChannel in) throws IOException, MPQException{ - // *** find MPQ archive header - // allocate a buffer and header interpreter - ByteBuffer buffer = ByteBuffer.allocate(FileHeader.STRUCT_SIZE); - FileHeader header = new FileHeader(buffer); - - // look for the header positioned at 512 bytes - archiveOffset = in.position() & ~(512 - 1); - for(;;){ - // read in possible header data - in.position(archiveOffset); - while( buffer.hasRemaining() ) - if( in.read(buffer) == -1 ) - throw new MPQException("channel does not contain a MPQ archive"); - buffer.clear(); - - // check header validity - if( header.getIdentifierInt() == FileHeader.ARCHIVE_IDENTIFIER_INT ) break; - // if user data header is found, extract archive header offset and continue - else if( header.getIdentifierInt() == FileHeader.USERDATA_IDENTIFIER_INT ){ - ByteBuffer temp = ByteBuffer.allocate(header.getHeaderSize()); - UserDataHeader udheader = new UserDataHeader(temp); - - while( temp.hasRemaining() ) - if( in.read(temp) == -1 ) - break; - - archiveOffset+= udheader.getArchiveOffset(); - continue; - } - - // prepare buffer for next operation and skip to next 512 bytes - archiveOffset+= 512; - } - - // *** load MPQ archive header - // allocate a buffer and archive header interpreter - int size = header.getHeaderSize() - FileHeader.STRUCT_SIZE; - // place a reasonable 8KB limit to archive header size - if( size > 1 << 13 || size < 0 ) size = 1 << 13; - buffer = ByteBuffer.allocate(size); - ArchiveHeader archiveheader = new ArchiveHeader(buffer); - - // read in archive header bytes - while( buffer.hasRemaining() ) - if( in.read(buffer) == -1 ) - break; - - return archiveheader; - } - - // - private void deserializeHashTable(SeekableByteChannel in, ArchiveHeader archiveheader) throws IOException, MPQException{ - // *** deserialize header - // version 1 - long htoffset = (long) archiveheader.getHashTablePosition() & 0xFFFFFFFFL; - int htsize = archiveheader.getHashTableSize(); - int rsize = htsize * HashTableEntry.STRUCT_SIZE; - // version 2 - if( version >= 1 ){ - htoffset|= ((long) archiveheader.getHashTablePositionHigh() & 0xFFFFL) << 32; - } - // version 3 - int csize; - if( version >= 3 ){ - csize = (int) archiveheader.getHashTableSizeCompressed(); - }else{ - csize = rsize; - } - - // *** validate hashtable - // no hashtable to load - if( htoffset == 0 ){ - hashTable = null; - return; - // hashtable size not power of 2 - }else if( (htsize & htsize - 1) != 0 ) - throw new MPQException("hashtable was not power of two ( was " + htsize + " )"); - - // *** read MPQ archive hashtable - ByteBuffer buffer = ByteBuffer.allocate(rsize); - buffer.limit(csize); - in.position(htoffset + archiveOffset); - while( buffer.hasRemaining() ) - if( in.read(buffer) == -1 ) - break; - buffer.rewind(); - - // *** decrypt hashtable - Cryption.decryptData(buffer, buffer, Cryption.KEY_HASH_TABLE); - - // *** decompress hashtable - if( csize < rsize ){ - buffer = new Compression().blockDecompressAny(buffer, ByteBuffer.allocate(rsize)); - if( buffer.limit() != buffer.capacity() ) System.err.println("hashtable decompressed size did not match expected size"); - } - - // *** deserialize hashtable - HashTable.Entry[] entries = new HashTable.Entry[htsize]; - HashTableEntry htentry = new HashTableEntry(); - for( int i = 0 ; i < htsize ; i+= 1 ){ - htentry.move(buffer); - HashTable.Entry tempentry = new HashTable.Entry(); - tempentry.hash = htentry.getHash(); - tempentry.locale = htentry.getLocale(); - tempentry.platform = htentry.getPlatform(); - tempentry.blockIndex = htentry.getBlockIndex(); - entries[i] = tempentry; - buffer.position(buffer.position() + HashTableEntry.STRUCT_SIZE); - } - hashTable = new HashTable(entries); - } - - private void deserializeBlockTable(SeekableByteChannel in, ArchiveHeader archiveheader) throws IOException, MPQException{ - // *** deserialize header - // version 1 - long btoffset = (long) archiveheader.getBlockTablePosition() & 0xFFFFFFFFL; - int btsize = archiveheader.getBlockTableSize(); - int rsize = btsize * BlockTableEntry.STRUCT_SIZE; - // version 2 - long hbtoffset; - int rhsize; - if( version >= 1 ){ - hbtoffset = archiveheader.getHighBlockTablePosition(); - rhsize = btsize * 2; - btoffset|= ((long) archiveheader.getBlockTablePositionHigh() & 0xFFFFL) << 32; - }else{ - hbtoffset = 0; - rhsize = 0; - } - // version 4 - int csize; - int chsize; - if( version >= 3 ){ - csize = (int) archiveheader.getBlockTableSizeCompressed(); - chsize = (int) archiveheader.getHighBlockTableSizeCompressed(); - }else{ - csize = rsize; - chsize = rhsize; - } - - // *** validate blocktable - // no blocktable to load - if( btoffset == 0 ){ - blockTable = null; - return; - // blocktable size clamp - }else if( btsize > 1 << 20 || btsize < 0 ){ - System.err.println("blocktable is stupidly large ( " + btsize + " ) so was clamped to " + (1 << 20)); - btsize = 1 << 20; - } - - // *** read MPQ archive blocktable - ByteBuffer buffer = ByteBuffer.allocate(rsize); - buffer.limit(csize); - in.position(btoffset + archiveOffset); - while( buffer.hasRemaining() ) - if( in.read(buffer) == -1 ) - break; - buffer.rewind(); - - // *** decrypt blocktable - Cryption.decryptData(buffer, buffer, Cryption.KEY_BLOCK_TABLE); - - // *** decompress blocktable - if( csize < rsize ){ - buffer = new Compression().blockDecompressAny(buffer, ByteBuffer.allocate(rsize)); - if( buffer.limit() != buffer.capacity() ) System.err.println("blocktable decompressed size did not match expected size"); - } - - // *** deserialize blocktable - BlockTable.Entry[] entries = new BlockTable.Entry[btsize]; - BlockTableEntry btentry = new BlockTableEntry(); - for( int i = 0 ; i < btsize ; i+= 1 ){ - btentry.move(buffer); - BlockTable.Entry tempentry = new BlockTable.Entry(); - tempentry.filePosition = (long) btentry.getFilePosition() & 0xFFFFFFFFL; - tempentry.compressedSize = btentry.getCompressedSize(); - tempentry.fileSize = btentry.getFileSize(); - tempentry.flags = btentry.getFlags(); - entries[i] = tempentry; - buffer.position(buffer.position() + BlockTableEntry.STRUCT_SIZE); - } - - // *** add high blocktable - if( hbtoffset > 0 ){ - // read MPQ archive high blocktable - buffer = ByteBuffer.allocate(rhsize); - buffer.limit(chsize); - in.position(hbtoffset + archiveOffset); - while( buffer.hasRemaining() ) - if( in.read(buffer) == -1 ) - break; - buffer.rewind(); - - // decompress high blocktable - if( chsize < rhsize ){ - buffer = new Compression().blockDecompressAny(buffer, ByteBuffer.allocate(rhsize)); - if( buffer.limit() != buffer.capacity() ) System.err.println("high blocktable decompressed size did not match expected size"); - } - - // deserialize high blocktable - short[] highposarray = RawArrays.getShortArray(buffer); - for( int i = 0 ; i < btsize ; i+= 1 ){ - entries[i].filePosition|= ((long) highposarray[i] & 0xFFFFL) << 32; - } - } - blockTable = new BlockTable(entries); - } - - public void loadArchive(SeekableByteChannel in, boolean fold) throws IOException, MPQException{ - // *** find archive header - ArchiveHeader archiveheader = locateArchive(in); - - // *** deserialize archive globals - archiveSize = (long) archiveheader.getArchiveSize() & 0xFFFFFFFFL; - // force old allows support for Warcraft III archives with corrupted version field (not 0) - if( fold ) version = 0; - else version = archiveheader.getFormatVersion(); - blockShift = archiveheader.getBlockSize(); - if( version >= 2 ) archiveSize = archiveheader.getArchiveSizeLong(); - - // *** deserialize archive components - deserializeHashTable(in, archiveheader); - deserializeBlockTable(in, archiveheader); - if( version >= 2 ) System.err.println("het and bet tables not supported"); - } - - public MPQArchive(SeekableByteChannel in) throws MPQException, IOException{ - loadArchive(in, false); - } - - public MPQArchive(){ - } - - public long getArchiveOffset() { - return archiveOffset; - } - - public short getBlockShift() { - return blockShift; - } - - public short getVersion() { - return version; - } - - public boolean isOffsetInArchive(long offset){ - return offset >= 0 && offset <= archiveSize; - } - - public boolean isPositionInArchive(long position){ - return isOffsetInArchive(position - archiveOffset); - } - - public int lookupPath(String path) throws MPQException{ - return hashTable.lookupBlock(new HashLookup(path)); - } - - public BlockTable.Entry lookupHash(HashLookup hash) throws MPQException{ - return blockTable.lookupEntry(hashTable.lookupBlock(hash)); - } - - public ArchivedFile lookupHash2(HashLookup hash) throws MPQException{ - return new ArchivedFile(this, hash, blockTable.lookupEntry(hashTable.lookupBlock(hash))); - } -} diff --git a/core/src/mpq/MPQException.java b/core/src/mpq/MPQException.java deleted file mode 100644 index c90140aa..00000000 --- a/core/src/mpq/MPQException.java +++ /dev/null @@ -1,29 +0,0 @@ -package mpq; - -public class MPQException extends Exception { - - /** - * - */ - private static final long serialVersionUID = 1106829951432295418L; - - public MPQException() { - } - - public MPQException(String arg0) { - super(arg0); - } - - public MPQException(Throwable arg0) { - super(arg0); - } - - public MPQException(String arg0, Throwable arg1) { - super(arg0, arg1); - } - - public MPQException(String arg0, Throwable arg1, boolean arg2, boolean arg3) { - super(arg0, arg1, arg2, arg3); - } - -} diff --git a/core/src/mpq/compression/Compression.java b/core/src/mpq/compression/Compression.java deleted file mode 100644 index 2caa5e37..00000000 --- a/core/src/mpq/compression/Compression.java +++ /dev/null @@ -1,397 +0,0 @@ -package mpq.compression; - -import java.nio.ByteBuffer; -import java.util.zip.DataFormatException; -import java.util.zip.Inflater; - -import mpq.compression.adpcm.ADPCM; -import mpq.compression.huffman.Huffman; -import mpq.compression.pkware.PKException; -import mpq.compression.pkware.PKExploder; - -public class Compression { - /*static TDecompressTable dcmp_table[] = - { - {MPQ_COMPRESSION_BZIP2, Decompress_BZIP2}, // Decompression with Bzip2 library - {MPQ_COMPRESSION_PKWARE, Decompress_PKLIB}, // Decompression with Pkware Data Compression Library - {MPQ_COMPRESSION_ZLIB, Decompress_ZLIB}, // Decompression with the "zlib" library - {MPQ_COMPRESSION_HUFFMANN, Decompress_huff}, // Huffmann decompression - {MPQ_COMPRESSION_ADPCM_STEREO, Decompress_ADPCM_stereo}, // IMA ADPCM stereo decompression - {MPQ_COMPRESSION_ADPCM_MONO, Decompress_ADPCM_mono}, // IMA ADPCM mono decompression - {MPQ_COMPRESSION_SPARSE, Decompress_SPARSE} // Sparse decompression - };*/ - - //private WritableByteBuffer adapter = new WritableByteBuffer(); - /*private OutputStream adapterFront = Channels.newOutputStream(adapter); - - private InflaterOutputStream zlibInflater = new InflaterOutputStream(adapterFront); - private WritableByteChannel zlibDecompressWriter = Channels.newChannel(zlibInflater);*/ - private PKExploder pkexploderDecompress = new PKExploder(); - private Huffman huffmanDecompress = new Huffman(); - private ADPCM adpcmDecompress = new ADPCM(2); - - // an array used to cache buffers of various regular sizes to reduce allocation overhead - private final ByteBuffer[] bufferCache = new ByteBuffer[22]; - - /* - * Compression Masks - */ - /* Masks for Compression Type 2 */ - private static final byte FLAG_HUFFMAN = 0x01; - private static final byte FLAG_DEFLATE = 0x02; - // 0x04 is unknown - private static final byte FLAG_IMPLODE = 0x08; - private static final byte FLAG_BZIP2 = 0x10; // introduced in version 1 - private static final byte FLAG_SPARSE = 0x20; // introduced in version 2 - private static final byte FLAG_ADPCM1C = 0x40; - private static final byte FLAG_ADPCM2C =-0x80; - /* Masks for Compresion Type 3 */ - private static final byte FLAG_LZMA = 0x12; - private static final byte FLAG_SPARSE_DEFLATE = FLAG_SPARSE | FLAG_DEFLATE; - private static final byte FLAG_SPARSE_BZIP2 = FLAG_SPARSE | FLAG_BZIP2 ; - - private ByteBuffer fetchBuffer(int size){ - ByteBuffer out; - if( size >= 0 ){ - out = bufferCache[size]; - if( out == null ){ - out = ByteBuffer.allocate(512 << size); - bufferCache[size] = out; - } - }else out = ByteBuffer.allocate(-size); - return out; - } - - /** - * Decompresses a sector following compression specification 3 used in version 2 and later MPQs. - * - * A lookup table is used to resolve compression. - * - * @param in buffer with compressed sector - * @param size sector size as bit shift or negative for sectors of irregular size - * @return buffer with decompressed sector - * @throws DecompressionException when decompression fails - */ - public ByteBuffer blockDecompress3(ByteBuffer in, int size) throws DecompressionException{ - byte mask = in.get(); - - ByteBuffer out = fetchBuffer(size); - boolean flip = true; - - // lookup table for valid compression types - switch( mask ) { - case FLAG_DEFLATE: - sectorInflate(in, out); - break; - case FLAG_IMPLODE: - sectorExplode(in, out); - break; - case FLAG_BZIP2: - // TODO add support - throw new DecompressionException(in, "unsupported compression type: BZIP2"); - case FLAG_SPARSE: - // TODO add support - throw new DecompressionException(in, "unsupported compression type: SPARSE"); - case FLAG_LZMA: - // TODO add support - throw new DecompressionException(in, "unsupported compression type: LZMA"); - case FLAG_SPARSE_DEFLATE: - // TODO add support - throw new DecompressionException(in, "unsupported compression type: SPARSE"); - case FLAG_SPARSE_BZIP2: - // TODO add support - throw new DecompressionException(in, "unsupported compression type: SPARSE"); - default: - throw new DecompressionException(in, "sector has unknown compression"); - } - - if( size >= 0 ) - if( flip ){ - in.clear(); - bufferCache[size] = in; - }else{ - out.clear(); - out = in; - } - else - if( !flip ) out = in; - - return out; - } - - /** - * Decompresses a sector following compression specification 2 used in version 0 and 1 MPQs. - * - * Masks are evaluated in order to undo compression. - * - * @param in buffer with compressed sector - * @param size sector size as bit shift or negative for sectors of irregular size - * @return buffer with decompressed sector - * @throws DecompressionException when decompression fails - */ - public ByteBuffer blockDecompress2(ByteBuffer in, int size) throws DecompressionException{ - byte mask = in.get(); - - ByteBuffer out = fetchBuffer(size); - boolean flip = false; - - // apply decompression flag at a time - if( (mask & FLAG_BZIP2) != 0 ){ - // TODO add support - throw new DecompressionException(in, "unsupported compression type: BZIP2"); - } - if( (mask & FLAG_IMPLODE) != 0 ){ - sectorExplode(flip ? out : in, flip ? in : out); - (flip ? out : in).clear(); - flip = !flip; - } - if( (mask & FLAG_DEFLATE) != 0 ){ - sectorInflate(flip ? out : in, flip ? in : out); - (flip ? out : in).clear(); - flip = !flip; - } - if( (mask & FLAG_HUFFMAN) != 0 ){ - sectorHuffmanExpand(flip ? out : in, flip ? in : out); - (flip ? out : in).clear(); - flip = !flip; - } - if( (mask & FLAG_ADPCM2C) != 0 ){ - sectorADPCMReconstruct(flip ? out : in, flip ? in : out, 2); - (flip ? out : in).clear(); - flip = !flip; - } - if( (mask & FLAG_ADPCM1C) != 0 ){ - sectorADPCMReconstruct(flip ? out : in, flip ? in : out, 1); - (flip ? out : in).clear(); - flip = !flip; - } - if( (mask & FLAG_SPARSE) != 0 ) System.err.println("sparse compression flag present in mpq version that lacked support"); - - if( flip ){ - bufferCache[size] = in; - return out; - }else return in; - } - - /** - * Decompresses a sector following compression specification 1 used by imploded blocks. - * - * pkware explode is always used on the input. A buffer flip always occurs. - * - * @param in buffer with compressed sector - * @param size sector size as bit shift or negative for sectors of irregular size - * @return buffer with decompressed sector - * @throws DecompressionException when decompression fails - */ - public ByteBuffer blockDecompress1(ByteBuffer in, int size) throws DecompressionException{ - ByteBuffer out = fetchBuffer(size); - sectorExplode(in, out); - in.clear(); - bufferCache[size] = in; - return out; - } - - private void sectorExplode(ByteBuffer in, ByteBuffer out) throws DecompressionException{ - try { - pkexploderDecompress.explode(in, out); - } catch (PKException e) { - throw new DecompressionException(in, "sector explode exception", e); - } - - out.flip(); - } - - private void sectorInflate(ByteBuffer in, ByteBuffer out) throws DecompressionException{ - try { - // a new inflater is needed for each sector as they cannot be recycled - Inflater zlibInflater = new Inflater(); - zlibInflater.setInput(in.array(), in.position(), in.remaining()); - out.position(zlibInflater.inflate(out.array())); - } catch ( DataFormatException e ) { - throw new DecompressionException(in, "sector deflae exception", e); - } - - out.flip(); - } - - private void sectorHuffmanExpand(ByteBuffer in, ByteBuffer out) throws DecompressionException{ - try { - huffmanDecompress.Decompress(in, out); - } catch ( Exception e ) { - throw new DecompressionException(in, "sector huffman expand exception", e); - } - - out.flip(); - } - - private void sectorADPCMReconstruct(ByteBuffer in, ByteBuffer out, int channeln) throws DecompressionException{ - try { - adpcmDecompress.decompress(in, out, channeln); - } catch ( Exception e ) { - throw new DecompressionException(in, "sector adpcm reconstruction exception", e); - } - - out.flip(); - } - - /*private static class WritableByteBuffer implements WritableByteChannel{ - public ByteBuffer dst; - - @Override - public void close() throws IOException { - // nothing to close - } - - @Override - public boolean isOpen() { - // always open - return true; - } - - @Override - public int write(ByteBuffer src) throws IOException { - int size = src.remaining(); - dst.put(src); - return size; - } - - }*/ - - public ByteBuffer blockDecompressAny(ByteBuffer block, ByteBuffer extra) throws DecompressionException{ - if( blockDecompress(block, extra) ) return extra; - else return block; - } - - public void blockExplode(ByteBuffer block, ByteBuffer extra){ - try { - pkexploderDecompress.explode(block, extra); - } catch (PKException e) { - System.err.println("pkware decompression exception: "+e.getLocalizedMessage()); - } - - if( extra.position() != extra.limit() ){ - System.err.println("a block failed exploding"); - } - - block.clear(); - extra.rewind();; - } - - public boolean blockDecompress(ByteBuffer block, ByteBuffer extra) throws DecompressionException{ - return blockDecompress(block, extra, false); - } - - public boolean blockDecompress(ByteBuffer block, ByteBuffer extra, boolean strict) throws DecompressionException{ - byte mask = block.get(); - - if( strict ){ - System.err.println("strict compression flag mode not supported"); - } - - boolean swap = false; - - // BZIP2 - if( (mask & 0x10) > 0 ){ - // TODO add support - throw new DecompressionException(block, "unsupported compression type: BZIP2"); - } - - // PKWARE - if( (mask & 0x08) > 0 ){ - try { - pkexploderDecompress.explode(block, extra); - } catch (PKException e) { - throw new DecompressionException(block, "failed PKWARE decompression", e); - } - block.rewind(); - block.limit(extra.limit()); - extra.flip(); - - ByteBuffer temp = extra; - extra = block; - block = temp; - - swap = !swap; - } - - // ZLIB - if( (mask & 0x02) > 0 ){ - try { - Inflater zlibInflater = new Inflater(); - zlibInflater.setInput(block.array(), block.position(), block.remaining()); - extra.position(zlibInflater.inflate(extra.array())); - } catch ( DataFormatException e ) { - throw new DecompressionException(block, "failed ZLIB decompression", e); - } - block.rewind(); - block.limit(extra.limit()); - extra.flip(); - - ByteBuffer temp = extra; - extra = block; - block = temp; - - swap = !swap; - } - - // HUFFMANN - if( (mask & 0x01) > 0 ){ - huffmanDecompress.Decompress(block, extra); - - block.rewind(); - block.limit(extra.limit()); - extra.flip(); - - ByteBuffer temp = extra; - extra = block; - block = temp; - - swap = !swap; - } - - // ADPCM_STEREO - if( (mask & 0x80) > 0 ){ - adpcmDecompress.decompress(block, extra, 2); - - block.rewind(); - block.limit(extra.limit()); - extra.flip(); - - ByteBuffer temp = extra; - extra = block; - block = temp; - - swap = !swap; - } - - // ADPCM_MONO - if( (mask & 0x40) > 0 ){ - adpcmDecompress.decompress(block, extra, 1); - - block.rewind(); - block.limit(extra.limit()); - extra.flip(); - - ByteBuffer temp = extra; - extra = block; - block = temp; - - swap = !swap; - } - - // SPARSE - if( (mask & 0x20) > 0 ){ - // TODO add support - throw new DecompressionException(block, "unsupported compression type: SPARSE"); - } - - if( block.limit() != extra.limit() ){ - throw new DecompressionException(block, "decompression result was smaller than expected"); - //System.err.println("a sector passed decompression but failed to meet the expected size"); - //block.limit(extra.limit()); - } - - extra.clear(); - return swap; - } -} \ No newline at end of file diff --git a/core/src/mpq/compression/DecompressionException.java b/core/src/mpq/compression/DecompressionException.java deleted file mode 100644 index 7a46595d..00000000 --- a/core/src/mpq/compression/DecompressionException.java +++ /dev/null @@ -1,25 +0,0 @@ -package mpq.compression; - -import java.nio.ByteBuffer; - -import mpq.MPQException; - -public class DecompressionException extends MPQException { - - private static final long serialVersionUID = 5481075695238468958L; - private final ByteBuffer decompressedBuffer; - - public DecompressionException(ByteBuffer buff, String arg0) { - super(arg0); - decompressedBuffer = buff.asReadOnlyBuffer(); - } - - public DecompressionException(ByteBuffer buff, String arg0, Throwable arg1) { - super(arg0, arg1); - decompressedBuffer = buff.asReadOnlyBuffer(); - } - - public ByteBuffer getDecompressedBuffer() { - return decompressedBuffer; - } -} diff --git a/core/src/mpq/compression/adpcm/ADPCM.java b/core/src/mpq/compression/adpcm/ADPCM.java deleted file mode 100644 index c39ee3ef..00000000 --- a/core/src/mpq/compression/adpcm/ADPCM.java +++ /dev/null @@ -1,118 +0,0 @@ -package mpq.compression.adpcm; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -public class ADPCM { - - private static class Channel{ - public short value; - public byte rate; - } - - private final Channel[] state; - - public ADPCM(int channelmax){ - state = new Channel[channelmax]; - for( int i = 0 ; i < state.length ; i+= 1 ) state[i] = new Channel(); - } - - public void decompress(ByteBuffer in, ByteBuffer out, int channeln){ - // prepare buffers - in.order(ByteOrder.LITTLE_ENDIAN); - out.order(ByteOrder.LITTLE_ENDIAN); - - byte stepshift = (byte) (in.getShort() >>> 8); - - // initialize channels - for( int i = 0 ; i < channeln ; i+= 1 ){ - Channel chan = state[i]; - chan.rate = 0x2C; - chan.value = in.getShort(); - out.putShort(chan.value); - } - - int current = 0; - Channel chan = state[current]; - boolean multichannel = channeln > 1; - - // decompress - while( in.hasRemaining() ){ - byte op = in.get(); - - if( (op & 0x80) > 0 ){ - switch( op & 0x7F ){ - // write current value - case 0 : - if( chan.rate != 0 ) chan.rate-= 1; - out.putShort(chan.value); - if( multichannel ) chan = state[++current % channeln]; - break; - // increment period - case 1 : - chan.rate+= 8; - if( chan.rate > 0x58 ) chan.rate = 0x58; - break; - // skip channel - case 2 : - if( multichannel ) chan = state[++current % channeln]; - break; - // all other values - default : - chan.rate-= 8; - if( chan.rate < 0 ) chan.rate = 0; - } - }else{ - // adjust value - short stepunit = STEP_TABLE[chan.rate]; - short stepsize = (short) (stepunit >>> stepshift); - int value = chan.value; - - for( int i = 0 ; i < 6 ; i+= 1 ){ - if( (op & 1 << i) > 0 ) stepsize+= stepunit >> i; - } - - if( (op & 0x40) > 0 ){ - value-= stepsize; - if( value < Short.MIN_VALUE ) value = Short.MIN_VALUE; - }else{ - value+= stepsize; - if( value > Short.MAX_VALUE ) value = Short.MAX_VALUE; - } - chan.value = (short) value; - - out.putShort(chan.value); - - chan.rate+= CHANGE_TABLE[op & 0x1F]; - if( chan.rate < 0 ) chan.rate = 0; - else if( chan.rate > 0x58 ) chan.rate = 0x58; - - if( multichannel ) chan = state[++current % channeln]; - } - } - } - - private static final byte CHANGE_TABLE[] = - { - 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000006, - 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007, - 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0x00000005, 0xFFFFFFFF, 0x00000003, 0xFFFFFFFF, 0x00000007, - 0xFFFFFFFF, 0x00000002, 0xFFFFFFFF, 0x00000004, 0xFFFFFFFF, 0x00000006, 0xFFFFFFFF, 0x00000008 - }; - - private static final short STEP_TABLE[] = - { - 0x00000007, 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, 0x0000000C, 0x0000000D, 0x0000000E, - 0x00000010, 0x00000011, 0x00000013, 0x00000015, 0x00000017, 0x00000019, 0x0000001C, 0x0000001F, - 0x00000022, 0x00000025, 0x00000029, 0x0000002D, 0x00000032, 0x00000037, 0x0000003C, 0x00000042, - 0x00000049, 0x00000050, 0x00000058, 0x00000061, 0x0000006B, 0x00000076, 0x00000082, 0x0000008F, - 0x0000009D, 0x000000AD, 0x000000BE, 0x000000D1, 0x000000E6, 0x000000FD, 0x00000117, 0x00000133, - 0x00000151, 0x00000173, 0x00000198, 0x000001C1, 0x000001EE, 0x00000220, 0x00000256, 0x00000292, - 0x000002D4, 0x0000031C, 0x0000036C, 0x000003C3, 0x00000424, 0x0000048E, 0x00000502, 0x00000583, - 0x00000610, 0x000006AB, 0x00000756, 0x00000812, 0x000008E0, 0x000009C3, 0x00000ABD, 0x00000BD0, - 0x00000CFF, 0x00000E4C, 0x00000FBA, 0x0000114C, 0x00001307, 0x000014EE, 0x00001706, 0x00001954, - 0x00001BDC, 0x00001EA5, 0x000021B6, 0x00002515, 0x000028CA, 0x00002CDF, 0x0000315B, 0x0000364B, - 0x00003BB9, 0x000041B2, 0x00004844, 0x00004F7E, 0x00005771, 0x0000602F, 0x000069CE, 0x00007462, - 0x00007FFF - }; -} diff --git a/core/src/mpq/compression/huffman/Huffman.java b/core/src/mpq/compression/huffman/Huffman.java deleted file mode 100644 index 1d117396..00000000 --- a/core/src/mpq/compression/huffman/Huffman.java +++ /dev/null @@ -1,481 +0,0 @@ -package mpq.compression.huffman; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Map.Entry; -import java.util.TreeMap; - -public class Huffman { - private static class Node { - public Node parent; - public final Node[] child = new Node[2]; - public Node next; - public Node prev; - public int value; - public int probability; - - public void treeSwap(Node with){ - Node temp; - - if( parent == with.parent ){ - temp = parent.child[0]; - parent.child[0] = parent.child[1]; - parent.child[1] = temp; - }else{ - if( with.parent.child[0] == with ) with.parent.child[0] = this; - else with.parent.child[1] = this; - if( this.parent.child[0] == this ) this.parent.child[0] = with; - else this.parent.child[1] = with; - } - - temp = parent; - parent = with.parent; - with.parent = temp; - } - - public void insertAfter(Node where){ - prev = where; - next = where.next; - where.next = this; - next.prev = this; - } - - public void listSwap(Node with){ - if( next == with ){ - next = with.next; - with.next = this; - with.prev = prev; - prev = with; - - with.prev.next = with; - next.prev = this; - }else if( prev == with ){ - prev = with.prev; - with.prev = this; - with.next = next; - next = with; - - with.next.prev = with; - prev.next = this; - }else{ - Node temp = prev; - prev = with.prev; - with.prev = temp; - - temp = next; - next = with.next; - with.next = temp; - - prev.next = this; - next.prev = this; - - with.prev.next = with; - with.next.prev = with; - } - } - - public void newList(){ - prev = next = this; - } - - public Node removeFromList(){ - if( this == next ) return null; - - prev.next = next; - next.prev = prev; - - return next; - } - - public void joinList(Node list){ - Node tail = prev; - - prev = list.prev; - prev.next = this; - - list.prev = tail; - tail.next = list; - } - } - - private boolean adjustProbability; - - private Node nodes = null; - private TreeMap sorted2 = new TreeMap(); - - private Node root = null; - private Node[] valueToNode = new Node[0x102]; - - private int bitBuffer; - private byte bitNumber; - private ByteBuffer source; - - private void setSource(ByteBuffer source){ - this.source = source; - bitBuffer = 0; - bitNumber = 0; - } - - private int getBits(int bits){ - while( bitNumber < bits ){ - bitBuffer|= ((int) source.get() & 0xFF) << bitNumber; - bitNumber+= 8; - } - - int result = bitBuffer & ((1 << bits) - 1); - bitBuffer>>>= bits; - bitNumber-= bits; - - return result; - } - - private Node getNode(){ - Node node; - if( nodes == null ) node = new Node(); - else{ - node = nodes; - nodes = nodes.removeFromList(); - } - return node; - } - - private void destroyTree(Node root){ - if( nodes == null ) nodes = root; - else nodes.joinList(root); - this.root = null; - sorted2.clear(); - Arrays.fill(valueToNode, null); - } - - private void insertNode( Node node ){ - Entry test2 = sorted2.ceilingEntry(node.probability); - Node current; - - - if( test2 != null ){ - current = test2.getValue(); - node.insertAfter(current); - }else{ - current = root; - if( root != null ){ - node.insertAfter(root.prev); - }else{ - node.newList(); - } - root = node; - } - - sorted2.put(node.probability, node); - } - - private Node addValueToTree( int value ){ - // create leaf node - Node node = getNode(); - node.value = value; - node.probability = 0; - node.child[0] = null; - node.child[1] = null; - - valueToNode[value] = node; - insertNode( node ); - - // create branch node - Node node2 = getNode(); - Node child1 = root.prev; - Node child2 = child1.prev; - - node2.value = -1; - node2.probability = child1.probability + child2.probability; - node2.child[0] = child1; - node2.child[1] = child2; - node2.parent = child2.parent; - - node2.insertAfter(child2.prev); - - // insert into tree - if( node2.parent.child[0] == child2 ) node2.parent.child[0] = node2; - else node2.parent.child[1] = node2; - - child1.parent = node2; - child2.parent = node2; - - return node; - } - - private void incrementProbability( Node node ){ - while( node != null ){ - // possible optimization here. Is all this really nescescary to enforce order? - if( sorted2.get(node.probability) == node ){ - if( node.probability == node.prev.probability ) - sorted2.put(node.probability, node.prev); - else - sorted2.remove(node.probability); - } - node.probability+= 1; - - Entry test2 = sorted2.ceilingEntry(node.probability); - Node where; - if( test2 != null ) where = test2.getValue().next; - else where = root; - - if( where != node ){ - node.listSwap(where); - node.treeSwap(where); - - if( where.probability != where.next.probability ){ - sorted2.put(where.probability, where); - } - } - sorted2.put(node.probability, node); - - node = node.parent; - } - } - - private void buildTree( byte tree ){ - byte[] probabilities = PROBABILITY_TABLES[tree]; - - // destroy any existing tree - if( root != null ) destroyTree(root); - - // generate leaves - for( int i = 0 ; i < 0x102 ; i++ ){ - int prob = (int) probabilities[i] & 0xFF; - - if( prob == 0 ) continue; - - Node node = getNode(); - node.value = i; - node.probability = prob; - node.child[0] = null; - node.child[1] = null; - - insertNode( node ); - valueToNode[i] = node; - } - - // generate tree - Node current = root.prev; - while( current != root ){ - Node node = getNode(); - Node child1 = current; - Node child2 = current = current.prev; - - child1.parent = node; - child2.parent = node; - - node.value = -1; - node.probability = child1.probability + child2.probability; - node.child[0] = child1; - node.child[1] = child2; - insertNode( node ); - - current = current.prev; - } - - root.parent = null; - } - - public void Decompress( ByteBuffer in, ByteBuffer out ){ - setSource(in); - byte type = (byte) getBits(8); - buildTree(type); - - adjustProbability = type == 0; - - for(;;){ - Node current = root; - while( current.value == -1 ) - current = current.child[getBits(1)]; - - if( current.value == 0x101 ){ - int value = getBits(8); - current = addValueToTree(value); - incrementProbability(current); - if( !adjustProbability ) incrementProbability(current); - }else if( current.value == 0x100 ){ - break; - } - - out.put((byte) current.value); - - if( adjustProbability ){ - incrementProbability(current); - } - } - - } - - private static final byte[][] PROBABILITY_TABLES = { - // Data for compression type 0x00 - {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x01, 0x01}, - - // Data for compression type 0x01 - {0x54, 0x16, 0x16, 0x0D, 0x0C, 0x08, 0x06, 0x05, 0x06, 0x05, 0x06, 0x03, 0x04, 0x04, 0x03, 0x05, - 0x0E, 0x0B, 0x14, 0x13, 0x13, 0x09, 0x0B, 0x06, 0x05, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, - 0x0D, 0x07, 0x09, 0x06, 0x06, 0x04, 0x03, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, - 0x09, 0x06, 0x04, 0x04, 0x04, 0x04, 0x03, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04, - 0x08, 0x03, 0x04, 0x07, 0x09, 0x05, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, - 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, - 0x06, 0x0A, 0x08, 0x08, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x03, 0x03, - 0x04, 0x03, 0x07, 0x07, 0x09, 0x06, 0x04, 0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x0A, 0x02, 0x02, 0x03, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x03, 0x05, 0x02, 0x03, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x09, 0x08, 0x0C, 0x02, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x03, - 0x04, 0x01, 0x02, 0x04, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x06, 0x4B, - 0x01, 0x01}, - - // Data for compression type 0x02 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x27, 0x00, 0x00, 0x23, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - (byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x06, 0x0E, 0x10, 0x04, - 0x06, 0x08, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01, - 0x01, 0x04, 0x02, 0x04, 0x02, 0x02, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0x02, 0x03, 0x03, 0x02, - 0x03, 0x01, 0x03, 0x06, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01, - 0x01, 0x29, 0x07, 0x16, 0x12, 0x40, 0x0A, 0x0A, 0x11, 0x25, 0x01, 0x03, 0x17, 0x10, 0x26, 0x2A, - 0x10, 0x01, 0x23, 0x23, 0x2F, 0x10, 0x06, 0x07, 0x02, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01}, - - // Data for compression type 0x03 - {(byte) 0xFF, 0x0B, 0x07, 0x05, 0x0B, 0x02, 0x02, 0x02, 0x06, 0x02, 0x02, 0x01, 0x04, 0x02, 0x01, 0x03, - 0x09, 0x01, 0x01, 0x01, 0x03, 0x04, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x05, 0x01, 0x01, 0x01, 0x0D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x0A, 0x04, 0x02, 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x01, - 0x05, 0x02, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02, 0x03, 0x03, - 0x01, 0x03, 0x01, 0x01, 0x02, 0x05, 0x01, 0x01, 0x04, 0x03, 0x05, 0x01, 0x03, 0x01, 0x03, 0x03, - 0x02, 0x01, 0x04, 0x03, 0x0A, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x01, 0x0A, 0x02, 0x05, 0x01, 0x01, 0x02, 0x07, 0x02, 0x17, 0x01, 0x05, 0x01, 0x01, - 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x06, 0x02, 0x01, 0x04, 0x05, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11, - 0x01, 0x01}, - - // Data for compression type 0x04 - {(byte) 0xFF, (byte) 0xFB, (byte) 0x98, (byte) 0x9A, (byte) 0x84, (byte) 0x85, 0x63, 0x64, 0x3E, 0x3E, 0x22, 0x22, 0x13, 0x13, 0x18, 0x17, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01}, - - // Data for compression type 0x05 - {(byte) 0xFF, (byte) 0xF1, (byte) 0x9D, (byte) 0x9E, (byte) 0x9A, (byte) 0x9B, (byte) 0x9A, (byte) 0x97, (byte) 0x93, (byte) 0x93, (byte) 0x8C, (byte) 0x8E, (byte) 0x86, (byte) 0x88, (byte) 0x80, (byte) 0x82, - 0x7C, 0x7C, 0x72, 0x73, 0x69, 0x6B, 0x5F, 0x60, 0x55, 0x56, 0x4A, 0x4B, 0x40, 0x41, 0x37, 0x37, - 0x2F, 0x2F, 0x27, 0x27, 0x21, 0x21, 0x1B, 0x1C, 0x17, 0x17, 0x13, 0x13, 0x10, 0x10, 0x0D, 0x0D, - 0x0B, 0x0B, 0x09, 0x09, 0x08, 0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x04, 0x04, 0x19, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01}, - - // Data for compression type 0x06 - {(byte) 0xC3, (byte) 0xCB, (byte) 0xF5, 0x41, (byte) 0xFF, 0x7B, (byte) 0xF7, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - (byte) 0xBF, (byte) 0xCC, (byte) 0xF2, 0x40, (byte) 0xFD, 0x7C, (byte) 0xF7, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01}, - - // Data for compression type 0x07 - {(byte) 0xC3, (byte) 0xD9, (byte) 0xEF, 0x3D, (byte) 0xF9, 0x7C, (byte) 0xE9, 0x1E, (byte) 0xFD, (byte) 0xAB, (byte) 0xF1, 0x2C, (byte) 0xFC, 0x5B, (byte) 0xFE, 0x17, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - (byte) 0xBD, (byte) 0xD9, (byte) 0xEC, 0x3D, (byte) 0xF5, 0x7D, (byte) 0xE8, 0x1D, (byte) 0xFB, (byte) 0xAE, (byte) 0xF0, 0x2C, (byte) 0xFB, 0x5C, (byte) 0xFF, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01}, - - // Data for compression type 0x08 - {(byte) 0xBA, (byte) 0xC5, (byte) 0xDA, 0x33, (byte) 0xE3, 0x6D, (byte) 0xD8, 0x18, (byte) 0xE5, (byte) 0x94, (byte) 0xDA, 0x23, (byte) 0xDF, 0x4A, (byte) 0xD1, 0x10, - (byte) 0xEE, (byte) 0xAF, (byte) 0xE4, 0x2C, (byte) 0xEA, 0x5A, (byte) 0xDE, 0x15, (byte) 0xF4, (byte) 0x87, (byte) 0xE9, 0x21, (byte) 0xF6, 0x43, (byte) 0xFC, 0x12, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - (byte) 0xB0, (byte) 0xC7, (byte) 0xD8, 0x33, (byte) 0xE3, 0x6B, (byte) 0xD6, 0x18, (byte) 0xE7, (byte) 0x95, (byte) 0xD8, 0x23, (byte) 0xDB, 0x49, (byte) 0xD0, 0x11, - (byte) 0xE9, (byte) 0xB2, (byte) 0xE2, 0x2B, (byte) 0xE8, 0x5C, (byte) 0xDD, 0x15, (byte) 0xF1, (byte) 0x87, (byte) 0xE7, 0x20, (byte) 0xF7, 0x44, (byte) 0xFF, 0x13, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5F, (byte) 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01} - }; -} diff --git a/core/src/mpq/compression/pkware/PKException.java b/core/src/mpq/compression/pkware/PKException.java deleted file mode 100644 index 858ca197..00000000 --- a/core/src/mpq/compression/pkware/PKException.java +++ /dev/null @@ -1,14 +0,0 @@ -package mpq.compression.pkware; - -public class PKException extends Exception { - - /** - * - */ - private static final long serialVersionUID = 6514086311357764773L; - - public PKException(String arg0) { - super(arg0); - } - -} diff --git a/core/src/mpq/compression/pkware/PKExploder.java b/core/src/mpq/compression/pkware/PKExploder.java deleted file mode 100644 index 8a6db4c2..00000000 --- a/core/src/mpq/compression/pkware/PKExploder.java +++ /dev/null @@ -1,200 +0,0 @@ -package mpq.compression.pkware; - -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; - -public class PKExploder { - private static final byte CMP_BINARY = 0; - private static final byte CMP_ASCII = 1; - - private static final byte LEN_SIZE = 16; - private static final byte[] LEN_BITS = { - 0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07 - }; - private static final short[] LEN_CODES = { - 0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00 - }; - private static final byte[] LENGTH_CODES = new byte[0x100]; - static { - denDecodeTabs(LENGTH_CODES, LEN_CODES, LEN_BITS, LEN_SIZE); - } - - private static final byte[] EX_LEN_BITS = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 - }; - - private static final short[] LEN_BASE ={ - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106 - }; - - private static final byte DIST_SIZE = 64; - private static final byte[] DIST_BITS = { - 0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 - }; - private static final short[] DIST_CODES = - { - 0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A, - 0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C, - 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, - 0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00 - }; - private static final byte[] DIST_POS_CODES = new byte[0x100]; - static { - denDecodeTabs(DIST_POS_CODES, DIST_CODES, DIST_BITS, DIST_SIZE); - } - - private static void denDecodeTabs(byte[] pos, short[] sindex, byte[] len, int size){ - for( byte i = 0 ; i < size ; i++ ){ - short length = (short) (1 << len[i]); - - for( short index = sindex[i] ; index < pos.length ; index+= length ) - { - pos[index] = i; - } - } - } - - private ByteBuffer in; - private ByteBuffer out; - private byte ctype; - private byte dsize_bits; - private short bit_buff; - private byte extra_bits; - private byte dsize_mask; - - private void WasteBits(byte nbits){ - bit_buff = (short) ((bit_buff & 0xFFFF) >>> nbits); - if( nbits <= extra_bits ){ - extra_bits-= nbits; - }else{ - bit_buff = (short) ((bit_buff | ((in.get() & 0xFF ) << (8 - nbits + extra_bits))) & 0xFFFF); - extra_bits-= nbits - 8; - } - } - - private void expand() throws PKException{ - for( ; ; ){ - if( (bit_buff & 0x01) != 0 ){ - WasteBits((byte) 1); - - // --- repeat bytes - - // get length - short length_code = (short) LENGTH_CODES[bit_buff & 0xFF]; - WasteBits((byte) LEN_BITS[length_code]); - - byte extra_length_bits; - if((extra_length_bits = EX_LEN_BITS[length_code]) != 0) - { - byte extra_length = (byte) (bit_buff & ((1 << extra_length_bits) - 1)); - - try{ - WasteBits(extra_length_bits); - }catch( BufferUnderflowException e ){ - if( (length_code + (extra_length & 0xFF)) == 0x10E ) return; - else throw e; - } - length_code = (short) (LEN_BASE[length_code] + (extra_length & 0xFF)); - - } - - length_code+= 2; - - // get distance - byte dist_pos_code = DIST_POS_CODES[bit_buff & 0xFF]; - byte dist_pos_bits = DIST_BITS[dist_pos_code]; - WasteBits(dist_pos_bits); - - short distance; - - if(length_code == 2){ - // If the repetition is only 2 bytes length, - // then take 2 bits from the stream in order to get the distance - distance = (short) ((dist_pos_code << 2) | (bit_buff & 0x03)); - WasteBits((byte) 2); - }else{ - // If the repetition is more than 2 bytes length, - // then take "dsize_bits" bits in order to get the distance - distance = (short) ((dist_pos_code << dsize_bits) | (bit_buff & dsize_mask)); - WasteBits(dsize_bits); - } - distance+= 1; - - // do the copying - int target = out.position(); - int source = target - distance; - - while( length_code > 0 ){ - if(source >= 0) - out.put(target++, out.get(source++)); - else{ - throw new PKException("distance pointing before output"); - } - length_code-= 1; - } - - out.position(target); - - }else{ - WasteBits((byte) 1); - - // --- raw byte - - switch( ctype ){ - case CMP_BINARY: - // read raw byte - byte uncompressed_byte = (byte) (bit_buff & 0xFF); - WasteBits((byte) 8); - - // write raw byte - out.put(uncompressed_byte); - break; - case CMP_ASCII: - // TODO add ASCII decompression stuff here - System.err.println("pkware ascii compression not supported"); - return; - default: throw new PKException("invalid compression mode"); - } - } - } - } - - public void explode(ByteBuffer in, ByteBuffer out) throws PKException{ - // set in and out buffers - this.in = in; - this.out = out; - if( in.remaining() <= 4 ) throw new PKException("received bad data"); - - // initialize state with compression header - ctype = in.get(); - dsize_bits = in.get(); - bit_buff = (short) (in.get() & 0xFF); - extra_bits = 0; - - // dictionary size mask - if( dsize_bits < 4 || 6 < dsize_bits ) throw new PKException("invalid dictionary size"); - dsize_mask = (byte) (0xFFFF >> (0x10 - dsize_bits)); - - // setup compression type dependent data - switch( ctype ){ - case CMP_BINARY: break; - case CMP_ASCII: - // TODO add ASCII decompression stuff here - System.err.println("pkware ascii compression not supported"); - return; - default: throw new PKException("invalid compression mode"); - } - - // perform explode - try{ - expand(); - }catch( BufferUnderflowException e ){ - throw new PKException("unexpected end of data"); - } - - } -} diff --git a/core/src/mpq/data/ArchiveHeader.java b/core/src/mpq/data/ArchiveHeader.java deleted file mode 100644 index 2da8cafd..00000000 --- a/core/src/mpq/data/ArchiveHeader.java +++ /dev/null @@ -1,98 +0,0 @@ -package mpq.data; - -import java.nio.ByteBuffer; - -public class ArchiveHeader extends Raw{ - public static final int STRUCT_SIZE_V1 = 32 - 8; - public static final int STRUCT_SIZE_V2 = STRUCT_SIZE_V1 + 12; - public static final int STRUCT_SIZE_V3 = STRUCT_SIZE_V2 + 24; - public static final int STRUCT_SIZE_V4 = STRUCT_SIZE_V3 + 44; - - public ArchiveHeader(ByteBuffer source) { - super(source); - } - - // VERSION 1 - - public int getArchiveSize() { - return data.getInt(0); - } - - public short getFormatVersion() { - return data.getShort(4); - } - - public short getBlockSize() { - return data.getShort(6); - } - - public int getHashTablePosition() { - return data.getInt(8); - } - - public int getBlockTablePosition() { - return data.getInt(12); - } - - public int getHashTableSize() { - return data.getInt(16); - } - - public int getBlockTableSize() { - return data.getInt(20); - } - - // VERSION 2 - - public long getHighBlockTablePosition() { - return data.getLong(24); - } - - public short getHashTablePositionHigh() { - return data.getShort(32); - } - - public short getBlockTablePositionHigh() { - return data.getShort(34); - } - - // VERSION 3 - - public long getArchiveSizeLong() { - return data.getLong(36); - } - - public long getBetTablePosition() { - return data.getLong(44); - } - - public long getHetTablePosition() { - return data.getLong(52); - } - - // VERSION 4 - - public long getHashTableSizeCompressed() { - return data.getLong(60); - } - - public long getBlockTableSizeCompressed() { - return data.getLong(68); - } - - public long getHighBlockTableSizeCompressed() { - return data.getLong(76); - } - - public long getHetTableSizeCompressed() { - return data.getLong(84); - } - - public long getBetTableSizeCompressed() { - return data.getLong(92); - } - - public int getRawChunkSize() { - return data.getInt(100); - } -} diff --git a/core/src/mpq/data/BlockTableEntry.java b/core/src/mpq/data/BlockTableEntry.java deleted file mode 100644 index bd262d5b..00000000 --- a/core/src/mpq/data/BlockTableEntry.java +++ /dev/null @@ -1,31 +0,0 @@ -package mpq.data; - -import java.nio.ByteBuffer; - -public class BlockTableEntry extends Raw { - public static final int STRUCT_SIZE = 16; - - public BlockTableEntry(ByteBuffer source) { - super(source); - } - - public BlockTableEntry() { - super(); - } - - public int getFilePosition() { - return data.getInt(0); - } - - public int getCompressedSize() { - return data.getInt(4); - } - - public int getFileSize() { - return data.getInt(8); - } - - public int getFlags() { - return data.getInt(12); - } -} diff --git a/core/src/mpq/data/FileHeader.java b/core/src/mpq/data/FileHeader.java deleted file mode 100644 index ca1b4c10..00000000 --- a/core/src/mpq/data/FileHeader.java +++ /dev/null @@ -1,31 +0,0 @@ -package mpq.data; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -public class FileHeader extends Raw{ - public static final byte[] ARCHIVE_IDENTIFIER_BYTES = {'M','P','Q',0x1a}; - public static final int ARCHIVE_IDENTIFIER_INT = ByteBuffer.wrap(ARCHIVE_IDENTIFIER_BYTES).order(ByteOrder.LITTLE_ENDIAN).getInt(0); - public static final byte[] USERDATA_IDENTIFIER_BYTES = {'M','P','Q',0x1b}; - public static final int USERDATA_IDENTIFIER_INT = ByteBuffer.wrap(USERDATA_IDENTIFIER_BYTES).order(ByteOrder.LITTLE_ENDIAN).getInt(0); - public static final int STRUCT_SIZE = 8; - - public FileHeader(ByteBuffer source) { - super(source); - } - - public byte[] getIdentifierBytes() { - byte[] bytes = new byte[4]; - data.position(0); - data.get(bytes); - return bytes; - } - - public int getIdentifierInt() { - return data.getInt(0); - } - - public int getHeaderSize() { - return data.getInt(4); - } -} diff --git a/core/src/mpq/data/HashTableEntry.java b/core/src/mpq/data/HashTableEntry.java deleted file mode 100644 index 1e970f8c..00000000 --- a/core/src/mpq/data/HashTableEntry.java +++ /dev/null @@ -1,31 +0,0 @@ -package mpq.data; - -import java.nio.ByteBuffer; - -public class HashTableEntry extends Raw { - public static final int STRUCT_SIZE = 16; - - public HashTableEntry(ByteBuffer source) { - super(source); - } - - public HashTableEntry() { - super(); - } - - public long getHash() { - return data.getLong(0); - } - - public short getLocale() { - return data.getShort(8); - } - - public short getPlatform() { - return data.getShort(10); - } - - public int getBlockIndex() { - return data.getInt(12); - } -} diff --git a/core/src/mpq/data/Raw.java b/core/src/mpq/data/Raw.java deleted file mode 100644 index 80fd27fe..00000000 --- a/core/src/mpq/data/Raw.java +++ /dev/null @@ -1,20 +0,0 @@ -package mpq.data; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -public abstract class Raw { - protected ByteBuffer data; - - public Raw(ByteBuffer source){ - move(source); - } - - public Raw(){ - data = null; - } - - public void move(ByteBuffer source){ - data = source.slice().order(ByteOrder.LITTLE_ENDIAN); - } -} diff --git a/core/src/mpq/data/RawArrays.java b/core/src/mpq/data/RawArrays.java deleted file mode 100644 index 4efe1e17..00000000 --- a/core/src/mpq/data/RawArrays.java +++ /dev/null @@ -1,36 +0,0 @@ -package mpq.data; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.IntBuffer; -import java.nio.ShortBuffer; - -public class RawArrays { - public static int[] getArray(ByteBuffer source){ - source.order(ByteOrder.LITTLE_ENDIAN); - IntBuffer in = source.asIntBuffer(); - - IntBuffer out = IntBuffer.allocate(in.capacity()); - out.put(in); - - return out.array(); - } - - public static void getArray(ByteBuffer source, int[] destination){ - source.order(ByteOrder.LITTLE_ENDIAN); - IntBuffer in = source.asIntBuffer(); - - IntBuffer out = IntBuffer.wrap(destination); - out.put(in); - } - - public static short[] getShortArray(ByteBuffer source){ - source.order(ByteOrder.LITTLE_ENDIAN); - ShortBuffer in = source.asShortBuffer(); - - ShortBuffer out = ShortBuffer.allocate(in.capacity()); - out.put(in); - - return out.array(); - } -} diff --git a/core/src/mpq/data/UserDataHeader.java b/core/src/mpq/data/UserDataHeader.java deleted file mode 100644 index 978186a9..00000000 --- a/core/src/mpq/data/UserDataHeader.java +++ /dev/null @@ -1,21 +0,0 @@ -package mpq.data; - -import java.nio.ByteBuffer; - -public class UserDataHeader extends Raw{ - public static final int STRUCT_SIZE = 16 - 8; - - public UserDataHeader(ByteBuffer source) { - super(source); - } - - - public int getArchiveOffset() { - return data.getInt(0); - } - - public int getUserDataSize() { - return data.getInt(4); - } - -} diff --git a/core/src/mpq/util/Cryption.java b/core/src/mpq/util/Cryption.java deleted file mode 100644 index 073c2260..00000000 --- a/core/src/mpq/util/Cryption.java +++ /dev/null @@ -1,116 +0,0 @@ -package mpq.util; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.charset.StandardCharsets; -import java.util.Locale; - -public class Cryption { - private static final int[] CRYPT_TABLE = new int[0x500]; - static { - int seed = 0x00100001; - - for (int index1 = 0; index1 < 0x100; index1++) { - for (int index2 = index1, i = 0; i < 5; i++, index2 += 0x100) { - seed = ((seed * 125) + 3) % 0x2AAAAB; - final int temp1 = (seed & 0xFFFF) << 0x10; - - seed = ((seed * 125) + 3) % 0x2AAAAB; - final int temp2 = (seed & 0xFFFF); - - CRYPT_TABLE[index2] = (temp1 | temp2); - } - } - } - - // different types of hashes to make with HashString - public static final int MPQ_HASH_TABLE_OFFSET = 0; - public static final int MPQ_HASH_NAME_A = 1; - public static final int MPQ_HASH_NAME_B = 2; - public static final int MPQ_HASH_FILE_KEY = 3; - - // cached hashes - public static final int KEY_HASH_TABLE = HashString("(hash table)", MPQ_HASH_FILE_KEY); - public static final int KEY_BLOCK_TABLE = HashString("(block table)", MPQ_HASH_FILE_KEY); - - public static void cryptData(ByteBuffer in, ByteBuffer out, int length, int key, final boolean de) { - // prepare platform independent views - in = in.asReadOnlyBuffer().order(ByteOrder.LITTLE_ENDIAN); - out = out.duplicate().order(ByteOrder.LITTLE_ENDIAN); - // cryption - int seed = 0xEEEEEEEE; - length /= 4; - while (length-- > 0) { - seed += CRYPT_TABLE[0x400 + (key & 0xFF)]; - // basic algorithm - final int read = in.getInt(); - final int ch = read ^ (key + seed); - out.putInt(ch); - // generation for next iteration - seed += (de ? ch : read) + (seed << 5) + 3; - key = ((~key << 21) + 0x11111111) | (key >>> 11); - } - out.rewind(); - } - - public static void encryptData(final ByteBuffer in, final ByteBuffer out, final int length, final int key) { - cryptData(in, out, length, key, false); - } - - public static void decryptData(final ByteBuffer in, final ByteBuffer out, final int length, final int key) { - cryptData(in, out, length, key, true); - } - - public static void cryptData(ByteBuffer in, ByteBuffer out, int key, final boolean de) { - // prepare platform independent views - in = in.asReadOnlyBuffer().order(ByteOrder.LITTLE_ENDIAN); - out = out.duplicate().order(ByteOrder.LITTLE_ENDIAN); - - // round to last dword to prevent buffer underflow - in.limit(in.limit() & ~0x03); - - // cryption - int seed = 0xEEEEEEEE; - while (in.hasRemaining()) { - seed += CRYPT_TABLE[0x400 + (key & 0xFF)]; - // basic algorithm - final int read = in.getInt(); - final int ch = read ^ (key + seed); - out.putInt(ch); - // generation for next iteration - seed += (de ? ch : read) + (seed << 5) + 3; - key = ((~key << 21) + 0x11111111) | (key >>> 11); - } - } - - public static void encryptData(final ByteBuffer in, final ByteBuffer out, final int key) { - cryptData(in, out, key, false); - } - - public static void decryptData(final ByteBuffer in, final ByteBuffer out, final int key) { - cryptData(in, out, key, true); - } - - public static byte[] stringToHashable(final String in) { - return in.toUpperCase(Locale.US).getBytes(StandardCharsets.UTF_8); // UTF_8 defined for platform independence - } - - public static int HashString(final String in, final int HashType) { - return HashString(stringToHashable(in), HashType); - } - - // Based on code from StormLib. - public static int HashString(final byte[] in, final int HashType) { - int seed1 = 0x7FED7FED; - int seed2 = 0xEEEEEEEE; - for (final byte ch : in) { - seed1 = CRYPT_TABLE[(HashType * 0x100) + ch] ^ (seed1 + seed2); - seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; - } - return seed1; - } - - public static int adjustFileDecryptKey(final int in, final int pos, final int size) { - return (in + pos) ^ size; - } -} From 2991a5a9570173d68cfaf684f3209a7a0ad8c973 Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:02:50 +0200 Subject: [PATCH 16/17] Delete Original Repo Is Back --- Original Repo Is Back | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Original Repo Is Back diff --git a/Original Repo Is Back b/Original Repo Is Back deleted file mode 100644 index 50fc7361..00000000 --- a/Original Repo Is Back +++ /dev/null @@ -1 +0,0 @@ -https://github.com/Retera/WarsmashModEngine From 97d5591dcfd977890e6bb196633710232c8c9e0c Mon Sep 17 00:00:00 2001 From: onlyreportingissues <103491514+onlyreportingissues@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:03:06 +0200 Subject: [PATCH 17/17] Create Original Repo Is Back https://github.com/Retera/WarsmashModEngine --- Original Repo Is Back | 1 + 1 file changed, 1 insertion(+) create mode 100644 Original Repo Is Back diff --git a/Original Repo Is Back b/Original Repo Is Back new file mode 100644 index 00000000..50fc7361 --- /dev/null +++ b/Original Repo Is Back @@ -0,0 +1 @@ +https://github.com/Retera/WarsmashModEngine