Mirror, array and quickreplace.
This commit is contained in:
43
.gitignore
vendored
Normal file
43
.gitignore
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
## Based on GitHub's Eclipse .gitignore
|
||||||
|
|
||||||
|
classes/
|
||||||
|
run/
|
||||||
|
.gradle/
|
||||||
|
build/
|
||||||
|
gradle-app.setting
|
||||||
|
|
||||||
|
## IntelliJ IDEA
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
*.iws
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
## Eclipse
|
||||||
|
|
||||||
|
eclipse/
|
||||||
|
*.pydevproject
|
||||||
|
.project
|
||||||
|
.metadata
|
||||||
|
bin/
|
||||||
|
tmp/
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
*~.nib
|
||||||
|
local.properties
|
||||||
|
.classpath
|
||||||
|
.settings/
|
||||||
|
.loadpath
|
||||||
|
|
||||||
|
# External tool builders
|
||||||
|
.externalToolBuilders/
|
||||||
|
|
||||||
|
# Locally stored "Eclipse launch configurations"
|
||||||
|
*.launch
|
||||||
|
|
||||||
|
# CDT-specific
|
||||||
|
.cproject
|
||||||
|
|
||||||
|
# PDT-specific
|
||||||
|
.buildpath
|
||||||
77
build.gradle
Normal file
77
build.gradle
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
maven { url = "http://files.minecraftforge.net/maven" }
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
apply plugin: 'net.minecraftforge.gradle.forge'
|
||||||
|
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
|
||||||
|
|
||||||
|
|
||||||
|
version = "0.1.1"
|
||||||
|
group = "nl.requios.effortlessbuilding" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||||
|
archivesBaseName = "effortlessbuilding"
|
||||||
|
|
||||||
|
sourceCompatibility = targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
|
||||||
|
compileJava {
|
||||||
|
sourceCompatibility = targetCompatibility = '1.8'
|
||||||
|
}
|
||||||
|
|
||||||
|
minecraft {
|
||||||
|
version = "1.12.2-14.23.4.2705"
|
||||||
|
runDir = "run"
|
||||||
|
|
||||||
|
// the mappings can be changed at any time, and must be in the following format.
|
||||||
|
// snapshot_YYYYMMDD snapshot are built nightly.
|
||||||
|
// stable_# stables are built at the discretion of the MCP team.
|
||||||
|
// Use non-default mappings at your own risk. they may not always work.
|
||||||
|
// simply re-run your setup task after changing the mappings to update your workspace.
|
||||||
|
mappings = "snapshot_20171003"
|
||||||
|
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// you may put jars on which you depend on in ./libs
|
||||||
|
// or you may define them like so..
|
||||||
|
//compile "some.group:artifact:version:classifier"
|
||||||
|
//compile "some.group:artifact:version"
|
||||||
|
|
||||||
|
// real examples
|
||||||
|
//compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
|
||||||
|
//compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env
|
||||||
|
|
||||||
|
// the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
|
||||||
|
//provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
|
||||||
|
|
||||||
|
// the deobf configurations: 'deobfCompile' and 'deobfProvided' are the same as the normal compile and provided,
|
||||||
|
// except that these dependencies get remapped to your current MCP mappings
|
||||||
|
//deobfCompile 'com.mod-buildcraft:buildcraft:6.0.8:dev'
|
||||||
|
//deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
|
||||||
|
|
||||||
|
// for more info...
|
||||||
|
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
|
||||||
|
// http://www.gradle.org/docs/current/userguide/dependency_management.html
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
processResources {
|
||||||
|
// this will ensure that this task is redone when the versions change.
|
||||||
|
inputs.property "version", project.version
|
||||||
|
inputs.property "mcversion", project.minecraft.version
|
||||||
|
|
||||||
|
// replace stuff in mcmod.info, nothing else
|
||||||
|
from(sourceSets.main.resources.srcDirs) {
|
||||||
|
include 'mcmod.info'
|
||||||
|
|
||||||
|
// replace version and mcversion
|
||||||
|
expand 'version':project.version, 'mcversion':project.minecraft.version
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy everything else except the mcmod.info
|
||||||
|
from(sourceSets.main.resources.srcDirs) {
|
||||||
|
exclude 'mcmod.info'
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#Mon Sep 14 12:28:28 PDT 2015
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip
|
||||||
164
gradlew
vendored
Normal file
164
gradlew
vendored
Normal file
@@ -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 "$@"
|
||||||
90
gradlew.bat
vendored
Normal file
90
gradlew.bat
vendored
Normal file
@@ -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
|
||||||
82
src/main/java/nl/requios/effortlessbuilding/Array.java
Normal file
82
src/main/java/nl/requios/effortlessbuilding/Array.java
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package nl.requios.effortlessbuilding;
|
||||||
|
|
||||||
|
import net.minecraft.util.EnumHand;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3i;
|
||||||
|
import net.minecraftforge.common.util.BlockSnapshot;
|
||||||
|
import net.minecraftforge.event.world.BlockEvent;
|
||||||
|
|
||||||
|
public class Array {
|
||||||
|
//TODO config file
|
||||||
|
public static final int MAX_COUNT = 100;
|
||||||
|
|
||||||
|
public static class ArraySettings{
|
||||||
|
public boolean enabled = false;
|
||||||
|
public BlockPos offset = BlockPos.ORIGIN;
|
||||||
|
public int count = 5;
|
||||||
|
|
||||||
|
public ArraySettings(){
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArraySettings(boolean enabled, BlockPos offset, int count) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
this.offset = offset;
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called from EventHandler
|
||||||
|
public static void onBlockPlaced(BlockEvent.PlaceEvent event) {
|
||||||
|
if (event.getWorld().isRemote) return;
|
||||||
|
|
||||||
|
//find arraysettings for the player that placed the block
|
||||||
|
ArraySettings a = BuildSettingsManager.getBuildSettings(event.getPlayer()).getArraySettings();
|
||||||
|
if (a == null || !a.enabled) return;
|
||||||
|
|
||||||
|
if (a.offset.getX() == 0 && a.offset.getY() == 0 && a.offset.getZ() == 0) return;
|
||||||
|
|
||||||
|
BlockPos pos = event.getPos();
|
||||||
|
Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ());
|
||||||
|
for (int i = 0; i < a.count; i++) {
|
||||||
|
pos = pos.add(offset);
|
||||||
|
if (event.getWorld().isBlockLoaded(pos, true)) {
|
||||||
|
event.getWorld().setBlockState(pos, event.getPlacedBlock());
|
||||||
|
|
||||||
|
//Mirror synergy
|
||||||
|
BlockSnapshot blockSnapshot = new BlockSnapshot(event.getWorld(), pos, event.getPlacedBlock());
|
||||||
|
BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, event.getPlacedBlock(), event.getPlayer(), EnumHand.MAIN_HAND);
|
||||||
|
Mirror.onBlockPlaced(placeEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called from EventHandler
|
||||||
|
public static void onBlockBroken(BlockEvent.BreakEvent event) {
|
||||||
|
if (event.getWorld().isRemote) return;
|
||||||
|
|
||||||
|
//find arraysettings for the player that placed the block
|
||||||
|
ArraySettings a = BuildSettingsManager.getBuildSettings(event.getPlayer()).getArraySettings();
|
||||||
|
if (a == null || !a.enabled) return;
|
||||||
|
|
||||||
|
if (a.offset.getX() == 0 && a.offset.getY() == 0 && a.offset.getZ() == 0) return;
|
||||||
|
|
||||||
|
BlockPos pos = event.getPos();
|
||||||
|
Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ());
|
||||||
|
for (int i = 0; i < a.count; i++) {
|
||||||
|
pos = pos.add(offset);
|
||||||
|
if (event.getWorld().isBlockLoaded(pos, false)) {
|
||||||
|
event.getWorld().setBlockToAir(pos);
|
||||||
|
|
||||||
|
//Mirror synergy
|
||||||
|
BlockEvent.BreakEvent breakEvent = new BlockEvent.BreakEvent(event.getWorld(), pos, event.getState(), event.getPlayer());
|
||||||
|
Mirror.onBlockBroken(breakEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @SubscribeEvent
|
||||||
|
// @SideOnly(Side.CLIENT)
|
||||||
|
// public static void onRender(RenderWorldLastEvent event) {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
package nl.requios.effortlessbuilding;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
|
||||||
|
import nl.requios.effortlessbuilding.capability.BuildModifierCapability;
|
||||||
|
import nl.requios.effortlessbuilding.network.BuildSettingsMessage;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber
|
||||||
|
public class BuildSettingsManager {
|
||||||
|
|
||||||
|
public static BuildSettings getBuildSettings(EntityPlayer player){
|
||||||
|
if (player.hasCapability(BuildModifierCapability.buildModifier, null)) {
|
||||||
|
BuildModifierCapability.IBuildModifier capability = player.getCapability(BuildModifierCapability.buildModifier, null);
|
||||||
|
return capability.getBuildModifierData();
|
||||||
|
}
|
||||||
|
EffortlessBuilding.log("buildsettings is null");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setBuildSettings(EntityPlayer player, BuildSettings buildSettings) {
|
||||||
|
if (player == null) {
|
||||||
|
EffortlessBuilding.log("cannot set buildsettings, player is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (player.hasCapability(BuildModifierCapability.buildModifier, null)) {
|
||||||
|
BuildModifierCapability.IBuildModifier capability = player.getCapability(BuildModifierCapability.buildModifier, null);
|
||||||
|
capability.setBuildModifierData(buildSettings);
|
||||||
|
} else {
|
||||||
|
EffortlessBuilding.log(player, "Saving buildsettings failed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BuildSettings {
|
||||||
|
private Mirror.MirrorSettings mirrorSettings;
|
||||||
|
private Array.ArraySettings arraySettings;
|
||||||
|
private boolean quickReplace = false;
|
||||||
|
|
||||||
|
public BuildSettings() {
|
||||||
|
mirrorSettings = new Mirror.MirrorSettings();
|
||||||
|
arraySettings = new Array.ArraySettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BuildSettings(Mirror.MirrorSettings mirrorSettings, Array.ArraySettings arraySettings, boolean quickReplace) {
|
||||||
|
this.mirrorSettings = mirrorSettings;
|
||||||
|
this.arraySettings = arraySettings;
|
||||||
|
this.quickReplace = quickReplace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mirror.MirrorSettings getMirrorSettings() {
|
||||||
|
return mirrorSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMirrorSettings(Mirror.MirrorSettings mirrorSettings) {
|
||||||
|
this.mirrorSettings = mirrorSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Array.ArraySettings getArraySettings() {
|
||||||
|
return arraySettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArraySettings(Array.ArraySettings arraySettings) {
|
||||||
|
this.arraySettings = arraySettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean doQuickReplace() {
|
||||||
|
return quickReplace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuickReplace(boolean quickReplace) {
|
||||||
|
this.quickReplace = quickReplace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
|
||||||
|
EntityPlayer player = event.player;
|
||||||
|
handleNewPlayer(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) {
|
||||||
|
EntityPlayer player = event.player;
|
||||||
|
handleNewPlayer(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void handleNewPlayer(EntityPlayer player){
|
||||||
|
if (getBuildSettings(player) == null) {
|
||||||
|
setBuildSettings(player, new BuildSettings());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Only on server
|
||||||
|
if (!player.world.isRemote) {
|
||||||
|
//Send to client
|
||||||
|
BuildSettingsMessage msg = new BuildSettingsMessage(getBuildSettings(player));
|
||||||
|
EffortlessBuilding.packetHandler.sendTo(msg, (EntityPlayerMP) player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package nl.requios.effortlessbuilding;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.util.text.TextComponentString;
|
||||||
|
import net.minecraftforge.common.capabilities.CapabilityManager;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.Mod.EventHandler;
|
||||||
|
import net.minecraftforge.fml.common.SidedProxy;
|
||||||
|
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||||
|
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
||||||
|
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||||
|
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
|
||||||
|
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
|
||||||
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
import nl.requios.effortlessbuilding.capability.*;
|
||||||
|
import nl.requios.effortlessbuilding.inventory.RandomizerGuiHandler;
|
||||||
|
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
|
||||||
|
import nl.requios.effortlessbuilding.network.BuildSettingsMessage;
|
||||||
|
import nl.requios.effortlessbuilding.network.QuickReplaceMessage;
|
||||||
|
import nl.requios.effortlessbuilding.proxy.IProxy;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
@Mod(modid = EffortlessBuilding.MODID, name = EffortlessBuilding.NAME, version = EffortlessBuilding.VERSION)
|
||||||
|
@Mod.EventBusSubscriber
|
||||||
|
public class EffortlessBuilding
|
||||||
|
{
|
||||||
|
public static final String MODID = "effortlessbuilding";
|
||||||
|
public static final String NAME = "Effortless Building";
|
||||||
|
public static final String VERSION = "0.1.2";
|
||||||
|
|
||||||
|
@Mod.Instance(EffortlessBuilding.MODID)
|
||||||
|
public static EffortlessBuilding instance;
|
||||||
|
|
||||||
|
public static Logger logger;
|
||||||
|
|
||||||
|
@SidedProxy(
|
||||||
|
clientSide="nl.requios.effortlessbuilding.proxy.ClientProxy",
|
||||||
|
serverSide="nl.requios.effortlessbuilding.proxy.ServerProxy"
|
||||||
|
)
|
||||||
|
public static IProxy proxy;
|
||||||
|
|
||||||
|
public static final SimpleNetworkWrapper packetHandler = NetworkRegistry.INSTANCE.newSimpleChannel(EffortlessBuilding.MODID);
|
||||||
|
|
||||||
|
public static final Block[] BLOCKS = {
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final Item[] ITEMS = {
|
||||||
|
new ItemRandomizerBag()
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final int RANDOMIZER_BAG_GUI = 0;
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
// preInit "Run before anything else. Read your config, create blocks, items, etc, and register them with the GameRegistry."
|
||||||
|
public void preInit(FMLPreInitializationEvent event)
|
||||||
|
{
|
||||||
|
logger = event.getModLog();
|
||||||
|
|
||||||
|
CapabilityManager.INSTANCE.register(BuildModifierCapability.IBuildModifier.class, new BuildModifierCapability.Storage(), BuildModifierCapability.BuildModifier.class);
|
||||||
|
|
||||||
|
EffortlessBuilding.packetHandler.registerMessage(BuildSettingsMessage.MessageHandler.class, BuildSettingsMessage.class, 0, Side.SERVER);
|
||||||
|
EffortlessBuilding.packetHandler.registerMessage(BuildSettingsMessage.MessageHandler.class, BuildSettingsMessage.class, 0, Side.CLIENT);
|
||||||
|
|
||||||
|
EffortlessBuilding.packetHandler.registerMessage(QuickReplaceMessage.MessageHandler.class, QuickReplaceMessage.class, 1, Side.SERVER);
|
||||||
|
EffortlessBuilding.packetHandler.registerMessage(QuickReplaceMessage.MessageHandler.class, QuickReplaceMessage.class, 1, Side.CLIENT);
|
||||||
|
|
||||||
|
proxy.preInit(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
// Do your mod setup. Build whatever data structures you care about.
|
||||||
|
// Register network handlers
|
||||||
|
public void init(FMLInitializationEvent event)
|
||||||
|
{
|
||||||
|
NetworkRegistry.INSTANCE.registerGuiHandler(EffortlessBuilding.instance, new RandomizerGuiHandler());
|
||||||
|
proxy.init(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
// postInit "Handle interaction with other mods, complete your setup based on this."
|
||||||
|
public void postInit(FMLPostInitializationEvent event)
|
||||||
|
{
|
||||||
|
proxy.postInit(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void serverStarting(FMLServerStartingEvent event)
|
||||||
|
{
|
||||||
|
proxy.serverStarting(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void log(String msg){
|
||||||
|
logger.info(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void log(EntityPlayer player, String msg){
|
||||||
|
log(player, msg, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void log(EntityPlayer player, String msg, boolean actionBar){
|
||||||
|
player.sendStatusMessage(new TextComponentString(msg), actionBar);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package nl.requios.effortlessbuilding;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemBlock;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraftforge.event.AttachCapabilitiesEvent;
|
||||||
|
import net.minecraftforge.event.RegistryEvent;
|
||||||
|
import net.minecraftforge.event.world.BlockEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import nl.requios.effortlessbuilding.capability.BuildModifierCapability;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber
|
||||||
|
public class EventHandler
|
||||||
|
{
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void registerBlocks(RegistryEvent.Register<Block> event)
|
||||||
|
{
|
||||||
|
event.getRegistry().registerAll(EffortlessBuilding.BLOCKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void registerItems(RegistryEvent.Register<Item> event)
|
||||||
|
{
|
||||||
|
event.getRegistry().registerAll(EffortlessBuilding.ITEMS);
|
||||||
|
|
||||||
|
for (Block block : EffortlessBuilding.BLOCKS)
|
||||||
|
{
|
||||||
|
event.getRegistry().register(new ItemBlock(block).setRegistryName(block.getRegistryName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void attachCapabilities(AttachCapabilitiesEvent<Entity> event) {
|
||||||
|
if (event.getObject() instanceof EntityPlayer) {
|
||||||
|
event.addCapability(new ResourceLocation(EffortlessBuilding.MODID, "BuildModifier"), new BuildModifierCapability.Provider());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onBlockPlaced(BlockEvent.PlaceEvent event) {
|
||||||
|
QuickReplace.onBlockPlaced(event);
|
||||||
|
if (event.isCanceled()) return;
|
||||||
|
Array.onBlockPlaced(event);
|
||||||
|
Mirror.onBlockPlaced(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onBlockBroken(BlockEvent.BreakEvent event) {
|
||||||
|
Array.onBlockBroken(event);
|
||||||
|
Mirror.onBlockBroken(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
401
src/main/java/nl/requios/effortlessbuilding/Mirror.java
Normal file
401
src/main/java/nl/requios/effortlessbuilding/Mirror.java
Normal file
@@ -0,0 +1,401 @@
|
|||||||
|
package nl.requios.effortlessbuilding;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockDirectional;
|
||||||
|
import net.minecraft.block.BlockDispenser;
|
||||||
|
import net.minecraft.block.BlockStairs;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
||||||
|
import net.minecraftforge.event.world.BlockEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.util.Color;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber
|
||||||
|
public class Mirror {
|
||||||
|
|
||||||
|
//TODO config file
|
||||||
|
public static final int MAX_RADIUS = 200;
|
||||||
|
|
||||||
|
private static final Color colorX = new Color(255, 72, 52);
|
||||||
|
private static final Color colorY = new Color(67, 204, 51);
|
||||||
|
private static final Color colorZ = new Color(52, 247, 255);
|
||||||
|
private static final int lineAlpha = 200;
|
||||||
|
private static final int planeAlpha = 75;
|
||||||
|
private static final Vec3d epsilon = new Vec3d(0.001, 0.001, 0.001); //prevents z-fighting
|
||||||
|
|
||||||
|
|
||||||
|
public static class MirrorSettings {
|
||||||
|
public boolean enabled = false;
|
||||||
|
public Vec3d position = new Vec3d(0.5, 64.5, 0.5);
|
||||||
|
public boolean mirrorX = true, mirrorY = false, mirrorZ = false;
|
||||||
|
public int radius = 20;
|
||||||
|
public boolean drawLines = true, drawPlanes = false;
|
||||||
|
|
||||||
|
public MirrorSettings() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public MirrorSettings(boolean mirrorEnabled, Vec3d position, boolean mirrorX, boolean mirrorY, boolean mirrorZ, int radius, boolean drawLines, boolean drawPlanes) {
|
||||||
|
this.enabled = mirrorEnabled;
|
||||||
|
this.position = position;
|
||||||
|
this.mirrorX = mirrorX;
|
||||||
|
this.mirrorY = mirrorY;
|
||||||
|
this.mirrorZ = mirrorZ;
|
||||||
|
this.radius = radius;
|
||||||
|
this.drawLines = drawLines;
|
||||||
|
this.drawPlanes = drawPlanes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called from EventHandler
|
||||||
|
public static void onBlockPlaced(BlockEvent.PlaceEvent event) {
|
||||||
|
if (event.getWorld().isRemote) return;
|
||||||
|
|
||||||
|
//find mirrorsettings for the player that placed the block
|
||||||
|
MirrorSettings m = BuildSettingsManager.getBuildSettings(event.getPlayer()).getMirrorSettings();
|
||||||
|
if (m == null) return;
|
||||||
|
|
||||||
|
if (!m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return;
|
||||||
|
|
||||||
|
//if within mirror distance, mirror
|
||||||
|
BlockPos oldBlockPos = event.getPos();
|
||||||
|
|
||||||
|
if (oldBlockPos.getX() + 0.5 < m.position.x - m.radius || oldBlockPos.getX() + 0.5 > m.position.x + m.radius ||
|
||||||
|
oldBlockPos.getY() + 0.5 < m.position.y - m.radius || oldBlockPos.getY() + 0.5 > m.position.y + m.radius ||
|
||||||
|
oldBlockPos.getZ() + 0.5 < m.position.z - m.radius || oldBlockPos.getZ() + 0.5 > m.position.z+ m.radius)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m.mirrorX) {
|
||||||
|
placeMirrorX(event.getWorld(), m, oldBlockPos, event.getPlacedBlock());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m.mirrorY) {
|
||||||
|
placeMirrorY(event.getWorld(), m, oldBlockPos, event.getPlacedBlock());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m.mirrorZ) {
|
||||||
|
placeMirrorZ(event.getWorld(), m, oldBlockPos, event.getPlacedBlock());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void placeMirrorX(World world, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState) {
|
||||||
|
//find mirror position
|
||||||
|
double x = m.position.x + (m.position.x - oldBlockPos.getX() - 0.5);
|
||||||
|
BlockPos newBlockPos = new BlockPos(x, oldBlockPos.getY(), oldBlockPos.getZ());
|
||||||
|
IBlockState newBlockState = oldBlockState;
|
||||||
|
//place block
|
||||||
|
if (world.isBlockLoaded(newBlockPos, true)) {
|
||||||
|
newBlockState = oldBlockState.withMirror(net.minecraft.util.Mirror.FRONT_BACK);
|
||||||
|
|
||||||
|
world.setBlockState(newBlockPos, newBlockState);
|
||||||
|
}
|
||||||
|
if (m.mirrorY) placeMirrorY(world, m, newBlockPos, newBlockState);
|
||||||
|
if (m.mirrorZ) placeMirrorZ(world, m, newBlockPos, newBlockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void placeMirrorY(World world, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState) {
|
||||||
|
//find mirror position
|
||||||
|
double y = m.position.y + (m.position.y - oldBlockPos.getY() - 0.5);
|
||||||
|
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), y, oldBlockPos.getZ());
|
||||||
|
IBlockState newBlockState = oldBlockState;
|
||||||
|
//place block
|
||||||
|
if (world.isBlockLoaded(newBlockPos, true)) {
|
||||||
|
newBlockState = getVerticalMirror(oldBlockState);
|
||||||
|
|
||||||
|
world.setBlockState(newBlockPos, newBlockState);
|
||||||
|
}
|
||||||
|
if (m.mirrorZ) placeMirrorZ(world, m, newBlockPos, newBlockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void placeMirrorZ(World world, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState) {
|
||||||
|
//find mirror position
|
||||||
|
double z = m.position.z + (m.position.z - oldBlockPos.getZ() - 0.5);
|
||||||
|
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), oldBlockPos.getY(), z);
|
||||||
|
IBlockState newBlockState = oldBlockState;
|
||||||
|
//place block
|
||||||
|
if (world.isBlockLoaded(newBlockPos, true)) {
|
||||||
|
newBlockState = oldBlockState.withMirror(net.minecraft.util.Mirror.LEFT_RIGHT);
|
||||||
|
|
||||||
|
world.setBlockState(newBlockPos, newBlockState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IBlockState getVerticalMirror(IBlockState blockState) {
|
||||||
|
//Stairs
|
||||||
|
if (blockState.getBlock() instanceof BlockStairs) {
|
||||||
|
if (blockState.getValue(BlockStairs.HALF) == BlockStairs.EnumHalf.BOTTOM) {
|
||||||
|
return blockState.withProperty(BlockStairs.HALF, BlockStairs.EnumHalf.TOP);
|
||||||
|
} else {
|
||||||
|
return blockState.withProperty(BlockStairs.HALF, BlockStairs.EnumHalf.BOTTOM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Buttons, endrod, observer, piston
|
||||||
|
if (blockState.getBlock() instanceof BlockDirectional) {
|
||||||
|
if (blockState.getValue(BlockDirectional.FACING) == EnumFacing.DOWN) {
|
||||||
|
return blockState.withProperty(BlockDirectional.FACING, EnumFacing.UP);
|
||||||
|
} else if (blockState.getValue(BlockDirectional.FACING) == EnumFacing.UP) {
|
||||||
|
return blockState.withProperty(BlockDirectional.FACING, EnumFacing.DOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Dispenser, dropper
|
||||||
|
if (blockState.getBlock() instanceof BlockDispenser) {
|
||||||
|
if (blockState.getValue(BlockDispenser.FACING) == EnumFacing.DOWN) {
|
||||||
|
return blockState.withProperty(BlockDispenser.FACING, EnumFacing.UP);
|
||||||
|
} else if (blockState.getValue(BlockDispenser.FACING) == EnumFacing.UP) {
|
||||||
|
return blockState.withProperty(BlockDispenser.FACING, EnumFacing.DOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return blockState;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called from EventHandler
|
||||||
|
public static void onBlockBroken(BlockEvent.BreakEvent event) {
|
||||||
|
if (event.getWorld().isRemote) return;
|
||||||
|
|
||||||
|
//find mirrorsettings for the player that broke the block
|
||||||
|
MirrorSettings m = BuildSettingsManager.getBuildSettings(event.getPlayer()).getMirrorSettings();
|
||||||
|
if (m == null) return;
|
||||||
|
|
||||||
|
if (!m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return;
|
||||||
|
|
||||||
|
//if within mirror distance, break mirror block
|
||||||
|
BlockPos oldBlockPos = event.getPos();
|
||||||
|
|
||||||
|
if (oldBlockPos.getX() + 0.5 < m.position.x - m.radius || oldBlockPos.getX() + 0.5 > m.position.x + m.radius ||
|
||||||
|
oldBlockPos.getY() + 0.5 < m.position.y - m.radius || oldBlockPos.getY() + 0.5 > m.position.y + m.radius ||
|
||||||
|
oldBlockPos.getZ() + 0.5 < m.position.z - m.radius || oldBlockPos.getZ() + 0.5 > m.position.z+ m.radius)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m.mirrorX) {
|
||||||
|
breakMirrorX(event, m, oldBlockPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m.mirrorY) {
|
||||||
|
breakMirrorY(event, m, oldBlockPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m.mirrorZ) {
|
||||||
|
breakMirrorZ(event, m, oldBlockPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void breakMirrorX(BlockEvent.BreakEvent event, MirrorSettings m, BlockPos oldBlockPos) {
|
||||||
|
//find mirror position
|
||||||
|
double x = m.position.x + (m.position.x - oldBlockPos.getX() - 0.5);
|
||||||
|
BlockPos newBlockPos = new BlockPos(x, oldBlockPos.getY(), oldBlockPos.getZ());
|
||||||
|
//break block
|
||||||
|
if (event.getWorld().isBlockLoaded(newBlockPos, true)) {
|
||||||
|
event.getWorld().setBlockToAir(newBlockPos);
|
||||||
|
}
|
||||||
|
if (m.mirrorY) breakMirrorY(event, m, newBlockPos);
|
||||||
|
if (m.mirrorZ) breakMirrorZ(event, m, newBlockPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void breakMirrorY(BlockEvent.BreakEvent event, MirrorSettings m, BlockPos oldBlockPos) {
|
||||||
|
//find mirror position
|
||||||
|
double y = m.position.y + (m.position.y - oldBlockPos.getY() - 0.5);
|
||||||
|
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), y, oldBlockPos.getZ());
|
||||||
|
//place block
|
||||||
|
if (event.getWorld().isBlockLoaded(newBlockPos, true)) {
|
||||||
|
event.getWorld().setBlockToAir(newBlockPos);
|
||||||
|
}
|
||||||
|
if (m.mirrorZ) breakMirrorZ(event, m, newBlockPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void breakMirrorZ(BlockEvent.BreakEvent event, MirrorSettings m, BlockPos oldBlockPos) {
|
||||||
|
//find mirror position
|
||||||
|
double z = m.position.z + (m.position.z - oldBlockPos.getZ() - 0.5);
|
||||||
|
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), oldBlockPos.getY(), z);
|
||||||
|
//place block
|
||||||
|
if (event.getWorld().isBlockLoaded(newBlockPos, true)) {
|
||||||
|
event.getWorld().setBlockToAir(newBlockPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
public static void onRender(RenderWorldLastEvent event) {
|
||||||
|
EntityPlayerSP player = Minecraft.getMinecraft().player;
|
||||||
|
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(player);
|
||||||
|
if (buildSettings == null) return;
|
||||||
|
MirrorSettings m = buildSettings.getMirrorSettings();
|
||||||
|
|
||||||
|
if (m == null || !m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return;
|
||||||
|
|
||||||
|
Vec3d playerPos = new Vec3d(player.posX, player.posY, player.posZ);
|
||||||
|
Vec3d pos = m.position.add(epsilon);
|
||||||
|
int radius = m.radius;
|
||||||
|
|
||||||
|
if (m.mirrorX) {
|
||||||
|
Vec3d posA = new Vec3d(pos.x, pos.y - radius, pos.z - radius);
|
||||||
|
Vec3d posB = new Vec3d(pos.x, pos.y + radius, pos.z + radius);
|
||||||
|
|
||||||
|
drawMirrorPlane(playerPos, posA, posB, colorX, m.drawLines, m.drawPlanes);
|
||||||
|
}
|
||||||
|
if (m.mirrorY) {
|
||||||
|
Vec3d posA = new Vec3d(pos.x - radius, pos.y, pos.z - radius);
|
||||||
|
Vec3d posB = new Vec3d(pos.x + radius, pos.y, pos.z + radius);
|
||||||
|
|
||||||
|
drawMirrorPlaneY(playerPos, posA, posB, colorY, m.drawLines, m.drawPlanes);
|
||||||
|
}
|
||||||
|
if (m.mirrorZ) {
|
||||||
|
Vec3d posA = new Vec3d(pos.x - radius, pos.y - radius, pos.z);
|
||||||
|
Vec3d posB = new Vec3d(pos.x + radius, pos.y + radius, pos.z);
|
||||||
|
|
||||||
|
drawMirrorPlane(playerPos, posA, posB, colorZ, m.drawLines, m.drawPlanes);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Draw axis coordinated colors if two or more axes are enabled
|
||||||
|
//(If only one is enabled the lines are that planes color)
|
||||||
|
if (m.drawLines && ((m.mirrorX && m.mirrorY) || (m.mirrorX && m.mirrorZ) || (m.mirrorY && m.mirrorZ))) {
|
||||||
|
drawMirrorLines(playerPos, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
public static void drawMirrorPlane(Vec3d playerPos, Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes) {
|
||||||
|
|
||||||
|
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
|
||||||
|
GL11.glPushMatrix();
|
||||||
|
GL11.glDisable(GL11.GL_CULL_FACE);
|
||||||
|
GL11.glDisable(GL11.GL_LIGHTING);
|
||||||
|
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
GL11.glEnable(GL11.GL_BLEND);
|
||||||
|
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
GL11.glTranslated(-playerPos.x, -playerPos.y, -playerPos.z);
|
||||||
|
|
||||||
|
GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha);
|
||||||
|
GL11.glLineWidth(2);
|
||||||
|
GL11.glDepthMask(false);
|
||||||
|
Tessellator tessellator = Tessellator.getInstance();
|
||||||
|
BufferBuilder bufferBuilder = tessellator.getBuffer();
|
||||||
|
|
||||||
|
if (drawPlanes) {
|
||||||
|
bufferBuilder.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_COLOR);
|
||||||
|
|
||||||
|
bufferBuilder.pos(posA.x, posA.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(posA.x, posB.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(posB.x, posA.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(posB.x, posB.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
|
||||||
|
|
||||||
|
tessellator.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drawLines) {
|
||||||
|
Vec3d middle = posA.add(posB).scale(0.5);
|
||||||
|
bufferBuilder.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
|
||||||
|
|
||||||
|
bufferBuilder.pos(posA.x, middle.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(posB.x, middle.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(middle.x, posA.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(middle.x, posB.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
|
||||||
|
|
||||||
|
tessellator.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
GL11.glDepthMask(true);
|
||||||
|
GL11.glPopMatrix();
|
||||||
|
GL11.glPopAttrib();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
public static void drawMirrorPlaneY(Vec3d playerPos, Vec3d posA, Vec3d posB, Color c, boolean drawLines, boolean drawPlanes) {
|
||||||
|
|
||||||
|
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
|
||||||
|
GL11.glPushMatrix();
|
||||||
|
GL11.glDisable(GL11.GL_CULL_FACE);
|
||||||
|
GL11.glDisable(GL11.GL_LIGHTING);
|
||||||
|
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
GL11.glEnable(GL11.GL_BLEND);
|
||||||
|
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
GL11.glTranslated(-playerPos.x, -playerPos.y, -playerPos.z);
|
||||||
|
|
||||||
|
GL11.glColor4d(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
|
||||||
|
GL11.glLineWidth(2);
|
||||||
|
GL11.glDepthMask(false);
|
||||||
|
Tessellator tessellator = Tessellator.getInstance();
|
||||||
|
BufferBuilder bufferBuilder = tessellator.getBuffer();
|
||||||
|
|
||||||
|
if (drawPlanes) {
|
||||||
|
bufferBuilder.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_COLOR);
|
||||||
|
|
||||||
|
bufferBuilder.pos(posA.x, posA.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(posA.x, posA.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(posB.x, posA.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(posB.x, posA.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), planeAlpha).endVertex();
|
||||||
|
|
||||||
|
tessellator.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drawLines) {
|
||||||
|
Vec3d middle = posA.add(posB).scale(0.5);
|
||||||
|
bufferBuilder.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
|
||||||
|
|
||||||
|
bufferBuilder.pos(middle.x, middle.y, posA.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(middle.x, middle.y, posB.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(posA.x, middle.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(posB.x, middle.y, middle.z).color(c.getRed(), c.getGreen(), c.getBlue(), lineAlpha).endVertex();
|
||||||
|
|
||||||
|
tessellator.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
GL11.glDepthMask(true);
|
||||||
|
GL11.glPopMatrix();
|
||||||
|
GL11.glPopAttrib();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
public static void drawMirrorLines(Vec3d playerPos, MirrorSettings m) {
|
||||||
|
|
||||||
|
Vec3d pos = m.position.add(epsilon);
|
||||||
|
|
||||||
|
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
|
||||||
|
GL11.glPushMatrix();
|
||||||
|
GL11.glDisable(GL11.GL_CULL_FACE);
|
||||||
|
GL11.glDisable(GL11.GL_LIGHTING);
|
||||||
|
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
GL11.glEnable(GL11.GL_BLEND);
|
||||||
|
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
GL11.glTranslated(-playerPos.x, -playerPos.y, -playerPos.z);
|
||||||
|
|
||||||
|
GL11.glColor4d(100, 100, 100, 255);
|
||||||
|
GL11.glLineWidth(2);
|
||||||
|
GL11.glDepthMask(false);
|
||||||
|
Tessellator tessellator = Tessellator.getInstance();
|
||||||
|
BufferBuilder bufferBuilder = tessellator.getBuffer();
|
||||||
|
|
||||||
|
bufferBuilder.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR);
|
||||||
|
|
||||||
|
bufferBuilder.pos(pos.x - m.radius, pos.y, pos.z).color(colorZ.getRed(), colorZ.getGreen(), colorZ.getBlue(), lineAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(pos.x + m.radius, pos.y, pos.z).color(colorZ.getRed(), colorZ.getGreen(), colorZ.getBlue(), lineAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(pos.x, pos.y - m.radius, pos.z).color(colorY.getRed(), colorY.getGreen(), colorY.getBlue(), lineAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(pos.x, pos.y + m.radius, pos.z).color(colorY.getRed(), colorY.getGreen(), colorY.getBlue(), lineAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(pos.x, pos.y, pos.z - m.radius).color(colorX.getRed(), colorX.getGreen(), colorX.getBlue(), lineAlpha).endVertex();
|
||||||
|
bufferBuilder.pos(pos.x, pos.y, pos.z + m.radius).color(colorX.getRed(), colorX.getGreen(), colorX.getBlue(), lineAlpha).endVertex();
|
||||||
|
|
||||||
|
tessellator.draw();
|
||||||
|
|
||||||
|
GL11.glDepthMask(true);
|
||||||
|
GL11.glPopMatrix();
|
||||||
|
GL11.glPopAttrib();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package nl.requios.effortlessbuilding;
|
||||||
|
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
|
import net.minecraft.util.EnumHand;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraftforge.common.util.BlockSnapshot;
|
||||||
|
import net.minecraftforge.event.world.BlockEvent;
|
||||||
|
import nl.requios.effortlessbuilding.network.QuickReplaceMessage;
|
||||||
|
|
||||||
|
import java.util.Dictionary;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class QuickReplace {
|
||||||
|
//Dilemma in getting blockstate from event to when message is received:
|
||||||
|
// 1) send via client. Then hacking makes it possible to place any block.
|
||||||
|
// 2) save serverside. Messages may not be received chronologically so data could get switched.
|
||||||
|
//Solution for now: save blockstate per player. Messages from 1 player will rarely come unchronologically
|
||||||
|
//and players will rarely switch between blocks that quickly.
|
||||||
|
|
||||||
|
private static Dictionary<UUID, IBlockState> blockStates = new Hashtable<>();
|
||||||
|
|
||||||
|
public static void onBlockPlaced(BlockEvent.PlaceEvent event) {
|
||||||
|
if (event.getWorld().isRemote) return;
|
||||||
|
//Only serverside
|
||||||
|
|
||||||
|
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(event.getPlayer());
|
||||||
|
if (!buildSettings.doQuickReplace()) return;
|
||||||
|
|
||||||
|
//TODO base on player facing instead, no more messages (or break block clientside)
|
||||||
|
|
||||||
|
blockStates.put(event.getPlayer().getUniqueID(), event.getPlacedBlock());
|
||||||
|
|
||||||
|
//RayTraceResult result = event.getWorld().rayTraceBlocks(event.getPlayer().getPositionEyes(1f), event.getPlayer().getLookVec());
|
||||||
|
EffortlessBuilding.packetHandler.sendTo(new QuickReplaceMessage(), (EntityPlayerMP) event.getPlayer());
|
||||||
|
|
||||||
|
event.setCanceled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onMessageReceived(EntityPlayer player, QuickReplaceMessage message) {
|
||||||
|
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(player);
|
||||||
|
if (!buildSettings.doQuickReplace()) return;
|
||||||
|
|
||||||
|
//TODO check for bedrock, end portal etc in survival
|
||||||
|
|
||||||
|
if (!message.isBlockHit() || message.getBlockPos() == null) return;
|
||||||
|
|
||||||
|
BlockPos placedAgainstBlockPos = message.getBlockPos();
|
||||||
|
//placedAgainstBlockPos = placedAgainstBlockPos.down();
|
||||||
|
IBlockState blockState = blockStates.get(player.getUniqueID());
|
||||||
|
player.world.setBlockState(placedAgainstBlockPos, blockState);
|
||||||
|
|
||||||
|
//Mirror and Array synergy
|
||||||
|
BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, placedAgainstBlockPos, blockState);
|
||||||
|
BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, blockState, player, EnumHand.MAIN_HAND);
|
||||||
|
Array.onBlockPlaced(placeEvent);
|
||||||
|
Mirror.onBlockPlaced(placeEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
package nl.requios.effortlessbuilding.capability;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.NBTBase;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
|
import net.minecraftforge.common.capabilities.CapabilityInject;
|
||||||
|
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
|
||||||
|
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import nl.requios.effortlessbuilding.Array;
|
||||||
|
import nl.requios.effortlessbuilding.BuildSettingsManager.BuildSettings;
|
||||||
|
import nl.requios.effortlessbuilding.Mirror;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber
|
||||||
|
public class BuildModifierCapability {
|
||||||
|
|
||||||
|
@CapabilityInject(IBuildModifier.class)
|
||||||
|
public final static Capability<IBuildModifier> buildModifier = null;
|
||||||
|
|
||||||
|
public interface IBuildModifier {
|
||||||
|
BuildSettings getBuildModifierData();
|
||||||
|
|
||||||
|
void setBuildModifierData(BuildSettings buildSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BuildModifier implements IBuildModifier {
|
||||||
|
private BuildSettings buildSettings;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BuildSettings getBuildModifierData() {
|
||||||
|
return buildSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBuildModifierData(BuildSettings buildSettings) {
|
||||||
|
this.buildSettings = buildSettings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Storage implements Capability.IStorage<IBuildModifier> {
|
||||||
|
@Override
|
||||||
|
public NBTBase writeNBT(Capability<IBuildModifier> capability, IBuildModifier instance, EnumFacing side) {
|
||||||
|
NBTTagCompound compound = new NBTTagCompound();
|
||||||
|
BuildSettings buildSettings = instance.getBuildModifierData();
|
||||||
|
|
||||||
|
//MIRROR
|
||||||
|
Mirror.MirrorSettings m = buildSettings.getMirrorSettings();
|
||||||
|
compound.setBoolean("mirrorEnabled", m.enabled);
|
||||||
|
compound.setDouble("mirrorPosX", m.position.x);
|
||||||
|
compound.setDouble("mirrorPosY", m.position.y);
|
||||||
|
compound.setDouble("mirrorPosZ", m.position.z);
|
||||||
|
compound.setBoolean("mirrorX", m.mirrorX);
|
||||||
|
compound.setBoolean("mirrorY", m.mirrorY);
|
||||||
|
compound.setBoolean("mirrorZ", m.mirrorZ);
|
||||||
|
compound.setInteger("mirrorRadius", m.radius);
|
||||||
|
compound.setBoolean("mirrorDrawLines", m.drawLines);
|
||||||
|
compound.setBoolean("mirrorDrawPlanes", m.drawPlanes);
|
||||||
|
|
||||||
|
//ARRAY
|
||||||
|
Array.ArraySettings a = buildSettings.getArraySettings();
|
||||||
|
compound.setBoolean("arrayEnabled", a.enabled);
|
||||||
|
compound.setInteger("arrayOffsetX", a.offset.getX());
|
||||||
|
compound.setInteger("arrayOffsetY", a.offset.getY());
|
||||||
|
compound.setInteger("arrayOffsetZ", a.offset.getZ());
|
||||||
|
compound.setInteger("arrayCount", a.count);
|
||||||
|
|
||||||
|
//compound.setBoolean("quickReplace", buildSettings.doQuickReplace()); dont save quickreplace
|
||||||
|
return compound;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readNBT(Capability<IBuildModifier> capability, IBuildModifier instance, EnumFacing side, NBTBase nbt) {
|
||||||
|
NBTTagCompound compound = (NBTTagCompound) nbt;
|
||||||
|
|
||||||
|
//MIRROR
|
||||||
|
boolean mirrorEnabled = compound.getBoolean("mirrorEnabled");
|
||||||
|
Vec3d mirrorPosition = new Vec3d(compound.getDouble("mirrorPosX"), compound.getDouble("mirrorPosY"), compound.getDouble("mirrorPosZ"));
|
||||||
|
boolean mirrorX = compound.getBoolean("mirrorX");
|
||||||
|
boolean mirrorY = compound.getBoolean("mirrorY");
|
||||||
|
boolean mirrorZ = compound.getBoolean("mirrorZ");
|
||||||
|
int mirrorRadius = compound.getInteger("mirrorRadius");
|
||||||
|
boolean mirrorDrawLines = compound.getBoolean("mirrorDrawLines");
|
||||||
|
boolean mirrorDrawPlanes = compound.getBoolean("mirrorDrawPlanes");
|
||||||
|
Mirror.MirrorSettings mirrorSettings = new Mirror.MirrorSettings(mirrorEnabled, mirrorPosition, mirrorX, mirrorY, mirrorZ, mirrorRadius, mirrorDrawLines, mirrorDrawPlanes);
|
||||||
|
|
||||||
|
//ARRAY
|
||||||
|
boolean arrayEnabled = compound.getBoolean("arrayEnabled");
|
||||||
|
BlockPos arrayOffset = new BlockPos(compound.getInteger("arrayOffsetX"), compound.getInteger("arrayOffsetY"), compound.getInteger("arrayOffsetZ"));
|
||||||
|
int arrayCount = compound.getInteger("arrayCount");
|
||||||
|
Array.ArraySettings arraySettings = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount);
|
||||||
|
|
||||||
|
//boolean quickReplace = compound.getBoolean("quickReplace"); //dont load quickreplace
|
||||||
|
|
||||||
|
BuildSettings buildSettings = new BuildSettings(mirrorSettings, arraySettings, false);
|
||||||
|
instance.setBuildModifierData(buildSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Provider implements ICapabilitySerializable<NBTBase> {
|
||||||
|
IBuildModifier inst = buildModifier.getDefaultInstance();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) {
|
||||||
|
return capability == buildModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing) {
|
||||||
|
if (capability == buildModifier) return buildModifier.<T>cast(inst);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NBTBase serializeNBT() {
|
||||||
|
return buildModifier.getStorage().writeNBT(buildModifier, inst, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deserializeNBT(NBTBase nbt) {
|
||||||
|
buildModifier.getStorage().readNBT(buildModifier, inst, null, nbt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allows for the capability to persist after death.
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void clonePlayer(PlayerEvent.Clone event) {
|
||||||
|
IBuildModifier original = event.getOriginal().getCapability(buildModifier, null);
|
||||||
|
IBuildModifier clone = event.getEntity().getCapability(buildModifier, null);
|
||||||
|
clone.setBuildModifierData(original.getBuildModifierData());
|
||||||
|
}
|
||||||
|
}
|
||||||
314
src/main/java/nl/requios/effortlessbuilding/gui/SettingsGui.java
Normal file
314
src/main/java/nl/requios/effortlessbuilding/gui/SettingsGui.java
Normal file
@@ -0,0 +1,314 @@
|
|||||||
|
package nl.requios.effortlessbuilding.gui;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.GuiButton;
|
||||||
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
|
import net.minecraft.client.gui.GuiTextField;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraftforge.fml.client.config.GuiCheckBox;
|
||||||
|
import nl.requios.effortlessbuilding.Array;
|
||||||
|
import nl.requios.effortlessbuilding.BuildSettingsManager;
|
||||||
|
import nl.requios.effortlessbuilding.EffortlessBuilding;
|
||||||
|
import nl.requios.effortlessbuilding.Mirror;
|
||||||
|
import nl.requios.effortlessbuilding.network.BuildSettingsMessage;
|
||||||
|
import nl.requios.effortlessbuilding.proxy.ClientProxy;
|
||||||
|
import org.lwjgl.input.Keyboard;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SettingsGui extends GuiScreen {
|
||||||
|
|
||||||
|
protected List<GuiTextField> textFieldList = new ArrayList<>();
|
||||||
|
|
||||||
|
protected List<GuiButton> mirrorButtonList = new ArrayList<>();
|
||||||
|
protected List<GuiTextField> mirrorTextFieldList = new ArrayList<>();
|
||||||
|
protected List<GuiTextField> arrayTextFieldList = new ArrayList<>();
|
||||||
|
|
||||||
|
private GuiTextField textMirrorPosX, textMirrorPosY, textMirrorPosZ, textMirrorRadius;
|
||||||
|
private GuiCheckBox buttonMirrorEnabled, buttonMirrorX, buttonMirrorY, buttonMirrorZ;
|
||||||
|
private GuiButton buttonDrawPlanes, buttonDrawLines;
|
||||||
|
private boolean drawPlanes, drawLines;
|
||||||
|
private GuiButton buttonCurrentPosition, buttonClose;
|
||||||
|
|
||||||
|
private GuiCheckBox buttonArrayEnabled;
|
||||||
|
private GuiTextField textArrayOffsetX, textArrayOffsetY, textArrayOffsetZ, textArrayCount;
|
||||||
|
|
||||||
|
private int left, right, top, bottom;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
//Create buttons and labels and add them to buttonList/labelList
|
||||||
|
public void initGui() {
|
||||||
|
int id = 0;
|
||||||
|
left = width / 2 - 140;
|
||||||
|
right = width / 2 + 140;
|
||||||
|
top = height / 2 - 100;
|
||||||
|
bottom = height / 2 + 100;
|
||||||
|
|
||||||
|
//MIRROR
|
||||||
|
int y = top - 2;
|
||||||
|
buttonMirrorEnabled = new GuiCheckBox(id++, left - 15 + 8, y, "", false);
|
||||||
|
buttonList.add(buttonMirrorEnabled);
|
||||||
|
|
||||||
|
y = top + 18;
|
||||||
|
textMirrorPosX = new GuiTextField(id++, fontRenderer, left + 70, y, 50, 18);
|
||||||
|
textMirrorPosX.setText("0.5");
|
||||||
|
mirrorTextFieldList.add(textMirrorPosX);
|
||||||
|
|
||||||
|
textMirrorPosY = new GuiTextField(id++, fontRenderer, left + 140, y, 50, 18);
|
||||||
|
textMirrorPosY.setText("64.5");
|
||||||
|
mirrorTextFieldList.add(textMirrorPosY);
|
||||||
|
|
||||||
|
textMirrorPosZ = new GuiTextField(id++, fontRenderer, left + 210, y, 50, 18);
|
||||||
|
textMirrorPosZ.setText("0.5");
|
||||||
|
mirrorTextFieldList.add(textMirrorPosZ);
|
||||||
|
|
||||||
|
y = top + 50;
|
||||||
|
buttonMirrorX = new GuiCheckBox(id++, left + 60, y, " X", true);
|
||||||
|
mirrorButtonList.add(buttonMirrorX);
|
||||||
|
|
||||||
|
buttonMirrorY = new GuiCheckBox(id++, left + 100, y, " Y", false);
|
||||||
|
mirrorButtonList.add(buttonMirrorY);
|
||||||
|
|
||||||
|
buttonMirrorZ = new GuiCheckBox(id++, left + 140, y, " Z", false);
|
||||||
|
mirrorButtonList.add(buttonMirrorZ);
|
||||||
|
|
||||||
|
y = top + 47;
|
||||||
|
textMirrorRadius = new GuiTextField(id++, fontRenderer, left + 220, y, 60, 18);
|
||||||
|
textMirrorRadius.setText("50");
|
||||||
|
mirrorTextFieldList.add(textMirrorRadius);
|
||||||
|
|
||||||
|
y = top + 72;
|
||||||
|
buttonCurrentPosition = new GuiButton(id++, left + 5, y, 110, 20, "Set to current pos");
|
||||||
|
mirrorButtonList.add(buttonCurrentPosition);
|
||||||
|
|
||||||
|
buttonDrawLines = new GuiButton(id++, left + 127, y, 70, 20, "Show lines");
|
||||||
|
mirrorButtonList.add(buttonDrawLines);
|
||||||
|
|
||||||
|
buttonDrawPlanes = new GuiButton(id++, left + 209, y, 75, 20, "Show area");
|
||||||
|
mirrorButtonList.add(buttonDrawPlanes);
|
||||||
|
|
||||||
|
//ARRAY
|
||||||
|
y = top + 100;
|
||||||
|
buttonArrayEnabled = new GuiCheckBox(id++, left - 15 + 8, y, "", false);
|
||||||
|
buttonList.add(buttonArrayEnabled);
|
||||||
|
|
||||||
|
y = top + 120;
|
||||||
|
textArrayOffsetX = new GuiTextField(id++, fontRenderer, left + 70, y, 50, 18);
|
||||||
|
textArrayOffsetX.setText("0");
|
||||||
|
arrayTextFieldList.add(textArrayOffsetX);
|
||||||
|
|
||||||
|
textArrayOffsetY = new GuiTextField(id++, fontRenderer, left + 140, y, 50, 18);
|
||||||
|
textArrayOffsetY.setText("0");
|
||||||
|
arrayTextFieldList.add(textArrayOffsetY);
|
||||||
|
|
||||||
|
textArrayOffsetZ = new GuiTextField(id++, fontRenderer, left + 210, y, 50, 18);
|
||||||
|
textArrayOffsetZ.setText("0");
|
||||||
|
arrayTextFieldList.add(textArrayOffsetZ);
|
||||||
|
|
||||||
|
y = top + 150;
|
||||||
|
textArrayCount = new GuiTextField(id++, fontRenderer, left + 55, y, 50, 18);
|
||||||
|
textArrayCount.setText("5");
|
||||||
|
arrayTextFieldList.add(textArrayCount);
|
||||||
|
|
||||||
|
//CLOSE
|
||||||
|
y = height - 40;
|
||||||
|
buttonClose = new GuiButton(id++, width / 2 - 100, y, "Close");
|
||||||
|
buttonList.add(buttonClose);
|
||||||
|
|
||||||
|
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(mc.player);
|
||||||
|
if (buildSettings != null) {
|
||||||
|
//MIRROR
|
||||||
|
Mirror.MirrorSettings m = buildSettings.getMirrorSettings();
|
||||||
|
buttonMirrorEnabled.setIsChecked(m.enabled);
|
||||||
|
textMirrorPosX.setText(String.valueOf(m.position.x));
|
||||||
|
textMirrorPosY.setText(String.valueOf(m.position.y));
|
||||||
|
textMirrorPosZ.setText(String.valueOf(m.position.z));
|
||||||
|
buttonMirrorX.setIsChecked(m.mirrorX);
|
||||||
|
buttonMirrorY.setIsChecked(m.mirrorY);
|
||||||
|
buttonMirrorZ.setIsChecked(m.mirrorZ);
|
||||||
|
textMirrorRadius.setText(String.valueOf(m.radius));
|
||||||
|
drawLines = m.drawLines;
|
||||||
|
drawPlanes = m.drawPlanes;
|
||||||
|
buttonDrawLines.displayString = drawLines ? "Hide lines" : "Show lines";
|
||||||
|
buttonDrawPlanes.displayString = drawPlanes ? "Hide area" : "Show area";
|
||||||
|
|
||||||
|
//ARRAY
|
||||||
|
Array.ArraySettings a = buildSettings.getArraySettings();
|
||||||
|
buttonArrayEnabled.setIsChecked(a.enabled);
|
||||||
|
textArrayOffsetX.setText(String.valueOf(a.offset.getX()));
|
||||||
|
textArrayOffsetY.setText(String.valueOf(a.offset.getY()));
|
||||||
|
textArrayOffsetZ.setText(String.valueOf(a.offset.getZ()));
|
||||||
|
textArrayCount.setText(String.valueOf(a.count));
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonList.addAll(mirrorButtonList);
|
||||||
|
textFieldList.addAll(mirrorTextFieldList);
|
||||||
|
textFieldList.addAll(arrayTextFieldList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
//Process general logic, i.e. hide buttons
|
||||||
|
public void updateScreen() {
|
||||||
|
textFieldList.forEach(GuiTextField::updateCursorCounter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
//Set colors using GL11, use the fontRendererObj field to display text
|
||||||
|
//Use drawTexturedModalRect() to transfers areas of a texture resource to the screen
|
||||||
|
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
|
||||||
|
this.drawDefaultBackground();
|
||||||
|
|
||||||
|
int y = top;
|
||||||
|
int offset = 8;
|
||||||
|
|
||||||
|
buttonMirrorEnabled.drawButton(this.mc, mouseX, mouseY, partialTicks);
|
||||||
|
if (buttonMirrorEnabled.isChecked()) {
|
||||||
|
fontRenderer.drawString("Mirror enabled", left + offset, y, 0xFFFFFF, true);
|
||||||
|
|
||||||
|
y = top + 18 + 5;
|
||||||
|
fontRenderer.drawString("Position", left + offset, y, 0xFFFFFF, true);
|
||||||
|
fontRenderer.drawString("X", left + 50 + offset, y, 0xFFFFFF, true);
|
||||||
|
fontRenderer.drawString("Y", left + 120 + offset, y, 0xFFFFFF, true);
|
||||||
|
fontRenderer.drawString("Z", left + 190 + offset, y, 0xFFFFFF, true);
|
||||||
|
|
||||||
|
y = top + 52;
|
||||||
|
fontRenderer.drawString("Direction", left + offset, y, 0xFFFFFF, true);
|
||||||
|
fontRenderer.drawString("Size", left + 190, y, 0xFFFFFF, true);
|
||||||
|
|
||||||
|
mirrorButtonList.forEach(button -> button.drawButton(this.mc, mouseX, mouseY, partialTicks));
|
||||||
|
mirrorTextFieldList.forEach(textField -> textField.drawTextBox());
|
||||||
|
} else {
|
||||||
|
fontRenderer.drawString("Mirror disabled", left + offset, y, 0x999999, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
y = top + 100 + 2;
|
||||||
|
buttonArrayEnabled.drawButton(this.mc, mouseX, mouseY, partialTicks);
|
||||||
|
if (buttonArrayEnabled.isChecked()) {
|
||||||
|
fontRenderer.drawString("Array enabled", left + offset, y, 0xFFFFFF, true);
|
||||||
|
|
||||||
|
y = top + 120 + 5;
|
||||||
|
fontRenderer.drawString("Offset", left + offset, y, 0xFFFFFF, true);
|
||||||
|
fontRenderer.drawString("X", left + 50 + offset, y, 0xFFFFFF, true);
|
||||||
|
fontRenderer.drawString("Y", left + 120 + offset, y, 0xFFFFFF, true);
|
||||||
|
fontRenderer.drawString("Z", left + 190 + offset, y, 0xFFFFFF, true);
|
||||||
|
|
||||||
|
y = top + 150 + 5;
|
||||||
|
fontRenderer.drawString("Count", left + offset, y, 0xFFFFFF, true);
|
||||||
|
|
||||||
|
arrayTextFieldList.forEach(textField -> textField.drawTextBox());
|
||||||
|
} else {
|
||||||
|
fontRenderer.drawString("Array disabled", left + offset, y, 0x999999, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonClose.drawButton(this.mc, mouseX, mouseY, partialTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void keyTyped(char typedChar, int keyCode) throws IOException {
|
||||||
|
super.keyTyped(typedChar, keyCode);
|
||||||
|
if (Character.isDigit(typedChar) || typedChar == '.' || typedChar == '-' || keyCode == Keyboard.KEY_BACK || keyCode == Keyboard.KEY_DELETE) {
|
||||||
|
for (GuiTextField textField : textFieldList) {
|
||||||
|
if (textField.isFocused()) {
|
||||||
|
textField.textboxKeyTyped(typedChar, keyCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (keyCode == ClientProxy.keyBindings[0].getKeyCode()) {
|
||||||
|
Minecraft.getMinecraft().player.closeScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
|
||||||
|
super.mouseClicked(mouseX, mouseY, mouseButton);
|
||||||
|
textFieldList.forEach(textField -> textField.mouseClicked(mouseX, mouseY, mouseButton));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void actionPerformed(GuiButton button) throws IOException {
|
||||||
|
//check what button and action type (left/right click)
|
||||||
|
if (button == buttonClose) {
|
||||||
|
mc.player.closeScreen();
|
||||||
|
}
|
||||||
|
if (button == buttonCurrentPosition) {
|
||||||
|
Vec3d pos = new Vec3d(Math.floor(mc.player.posX) + 0.5, Math.floor(mc.player.posY) + 0.5, Math.floor(mc.player.posZ) + 0.5);
|
||||||
|
textMirrorPosX.setText(String.valueOf(pos.x));
|
||||||
|
textMirrorPosY.setText(String.valueOf(pos.y));
|
||||||
|
textMirrorPosZ.setText(String.valueOf(pos.z));
|
||||||
|
}
|
||||||
|
if (button == buttonDrawLines) {
|
||||||
|
drawLines = !drawLines;
|
||||||
|
buttonDrawLines.displayString = drawLines ? "Hide lines" : "Show lines";
|
||||||
|
}
|
||||||
|
if (button == buttonDrawPlanes) {
|
||||||
|
drawPlanes = !drawPlanes;
|
||||||
|
buttonDrawPlanes.displayString = drawPlanes ? "Hide area" : "Show area";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGuiClosed() {
|
||||||
|
//save everything
|
||||||
|
|
||||||
|
//MIRROR
|
||||||
|
boolean mirrorEnabled = buttonMirrorEnabled.isChecked();
|
||||||
|
|
||||||
|
Vec3d mirrorPos = new Vec3d(0.5, 64.5, 0.5);
|
||||||
|
try {
|
||||||
|
mirrorPos = new Vec3d(Double.parseDouble(textMirrorPosX.getText()), Double.parseDouble(textMirrorPosY.getText()), Double.parseDouble(textMirrorPosZ.getText()));
|
||||||
|
} catch (NumberFormatException | NullPointerException ex) {
|
||||||
|
EffortlessBuilding.log(Minecraft.getMinecraft().player, "Mirror position not valid.", true);
|
||||||
|
EffortlessBuilding.log("Mirror position not valid. Resetting to default.");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean mirrorX = buttonMirrorX.isChecked();
|
||||||
|
boolean mirrorY = buttonMirrorY.isChecked();
|
||||||
|
boolean mirrorZ = buttonMirrorZ.isChecked();
|
||||||
|
|
||||||
|
int mirrorRadius = 50;
|
||||||
|
try {
|
||||||
|
mirrorRadius = Math.min(Integer.parseInt(textMirrorRadius.getText()), Mirror.MAX_RADIUS);
|
||||||
|
} catch (NumberFormatException | NullPointerException ex) {
|
||||||
|
EffortlessBuilding.log(Minecraft.getMinecraft().player, "Mirror radius not valid.", true);
|
||||||
|
EffortlessBuilding.log("Mirror radius not valid. Resetting to default.");
|
||||||
|
}
|
||||||
|
mirrorRadius = Math.max(1, mirrorRadius);
|
||||||
|
mirrorRadius = Math.min(Mirror.MAX_RADIUS, mirrorRadius);
|
||||||
|
|
||||||
|
Mirror.MirrorSettings m = new Mirror.MirrorSettings(mirrorEnabled, mirrorPos, mirrorX, mirrorY, mirrorZ, mirrorRadius, drawLines, drawPlanes);
|
||||||
|
|
||||||
|
//ARRAY
|
||||||
|
boolean arrayEnabled = buttonArrayEnabled.isChecked();
|
||||||
|
BlockPos arrayOffset = new BlockPos(0, 0, 0);
|
||||||
|
try {
|
||||||
|
arrayOffset = new BlockPos(Integer.parseInt(textArrayOffsetX.getText()), Integer.parseInt(textArrayOffsetY.getText()), Integer.parseInt(textArrayOffsetZ.getText()));
|
||||||
|
} catch (NumberFormatException | NullPointerException ex) {
|
||||||
|
EffortlessBuilding.log(Minecraft.getMinecraft().player, "Array offset not valid.", true);
|
||||||
|
EffortlessBuilding.log("Array offset not valid. Resetting to default.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int arrayCount = 5;
|
||||||
|
try {
|
||||||
|
arrayCount = Integer.parseInt(textArrayCount.getText());
|
||||||
|
} catch (NumberFormatException | NullPointerException ex) {
|
||||||
|
EffortlessBuilding.log(Minecraft.getMinecraft().player, "Array count not valid.", true);
|
||||||
|
EffortlessBuilding.log("Array count not valid. Resetting to default.");
|
||||||
|
}
|
||||||
|
arrayCount = Math.max(1, arrayCount);
|
||||||
|
arrayCount = Math.min(Array.MAX_COUNT, arrayCount);
|
||||||
|
|
||||||
|
Array.ArraySettings a = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount);
|
||||||
|
|
||||||
|
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(mc.player);
|
||||||
|
if (buildSettings == null) buildSettings = new BuildSettingsManager.BuildSettings();
|
||||||
|
buildSettings.setMirrorSettings(m);
|
||||||
|
buildSettings.setArraySettings(a);
|
||||||
|
BuildSettingsManager.setBuildSettings(mc.player, buildSettings);
|
||||||
|
|
||||||
|
//Send to server
|
||||||
|
EffortlessBuilding.packetHandler.sendToServer(new BuildSettingsMessage(buildSettings));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package nl.requios.effortlessbuilding.inventory;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.inventory.Container;
|
||||||
|
|
||||||
|
public class RandomizerBagContainer extends Container {
|
||||||
|
@Override
|
||||||
|
public boolean canInteractWith(EntityPlayer playerIn) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package nl.requios.effortlessbuilding.inventory;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||||
|
import net.minecraft.inventory.Container;
|
||||||
|
|
||||||
|
public class RandomizerBagGuiContainer extends GuiContainer {
|
||||||
|
public RandomizerBagGuiContainer(Container inventorySlotsIn) {
|
||||||
|
super(inventorySlotsIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
package nl.requios.effortlessbuilding.inventory;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.nbt.NBTTagList;
|
||||||
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public class RandomizerBagInventory implements IItemHandler {
|
||||||
|
|
||||||
|
//Reference to NBT data
|
||||||
|
private final ItemStack invItem;
|
||||||
|
|
||||||
|
public static final int INV_SIZE = 5;
|
||||||
|
|
||||||
|
private ItemStack[] inventory = new ItemStack[INV_SIZE];
|
||||||
|
|
||||||
|
public RandomizerBagInventory(ItemStack invItem) {
|
||||||
|
this.invItem = invItem;
|
||||||
|
|
||||||
|
if (!invItem.hasTagCompound()) {
|
||||||
|
invItem.setTagCompound(new NBTTagCompound());
|
||||||
|
}
|
||||||
|
|
||||||
|
readFromNBT(invItem.getTagCompound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSlots() {
|
||||||
|
return INV_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public ItemStack getStackInSlot(int slot) {
|
||||||
|
return inventory[slot];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
|
||||||
|
ItemStack slotStack = getStackInSlot(slot);
|
||||||
|
if (slotStack.getCount() == 0) {
|
||||||
|
setInventorySlotContents(slot, stack);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (getSlotLimit(slot) - slotStack.getCount() < stack.getCount()) {
|
||||||
|
//Not enough place remaining, split stack
|
||||||
|
slotStack.setCount(getSlotLimit(slot));
|
||||||
|
onInventoryChanged();
|
||||||
|
stack.copy().shrink(getSlotLimit(slot) - slotStack.getCount());
|
||||||
|
//TODO make proper
|
||||||
|
return stack;
|
||||||
|
} else {
|
||||||
|
slotStack.grow(stack.getCount());
|
||||||
|
onInventoryChanged();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||||
|
ItemStack stack = getStackInSlot(slot);
|
||||||
|
if (stack == null) return stack;
|
||||||
|
|
||||||
|
if (stack.getCount() > amount) {
|
||||||
|
stack = stack.splitStack(amount);
|
||||||
|
onInventoryChanged();
|
||||||
|
} else {
|
||||||
|
setInventorySlotContents(slot, null);
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSlotLimit(int slot) {
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onInventoryChanged() {
|
||||||
|
for (int i = 0; i < getSlotLimit(0); ++i) {
|
||||||
|
if (getStackInSlot(i) != null && getStackInSlot(i).getCount() == 0) {
|
||||||
|
inventory[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeToNBT(invItem.getTagCompound());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInventorySlotContents(int slot, ItemStack stack) {
|
||||||
|
inventory[slot] = stack;
|
||||||
|
|
||||||
|
if (stack != null && stack.getCount() > getSlotLimit(slot)) {
|
||||||
|
stack.setCount(getSlotLimit(slot));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't forget this line or your inventory will not be saved!
|
||||||
|
onInventoryChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readFromNBT(NBTTagCompound compound) {
|
||||||
|
// Gets the custom taglist we wrote to this compound, if any
|
||||||
|
// 1.7.2+ change to compound.getTagList("ItemInventory", Constants.NBT.TAG_COMPOUND);
|
||||||
|
NBTTagList items = compound.getTagList("ItemInventory", 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < items.tagCount(); ++i) {
|
||||||
|
// 1.7.2+ change to items.getCompoundTagAt(i)
|
||||||
|
NBTTagCompound item = items.getCompoundTagAt(i);
|
||||||
|
int slot = item.getInteger("Slot");
|
||||||
|
|
||||||
|
// Just double-checking that the saved slot index is within our inventory array bounds
|
||||||
|
if (slot >= 0 && slot < getSlots()) {
|
||||||
|
inventory[slot] = new ItemStack(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom method to write our inventory to an ItemStack's NBT compound
|
||||||
|
*/
|
||||||
|
public void writeToNBT(NBTTagCompound tagcompound) {
|
||||||
|
// Create a new NBT Tag List to store itemstacks as NBT Tags
|
||||||
|
NBTTagList items = new NBTTagList();
|
||||||
|
|
||||||
|
for (int i = 0; i < getSlots(); ++i) {
|
||||||
|
// Only write stacks that contain items
|
||||||
|
if (getStackInSlot(i) != null) {
|
||||||
|
// Make a new NBT Tag Compound to write the itemstack and slot index to
|
||||||
|
NBTTagCompound item = new NBTTagCompound();
|
||||||
|
item.setInteger("Slot", i);
|
||||||
|
// Writes the itemstack in slot(i) to the Tag Compound we just made
|
||||||
|
getStackInSlot(i).writeToNBT(item);
|
||||||
|
|
||||||
|
// add the tag compound to our tag list
|
||||||
|
items.appendTag(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add the TagList to the ItemStack's Tag Compound with the name "ItemInventory"
|
||||||
|
tagcompound.setTag("ItemInventory", items);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package nl.requios.effortlessbuilding.inventory;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.fml.common.network.IGuiHandler;
|
||||||
|
import nl.requios.effortlessbuilding.EffortlessBuilding;
|
||||||
|
import nl.requios.effortlessbuilding.inventory.RandomizerBagContainer;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class RandomizerGuiHandler implements IGuiHandler {
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
|
||||||
|
if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) {
|
||||||
|
// Use the player's held item to create the inventory
|
||||||
|
return new RandomizerBagContainer();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
|
||||||
|
if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) {
|
||||||
|
// We have to cast the new container as our custom class
|
||||||
|
// and pass in currently held item for the inventory
|
||||||
|
return new RandomizerBagGuiContainer(new RandomizerBagContainer());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package nl.requios.effortlessbuilding.item;
|
||||||
|
|
||||||
|
import net.minecraft.creativetab.CreativeTabs;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.EnumActionResult;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.EnumHand;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import nl.requios.effortlessbuilding.EffortlessBuilding;
|
||||||
|
|
||||||
|
public class ItemRandomizerBag extends Item {
|
||||||
|
|
||||||
|
public ItemRandomizerBag(){
|
||||||
|
this.setRegistryName(EffortlessBuilding.MODID, "randomizer_bag");
|
||||||
|
this.setUnlocalizedName(this.getRegistryName().toString());
|
||||||
|
|
||||||
|
this.maxStackSize = 1;
|
||||||
|
this.setCreativeTab(CreativeTabs.DECORATIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumActionResult onItemUse(EntityPlayer player, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
|
||||||
|
|
||||||
|
if (worldIn.isRemote) return EnumActionResult.PASS;
|
||||||
|
EffortlessBuilding.log(player, "onItemUse");
|
||||||
|
|
||||||
|
if (player.isSneaking()){
|
||||||
|
//Open inventory
|
||||||
|
player.openGui(EffortlessBuilding.instance, EffortlessBuilding.RANDOMIZER_BAG_GUI, worldIn, 0, 0, 0);
|
||||||
|
} else {
|
||||||
|
//Place block
|
||||||
|
|
||||||
|
}
|
||||||
|
return EnumActionResult.PASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) {
|
||||||
|
if (worldIn.isRemote) return new ActionResult<>(EnumActionResult.PASS, playerIn.getHeldItem(handIn));
|
||||||
|
EffortlessBuilding.log(playerIn, "onItemRightClick");
|
||||||
|
|
||||||
|
//Open inventory
|
||||||
|
playerIn.openGui(EffortlessBuilding.instance, EffortlessBuilding.RANDOMIZER_BAG_GUI, worldIn, 0, 0, 0);
|
||||||
|
|
||||||
|
return new ActionResult<>(EnumActionResult.PASS, playerIn.getHeldItem(handIn));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxItemUseDuration(ItemStack stack) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
package nl.requios.effortlessbuilding.network;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
|
import net.minecraft.util.IThreadListener;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||||
|
import nl.requios.effortlessbuilding.Array;
|
||||||
|
import nl.requios.effortlessbuilding.BuildSettingsManager;
|
||||||
|
import nl.requios.effortlessbuilding.BuildSettingsManager.BuildSettings;
|
||||||
|
import nl.requios.effortlessbuilding.Mirror;
|
||||||
|
|
||||||
|
public class BuildSettingsMessage implements IMessage {
|
||||||
|
|
||||||
|
private BuildSettings buildSettings;
|
||||||
|
|
||||||
|
public BuildSettingsMessage() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public BuildSettingsMessage(BuildSettings buildSettings) {
|
||||||
|
this.buildSettings = buildSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toBytes(ByteBuf buf) {
|
||||||
|
//MIRROR
|
||||||
|
Mirror.MirrorSettings m = buildSettings.getMirrorSettings();
|
||||||
|
buf.writeBoolean(m.enabled);
|
||||||
|
buf.writeDouble(m.position.x);
|
||||||
|
buf.writeDouble(m.position.y);
|
||||||
|
buf.writeDouble(m.position.z);
|
||||||
|
buf.writeBoolean(m.mirrorX);
|
||||||
|
buf.writeBoolean(m.mirrorY);
|
||||||
|
buf.writeBoolean(m.mirrorZ);
|
||||||
|
buf.writeInt(m.radius);
|
||||||
|
buf.writeBoolean(m.drawLines);
|
||||||
|
buf.writeBoolean(m.drawPlanes);
|
||||||
|
|
||||||
|
//ARRAY
|
||||||
|
Array.ArraySettings a = buildSettings.getArraySettings();
|
||||||
|
buf.writeBoolean(a.enabled);
|
||||||
|
buf.writeInt(a.offset.getX());
|
||||||
|
buf.writeInt(a.offset.getY());
|
||||||
|
buf.writeInt(a.offset.getZ());
|
||||||
|
buf.writeInt(a.count);
|
||||||
|
|
||||||
|
buf.writeBoolean(buildSettings.doQuickReplace());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fromBytes(ByteBuf buf) {
|
||||||
|
//MIRROR
|
||||||
|
boolean mirrorEnabled = buf.readBoolean();
|
||||||
|
Vec3d mirrorPosition = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
|
||||||
|
boolean mirrorX = buf.readBoolean();
|
||||||
|
boolean mirrorY = buf.readBoolean();
|
||||||
|
boolean mirrorZ = buf.readBoolean();
|
||||||
|
int mirrorRadius = buf.readInt();
|
||||||
|
boolean mirrorDrawLines = buf.readBoolean();
|
||||||
|
boolean mirrorDrawPlanes = buf.readBoolean();
|
||||||
|
Mirror.MirrorSettings m = new Mirror.MirrorSettings(mirrorEnabled, mirrorPosition, mirrorX, mirrorY, mirrorZ, mirrorRadius, mirrorDrawLines, mirrorDrawPlanes);
|
||||||
|
|
||||||
|
//ARRAY
|
||||||
|
boolean arrayEnabled = buf.readBoolean();
|
||||||
|
BlockPos arrayOffset = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
|
||||||
|
int arrayCount = buf.readInt();
|
||||||
|
Array.ArraySettings a = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount);
|
||||||
|
|
||||||
|
boolean quickReplace = buf.readBoolean();
|
||||||
|
buildSettings = new BuildSettings(m, a, quickReplace);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The params of the IMessageHandler are <REQ, REPLY>
|
||||||
|
public static class MessageHandler implements IMessageHandler<BuildSettingsMessage, IMessage> {
|
||||||
|
// Do note that the default constructor is required, but implicitly defined in this case
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IMessage onMessage(BuildSettingsMessage message, MessageContext ctx) {
|
||||||
|
//EffortlessBuilding.log("message received on " + ctx.side + " side");
|
||||||
|
|
||||||
|
// This is the player the packet was sent to the server from
|
||||||
|
EntityPlayer player = (ctx.side.isClient() ? Minecraft.getMinecraft().player : ctx.getServerHandler().player);
|
||||||
|
// The value that was sent
|
||||||
|
BuildSettings buildSettings = message.buildSettings;
|
||||||
|
Mirror.MirrorSettings m = buildSettings.getMirrorSettings();
|
||||||
|
Array.ArraySettings a = buildSettings.getArraySettings();
|
||||||
|
|
||||||
|
// Sanitize
|
||||||
|
m.radius = Math.min(m.radius, Mirror.MAX_RADIUS);
|
||||||
|
m.radius = Math.max(1, m.radius);
|
||||||
|
|
||||||
|
a.count = Math.min(a.count, Array.MAX_COUNT);
|
||||||
|
a.count = Math.max(0, a.count);
|
||||||
|
|
||||||
|
// Execute the action on the main server thread by adding it as a scheduled task
|
||||||
|
IThreadListener threadListener = (ctx.side.isClient() ? Minecraft.getMinecraft() : ((EntityPlayerMP) player).getServerWorld());
|
||||||
|
threadListener.addScheduledTask(() -> {
|
||||||
|
EntityPlayer p = (ctx.side.isClient() ? Minecraft.getMinecraft().player : ctx.getServerHandler().player);
|
||||||
|
BuildSettingsManager.setBuildSettings(p, buildSettings);
|
||||||
|
});
|
||||||
|
// No response packet
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package nl.requios.effortlessbuilding.network;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||||
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
import nl.requios.effortlessbuilding.QuickReplace;
|
||||||
|
import nl.requios.effortlessbuilding.proxy.ClientProxy;
|
||||||
|
|
||||||
|
public class QuickReplaceMessage implements IMessage {
|
||||||
|
|
||||||
|
private boolean blockHit;
|
||||||
|
private BlockPos blockPos;
|
||||||
|
private EnumFacing sideHit;
|
||||||
|
|
||||||
|
public QuickReplaceMessage() {
|
||||||
|
this.blockHit = false;
|
||||||
|
this.blockPos = BlockPos.ORIGIN;
|
||||||
|
this.sideHit = EnumFacing.UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QuickReplaceMessage(RayTraceResult result) {
|
||||||
|
this.blockHit = result.typeOfHit == RayTraceResult.Type.BLOCK;
|
||||||
|
this.blockPos = result.getBlockPos();
|
||||||
|
this.sideHit = result.sideHit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBlockHit() {
|
||||||
|
return blockHit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockPos getBlockPos() {
|
||||||
|
return blockPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnumFacing getSideHit() {
|
||||||
|
return sideHit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toBytes(ByteBuf buf) {
|
||||||
|
buf.writeBoolean(blockHit);
|
||||||
|
buf.writeInt(blockPos.getX());
|
||||||
|
buf.writeInt(blockPos.getY());
|
||||||
|
buf.writeInt(blockPos.getZ());
|
||||||
|
buf.writeInt(sideHit.getIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fromBytes(ByteBuf buf) {
|
||||||
|
blockHit = buf.readBoolean();
|
||||||
|
blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
|
||||||
|
sideHit = EnumFacing.getFront(buf.readInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
// The params of the IMessageHandler are <REQ, REPLY>
|
||||||
|
public static class MessageHandler implements IMessageHandler<QuickReplaceMessage, IMessage> {
|
||||||
|
// Do note that the default constructor is required, but implicitly defined in this case
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IMessage onMessage(QuickReplaceMessage message, MessageContext ctx) {
|
||||||
|
//EffortlessBuilding.log("message received on " + ctx.side + " side");
|
||||||
|
|
||||||
|
if (ctx.side == Side.CLIENT){
|
||||||
|
//Received clientside
|
||||||
|
//Send back your info
|
||||||
|
return new QuickReplaceMessage(ClientProxy.previousLookAt);
|
||||||
|
|
||||||
|
//TODO break block then return
|
||||||
|
// Minecraft.getMinecraft().addScheduledTask(() -> {
|
||||||
|
// EffortlessBuilding.packetHandler.sendToServer(new QuickReplaceMessage(Minecraft.getMinecraft().objectMouseOver));
|
||||||
|
// });
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//Received serverside
|
||||||
|
ctx.getServerHandler().player.getServerWorld().addScheduledTask(() -> {
|
||||||
|
QuickReplace.onMessageReceived(ctx.getServerHandler().player, message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// No response packet
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
package nl.requios.effortlessbuilding.proxy;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
|
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||||
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
import net.minecraft.util.text.TextFormatting;
|
||||||
|
import net.minecraftforge.client.event.ModelRegistryEvent;
|
||||||
|
import net.minecraftforge.client.model.ModelLoader;
|
||||||
|
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.event.*;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.EventPriority;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.gameevent.InputEvent;
|
||||||
|
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||||
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
import nl.requios.effortlessbuilding.BuildSettingsManager;
|
||||||
|
import nl.requios.effortlessbuilding.EffortlessBuilding;
|
||||||
|
import nl.requios.effortlessbuilding.gui.SettingsGui;
|
||||||
|
import nl.requios.effortlessbuilding.network.BuildSettingsMessage;
|
||||||
|
import org.lwjgl.input.Keyboard;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||||
|
public class ClientProxy implements IProxy {
|
||||||
|
public static KeyBinding[] keyBindings;
|
||||||
|
public static RayTraceResult previousLookAt;
|
||||||
|
public static RayTraceResult currentLookAt;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preInit(FMLPreInitializationEvent event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FMLInitializationEvent event) {
|
||||||
|
// register key bindings
|
||||||
|
keyBindings = new KeyBinding[2];
|
||||||
|
|
||||||
|
// instantiate the key bindings
|
||||||
|
keyBindings[0] = new KeyBinding("key.hud.desc", Keyboard.KEY_NUMPAD0, "key.effortlessbuilding.category");
|
||||||
|
keyBindings[1] = new KeyBinding("key.replace.desc", Keyboard.KEY_NUMPAD1, "key.effortlessbuilding.category");
|
||||||
|
|
||||||
|
// register all the key bindings
|
||||||
|
for (int i = 0; i < keyBindings.length; ++i) {
|
||||||
|
ClientRegistry.registerKeyBinding(keyBindings[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postInit(FMLPostInitializationEvent event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityPlayer getPlayerEntityFromContext(MessageContext ctx) {
|
||||||
|
return (ctx.side.isClient() ? Minecraft.getMinecraft().player : EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serverStarting(FMLServerStartingEvent event) {
|
||||||
|
// This will never get called on client side
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void registerModels(ModelRegistryEvent event) {
|
||||||
|
for (Block block : EffortlessBuilding.BLOCKS) {
|
||||||
|
ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation(block.getRegistryName(), "inventory"));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Item item : EffortlessBuilding.ITEMS) {
|
||||||
|
ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(item.getRegistryName(), "inventory"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent(priority = EventPriority.NORMAL, receiveCanceled = true)
|
||||||
|
public static void onKeyPress(InputEvent.KeyInputEvent event) {
|
||||||
|
// check each enumerated key binding type for pressed and take appropriate action
|
||||||
|
EntityPlayerSP player = Minecraft.getMinecraft().player;
|
||||||
|
if (keyBindings[0].isPressed()) {
|
||||||
|
// do stuff for this key binding here
|
||||||
|
// remember you may need to send packet to server
|
||||||
|
if (Minecraft.getMinecraft().currentScreen == null) {
|
||||||
|
Minecraft.getMinecraft().displayGuiScreen(new SettingsGui());
|
||||||
|
} else {
|
||||||
|
player.closeScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (keyBindings[1].isPressed()) {
|
||||||
|
// do stuff for this key binding here
|
||||||
|
// remember you may need to send packet to server
|
||||||
|
BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(player);
|
||||||
|
buildSettings.setQuickReplace(!buildSettings.doQuickReplace());
|
||||||
|
EffortlessBuilding.log(player, "Set "+ TextFormatting.GOLD + "Quick Replace " + TextFormatting.RESET + (buildSettings.doQuickReplace() ? "on" : "off"));
|
||||||
|
EffortlessBuilding.packetHandler.sendToServer(new BuildSettingsMessage(buildSettings));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onClientTick(TickEvent.ClientTickEvent event) {
|
||||||
|
if (event.phase != TickEvent.Phase.START) return;
|
||||||
|
|
||||||
|
RayTraceResult objectMouseOver = Minecraft.getMinecraft().objectMouseOver;
|
||||||
|
if (objectMouseOver == null) return;
|
||||||
|
|
||||||
|
if (currentLookAt == null) {
|
||||||
|
currentLookAt = objectMouseOver;
|
||||||
|
previousLookAt = objectMouseOver;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||||
|
if (currentLookAt.typeOfHit != RayTraceResult.Type.BLOCK) {
|
||||||
|
currentLookAt = objectMouseOver;
|
||||||
|
previousLookAt = objectMouseOver;
|
||||||
|
} else {
|
||||||
|
if (currentLookAt.getBlockPos() != objectMouseOver.getBlockPos()){
|
||||||
|
previousLookAt = currentLookAt;
|
||||||
|
currentLookAt = objectMouseOver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package nl.requios.effortlessbuilding.proxy;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||||
|
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
||||||
|
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||||
|
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||||
|
|
||||||
|
public interface IProxy
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Register entities and networking.
|
||||||
|
*/
|
||||||
|
void preInit(FMLPreInitializationEvent event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register event listeners, recipes and advancements.
|
||||||
|
*/
|
||||||
|
void init(FMLInitializationEvent event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For doing inter-mod stuff like checking which mods are loaded or if you want a complete view of things across
|
||||||
|
* mods like having a list of all registered items to aid random item generation.
|
||||||
|
*/
|
||||||
|
void postInit(FMLPostInitializationEvent event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server commands should be registered here.
|
||||||
|
*/
|
||||||
|
void serverStarting(FMLServerStartingEvent event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a side-appropriate EntityPlayer for use during message handling.
|
||||||
|
*
|
||||||
|
* @param parContext the context
|
||||||
|
* @return the player entity from context
|
||||||
|
*/
|
||||||
|
EntityPlayer getPlayerEntityFromContext(MessageContext parContext);
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package nl.requios.effortlessbuilding.proxy;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||||
|
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
||||||
|
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||||
|
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
|
||||||
|
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||||
|
|
||||||
|
public class ServerProxy implements IProxy
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void preInit(FMLPreInitializationEvent event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FMLInitializationEvent event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postInit(FMLPostInitializationEvent event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serverStarting(FMLServerStartingEvent event)
|
||||||
|
{
|
||||||
|
//event.registerServerCommand(new CommandStructureCapture());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityPlayer getPlayerEntityFromContext(MessageContext ctx)
|
||||||
|
{
|
||||||
|
return ctx.getServerHandler().player;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
key.effortlessbuilding.category=Effortless Building
|
||||||
|
key.hud.desc=Open Settings
|
||||||
|
key.replace.desc=Switch Replace Mode
|
||||||
|
|
||||||
|
item.effortlessbuilding:randomizer_bag.name=Randomizer Bag
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "items/fireball"
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/main/resources/mcmod.info
Normal file
16
src/main/resources/mcmod.info
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"modid": "effortlessbuilding",
|
||||||
|
"name": "Effortless Building",
|
||||||
|
"description": "Makes building easier by providing tools like mirrors, arrays, quickreplace and a block randomizer.",
|
||||||
|
"version": "${version}",
|
||||||
|
"mcversion": "${mcversion}",
|
||||||
|
"url": "https://requios.nl/",
|
||||||
|
"updateUrl": "",
|
||||||
|
"authorList": ["Requios"],
|
||||||
|
"credits": "",
|
||||||
|
"logoFile": "",
|
||||||
|
"screenshots": [],
|
||||||
|
"dependencies": []
|
||||||
|
}
|
||||||
|
]
|
||||||
7
src/main/resources/pack.mcmeta
Normal file
7
src/main/resources/pack.mcmeta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"pack": {
|
||||||
|
"description": "examplemod resources",
|
||||||
|
"pack_format": 3,
|
||||||
|
"_comment": "A pack_format of 3 should be used starting with Minecraft 1.11. All resources, including language files, should be lowercase (eg: en_us.lang). A pack_format of 2 will load your mod resources with LegacyV2Adapter, which requires language files to have uppercase letters (eg: en_US.lang)."
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user