mirror of
https://github.com/GTNewHorizons/StructureLib.git
synced 2026-10-25 20:32:24 +00:00
Add most of code. Still missing some hint related stuff.
Signed-off-by: Glease <4586901+Glease@users.noreply.github.com>
This commit is contained in:
1 parent
b5166dbd1c
commit
dc12c4a1df
40 files changed
+4085
No files matched your search
@@ -0,0 +1,22 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
*.sln merge=union
|
||||
*.csproj merge=union
|
||||
*.vbproj merge=union
|
||||
*.fsproj merge=union
|
||||
*.dbproj merge=union
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
*.class
|
||||
*.log
|
||||
*.ctxt
|
||||
.mtj.tmp/
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
hs_err_pid*
|
||||
.gradle
|
||||
**/build/
|
||||
!src/**/build/
|
||||
gradle-app.setting
|
||||
!gradle-wrapper.jar
|
||||
.gradletasknamecache
|
||||
.idea/
|
||||
run/
|
||||
@@ -0,0 +1,56 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = "forge"
|
||||
url = "https://files.minecraftforge.net/maven"
|
||||
}
|
||||
maven {
|
||||
name = "sonatype"
|
||||
url = "https://oss.sonatype.org/content/repositories/snapshots/"
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT'
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'forge'
|
||||
|
||||
version = modVersion
|
||||
group= modGroup
|
||||
archivesBaseName = modBaseName
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
minecraft {
|
||||
version = project.forgeVersion
|
||||
}
|
||||
|
||||
dependencies {
|
||||
}
|
||||
|
||||
processResources
|
||||
{
|
||||
inputs.property "version", project.version
|
||||
inputs.property "mcversion", project.minecraft.version
|
||||
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
include 'mcmod.info'
|
||||
expand 'version':project.version, 'mcversion':project.minecraft.version
|
||||
}
|
||||
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude 'mcmod.info'
|
||||
}
|
||||
}
|
||||
|
||||
task deobfJar(type: Jar) {
|
||||
from sourceSets.main.output
|
||||
appendix = 'deobf'
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives deobfJar
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
modGroup = com.gtnewhorizon
|
||||
modVersion = 1.0.0
|
||||
modBaseName = StructureLib
|
||||
|
||||
forgeVersion = 1.7.10-10.13.4.1614-1.7.10
|
||||
Vendored
BIN
Binary file not shown.
+6
@@ -0,0 +1,6 @@
|
||||
#Sat Jan 04 01:52:14 CET 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-bin.zip
|
||||
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# 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
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# 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\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
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" ] ; 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"`
|
||||
|
||||
# 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
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
Vendored
+90
@@ -0,0 +1,90 @@
|
||||
@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
|
||||
|
||||
@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=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@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 Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_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=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
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
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.gtnewhorizon.structurelib;
|
||||
|
||||
import com.gtnewhorizon.structurelib.proxy.CommonProxy;
|
||||
import com.gtnewhorizon.structurelib.util.XSTR;
|
||||
import cpw.mods.fml.common.Mod;
|
||||
import cpw.mods.fml.common.SidedProxy;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@Mod(modid = StructureLib.MOD_ID, name = "StructureLib", version = "${version}", acceptableRemoteVersions = "*", canBeDeactivated = false)
|
||||
public class StructureLib {
|
||||
public static boolean DEBUG_MODE = true;
|
||||
public static Logger LOGGER = LogManager.getLogger("StructureLib");
|
||||
public static final String MOD_ID = "structurelib";
|
||||
@SidedProxy(serverSide = "com.gtnewhorizon.structurelib.proxy.CommonProxy", clientSide = "com.gtnewhorizon.structurelib.proxy.ClientProxy")
|
||||
public static CommonProxy proxy;
|
||||
public static final XSTR RANDOM = new XSTR();
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
package com.gtnewhorizon.structurelib.alignment;
|
||||
|
||||
import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
|
||||
import com.gtnewhorizon.structurelib.alignment.enumerable.Flip;
|
||||
import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static com.gtnewhorizon.structurelib.alignment.IAlignment.STATES_COUNT;
|
||||
|
||||
public class AlignmentLimits implements IAlignmentLimits {
|
||||
|
||||
protected final boolean[] validStates=new boolean[STATES_COUNT];
|
||||
|
||||
public AlignmentLimits() {
|
||||
allowAll();
|
||||
}
|
||||
|
||||
AlignmentLimits allowAll(){
|
||||
Arrays.fill(validStates,true);
|
||||
return this;
|
||||
}
|
||||
|
||||
AlignmentLimits denyAll(){
|
||||
Arrays.fill(validStates,false);
|
||||
return this;
|
||||
}
|
||||
|
||||
AlignmentLimits randomAll(Random random){
|
||||
for (int i = 0; i < validStates.length; i++) {
|
||||
validStates[i]=random.nextBoolean();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
AlignmentLimits deny(ExtendedFacing... deny){
|
||||
if(deny!=null){
|
||||
for (ExtendedFacing extendedFacing : deny) {
|
||||
validStates[extendedFacing.getIndex()]=false;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
AlignmentLimits allow(ExtendedFacing... allow){
|
||||
if(allow!=null){
|
||||
for (ExtendedFacing extendedFacing : allow) {
|
||||
validStates[extendedFacing.getIndex()]=false;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
AlignmentLimits deny(ForgeDirection... deny){
|
||||
if(deny!=null){
|
||||
for (ExtendedFacing value : ExtendedFacing.VALUES) {
|
||||
for (ForgeDirection direction : deny) {
|
||||
if (value.getDirection() == direction) {
|
||||
validStates[value.getIndex()] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
AlignmentLimits allow(ForgeDirection... allow){
|
||||
if(allow!=null){
|
||||
for (ExtendedFacing value : ExtendedFacing.VALUES) {
|
||||
for (ForgeDirection direction : allow) {
|
||||
if (value.getDirection() == direction) {
|
||||
validStates[value.getIndex()] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
AlignmentLimits deny(Rotation... deny){
|
||||
if(deny!=null){
|
||||
for (ExtendedFacing value : ExtendedFacing.VALUES) {
|
||||
for (Rotation rotation : deny) {
|
||||
if (value.getRotation() == rotation) {
|
||||
validStates[value.getIndex()] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
AlignmentLimits allow(Rotation... allow){
|
||||
if(allow!=null){
|
||||
for (ExtendedFacing value : ExtendedFacing.VALUES) {
|
||||
for (Rotation rotation : allow) {
|
||||
if (value.getRotation() == rotation) {
|
||||
validStates[value.getIndex()] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
AlignmentLimits deny(Flip... deny){
|
||||
if(deny!=null){
|
||||
for (ExtendedFacing value : ExtendedFacing.VALUES) {
|
||||
for (Flip flip : deny) {
|
||||
if (value.getFlip() == flip) {
|
||||
validStates[value.getIndex()] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
AlignmentLimits allow(Flip... allow){
|
||||
if(allow!=null){
|
||||
for (ExtendedFacing value : ExtendedFacing.VALUES) {
|
||||
for (Flip flip : allow) {
|
||||
if (value.getFlip() == flip) {
|
||||
validStates[value.getIndex()] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
AlignmentLimits predicateApply(Function<ExtendedFacing,Optional<Boolean>> predicate){
|
||||
for (ExtendedFacing value : ExtendedFacing.VALUES) {
|
||||
predicate.apply(value).ifPresent(bool->validStates[value.getIndex()]=bool);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
AlignmentLimits ensureDuplicates(){
|
||||
for (ExtendedFacing value : ExtendedFacing.VALUES) {
|
||||
if(validStates[value.getIndex()]){
|
||||
validStates[value.getDuplicate().getIndex()]=true;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefers rotation over flip, so both flip will get translated to opposite rotation and no flip
|
||||
* @param flip the preferred flip to be used Horizontal or vertical
|
||||
* @return this
|
||||
*/
|
||||
AlignmentLimits ensureNoDuplicates(Flip flip){
|
||||
if(flip==Flip.BOTH||flip==Flip.NONE){
|
||||
throw new IllegalArgumentException("Preffered Flip must be Horizontal or Vertical");
|
||||
}
|
||||
flip=flip.getOpposite();
|
||||
for (ExtendedFacing value : ExtendedFacing.VALUES) {
|
||||
if(validStates[value.getIndex()]){
|
||||
if(value.getFlip()==Flip.BOTH || value.getFlip()==flip){
|
||||
validStates[value.getIndex()]=false;
|
||||
validStates[value.getDuplicate().getIndex()]=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNewExtendedFacingValid(ForgeDirection direction, Rotation rotation, Flip flip) {
|
||||
return validStates[IAlignment.getAlignmentIndex(direction,rotation,flip)];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.gtnewhorizon.structurelib.alignment;
|
||||
|
||||
import cpw.mods.fml.common.network.ByteBufUtils;
|
||||
import cpw.mods.fml.common.network.simpleimpl.IMessage;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
public class AlignmentMessage implements IMessage {
|
||||
int mPosX;
|
||||
int mPosY;
|
||||
int mPosZ;
|
||||
int mPosD;
|
||||
int mAlign;
|
||||
|
||||
public AlignmentMessage() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf pBuffer) {
|
||||
NBTTagCompound tTag = ByteBufUtils.readTag(pBuffer);
|
||||
mPosX = tTag.getInteger("posx");
|
||||
mPosY = tTag.getInteger("posy");
|
||||
mPosZ = tTag.getInteger("posz");
|
||||
mPosD = tTag.getInteger("posd");
|
||||
mAlign = tTag.getInteger("rotf");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf pBuffer) {
|
||||
NBTTagCompound tFXTag = new NBTTagCompound();
|
||||
tFXTag.setInteger("posx", mPosX);
|
||||
tFXTag.setInteger("posy", mPosY);
|
||||
tFXTag.setInteger("posz", mPosZ);
|
||||
tFXTag.setInteger("posd", mPosD);
|
||||
tFXTag.setInteger("rotf", mAlign);
|
||||
|
||||
ByteBufUtils.writeTag(pBuffer, tFXTag);
|
||||
}
|
||||
/*
|
||||
private AlignmentMessage(GT_MetaTileEntity_MultiblockBase_EM metaTile) {
|
||||
IGregTechTileEntity base=metaTile.getBaseMetaTileEntity();
|
||||
mPosX=base.getXCoord();
|
||||
mPosY=base.getYCoord();
|
||||
mPosZ=base.getZCoord();
|
||||
mPosD=base.getWorld().provider.dimensionId;
|
||||
mAlign =metaTile.getExtendedFacing().getIndex();
|
||||
}
|
||||
|
||||
private AlignmentMessage(World world, int x, int y, int z, IAlignment front) {
|
||||
mPosX=x;
|
||||
mPosY=y;
|
||||
mPosZ=z;
|
||||
mPosD=world.provider.dimensionId;
|
||||
mAlign =front.getExtendedFacing().getIndex();
|
||||
}
|
||||
|
||||
public static class AlignmentQuery extends AlignmentMessage {
|
||||
public AlignmentQuery() {
|
||||
}
|
||||
|
||||
public AlignmentQuery(GT_MetaTileEntity_MultiblockBase_EM metaTile) {
|
||||
super(metaTile);
|
||||
}
|
||||
|
||||
public AlignmentQuery(World world, int x, int y, int z, IAlignment front) {
|
||||
super(world,x,y,z,front);
|
||||
}
|
||||
}
|
||||
|
||||
public static class AlignmentData extends AlignmentMessage {
|
||||
public AlignmentData() {
|
||||
}
|
||||
|
||||
private AlignmentData(AlignmentQuery query){
|
||||
mPosX=query.mPosX;
|
||||
mPosY=query.mPosY;
|
||||
mPosZ=query.mPosZ;
|
||||
mPosD=query.mPosD;
|
||||
mAlign =query.mAlign;
|
||||
}
|
||||
|
||||
public AlignmentData(GT_MetaTileEntity_MultiblockBase_EM metaTile) {
|
||||
super(metaTile);
|
||||
}
|
||||
|
||||
public AlignmentData(World world, int x, int y, int z, IAlignment front) {
|
||||
super(world,x,y,z,front);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ClientHandler extends AbstractClientMessageHandler<AlignmentData> {
|
||||
@Override
|
||||
public IMessage handleClientMessage(EntityPlayer pPlayer, AlignmentData pMessage, MessageContext pCtx) {
|
||||
if(pPlayer.worldObj.provider.dimensionId==pMessage.mPosD){
|
||||
TileEntity te=pPlayer.worldObj.getTileEntity(pMessage.mPosX,pMessage.mPosY,pMessage.mPosZ);
|
||||
if(te instanceof IGregTechTileEntity){
|
||||
IMetaTileEntity meta = ((IGregTechTileEntity) te).getMetaTileEntity();
|
||||
if(meta instanceof IAlignment){
|
||||
((IAlignment) meta).setExtendedFacing(ExtendedFacing.byIndex(pMessage.mAlign));
|
||||
}
|
||||
}else if (te instanceof IAlignment){
|
||||
((IAlignment) te).setExtendedFacing(ExtendedFacing.byIndex(pMessage.mAlign));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ServerHandler extends AbstractServerMessageHandler<AlignmentQuery> {
|
||||
@Override
|
||||
public IMessage handleServerMessage(EntityPlayer pPlayer, AlignmentQuery pMessage, MessageContext pCtx) {
|
||||
World world= DimensionManager.getWorld(pMessage.mPosD);
|
||||
if(world!=null) {
|
||||
TileEntity te = world.getTileEntity(pMessage.mPosX, pMessage.mPosY, pMessage.mPosZ);
|
||||
if (te instanceof IGregTechTileEntity) {
|
||||
IMetaTileEntity meta = ((IGregTechTileEntity) te).getMetaTileEntity();
|
||||
if (meta instanceof IAlignment) {
|
||||
pMessage.mAlign =((IAlignment) meta).getExtendedFacing().getIndex();
|
||||
return new AlignmentData(pMessage);
|
||||
}
|
||||
} else if (te instanceof IAlignment) {
|
||||
pMessage.mAlign =((IAlignment) te).getExtendedFacing().getIndex();
|
||||
return new AlignmentData(pMessage);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.gtnewhorizon.structurelib.alignment;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
|
||||
public class AlignmentUtility {
|
||||
private AlignmentUtility(){
|
||||
}
|
||||
|
||||
public static boolean handle(EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ){
|
||||
TileEntity tTileEntity = aWorld.getTileEntity(aX, aY, aZ);
|
||||
if(tTileEntity==null || aPlayer instanceof FakePlayer) {
|
||||
return aPlayer instanceof EntityPlayerMP;
|
||||
}
|
||||
if (aPlayer instanceof EntityPlayerMP) {
|
||||
/* TODO Make GT tile entity implement this interface and delegate all functionality to MTE
|
||||
if (tTileEntity instanceof IGregTechTileEntity) {
|
||||
IMetaTileEntity metaTE = ((IGregTechTileEntity) tTileEntity).getMetaTileEntity();
|
||||
if (metaTE instanceof IAlignmentProvider) {
|
||||
IAlignment alignment = ((IAlignmentProvider) metaTE).getAlignment();
|
||||
if(aPlayer.isSneaking()){
|
||||
alignment.toolSetFlip(null);
|
||||
}else {
|
||||
alignment.toolSetRotation(null);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else */ if (tTileEntity instanceof IAlignmentProvider) {
|
||||
IAlignment alignment = ((IAlignmentProvider) tTileEntity).getAlignment();
|
||||
if(aPlayer.isSneaking()){
|
||||
alignment.toolSetFlip(null);
|
||||
}else {
|
||||
alignment.toolSetRotation(null);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package com.gtnewhorizon.structurelib.alignment;
|
||||
|
||||
import com.gtnewhorizon.structurelib.alignment.enumerable.Direction;
|
||||
import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
|
||||
import com.gtnewhorizon.structurelib.alignment.enumerable.Flip;
|
||||
import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public interface IAlignment extends IAlignmentLimits,IAlignmentProvider {
|
||||
int DIRECTIONS_COUNT= Direction.VALUES.length;
|
||||
int ROTATIONS_COUNT= Rotation.VALUES.length;
|
||||
int FLIPS_COUNT= Flip.VALUES.length;
|
||||
int STATES_COUNT = ExtendedFacing.VALUES.length;
|
||||
|
||||
ExtendedFacing getExtendedFacing();
|
||||
|
||||
void setExtendedFacing(ExtendedFacing alignment);
|
||||
|
||||
IAlignmentLimits getAlignmentLimits();
|
||||
|
||||
void setAlignmentLimits(IAlignmentLimits limits);
|
||||
|
||||
@Override
|
||||
default IAlignment getAlignment(){
|
||||
return this;
|
||||
}
|
||||
|
||||
static int getAlignmentIndex(ForgeDirection direction, Rotation rotation, Flip flip){
|
||||
return (direction.ordinal()*ROTATIONS_COUNT+rotation.getIndex())*FLIPS_COUNT+flip.getIndex();
|
||||
}
|
||||
|
||||
default ForgeDirection getDirection(){
|
||||
return getExtendedFacing().getDirection();
|
||||
}
|
||||
|
||||
default void setDirection(ForgeDirection direction){
|
||||
setExtendedFacing(getExtendedFacing().with(direction));
|
||||
}
|
||||
|
||||
default Rotation getRotation(){
|
||||
return getExtendedFacing().getRotation();
|
||||
}
|
||||
|
||||
default void setRotation(Rotation rotation){
|
||||
setExtendedFacing(getExtendedFacing().with(rotation));
|
||||
}
|
||||
|
||||
default Flip getFlip(){
|
||||
return getExtendedFacing().getFlip();
|
||||
}
|
||||
|
||||
default void setFlip(Flip flip){
|
||||
setExtendedFacing(getExtendedFacing().with(flip));
|
||||
}
|
||||
|
||||
default boolean toolSetDirection(ForgeDirection direction){
|
||||
if(direction==null || direction==ForgeDirection.UNKNOWN){
|
||||
for (int i = 0,j=getDirection().ordinal()+1, valuesLength = Direction.VALUES.length; i < valuesLength; i++) {
|
||||
if(toolSetDirection(Direction.VALUES[j%valuesLength].getForgeDirection())){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}else {
|
||||
for (ExtendedFacing extendedFacing : ExtendedFacing.FOR_FACING.get(direction)) {
|
||||
if(checkedSetExtendedFacing(extendedFacing)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean checkedSetDirection(ForgeDirection direction){
|
||||
if (isNewDirectionValid(direction)){
|
||||
setDirection(direction);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean canSetToDirectionAny(ForgeDirection direction){
|
||||
for (ExtendedFacing extendedFacing : ExtendedFacing.FOR_FACING.get(direction)) {
|
||||
if(isNewExtendedFacingValid(extendedFacing)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean toolSetRotation(Rotation rotation) {
|
||||
if(rotation==null){
|
||||
int flips = Flip.VALUES.length;
|
||||
int rotations = Rotation.VALUES.length;
|
||||
for (int ii = 0,jj=getFlip().ordinal(); ii < flips; ii++) {
|
||||
for (int i = 0,j=getRotation().ordinal()+1; i < rotations; i++) {
|
||||
if(checkedSetExtendedFacing(ExtendedFacing.of(getDirection(),Rotation.VALUES[j%rotations],Flip.VALUES[jj%flips]))){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}else {
|
||||
return checkedSetRotation(rotation);
|
||||
}
|
||||
}
|
||||
|
||||
default boolean checkedSetRotation(Rotation rotation){
|
||||
if (isNewRotationValid(rotation)){
|
||||
setRotation(rotation);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean toolSetFlip(Flip flip){
|
||||
if(flip==null){
|
||||
for (int i = 0,j=getFlip().ordinal()+1, valuesLength = Flip.VALUES.length; i < valuesLength; i++) {
|
||||
if(toolSetFlip(Flip.VALUES[j%valuesLength])){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}else {
|
||||
return checkedSetFlip(flip);
|
||||
}
|
||||
}
|
||||
|
||||
default boolean checkedSetFlip(Flip flip){
|
||||
if (isNewFlipValid(flip)){
|
||||
setFlip(flip);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean toolSetExtendedFacing(ExtendedFacing extendedFacing){
|
||||
if(extendedFacing==null){
|
||||
for (int i = 0,j=getExtendedFacing().ordinal()+1, valuesLength = ExtendedFacing.VALUES.length; i < valuesLength; i++) {
|
||||
if(toolSetExtendedFacing(ExtendedFacing.VALUES[j%valuesLength])){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}else {
|
||||
return checkedSetExtendedFacing(extendedFacing);
|
||||
}
|
||||
}
|
||||
|
||||
default boolean checkedSetExtendedFacing(ExtendedFacing alignment){
|
||||
if (isNewExtendedFacingValid(alignment)){
|
||||
setExtendedFacing(alignment);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean isNewDirectionValid(ForgeDirection direction) {
|
||||
return isNewExtendedFacingValid(direction,getRotation(),getFlip());
|
||||
}
|
||||
|
||||
default boolean isNewRotationValid(Rotation rotation){
|
||||
return isNewExtendedFacingValid(getDirection(),rotation,getFlip());
|
||||
}
|
||||
|
||||
default boolean isNewFlipValid(Flip flip){
|
||||
return isNewExtendedFacingValid(getDirection(),getRotation(),flip);
|
||||
}
|
||||
|
||||
default boolean isExtendedFacingValid() {
|
||||
return isNewExtendedFacingValid(getDirection(),getRotation(),getFlip());
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isNewExtendedFacingValid(ForgeDirection direction, Rotation rotation, Flip flip){
|
||||
return getAlignmentLimits().isNewExtendedFacingValid(direction, rotation, flip);
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isNewExtendedFacingValid(ExtendedFacing alignment){
|
||||
return getAlignmentLimits().isNewExtendedFacingValid(
|
||||
alignment.getDirection(),
|
||||
alignment.getRotation(),
|
||||
alignment.getFlip());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.gtnewhorizon.structurelib.alignment;
|
||||
import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
|
||||
import com.gtnewhorizon.structurelib.alignment.enumerable.Flip;
|
||||
import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public interface IAlignmentLimits {
|
||||
|
||||
IAlignmentLimits UNLIMITED= (direction, rotation, flip) -> true;
|
||||
|
||||
boolean isNewExtendedFacingValid(ForgeDirection direction, Rotation rotation, Flip flip);
|
||||
|
||||
default boolean isNewExtendedFacingValid(ExtendedFacing alignment){
|
||||
return isNewExtendedFacingValid(
|
||||
alignment.getDirection(),
|
||||
alignment.getRotation(),
|
||||
alignment.getFlip());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.gtnewhorizon.structurelib.alignment;
|
||||
|
||||
public interface IAlignmentProvider {
|
||||
IAlignment getAlignment();
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.gtnewhorizon.structurelib.alignment;
|
||||
|
||||
import com.gtnewhorizon.structurelib.util.Vec3Impl;
|
||||
import com.gtnewhorizon.structurelib.alignment.enumerable.Direction;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
public class IntegerAxisSwap {
|
||||
private final Vec3Impl forFirstAxis;
|
||||
private final Vec3Impl forSecondAxis;
|
||||
private final Vec3Impl forThirdAxis;
|
||||
|
||||
public IntegerAxisSwap(ForgeDirection forFirstAxis, ForgeDirection forSecondAxis, ForgeDirection forThirdAxis) {
|
||||
this.forFirstAxis = Direction.getAxisVector(forFirstAxis);
|
||||
this.forSecondAxis = Direction.getAxisVector(forSecondAxis);
|
||||
this.forThirdAxis = Direction.getAxisVector(forThirdAxis);
|
||||
if(abs(this.forFirstAxis.get0())+abs(this.forSecondAxis.get0())+abs(this.forThirdAxis.get0())!=1 ||
|
||||
abs(this.forFirstAxis.get1())+abs(this.forSecondAxis.get1())+abs(this.forThirdAxis.get1())!=1 ||
|
||||
abs(this.forFirstAxis.get2())+abs(this.forSecondAxis.get2())+abs(this.forThirdAxis.get2())!=1){
|
||||
throw new IllegalArgumentException("Axis are overlapping/missing! "+
|
||||
forFirstAxis.name()+" "+
|
||||
forSecondAxis.name()+" "+
|
||||
forThirdAxis.name());
|
||||
}
|
||||
}
|
||||
|
||||
public Vec3Impl translate(Vec3Impl point){
|
||||
return new Vec3Impl(
|
||||
forFirstAxis.get0()*point.get0() +forFirstAxis.get1()*point.get1() +forFirstAxis.get2()*point.get2(),
|
||||
forSecondAxis.get0()*point.get0()+forSecondAxis.get1()*point.get1()+forSecondAxis.get2()*point.get2(),
|
||||
forThirdAxis.get0()*point.get0() +forThirdAxis.get1()*point.get1() +forThirdAxis.get2()*point.get2()
|
||||
);
|
||||
}
|
||||
|
||||
public Vec3Impl inverseTranslate(Vec3Impl point){
|
||||
return new Vec3Impl(
|
||||
forFirstAxis.get0()*point.get0()+forSecondAxis.get0()*point.get1()+forThirdAxis.get0()*point.get2(),
|
||||
forFirstAxis.get1()*point.get0()+forSecondAxis.get1()*point.get1()+forThirdAxis.get1()*point.get2(),
|
||||
forFirstAxis.get2()*point.get0()+forSecondAxis.get2()*point.get1()+forThirdAxis.get2()*point.get2()
|
||||
);
|
||||
}
|
||||
|
||||
public Vec3 translate(Vec3 point){
|
||||
return Vec3.createVectorHelper(
|
||||
forFirstAxis.get0()*point.xCoord +forFirstAxis.get1()*point.yCoord +forFirstAxis.get2()*point.zCoord,
|
||||
forSecondAxis.get0()*point.xCoord+forSecondAxis.get1()*point.yCoord+forSecondAxis.get2()*point.zCoord,
|
||||
forThirdAxis.get0()*point.xCoord +forThirdAxis.get1()*point.yCoord +forThirdAxis.get2()*point.zCoord
|
||||
);
|
||||
}
|
||||
|
||||
public Vec3 inverseTranslate(Vec3 point){
|
||||
return Vec3.createVectorHelper(
|
||||
forFirstAxis.get0()*point.xCoord+forSecondAxis.get0()*point.yCoord+forThirdAxis.get0()*point.zCoord,
|
||||
forFirstAxis.get1()*point.xCoord+forSecondAxis.get1()*point.yCoord+forThirdAxis.get1()*point.zCoord,
|
||||
forFirstAxis.get2()*point.xCoord+forSecondAxis.get2()*point.yCoord+forThirdAxis.get2()*point.zCoord
|
||||
);
|
||||
}
|
||||
|
||||
public void translate(int[] point,int[] out){
|
||||
out[0]=forFirstAxis.get0()*point[0] +forFirstAxis.get1()*point[1] +forFirstAxis.get2()*point[2];
|
||||
out[1]=forSecondAxis.get0()*point[0]+forSecondAxis.get1()*point[1]+forSecondAxis.get2()*point[2];
|
||||
out[2]=forThirdAxis.get0()*point[0] +forThirdAxis.get1()*point[1] +forThirdAxis.get2()*point[2];
|
||||
}
|
||||
|
||||
public void inverseTranslate(int[] point,int[] out){
|
||||
out[0]=forFirstAxis.get0()*point[0]+forSecondAxis.get0()*point[1]+forThirdAxis.get0()*point[2];
|
||||
out[1]=forFirstAxis.get1()*point[0]+forSecondAxis.get1()*point[1]+forThirdAxis.get1()*point[2];
|
||||
out[2]=forFirstAxis.get2()*point[0]+forSecondAxis.get2()*point[1]+forThirdAxis.get2()*point[2];
|
||||
}
|
||||
|
||||
public void translate(double[] point,double[] out){
|
||||
out[0]=forFirstAxis.get0()*point[0] +forFirstAxis.get1()*point[1] +forFirstAxis.get2()*point[2];
|
||||
out[1]=forSecondAxis.get0()*point[0]+forSecondAxis.get1()*point[1]+forSecondAxis.get2()*point[2];
|
||||
out[2]=forThirdAxis.get0()*point[0] +forThirdAxis.get1()*point[1] +forThirdAxis.get2()*point[2];
|
||||
}
|
||||
|
||||
public void inverseTranslate(double[] point,double[] out){
|
||||
out[0]=forFirstAxis.get0()*point[0]+forSecondAxis.get0()*point[1]+forThirdAxis.get0()*point[2];
|
||||
out[1]=forFirstAxis.get1()*point[0]+forSecondAxis.get1()*point[1]+forThirdAxis.get1()*point[2];
|
||||
out[2]=forFirstAxis.get2()*point[0]+forSecondAxis.get2()*point[1]+forThirdAxis.get2()*point[2];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.gtnewhorizon.structurelib.alignment.enumerable;
|
||||
|
||||
import com.gtnewhorizon.structurelib.util.Vec3Impl;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public enum Direction {
|
||||
DOWN(ForgeDirection.DOWN),
|
||||
UP(ForgeDirection.UP),
|
||||
NORTH(ForgeDirection.NORTH),
|
||||
SOUTH(ForgeDirection.SOUTH),
|
||||
WEST(ForgeDirection.WEST),
|
||||
EAST(ForgeDirection.EAST);
|
||||
|
||||
private final ForgeDirection forgeDirection;
|
||||
private final Vec3Impl axisVector;
|
||||
public static final Direction[] VALUES=values();
|
||||
|
||||
Direction(ForgeDirection forgeDirection) {
|
||||
this.forgeDirection = forgeDirection;
|
||||
axisVector=new Vec3Impl(forgeDirection.offsetX,forgeDirection.offsetY,forgeDirection.offsetZ);
|
||||
}
|
||||
|
||||
public ForgeDirection getForgeDirection() {
|
||||
return forgeDirection;
|
||||
}
|
||||
|
||||
public Vec3Impl getAxisVector() {
|
||||
return axisVector;
|
||||
}
|
||||
|
||||
public static Vec3Impl getAxisVector(ForgeDirection forgeDirection){
|
||||
return VALUES[forgeDirection.ordinal()].axisVector;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,358 @@
|
||||
package com.gtnewhorizon.structurelib.alignment.enumerable;
|
||||
|
||||
import com.gtnewhorizon.structurelib.alignment.IAlignment;
|
||||
import com.gtnewhorizon.structurelib.alignment.IntegerAxisSwap;
|
||||
import com.gtnewhorizon.structurelib.util.Vec3Impl;
|
||||
import net.minecraft.util.Vec3;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.gtnewhorizon.structurelib.alignment.IAlignment.FLIPS_COUNT;
|
||||
import static com.gtnewhorizon.structurelib.alignment.IAlignment.ROTATIONS_COUNT;
|
||||
import static java.lang.Math.abs;
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
public enum ExtendedFacing {
|
||||
DOWN_NORMAL_NONE("down normal none"),
|
||||
DOWN_NORMAL_HORIZONTAL("down normal horizontal"),
|
||||
DOWN_NORMAL_VERTICAL("down normal vertical"),
|
||||
DOWN_NORMAL_BOTH("down normal both"),
|
||||
DOWN_CLOCKWISE_NONE("down clockwise none"),
|
||||
DOWN_CLOCKWISE_HORIZONTAL("down clockwise horizontal"),
|
||||
DOWN_CLOCKWISE_VERTICAL("down clockwise vertical"),
|
||||
DOWN_CLOCKWISE_BOTH("down clockwise both"),
|
||||
DOWN_UPSIDE_DOWN_NONE("down upside down none"),
|
||||
DOWN_UPSIDE_DOWN_HORIZONTAL("down upside down horizontal"),
|
||||
DOWN_UPSIDE_DOWN_VERTICAL("down upside down vertical"),
|
||||
DOWN_UPSIDE_DOWN_BOTH("down upside down both"),
|
||||
DOWN_COUNTER_CLOCKWISE_NONE("down counter clockwise none"),
|
||||
DOWN_COUNTER_CLOCKWISE_HORIZONTAL("down counter clockwise horizontal"),
|
||||
DOWN_COUNTER_CLOCKWISE_VERTICAL("down counter clockwise vertical"),
|
||||
DOWN_COUNTER_CLOCKWISE_BOTH("down counter clockwise both"),
|
||||
UP_NORMAL_NONE("up normal none"),
|
||||
UP_NORMAL_HORIZONTAL("up normal horizontal"),
|
||||
UP_NORMAL_VERTICAL("up normal vertical"),
|
||||
UP_NORMAL_BOTH("up normal both"),
|
||||
UP_CLOCKWISE_NONE("up clockwise none"),
|
||||
UP_CLOCKWISE_HORIZONTAL("up clockwise horizontal"),
|
||||
UP_CLOCKWISE_VERTICAL("up clockwise vertical"),
|
||||
UP_CLOCKWISE_BOTH("up clockwise both"),
|
||||
UP_UPSIDE_DOWN_NONE("up upside down none"),
|
||||
UP_UPSIDE_DOWN_HORIZONTAL("up upside down horizontal"),
|
||||
UP_UPSIDE_DOWN_VERTICAL("up upside down vertical"),
|
||||
UP_UPSIDE_DOWN_BOTH("up upside down both"),
|
||||
UP_COUNTER_CLOCKWISE_NONE("up counter clockwise none"),
|
||||
UP_COUNTER_CLOCKWISE_HORIZONTAL("up counter clockwise horizontal"),
|
||||
UP_COUNTER_CLOCKWISE_VERTICAL("up counter clockwise vertical"),
|
||||
UP_COUNTER_CLOCKWISE_BOTH("up counter clockwise both"),
|
||||
NORTH_NORMAL_NONE("north normal none"),
|
||||
NORTH_NORMAL_HORIZONTAL("north normal horizontal"),
|
||||
NORTH_NORMAL_VERTICAL("north normal vertical"),
|
||||
NORTH_NORMAL_BOTH("north normal both"),
|
||||
NORTH_CLOCKWISE_NONE("north clockwise none"),
|
||||
NORTH_CLOCKWISE_HORIZONTAL("north clockwise horizontal"),
|
||||
NORTH_CLOCKWISE_VERTICAL("north clockwise vertical"),
|
||||
NORTH_CLOCKWISE_BOTH("north clockwise both"),
|
||||
NORTH_UPSIDE_DOWN_NONE("north upside down none"),
|
||||
NORTH_UPSIDE_DOWN_HORIZONTAL("north upside down horizontal"),
|
||||
NORTH_UPSIDE_DOWN_VERTICAL("north upside down vertical"),
|
||||
NORTH_UPSIDE_DOWN_BOTH("north upside down both"),
|
||||
NORTH_COUNTER_CLOCKWISE_NONE("north counter clockwise none"),
|
||||
NORTH_COUNTER_CLOCKWISE_HORIZONTAL("north counter clockwise horizontal"),
|
||||
NORTH_COUNTER_CLOCKWISE_VERTICAL("north counter clockwise vertical"),
|
||||
NORTH_COUNTER_CLOCKWISE_BOTH("north counter clockwise both"),
|
||||
SOUTH_NORMAL_NONE("south normal none"),
|
||||
SOUTH_NORMAL_HORIZONTAL("south normal horizontal"),
|
||||
SOUTH_NORMAL_VERTICAL("south normal vertical"),
|
||||
SOUTH_NORMAL_BOTH("south normal both"),
|
||||
SOUTH_CLOCKWISE_NONE("south clockwise none"),
|
||||
SOUTH_CLOCKWISE_HORIZONTAL("south clockwise horizontal"),
|
||||
SOUTH_CLOCKWISE_VERTICAL("south clockwise vertical"),
|
||||
SOUTH_CLOCKWISE_BOTH("south clockwise both"),
|
||||
SOUTH_UPSIDE_DOWN_NONE("south upside down none"),
|
||||
SOUTH_UPSIDE_DOWN_HORIZONTAL("south upside down horizontal"),
|
||||
SOUTH_UPSIDE_DOWN_VERTICAL("south upside down vertical"),
|
||||
SOUTH_UPSIDE_DOWN_BOTH("south upside down both"),
|
||||
SOUTH_COUNTER_CLOCKWISE_NONE("south counter clockwise none"),
|
||||
SOUTH_COUNTER_CLOCKWISE_HORIZONTAL("south counter clockwise horizontal"),
|
||||
SOUTH_COUNTER_CLOCKWISE_VERTICAL("south counter clockwise vertical"),
|
||||
SOUTH_COUNTER_CLOCKWISE_BOTH("south counter clockwise both"),
|
||||
WEST_NORMAL_NONE("west normal none"),
|
||||
WEST_NORMAL_HORIZONTAL("west normal horizontal"),
|
||||
WEST_NORMAL_VERTICAL("west normal vertical"),
|
||||
WEST_NORMAL_BOTH("west normal both"),
|
||||
WEST_CLOCKWISE_NONE("west clockwise none"),
|
||||
WEST_CLOCKWISE_HORIZONTAL("west clockwise horizontal"),
|
||||
WEST_CLOCKWISE_VERTICAL("west clockwise vertical"),
|
||||
WEST_CLOCKWISE_BOTH("west clockwise both"),
|
||||
WEST_UPSIDE_DOWN_NONE("west upside down none"),
|
||||
WEST_UPSIDE_DOWN_HORIZONTAL("west upside down horizontal"),
|
||||
WEST_UPSIDE_DOWN_VERTICAL("west upside down vertical"),
|
||||
WEST_UPSIDE_DOWN_BOTH("west upside down both"),
|
||||
WEST_COUNTER_CLOCKWISE_NONE("west counter clockwise none"),
|
||||
WEST_COUNTER_CLOCKWISE_HORIZONTAL("west counter clockwise horizontal"),
|
||||
WEST_COUNTER_CLOCKWISE_VERTICAL("west counter clockwise vertical"),
|
||||
WEST_COUNTER_CLOCKWISE_BOTH("west counter clockwise both"),
|
||||
EAST_NORMAL_NONE("east normal none"),
|
||||
EAST_NORMAL_HORIZONTAL("east normal horizontal"),
|
||||
EAST_NORMAL_VERTICAL("east normal vertical"),
|
||||
EAST_NORMAL_BOTH("east normal both"),
|
||||
EAST_CLOCKWISE_NONE("east clockwise none"),
|
||||
EAST_CLOCKWISE_HORIZONTAL("east clockwise horizontal"),
|
||||
EAST_CLOCKWISE_VERTICAL("east clockwise vertical"),
|
||||
EAST_CLOCKWISE_BOTH("east clockwise both"),
|
||||
EAST_UPSIDE_DOWN_NONE("east upside down none"),
|
||||
EAST_UPSIDE_DOWN_HORIZONTAL("east upside down horizontal"),
|
||||
EAST_UPSIDE_DOWN_VERTICAL("east upside down vertical"),
|
||||
EAST_UPSIDE_DOWN_BOTH("east upside down both"),
|
||||
EAST_COUNTER_CLOCKWISE_NONE("east counter clockwise none"),
|
||||
EAST_COUNTER_CLOCKWISE_HORIZONTAL("east counter clockwise horizontal"),
|
||||
EAST_COUNTER_CLOCKWISE_VERTICAL("east counter clockwise vertical"),
|
||||
EAST_COUNTER_CLOCKWISE_BOTH("east counter clockwise both");
|
||||
|
||||
public static final ExtendedFacing DEFAULT=NORTH_NORMAL_NONE;
|
||||
public static final ExtendedFacing[] VALUES = values();
|
||||
public static final Map<ForgeDirection, List<ExtendedFacing>> FOR_FACING=new HashMap<>();
|
||||
static {
|
||||
stream(values()).forEach(extendedFacing ->
|
||||
FOR_FACING.compute(extendedFacing.direction,((forgeDirection, extendedFacings) -> {
|
||||
if(extendedFacings==null){
|
||||
extendedFacings = new ArrayList<>();
|
||||
}
|
||||
extendedFacings.add(extendedFacing);
|
||||
return extendedFacings;
|
||||
})));
|
||||
}
|
||||
private static final Map<String, ExtendedFacing> NAME_LOOKUP = stream(VALUES).collect(toMap(ExtendedFacing::getName2, (extendedFacing) -> extendedFacing));
|
||||
|
||||
private final ForgeDirection direction;
|
||||
private final ForgeDirection a,b,c;
|
||||
private final Rotation rotation;
|
||||
private final Flip flip;
|
||||
|
||||
private final String name;
|
||||
private final IntegerAxisSwap integerAxisSwap;
|
||||
|
||||
ExtendedFacing(String name) {
|
||||
this.name = name;
|
||||
direction= Direction.VALUES[ordinal()/(ROTATIONS_COUNT*FLIPS_COUNT)].getForgeDirection();
|
||||
rotation=Rotation.VALUES[ordinal()/FLIPS_COUNT-direction.ordinal()*ROTATIONS_COUNT];
|
||||
flip=Flip.VALUES[ordinal()%FLIPS_COUNT];
|
||||
ForgeDirection a,b,c;
|
||||
switch (direction){
|
||||
case DOWN:
|
||||
a= ForgeDirection.WEST;
|
||||
b= ForgeDirection.SOUTH;
|
||||
c= ForgeDirection.UP;
|
||||
break;
|
||||
case UP:
|
||||
a= ForgeDirection.EAST;
|
||||
b= ForgeDirection.SOUTH;
|
||||
c= ForgeDirection.DOWN;
|
||||
break;
|
||||
case NORTH:
|
||||
a= ForgeDirection.WEST;
|
||||
b= ForgeDirection.DOWN;
|
||||
c= ForgeDirection.SOUTH;
|
||||
break;
|
||||
case SOUTH:
|
||||
a= ForgeDirection.EAST;
|
||||
b= ForgeDirection.DOWN;
|
||||
c= ForgeDirection.NORTH;
|
||||
break;
|
||||
case WEST:
|
||||
a= ForgeDirection.SOUTH;
|
||||
b= ForgeDirection.DOWN;
|
||||
c= ForgeDirection.EAST;
|
||||
break;
|
||||
case EAST:
|
||||
a= ForgeDirection.NORTH;
|
||||
b= ForgeDirection.DOWN;
|
||||
c= ForgeDirection.WEST;
|
||||
break;
|
||||
default:throw new RuntimeException("Is impossible...");
|
||||
}
|
||||
switch (flip){//This duplicates some axis swaps since flip boolean would do, but seems more convenient to use
|
||||
case HORIZONTAL:
|
||||
a=a.getOpposite();
|
||||
break;
|
||||
case BOTH:
|
||||
a=a.getOpposite();
|
||||
case VERTICAL:
|
||||
b=b.getOpposite();
|
||||
break;
|
||||
case NONE: break;
|
||||
default:throw new RuntimeException("Even more impossible...");
|
||||
}
|
||||
switch (rotation) {
|
||||
case CLOCKWISE: {
|
||||
ForgeDirection _a=a;
|
||||
a =b;
|
||||
b =_a.getOpposite();
|
||||
break;
|
||||
}
|
||||
case UPSIDE_DOWN:
|
||||
a=a.getOpposite();
|
||||
b=b.getOpposite();
|
||||
break;
|
||||
case COUNTER_CLOCKWISE: {
|
||||
ForgeDirection _a=a;
|
||||
a =b.getOpposite();
|
||||
b =_a;
|
||||
break;
|
||||
}
|
||||
case NORMAL: break;
|
||||
default:
|
||||
throw new RuntimeException("More impossible...");
|
||||
}
|
||||
this.a=a;
|
||||
this.b=b;
|
||||
this.c=c;
|
||||
integerAxisSwap =new IntegerAxisSwap(a,b,c);
|
||||
}
|
||||
|
||||
public static ExtendedFacing of(ForgeDirection direction, Rotation rotation, Flip flip){
|
||||
if(direction==ForgeDirection.UNKNOWN){
|
||||
return VALUES[IAlignment.getAlignmentIndex(ForgeDirection.NORTH, rotation, flip)];
|
||||
}
|
||||
return VALUES[IAlignment.getAlignmentIndex(direction, rotation, flip)];
|
||||
}
|
||||
|
||||
public static ExtendedFacing of(ForgeDirection direction){
|
||||
if(direction==ForgeDirection.UNKNOWN){
|
||||
return DEFAULT;
|
||||
}
|
||||
return VALUES[IAlignment.getAlignmentIndex(direction, Rotation.NORMAL, Flip.NONE)];
|
||||
}
|
||||
|
||||
public ExtendedFacing with(ForgeDirection direction){
|
||||
return of(direction,rotation,flip);
|
||||
}
|
||||
|
||||
public ExtendedFacing with(Rotation rotation){
|
||||
return of(direction,rotation,flip);
|
||||
}
|
||||
|
||||
public ExtendedFacing with(Flip flip){
|
||||
return of(direction,rotation,flip);
|
||||
}
|
||||
|
||||
public ExtendedFacing getOppositeDirection() {
|
||||
return of(direction.getOpposite(),rotation,flip);
|
||||
}
|
||||
|
||||
public ExtendedFacing getOppositeRotation() {
|
||||
return of(direction,rotation.getOpposite(),flip);
|
||||
}
|
||||
|
||||
public ExtendedFacing getOppositeFlip() {
|
||||
return of(direction,rotation,flip.getOpposite());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the same effective facing achieved by different rot/flip combo
|
||||
* @return same effective facing, but different enum value
|
||||
*/
|
||||
public ExtendedFacing getDuplicate(){
|
||||
return of(direction,rotation.getOpposite(),flip.getOpposite());
|
||||
}
|
||||
|
||||
public int getIndex(){
|
||||
return ordinal();
|
||||
}
|
||||
|
||||
public String getName2() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public static ExtendedFacing byName(String name) {
|
||||
return name == null ? null : NAME_LOOKUP.get(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
public static ExtendedFacing byIndex(int index) {
|
||||
return VALUES[abs(index % VALUES.length)];
|
||||
}
|
||||
|
||||
public static ExtendedFacing random(Random rand) {
|
||||
return VALUES[rand.nextInt(VALUES.length)];
|
||||
}
|
||||
|
||||
public ForgeDirection getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public Rotation getRotation() {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
public Flip getFlip() {
|
||||
return flip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates relative to front facing offset to world offset
|
||||
* @param abcOffset A,B,C offset (facing relative L-->R,U-->D,F-->B)
|
||||
* @return X,Y,Z offset in world
|
||||
*/
|
||||
public Vec3 getWorldOffset(Vec3 abcOffset) {
|
||||
return integerAxisSwap.inverseTranslate(abcOffset);
|
||||
}
|
||||
public Vec3Impl getWorldOffset(Vec3Impl abcOffset) {
|
||||
return integerAxisSwap.inverseTranslate(abcOffset);
|
||||
}
|
||||
public void getWorldOffset(int[] point,int[] out){
|
||||
integerAxisSwap.inverseTranslate(point,out);
|
||||
}
|
||||
public void getWorldOffset(double[] point,double[] out){
|
||||
integerAxisSwap.inverseTranslate(point,out);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translates world offset to relative front facing offset
|
||||
* @param xyzOffset X,Y,Z offset in world
|
||||
* @return A,B,C offset (facing relative L-->R,U-->D,F-->B)
|
||||
*/
|
||||
public Vec3 getOffsetABC(Vec3 xyzOffset){
|
||||
return integerAxisSwap.translate(xyzOffset);
|
||||
}
|
||||
public Vec3Impl getOffsetABC(Vec3Impl xyzOffset){
|
||||
return integerAxisSwap.translate(xyzOffset);
|
||||
}
|
||||
public void getOffsetABC(int[] point,int[] out){
|
||||
integerAxisSwap.translate(point,out);
|
||||
}
|
||||
public void getOffsetABC(double[] point,double[] out){
|
||||
integerAxisSwap.translate(point,out);
|
||||
}
|
||||
|
||||
public IntegerAxisSwap getIntegerAxisSwap() {
|
||||
return integerAxisSwap;
|
||||
}
|
||||
|
||||
public ForgeDirection getRelativeLeftInWorld() {
|
||||
return a;
|
||||
}
|
||||
|
||||
public ForgeDirection getRelativeRightInWorld() {
|
||||
return a.getOpposite();
|
||||
}
|
||||
|
||||
public ForgeDirection getRelativeDownInWorld() {
|
||||
return b;
|
||||
}
|
||||
|
||||
public ForgeDirection getRelativeUpInWorld() {
|
||||
return b.getOpposite();
|
||||
}
|
||||
|
||||
public ForgeDirection getRelativeBackInWorld() {
|
||||
return c;
|
||||
}
|
||||
|
||||
public ForgeDirection getRelativeForwardInWorld() {
|
||||
return c.getOpposite();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.gtnewhorizon.structurelib.alignment.enumerable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import static java.lang.Math.abs;
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
public enum Flip {
|
||||
NONE(3, "none"),
|
||||
HORIZONTAL(2, "horizontal"),
|
||||
VERTICAL(1, "vertical"),
|
||||
BOTH(0, "both");
|
||||
|
||||
private final int opposite;
|
||||
private final String name;
|
||||
|
||||
public static final Flip[] VALUES = values();
|
||||
private static final Map<String, Flip> NAME_LOOKUP = stream(VALUES).collect(toMap(Flip::getName2, (flip) -> flip));
|
||||
|
||||
Flip(int oppositeIn, String nameIn) {
|
||||
this.opposite = oppositeIn;
|
||||
this.name = nameIn;
|
||||
}
|
||||
|
||||
public int getIndex(){
|
||||
return ordinal();
|
||||
}
|
||||
|
||||
public Flip getOpposite() {
|
||||
return VALUES[opposite];
|
||||
}
|
||||
|
||||
public String getName2() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public static Flip byName(String name) {
|
||||
return name == null ? null : NAME_LOOKUP.get(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
public static Flip byIndex(int index) {
|
||||
return VALUES[abs(index % VALUES.length)];
|
||||
}
|
||||
|
||||
public static Flip random(@Nonnull Random rand) {
|
||||
return VALUES[rand.nextInt(VALUES.length)];
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public boolean isNotFlipped(){
|
||||
return this==NONE;
|
||||
}
|
||||
|
||||
public boolean isBothFlipped(){
|
||||
return this==BOTH;
|
||||
}
|
||||
|
||||
public boolean isHorizontallyFlipped() {
|
||||
return this==HORIZONTAL || isBothFlipped();
|
||||
}
|
||||
|
||||
public boolean isVerticallyFliped() {
|
||||
return this==VERTICAL || isBothFlipped();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.gtnewhorizon.structurelib.alignment.enumerable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import static java.lang.Math.abs;
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
public enum Rotation {
|
||||
NORMAL(2, "normal"),
|
||||
CLOCKWISE(3, "clockwise"),
|
||||
UPSIDE_DOWN(0, "upside down"),
|
||||
COUNTER_CLOCKWISE(1, "counter clockwise");
|
||||
|
||||
private final int opposite;
|
||||
private final String name;
|
||||
|
||||
public static final Rotation[] VALUES = values();
|
||||
private static final Map<String, Rotation> NAME_LOOKUP = stream(VALUES).collect(toMap(Rotation::getName2, (rotation) -> rotation));
|
||||
|
||||
Rotation(int oppositeIn, String nameIn) {
|
||||
this.opposite = oppositeIn;
|
||||
this.name = nameIn;
|
||||
}
|
||||
|
||||
public int getIndex(){
|
||||
return ordinal();
|
||||
}
|
||||
|
||||
public Rotation getOpposite() {
|
||||
return VALUES[opposite];
|
||||
}
|
||||
|
||||
public String getName2() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public static Rotation byName(String name) {
|
||||
return name == null ? null : NAME_LOOKUP.get(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
public static Rotation byIndex(int index) {
|
||||
return VALUES[abs(index % VALUES.length)];
|
||||
}
|
||||
|
||||
public static Rotation random(@Nonnull Random rand) {
|
||||
return VALUES[rand.nextInt(VALUES.length)];
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public boolean isNotRotated(){
|
||||
return this==NORMAL;
|
||||
}
|
||||
|
||||
public boolean isClockwise(){
|
||||
return this==CLOCKWISE;
|
||||
}
|
||||
|
||||
public boolean isCounterClockwise(){
|
||||
return this==COUNTER_CLOCKWISE;
|
||||
}
|
||||
|
||||
public boolean isUpsideDown(){
|
||||
return this==UPSIDE_DOWN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package com.gtnewhorizon.structurelib.entity.fx;
|
||||
|
||||
import com.gtnewhorizon.structurelib.StructureLib;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.particle.EntityFX;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.World;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class BlockHint extends EntityFX {
|
||||
private IIcon[] icons;
|
||||
private short[] mRGBa = {255,255,255,0};
|
||||
|
||||
public BlockHint(World world){
|
||||
this(world,0,0,0, Blocks.stone,0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param world
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param icons DOWN, UP, NORTH, SOUTH, WEST, EAST
|
||||
*/
|
||||
public BlockHint(World world, int x, int y, int z, IIcon[] icons) {
|
||||
super(world, x + .25, y + .5, z + .25);
|
||||
particleGravity = 0;
|
||||
prevPosX = posX;
|
||||
prevPosY = posY;
|
||||
prevPosZ = posZ;
|
||||
noClip = true;
|
||||
particleMaxAge = 2000 + StructureLib.RANDOM.nextInt(200);
|
||||
this.icons=icons;
|
||||
}
|
||||
|
||||
public BlockHint(World world, int x, int y, int z, Block block, int meta) {
|
||||
super(world, x+.25, y+.5, z+.25);
|
||||
particleGravity = 0;
|
||||
prevPosX = posX;
|
||||
prevPosY = posY;
|
||||
prevPosZ = posZ;
|
||||
noClip = true;
|
||||
particleMaxAge = 2000 + StructureLib.RANDOM.nextInt(200);
|
||||
icons = new IIcon[6];
|
||||
for (int i = 0; i < 6; i++) {
|
||||
icons[i] = block.getIcon(i, meta);
|
||||
}
|
||||
}
|
||||
|
||||
public BlockHint withColorTint(short[] coloure){
|
||||
this.mRGBa =coloure;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderParticle(Tessellator tes, float subTickTime, float p_70539_3_, float p_70539_4_, float p_70539_5_, float p_70539_6_, float p_70539_7_) {
|
||||
float size = .5f;
|
||||
float X = (float) (prevPosX + (posX - prevPosX) * (double) subTickTime - EntityFX.interpPosX);
|
||||
float Y = (float) (prevPosY + (posY - prevPosY) * (double) subTickTime - EntityFX.interpPosY) - size / 2;
|
||||
float Z = (float) (prevPosZ + (posZ - prevPosZ) * (double) subTickTime - EntityFX.interpPosZ);
|
||||
GL11.glDisable(GL11.GL_CULL_FACE);
|
||||
GL11.glDepthMask(false);
|
||||
tes.setColorRGBA((int) (mRGBa[0] * .9F), (int) (mRGBa[1] * .95F), (int) (mRGBa[2] * 1F), 192);
|
||||
|
||||
//var8, var9 - X U
|
||||
//var 10, var 11 - Y V
|
||||
for(int i=0;i<6;i++){
|
||||
if(icons[i]==null) {
|
||||
continue;
|
||||
}
|
||||
double u=icons[i].getMinU();
|
||||
double U=icons[i].getMaxU();
|
||||
double v=icons[i].getMinV();
|
||||
double V=icons[i].getMaxV();
|
||||
switch (i){//{DOWN, UP, NORTH, SOUTH, WEST, EAST}
|
||||
case 0:
|
||||
tes.addVertexWithUV(X, Y, Z + size, u, V);
|
||||
tes.addVertexWithUV(X, Y, Z, u, v);
|
||||
tes.addVertexWithUV(X + size, Y, Z, U, v);
|
||||
tes.addVertexWithUV(X + size, Y, Z + size, U, V);
|
||||
break;
|
||||
case 1:
|
||||
tes.addVertexWithUV(X, Y + size, Z, u, v);
|
||||
tes.addVertexWithUV(X, Y + size, Z + size, u, V);
|
||||
tes.addVertexWithUV(X + size, Y + size, Z + size, U, V);
|
||||
tes.addVertexWithUV(X + size, Y + size, Z, U, v);
|
||||
break;
|
||||
case 2:
|
||||
tes.addVertexWithUV(X, Y, Z, U, V);
|
||||
tes.addVertexWithUV(X, Y + size, Z, U, v);
|
||||
tes.addVertexWithUV(X + size, Y + size, Z, u, v);
|
||||
tes.addVertexWithUV(X + size, Y, Z, u, V);
|
||||
break;
|
||||
case 3:
|
||||
tes.addVertexWithUV(X + size, Y, Z + size, U, V);
|
||||
tes.addVertexWithUV(X + size, Y + size, Z + size, U, v);
|
||||
tes.addVertexWithUV(X, Y + size, Z + size, u, v);
|
||||
tes.addVertexWithUV(X, Y, Z + size, u, V);
|
||||
break;
|
||||
case 4:
|
||||
tes.addVertexWithUV(X, Y, Z + size, U, V);
|
||||
tes.addVertexWithUV(X, Y + size, Z + size, U, v);
|
||||
tes.addVertexWithUV(X, Y + size, Z, u, v);
|
||||
tes.addVertexWithUV(X, Y, Z, u, V);
|
||||
break;
|
||||
case 5:
|
||||
tes.addVertexWithUV(X + size, Y, Z, U, V);
|
||||
tes.addVertexWithUV(X + size, Y + size, Z, U, v);
|
||||
tes.addVertexWithUV(X + size, Y + size, Z + size, u, v);
|
||||
tes.addVertexWithUV(X + size, Y, Z + size, u, V);
|
||||
break;
|
||||
}
|
||||
}
|
||||
GL11.glEnable(GL11.GL_CULL_FACE);
|
||||
GL11.glDepthMask(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFXLayer() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRenderInPass(int pass) {
|
||||
return pass==2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.gtnewhorizon.structurelib.entity.fx;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.client.particle.EntityFX;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class WeightlessParticleFX extends EntityFX
|
||||
{
|
||||
public WeightlessParticleFX(World p_i1205_1_, double p_i1205_2_, double p_i1205_4_, double p_i1205_6_, double p_i1205_8_, double p_i1205_10_, double p_i1205_12_)
|
||||
{
|
||||
super(p_i1205_1_, p_i1205_2_, p_i1205_4_, p_i1205_6_, p_i1205_8_, p_i1205_10_, p_i1205_12_);
|
||||
this.motionX = p_i1205_8_ + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.05F);
|
||||
this.motionY = p_i1205_10_ + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.05F);
|
||||
this.motionZ = p_i1205_12_ + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.05F);
|
||||
this.particleRed = this.particleGreen = this.particleBlue = this.rand.nextFloat() * 0.3F + 0.7F;
|
||||
this.particleScale = this.rand.nextFloat() * this.rand.nextFloat() * 6.0F + 1.0F;
|
||||
this.particleMaxAge = (int)(16.0D / ((double)this.rand.nextFloat() * 0.8D + 0.2D)) + 2;
|
||||
this.noClip=true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
public void onUpdate()
|
||||
{
|
||||
this.prevPosX = this.posX;
|
||||
this.prevPosY = this.posY;
|
||||
this.prevPosZ = this.posZ;
|
||||
|
||||
if (this.particleAge++ >= this.particleMaxAge)
|
||||
{
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
this.setParticleTextureIndex(7 - this.particleAge * 8 / this.particleMaxAge);
|
||||
//this.motionY += 0.004D;
|
||||
this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
this.motionX *= 0.8999999761581421D;
|
||||
this.motionY *= 0.8999999761581421D;
|
||||
this.motionZ *= 0.8999999761581421D;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.gtnewhorizon.structurelib.proxy;
|
||||
|
||||
import com.gtnewhorizon.structurelib.entity.fx.BlockHint;
|
||||
import com.gtnewhorizon.structurelib.entity.fx.WeightlessParticleFX;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.particle.EntityFX;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import static com.gtnewhorizon.structurelib.StructureLib.RANDOM;
|
||||
|
||||
public class ClientProxy extends CommonProxy {
|
||||
@Override
|
||||
public void hint_particle_tinted(World w, int x, int y, int z, IIcon[] icons, short[] RGBa) {
|
||||
Minecraft.getMinecraft().effectRenderer.addEffect(new BlockHint(w, x, y, z, icons).withColorTint(RGBa));
|
||||
createParticleFX(w, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hint_particle_tinted(World w, int x, int y, int z, Block block, int meta, short[] RGBa) {
|
||||
Minecraft.getMinecraft().effectRenderer.addEffect(new BlockHint(w, x, y, z, block, meta).withColorTint(RGBa));
|
||||
createParticleFX(w, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hint_particle(World w, int x, int y, int z, IIcon[] icons) {
|
||||
Minecraft.getMinecraft().effectRenderer.addEffect(new BlockHint(w, x, y, z, icons));
|
||||
createParticleFX(w, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hint_particle(World w, int x, int y, int z, Block block, int meta) {
|
||||
Minecraft.getMinecraft().effectRenderer.addEffect(new BlockHint(w, x, y, z, block, meta));
|
||||
createParticleFX(w, x, y, z);
|
||||
}
|
||||
|
||||
private static void createParticleFX(World w, int x, int y, int z) {
|
||||
EntityFX particle = new WeightlessParticleFX(w, x + RANDOM.nextFloat() * 0.5F, y + RANDOM.nextFloat() * 0.5F, z + RANDOM.nextFloat() * 0.5F, 0, 0, 0);
|
||||
particle.setRBGColorF(0, 0.6F * RANDOM.nextFloat(), 0.8f);
|
||||
Minecraft.getMinecraft().effectRenderer.addEffect(particle);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.gtnewhorizon.structurelib.proxy;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class CommonProxy {
|
||||
public void hint_particle_tinted(World w, int x, int y, int z, IIcon[] icons, short[] RGBa){}
|
||||
public void hint_particle_tinted(World w, int x, int y, int z, Block block, int meta, short[] RGBa){}
|
||||
public void hint_particle(World w,int x, int y, int z, IIcon[] icons){}
|
||||
public void hint_particle(World w,int x, int y, int z, Block block, int meta){}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.gtnewhorizon.structurelib.structure;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface IBlockPosConsumer {
|
||||
void consume(World world, int x, int y, int z);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.gtnewhorizon.structurelib.structure;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface ICustomBlockSetting {
|
||||
/**
|
||||
* Default block setting calls {@link World#setBlock(int x, int y, int z, Block block, int meta, int updateType)} like:
|
||||
* {@code world.setBlock(x,y,z,this/block,meta,2)} where updateType 2 means to update lighting and stuff
|
||||
*
|
||||
* @param world world that should be affected
|
||||
* @param x x position to set
|
||||
* @param y y position to set
|
||||
* @param z z position to set
|
||||
* @param meta required meta
|
||||
*/
|
||||
void setBlock(World world, int x, int y, int z, int meta);
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package com.gtnewhorizon.structurelib.structure;
|
||||
|
||||
import com.gtnewhorizon.structurelib.StructureLib;
|
||||
import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.gtnewhorizon.structurelib.StructureLib.DEBUG_MODE;
|
||||
|
||||
public interface IStructureDefinition<T> {
|
||||
/**
|
||||
* Used internally
|
||||
*
|
||||
* @param name same name as for other methods here
|
||||
* @return the array of elements to process
|
||||
*/
|
||||
IStructureElement<T>[] getStructureFor(String name);
|
||||
|
||||
default boolean check(T object, String piece, World world, ExtendedFacing extendedFacing,
|
||||
int basePositionX, int basePositionY, int basePositionZ,
|
||||
int basePositionA, int basePositionB, int basePositionC,
|
||||
boolean forceCheckAllBlocks) {
|
||||
return iterate(object, null, getStructureFor(piece), world, extendedFacing, basePositionX, basePositionY, basePositionZ,
|
||||
basePositionA, basePositionB, basePositionC, false, forceCheckAllBlocks);
|
||||
}
|
||||
|
||||
default boolean hints(T object, ItemStack trigger, String piece, World world, ExtendedFacing extendedFacing,
|
||||
int basePositionX, int basePositionY, int basePositionZ,
|
||||
int basePositionA, int basePositionB, int basePositionC) {
|
||||
return iterate(object, trigger, getStructureFor(piece), world, extendedFacing, basePositionX, basePositionY, basePositionZ,
|
||||
basePositionA, basePositionB, basePositionC, true, null);
|
||||
}
|
||||
|
||||
default boolean build(T object, ItemStack trigger, String piece, World world, ExtendedFacing extendedFacing,
|
||||
int basePositionX, int basePositionY, int basePositionZ,
|
||||
int basePositionA, int basePositionB, int basePositionC) {
|
||||
return iterate(object, trigger, getStructureFor(piece), world, extendedFacing, basePositionX, basePositionY, basePositionZ,
|
||||
basePositionA, basePositionB, basePositionC, false, null);
|
||||
}
|
||||
|
||||
default boolean buildOrHints(T object, ItemStack trigger, String piece, World world, ExtendedFacing extendedFacing,
|
||||
int basePositionX, int basePositionY, int basePositionZ,
|
||||
int basePositionA, int basePositionB, int basePositionC,
|
||||
boolean hintsOnly) {
|
||||
return iterate(object, trigger, getStructureFor(piece), world, extendedFacing, basePositionX, basePositionY, basePositionZ,
|
||||
basePositionA, basePositionB, basePositionC, hintsOnly, null);
|
||||
}
|
||||
|
||||
static <T> boolean iterate(T object, ItemStack trigger, IStructureElement<T>[] elements, World world, ExtendedFacing extendedFacing,
|
||||
int basePositionX, int basePositionY, int basePositionZ,
|
||||
int basePositionA, int basePositionB, int basePositionC,
|
||||
boolean hintsOnly, Boolean checkBlocksIfNotNullForceCheckAllIfTrue) {
|
||||
if (world.isRemote ^ hintsOnly) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//change base position to base offset
|
||||
basePositionA = -basePositionA;
|
||||
basePositionB = -basePositionB;
|
||||
basePositionC = -basePositionC;
|
||||
|
||||
int[] abc = new int[]{basePositionA, basePositionB, basePositionC};
|
||||
int[] xyz = new int[3];
|
||||
|
||||
if (checkBlocksIfNotNullForceCheckAllIfTrue != null) {
|
||||
if (checkBlocksIfNotNullForceCheckAllIfTrue) {
|
||||
for (IStructureElement<T> element : elements) {
|
||||
if (element.isNavigating()) {
|
||||
abc[0] = (element.resetA() ? basePositionA : abc[0]) + element.getStepA();
|
||||
abc[1] = (element.resetB() ? basePositionB : abc[1]) + element.getStepB();
|
||||
abc[2] = (element.resetC() ? basePositionC : abc[2]) + element.getStepC();
|
||||
} else {
|
||||
extendedFacing.getWorldOffset(abc, xyz);
|
||||
xyz[0] += basePositionX;
|
||||
xyz[1] += basePositionY;
|
||||
xyz[2] += basePositionZ;
|
||||
|
||||
if (world.blockExists(xyz[0], xyz[1], xyz[2])) {
|
||||
if (!element.check(object, world, xyz[0], xyz[1], xyz[2])) {
|
||||
if (DEBUG_MODE) {
|
||||
StructureLib.LOGGER.info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] failed @ " +
|
||||
Arrays.toString(xyz) + " " + Arrays.toString(abc));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (DEBUG_MODE) {
|
||||
StructureLib.LOGGER.info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] !blockExists @ " +
|
||||
Arrays.toString(xyz) + " " + Arrays.toString(abc));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
abc[0] += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (IStructureElement<T> element : elements) {
|
||||
if (element.isNavigating()) {
|
||||
abc[0] = (element.resetA() ? basePositionA : abc[0]) + element.getStepA();
|
||||
abc[1] = (element.resetB() ? basePositionB : abc[1]) + element.getStepB();
|
||||
abc[2] = (element.resetC() ? basePositionC : abc[2]) + element.getStepC();
|
||||
} else {
|
||||
extendedFacing.getWorldOffset(abc, xyz);
|
||||
xyz[0] += basePositionX;
|
||||
xyz[1] += basePositionY;
|
||||
xyz[2] += basePositionZ;
|
||||
|
||||
if (world.blockExists(xyz[0], xyz[1], xyz[2])) {
|
||||
if (!element.check(object, world, xyz[0], xyz[1], xyz[2])) {
|
||||
if (DEBUG_MODE) {
|
||||
StructureLib.LOGGER.info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] failed @ " +
|
||||
Arrays.toString(xyz) + " " + Arrays.toString(abc));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (DEBUG_MODE) {
|
||||
StructureLib.LOGGER.info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] !blockExists @ " +
|
||||
Arrays.toString(xyz) + " " + Arrays.toString(abc));
|
||||
}
|
||||
}
|
||||
abc[0] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (hintsOnly) {
|
||||
for (IStructureElement<T> element : elements) {
|
||||
if (element.isNavigating()) {
|
||||
abc[0] = (element.resetA() ? basePositionA : abc[0]) + element.getStepA();
|
||||
abc[1] = (element.resetB() ? basePositionB : abc[1]) + element.getStepB();
|
||||
abc[2] = (element.resetC() ? basePositionC : abc[2]) + element.getStepC();
|
||||
} else {
|
||||
extendedFacing.getWorldOffset(abc, xyz);
|
||||
xyz[0] += basePositionX;
|
||||
xyz[1] += basePositionY;
|
||||
xyz[2] += basePositionZ;
|
||||
|
||||
element.spawnHint(object, world, xyz[0], xyz[1], xyz[2], trigger);
|
||||
|
||||
abc[0] += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (IStructureElement<T> element : elements) {
|
||||
if (element.isNavigating()) {
|
||||
abc[0] = (element.resetA() ? basePositionA : abc[0]) + element.getStepA();
|
||||
abc[1] = (element.resetB() ? basePositionB : abc[1]) + element.getStepB();
|
||||
abc[2] = (element.resetC() ? basePositionC : abc[2]) + element.getStepC();
|
||||
} else {
|
||||
extendedFacing.getWorldOffset(abc, xyz);
|
||||
xyz[0] += basePositionX;
|
||||
xyz[1] += basePositionY;
|
||||
xyz[2] += basePositionZ;
|
||||
|
||||
if (world.blockExists(xyz[0], xyz[1], xyz[2])) {
|
||||
element.placeBlock(object, world, xyz[0], xyz[1], xyz[2], trigger);
|
||||
}
|
||||
abc[0] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.gtnewhorizon.structurelib.structure;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* Use StructureUtility to instantiate
|
||||
*/
|
||||
public interface IStructureElement<T> {
|
||||
boolean check(T t, World world, int x, int y, int z);
|
||||
|
||||
boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger);
|
||||
|
||||
boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger);
|
||||
|
||||
default int getStepA() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
default int getStepB() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
default int getStepC() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
default boolean resetA() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean resetB() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean resetC() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean isNavigating() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.gtnewhorizon.structurelib.structure;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* Use StructureUtility to instantiate
|
||||
*/
|
||||
public interface IStructureElementChain<T> extends IStructureElement<T> {
|
||||
IStructureElement<T>[] fallbacks();
|
||||
|
||||
@Override
|
||||
default boolean check(T t, World world, int x, int y, int z) {
|
||||
for (IStructureElement<T> fallback : fallbacks()) {
|
||||
if (fallback.check(t, world, x, y, z)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
|
||||
for (IStructureElement<T> fallback : fallbacks()) {
|
||||
if (fallback.spawnHint(t, world, x, y, z, trigger)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
|
||||
for (IStructureElement<T> fallback : fallbacks()) {
|
||||
if (fallback.placeBlock(t, world, x, y, z, trigger)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.gtnewhorizon.structurelib.structure;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface IStructureElementCheckOnly<T> extends IStructureElement<T> {
|
||||
@Override
|
||||
default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.gtnewhorizon.structurelib.structure;
|
||||
|
||||
/**
|
||||
* Use StructureUtility to instantiate
|
||||
*/
|
||||
public interface IStructureElementDeferred<T> extends IStructureElement<T> {
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.gtnewhorizon.structurelib.structure;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface IStructureElementNoPlacement<T> extends IStructureElement<T> {
|
||||
@Override
|
||||
default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.gtnewhorizon.structurelib.structure;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* Use StructureUtility to instantiate
|
||||
*/
|
||||
interface IStructureNavigate<T> extends IStructureElement<T> {
|
||||
@Override
|
||||
default boolean check(T t, World world, int x, int y, int z) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
|
||||
return true;
|
||||
}
|
||||
|
||||
default boolean isNavigating() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
package com.gtnewhorizon.structurelib.structure;
|
||||
|
||||
import com.gtnewhorizon.structurelib.util.Vec3Impl;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.gtnewhorizon.structurelib.StructureLib.DEBUG_MODE;
|
||||
import static com.gtnewhorizon.structurelib.structure.StructureUtility.*;
|
||||
|
||||
public class StructureDefinition<T> implements IStructureDefinition<T> {
|
||||
private final Map<Character, IStructureElement<T>> elements;
|
||||
private final Map<String, String> shapes;
|
||||
private final Map<String, IStructureElement<T>[]> structures;
|
||||
|
||||
public static <B> Builder<B> builder() {
|
||||
return new Builder<>();
|
||||
}
|
||||
|
||||
private StructureDefinition(
|
||||
Map<Character, IStructureElement<T>> elements,
|
||||
Map<String, String> shapes,
|
||||
Map<String, IStructureElement<T>[]> structures) {
|
||||
this.elements = elements;
|
||||
this.shapes = shapes;
|
||||
this.structures = structures;
|
||||
}
|
||||
|
||||
public static class Builder<T> {
|
||||
private static final char A = '\uA000';
|
||||
private static final char B = '\uB000';
|
||||
private static final char C = '\uC000';
|
||||
private char d = '\uD000';
|
||||
private final Map<Vec3Impl, Character> navigates;
|
||||
private final Map<Character, IStructureElement<T>> elements;
|
||||
private final Map<String, String> shapes;
|
||||
|
||||
private Builder() {
|
||||
navigates = new HashMap<>();
|
||||
elements = new HashMap<>();
|
||||
shapes = new HashMap<>();
|
||||
}
|
||||
|
||||
public Map<Character, IStructureElement<T>> getElements() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
public Map<String, String> getShapes() {
|
||||
return shapes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds shape
|
||||
* +- is air/no air checks
|
||||
* space bar is skip
|
||||
* ~ is also skip (but marks controller position, optional and logically it is a space...)
|
||||
* rest needs to be defined
|
||||
* <p>
|
||||
* next char is next block(a)
|
||||
* next string is next line(b)
|
||||
* next string[] is next slice(c)
|
||||
* <p>
|
||||
* char A000-FFFF range is reserved for generated skips
|
||||
*
|
||||
* @param name unlocalized/code name
|
||||
* @param structurePiece generated or written struct - DO NOT STORE IT ANYWHERE, or at least set them to null afterwards
|
||||
* @return this builder
|
||||
*/
|
||||
public Builder<T> addShape(String name, String[][] structurePiece) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (structurePiece.length > 0) {
|
||||
for (String[] strings : structurePiece) {
|
||||
if (strings.length > 0) {
|
||||
for (String string : strings) {
|
||||
builder.append(string).append(B);
|
||||
}
|
||||
builder.setLength(builder.length() - 1);
|
||||
}
|
||||
builder.append(C);
|
||||
}
|
||||
builder.setLength(builder.length() - 1);
|
||||
}
|
||||
int a = 0, b = 0, c = 0;
|
||||
for (int i = 0; i < builder.length(); i++) {
|
||||
char ch = builder.charAt(i);
|
||||
if (ch == ' ' || ch == '~') {
|
||||
builder.setCharAt(i, A);
|
||||
ch = A;
|
||||
}
|
||||
if (ch == A) {
|
||||
a++;
|
||||
} else if (ch == B) {
|
||||
a = 0;
|
||||
b++;
|
||||
} else if (ch == C) {
|
||||
a = 0;
|
||||
b = 0;
|
||||
c++;
|
||||
} else if (a != 0 || b != 0 || c != 0) {
|
||||
Vec3Impl vec3 = new Vec3Impl(a, b, c);
|
||||
Character navigate = navigates.get(vec3);
|
||||
if (navigate == null) {
|
||||
navigate = d++;
|
||||
navigates.put(vec3, navigate);
|
||||
addElement(navigate, step(vec3));
|
||||
}
|
||||
builder.setCharAt(i - 1, navigate);
|
||||
a = 0;
|
||||
b = 0;
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
|
||||
String built = builder.toString().replaceAll("[\\uA000\\uB000\\uC000]", "");
|
||||
|
||||
if (built.contains("+")) {
|
||||
addElement('+', notAir());
|
||||
}
|
||||
if (built.contains("-")) {
|
||||
addElement('-', isAir());
|
||||
}
|
||||
shapes.put(name, built);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> addElement(Character name, IStructureElement<T> structurePiece) {
|
||||
elements.putIfAbsent(name, structurePiece);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IStructureDefinition<T> build() {
|
||||
Map<String, IStructureElement<T>[]> structures = compileStructureMap();
|
||||
if (DEBUG_MODE) {
|
||||
return new StructureDefinition<>(new HashMap<>(elements), new HashMap<>(shapes), structures);
|
||||
} else {
|
||||
return structures::get;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, IStructureElement<T>[]> compileElementSetMap() {
|
||||
Set<Integer> missing = new HashSet<>();
|
||||
shapes.values().stream().map(CharSequence::chars).forEach(intStream -> intStream.forEach(c -> {
|
||||
IStructureElement<T> iStructureElement = elements.get((char) c);
|
||||
if (iStructureElement == null) {
|
||||
missing.add(c);
|
||||
}
|
||||
}));
|
||||
if (missing.isEmpty()) {
|
||||
Map<String, IStructureElement<T>[]> map = new HashMap<>();
|
||||
shapes.forEach((key, value) -> {
|
||||
Set<Character> chars = new HashSet<>();
|
||||
for (char c : value.toCharArray()) {
|
||||
chars.add(c);
|
||||
}
|
||||
IStructureElement<T>[] compiled = new IStructureElement[chars.size()];
|
||||
int i = 0;
|
||||
for (Character aChar : chars) {
|
||||
compiled[i++] = elements.get(aChar);
|
||||
}
|
||||
map.put(key, compiled);
|
||||
});
|
||||
return map;
|
||||
} else {
|
||||
throw new RuntimeException("Missing Structure Element bindings for (chars as integers): " +
|
||||
Arrays.toString(missing.toArray()));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, IStructureElement<T>[]> compileStructureMap() {
|
||||
Set<Integer> mising = new HashSet<>();
|
||||
shapes.values().stream().map(CharSequence::chars).forEach(intStream -> intStream.forEach(c -> {
|
||||
IStructureElement<T> iStructureElement = elements.get((char) c);
|
||||
if (iStructureElement == null) {
|
||||
mising.add(c);
|
||||
}
|
||||
}));
|
||||
if (mising.isEmpty()) {
|
||||
Map<String, IStructureElement<T>[]> map = new HashMap<>();
|
||||
shapes.forEach((key, value) -> {
|
||||
IStructureElement<T>[] compiled = new IStructureElement[value.length()];
|
||||
for (int i = 0; i < value.length(); i++) {
|
||||
compiled[i] = elements.get(value.charAt(i));
|
||||
}
|
||||
map.put(key, compiled);
|
||||
});
|
||||
return map;
|
||||
} else {
|
||||
throw new RuntimeException("Missing Structure Element bindings for (chars as integers): " +
|
||||
Arrays.toString(mising.toArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Character, IStructureElement<T>> getElements() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
public Map<String, String> getShapes() {
|
||||
return shapes;
|
||||
}
|
||||
|
||||
public Map<String, IStructureElement<T>[]> getStructures() {
|
||||
return structures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStructureElement<T>[] getStructureFor(String name) {
|
||||
return structures.get(name);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,15 @@
|
||||
package com.gtnewhorizon.structurelib.structure.adders;
|
||||
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
||||
public interface IBlockAdder<T> {
|
||||
/**
|
||||
* Callback on block added, needs to check if block is valid (and add it)
|
||||
*
|
||||
* @param block block attempted to add
|
||||
* @param meta meta of block attempted to add
|
||||
* @return is structure still valid
|
||||
*/
|
||||
boolean apply(T t, Block block, Integer meta);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.gtnewhorizon.structurelib.structure.adders;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
public interface ITileAdder<T> {
|
||||
/**
|
||||
* Callback to add hatch, needs to check if tile is valid (and add it)
|
||||
*
|
||||
* @param tileEntity tile
|
||||
* @return managed to add hatch (structure still valid)
|
||||
*/
|
||||
boolean apply(T t, TileEntity tileEntity);
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package com.gtnewhorizon.structurelib.util;
|
||||
|
||||
import net.minecraft.dispenser.IPosition;
|
||||
import net.minecraftforge.common.util.ForgeDirection;
|
||||
|
||||
public class Vec3Impl implements Comparable<Vec3Impl> {
|
||||
public static final Vec3Impl NULL_VECTOR = new Vec3Impl(0, 0, 0);
|
||||
private final int val0;
|
||||
private final int val1;
|
||||
private final int val2;
|
||||
|
||||
public Vec3Impl(int in0, int in1, int in2) {
|
||||
this.val0 = in0;
|
||||
this.val1 = in1;
|
||||
this.val2 = in2;
|
||||
}
|
||||
|
||||
public int compareTo(Vec3Impl o) {
|
||||
return val1 == o.val1 ? val2 == o.val2 ? val0 - o.val0 : val2 - o.val2 : val1 - o.val1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the coordinate.
|
||||
*/
|
||||
public int get(int index) {
|
||||
switch (index){
|
||||
case 0: return val0;
|
||||
case 1: return val1;
|
||||
case 2: return val2;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the X coordinate.
|
||||
*/
|
||||
public int get0() {
|
||||
return this.val0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Y coordinate.
|
||||
*/
|
||||
public int get1() {
|
||||
return this.val1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Z coordinate.
|
||||
*/
|
||||
public int get2() {
|
||||
return this.val2;
|
||||
}
|
||||
|
||||
public Vec3Impl offset(ForgeDirection facing, int n) {
|
||||
return n == 0 ? this : new Vec3Impl(val0 + facing.offsetX * n, val1 + facing.offsetY * n, val2 + facing.offsetZ * n);
|
||||
}
|
||||
|
||||
public Vec3Impl add(Vec3Impl pos) {
|
||||
return new Vec3Impl(val0 + pos.val0, val1 + pos.val1, val2 + pos.val2);
|
||||
}
|
||||
|
||||
public Vec3Impl sub(Vec3Impl pos) {
|
||||
return new Vec3Impl(val0 - pos.val0, val1 - pos.val1, val2 - pos.val2);
|
||||
}
|
||||
|
||||
public Vec3Impl add(int pos0,int pos1,int pos2) {
|
||||
return new Vec3Impl(val0 + pos0, val1 + pos1, val2 + pos2);
|
||||
}
|
||||
|
||||
public Vec3Impl sub(int pos0,int pos1,int pos2) {
|
||||
return new Vec3Impl(val0 - pos0, val1 - pos1, val2 - pos2);
|
||||
}
|
||||
|
||||
public Vec3Impl crossProduct(Vec3Impl vec) {
|
||||
return new Vec3Impl(val1 * vec.val2 - val2 * vec.val1, val2 * vec.val0 - val0 * vec.val2,
|
||||
val0 * vec.val1 - val1 * vec.val0);
|
||||
}
|
||||
|
||||
public boolean withinDistance(Vec3Impl to, double distance) {
|
||||
return this.distanceSq(to.val0, to.val1, to.val2, false) < distance * distance;
|
||||
}
|
||||
|
||||
public boolean withinDistance(IPosition to, double distance) {
|
||||
return this.distanceSq(to.getX(), to.getY(), to.getZ(), true) < distance * distance;
|
||||
}
|
||||
|
||||
public double distanceSq(Vec3Impl to) {
|
||||
return this.distanceSq(to.val0, to.val1, to.val2, true);
|
||||
}
|
||||
|
||||
public double distanceSq(IPosition to, boolean useCenter) {
|
||||
return this.distanceSq(to.getX(), to.getY(), to.getZ(), useCenter);
|
||||
}
|
||||
|
||||
public double distanceSq(double x, double y, double z, boolean useCenter) {
|
||||
double d0 = useCenter ? 0.5D : 0.0D;
|
||||
double d1 = (double)val0 + d0 - x;
|
||||
double d2 = (double)val1 + d0 - y;
|
||||
double d3 = (double)val2 + d0 - z;
|
||||
return d1 * d1 + d2 * d2 + d3 * d3;
|
||||
}
|
||||
|
||||
public int manhattanDistance(Vec3Impl to) {
|
||||
float f = (float)Math.abs(to.val0 - val0);
|
||||
float f1 = (float)Math.abs(to.val1 - val1);
|
||||
float f2 = (float)Math.abs(to.val2 - val2);
|
||||
return (int)(f + f1 + f2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Vec3[" + val0 + ", " + val1 + ", " + val2 + "]";
|
||||
}
|
||||
|
||||
public Vec3Impl abs() {
|
||||
return new Vec3Impl(Math.abs(val0),Math.abs(val1),Math.abs(val2));
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
} else if (o instanceof Vec3Impl) {
|
||||
Vec3Impl vec3i = (Vec3Impl)o;
|
||||
return val0 == vec3i.val0 && val1 == vec3i.val1 && val2 == vec3i.val2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return (val1 + val2 * 31) * 31 + val0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
package com.gtnewhorizon.structurelib.util;
|
||||
/*
|
||||
A subclass of java.util.random that implements the Xorshift random number
|
||||
generator
|
||||
<p>
|
||||
- it is 30% faster than the generator from Java's library - it produces
|
||||
random sequences of higher quality than java.util.Random - this class also
|
||||
provides a clone() function
|
||||
<p>
|
||||
Usage: XSRandom rand = new XSRandom(); //Instantiation x = rand.nextInt();
|
||||
//pull a random number
|
||||
<p>
|
||||
To use the class in legacy code, you may also instantiate an XSRandom object
|
||||
and assign it to a java.util.Random object: java.util.Random rand = new
|
||||
XSRandom();
|
||||
<p>
|
||||
for an explanation of the algorithm, see
|
||||
http://demesos.blogspot.com/2011/09/pseudo-random-number-generators.html
|
||||
|
||||
@author Wilfried Elmenreich University of Klagenfurt/Lakeside Labs
|
||||
* http://www.elmenreich.tk
|
||||
* <p>
|
||||
* This code is released under the GNU Lesser General Public License Version 3
|
||||
* http://www.gnu.org/licenses/lgpl-3.0.txt
|
||||
*/
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* XSTR - Xorshift ThermiteRandom
|
||||
* Modified by Bogdan-G
|
||||
* 03.06.2016
|
||||
* version 0.0.4
|
||||
*/
|
||||
public class XSTR extends Random {
|
||||
|
||||
private static final long serialVersionUID = 6208727693524452904L;
|
||||
private long seed;
|
||||
private static final long GAMMA = 0x9e3779b97f4a7c15L;
|
||||
private static final int PROBE_INCREMENT = 0x9e3779b9;
|
||||
private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
|
||||
private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53)
|
||||
private static final float FLOAT_UNIT = 0x1.0p-24f; // 1.0f / (1 << 24)
|
||||
private static final AtomicLong seedUniquifier = new AtomicLong(8682522807148012L);
|
||||
public static final XSTR XSTR_INSTANCE=new XSTR(){
|
||||
@Override
|
||||
public synchronized void setSeed(long seed) {
|
||||
if(!Thread.currentThread().getStackTrace()[2].getClassName().equals(Random.class.getName())) {
|
||||
throw new NoSuchMethodError("This is meant to be shared!, leave seed state alone!");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
MODIFIED BY: Robotia
|
||||
Modification: Implemented Random class seed generator
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a new pseudo random number generator. The seed is initialized to
|
||||
* the current time, as if by
|
||||
* <code>setSeed(System.currentTimeMillis());</code>.
|
||||
*/
|
||||
public XSTR() {
|
||||
this(seedUniquifier() ^ System.nanoTime());
|
||||
}
|
||||
|
||||
private static long seedUniquifier() {
|
||||
// L'Ecuyer, "Tables of Linear Congruential Generators of
|
||||
// Different Sizes and Good Lattice Structure", 1999
|
||||
while (true) {
|
||||
long current = seedUniquifier.get();
|
||||
long next = current * 181783497276652981L;
|
||||
if (seedUniquifier.compareAndSet(current, next)) {
|
||||
return next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new pseudo random number generator, starting with the specified
|
||||
* seed, using <code>setSeed(seed);</code>.
|
||||
*
|
||||
* @param seed the initial seed
|
||||
*/
|
||||
public XSTR(long seed) {
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nextBoolean() {
|
||||
return next(1) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double nextDouble() {
|
||||
return (((long) next(26) << 27) + next(27)) * DOUBLE_UNIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current state of the seed, can be used to clone the object
|
||||
*
|
||||
* @return the current seed
|
||||
*/
|
||||
public synchronized long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the seed for this pseudo random number generator. As described
|
||||
* above, two instances of the same random class, starting with the same
|
||||
* seed, produce the same results, if the same methods are called.
|
||||
*
|
||||
* @param seed the new seed
|
||||
*/
|
||||
@Override
|
||||
public synchronized void setSeed(long seed) {
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns an XSRandom object with the same state as the original
|
||||
*/
|
||||
@Override
|
||||
public XSTR clone() {
|
||||
return new XSTR(getSeed());
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of George Marsaglia's elegant Xorshift random generator
|
||||
* 30% faster and better quality than the built-in java.util.random see also
|
||||
* see http://www.javamex.com/tutorials/random_numbers/xorshift.shtml
|
||||
*
|
||||
* @param nbits will shift nbits bits
|
||||
* @return next seed
|
||||
*/
|
||||
@Override
|
||||
public int next(int nbits) {
|
||||
long x = seed;
|
||||
x ^= x << 21;
|
||||
x ^= x >>> 35;
|
||||
x ^= x << 4;
|
||||
seed = x;
|
||||
x &= (1L << nbits) - 1;
|
||||
return (int) x;
|
||||
}
|
||||
|
||||
private boolean haveNextNextGaussian = false;
|
||||
private double nextNextGaussian = 0;
|
||||
|
||||
@Override
|
||||
public synchronized double nextGaussian() {
|
||||
// See Knuth, ACP, Section 3.4.1 Algorithm C.
|
||||
if (haveNextNextGaussian) {
|
||||
haveNextNextGaussian = false;
|
||||
return nextNextGaussian;
|
||||
} else {
|
||||
double v1, v2, vs;
|
||||
do {
|
||||
v1 = 2 * nextDouble() - 1; // between -1 and 1
|
||||
v2 = 2 * nextDouble() - 1; // between -1 and 1
|
||||
vs = v1 * v1 + v2 * v2;
|
||||
} while (vs >= 1 || vs == 0);
|
||||
double multiplier = StrictMath.sqrt(-2 * StrictMath.log(vs) / vs);
|
||||
nextNextGaussian = v2 * multiplier;
|
||||
haveNextNextGaussian = true;
|
||||
return v1 * multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pseudorandom, uniformly distributed {@code int} value between 0
|
||||
* (inclusive) and the specified value (exclusive), drawn from this random
|
||||
* number generator's sequence. The general contract of {@code nextInt} is
|
||||
* that one {@code int} value in the specified range is pseudorandomly
|
||||
* generated and returned. All {@code bound} possible {@code int} values are
|
||||
* produced with (approximately) equal probability. The method
|
||||
* {@code nextInt(int bound)} is implemented by class {@code Random} as if
|
||||
* by:
|
||||
* <pre> {@code
|
||||
* public int nextInt(int bound) {
|
||||
* if (bound <= 0)
|
||||
* throw new IllegalArgumentException("bound must be positive");
|
||||
*
|
||||
* if ((bound & -bound) == bound) // i.e., bound is a power of 2
|
||||
* return (int)((bound * (long)next(31)) >> 31);
|
||||
*
|
||||
* int bits, val;
|
||||
* do {
|
||||
* bits = next(31);
|
||||
* val = bits % bound;
|
||||
* } while (bits - val + (bound-1) < 0);
|
||||
* return val;
|
||||
* }}</pre>
|
||||
*
|
||||
* <p>The hedge "approx
|
||||
* imately" is used in the foregoing description only because the next
|
||||
* method is only approximately an unbiased source of independently chosen
|
||||
* bits. If it were a perfect source of randomly chosen bits, then the
|
||||
* algorithm shown would choose {@code int} values from the stated range
|
||||
* with perfect uniformity.
|
||||
* <p>
|
||||
* The algorithm is slightly tricky. It rejects values that would result in
|
||||
* an uneven distribution (due to the fact that 2^31 is not divisible by n).
|
||||
* The probability of a value being rejected depends on n. The worst case is
|
||||
* n=2^30+1, for which the probability of a reject is 1/2, and the expected
|
||||
* number of iterations before the loop terminates is 2.
|
||||
* <p>
|
||||
* The algorithm treats the case where n is a power of two specially: it
|
||||
* returns the correct number of high-order bits from the underlying
|
||||
* pseudo-random number generator. In the absence of special treatment, the
|
||||
* correct number of <i>low-order</i> bits would be returned. Linear
|
||||
* congruential pseudo-random number generators such as the one implemented
|
||||
* by this class are known to have short periods in the sequence of values
|
||||
* of their low-order bits. Thus, this special case greatly increases the
|
||||
* length of the sequence of values returned by successive calls to this
|
||||
* method if n is a small power of two.
|
||||
*
|
||||
* @param bound the upper bound (exclusive). Must be positive.
|
||||
* @return the next pseudorandom, uniformly distributed {@code int} value
|
||||
* between zero (inclusive) and {@code bound} (exclusive) from this random
|
||||
* number generator's sequence
|
||||
* @throws IllegalArgumentException if bound is not positive
|
||||
* @since 1.2
|
||||
*/
|
||||
@Override
|
||||
public int nextInt(int bound) {
|
||||
//if (bound <= 0) {
|
||||
//throw new RuntimeException("BadBound");
|
||||
//}
|
||||
|
||||
/*int r = next(31);
|
||||
int m = bound - 1;
|
||||
if ((bound & m) == 0) // i.e., bound is a power of 2
|
||||
{
|
||||
r = (int) ((bound * (long) r) >> 31);
|
||||
} else {
|
||||
for (int u = r;
|
||||
u - (r = u % bound) + m < 0;
|
||||
u = next(31))
|
||||
;
|
||||
}
|
||||
return r;*/
|
||||
//speedup, new nextInt ~+40%
|
||||
long last = seed ^ seed << 21;
|
||||
last ^= last >>> 35;
|
||||
last ^= last << 4;
|
||||
seed = last;
|
||||
int out = (int) last % bound;
|
||||
return out < 0 ? -out : out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextInt() {
|
||||
return next(32);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float nextFloat() {
|
||||
return next(24) * FLOAT_UNIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nextLong() {
|
||||
// it's okay that the bottom word remains signed.
|
||||
return ((long) next(32) << 32) + next(32);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextBytes(byte[] bytes_arr) {
|
||||
for (int iba = 0, lenba = bytes_arr.length; iba < lenba; ) {
|
||||
for (int rndba = nextInt(), nba = Math.min(lenba - iba, Integer.SIZE / Byte.SIZE); nba-- > 0; rndba >>= Byte.SIZE) {
|
||||
bytes_arr[iba++] = (byte) rndba;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
[
|
||||
{
|
||||
"modid": "structurelib",
|
||||
"name": "StructureLib",
|
||||
"description": "Multiblocks with ease",
|
||||
"version": "${version}",
|
||||
"mcversion": "${mcversion}",
|
||||
"url": "",
|
||||
"updateUrl": "",
|
||||
"authorList": ["glee8e"],
|
||||
"credits": "",
|
||||
"logoFile": "",
|
||||
"screenshots": [],
|
||||
"dependencies": ["Thaumcraft"]
|
||||
}
|
||||
]
|
||||
Reference in new issue
Block a user