+ Added base files
This commit is contained in:
commit
2d29747888
23
.gitignore
vendored
Normal file
23
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# eclipse
|
||||
bin
|
||||
*.launch
|
||||
.settings
|
||||
.metadata
|
||||
.classpath
|
||||
.project
|
||||
|
||||
# idea
|
||||
out
|
||||
*.ipr
|
||||
*.iws
|
||||
*.iml
|
||||
.idea
|
||||
|
||||
# gradle
|
||||
build
|
||||
.gradle
|
||||
|
||||
# other
|
||||
eclipse
|
||||
run
|
||||
/_OLD
|
||||
56
build.gradle
Normal file
56
build.gradle
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
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 = "1.12.2-1.0"
|
||||
group = "net.montoyo.wd" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
archivesBaseName = "webdisplays"
|
||||
|
||||
sourceCompatibility = targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
|
||||
compileJava {
|
||||
sourceCompatibility = targetCompatibility = '1.8'
|
||||
}
|
||||
|
||||
minecraft {
|
||||
version = "1.12.2-14.23.1.2555"
|
||||
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 {
|
||||
}
|
||||
|
||||
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'
|
||||
}
|
||||
}
|
||||
3
gradle.properties
Normal file
3
gradle.properties
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
|
||||
# This is required to provide enough memory for the Minecraft decompilation process.
|
||||
org.gradle.jvmargs=-Xmx3G
|
||||
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
|
||||
BIN
libs/mcef-1.12.2-0.9-api.jar
Normal file
BIN
libs/mcef-1.12.2-0.9-api.jar
Normal file
Binary file not shown.
68
src/main/java/net/montoyo/wd/SharedProxy.java
Normal file
68
src/main/java/net/montoyo/wd/SharedProxy.java
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import net.minecraftforge.fml.server.FMLServerHandler;
|
||||
import net.montoyo.mcef.utilities.Log;
|
||||
import net.montoyo.wd.data.GuiData;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.NameUUIDPair;
|
||||
import net.montoyo.wd.utilities.Vector2i;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
|
||||
public class SharedProxy {
|
||||
|
||||
public static final int CURRENT_DIMENSION = Integer.MAX_VALUE;
|
||||
|
||||
public void preInit() {
|
||||
}
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
public void postInit() {
|
||||
}
|
||||
|
||||
public World getWorld(int dim) {
|
||||
if(dim == CURRENT_DIMENSION)
|
||||
throw new RuntimeException("Current dimension not available server side...");
|
||||
|
||||
return DimensionManager.getWorld(dim);
|
||||
}
|
||||
|
||||
public void enqueue(Runnable r) {
|
||||
FMLServerHandler.instance().getServer().addScheduledTask(r);
|
||||
}
|
||||
|
||||
public void displayGui(GuiData data) {
|
||||
Log.error("Called SharedProxy.displayGui() on server side...");
|
||||
}
|
||||
|
||||
public void trackScreen(TileEntityScreen tes, boolean track) {
|
||||
}
|
||||
|
||||
public void onAutocompleteResult(NameUUIDPair pairs[]) {
|
||||
}
|
||||
|
||||
public GameProfile[] getOnlineGameProfiles() {
|
||||
return FMLServerHandler.instance().getServer().getOnlinePlayerProfiles();
|
||||
}
|
||||
|
||||
public void screenUpdateResolutionInGui(Vector3i pos, BlockSide side, Vector2i res) {
|
||||
}
|
||||
|
||||
public void displaySetPadURLGui(String padURL) {
|
||||
Log.error("Called SharedProxy.displaySetPadURLGui() on server side...");
|
||||
}
|
||||
|
||||
public void openMinePadGui(int padId) {
|
||||
Log.error("Called SharedProxy.openMinePadGui() on server side...");
|
||||
}
|
||||
|
||||
}
|
||||
193
src/main/java/net/montoyo/wd/WebDisplays.java
Normal file
193
src/main/java/net/montoyo/wd/WebDisplays.java
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
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.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.montoyo.wd.block.BlockKeyboardRight;
|
||||
import net.montoyo.wd.block.BlockPeripheral;
|
||||
import net.montoyo.wd.block.BlockScreen;
|
||||
import net.montoyo.wd.core.DefaultPeripheral;
|
||||
import net.montoyo.wd.core.WDCreativeTab;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.item.ItemLinker;
|
||||
import net.montoyo.wd.item.ItemMinePad2;
|
||||
import net.montoyo.wd.item.ItemOwnershipThief;
|
||||
import net.montoyo.wd.item.ItemScreenConfigurator;
|
||||
import net.montoyo.wd.net.Messages;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
import net.montoyo.wd.utilities.Util;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
@Mod(modid = "webdisplays", version = WebDisplays.MOD_VERSION, dependencies = "required-after:mcef;")
|
||||
public class WebDisplays {
|
||||
|
||||
public static final String MOD_VERSION = "1.0";
|
||||
|
||||
@Mod.Instance(owner = "webdisplays")
|
||||
public static WebDisplays INSTANCE;
|
||||
|
||||
@SidedProxy(serverSide = "net.montoyo.wd.SharedProxy", clientSide = "net.montoyo.wd.client.ClientProxy")
|
||||
public static SharedProxy PROXY;
|
||||
|
||||
public static SimpleNetworkWrapper NET_HANDLER;
|
||||
public static WDCreativeTab CREATIVE_TAB;
|
||||
|
||||
//Blocks
|
||||
public BlockScreen blockScreen;
|
||||
public BlockPeripheral blockPeripheral;
|
||||
public BlockKeyboardRight blockKbRight;
|
||||
|
||||
//Items
|
||||
public ItemScreenConfigurator itemScreenCfg;
|
||||
public ItemOwnershipThief itemOwnerThief;
|
||||
public ItemLinker itemLinker;
|
||||
public Item itemStoneKey;
|
||||
public ItemMinePad2 itemMinePad;
|
||||
|
||||
//Sounds
|
||||
public SoundEvent soundTyping;
|
||||
|
||||
//Config
|
||||
public static final double PAD_RATIO = 59.0 / 30.0;
|
||||
public String homePage = "https://google.com"; //TODO: Read from config
|
||||
public double padResX;
|
||||
public double padResY;
|
||||
private int lastPadId = 0;
|
||||
|
||||
@Mod.EventHandler
|
||||
public void onPreInit(FMLPreInitializationEvent ev) {
|
||||
CREATIVE_TAB = new WDCreativeTab();
|
||||
|
||||
//TODO: Read configuration
|
||||
final int padHeight = 480;
|
||||
padResY = (double) padHeight;
|
||||
padResX = padResY * PAD_RATIO;
|
||||
|
||||
//Init blocks
|
||||
blockScreen = new BlockScreen();
|
||||
blockScreen.makeItemBlock();
|
||||
|
||||
blockPeripheral = new BlockPeripheral();
|
||||
blockPeripheral.makeItemBlock();
|
||||
|
||||
blockKbRight = new BlockKeyboardRight();
|
||||
|
||||
//Init items
|
||||
itemScreenCfg = new ItemScreenConfigurator();
|
||||
itemOwnerThief = new ItemOwnershipThief();
|
||||
itemLinker = new ItemLinker();
|
||||
itemMinePad = new ItemMinePad2();
|
||||
|
||||
itemStoneKey = new Item();
|
||||
itemStoneKey.setCreativeTab(CREATIVE_TAB);
|
||||
itemStoneKey.setUnlocalizedName("webdisplays.stonekey");
|
||||
itemStoneKey.setRegistryName("stonekey");
|
||||
|
||||
PROXY.preInit();
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
}
|
||||
|
||||
@Mod.EventHandler
|
||||
public void onInit(FMLInitializationEvent ev) {
|
||||
//Register tile entities
|
||||
GameRegistry.registerTileEntity(TileEntityScreen.class, "webdisplays:screen");
|
||||
for(DefaultPeripheral dp: DefaultPeripheral.values()) {
|
||||
if(dp.getTEClass() != null)
|
||||
GameRegistry.registerTileEntity(dp.getTEClass(), "webdisplays:" + dp.getName());
|
||||
}
|
||||
|
||||
//Other things
|
||||
PROXY.init();
|
||||
NET_HANDLER = NetworkRegistry.INSTANCE.newSimpleChannel("webdisplays");
|
||||
Messages.registerAll(NET_HANDLER);
|
||||
}
|
||||
|
||||
@Mod.EventHandler
|
||||
public void onPostInit(FMLPostInitializationEvent ev) {
|
||||
PROXY.postInit();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRegisterBlocks(RegistryEvent.Register<Block> ev) {
|
||||
ev.getRegistry().registerAll(blockScreen, blockPeripheral, blockKbRight);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRegisterItems(RegistryEvent.Register<Item> ev) {
|
||||
ev.getRegistry().registerAll(blockScreen.getItem(), blockPeripheral.getItem());
|
||||
ev.getRegistry().registerAll(itemScreenCfg, itemOwnerThief, itemLinker, itemStoneKey, itemMinePad);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRegisterSounds(RegistryEvent.Register<SoundEvent> ev) {
|
||||
soundTyping = new SoundEvent(new ResourceLocation("webdisplays", "keyboardType"));
|
||||
soundTyping.setRegistryName(soundTyping.getSoundName());
|
||||
ev.getRegistry().register(soundTyping);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onWorldLoad(WorldEvent.Load ev) {
|
||||
if(ev.getWorld().isRemote || ev.getWorld().provider.getDimension() != 0)
|
||||
return;
|
||||
|
||||
File f = new File(ev.getWorld().getSaveHandler().getWorldDirectory(), "wd_next.txt");
|
||||
|
||||
if(f.exists()) {
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new FileReader(f));
|
||||
String idx = br.readLine();
|
||||
Util.silentClose(br);
|
||||
|
||||
if(idx == null)
|
||||
throw new RuntimeException("Seems like the file is empty (1)");
|
||||
|
||||
idx = idx.trim();
|
||||
if(idx.isEmpty())
|
||||
throw new RuntimeException("Seems like the file is empty (2)");
|
||||
|
||||
lastPadId = Integer.parseInt(idx); //This will throw NumberFormatException if it goes wrong
|
||||
} catch(Throwable t) {
|
||||
Log.warningEx("Could not read last minePad ID from %s. I'm afraid this might break all minePads.", t, f.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onWorldSave(WorldEvent.Save ev) {
|
||||
if(ev.getWorld().isRemote || ev.getWorld().provider.getDimension() != 0)
|
||||
return;
|
||||
|
||||
File f = new File(ev.getWorld().getSaveHandler().getWorldDirectory(), "wd_next.txt");
|
||||
|
||||
try {
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
|
||||
bw.write("" + lastPadId + "\n");
|
||||
Util.silentClose(bw);
|
||||
} catch(Throwable t) {
|
||||
Log.warningEx("Could not save last minePad ID (%d) to %s. I'm afraid this might break all minePads.", t, lastPadId, f.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
public static int getNextAvailablePadID() {
|
||||
return INSTANCE.lastPadId++;
|
||||
}
|
||||
|
||||
}
|
||||
218
src/main/java/net/montoyo/wd/block/BlockKeyboardRight.java
Normal file
218
src/main/java/net/montoyo/wd/block/BlockKeyboardRight.java
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.EnumPushReaction;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.properties.PropertyInteger;
|
||||
import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.core.DefaultPeripheral;
|
||||
import net.montoyo.wd.core.IPeripheral;
|
||||
import net.montoyo.wd.entity.TileEntityKeyboard;
|
||||
import net.montoyo.wd.item.ItemLinker;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class BlockKeyboardRight extends Block implements IPeripheral {
|
||||
|
||||
public static final PropertyInteger facing = PropertyInteger.create("facing", 0, 3);
|
||||
private static final IProperty[] properties = new IProperty[] { facing };
|
||||
public static final AxisAlignedBB KEYBOARD_AABB = new AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 1.0 / 16.0, 1.0);
|
||||
|
||||
public BlockKeyboardRight() {
|
||||
super(Material.ROCK);
|
||||
setHardness(1.5f);
|
||||
setResistance(10.f);
|
||||
setUnlocalizedName("webdisplays.peripheral.keyboard");
|
||||
setRegistryName("keyboard");
|
||||
fullBlock = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockStateContainer createBlockState() {
|
||||
return new BlockStateContainer(this, properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int quantityDropped(Random random) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullCube(IBlockState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullBlock(IBlockState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaqueCube(IBlockState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
|
||||
return KEYBOARD_AABB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta(int meta) {
|
||||
return getDefaultState().withProperty(facing, meta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState(IBlockState state) {
|
||||
return state.getValue(facing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickBlock(IBlockState state, RayTraceResult target, World world, BlockPos pos, EntityPlayer player) {
|
||||
return new ItemStack(WebDisplays.INSTANCE.blockPeripheral, 1, 0);
|
||||
}
|
||||
|
||||
TileEntityKeyboard getTileEntity(World world, BlockPos pos) {
|
||||
for(EnumFacing nf: EnumFacing.HORIZONTALS) {
|
||||
BlockPos np = pos.add(nf.getDirectionVec());
|
||||
IBlockState ns = world.getBlockState(np);
|
||||
|
||||
if(ns.getBlock() instanceof BlockPeripheral && ns.getValue(BlockPeripheral.type) == DefaultPeripheral.KEYBOARD) {
|
||||
TileEntity te = world.getTileEntity(np);
|
||||
if(te != null && te instanceof TileEntityKeyboard)
|
||||
return (TileEntityKeyboard) te;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connect(World world, BlockPos pos, IBlockState state, Vector3i scrPos, BlockSide scrSide) {
|
||||
TileEntityKeyboard keyboard = getTileEntity(world, pos);
|
||||
return keyboard != null && keyboard.connect(world, pos, state, scrPos, scrSide);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumPushReaction getMobilityFlag(IBlockState state) {
|
||||
return EnumPushReaction.IGNORE;
|
||||
}
|
||||
|
||||
public static boolean checkNeighborhood(IBlockAccess world, BlockPos bp, BlockPos ignore) {
|
||||
for(EnumFacing neighbor: EnumFacing.HORIZONTALS) {
|
||||
BlockPos np = bp.add(neighbor.getDirectionVec());
|
||||
|
||||
if(ignore == null || !np.equals(ignore)) {
|
||||
IBlockState state = world.getBlockState(np);
|
||||
|
||||
if(state.getBlock() instanceof BlockPeripheral) {
|
||||
if(state.getValue(BlockPeripheral.type) == DefaultPeripheral.KEYBOARD)
|
||||
return false;
|
||||
} else if(state.getBlock() instanceof BlockKeyboardRight)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void removeLeftPiece(World world, BlockPos pos, boolean dropItem) {
|
||||
for(EnumFacing nf: EnumFacing.HORIZONTALS) {
|
||||
BlockPos np = pos.add(nf.getDirectionVec());
|
||||
IBlockState ns = world.getBlockState(np);
|
||||
|
||||
if(ns.getBlock() instanceof BlockPeripheral && ns.getValue(BlockPeripheral.type) == DefaultPeripheral.KEYBOARD) {
|
||||
if(dropItem)
|
||||
ns.getBlock().dropBlockAsItem(world, np, ns, 0);
|
||||
|
||||
world.setBlockToAir(np);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block neighborType, BlockPos neighbor) {
|
||||
if(world.isRemote)
|
||||
return;
|
||||
|
||||
if(neighbor.getX() == pos.getX() && neighbor.getY() == pos.getY() - 1 && neighbor.getZ() == pos.getZ() && world.isAirBlock(neighbor)) {
|
||||
removeLeftPiece(world, pos, true);
|
||||
world.setBlockToAir(pos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer ply, boolean willHarvest) {
|
||||
if(!world.isRemote)
|
||||
removeLeftPiece(world, pos, !ply.isCreative());
|
||||
|
||||
return super.removedByPlayer(state, world, pos, ply, willHarvest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockDestroyedByExplosion(World world, BlockPos pos, Explosion explosionIn) {
|
||||
if(!world.isRemote)
|
||||
removeLeftPiece(world, pos, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity) {
|
||||
double rpos = (entity.posY - ((double) pos.getY())) * 16.0;
|
||||
if(!world.isRemote && rpos >= 1.0 && rpos <= 2.0 && Math.random() < 0.25) {
|
||||
TileEntityKeyboard tek = getTileEntity(world, pos);
|
||||
|
||||
if(tek != null)
|
||||
tek.simulateCat(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
|
||||
if(player.isSneaking())
|
||||
return false;
|
||||
|
||||
if(player.getHeldItem(hand).getItem() instanceof ItemLinker)
|
||||
return false;
|
||||
|
||||
TileEntityKeyboard tek = getTileEntity(world, pos);
|
||||
if(tek != null)
|
||||
return tek.onRightClick(player, hand, BlockSide.values()[facing.ordinal()]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
243
src/main/java/net/montoyo/wd/block/BlockPeripheral.java
Normal file
243
src/main/java/net/montoyo/wd/block/BlockPeripheral.java
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.EnumPushReaction;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.properties.PropertyInteger;
|
||||
import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumBlockRenderType;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.core.DefaultPeripheral;
|
||||
import net.montoyo.wd.entity.TileEntityKeyboard;
|
||||
import net.montoyo.wd.entity.TileEntityPeripheralBase;
|
||||
import net.montoyo.wd.item.ItemLinker;
|
||||
import net.montoyo.wd.item.ItemPeripheral;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class BlockPeripheral extends WDBlockContainer {
|
||||
|
||||
public static final PropertyEnum<DefaultPeripheral> type = PropertyEnum.create("type", DefaultPeripheral.class);
|
||||
public static final PropertyInteger facing = PropertyInteger.create("facing", 0, 3);
|
||||
private static final IProperty[] properties = new IProperty[] { type, facing };
|
||||
|
||||
public BlockPeripheral() {
|
||||
super(Material.ROCK);
|
||||
setHardness(1.5f);
|
||||
setResistance(10.f);
|
||||
setCreativeTab(WebDisplays.CREATIVE_TAB);
|
||||
setName("peripheral");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemBlock createItemBlock() {
|
||||
return new ItemPeripheral(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockStateContainer createBlockState() {
|
||||
return new BlockStateContainer(this, properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing rrezozei, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) {
|
||||
int rot = MathHelper.floor(((double) (placer.rotationYaw * 4.0f / 360.0f)) + 2.5) & 3;
|
||||
return getDefaultState().withProperty(type, DefaultPeripheral.values()[meta]).withProperty(facing, rot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubBlocks(CreativeTabs tab, NonNullList<ItemStack> list) {
|
||||
for(DefaultPeripheral dp : DefaultPeripheral.values())
|
||||
list.add(new ItemStack(getItem(), 1, dp.ordinal()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta(int meta) {
|
||||
return getDefaultState().withProperty(type, DefaultPeripheral.values()[meta & 3]).withProperty(facing, (meta >> 2) & 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState(IBlockState state) {
|
||||
return state.getValue(type).ordinal() | (state.getValue(facing) << 2);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World world, int meta) {
|
||||
Class<? extends TileEntityPeripheralBase> cls = DefaultPeripheral.values()[meta & 3].getTEClass();
|
||||
if(cls == null)
|
||||
return null;
|
||||
|
||||
try {
|
||||
return cls.newInstance();
|
||||
} catch(Throwable t) {
|
||||
Log.errorEx("Couldn't instantiate peripheral TileEntity:", t);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumBlockRenderType getRenderType(IBlockState state) {
|
||||
return EnumBlockRenderType.MODEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageDropped(IBlockState state) {
|
||||
return state.getValue(type).ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
|
||||
if(player.isSneaking())
|
||||
return false;
|
||||
|
||||
if(player.getHeldItem(hand).getItem() instanceof ItemLinker)
|
||||
return false;
|
||||
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
if(te == null || !(te instanceof TileEntityPeripheralBase))
|
||||
return false;
|
||||
|
||||
return ((TileEntityPeripheralBase) te).onRightClick(player, hand, BlockSide.values()[facing.ordinal()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullCube(IBlockState state) {
|
||||
return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullBlock(IBlockState state) {
|
||||
return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) {
|
||||
return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpaqueCube(IBlockState state) {
|
||||
return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) {
|
||||
return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
|
||||
return state.getValue(type) == DefaultPeripheral.KEYBOARD ? BlockKeyboardRight.KEYBOARD_AABB : FULL_BLOCK_AABB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) {
|
||||
if(world.isRemote || state.getValue(type) != DefaultPeripheral.KEYBOARD)
|
||||
return;
|
||||
|
||||
//Keyboard special treatment
|
||||
int f = state.getValue(facing);
|
||||
Vec3i dir = EnumFacing.getHorizontal(f).rotateY().getDirectionVec();
|
||||
BlockPos left = pos.add(dir);
|
||||
BlockPos right = pos.subtract(dir);
|
||||
|
||||
if(!world.isAirBlock(pos.down()) && BlockKeyboardRight.checkNeighborhood(world, pos, null)) {
|
||||
if(world.isAirBlock(right) && !world.isAirBlock(right.down()) && BlockKeyboardRight.checkNeighborhood(world, right, pos)) {
|
||||
world.setBlockState(right, WebDisplays.INSTANCE.blockKbRight.getDefaultState().withProperty(BlockKeyboardRight.facing, f));
|
||||
return;
|
||||
} else if(world.isAirBlock(left) && !world.isAirBlock(left.down()) && BlockKeyboardRight.checkNeighborhood(world, left, pos)) {
|
||||
world.setBlockState(left, state);
|
||||
world.setBlockState(pos, WebDisplays.INSTANCE.blockKbRight.getDefaultState().withProperty(BlockKeyboardRight.facing, f));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Not good; remove this shit...
|
||||
world.setBlockToAir(pos);
|
||||
if(!(placer instanceof EntityPlayer) || !((EntityPlayer) placer).isCreative())
|
||||
dropBlockAsItem(world, pos, state, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumPushReaction getMobilityFlag(IBlockState state) {
|
||||
return EnumPushReaction.IGNORE;
|
||||
}
|
||||
|
||||
private void removeRightPiece(World world, BlockPos pos) {
|
||||
for(EnumFacing nf: EnumFacing.HORIZONTALS) {
|
||||
BlockPos np = pos.add(nf.getDirectionVec());
|
||||
|
||||
if(world.getBlockState(np).getBlock() instanceof BlockKeyboardRight) {
|
||||
world.setBlockToAir(np);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block neighborType, BlockPos neighbor) {
|
||||
if(world.isRemote || state.getValue(type) != DefaultPeripheral.KEYBOARD)
|
||||
return;
|
||||
|
||||
if(neighbor.getX() == pos.getX() && neighbor.getY() == pos.getY() - 1 && neighbor.getZ() == pos.getZ() && world.isAirBlock(neighbor)) {
|
||||
removeRightPiece(world, pos);
|
||||
world.setBlockToAir(pos);
|
||||
dropBlockAsItem(world, pos, state, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockDestroyedByPlayer(World world, BlockPos pos, IBlockState state) {
|
||||
if(!world.isRemote && state.getValue(type) == DefaultPeripheral.KEYBOARD)
|
||||
removeRightPiece(world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockDestroyedByExplosion(World world, BlockPos pos, Explosion explosion) {
|
||||
if(!world.isRemote && world.getBlockState(pos).getValue(type) == DefaultPeripheral.KEYBOARD)
|
||||
removeRightPiece(world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity) {
|
||||
if(!world.isRemote && world.getBlockState(pos).getValue(type) == DefaultPeripheral.KEYBOARD) {
|
||||
double rpos = (entity.posY - ((double) pos.getY())) * 16.0;
|
||||
|
||||
if(rpos >= 1.0 && rpos <= 2.0 && Math.random() < 0.25) {
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
|
||||
if(te != null && te instanceof TileEntityKeyboard)
|
||||
((TileEntityKeyboard) te).simulateCat(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
253
src/main/java/net/montoyo/wd/block/BlockScreen.java
Normal file
253
src/main/java/net/montoyo/wd/block/BlockScreen.java
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.block.material.EnumPushReaction;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.properties.PropertyBool;
|
||||
import net.minecraft.block.properties.PropertyInteger;
|
||||
import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumBlockRenderType;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.property.ExtendedBlockState;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.common.property.IUnlistedProperty;
|
||||
import net.minecraftforge.common.property.Properties;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.data.SetURLData;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.utilities.*;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class BlockScreen extends WDBlockContainer {
|
||||
|
||||
public static final PropertyBool hasTE = PropertyBool.create("haste");
|
||||
private static final IProperty[] properties = new IProperty[] { hasTE };
|
||||
public static final IUnlistedProperty<Integer>[] sideFlags = new IUnlistedProperty[6];
|
||||
static {
|
||||
for(int i = 0; i < sideFlags.length; i++)
|
||||
sideFlags[i] = Properties.toUnlisted(PropertyInteger.create("neighbor" + i, 0, 15));
|
||||
}
|
||||
|
||||
public static final int BAR_BOT = 1;
|
||||
public static final int BAR_RIGHT = 2;
|
||||
public static final int BAR_TOP = 4;
|
||||
public static final int BAR_LEFT = 8;
|
||||
|
||||
public BlockScreen() {
|
||||
super(Material.ROCK);
|
||||
setHardness(1.5f);
|
||||
setResistance(10.f);
|
||||
setCreativeTab(WebDisplays.CREATIVE_TAB);
|
||||
setName("screen");
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumBlockRenderType getRenderType(IBlockState state) {
|
||||
return EnumBlockRenderType.MODEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockStateContainer createBlockState() {
|
||||
return new ExtendedBlockState(this, properties, sideFlags);
|
||||
}
|
||||
|
||||
public static boolean isScreenBlock(IBlockAccess world, Vector3i pos) {
|
||||
return world.getBlockState(pos.toBlock()).getBlock() instanceof BlockScreen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getExtendedState(IBlockState state, IBlockAccess world, BlockPos bpos) {
|
||||
IExtendedBlockState ret = (IExtendedBlockState) blockState.getBaseState();
|
||||
Vector3i pos = new Vector3i(bpos);
|
||||
|
||||
for(BlockSide side : BlockSide.values()) {
|
||||
int icon = 0;
|
||||
if(!isScreenBlock(world, side.up.clone().add(pos))) icon |= BAR_TOP;
|
||||
if(!isScreenBlock(world, side.down.clone().add(pos))) icon |= BAR_BOT;
|
||||
if(!isScreenBlock(world, side.left.clone().add(pos))) icon |= BAR_LEFT;
|
||||
if(!isScreenBlock(world, side.right.clone().add(pos))) icon |= BAR_RIGHT;
|
||||
|
||||
ret = ret.withProperty(sideFlags[side.ordinal()], icon);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta(int meta) {
|
||||
return getDefaultState().withProperty(hasTE, meta != 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState(IBlockState state) {
|
||||
return state.getValue(hasTE) ? 1 : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World world, BlockPos bpos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
|
||||
if(!player.getHeldItem(hand).isEmpty())
|
||||
return false;
|
||||
|
||||
if(world.isRemote)
|
||||
return true;
|
||||
|
||||
boolean sneaking = player.isSneaking();
|
||||
Vector3i pos = new Vector3i(bpos);
|
||||
BlockSide side = BlockSide.values()[facing.ordinal()];
|
||||
|
||||
Multiblock.findOrigin(world, pos, side, null);
|
||||
TileEntityScreen te = (TileEntityScreen) world.getTileEntity(pos.toBlock());
|
||||
|
||||
if(te != null && te.getScreen(side) != null) {
|
||||
TileEntityScreen.Screen scr = te.getScreen(side);
|
||||
|
||||
if(sneaking) { //Set URL
|
||||
if((scr.rightsFor(player) & ScreenRights.CHANGE_URL) == 0)
|
||||
Util.toast(player, "restrictions");
|
||||
else
|
||||
(new SetURLData(pos, scr.side, scr.url)).sendTo((EntityPlayerMP) player);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
if((scr.rightsFor(player) & ScreenRights.CLICK) == 0) {
|
||||
Util.toast(player, "restrictions");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(side.right.x < 0)
|
||||
hitX -= 1.f;
|
||||
|
||||
if(side.right.z < 0 || side == BlockSide.TOP || side == BlockSide.BOTTOM)
|
||||
hitZ -= 1.f;
|
||||
|
||||
Vector3f rel = new Vector3f(bpos.getX(), bpos.getY(), bpos.getZ());
|
||||
rel.sub((float) pos.x, (float) pos.y, (float) pos.z);
|
||||
rel.add(hitX, hitY, hitZ);
|
||||
|
||||
float cx = rel.dot(side.right.toFloat()) - 2.f / 16.f;
|
||||
float cy = rel.dot(side.up.toFloat()) - 2.f / 16.f;
|
||||
float sw = ((float) scr.size.x) - 4.f / 16.f;
|
||||
float sh = ((float) scr.size.y) - 4.f / 16.f;
|
||||
|
||||
cx /= sw;
|
||||
cy /= sh;
|
||||
|
||||
if(cx >= 0.f && cx <= 1.0 && cy >= 0.f && cy <= 1.f) {
|
||||
if(side != BlockSide.BOTTOM)
|
||||
cy = 1.f - cy;
|
||||
|
||||
cx *= (float) scr.resolution.x;
|
||||
cy *= (float) scr.resolution.y;
|
||||
te.click(side, new Vector2i((int) cx, (int) cy));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} else if(sneaking) {
|
||||
Util.toast(player, "turnOn");
|
||||
return true;
|
||||
}
|
||||
|
||||
Vector2i size = Multiblock.measure(world, pos, side);
|
||||
if(size.x < 2 || size.y < 2) {
|
||||
Util.toast(player, "tooSmall");
|
||||
return true;
|
||||
}
|
||||
|
||||
Vector3i err = Multiblock.check(world, pos, size, side);
|
||||
if(err != null) {
|
||||
Util.toast(player, "invalid", err.toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean created = false;
|
||||
Log.info("Structure at %s of size %dx%d", pos.toString(), size.x, size.y);
|
||||
|
||||
if(te == null) {
|
||||
BlockPos bp = pos.toBlock();
|
||||
world.setBlockState(bp, getDefaultState().withProperty(hasTE, true));
|
||||
te = (TileEntityScreen) world.getTileEntity(bp);
|
||||
created = true;
|
||||
}
|
||||
|
||||
te.addScreen(side, size, null, !created).setOwner(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World world, int meta) {
|
||||
return meta == 0 ? null : new TileEntityScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockDestroyedByPlayer(World world, BlockPos pos, IBlockState dontCare) {
|
||||
if(!world.isRemote) {
|
||||
Vector3i bp = new Vector3i(pos);
|
||||
Multiblock.BlockOverride override = new Multiblock.BlockOverride(bp, Multiblock.OverrideAction.SIMULATE);
|
||||
|
||||
for(BlockSide bs: BlockSide.values())
|
||||
destroySide(world, bp.clone(), bs, override);
|
||||
}
|
||||
}
|
||||
|
||||
private void destroySide(World world, Vector3i pos, BlockSide side, Multiblock.BlockOverride override) {
|
||||
Multiblock.findOrigin(world, pos, side, override);
|
||||
BlockPos bp = pos.toBlock();
|
||||
TileEntity te = world.getTileEntity(bp);
|
||||
|
||||
if(te != null && te instanceof TileEntityScreen)
|
||||
world.setBlockState(bp, getDefaultState().withProperty(hasTE, false)); //Destroy tile entity
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumPushReaction getMobilityFlag(IBlockState state) {
|
||||
return EnumPushReaction.IGNORE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockDestroyedByExplosion(World world, BlockPos pos, Explosion explosion) {
|
||||
onBlockDestroyedByPlayer(world, pos, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase whoDidThisShit, ItemStack stack) {
|
||||
if(world.isRemote)
|
||||
return;
|
||||
|
||||
Multiblock.BlockOverride override = new Multiblock.BlockOverride(new Vector3i(pos), Multiblock.OverrideAction.IGNORE);
|
||||
Vector3i[] neighbors = new Vector3i[6];
|
||||
|
||||
neighbors[0] = new Vector3i(pos.getX() + 1, pos.getY(), pos.getZ());
|
||||
neighbors[1] = new Vector3i(pos.getX() - 1, pos.getY(), pos.getZ());
|
||||
neighbors[2] = new Vector3i(pos.getX(), pos.getY() + 1, pos.getZ());
|
||||
neighbors[3] = new Vector3i(pos.getX(), pos.getY() - 1, pos.getZ());
|
||||
neighbors[4] = new Vector3i(pos.getX(), pos.getY(), pos.getZ() + 1);
|
||||
neighbors[5] = new Vector3i(pos.getX(), pos.getY(), pos.getZ() - 1);
|
||||
|
||||
for(Vector3i neighbor: neighbors) {
|
||||
if(world.getBlockState(neighbor.toBlock()).getBlock() instanceof BlockScreen) {
|
||||
for(BlockSide bs: BlockSide.values())
|
||||
destroySide(world, neighbor.clone(), bs, override);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
42
src/main/java/net/montoyo/wd/block/WDBlock.java
Normal file
42
src/main/java/net/montoyo/wd/block/WDBlock.java
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.MapColor;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
|
||||
public abstract class WDBlock extends Block {
|
||||
|
||||
protected ItemBlock itemBlock;
|
||||
|
||||
public WDBlock(Material mat, MapColor color) {
|
||||
super(mat, color);
|
||||
}
|
||||
|
||||
public WDBlock(Material material) {
|
||||
super(material);
|
||||
}
|
||||
|
||||
protected void setName(String name) {
|
||||
setUnlocalizedName("webdisplays." + name);
|
||||
setRegistryName(name);
|
||||
}
|
||||
|
||||
public void makeItemBlock() {
|
||||
if(itemBlock != null)
|
||||
throw new RuntimeException("WDBlock.makeItemBlock() called twice!");
|
||||
|
||||
itemBlock = new ItemBlock(this);
|
||||
itemBlock.setUnlocalizedName(getUnlocalizedName());
|
||||
itemBlock.setRegistryName(getRegistryName());
|
||||
}
|
||||
|
||||
public ItemBlock getItem() {
|
||||
return itemBlock;
|
||||
}
|
||||
|
||||
}
|
||||
46
src/main/java/net/montoyo/wd/block/WDBlockContainer.java
Normal file
46
src/main/java/net/montoyo/wd/block/WDBlockContainer.java
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.block.BlockContainer;
|
||||
import net.minecraft.block.material.MapColor;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
|
||||
public abstract class WDBlockContainer extends BlockContainer {
|
||||
|
||||
protected ItemBlock itemBlock;
|
||||
|
||||
public WDBlockContainer(Material mat, MapColor color) {
|
||||
super(mat, color);
|
||||
}
|
||||
|
||||
public WDBlockContainer(Material material) {
|
||||
super(material);
|
||||
}
|
||||
|
||||
protected void setName(String name) {
|
||||
setUnlocalizedName("webdisplays." + name);
|
||||
setRegistryName(name);
|
||||
}
|
||||
|
||||
protected ItemBlock createItemBlock() {
|
||||
return new ItemBlock(this);
|
||||
}
|
||||
|
||||
public void makeItemBlock() {
|
||||
if(itemBlock != null)
|
||||
throw new RuntimeException("WDBlockContainer.makeItemBlock() called twice!");
|
||||
|
||||
itemBlock = createItemBlock();
|
||||
itemBlock.setUnlocalizedName(getUnlocalizedName());
|
||||
itemBlock.setRegistryName(getRegistryName());
|
||||
}
|
||||
|
||||
public ItemBlock getItem() {
|
||||
return itemBlock;
|
||||
}
|
||||
|
||||
}
|
||||
376
src/main/java/net/montoyo/wd/client/ClientProxy.java
Normal file
376
src/main/java/net/montoyo/wd/client/ClientProxy.java
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.client.resources.IResourceManager;
|
||||
import net.minecraft.client.resources.IResourceManagerReloadListener;
|
||||
import net.minecraft.client.resources.SimpleReloadableResourceManager;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.EnumHandSide;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.ModelBakeEvent;
|
||||
import net.minecraftforge.client.event.ModelRegistryEvent;
|
||||
import net.minecraftforge.client.event.RenderSpecificHandEvent;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.client.model.ModelLoader;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||
import net.montoyo.mcef.api.IBrowser;
|
||||
import net.montoyo.mcef.api.IDisplayHandler;
|
||||
import net.montoyo.mcef.api.MCEFApi;
|
||||
import net.montoyo.wd.SharedProxy;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.gui.GuiMinePad;
|
||||
import net.montoyo.wd.client.gui.GuiScreenConfig;
|
||||
import net.montoyo.wd.client.gui.GuiSetURL2;
|
||||
import net.montoyo.wd.client.gui.WDScreen;
|
||||
import net.montoyo.wd.client.gui.loading.GuiLoader;
|
||||
import net.montoyo.wd.client.renderers.IModelBaker;
|
||||
import net.montoyo.wd.client.renderers.MinePadRenderer;
|
||||
import net.montoyo.wd.client.renderers.ScreenBaker;
|
||||
import net.montoyo.wd.client.renderers.ScreenRenderer;
|
||||
import net.montoyo.wd.data.GuiData;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.net.SMessagePadCtrl;
|
||||
import net.montoyo.wd.utilities.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ClientProxy extends SharedProxy implements IResourceManagerReloadListener, IDisplayHandler {
|
||||
|
||||
public class PadData {
|
||||
|
||||
public IBrowser view;
|
||||
private boolean isInHotbar;
|
||||
private int id;
|
||||
private long lastURLSent;
|
||||
|
||||
private PadData(String url, int id) {
|
||||
view = mcef.createBrowser(url);
|
||||
view.resize((int) WebDisplays.INSTANCE.padResX, (int) WebDisplays.INSTANCE.padResY);
|
||||
isInHotbar = true;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Minecraft mc;
|
||||
private ArrayList<ResourceModelPair> modelBakers = new ArrayList<>();
|
||||
private net.montoyo.mcef.api.API mcef;
|
||||
private MinePadRenderer minePadRenderer;
|
||||
|
||||
//Tracking
|
||||
private ArrayList<TileEntityScreen> screenTracking = new ArrayList<>();
|
||||
private double unloadDistance2 = 32.0 * 32.0;
|
||||
private double loadDistance2 = 30.0 * 30.0;
|
||||
private int lastTracked = 0;
|
||||
|
||||
//MinePads Management
|
||||
private HashMap<Integer, PadData> padMap = new HashMap<>();
|
||||
private ArrayList<PadData> padList = new ArrayList<>();
|
||||
private int minePadTickCounter = 0;
|
||||
|
||||
/**************************************** INHERITED METHODS ****************************************/
|
||||
|
||||
@Override
|
||||
public void preInit() {
|
||||
mc = Minecraft.getMinecraft();
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
registerCustomBlockBaker(new ScreenBaker(), WebDisplays.INSTANCE.blockScreen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityScreen.class, new ScreenRenderer());
|
||||
mcef = MCEFApi.getAPI();
|
||||
minePadRenderer = new MinePadRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit() {
|
||||
((SimpleReloadableResourceManager) mc.getResourceManager()).registerReloadListener(this);
|
||||
|
||||
if(mcef == null)
|
||||
throw new RuntimeException("MCEF is missing");
|
||||
|
||||
mcef.registerDisplayHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld(int dim) {
|
||||
World ret = mc.world;
|
||||
if(dim == CURRENT_DIMENSION)
|
||||
return ret;
|
||||
|
||||
if(ret.provider.getDimension() != dim)
|
||||
throw new RuntimeException("Can't get non-current dimension " + dim + " from client.");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enqueue(Runnable r) {
|
||||
mc.addScheduledTask(r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayGui(GuiData data) {
|
||||
GuiScreen gui = data.createGui(mc.currentScreen, mc.world);
|
||||
if(gui != null)
|
||||
mc.displayGuiScreen(gui);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackScreen(TileEntityScreen tes, boolean track) {
|
||||
int idx = -1;
|
||||
for(int i = 0; i < screenTracking.size(); i++) {
|
||||
if(screenTracking.get(i) == tes) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(track) {
|
||||
if(idx < 0)
|
||||
screenTracking.add(tes);
|
||||
} else
|
||||
screenTracking.remove(idx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutocompleteResult(NameUUIDPair[] pairs) {
|
||||
if(mc.currentScreen != null && mc.currentScreen instanceof WDScreen) {
|
||||
if(pairs.length == 0)
|
||||
((WDScreen) mc.currentScreen).onAutocompleteFailure();
|
||||
else
|
||||
((WDScreen) mc.currentScreen).onAutocompleteResult(pairs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameProfile[] getOnlineGameProfiles() {
|
||||
return new GameProfile[] { mc.player.getGameProfile() };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void screenUpdateResolutionInGui(Vector3i pos, BlockSide side, Vector2i res) {
|
||||
if(mc.currentScreen != null && mc.currentScreen instanceof GuiScreenConfig) {
|
||||
GuiScreenConfig gsc = (GuiScreenConfig) mc.currentScreen;
|
||||
|
||||
if(gsc.isScreen(pos, side))
|
||||
gsc.updateResolution(res);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displaySetPadURLGui(String padURL) {
|
||||
mc.displayGuiScreen(new GuiSetURL2(padURL));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openMinePadGui(int padId) {
|
||||
PadData pd = padMap.get(padId);
|
||||
|
||||
if(pd != null && pd.view != null)
|
||||
mc.displayGuiScreen(new GuiMinePad(pd));
|
||||
}
|
||||
|
||||
/**************************************** RESOURCE MANAGER METHODS ****************************************/
|
||||
|
||||
@Override
|
||||
public void onResourceManagerReload(IResourceManager rm) {
|
||||
Log.info("Resource manager reload: clearing GUI cache...");
|
||||
GuiLoader.clearCache();
|
||||
}
|
||||
|
||||
/**************************************** DISPLAY HANDLER METHODS ****************************************/
|
||||
|
||||
@Override
|
||||
public void onAddressChange(IBrowser browser, String url) {
|
||||
if(browser != null) {
|
||||
long t = System.currentTimeMillis();
|
||||
|
||||
for(PadData pd : padList) {
|
||||
if(pd.view == browser && t - pd.lastURLSent >= 1000) {
|
||||
pd.lastURLSent = t; //Avoid spamming the server with porn URLs
|
||||
WebDisplays.NET_HANDLER.sendToServer(new SMessagePadCtrl(pd.id, url));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTitleChange(IBrowser browser, String title) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTooltip(IBrowser browser, String text) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusMessage(IBrowser browser, String value) {
|
||||
}
|
||||
|
||||
/**************************************** EVENT METHODS ****************************************/
|
||||
|
||||
@SubscribeEvent
|
||||
public void onStitchTextures(TextureStitchEvent.Pre ev) {
|
||||
TextureMap texMap = ev.getMap();
|
||||
|
||||
if(texMap == mc.getTextureMapBlocks()) {
|
||||
for(ResourceModelPair pair : modelBakers)
|
||||
pair.getModel().loadTextures(texMap);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onBakeModel(ModelBakeEvent ev) {
|
||||
for(ResourceModelPair pair : modelBakers)
|
||||
ev.getModelRegistry().putObject(pair.getResourceLocation(), pair.getModel());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRegisterModels(ModelRegistryEvent ev) {
|
||||
final WebDisplays wd = WebDisplays.INSTANCE;
|
||||
|
||||
registerItemModel(wd.blockScreen.getItem(), 0, "inventory");
|
||||
ModelLoader.setCustomModelResourceLocation(wd.blockPeripheral.getItem(), 0, new ModelResourceLocation("webdisplays:kb_inv", "normal"));
|
||||
registerItemModel(wd.blockPeripheral.getItem(), 1, "facing=0,type=remotectrl");
|
||||
registerItemModel(wd.blockPeripheral.getItem(), 2, "facing=0,type=ccinterface"); //TODO: This doesn't work...
|
||||
registerItemModel(wd.blockPeripheral.getItem(), 3, "facing=0,type=cointerface");
|
||||
registerItemModel(wd.itemScreenCfg, 0, "normal");
|
||||
registerItemModel(wd.itemOwnerThief, 0, "normal");
|
||||
registerItemModel(wd.itemLinker, 0, "normal");
|
||||
registerItemModel(wd.itemStoneKey, 0, "normal");
|
||||
registerItemModel(wd.itemMinePad, 0, "normal");
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onTick(TickEvent.ClientTickEvent ev) {
|
||||
if(ev.phase == TickEvent.Phase.END) {
|
||||
//Unload/load screens depending on client player distance
|
||||
if(mc.player != null && !screenTracking.isEmpty()) {
|
||||
int id = lastTracked % screenTracking.size();
|
||||
lastTracked++;
|
||||
|
||||
TileEntityScreen tes = screenTracking.get(id);
|
||||
double dist2 = mc.player.getDistanceSq(tes.getPos());
|
||||
|
||||
if(tes.isLoaded()) {
|
||||
if(dist2 > unloadDistance2)
|
||||
tes.unload();
|
||||
else
|
||||
tes.updateTrackDistance(dist2);
|
||||
} else if(dist2 <= loadDistance2)
|
||||
tes.load();
|
||||
}
|
||||
|
||||
//Load/unload minePads depending on which item is in the player's hand
|
||||
if(++minePadTickCounter >= 10) {
|
||||
minePadTickCounter = 0;
|
||||
EntityPlayer ep = mc.player;
|
||||
|
||||
for(PadData pd: padList)
|
||||
pd.isInHotbar = false;
|
||||
|
||||
if(ep != null) {
|
||||
updateInventory(ep.inventory.mainInventory, ep.getHeldItem(EnumHand.MAIN_HAND), 9);
|
||||
updateInventory(ep.inventory.offHandInventory, ep.getHeldItem(EnumHand.OFF_HAND), 1); //Is this okay?
|
||||
}
|
||||
|
||||
//TODO: Check for GuiContainer.draggedStack
|
||||
|
||||
for(int i = padList.size() - 1; i >= 0; i--) {
|
||||
PadData pd = padList.get(i);
|
||||
|
||||
if(!pd.isInHotbar) {
|
||||
pd.view.close();
|
||||
pd.view = null; //This is for GuiMinePad, in case the player dies with the GUI open
|
||||
padList.remove(i);
|
||||
padMap.remove(pd.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRenderPlayerHand(RenderSpecificHandEvent ev) {
|
||||
if(ev.getItemStack().getItem() == WebDisplays.INSTANCE.itemMinePad) {
|
||||
EnumHandSide handSide = mc.player.getPrimaryHand();
|
||||
if(ev.getHand() == EnumHand.OFF_HAND)
|
||||
handSide = handSide.opposite();
|
||||
|
||||
minePadRenderer.render(ev.getItemStack(), (handSide == EnumHandSide.RIGHT) ? 1.0f : -1.0f, ev.getSwingProgress(), ev.getEquipProgress());
|
||||
ev.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************** OTHER METHODS ****************************************/
|
||||
|
||||
private void updateInventory(NonNullList<ItemStack> inv, ItemStack heldStack, int cnt) {
|
||||
for(int i = 0; i < cnt; i++) {
|
||||
ItemStack item = inv.get(i);
|
||||
|
||||
if(item.getItem() == WebDisplays.INSTANCE.itemMinePad) {
|
||||
NBTTagCompound tag = item.getTagCompound();
|
||||
|
||||
if(tag != null && tag.hasKey("PadID"))
|
||||
updatePad(tag.getInteger("PadID"), tag, item == heldStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerCustomBlockBaker(IModelBaker baker, Block block0) {
|
||||
ModelResourceLocation normalLoc = new ModelResourceLocation(block0.getRegistryName(), "normal");
|
||||
ResourceModelPair pair = new ResourceModelPair(normalLoc, baker);
|
||||
modelBakers.add(pair);
|
||||
ModelLoader.setCustomStateMapper(block0, new StaticStateMapper(normalLoc));
|
||||
}
|
||||
|
||||
private void registerItemModel(Item item, int meta, String variant) {
|
||||
ModelLoader.setCustomModelResourceLocation(item, meta, new ModelResourceLocation(item.getRegistryName(), variant));
|
||||
}
|
||||
|
||||
private void updatePad(int id, NBTTagCompound tag, boolean isSelected) {
|
||||
PadData pd = padMap.get(id);
|
||||
|
||||
if(pd != null)
|
||||
pd.isInHotbar = true;
|
||||
else if(isSelected && tag.hasKey("PadURL")) {
|
||||
pd = new PadData(tag.getString("PadURL"), id);
|
||||
padMap.put(id, pd);
|
||||
padList.add(pd);
|
||||
}
|
||||
}
|
||||
|
||||
public MinePadRenderer getMinePadRenderer() {
|
||||
return minePadRenderer;
|
||||
}
|
||||
|
||||
public PadData getPadByID(int id) {
|
||||
return padMap.get(id);
|
||||
}
|
||||
|
||||
public net.montoyo.mcef.api.API getMCEF() {
|
||||
return mcef;
|
||||
}
|
||||
|
||||
}
|
||||
28
src/main/java/net/montoyo/wd/client/ResourceModelPair.java
Normal file
28
src/main/java/net/montoyo/wd/client/ResourceModelPair.java
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
import net.montoyo.wd.client.renderers.IModelBaker;
|
||||
|
||||
public class ResourceModelPair {
|
||||
|
||||
private ModelResourceLocation resLoc;
|
||||
private IModelBaker model;
|
||||
|
||||
public ResourceModelPair(ModelResourceLocation rl, IModelBaker m) {
|
||||
resLoc = rl;
|
||||
model = m;
|
||||
}
|
||||
|
||||
public ModelResourceLocation getResourceLocation() {
|
||||
return resLoc;
|
||||
}
|
||||
|
||||
public IModelBaker getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
}
|
||||
24
src/main/java/net/montoyo/wd/client/StaticStateMapper.java
Normal file
24
src/main/java/net/montoyo/wd/client/StaticStateMapper.java
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
||||
import net.minecraft.client.renderer.block.statemap.StateMapperBase;
|
||||
|
||||
public class StaticStateMapper extends StateMapperBase {
|
||||
|
||||
private ModelResourceLocation resLoc;
|
||||
|
||||
public StaticStateMapper(ModelResourceLocation rl) {
|
||||
resLoc = rl;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ModelResourceLocation getModelResourceLocation(IBlockState state) {
|
||||
return resLoc;
|
||||
}
|
||||
|
||||
}
|
||||
219
src/main/java/net/montoyo/wd/client/gui/GuiKeyboard.java
Normal file
219
src/main/java/net/montoyo/wd/client/gui/GuiKeyboard.java
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.gui.controls.Button;
|
||||
import net.montoyo.wd.client.gui.controls.Control;
|
||||
import net.montoyo.wd.client.gui.controls.Label;
|
||||
import net.montoyo.wd.client.gui.loading.FillControl;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.net.SMessageScreenCtrl;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
import net.montoyo.wd.utilities.Util;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class GuiKeyboard extends WDScreen {
|
||||
|
||||
private static final String WARNING_FNAME = "wd_keyboard_warning.txt";
|
||||
|
||||
private TileEntityScreen tes;
|
||||
private BlockSide side;
|
||||
private String eventStack = "";
|
||||
private boolean lastIsType = false;
|
||||
private BlockPos kbPos;
|
||||
private boolean showWarning = true;
|
||||
|
||||
@FillControl
|
||||
private Label lblInfo;
|
||||
|
||||
@FillControl
|
||||
private Button btnOk;
|
||||
|
||||
public GuiKeyboard() {
|
||||
}
|
||||
|
||||
public GuiKeyboard(TileEntityScreen tes, BlockSide side, BlockPos kbPos) {
|
||||
this.tes = tes;
|
||||
this.side = side;
|
||||
this.kbPos = kbPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addLoadCustomVariables(Map<String, Double> vars) {
|
||||
vars.put("showWarning", showWarning ? 1.0 : 0.0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
super.initGui();
|
||||
|
||||
if(mc.isIntegratedServerRunning() && mc.getIntegratedServer() != null && !mc.getIntegratedServer().getPublic())
|
||||
showWarning = false; //NO NEED
|
||||
else
|
||||
showWarning = !hasUserReadWarning();
|
||||
|
||||
loadFrom(new ResourceLocation("webdisplays", "gui/keyboard.json"));
|
||||
|
||||
if(showWarning) {
|
||||
int maxLabelW = 0;
|
||||
int totalH = 0;
|
||||
|
||||
for(Control ctrl : controls) {
|
||||
if(ctrl != lblInfo && ctrl instanceof Label) {
|
||||
if(ctrl.getWidth() > maxLabelW)
|
||||
maxLabelW = ctrl.getWidth();
|
||||
|
||||
totalH += ctrl.getHeight();
|
||||
ctrl.setPos((width - ctrl.getWidth()) / 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
btnOk.setWidth(maxLabelW);
|
||||
btnOk.setPos((width - maxLabelW) / 2, 0);
|
||||
totalH += btnOk.getHeight();
|
||||
|
||||
int y = (height - totalH) / 2;
|
||||
for(Control ctrl : controls) {
|
||||
if(ctrl != lblInfo) {
|
||||
ctrl.setPos(ctrl.getX(), y);
|
||||
y += ctrl.getHeight();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mc.inGameHasFocus = true;
|
||||
mc.mouseHelper.grabMouseCursor();
|
||||
}
|
||||
|
||||
defaultBackground = showWarning;
|
||||
syncTicks = 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleInput() {
|
||||
if(showWarning) {
|
||||
try {
|
||||
super.handleInput();
|
||||
} catch(IOException ex) {
|
||||
Log.warningEx("Caught exception while handling screen input", ex);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(Keyboard.isCreated()) {
|
||||
while(Keyboard.next()) {
|
||||
if(Keyboard.getEventKey() == Keyboard.KEY_ESCAPE)
|
||||
mc.displayGuiScreen(null);
|
||||
else {
|
||||
char chr = Keyboard.getEventCharacter();
|
||||
|
||||
if(chr == '\n' || chr == '\r' || chr == '\b') {
|
||||
if(lastIsType)
|
||||
lastIsType = false;
|
||||
|
||||
if(!eventStack.isEmpty())
|
||||
eventStack += (char) 1;
|
||||
|
||||
if(Keyboard.getEventKeyState())
|
||||
eventStack += 'p';
|
||||
else
|
||||
eventStack += 'r';
|
||||
|
||||
eventStack += chr;
|
||||
} else if(chr != 0) {
|
||||
if(!lastIsType) {
|
||||
if(!eventStack.isEmpty())
|
||||
eventStack += (char) 1;
|
||||
|
||||
eventStack += 't';
|
||||
lastIsType = true;
|
||||
}
|
||||
|
||||
eventStack += chr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!eventStack.isEmpty() && !syncRequested())
|
||||
requestSync();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesGuiPauseGame() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sync() {
|
||||
if(!eventStack.isEmpty()) {
|
||||
WebDisplays.NET_HANDLER.sendToServer(SMessageScreenCtrl.type(tes, side, eventStack, kbPos));
|
||||
eventStack = "";
|
||||
lastIsType = false;
|
||||
}
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onClick(Button.ClickEvent ev) {
|
||||
if(showWarning && ev.getSource() == btnOk) {
|
||||
writeUserAcknowledge();
|
||||
|
||||
for(Control ctrl: controls) {
|
||||
if(ctrl instanceof Label) {
|
||||
Label lbl = (Label) ctrl;
|
||||
lbl.setVisible(!lbl.isVisible());
|
||||
}
|
||||
}
|
||||
|
||||
btnOk.setDisabled(true);
|
||||
btnOk.setVisible(false);
|
||||
showWarning = false;
|
||||
defaultBackground = false;
|
||||
mc.inGameHasFocus = true;
|
||||
mc.mouseHelper.grabMouseCursor();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasUserReadWarning() {
|
||||
try {
|
||||
File f = new File(mc.mcDataDir, WARNING_FNAME);
|
||||
|
||||
if(f.exists()) {
|
||||
BufferedReader br = new BufferedReader(new FileReader(f));
|
||||
String str = br.readLine();
|
||||
Util.silentClose(br);
|
||||
|
||||
return str != null && str.trim().equalsIgnoreCase("read");
|
||||
}
|
||||
} catch(Throwable t) {
|
||||
Log.warningEx("Can't know if user has already read the warning", t);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void writeUserAcknowledge() {
|
||||
try {
|
||||
File f = new File(mc.mcDataDir, WARNING_FNAME);
|
||||
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
|
||||
bw.write("read\n");
|
||||
Util.silentClose(bw);
|
||||
} catch(Throwable t) {
|
||||
Log.warningEx("Can't write that the user read the warning", t);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
143
src/main/java/net/montoyo/wd/client/gui/GuiMinePad.java
Normal file
143
src/main/java/net/montoyo/wd/client/gui/GuiMinePad.java
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui;
|
||||
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.ClientProxy;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class GuiMinePad extends WDScreen {
|
||||
|
||||
private ClientProxy.PadData pad;
|
||||
private double vx;
|
||||
private double vy;
|
||||
private double vw;
|
||||
private double vh;
|
||||
|
||||
public GuiMinePad() {
|
||||
}
|
||||
|
||||
public GuiMinePad(ClientProxy.PadData pad) {
|
||||
this.pad = pad;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
super.initGui();
|
||||
|
||||
vw = ((double) width) - 32.0f;
|
||||
vh = vw / WebDisplays.PAD_RATIO;
|
||||
vx = 16.0f;
|
||||
vy = (((double) height) - vh) / 2.0f;
|
||||
}
|
||||
|
||||
private static void addRect(BufferBuilder bb, double x, double y, double w, double h) {
|
||||
bb.pos(x, y, 0.0).endVertex();
|
||||
bb.pos(x + w, y, 0.0).endVertex();
|
||||
bb.pos(x + w, y + h, 0.0).endVertex();
|
||||
bb.pos(x, y + h, 0.0).endVertex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int mouseX, int mouseY, float ptt) {
|
||||
drawDefaultBackground();
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glColor4f(0.73f, 0.73f, 0.73f, 1.0f);
|
||||
|
||||
Tessellator t = Tessellator.getInstance();
|
||||
BufferBuilder bb = t.getBuffer();
|
||||
bb.begin(GL_QUADS, DefaultVertexFormats.POSITION);
|
||||
addRect(bb, vx, vy - 16, vw, 16);
|
||||
addRect(bb, vx, vy + vh, vw, 16);
|
||||
addRect(bb, vx - 16, vy, 16, vh);
|
||||
addRect(bb, vx + vw, vy, 16, vh);
|
||||
t.draw();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
if(pad.view != null) {
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
pad.view.draw(vx, vy + vh, vx + vw, vy);
|
||||
}
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleInput() {
|
||||
while(Keyboard.next()) {
|
||||
char key = Keyboard.getEventCharacter();
|
||||
boolean pressed = Keyboard.getEventKeyState();
|
||||
|
||||
if(Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) {
|
||||
mc.displayGuiScreen(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if(pad.view != null) {
|
||||
if(key != '.' && key != ';' && key != ',') {
|
||||
if(pressed)
|
||||
pad.view.injectKeyPressed(key, 0);
|
||||
else
|
||||
pad.view.injectKeyReleased(key, 0);
|
||||
}
|
||||
|
||||
if(key != Keyboard.CHAR_NONE)
|
||||
pad.view.injectKeyTyped(key, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int vx = screen2DisplayX((int) this.vx);
|
||||
int vy = screen2DisplayY((int) this.vy);
|
||||
int vh = screen2DisplayX((int) this.vh);
|
||||
int vw = screen2DisplayY((int) this.vw);
|
||||
|
||||
while(Mouse.next()) {
|
||||
int btn = Mouse.getEventButton();
|
||||
boolean pressed = Mouse.getEventButtonState();
|
||||
int sx = Mouse.getEventX();
|
||||
int sy = Mouse.getEventY();
|
||||
|
||||
if(pad.view != null && sx >= vx && sx <= vx + vw && sy >= vy && sy <= vy + vh) {
|
||||
sx -= vx;
|
||||
sy -= vy;
|
||||
sy = vh - sy;
|
||||
|
||||
//Scale again according to the webview
|
||||
sx = (int) (((double) sx) / ((double) vw) * WebDisplays.INSTANCE.padResX);
|
||||
sy = (int) (((double) sy) / ((double) vh) * WebDisplays.INSTANCE.padResY);
|
||||
|
||||
if(btn == -1)
|
||||
pad.view.injectMouseMove(sx, sy, 0, false);
|
||||
else
|
||||
pad.view.injectMouseButton(sx, sy, 0, btn + 1, pressed, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateScreen() {
|
||||
if(pad.view == null)
|
||||
mc.displayGuiScreen(null); //In case the user dies with the pad in the hand
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesGuiPauseGame() {
|
||||
//TODO: Is this necessary??
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
415
src/main/java/net/montoyo/wd/client/gui/GuiScreenConfig.java
Normal file
415
src/main/java/net/montoyo/wd/client/gui/GuiScreenConfig.java
Normal file
|
|
@ -0,0 +1,415 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.gui.controls.*;
|
||||
import net.montoyo.wd.client.gui.loading.FillControl;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.net.SMessageScreenCtrl;
|
||||
import net.montoyo.wd.utilities.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class GuiScreenConfig extends WDScreen {
|
||||
|
||||
//Screen data
|
||||
private TileEntityScreen tes;
|
||||
private BlockSide side;
|
||||
private NameUUIDPair owner;
|
||||
private NameUUIDPair[] friends;
|
||||
private int friendRights;
|
||||
private int otherRights;
|
||||
|
||||
//Autocomplete handling
|
||||
private boolean waitingAC;
|
||||
private int acFailTicks = -1;
|
||||
|
||||
private ArrayList<NameUUIDPair> acResults = new ArrayList<NameUUIDPair>();
|
||||
private boolean adding;
|
||||
|
||||
//Controls
|
||||
@FillControl
|
||||
private Label lblOwner;
|
||||
|
||||
@FillControl
|
||||
private List lstFriends;
|
||||
|
||||
@FillControl
|
||||
private Button btnAdd;
|
||||
|
||||
@FillControl
|
||||
private TextField tfFriend;
|
||||
|
||||
@FillControl
|
||||
private TextField tfResX;
|
||||
|
||||
@FillControl
|
||||
private TextField tfResY;
|
||||
|
||||
@FillControl
|
||||
private ControlGroup grpFriends;
|
||||
|
||||
@FillControl
|
||||
private ControlGroup grpOthers;
|
||||
|
||||
@FillControl
|
||||
private CheckBox boxFSetUrl;
|
||||
|
||||
@FillControl
|
||||
private CheckBox boxFClick;
|
||||
|
||||
@FillControl
|
||||
private CheckBox boxFFriends;
|
||||
|
||||
@FillControl
|
||||
private CheckBox boxFOthers;
|
||||
|
||||
@FillControl
|
||||
private CheckBox boxFUpgrades;
|
||||
|
||||
@FillControl
|
||||
private CheckBox boxFResolution;
|
||||
|
||||
@FillControl
|
||||
private CheckBox boxOSetUrl;
|
||||
|
||||
@FillControl
|
||||
private CheckBox boxOClick;
|
||||
|
||||
@FillControl
|
||||
private CheckBox boxOUpgrades;
|
||||
|
||||
@FillControl
|
||||
private CheckBox boxOResolution;
|
||||
|
||||
@FillControl
|
||||
private Button btnSetRes;
|
||||
|
||||
private CheckBox[] friendBoxes;
|
||||
private CheckBox[] otherBoxes;
|
||||
|
||||
public GuiScreenConfig(TileEntityScreen tes, BlockSide side, NameUUIDPair owner, NameUUIDPair[] friends, int fr, int or) {
|
||||
this.tes = tes;
|
||||
this.side = side;
|
||||
this.owner = owner;
|
||||
this.friends = friends;
|
||||
friendRights = fr;
|
||||
otherRights = or;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
super.initGui();
|
||||
loadFrom(new ResourceLocation("webdisplays", "gui/screencfg.json"));
|
||||
|
||||
friendBoxes = new CheckBox[] { boxFResolution, boxFUpgrades, boxFOthers, boxFFriends, boxFClick, boxFSetUrl };
|
||||
boxFResolution.setUserdata(ScreenRights.CHANGE_RESOLUTION);
|
||||
boxFUpgrades.setUserdata(ScreenRights.MANAGE_UPGRADES);
|
||||
boxFOthers.setUserdata(ScreenRights.MANAGE_OTHER_RIGHTS);
|
||||
boxFFriends.setUserdata(ScreenRights.MANAGE_FRIEND_LIST);
|
||||
boxFClick.setUserdata(ScreenRights.CLICK);
|
||||
boxFSetUrl.setUserdata(ScreenRights.CHANGE_URL);
|
||||
|
||||
otherBoxes = new CheckBox[] { boxOResolution, boxOUpgrades, boxOClick, boxOSetUrl };
|
||||
boxOResolution.setUserdata(ScreenRights.CHANGE_RESOLUTION);
|
||||
boxOUpgrades.setUserdata(ScreenRights.MANAGE_UPGRADES);
|
||||
boxOClick.setUserdata(ScreenRights.CLICK);
|
||||
boxOSetUrl.setUserdata(ScreenRights.CHANGE_URL);
|
||||
|
||||
TileEntityScreen.Screen scr = tes.getScreen(side);
|
||||
if(scr != null) {
|
||||
tfResX.setText("" + scr.resolution.x);
|
||||
tfResY.setText("" + scr.resolution.y);
|
||||
}
|
||||
|
||||
lblOwner.setLabel(lblOwner.getLabel() + owner.name);
|
||||
for(NameUUIDPair f : friends)
|
||||
lstFriends.addElementRaw(f.name, f);
|
||||
|
||||
lstFriends.updateContent();
|
||||
updateRights(friendRights, friendRights, friendBoxes, true);
|
||||
updateRights(otherRights, otherRights, otherBoxes, true);
|
||||
updateMyRights();
|
||||
}
|
||||
|
||||
private void addFriend(String name) {
|
||||
if(!name.isEmpty()) {
|
||||
requestAutocomplete(name, true);
|
||||
tfFriend.setDisabled(true);
|
||||
adding = true;
|
||||
waitingAC = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void clickSetRes() {
|
||||
TileEntityScreen.Screen scr = tes.getScreen(side);
|
||||
if(scr == null)
|
||||
return; //WHATDAFUQ?
|
||||
|
||||
try {
|
||||
int x = Integer.parseInt(tfResX.getText());
|
||||
int y = Integer.parseInt(tfResY.getText());
|
||||
if(x < 1 || y < 1)
|
||||
throw new NumberFormatException(); //I'm lazy
|
||||
|
||||
if(x != scr.resolution.x || y != scr.resolution.y)
|
||||
WebDisplays.NET_HANDLER.sendToServer(new SMessageScreenCtrl(tes, side, new Vector2i(x, y)));
|
||||
} catch(NumberFormatException ex) {
|
||||
//Roll back
|
||||
tfResX.setText("" + scr.resolution.x);
|
||||
tfResY.setText("" + scr.resolution.y);
|
||||
}
|
||||
|
||||
btnSetRes.setDisabled(true);
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onClick(Button.ClickEvent ev) {
|
||||
if(ev.getSource() == btnAdd && !waitingAC)
|
||||
addFriend(tfFriend.getText().trim());
|
||||
else if(ev.getSource() == btnSetRes)
|
||||
clickSetRes();
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onEnterPressed(TextField.EnterPressedEvent ev) {
|
||||
if(ev.getSource() == tfFriend && !waitingAC)
|
||||
addFriend(ev.getText().trim());
|
||||
else if((ev.getSource() == tfResX || ev.getSource() == tfResY) && !btnSetRes.isDisabled())
|
||||
clickSetRes();
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onAutocomplete(TextField.TabPressedEvent ev) {
|
||||
if(ev.getSource() == tfFriend && !waitingAC && !ev.getBeginning().isEmpty()) {
|
||||
if(acResults.isEmpty()) {
|
||||
waitingAC = true;
|
||||
requestAutocomplete(ev.getBeginning(), false);
|
||||
} else {
|
||||
NameUUIDPair pair = acResults.remove(0);
|
||||
tfFriend.setText(pair.name);
|
||||
}
|
||||
} else if(ev.getSource() == tfResX) {
|
||||
tfResX.setFocused(false);
|
||||
tfResY.focus();
|
||||
tfResY.getMcField().setCursorPositionZero();
|
||||
tfResY.getMcField().setSelectionPos(tfResY.getText().length());
|
||||
}
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onTextChanged(TextField.TextChangedEvent ev) {
|
||||
if(ev.getSource() == tfResX || ev.getSource() == tfResY) {
|
||||
for(int i = 0; i < ev.getNewContent().length(); i++) {
|
||||
if(!Character.isDigit(ev.getNewContent().charAt(i))) {
|
||||
ev.getSource().setText(ev.getOldContent());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
btnSetRes.setDisabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onRemovePlayer(List.EntryClick ev) {
|
||||
if(ev.getSource() == lstFriends)
|
||||
WebDisplays.NET_HANDLER.sendToServer(new SMessageScreenCtrl(tes, side, (NameUUIDPair) ev.getUserdata(), true));
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onCheckboxChanged(CheckBox.CheckedEvent ev) {
|
||||
if(isFriendCheckbox(ev.getSource())) {
|
||||
int flag = (Integer) ev.getSource().getUserdata();
|
||||
if(ev.isChecked())
|
||||
friendRights |= flag;
|
||||
else
|
||||
friendRights &= ~flag;
|
||||
|
||||
requestSync();
|
||||
} else if(isOtherCheckbox(ev.getSource())) {
|
||||
int flag = (Integer) ev.getSource().getUserdata();
|
||||
if(ev.isChecked())
|
||||
otherRights |= flag;
|
||||
else
|
||||
otherRights &= ~flag;
|
||||
|
||||
requestSync();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFriendCheckbox(CheckBox cb) {
|
||||
for(CheckBox box : friendBoxes) {
|
||||
if(box == cb)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isOtherCheckbox(CheckBox cb) {
|
||||
for(CheckBox box : otherBoxes) {
|
||||
if(box == cb)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasFriend(NameUUIDPair f) {
|
||||
for(NameUUIDPair pair : friends) {
|
||||
if(pair.equals(f))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutocompleteResult(NameUUIDPair pairs[]) {
|
||||
waitingAC = false;
|
||||
|
||||
if(adding) {
|
||||
if(!hasFriend(pairs[0]))
|
||||
WebDisplays.NET_HANDLER.sendToServer(new SMessageScreenCtrl(tes, side, pairs[0], false));
|
||||
|
||||
tfFriend.setDisabled(false);
|
||||
tfFriend.clear();
|
||||
tfFriend.focus();
|
||||
adding = false;
|
||||
} else {
|
||||
acResults.clear();
|
||||
acResults.addAll(Arrays.asList(pairs));
|
||||
|
||||
NameUUIDPair pair = acResults.remove(0);
|
||||
tfFriend.setText(pair.name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutocompleteFailure() {
|
||||
waitingAC = false;
|
||||
acResults.clear();
|
||||
acFailTicks = 0;
|
||||
tfFriend.setTextColor(Control.COLOR_RED);
|
||||
|
||||
if(adding) {
|
||||
tfFriend.setDisabled(false);
|
||||
adding = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateScreen() {
|
||||
super.updateScreen();
|
||||
|
||||
if(acFailTicks >= 0) {
|
||||
if(++acFailTicks >= 10) {
|
||||
acFailTicks = -1;
|
||||
tfFriend.setTextColor(TextField.DEFAULT_TEXT_COLOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateFriends(NameUUIDPair[] friends) {
|
||||
boolean diff = false;
|
||||
if(friends.length != this.friends.length)
|
||||
diff = true;
|
||||
else {
|
||||
for(NameUUIDPair pair : friends) {
|
||||
if(!hasFriend(pair)) {
|
||||
diff = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(diff) {
|
||||
this.friends = friends;
|
||||
lstFriends.clearRaw();
|
||||
for(NameUUIDPair pair : friends)
|
||||
lstFriends.addElementRaw(pair.name, pair);
|
||||
|
||||
lstFriends.updateContent();
|
||||
}
|
||||
}
|
||||
|
||||
private int updateRights(int current, int newVal, CheckBox[] boxes, boolean force) {
|
||||
if(force || current != newVal) {
|
||||
for(CheckBox box : boxes) {
|
||||
int flag = (Integer) box.getUserdata();
|
||||
box.setChecked((newVal & flag) != 0);
|
||||
}
|
||||
|
||||
if(!force) {
|
||||
Log.info("Screen check boxes were updated");
|
||||
abortSync(); //Value changed by another user, abort modifications by local user
|
||||
}
|
||||
}
|
||||
|
||||
return newVal;
|
||||
}
|
||||
|
||||
public void updateFriendRights(int rights) {
|
||||
friendRights = updateRights(friendRights, rights, friendBoxes, false);
|
||||
}
|
||||
|
||||
public void updateOtherRights(int rights) {
|
||||
otherRights = updateRights(otherRights, rights, otherBoxes, false);
|
||||
}
|
||||
|
||||
public boolean isScreen(Vector3i pos, BlockSide side) {
|
||||
return pos.x == tes.getPos().getX() && pos.y == tes.getPos().getY() && pos.z == tes.getPos().getZ() && side == this.side;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sync() {
|
||||
WebDisplays.NET_HANDLER.sendToServer(new SMessageScreenCtrl(tes, side, friendRights, otherRights));
|
||||
Log.info("Sent sync packet");
|
||||
}
|
||||
|
||||
public void updateMyRights() {
|
||||
NameUUIDPair me = new NameUUIDPair(mc.player.getGameProfile());
|
||||
int myRights = 0;
|
||||
boolean clientIsOwner = false;
|
||||
|
||||
if(me.equals(owner)) {
|
||||
myRights = ScreenRights.ALL;
|
||||
clientIsOwner = true;
|
||||
} else if(hasFriend(me))
|
||||
myRights = friendRights;
|
||||
else
|
||||
myRights = otherRights;
|
||||
|
||||
//Disable components according to client rights
|
||||
grpFriends.setDisabled(!clientIsOwner);
|
||||
|
||||
boolean flag = (myRights & ScreenRights.MANAGE_FRIEND_LIST) == 0;
|
||||
lstFriends.setDisabled(flag);
|
||||
tfFriend.setDisabled(flag);
|
||||
btnAdd.setDisabled(flag);
|
||||
|
||||
flag = (myRights & ScreenRights.MANAGE_OTHER_RIGHTS) == 0;
|
||||
grpOthers.setDisabled(flag);
|
||||
|
||||
flag = (myRights & ScreenRights.CHANGE_RESOLUTION) == 0;
|
||||
tfResX.setDisabled(flag);
|
||||
tfResY.setDisabled(flag);
|
||||
|
||||
if(flag)
|
||||
btnSetRes.setDisabled(true);
|
||||
}
|
||||
|
||||
public void updateResolution(Vector2i res) {
|
||||
tfResX.setText("" + res.x);
|
||||
tfResY.setText("" + res.y);
|
||||
btnSetRes.setDisabled(true);
|
||||
}
|
||||
|
||||
}
|
||||
102
src/main/java/net/montoyo/wd/client/gui/GuiSetURL2.java
Normal file
102
src/main/java/net/montoyo/wd/client/gui/GuiSetURL2.java
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.gui.controls.Button;
|
||||
import net.montoyo.wd.client.gui.controls.TextField;
|
||||
import net.montoyo.wd.client.gui.loading.FillControl;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.net.SMessagePadCtrl;
|
||||
import net.montoyo.wd.net.SMessageScreenCtrl;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class GuiSetURL2 extends WDScreen {
|
||||
|
||||
//Screen data
|
||||
private TileEntityScreen tileEntity;
|
||||
private BlockSide screenSide;
|
||||
|
||||
//Pad data
|
||||
private boolean isPad;
|
||||
|
||||
//Common
|
||||
private String screenURL;
|
||||
|
||||
@FillControl
|
||||
private TextField tfURL;
|
||||
|
||||
@FillControl
|
||||
private Button btnShutDown;
|
||||
|
||||
@FillControl
|
||||
private Button btnCancel;
|
||||
|
||||
@FillControl
|
||||
private Button btnOk;
|
||||
|
||||
@FillControl
|
||||
private Button btnYT;
|
||||
|
||||
public GuiSetURL2(TileEntityScreen tes, BlockSide side, String url) {
|
||||
tileEntity = tes;
|
||||
screenSide = side;
|
||||
screenURL = url;
|
||||
isPad = false;
|
||||
}
|
||||
|
||||
public GuiSetURL2(String url) {
|
||||
screenURL = url;
|
||||
isPad = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
super.initGui();
|
||||
loadFrom(new ResourceLocation("webdisplays", "gui/seturl.json"));
|
||||
tfURL.setText(screenURL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addLoadCustomVariables(Map<String, Double> vars) {
|
||||
vars.put("isPad", isPad ? 1.0 : 0.0);
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onButtonClicked(Button.ClickEvent ev) {
|
||||
if(ev.getSource() == btnCancel)
|
||||
mc.displayGuiScreen(null);
|
||||
else if(ev.getSource() == btnOk)
|
||||
validate(tfURL.getText());
|
||||
else if(ev.getSource() == btnShutDown) {
|
||||
if(isPad)
|
||||
WebDisplays.NET_HANDLER.sendToServer(new SMessagePadCtrl(""));
|
||||
|
||||
mc.displayGuiScreen(null);
|
||||
} else
|
||||
Log.info("GuiSetURL2: TODO"); //TODO
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onEnterPressed(TextField.EnterPressedEvent ev) {
|
||||
validate(ev.getText());
|
||||
}
|
||||
|
||||
private void validate(String url) {
|
||||
if(!url.isEmpty()) {
|
||||
if(isPad)
|
||||
WebDisplays.NET_HANDLER.sendToServer(new SMessagePadCtrl(url));
|
||||
else
|
||||
WebDisplays.NET_HANDLER.sendToServer(new SMessageScreenCtrl(tileEntity, screenSide, url));
|
||||
}
|
||||
|
||||
mc.displayGuiScreen(null);
|
||||
}
|
||||
|
||||
}
|
||||
15
src/main/java/net/montoyo/wd/client/gui/GuiSubscribe.java
Normal file
15
src/main/java/net/montoyo/wd/client/gui/GuiSubscribe.java
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface GuiSubscribe {
|
||||
}
|
||||
353
src/main/java/net/montoyo/wd/client/gui/WDScreen.java
Normal file
353
src/main/java/net/montoyo/wd/client/gui/WDScreen.java
Normal file
|
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.gui.controls.Container;
|
||||
import net.montoyo.wd.client.gui.controls.Control;
|
||||
import net.montoyo.wd.client.gui.controls.Event;
|
||||
import net.montoyo.wd.client.gui.loading.FillControl;
|
||||
import net.montoyo.wd.client.gui.loading.GuiLoader;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
import net.montoyo.wd.net.SMessageACQuery;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
import net.montoyo.wd.utilities.NameUUIDPair;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class WDScreen extends GuiScreen {
|
||||
|
||||
public static WDScreen CURRENT_SCREEN = null;
|
||||
|
||||
protected ArrayList<Control> controls = new ArrayList<Control>();
|
||||
private HashMap<Class<? extends Event>, Method> eventMap = new HashMap<Class<? extends Event>, Method>();
|
||||
protected boolean quitOnEscape = true;
|
||||
protected boolean defaultBackground = true;
|
||||
protected int syncTicks = 40;
|
||||
private int syncTicksLeft = -1;
|
||||
|
||||
public WDScreen() {
|
||||
Method[] methods = getClass().getMethods();
|
||||
|
||||
for(Method m : methods) {
|
||||
if(m.getAnnotation(GuiSubscribe.class) != null) {
|
||||
if(!Modifier.isPublic(m.getModifiers()))
|
||||
throw new RuntimeException("Found non public @GuiSubscribe");
|
||||
|
||||
Class<?> params[] = m.getParameterTypes();
|
||||
if(params.length != 1 || !Event.class.isAssignableFrom(params[0]))
|
||||
throw new RuntimeException("Invalid parameters for @GuiSubscribe");
|
||||
|
||||
eventMap.put((Class<? extends Event>) params[0], m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected <T extends Control> T addControl(T ctrl) {
|
||||
controls.add(ctrl);
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
public int screen2DisplayX(int x) {
|
||||
double ret = ((double) x) / ((double) width) * ((double) mc.displayWidth);
|
||||
return (int) ret;
|
||||
}
|
||||
|
||||
public int screen2DisplayY(int y) {
|
||||
double ret = ((double) y) / ((double) height) * ((double) mc.displayHeight);
|
||||
return (int) ret;
|
||||
}
|
||||
|
||||
public int display2ScreenX(int x) {
|
||||
double ret = ((double) x) / ((double) mc.displayWidth) * ((double) width);
|
||||
return (int) ret;
|
||||
}
|
||||
|
||||
public int display2ScreenY(int y) {
|
||||
double ret = ((double) y) / ((double) mc.displayHeight) * ((double) height);
|
||||
return (int) ret;
|
||||
}
|
||||
|
||||
protected void centerControls() {
|
||||
//Determine bounding box
|
||||
int minX = Integer.MAX_VALUE;
|
||||
int minY = Integer.MAX_VALUE;
|
||||
int maxX = Integer.MIN_VALUE;
|
||||
int maxY = Integer.MIN_VALUE;
|
||||
|
||||
for(Control ctrl : controls) {
|
||||
int x = ctrl.getX();
|
||||
int y = ctrl.getY();
|
||||
if(x < minX)
|
||||
minX = x;
|
||||
|
||||
if(y < minY)
|
||||
minY = y;
|
||||
|
||||
x += ctrl.getWidth();
|
||||
y += ctrl.getHeight();
|
||||
|
||||
if(x > maxX)
|
||||
maxX = x;
|
||||
|
||||
if(y >= maxY)
|
||||
maxY = y;
|
||||
}
|
||||
|
||||
//Translation vector
|
||||
int diffX = (width - maxX - minX) / 2;
|
||||
int diffY = (height - maxY - minY) / 2;
|
||||
|
||||
//Translate controls
|
||||
for(Control ctrl : controls) {
|
||||
int x = ctrl.getX();
|
||||
int y = ctrl.getY();
|
||||
|
||||
ctrl.setPos(x + diffX, y + diffY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int mouseX, int mouseY, float ptt) {
|
||||
if(defaultBackground)
|
||||
drawDefaultBackground();
|
||||
|
||||
for(Control ctrl: controls)
|
||||
ctrl.draw(mouseX, mouseY, ptt);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void keyTyped(char typedChar, int keyCode) throws IOException {
|
||||
if(quitOnEscape && keyCode == Keyboard.KEY_ESCAPE) {
|
||||
mc.displayGuiScreen(null);
|
||||
return;
|
||||
}
|
||||
|
||||
for(Control ctrl: controls)
|
||||
ctrl.keyTyped(typedChar, keyCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
|
||||
for(Control ctrl: controls)
|
||||
ctrl.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseReleased(int mouseX, int mouseY, int state) {
|
||||
for(Control ctrl: controls)
|
||||
ctrl.mouseReleased(mouseX, mouseY, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) {
|
||||
for(Control ctrl: controls)
|
||||
ctrl.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
CURRENT_SCREEN = this;
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed() {
|
||||
if(syncTicksLeft >= 0) {
|
||||
sync();
|
||||
syncTicksLeft = -1;
|
||||
}
|
||||
|
||||
for(Control ctrl : controls)
|
||||
ctrl.destroy();
|
||||
|
||||
Keyboard.enableRepeatEvents(false);
|
||||
CURRENT_SCREEN = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMouseInput() throws IOException {
|
||||
super.handleMouseInput();
|
||||
|
||||
int x = Mouse.getEventX() * width / mc.displayWidth;
|
||||
int y = height - Mouse.getEventY() * height / mc.displayHeight - 1;
|
||||
int dw = Mouse.getEventDWheel();
|
||||
|
||||
if(dw != 0)
|
||||
onMouseScroll(x, y, dw);
|
||||
else if(Mouse.getEventButton() == -1)
|
||||
onMouseMove(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleKeyboardInput() throws IOException {
|
||||
super.handleKeyboardInput();
|
||||
|
||||
int key = Keyboard.getEventKey();
|
||||
if(key != Keyboard.KEY_NONE) {
|
||||
if(Keyboard.getEventKeyState()) {
|
||||
for(Control ctrl : controls)
|
||||
ctrl.keyDown(key);
|
||||
} else {
|
||||
for(Control ctrl : controls)
|
||||
ctrl.keyUp(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onMouseScroll(int mouseX, int mouseY, int amount) {
|
||||
for(Control ctrl : controls)
|
||||
ctrl.mouseScroll(mouseX, mouseY, amount);
|
||||
}
|
||||
|
||||
public void onMouseMove(int mouseX, int mouseY) {
|
||||
for(Control ctrl : controls)
|
||||
ctrl.mouseMove(mouseX, mouseY);
|
||||
}
|
||||
|
||||
public Object actionPerformed(Event ev) {
|
||||
Method m = eventMap.get(ev.getClass());
|
||||
|
||||
if(m != null) {
|
||||
try {
|
||||
return m.invoke(this, ev);
|
||||
} catch(IllegalAccessException e) {
|
||||
Log.errorEx("Access to event %s of screen %s is denied", e, ev.getClass().getSimpleName(), getClass().getSimpleName());
|
||||
} catch(InvocationTargetException e) {
|
||||
Log.errorEx("Event %s of screen %s failed", e, ev.getClass().getSimpleName(), getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T extends Control> T getControlByName(String name) {
|
||||
for(Control ctrl : controls) {
|
||||
if(name.equals(ctrl.getName()))
|
||||
return (T) ctrl;
|
||||
|
||||
if(ctrl instanceof Container) {
|
||||
Control ret = ((Container) ctrl).getByName(name);
|
||||
|
||||
if(ret != null)
|
||||
return (T) ret;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void addLoadCustomVariables(Map<String, Double> vars) {
|
||||
}
|
||||
|
||||
public void loadFrom(ResourceLocation resLoc) {
|
||||
JsonObject root = GuiLoader.getJson(resLoc);
|
||||
if(root == null)
|
||||
throw new RuntimeException("Could not load GUI file " + resLoc.toString());
|
||||
|
||||
if(!root.has("controls") || !root.get("controls").isJsonArray())
|
||||
throw new RuntimeException("In GUI file " + resLoc.toString() + ": missing root 'controls' object.");
|
||||
|
||||
HashMap<String, Double> vars = new HashMap<String, Double>();
|
||||
vars.put("width", (double) width);
|
||||
vars.put("height", (double) height);
|
||||
vars.put("displayWidth", (double) mc.displayWidth);
|
||||
vars.put("displayHeight", (double) mc.displayHeight);
|
||||
addLoadCustomVariables(vars);
|
||||
|
||||
JsonArray content = root.get("controls").getAsJsonArray();
|
||||
for(JsonElement elem: content)
|
||||
controls.add(GuiLoader.create(new JsonOWrapper(elem.getAsJsonObject(), vars)));
|
||||
|
||||
Field[] fields = getClass().getDeclaredFields();
|
||||
for(Field f: fields) {
|
||||
f.setAccessible(true);
|
||||
FillControl fc = f.getAnnotation(FillControl.class);
|
||||
|
||||
if(fc != null) {
|
||||
String name = fc.name().isEmpty() ? f.getName() : fc.name();
|
||||
Control ctrl = getControlByName(name);
|
||||
|
||||
if(ctrl == null) {
|
||||
if(fc.required())
|
||||
throw new RuntimeException("In GUI file " + resLoc.toString() + ": missing required control " + name);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!f.getType().isAssignableFrom(ctrl.getClass()))
|
||||
throw new RuntimeException("In GUI file " + resLoc.toString() + ": invalid type for control " + name);
|
||||
|
||||
try {
|
||||
f.set(this, ctrl);
|
||||
} catch(IllegalAccessException e) {
|
||||
if(fc.required())
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(root.has("center") && root.get("center").getAsBoolean())
|
||||
centerControls();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResize(Minecraft mcIn, int w, int h) {
|
||||
for(Control ctrl : controls)
|
||||
ctrl.destroy();
|
||||
|
||||
controls.clear();
|
||||
super.onResize(mcIn, w, h);
|
||||
}
|
||||
|
||||
protected void requestAutocomplete(String beginning, boolean matchExact) {
|
||||
WebDisplays.NET_HANDLER.sendToServer(new SMessageACQuery(beginning, matchExact));
|
||||
}
|
||||
|
||||
public void onAutocompleteResult(NameUUIDPair pairs[]) {
|
||||
}
|
||||
|
||||
public void onAutocompleteFailure() {
|
||||
}
|
||||
|
||||
protected void requestSync() {
|
||||
syncTicksLeft = syncTicks - 1;
|
||||
}
|
||||
|
||||
protected boolean syncRequested() {
|
||||
return syncTicksLeft >= 0;
|
||||
}
|
||||
|
||||
protected void abortSync() {
|
||||
syncTicksLeft = -1;
|
||||
}
|
||||
|
||||
protected void sync() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateScreen() {
|
||||
if(syncTicksLeft >= 0) {
|
||||
if(--syncTicksLeft < 0)
|
||||
sync();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui.controls;
|
||||
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
|
||||
public abstract class BasicControl extends Control {
|
||||
|
||||
protected int x;
|
||||
protected int y;
|
||||
protected boolean visible = true;
|
||||
protected boolean disabled = false;
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPos(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public boolean isDisabled() {
|
||||
return disabled;
|
||||
}
|
||||
|
||||
public void setDisabled(boolean disabled) {
|
||||
this.disabled = disabled;
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
disabled = false;
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
disabled = true;
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
public void setVisible(boolean visible) {
|
||||
this.visible = visible;
|
||||
}
|
||||
|
||||
public void show() {
|
||||
visible = true;
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
visible = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(JsonOWrapper json) {
|
||||
super.load(json);
|
||||
x = json.getInt("x", 0);
|
||||
y = json.getInt("y", 0);
|
||||
disabled = json.getBool("disabled", false);
|
||||
visible = json.getBool("visible", true);
|
||||
}
|
||||
|
||||
}
|
||||
199
src/main/java/net/montoyo/wd/client/gui/controls/Button.java
Normal file
199
src/main/java/net/montoyo/wd/client/gui/controls/Button.java
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui.controls;
|
||||
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Button extends Control {
|
||||
|
||||
private final GuiButton btn;
|
||||
private boolean selected = false;
|
||||
private boolean shiftDown = false;
|
||||
private int originalColor = 0;
|
||||
private int shiftColor = 0;
|
||||
|
||||
public static class ClickEvent extends Event<Button> {
|
||||
|
||||
private boolean shiftDown;
|
||||
|
||||
private ClickEvent(Button btn) {
|
||||
source = btn;
|
||||
shiftDown = btn.shiftDown;
|
||||
}
|
||||
|
||||
public boolean isShiftDown() {
|
||||
return shiftDown;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Button() {
|
||||
btn = new GuiButton(0, 0, 0, "");
|
||||
}
|
||||
|
||||
public Button(String text, int x, int y, int width) {
|
||||
btn = new GuiButton(0, x, y, width, 20, text);
|
||||
}
|
||||
|
||||
public Button(String text, int x, int y) {
|
||||
btn = new GuiButton(0, x, y, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
|
||||
if(mouseButton == 0 && btn.mousePressed(mc, mouseX, mouseY)) {
|
||||
selected = true;
|
||||
btn.playPressSound(mc.getSoundHandler());
|
||||
parent.actionPerformed(new ClickEvent(this));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(int mouseX, int mouseY, int state) {
|
||||
if(selected && state == 0) {
|
||||
btn.mouseReleased(mouseX, mouseY);
|
||||
selected = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mouseX, int mouseY, float ptt) {
|
||||
btn.drawButton(mc, mouseX, mouseY, ptt);
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
btn.displayString = label;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return btn.displayString;
|
||||
}
|
||||
|
||||
public void setWidth(int width) {
|
||||
btn.setWidth(width);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return btn.getButtonWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPos(int x, int y) {
|
||||
btn.x = x;
|
||||
btn.y = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return btn.x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY() {
|
||||
return btn.y;
|
||||
}
|
||||
|
||||
public GuiButton getMcButton() {
|
||||
return btn;
|
||||
}
|
||||
|
||||
public void setDisabled(boolean dis) {
|
||||
btn.enabled = !dis;
|
||||
}
|
||||
|
||||
public boolean isDisabled() {
|
||||
return !btn.enabled;
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
btn.enabled = true;
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
btn.enabled = false;
|
||||
}
|
||||
|
||||
public void setVisible(boolean visible) {
|
||||
btn.visible = visible;
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return btn.visible;
|
||||
}
|
||||
|
||||
public void show() {
|
||||
btn.visible = true;
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
btn.visible = false;
|
||||
}
|
||||
|
||||
public boolean isShiftDown() {
|
||||
return shiftDown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyUp(int key) {
|
||||
if(key == Keyboard.KEY_LSHIFT || key == Keyboard.KEY_RSHIFT) {
|
||||
shiftDown = false;
|
||||
btn.packedFGColour = originalColor;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyDown(int key) {
|
||||
if(key == Keyboard.KEY_LSHIFT || key == Keyboard.KEY_RSHIFT) {
|
||||
shiftDown = true;
|
||||
btn.packedFGColour = shiftColor;
|
||||
}
|
||||
}
|
||||
|
||||
public void setTextColor(int color) {
|
||||
originalColor = color;
|
||||
if(!shiftDown)
|
||||
btn.packedFGColour = color;
|
||||
}
|
||||
|
||||
public int getTextColor() {
|
||||
return btn.packedFGColour;
|
||||
}
|
||||
|
||||
public void setShiftTextColor(int shiftColor) {
|
||||
this.shiftColor = shiftColor;
|
||||
if(shiftDown)
|
||||
btn.packedFGColour = shiftColor;
|
||||
}
|
||||
|
||||
public int getShiftTextColor() {
|
||||
return shiftColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(JsonOWrapper json) {
|
||||
super.load(json);
|
||||
btn.x = json.getInt("x", 0);
|
||||
btn.y = json.getInt("y", 0);
|
||||
btn.width = json.getInt("width", 200);
|
||||
btn.displayString = tr(json.getString("label", ""));
|
||||
btn.enabled = !json.getBool("disabled", false);
|
||||
btn.visible = json.getBool("visible", true);
|
||||
|
||||
originalColor = json.getColor("color", 0);
|
||||
shiftColor = json.getColor("shiftColor", 0);
|
||||
btn.packedFGColour = originalColor;
|
||||
}
|
||||
|
||||
}
|
||||
120
src/main/java/net/montoyo/wd/client/gui/controls/CheckBox.java
Normal file
120
src/main/java/net/montoyo/wd/client/gui/controls/CheckBox.java
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui.controls;
|
||||
|
||||
import net.minecraft.client.audio.PositionedSoundRecord;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class CheckBox extends BasicControl {
|
||||
|
||||
private static final ResourceLocation texUnchecked = new ResourceLocation("webdisplays", "textures/gui/checkbox.png");
|
||||
private static final ResourceLocation texChecked = new ResourceLocation("webdisplays", "textures/gui/checkbox_checked.png");
|
||||
public static final int WIDTH = 16;
|
||||
public static final int HEIGHT = 16;
|
||||
|
||||
public static class CheckedEvent extends Event<CheckBox> {
|
||||
|
||||
private boolean checked;
|
||||
|
||||
private CheckedEvent(CheckBox cb) {
|
||||
source = cb;
|
||||
checked = cb.checked;
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return checked;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String label;
|
||||
private int labelW;
|
||||
private boolean checked;
|
||||
|
||||
public CheckBox() {
|
||||
label = "";
|
||||
}
|
||||
|
||||
public CheckBox(int x, int y, String label) {
|
||||
this.label = label;
|
||||
labelW = font.getStringWidth(label);
|
||||
checked = false;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public CheckBox(int x, int y, String label, boolean val) {
|
||||
this.label = label;
|
||||
labelW = font.getStringWidth(label);
|
||||
checked = val;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
|
||||
if(mouseButton == 0 && !disabled) {
|
||||
if(mouseX >= x && mouseX <= x + WIDTH + 2 + labelW && mouseY >= y && mouseY < y + HEIGHT) {
|
||||
checked = !checked;
|
||||
mc.getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(SoundEvents.UI_BUTTON_CLICK, 1.0F));
|
||||
parent.actionPerformed(new CheckedEvent(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mouseX, int mouseY, float ptt) {
|
||||
if(visible) {
|
||||
bindTexture(checked ? texChecked : texUnchecked);
|
||||
blend(true);
|
||||
fillTexturedRect(x, y, WIDTH, HEIGHT, 0.0, 0.0, 1.0, 1.0);
|
||||
blend(false);
|
||||
bindTexture(null);
|
||||
|
||||
boolean inside = (!disabled && mouseX >= x && mouseX <= x + WIDTH + 2 + labelW && mouseY >= y && mouseY < y + HEIGHT);
|
||||
font.drawString(label, x + WIDTH + 2, y + 4, inside ? 0xFF0080FF : COLOR_WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
labelW = font.getStringWidth(label);
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return checked;
|
||||
}
|
||||
|
||||
public void setChecked(boolean checked) {
|
||||
this.checked = checked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return WIDTH + 2 + labelW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return HEIGHT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(JsonOWrapper json) {
|
||||
super.load(json);
|
||||
label = tr(json.getString("label", ""));
|
||||
labelW = font.getStringWidth(label);
|
||||
checked = json.getBool("checked", false);
|
||||
}
|
||||
|
||||
}
|
||||
157
src/main/java/net/montoyo/wd/client/gui/controls/Container.java
Normal file
157
src/main/java/net/montoyo/wd/client/gui/controls/Container.java
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui.controls;
|
||||
|
||||
import net.montoyo.wd.client.gui.loading.GuiLoader;
|
||||
import net.montoyo.wd.client.gui.loading.JsonAWrapper;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public abstract class Container extends BasicControl {
|
||||
|
||||
protected int paddingX = 0;
|
||||
protected int paddingY = 0;
|
||||
protected ArrayList<Control> childs = new ArrayList<Control>();
|
||||
|
||||
public <T extends Control> T addControl(T ctrl) {
|
||||
childs.add(ctrl);
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(char typedChar, int keyCode) throws IOException {
|
||||
if(!disabled) {
|
||||
for(Control ctrl : childs)
|
||||
ctrl.keyTyped(typedChar, keyCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyUp(int key) {
|
||||
if(!disabled) {
|
||||
for(Control ctrl : childs)
|
||||
ctrl.keyUp(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyDown(int key) {
|
||||
if(!disabled) {
|
||||
for(Control ctrl : childs)
|
||||
ctrl.keyDown(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
|
||||
if(!disabled) {
|
||||
mouseX -= x + paddingX;
|
||||
mouseY -= y + paddingY;
|
||||
|
||||
for(Control ctrl : childs)
|
||||
ctrl.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(int mouseX, int mouseY, int state) {
|
||||
if(!disabled) {
|
||||
mouseX -= x + paddingX;
|
||||
mouseY -= y + paddingY;
|
||||
|
||||
for(Control ctrl : childs)
|
||||
ctrl.mouseReleased(mouseX, mouseY, state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) {
|
||||
if(!disabled) {
|
||||
mouseX -= x + paddingX;
|
||||
mouseY -= y + paddingY;
|
||||
|
||||
for(Control ctrl : childs)
|
||||
ctrl.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMove(int mouseX, int mouseY) {
|
||||
if(!disabled) {
|
||||
mouseX -= x + paddingX;
|
||||
mouseY -= y + paddingY;
|
||||
|
||||
for(Control ctrl : childs)
|
||||
ctrl.mouseMove(mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseScroll(int mouseX, int mouseY, int amount) {
|
||||
if(!disabled) {
|
||||
mouseX -= x + paddingX;
|
||||
mouseY -= y + paddingY;
|
||||
|
||||
for(Control ctrl : childs)
|
||||
ctrl.mouseScroll(mouseX, mouseY, amount);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mouseX, int mouseY, float ptt) {
|
||||
if(visible) {
|
||||
mouseX -= x + paddingX;
|
||||
mouseY -= y + paddingY;
|
||||
|
||||
GL11.glPushMatrix();
|
||||
GL11.glTranslated((double) (x + paddingX), (double) (y + paddingY), 0.0);
|
||||
|
||||
if(disabled) {
|
||||
for(Control ctrl : childs)
|
||||
ctrl.draw(-1, -1, ptt);
|
||||
} else {
|
||||
for(Control ctrl : childs)
|
||||
ctrl.draw(mouseX, mouseY, ptt);
|
||||
}
|
||||
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
for(Control ctrl : childs)
|
||||
ctrl.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(JsonOWrapper json) {
|
||||
super.load(json);
|
||||
|
||||
JsonAWrapper objs = json.getArray("childs");
|
||||
for(int i = 0; i < objs.size(); i++)
|
||||
childs.add(GuiLoader.create(objs.getObject(i)));
|
||||
}
|
||||
|
||||
public Control getByName(String name) {
|
||||
for(Control ctrl : childs) {
|
||||
if(name.equals(ctrl.name))
|
||||
return ctrl;
|
||||
|
||||
if(ctrl instanceof Container) {
|
||||
Control ret = ((Container) ctrl).getByName(name);
|
||||
|
||||
if(ret != null)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
249
src/main/java/net/montoyo/wd/client/gui/controls/Control.java
Normal file
249
src/main/java/net/montoyo/wd/client/gui/controls/Control.java
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui.controls;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.client.shader.Framebuffer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.montoyo.wd.client.gui.WDScreen;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
public abstract class Control {
|
||||
|
||||
public static final int COLOR_BLACK = 0xFF000000;
|
||||
public static final int COLOR_WHITE = 0xFFFFFFFF;
|
||||
public static final int COLOR_RED = 0xFFFF0000;
|
||||
public static final int COLOR_GREEN = 0xFF00FF00;
|
||||
public static final int COLOR_BLUE = 0xFF0000FF;
|
||||
public static final int COLOR_CYAN = 0xFF00FFFF;
|
||||
public static final int COLOR_MANGENTA = 0xFFFF00FF;
|
||||
public static final int COLOR_YELLOW = 0xFFFFFF00;
|
||||
|
||||
protected final Minecraft mc;
|
||||
protected final FontRenderer font;
|
||||
protected final Tessellator tessellator;
|
||||
protected final BufferBuilder vBuffer;
|
||||
protected final WDScreen parent;
|
||||
protected String name;
|
||||
protected Object userdata;
|
||||
|
||||
public Control() {
|
||||
mc = Minecraft.getMinecraft();
|
||||
font = mc.fontRenderer;
|
||||
tessellator = Tessellator.getInstance();
|
||||
vBuffer = tessellator.getBuffer();
|
||||
parent = WDScreen.CURRENT_SCREEN;
|
||||
}
|
||||
|
||||
public Object getUserdata() {
|
||||
return userdata;
|
||||
}
|
||||
|
||||
public void setUserdata(Object userdata) {
|
||||
this.userdata = userdata;
|
||||
}
|
||||
|
||||
public void keyTyped(char typedChar, int keyCode) throws IOException {
|
||||
}
|
||||
|
||||
public void keyUp(int key) {
|
||||
}
|
||||
|
||||
public void keyDown(int key) {
|
||||
}
|
||||
|
||||
public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
|
||||
}
|
||||
|
||||
public void mouseReleased(int mouseX, int mouseY, int state) {
|
||||
}
|
||||
|
||||
public void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) {
|
||||
}
|
||||
|
||||
public void mouseMove(int mouseX, int mouseY) {
|
||||
}
|
||||
|
||||
public void mouseScroll(int mouseX, int mouseY, int amount) {
|
||||
}
|
||||
|
||||
public void draw(int mouseX, int mouseY, float ptt) {
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
public WDScreen getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public abstract int getX();
|
||||
public abstract int getY();
|
||||
public abstract int getWidth();
|
||||
public abstract int getHeight();
|
||||
public abstract void setPos(int x, int y);
|
||||
|
||||
public void fillRect(int x, int y, int w, int h, int color) {
|
||||
double x1 = (double) x;
|
||||
double y1 = (double) y;
|
||||
double x2 = (double) (x + w);
|
||||
double y2 = (double) (y + h);
|
||||
int a = (color >> 24) & 0xFF;
|
||||
int r = (color >> 16) & 0xFF;
|
||||
int g = (color >> 8 ) & 0xFF;
|
||||
int b = color & 0xFF;
|
||||
|
||||
glColor4f(((float) r) / 255.f, ((float) g) / 255.f, ((float) b) / 255.f, ((float) a) / 255.f);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
vBuffer.begin(GL_QUADS, DefaultVertexFormats.POSITION);
|
||||
vBuffer.pos(x1, y2, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y2, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y1, 0.0).endVertex();
|
||||
vBuffer.pos(x1, y1, 0.0).endVertex();
|
||||
tessellator.draw();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
public void fillTexturedRect(int x, int y, int w, int h, double u1, double v1, double u2, double v2) {
|
||||
double x1 = (double) x;
|
||||
double y1 = (double) y;
|
||||
double x2 = (double) (x + w);
|
||||
double y2 = (double) (y + h);
|
||||
|
||||
vBuffer.begin(GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
|
||||
vBuffer.pos(x1, y2, 0.0).tex(u1, v2).color(255, 255, 255, 255).endVertex();
|
||||
vBuffer.pos(x2, y2, 0.0).tex(u2, v2).color(255, 255, 255, 255).endVertex();
|
||||
vBuffer.pos(x2, y1, 0.0).tex(u2, v1).color(255, 255, 255, 255).endVertex();
|
||||
vBuffer.pos(x1, y1, 0.0).tex(u1, v1).color(255, 255, 255, 255).endVertex();
|
||||
tessellator.draw();
|
||||
}
|
||||
|
||||
public static void blend(boolean enable) {
|
||||
if(enable) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
} else
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
public void bindTexture(ResourceLocation resLoc) {
|
||||
if(resLoc == null)
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
else
|
||||
mc.renderEngine.bindTexture(resLoc);
|
||||
}
|
||||
|
||||
public void drawBorder(int x, int y, int w, int h, int color) {
|
||||
drawBorder(x, y, w, h, color, 1.0);
|
||||
}
|
||||
|
||||
public void drawBorder(int x, int y, int w, int h, int color, double sz) {
|
||||
double x1 = (double) x;
|
||||
double y1 = (double) y;
|
||||
double x2 = (double) (x + w);
|
||||
double y2 = (double) (y + h);
|
||||
int a = (color >> 24) & 0xFF;
|
||||
int r = (color >> 16) & 0xFF;
|
||||
int g = (color >> 8 ) & 0xFF;
|
||||
int b = color & 0xFF;
|
||||
|
||||
glColor4f(((float) r) / 255.f, ((float) g) / 255.f, ((float) b) / 255.f, ((float) a) / 255.f);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
vBuffer.begin(GL_QUADS, DefaultVertexFormats.POSITION);
|
||||
//Top edge (y = y1)
|
||||
vBuffer.pos(x1, y1 + sz, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y1 + sz, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y1, 0.0).endVertex();
|
||||
vBuffer.pos(x1, y1, 0.0).endVertex();
|
||||
|
||||
//Bottom edge (y = y2)
|
||||
vBuffer.pos(x1, y2, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y2, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y2 - sz, 0.0).endVertex();
|
||||
vBuffer.pos(x1, y2 - sz, 0.0).endVertex();
|
||||
|
||||
//Left edge (x = x1)
|
||||
vBuffer.pos(x1, y2, 0.0).endVertex();
|
||||
vBuffer.pos(x1 + sz, y2, 0.0).endVertex();
|
||||
vBuffer.pos(x1 + sz, y1, 0.0).endVertex();
|
||||
vBuffer.pos(x1, y1, 0.0).endVertex();
|
||||
|
||||
//Right edge (x = x2)
|
||||
vBuffer.pos(x2 - sz, y2, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y2, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y1, 0.0).endVertex();
|
||||
vBuffer.pos(x2 - sz, y1, 0.0).endVertex();
|
||||
tessellator.draw();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
public void beginFramebuffer(Framebuffer fbo, int vpW, int vpH) {
|
||||
fbo.bindFramebuffer(true);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0, (double) vpW, (double) vpH, 0.0, -1.0,1.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
if(!fbo.useDepth)
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
public void endFramebuffer(Framebuffer fbo) {
|
||||
if(!fbo.useDepth)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
fbo.unbindFramebuffer();
|
||||
mc.getFramebuffer().bindFramebuffer(true);
|
||||
}
|
||||
|
||||
public static String tr(String text) {
|
||||
if(text.length() >= 2 && text.charAt(0) == '$') {
|
||||
if(text.charAt(1) == '$')
|
||||
return text.substring(1);
|
||||
else
|
||||
return I18n.format(text.substring(1));
|
||||
} else
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void load(JsonOWrapper json) {
|
||||
name = json.getString("name", "");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui.controls;
|
||||
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
public class ControlGroup extends Container {
|
||||
|
||||
private int width;
|
||||
private int height;
|
||||
private String label;
|
||||
private int labelW;
|
||||
private int labelColor = COLOR_WHITE;
|
||||
private boolean labelShadowed = true;
|
||||
|
||||
public ControlGroup() {
|
||||
width = 100;
|
||||
height = 100;
|
||||
label = "";
|
||||
paddingX = 8;
|
||||
paddingY = 8;
|
||||
}
|
||||
|
||||
public ControlGroup(int x, int y, int w, int h) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
width = w;
|
||||
height = h;
|
||||
paddingX = 8;
|
||||
paddingY = 8;
|
||||
label = "";
|
||||
labelW = 0;
|
||||
}
|
||||
|
||||
public ControlGroup(int x, int y, int w, int h, String label) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
width = w;
|
||||
height = h;
|
||||
this.label = label;
|
||||
this.labelW = font.getStringWidth(label);
|
||||
paddingX = 8;
|
||||
paddingY = 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setSize(int w, int h) {
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
labelW = font.getStringWidth(label);
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public int getLabelColor() {
|
||||
return labelColor;
|
||||
}
|
||||
|
||||
public void setLabelColor(int labelColor) {
|
||||
this.labelColor = labelColor;
|
||||
}
|
||||
|
||||
public boolean isLabelShadowed() {
|
||||
return labelShadowed;
|
||||
}
|
||||
|
||||
public void setLabelShadowed(boolean labelShadowed) {
|
||||
this.labelShadowed = labelShadowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mouseX, int mouseY, float ptt) {
|
||||
super.draw(mouseX, mouseY, ptt);
|
||||
|
||||
if(visible) {
|
||||
glColor4f(0.5f, 0.5f, 0.5f, 1.f);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
double x1 = (double) x;
|
||||
double y1 = (double) y;
|
||||
double x2 = (double) (x + width);
|
||||
double y2 = (double) (y + height);
|
||||
double bp = 4.0;
|
||||
double lw = (double) labelW;
|
||||
|
||||
x1 += bp;
|
||||
y1 += bp;
|
||||
x2 -= bp;
|
||||
y2 -= bp;
|
||||
lw += 12.0;
|
||||
|
||||
vBuffer.begin(GL_QUADS, DefaultVertexFormats.POSITION);
|
||||
|
||||
//Top edge (y = y1)
|
||||
if(labelW == 0) {
|
||||
vBuffer.pos(x1, y1 + 1.0, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y1 + 1.0, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y1, 0.0).endVertex();
|
||||
vBuffer.pos(x1, y1, 0.0).endVertex();
|
||||
} else {
|
||||
//Left
|
||||
vBuffer.pos(x1, y1 + 1.0, 0.0).endVertex();
|
||||
vBuffer.pos(x1 + 8.0, y1 + 1.0, 0.0).endVertex();
|
||||
vBuffer.pos(x1 + 8.0, y1, 0.0).endVertex();
|
||||
vBuffer.pos(x1, y1, 0.0).endVertex();
|
||||
|
||||
//Right
|
||||
vBuffer.pos(x1 + lw, y1 + 1.0, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y1 + 1.0, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y1, 0.0).endVertex();
|
||||
vBuffer.pos(x1 + lw, y1, 0.0).endVertex();
|
||||
}
|
||||
|
||||
//Bottom edge (y = y2)
|
||||
vBuffer.pos(x1, y2, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y2, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y2 - 1.0, 0.0).endVertex();
|
||||
vBuffer.pos(x1, y2 - 1.0, 0.0).endVertex();
|
||||
|
||||
//Left edge (x = x1)
|
||||
vBuffer.pos(x1, y2, 0.0).endVertex();
|
||||
vBuffer.pos(x1 + 1.0, y2, 0.0).endVertex();
|
||||
vBuffer.pos(x1 + 1.0, y1, 0.0).endVertex();
|
||||
vBuffer.pos(x1, y1, 0.0).endVertex();
|
||||
|
||||
//Right edge (x = x2)
|
||||
vBuffer.pos(x2 - 1.0, y2, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y2, 0.0).endVertex();
|
||||
vBuffer.pos(x2, y1, 0.0).endVertex();
|
||||
vBuffer.pos(x2 - 1.0, y1, 0.0).endVertex();
|
||||
tessellator.draw();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
if(labelW != 0)
|
||||
font.drawString(label, x + 10 + ((int) bp), y, labelColor, labelShadowed);
|
||||
}
|
||||
}
|
||||
|
||||
public void pack() {
|
||||
int minX = Integer.MAX_VALUE;
|
||||
int minY = Integer.MAX_VALUE;
|
||||
int maxX = Integer.MIN_VALUE;
|
||||
int maxY = Integer.MIN_VALUE;
|
||||
|
||||
for(Control ctrl : childs) {
|
||||
int x = ctrl.getX();
|
||||
int y = ctrl.getY();
|
||||
if(x < minX)
|
||||
minX = x;
|
||||
|
||||
if(y < minY)
|
||||
minY = y;
|
||||
|
||||
x += ctrl.getWidth();
|
||||
y += ctrl.getHeight();
|
||||
|
||||
if(x > maxX)
|
||||
maxX = x;
|
||||
|
||||
if(y >= maxY)
|
||||
maxY = y;
|
||||
}
|
||||
|
||||
for(Control ctrl : childs)
|
||||
ctrl.setPos(ctrl.getX() - minX, ctrl.getY() - minY);
|
||||
|
||||
maxX -= minX;
|
||||
maxY -= minY;
|
||||
width = maxX + paddingX * 2;
|
||||
height = maxY + paddingY * 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(JsonOWrapper json) {
|
||||
super.load(json);
|
||||
width = json.getInt("width", 100);
|
||||
height = json.getInt("height", 100);
|
||||
label = tr(json.getString("label", ""));
|
||||
labelW = font.getStringWidth(label);
|
||||
labelColor = json.getColor("labelColor", COLOR_WHITE);
|
||||
labelShadowed = json.getBool("labelShadowed", true);
|
||||
|
||||
if(json.getBool("pack", false))
|
||||
pack();
|
||||
}
|
||||
|
||||
}
|
||||
15
src/main/java/net/montoyo/wd/client/gui/controls/Event.java
Normal file
15
src/main/java/net/montoyo/wd/client/gui/controls/Event.java
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui.controls;
|
||||
|
||||
public abstract class Event<T extends Control> {
|
||||
|
||||
protected T source;
|
||||
|
||||
public T getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
}
|
||||
98
src/main/java/net/montoyo/wd/client/gui/controls/Label.java
Normal file
98
src/main/java/net/montoyo/wd/client/gui/controls/Label.java
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui.controls;
|
||||
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
|
||||
public class Label extends BasicControl {
|
||||
|
||||
private String label;
|
||||
private int labelW;
|
||||
private int color;
|
||||
private boolean shadowed;
|
||||
|
||||
public Label() {
|
||||
label = "";
|
||||
color = COLOR_WHITE;
|
||||
}
|
||||
|
||||
public Label(int x, int y, String str) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
label = str;
|
||||
labelW = font.getStringWidth(str);
|
||||
color = COLOR_WHITE;
|
||||
shadowed = false;
|
||||
}
|
||||
|
||||
public Label(int x, int y, String str, int color) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
label = str;
|
||||
labelW = font.getStringWidth(str);
|
||||
this.color = color;
|
||||
shadowed = false;
|
||||
}
|
||||
|
||||
public Label(int x, int y, String str, int color, boolean shadowed) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
label = str;
|
||||
labelW = font.getStringWidth(str);
|
||||
this.color = color;
|
||||
this.shadowed = shadowed;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
labelW = font.getStringWidth(label);
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public void setColor(int color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setShadowed(boolean shadowed) {
|
||||
this.shadowed = shadowed;
|
||||
}
|
||||
|
||||
public boolean isShadowed() {
|
||||
return shadowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mouseX, int mouseY, float ptt) {
|
||||
if(visible)
|
||||
font.drawString(label, x, y, color, shadowed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return labelW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return 12;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(JsonOWrapper json) {
|
||||
super.load(json);
|
||||
label = tr(json.getString("label", ""));
|
||||
labelW = font.getStringWidth(label);
|
||||
color = json.getColor("color", COLOR_WHITE);
|
||||
shadowed = json.getBool("shadowed", false);
|
||||
}
|
||||
|
||||
}
|
||||
384
src/main/java/net/montoyo/wd/client/gui/controls/List.java
Normal file
384
src/main/java/net/montoyo/wd/client/gui/controls/List.java
Normal file
|
|
@ -0,0 +1,384 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui.controls;
|
||||
|
||||
import net.minecraft.client.shader.Framebuffer;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
public class List extends BasicControl {
|
||||
|
||||
private static class Entry {
|
||||
public String text;
|
||||
public Object userdata;
|
||||
|
||||
public Entry(String t, Object o) {
|
||||
text = t;
|
||||
userdata = o;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class EntryClick extends Event<List> {
|
||||
|
||||
private int id;
|
||||
private Entry entry;
|
||||
|
||||
private EntryClick(List lst) {
|
||||
source = lst;
|
||||
id = lst.selected;
|
||||
entry = lst.content.get(lst.selected);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return entry.text;
|
||||
}
|
||||
|
||||
public Object getUserdata() {
|
||||
return entry.userdata;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int width;
|
||||
private int height;
|
||||
private ArrayList<Entry> content = new ArrayList<Entry>();
|
||||
private Framebuffer fbo;
|
||||
private int selected = -1;
|
||||
private boolean update;
|
||||
private int selColor = 0xFF0080FF;
|
||||
|
||||
//Scroll handling
|
||||
private int contentH = 0;
|
||||
private int scrollSize;
|
||||
private int scrollPos = 0;
|
||||
private boolean scrolling = false;
|
||||
private int scrollGrab;
|
||||
|
||||
public List() {
|
||||
}
|
||||
|
||||
public List(int x, int y, int w, int h) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
width = w;
|
||||
height = h;
|
||||
scrollSize = h - 2;
|
||||
createFBO();
|
||||
}
|
||||
|
||||
private int getYOffset() {
|
||||
double amount = ((double) scrollPos) / ((double) (height - 2 - scrollSize)) * ((double) (contentH - height));
|
||||
return (int) amount;
|
||||
}
|
||||
|
||||
private boolean isInScrollbar(int mouseX, int mouseY) {
|
||||
return mouseX >= x + width - 5 && mouseX <= x + width - 1 && mouseY >= y + 1 + scrollPos && mouseY <= y + 1 + scrollPos + scrollSize;
|
||||
}
|
||||
|
||||
private void createFBO() {
|
||||
if(fbo != null)
|
||||
fbo.deleteFramebuffer();
|
||||
|
||||
fbo = new Framebuffer(parent.screen2DisplayX(width), parent.screen2DisplayY(height), false);
|
||||
fbo.setFramebufferFilter(GL_NEAREST);
|
||||
fbo.bindFramebuffer(false);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.f); //Set alpha to 1
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
fbo.unbindFramebuffer();
|
||||
update = true;
|
||||
}
|
||||
|
||||
private void renderToFBO() {
|
||||
beginFramebuffer(fbo, width, height);
|
||||
fillRect(0, 0, width, height, COLOR_BLACK);
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
int offset = 4 - getYOffset();
|
||||
for(int i = 0; i < content.size(); i++) {
|
||||
int pos = i * 12 + offset;
|
||||
|
||||
if(pos + 12 >= 1) {
|
||||
if(pos >= height - 1)
|
||||
break;
|
||||
|
||||
int color = (i == selected) ? selColor : COLOR_WHITE;
|
||||
font.drawString(content.get(i).text, 4, i * 12 + offset, color);
|
||||
}
|
||||
}
|
||||
|
||||
drawBorder(0, 0, width, height, 0xFF808080);
|
||||
endFramebuffer(fbo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
if(fbo != null)
|
||||
fbo.deleteFramebuffer();
|
||||
}
|
||||
|
||||
public void setSize(int w, int h) {
|
||||
width = w;
|
||||
height = h;
|
||||
createFBO();
|
||||
}
|
||||
|
||||
public void setWidth(int width) {
|
||||
this.width = width;
|
||||
createFBO();
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
this.height = height;
|
||||
createFBO();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void updateContent() {
|
||||
contentH = content.size() * 12 + 4;
|
||||
|
||||
int h2 = height - 2;
|
||||
if(contentH <= h2) {
|
||||
scrollSize = h2;
|
||||
scrollPos = 0;
|
||||
} else {
|
||||
scrollSize = h2 * h2 / contentH;
|
||||
|
||||
if(scrollSize < 4)
|
||||
scrollSize = 4;
|
||||
}
|
||||
|
||||
update = true;
|
||||
}
|
||||
|
||||
public int addElement(String str) {
|
||||
return addElement(str, null);
|
||||
}
|
||||
|
||||
public int addElement(String str, Object ud) {
|
||||
content.add(new Entry(str, ud));
|
||||
updateContent();
|
||||
return content.size() - 1;
|
||||
}
|
||||
|
||||
public int addElementRaw(String str) {
|
||||
return addElement(str, null);
|
||||
}
|
||||
|
||||
public int addElementRaw(String str, Object ud) {
|
||||
content.add(new Entry(str, ud));
|
||||
return content.size() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisabled(boolean dis) {
|
||||
disabled = dis;
|
||||
|
||||
if(dis) {
|
||||
selected = -1;
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
disabled = true;
|
||||
selected = -1;
|
||||
update = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMove(int mouseX, int mouseY) {
|
||||
int sel = -1;
|
||||
if(!disabled && mouseX >= x + 1 && mouseX <= x + width - 6 && mouseY >= y + 2 && mouseY <= y + height - 2) {
|
||||
int offset = y + 4 - getYOffset();
|
||||
sel = (mouseY - offset) / 12;
|
||||
|
||||
if(sel < 0 || sel >= content.size())
|
||||
sel = -1;
|
||||
}
|
||||
|
||||
if(selected != sel) {
|
||||
selected = sel;
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
|
||||
if(!disabled && mouseButton == 0) {
|
||||
if(isInScrollbar(mouseX, mouseY)) {
|
||||
scrolling = true;
|
||||
scrollGrab = mouseY - (y + 1 + scrollPos);
|
||||
} else if(selected >= 0)
|
||||
parent.actionPerformed(new EntryClick(this));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(int mouseX, int mouseY, int state) {
|
||||
if(!disabled && scrolling)
|
||||
scrolling = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseScroll(int mouseX, int mouseY, int amount) {
|
||||
if(!disabled && !scrolling && mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height) {
|
||||
double disp = 12.d * ((double) (height - 2 - scrollSize)) / ((double) (contentH - height));
|
||||
int sp = scrollPos;
|
||||
|
||||
if(amount < 0)
|
||||
sp += (int) disp;
|
||||
else
|
||||
sp -= (int) disp;
|
||||
|
||||
if(sp < 0)
|
||||
sp = 0;
|
||||
else if(sp > height - 2 - scrollSize)
|
||||
sp = height - 2 - scrollSize;
|
||||
|
||||
if(sp != scrollPos) {
|
||||
scrollPos = sp;
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) {
|
||||
if(!disabled && scrolling) {
|
||||
int sp = mouseY - scrollGrab - y - 1;
|
||||
if(sp < 0)
|
||||
sp = 0;
|
||||
else if(sp > height - 2 - scrollSize)
|
||||
sp = height - 2 - scrollSize;
|
||||
|
||||
if(scrollPos != sp) {
|
||||
scrollPos = sp;
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mouseX, int mouseY, float ptt) {
|
||||
if(visible) {
|
||||
if(update) {
|
||||
renderToFBO();
|
||||
update = false;
|
||||
}
|
||||
|
||||
fbo.bindFramebufferTexture();
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f);
|
||||
fillTexturedRect(x, y, width, height, 0.0, 1.0, 1.0, 0.0);
|
||||
fbo.unbindFramebufferTexture();
|
||||
|
||||
fillRect(x + width - 5, y + 1 + scrollPos, 4, scrollSize, (scrolling || isInScrollbar(mouseX, mouseY)) ? 0xFF202020 : 0xFF404040);
|
||||
}
|
||||
}
|
||||
|
||||
public String getEntryLabel(int id) {
|
||||
return content.get(id).text;
|
||||
}
|
||||
|
||||
public Object getEntryUserdata(int id) {
|
||||
return content.get(id).userdata;
|
||||
}
|
||||
|
||||
public int findEntryByLabel(String label) {
|
||||
for(int i = 0; i < content.size(); i++) {
|
||||
if(content.get(i).text.equals(label))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int findEntryByUserdata(Object o) {
|
||||
if(o == null) {
|
||||
for(int i = 0; i < content.size(); i++) {
|
||||
if(content.get(i).userdata == null)
|
||||
return i;
|
||||
}
|
||||
} else {
|
||||
for(int i = 0; i < content.size(); i++) {
|
||||
if(content.get(i).userdata != null && content.get(i).userdata.equals(o))
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void setSelectionColor(int selColor) {
|
||||
this.selColor = selColor;
|
||||
}
|
||||
|
||||
public int getSelectionColor() {
|
||||
return selColor;
|
||||
}
|
||||
|
||||
public int getElementCount() {
|
||||
return content.size();
|
||||
}
|
||||
|
||||
public void removeElement(int id) {
|
||||
if(selected != -1 && id == content.size() - 1)
|
||||
selected = -1;
|
||||
|
||||
content.remove(id);
|
||||
updateContent();
|
||||
}
|
||||
|
||||
public void removeElementRaw(int id) {
|
||||
if(selected != -1 && id == content.size() - 1)
|
||||
selected = -1;
|
||||
|
||||
content.remove(id);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
content.clear();
|
||||
scrollPos = 0;
|
||||
scrolling = false;
|
||||
scrollSize = height - 2;
|
||||
selected = -1;
|
||||
update = true;
|
||||
}
|
||||
|
||||
public void clearRaw() {
|
||||
content.clear();
|
||||
scrollPos = 0;
|
||||
scrolling = false;
|
||||
selected = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(JsonOWrapper json) {
|
||||
super.load(json);
|
||||
width = json.getInt("width", 100);
|
||||
height = json.getInt("height", 100);
|
||||
selColor = json.getColor("selectionColor", 0xFF0080FF);
|
||||
createFBO();
|
||||
}
|
||||
|
||||
}
|
||||
281
src/main/java/net/montoyo/wd/client/gui/controls/TextField.java
Normal file
281
src/main/java/net/montoyo/wd/client/gui/controls/TextField.java
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui.controls;
|
||||
|
||||
import net.minecraft.client.gui.GuiTextField;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TextField extends Control {
|
||||
|
||||
public static class EnterPressedEvent extends Event<TextField> {
|
||||
|
||||
private String text;
|
||||
|
||||
private EnterPressedEvent(TextField field) {
|
||||
source = field;
|
||||
text = field.field.getText();
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TabPressedEvent extends Event<TextField> {
|
||||
|
||||
private String beginning;
|
||||
|
||||
private TabPressedEvent(TextField field) {
|
||||
source = field;
|
||||
|
||||
String text = field.field.getText();
|
||||
int max = field.field.getCursorPosition();
|
||||
int spacePos = 0;
|
||||
|
||||
for(int i = max - 1; i >= 0; i--) {
|
||||
if(Character.isSpaceChar(text.charAt(i))) {
|
||||
spacePos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
beginning = text.substring(spacePos, max).trim();
|
||||
}
|
||||
|
||||
public String getBeginning() {
|
||||
return beginning;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TextChangedEvent extends Event<TextField> {
|
||||
|
||||
private String oldContent;
|
||||
private String newContent;
|
||||
|
||||
private TextChangedEvent(TextField tf, String old) {
|
||||
source = tf;
|
||||
oldContent = old;
|
||||
newContent = tf.field.getText();
|
||||
}
|
||||
|
||||
public String getOldContent() {
|
||||
return oldContent;
|
||||
}
|
||||
|
||||
public String getNewContent() {
|
||||
return newContent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final int DEFAULT_TEXT_COLOR = 14737632;
|
||||
public static final int DEFAULT_DISABLED_COLOR = 7368816;
|
||||
|
||||
private final GuiTextField field;
|
||||
private boolean enabled = true;
|
||||
private int textColor = DEFAULT_TEXT_COLOR;
|
||||
private int disabledColor = DEFAULT_DISABLED_COLOR;
|
||||
|
||||
public TextField() {
|
||||
field = new GuiTextField(0, font, 1, 1, 198, 20);
|
||||
}
|
||||
|
||||
public TextField(int x, int y, int width, int height) {
|
||||
field = new GuiTextField(0, font, x + 1, y + 1, width - 2, height - 2);
|
||||
}
|
||||
|
||||
public TextField(int x, int y, int width, int height, String text) {
|
||||
field = new GuiTextField(0, font, x + 1, y + 1, width - 2, height - 2);
|
||||
field.setText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(char typedChar, int keyCode) throws IOException {
|
||||
if(keyCode == Keyboard.KEY_RETURN || keyCode == Keyboard.KEY_NUMPADENTER)
|
||||
parent.actionPerformed(new EnterPressedEvent(this));
|
||||
else if(keyCode == Keyboard.KEY_TAB)
|
||||
parent.actionPerformed(new TabPressedEvent(this));
|
||||
else {
|
||||
String old;
|
||||
if(enabled && field.isFocused())
|
||||
old = field.getText();
|
||||
else
|
||||
old = null;
|
||||
|
||||
field.textboxKeyTyped(typedChar, keyCode);
|
||||
|
||||
if(enabled && field.isFocused() && !field.getText().equals(old))
|
||||
parent.actionPerformed(new TextChangedEvent(this, old));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
|
||||
field.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mouseX, int mouseY, float ptt) {
|
||||
field.drawTextBox();
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
field.setText(text);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
field.setText("");
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return field.getText();
|
||||
}
|
||||
|
||||
public String getSelectedText() {
|
||||
return field.getSelectedText();
|
||||
}
|
||||
|
||||
public void setWidth(int width) {
|
||||
field.width = width - 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return field.width + 2;
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
field.height = height - 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return field.height + 2;
|
||||
}
|
||||
|
||||
public void setSize(int w, int h) {
|
||||
field.width = w - 2;
|
||||
field.height = h - 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPos(int x, int y) {
|
||||
field.x = x + 1;
|
||||
field.y = y + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return field.x - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY() {
|
||||
return field.y - 1;
|
||||
}
|
||||
|
||||
public void setDisabled(boolean en) {
|
||||
enabled = !en;
|
||||
field.setEnabled(enabled);
|
||||
}
|
||||
|
||||
public boolean isDisabled() {
|
||||
return !enabled;
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
field.setEnabled(true);
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
field.setEnabled(false);
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
public void setVisible(boolean vi) {
|
||||
field.setVisible(vi);
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return field.getVisible();
|
||||
}
|
||||
|
||||
public void show() {
|
||||
field.setVisible(true);
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
field.setVisible(false);
|
||||
}
|
||||
|
||||
public void setFocused(boolean val) {
|
||||
field.setFocused(val);
|
||||
}
|
||||
|
||||
public boolean hasFocus() {
|
||||
return field.isFocused();
|
||||
}
|
||||
|
||||
public void focus() {
|
||||
field.setFocused(true);
|
||||
}
|
||||
|
||||
public void setMaxLength(int len) {
|
||||
field.setMaxStringLength(len);
|
||||
}
|
||||
|
||||
public int getMaxLength() {
|
||||
return field.getMaxStringLength();
|
||||
}
|
||||
|
||||
public void setTextColor(int color) {
|
||||
field.setTextColor(color);
|
||||
textColor = color;
|
||||
}
|
||||
|
||||
public int getTextColor() {
|
||||
return textColor;
|
||||
}
|
||||
|
||||
public void setDisabledTextColor(int color) {
|
||||
field.setDisabledTextColour(color);
|
||||
disabledColor = color;
|
||||
}
|
||||
|
||||
public int getDisabledTextColor() {
|
||||
return disabledColor;
|
||||
}
|
||||
|
||||
public GuiTextField getMcField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(JsonOWrapper json) {
|
||||
super.load(json);
|
||||
field.x = json.getInt("x", 0) + 1;
|
||||
field.y = json.getInt("y", 0) + 1;
|
||||
field.width = json.getInt("width", 200) - 2;
|
||||
field.height = json.getInt("height", 22) - 2;
|
||||
field.setText(tr(json.getString("text", "")));
|
||||
field.setVisible(json.getBool("visible", true));
|
||||
field.setMaxStringLength(json.getInt("maxLength", 32));
|
||||
|
||||
enabled = !json.getBool("disabled", false);
|
||||
textColor = json.getColor("textColor", DEFAULT_TEXT_COLOR);
|
||||
disabledColor = json.getColor("disabledColor", DEFAULT_DISABLED_COLOR);
|
||||
|
||||
field.setTextColor(textColor);
|
||||
field.setDisabledTextColour(disabledColor);
|
||||
field.setEnabled(enabled);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui.loading;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface FillControl {
|
||||
|
||||
String name() default "";
|
||||
boolean required() default true;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui.loading;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.resources.IResource;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.montoyo.wd.client.gui.controls.*;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class GuiLoader {
|
||||
|
||||
private static HashMap<String, Class<? extends Control>> controls = new HashMap<String, Class<? extends Control>>();
|
||||
private static HashMap<ResourceLocation, JsonObject> resources = new HashMap<ResourceLocation, JsonObject>();
|
||||
|
||||
public static void register(Class<? extends Control> cls) {
|
||||
if(Modifier.isAbstract(cls.getModifiers()))
|
||||
throw new RuntimeException("GG retard, you just registered an abstract class...");
|
||||
|
||||
String name = cls.getSimpleName();
|
||||
if(controls.containsKey(name))
|
||||
throw new RuntimeException("Control class already registered or name taken!");
|
||||
|
||||
controls.put(name, cls);
|
||||
}
|
||||
|
||||
static {
|
||||
register(Button.class);
|
||||
register(CheckBox.class);
|
||||
register(ControlGroup.class);
|
||||
register(Label.class);
|
||||
register(List.class);
|
||||
register(TextField.class);
|
||||
}
|
||||
|
||||
public static Control create(JsonOWrapper json) {
|
||||
Control ret;
|
||||
|
||||
try {
|
||||
ret = controls.get(json.getString("type", null)).newInstance();
|
||||
} catch(InstantiationException e) {
|
||||
Log.errorEx("Could not create control from JSON: instantiation exception", e);
|
||||
throw Throwables.propagate(e);
|
||||
} catch(IllegalAccessException e) {
|
||||
Log.errorEx("Could not create control from JSON: access denied", e);
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
|
||||
ret.load(json);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static JsonObject getJson(ResourceLocation resLoc) {
|
||||
JsonObject ret = resources.get(resLoc);
|
||||
if(ret == null) {
|
||||
IResource resource;
|
||||
|
||||
try {
|
||||
resource = Minecraft.getMinecraft().getResourceManager().getResource(resLoc);
|
||||
} catch(IOException e) {
|
||||
Log.errorEx("Couldn't load JSON UI from file", e);
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
|
||||
JsonParser parser = new JsonParser();
|
||||
ret = parser.parse(new InputStreamReader(resource.getInputStream())).getAsJsonObject();
|
||||
|
||||
try {
|
||||
resource.close();
|
||||
} catch(IOException e) {}
|
||||
|
||||
resources.put(resLoc, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
resources.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui.loading;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class JsonAWrapper {
|
||||
|
||||
private final JsonArray array;
|
||||
private final Map<String, Double> variables;
|
||||
|
||||
public JsonAWrapper(JsonArray a, Map<String, Double> vars) {
|
||||
array = a;
|
||||
variables = vars;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return array.size();
|
||||
}
|
||||
|
||||
public String getString(int i) {
|
||||
return array.get(i).getAsString();
|
||||
}
|
||||
|
||||
public int getInt(int i) {
|
||||
return array.get(i).getAsInt();
|
||||
}
|
||||
|
||||
public long getLong(int i) {
|
||||
return array.get(i).getAsLong();
|
||||
}
|
||||
|
||||
public float getFloat(int i) {
|
||||
return array.get(i).getAsFloat();
|
||||
}
|
||||
|
||||
public double getDouble(int i) {
|
||||
return array.get(i).getAsDouble();
|
||||
}
|
||||
|
||||
public boolean getBool(int i) {
|
||||
return array.get(i).getAsBoolean();
|
||||
}
|
||||
|
||||
public JsonOWrapper getObject(int i) {
|
||||
return new JsonOWrapper(array.get(i).getAsJsonObject(), variables);
|
||||
}
|
||||
|
||||
public JsonAWrapper getArray(int i) {
|
||||
return new JsonAWrapper(array.get(i).getAsJsonArray(), variables);
|
||||
}
|
||||
|
||||
public JsonArray getArray() {
|
||||
return array;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.gui.loading;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import net.montoyo.wd.client.gui.controls.Control;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class JsonOWrapper {
|
||||
|
||||
private static final HashMap<String, Integer> defaultColors = new HashMap<String, Integer>();
|
||||
static {
|
||||
defaultColors.put("black", Control.COLOR_BLACK);
|
||||
defaultColors.put("white", Control.COLOR_WHITE);
|
||||
defaultColors.put("red", Control.COLOR_RED);
|
||||
defaultColors.put("green", Control.COLOR_GREEN);
|
||||
defaultColors.put("blue", Control.COLOR_BLUE);
|
||||
defaultColors.put("magenta", Control.COLOR_MANGENTA);
|
||||
defaultColors.put("cyan", Control.COLOR_CYAN);
|
||||
defaultColors.put("yellow", Control.COLOR_YELLOW);
|
||||
}
|
||||
|
||||
private final JsonObject object;
|
||||
private final Map<String, Double> variables;
|
||||
|
||||
public JsonOWrapper(JsonObject obj, Map<String, Double> vars) {
|
||||
object = obj;
|
||||
variables = vars;
|
||||
}
|
||||
|
||||
public String getString(String key, String def) {
|
||||
return object.has(key) ? object.get(key).getAsString() : def;
|
||||
}
|
||||
|
||||
public long getLong(String key, long def) {
|
||||
return object.has(key) ? object.get(key).getAsLong() : def;
|
||||
}
|
||||
|
||||
public int getInt(String key, int def) {
|
||||
if(!object.has(key))
|
||||
return def;
|
||||
|
||||
JsonPrimitive prim = object.get(key).getAsJsonPrimitive();
|
||||
if(prim.isNumber())
|
||||
return prim.getAsInt();
|
||||
|
||||
return (int) evalExpr(prim.getAsString(), variables);
|
||||
}
|
||||
|
||||
public float getFloat(String key, float def) {
|
||||
if(!object.has(key))
|
||||
return def;
|
||||
|
||||
JsonPrimitive prim = object.get(key).getAsJsonPrimitive();
|
||||
if(prim.isNumber())
|
||||
return prim.getAsFloat();
|
||||
|
||||
return (float) evalExpr(prim.getAsString(), variables);
|
||||
}
|
||||
|
||||
public double getDouble(String key, double def) {
|
||||
if(!object.has(key))
|
||||
return def;
|
||||
|
||||
JsonPrimitive prim = object.get(key).getAsJsonPrimitive();
|
||||
if(prim.isNumber())
|
||||
return prim.getAsDouble();
|
||||
|
||||
return evalExpr(prim.getAsString(), variables);
|
||||
}
|
||||
|
||||
public boolean getBool(String key, boolean def) {
|
||||
if(!object.has(key))
|
||||
return def;
|
||||
|
||||
JsonPrimitive prim = object.get(key).getAsJsonPrimitive();
|
||||
if(prim.isBoolean())
|
||||
return prim.getAsBoolean();
|
||||
else if(prim.isNumber())
|
||||
return prim.getAsInt() != 0;
|
||||
|
||||
return evalExpr(prim.getAsString(), variables) != 0.0;
|
||||
}
|
||||
|
||||
public JsonOWrapper getObject(String key) {
|
||||
return new JsonOWrapper(object.has(key) ? object.get(key).getAsJsonObject() : (new JsonObject()), variables);
|
||||
}
|
||||
|
||||
public JsonAWrapper getArray(String key) {
|
||||
return new JsonAWrapper(object.has(key) ? object.get(key).getAsJsonArray() : (new JsonArray()), variables);
|
||||
}
|
||||
|
||||
public JsonObject getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
public int getColor(String key, int def) {
|
||||
if(!object.has(key))
|
||||
return def;
|
||||
|
||||
JsonElement c = object.get(key);
|
||||
if(c.isJsonPrimitive()) {
|
||||
JsonPrimitive prim = c.getAsJsonPrimitive();
|
||||
|
||||
if(prim.isNumber())
|
||||
return (int) prim.getAsLong();
|
||||
else if(prim.isString()) {
|
||||
String str = prim.getAsString();
|
||||
Integer dc = defaultColors.get(str.toLowerCase());
|
||||
if(dc != null)
|
||||
return dc;
|
||||
|
||||
if(!str.isEmpty() && str.charAt(0) == '#')
|
||||
str = str.substring(1);
|
||||
|
||||
long ret = Long.parseLong(str, 16);
|
||||
if(str.length() <= 6)
|
||||
ret |= 0xFF000000L;
|
||||
|
||||
return (int) ret;
|
||||
} else
|
||||
return def;
|
||||
}
|
||||
|
||||
int r, g, b, a;
|
||||
if(c.isJsonArray()) {
|
||||
JsonArray array = c.getAsJsonArray();
|
||||
|
||||
r = array.get(0).getAsInt();
|
||||
g = array.get(1).getAsInt();
|
||||
b = array.get(2).getAsInt();
|
||||
a = (array.size() >= 4) ? array.get(3).getAsInt() : 255;
|
||||
} else if(c.isJsonObject()) {
|
||||
JsonObject obj = c.getAsJsonObject();
|
||||
|
||||
r = obj.get("r").getAsInt();
|
||||
g = obj.get("g").getAsInt();
|
||||
b = obj.get("b").getAsInt();
|
||||
a = obj.has("a") ? obj.get("a").getAsInt() : 255;
|
||||
} else
|
||||
return def;
|
||||
|
||||
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
private static final String OPS = "+*/%&|"; //The - sign is an exception, don't add it here
|
||||
private static final String[] OPS_PRIORITY = new String[] { "*/%", "+-", "&|" };
|
||||
|
||||
private static class VarOpPair {
|
||||
double var;
|
||||
char op;
|
||||
|
||||
void setVar(String str, boolean isNumber, String expr, Map<String, Double> variables) {
|
||||
if(isNumber)
|
||||
var = Double.parseDouble(str);
|
||||
else {
|
||||
boolean neg = (str.charAt(0) == '-');
|
||||
String varName = neg ? str.substring(1) : str;
|
||||
Double d = variables.get(varName);
|
||||
|
||||
if(d == null)
|
||||
throw new RuntimeException("Unknown variable \"" + varName + "\" in expression \"" + expr + "\"");
|
||||
|
||||
var = neg ? -d : d;
|
||||
}
|
||||
}
|
||||
|
||||
void setOp(char op) {
|
||||
this.op = op;
|
||||
}
|
||||
}
|
||||
|
||||
private static int findPair(List<VarOpPair> list, String ops) {
|
||||
for(int i = 0; i < list.size(); i++) {
|
||||
if(ops.indexOf(list.get(i).op) >= 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static double evalExpr(String expr, Map<String, Double> variables) {
|
||||
//Apply parenthesis
|
||||
while(true) {
|
||||
int pos = expr.indexOf('(');
|
||||
if(pos < 0)
|
||||
break;
|
||||
|
||||
int end = ++pos;
|
||||
int lvl = 0;
|
||||
|
||||
for(; end < expr.length(); end++) {
|
||||
char chr = expr.charAt(end);
|
||||
|
||||
if(chr == '(')
|
||||
lvl++;
|
||||
else if(chr == ')') {
|
||||
if(lvl == 0)
|
||||
break;
|
||||
|
||||
lvl--;
|
||||
}
|
||||
}
|
||||
|
||||
if(end >= expr.length())
|
||||
throw new RuntimeException("Unclosed parenthesis in expression \"" + expr + "\"");
|
||||
|
||||
double val = evalExpr(expr.substring(pos, end), variables);
|
||||
expr = expr.substring(0, pos - 1) + val + expr.substring(end + 1);
|
||||
}
|
||||
|
||||
//Parse into ops
|
||||
ArrayList<VarOpPair> ops = new ArrayList<VarOpPair>();
|
||||
StringBuilder str = new StringBuilder();
|
||||
boolean negIsPartOfStr = true;
|
||||
boolean strIsNumber = true;
|
||||
|
||||
for(int i = 0; i < expr.length(); i++) {
|
||||
char chr = expr.charAt(i);
|
||||
if(Character.isSpaceChar(chr))
|
||||
continue;
|
||||
|
||||
if((chr == '-' && !negIsPartOfStr) || OPS.indexOf(chr) >= 0) {
|
||||
//Parse
|
||||
VarOpPair pair = new VarOpPair();
|
||||
pair.setVar(str.toString(), strIsNumber, expr, variables);
|
||||
pair.setOp(chr);
|
||||
ops.add(pair);
|
||||
|
||||
//Reset
|
||||
str.setLength(0);
|
||||
negIsPartOfStr = true;
|
||||
strIsNumber = true;
|
||||
} else {
|
||||
if(strIsNumber && chr != '-' && chr != '.' && !Character.isDigit(chr))
|
||||
strIsNumber = false;
|
||||
|
||||
if(negIsPartOfStr)
|
||||
negIsPartOfStr = false;
|
||||
|
||||
str.append(chr);
|
||||
}
|
||||
}
|
||||
|
||||
if(str.length() > 0) {
|
||||
VarOpPair pair = new VarOpPair();
|
||||
pair.setVar(str.toString(), strIsNumber, expr, variables);
|
||||
pair.setOp((char) 0);
|
||||
ops.add(pair);
|
||||
}
|
||||
|
||||
//Compute
|
||||
while(true) {
|
||||
int pairId = -1;
|
||||
for(String opList : OPS_PRIORITY) {
|
||||
pairId = findPair(ops, opList);
|
||||
|
||||
if(pairId >= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if(pairId < 0)
|
||||
break;
|
||||
|
||||
VarOpPair a = ops.get(pairId);
|
||||
VarOpPair b = ops.get(pairId + 1);
|
||||
|
||||
if(a.op == '*')
|
||||
b.var = a.var * b.var;
|
||||
else if(a.op == '/')
|
||||
b.var = a.var / b.var;
|
||||
else if(a.op == '%')
|
||||
b.var = a.var % b.var;
|
||||
else if(a.op == '+')
|
||||
b.var = a.var + b.var;
|
||||
else if(a.op == '-')
|
||||
b.var = a.var - b.var;
|
||||
else if(a.op == '&') {
|
||||
if(a.var == 0.0)
|
||||
b.var = 0.0;
|
||||
|
||||
//if b.var == 0, b.var stays 0
|
||||
//if a.var != 0, b.var keeps its value
|
||||
} else if(a.op == '|') {
|
||||
if(a.var != 0.0)
|
||||
b.var = a.var;
|
||||
|
||||
//if a.var == 0, b.var keeps its value
|
||||
//if a.var != 0, b.var takes the value of a
|
||||
}
|
||||
|
||||
ops.remove(pairId);
|
||||
}
|
||||
|
||||
//Check
|
||||
if(ops.size() != 1 || ops.get(0).op != (char) 0)
|
||||
throw new RuntimeException("Error while parsing evaluating \"" + expr + "\"");
|
||||
|
||||
return ops.get(0).var;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.renderers;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
|
||||
public interface IModelBaker extends IBakedModel {
|
||||
|
||||
void loadTextures(TextureMap texMap);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.renderers;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.AbstractClientPlayer;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.client.renderer.entity.RenderPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.ClientProxy;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL12.GL_RESCALE_NORMAL;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public final class MinePadRenderer {
|
||||
|
||||
private static final float PI = (float) Math.PI;
|
||||
private final Minecraft mc = Minecraft.getMinecraft();
|
||||
private final ResourceLocation tex = new ResourceLocation("webdisplays", "textures/models/minepad.png");
|
||||
private final ModelMinePad model = new ModelMinePad();
|
||||
private final ClientProxy clientProxy = (ClientProxy) WebDisplays.PROXY;
|
||||
|
||||
private float sinSqrtSwingProg1;
|
||||
private float sinSqrtSwingProg2;
|
||||
private float sinSwingProg1;
|
||||
private float sinSwingProg2;
|
||||
|
||||
private static void drawAxis() {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBegin(GL_LINES);
|
||||
glColor4f(1.f, 0.f, 0.f, 1.f); glVertex3d(0.0, 0.0, 0.0);
|
||||
glColor4f(1.f, 0.f, 0.f, 1.f); glVertex3d(5.0, 0.0, 0.0);
|
||||
glColor4f(0.f, 1.f, 0.f, 1.f); glVertex3d(0.0, 0.0, 0.0);
|
||||
glColor4f(0.f, 1.f, 0.f, 1.f); glVertex3d(0.0, 5.0, 0.0);
|
||||
glColor4f(0.f, 0.f, 1.f, 1.f); glVertex3d(0.0, 0.0, 0.0);
|
||||
glColor4f(0.f, 0.f, 1.f, 1.f); glVertex3d(0.0, 0.0, 5.0);
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
public final void render(ItemStack is, float handSideSign, float swingProgress, float equipProgress) {
|
||||
//Pre-compute values
|
||||
float sqrtSwingProg = (float) Math.sqrt((double) swingProgress);
|
||||
sinSqrtSwingProg1 = MathHelper.sin(sqrtSwingProg * PI);
|
||||
sinSqrtSwingProg2 = MathHelper.sin(sqrtSwingProg * PI * 2.0f);
|
||||
sinSwingProg1 = MathHelper.sin(swingProgress * PI);
|
||||
sinSwingProg2 = MathHelper.sin(swingProgress * swingProgress * PI);
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
glEnable(GL_RESCALE_NORMAL);
|
||||
|
||||
//Render arm
|
||||
glPushMatrix();
|
||||
renderArmFirstPerson(equipProgress, handSideSign);
|
||||
glPopMatrix();
|
||||
|
||||
//Prepare minePad transform
|
||||
glPushMatrix();
|
||||
glTranslatef(handSideSign * -0.4f * sinSqrtSwingProg1, 0.2f * sinSqrtSwingProg2, -0.2f * sinSwingProg1);
|
||||
glTranslatef(handSideSign * 0.56f, -0.52f - equipProgress * 0.6f, -0.72f);
|
||||
glRotatef(handSideSign * (45.0f - sinSwingProg2 * 20.0f), 0.0f, 1.0f, 0.0f);
|
||||
glRotatef(handSideSign * sinSqrtSwingProg1 * -20.0f, 0.0f, 0.0f, 1.0f);
|
||||
glRotatef(sinSqrtSwingProg1 * -80.0f, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef(handSideSign * -45.0f, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
if(handSideSign >= 0.0f)
|
||||
glTranslatef(-1.065f, 0.0f, 0.0f);
|
||||
else {
|
||||
glTranslatef(0.0f, 0.0f, -0.2f);
|
||||
glRotatef(20.0f, 0.0f, 1.0f, 0.0f);
|
||||
glTranslatef(-0.475f, -0.1f, 0.0f);
|
||||
glRotatef(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
//Render model
|
||||
glPushMatrix();
|
||||
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
mc.renderEngine.bindTexture(tex);
|
||||
model.render(1.f / 16.f);
|
||||
glPopMatrix();
|
||||
|
||||
//Render web view
|
||||
if(is.getTagCompound() != null && is.getTagCompound().hasKey("PadID")) {
|
||||
ClientProxy.PadData pd = clientProxy.getPadByID(is.getTagCompound().getInteger("PadID"));
|
||||
|
||||
if(pd != null) {
|
||||
glTranslatef(0.063f, 0.28f, 0.001f);
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit);
|
||||
pd.view.draw(0.0, 0.0, 27.65 / 32.0 + 0.01, 14.0 / 32.0 + 0.002);
|
||||
}
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
glDisable(GL_RESCALE_NORMAL);
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
private void renderArmFirstPerson(float equipProgress, float handSideSign) {
|
||||
float tx = -0.3f * sinSqrtSwingProg1;
|
||||
float ty = 0.4f * sinSqrtSwingProg2;
|
||||
float tz = -0.4f * sinSwingProg1;
|
||||
|
||||
glTranslatef(handSideSign * (tx + 0.64000005f), ty - 0.6f - equipProgress * 0.6f, tz - 0.71999997f);
|
||||
glRotatef(handSideSign * 45.0f, 0.0f, 1.0f, 0.0f);
|
||||
glRotatef(handSideSign * sinSqrtSwingProg1 * 70.0f, 0.0f, 1.0f, 0.0f);
|
||||
glRotatef(handSideSign * sinSwingProg2 * -20.0f, 0.0f, 0.0f, 1.0f);
|
||||
glTranslatef(-handSideSign, 3.6f, 3.5f);
|
||||
glRotatef(handSideSign * 120.0f, 0.0f, 0.0f, 1.0f);
|
||||
glRotatef(200.0f, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef(handSideSign * -135.0f, 0.0f, 1.0f, 0.0f);
|
||||
glTranslatef(handSideSign * 5.6f, 0.0f, 0.0f);
|
||||
|
||||
RenderPlayer playerRenderer = (RenderPlayer) mc.getRenderManager().<AbstractClientPlayer>getEntityRenderObject(mc.player);
|
||||
mc.getTextureManager().bindTexture(mc.player.getLocationSkin());
|
||||
|
||||
if(handSideSign >= 0.0f)
|
||||
playerRenderer.renderRightArm(mc.player);
|
||||
else
|
||||
playerRenderer.renderLeftArm(mc.player);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.renderers;
|
||||
|
||||
import net.minecraft.client.model.ModelBase;
|
||||
import net.minecraft.client.model.ModelRenderer;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public final class ModelMinePad extends ModelBase {
|
||||
|
||||
// fields
|
||||
ModelRenderer base;
|
||||
ModelRenderer left;
|
||||
ModelRenderer right;
|
||||
|
||||
public ModelMinePad() {
|
||||
textureWidth = 64;
|
||||
textureHeight = 32;
|
||||
|
||||
base = new ModelRenderer(this, 0, 0);
|
||||
base.addBox(0F, 0F, 0F, 14, 1, 9);
|
||||
base.setRotationPoint(1F, 0F, 3.5F);
|
||||
base.setTextureSize(64, 32);
|
||||
base.mirror = true;
|
||||
setRotation(base, 0F, 0F, 0F);
|
||||
left = new ModelRenderer(this, 0, 10);
|
||||
left.addBox(0F, 0F, 0F, 1, 1, 7);
|
||||
left.setRotationPoint(0F, 0F, 4.5F);
|
||||
left.setTextureSize(64, 32);
|
||||
left.mirror = true;
|
||||
setRotation(left, 0F, 0F, 0F);
|
||||
right = new ModelRenderer(this, 30, 10);
|
||||
right.addBox(0F, 0F, 0F, 1, 1, 7);
|
||||
right.setRotationPoint(15F, 0F, 4.5F);
|
||||
right.setTextureSize(64, 32);
|
||||
right.mirror = true;
|
||||
setRotation(right, 0F, 0F, 0F);
|
||||
}
|
||||
|
||||
public final void render(float f5) {
|
||||
base.render(f5);
|
||||
left.render(f5);
|
||||
right.render(f5);
|
||||
}
|
||||
|
||||
private void setRotation(ModelRenderer model, float x, float y, float z) {
|
||||
model.rotateAngleX = x;
|
||||
model.rotateAngleY = y;
|
||||
model.rotateAngleZ = z;
|
||||
}
|
||||
|
||||
}
|
||||
139
src/main/java/net/montoyo/wd/client/renderers/ScreenBaker.java
Normal file
139
src/main/java/net/montoyo/wd/client/renderers/ScreenBaker.java
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.renderers;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.block.model.ItemOverrideList;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.montoyo.wd.block.BlockScreen;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Vector3f;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ScreenBaker implements IModelBaker {
|
||||
|
||||
private static final List<BakedQuad> noQuads = ImmutableList.of();
|
||||
private TextureAtlasSprite[] texs = new TextureAtlasSprite[16];
|
||||
private BlockSide[] blockSides = BlockSide.values();
|
||||
private EnumFacing[] blockFacings = EnumFacing.values();
|
||||
|
||||
@Override
|
||||
public void loadTextures(TextureMap texMap) {
|
||||
for(int i = 0; i < texs.length; i++)
|
||||
texs[i] = texMap.registerSprite(new ResourceLocation("webdisplays", "blocks/screen" + i));
|
||||
}
|
||||
|
||||
private void putVertex(int[] buf, int pos, Vector3f vpos, TextureAtlasSprite tex, Vector3f uv, Vector3i normal) {
|
||||
buf[pos * 7 + 0] = Float.floatToRawIntBits(vpos.x);
|
||||
buf[pos * 7 + 1] = Float.floatToRawIntBits(vpos.y);
|
||||
buf[pos * 7 + 2] = Float.floatToRawIntBits(vpos.z);
|
||||
buf[pos * 7 + 3] = 0xFFFFFFFF; //Color, let this white...
|
||||
buf[pos * 7 + 4] = Float.floatToRawIntBits(tex.getInterpolatedU(uv.x));
|
||||
buf[pos * 7 + 5] = Float.floatToRawIntBits(tex.getInterpolatedV(uv.y));
|
||||
|
||||
int nx = (normal.x * 127) & 0xFF;
|
||||
int ny = (normal.y * 127) & 0xFF;
|
||||
int nz = (normal.z * 127) & 0xFF;
|
||||
buf[pos * 7 + 6] = nx | (ny << 8) | (nz << 16);
|
||||
}
|
||||
|
||||
private Vector3f rotateVec(Vector3f vec, BlockSide side) {
|
||||
switch(side) {
|
||||
case BOTTOM: return new Vector3f(vec.x, 1.0f, 1.0f - vec.z);
|
||||
case TOP: return new Vector3f(vec.x, 0.0f, vec.z);
|
||||
case NORTH: return new Vector3f(vec.x, vec.z, 1.0f);
|
||||
case SOUTH: return new Vector3f(vec.x, 1.0f - vec.z, 0.0f);
|
||||
case WEST: return new Vector3f(1.f , vec.x, vec.z);
|
||||
case EAST: return new Vector3f(0.0f, 1.0f - vec.x, vec.z);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unknown block side " + side);
|
||||
}
|
||||
|
||||
private Vector3f rotateTex(BlockSide side, float u, float v) {
|
||||
switch(side) {
|
||||
case BOTTOM: return new Vector3f(u, 16.f - v, 0.0f);
|
||||
case TOP: return new Vector3f(u, v, 0.0f);
|
||||
case NORTH: return new Vector3f(16.f - u, 16.f - v, 0.0f);
|
||||
case SOUTH: return new Vector3f(u, v, 0.0f);
|
||||
case WEST: return new Vector3f(v, 16.f - u, 0.0f);
|
||||
case EAST: return new Vector3f(16.f - v, u, 0.0f);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unknown block side " + side);
|
||||
}
|
||||
|
||||
private BakedQuad bakeSide(BlockSide side, TextureAtlasSprite tex) {
|
||||
int[] data = new int[7 * 4];
|
||||
|
||||
putVertex(data, 3, rotateVec(new Vector3f(0.0f, 0.0f, 0.0f), side), tex, rotateTex(side, 0.0f, 0.0f ), side.backward);
|
||||
putVertex(data, 2, rotateVec(new Vector3f(0.0f, 0.0f, 1.0f), side), tex, rotateTex(side, 0.0f, 16.0f ), side.backward);
|
||||
putVertex(data, 1, rotateVec(new Vector3f(1.0f, 0.0f, 1.0f), side), tex, rotateTex(side, 16.0f, 16.0f), side.backward);
|
||||
putVertex(data, 0, rotateVec(new Vector3f(1.0f, 0.0f, 0.0f), side), tex, rotateTex(side, 16.0f, 0.0f ), side.backward);
|
||||
|
||||
return new BakedQuad(data, 0xFFFFFFFF, blockFacings[side.ordinal()], tex, true, DefaultVertexFormats.ITEM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) {
|
||||
if(side == null)
|
||||
return noQuads;
|
||||
|
||||
IExtendedBlockState bs = (IExtendedBlockState) state;
|
||||
List<BakedQuad> ret = new ArrayList<BakedQuad>();
|
||||
|
||||
int sid = BlockSide.reverse(side.ordinal());
|
||||
BlockSide s = blockSides[sid];
|
||||
TextureAtlasSprite tex = texs[15];
|
||||
if(bs != null)
|
||||
tex = texs[bs.getValue(BlockScreen.sideFlags[sid])];
|
||||
|
||||
ret.add(bakeSide(s, tex));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltInRenderer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleTexture() {
|
||||
return texs[15];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemCameraTransforms getItemCameraTransforms() {
|
||||
return ItemCameraTransforms.DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemOverrideList getOverrides() {
|
||||
return ItemOverrideList.NONE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.renderers;
|
||||
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.ClientProxy;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.utilities.Vector3f;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
public class ScreenRenderer extends TileEntitySpecialRenderer<TileEntityScreen> {
|
||||
|
||||
private final Vector3f mid = new Vector3f();
|
||||
private final Vector3i tmpi = new Vector3i();
|
||||
private final Vector3f tmpf = new Vector3f();
|
||||
|
||||
@Override
|
||||
public void render(TileEntityScreen te, double x, double y, double z, float partialTicks, int destroyStage, float alpha) {
|
||||
if(!te.isLoaded())
|
||||
return;
|
||||
|
||||
//Disable lighting
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
setLightmapDisabled(true);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
for(int i = 0; i < te.screenCount(); i++) {
|
||||
TileEntityScreen.Screen scr = te.getScreen(i);
|
||||
if(scr.browser == null) {
|
||||
scr.browser = ((ClientProxy) WebDisplays.PROXY).getMCEF().createBrowser(scr.url);
|
||||
scr.browser.resize(scr.resolution.x, scr.resolution.y);
|
||||
}
|
||||
|
||||
tmpi.set(scr.side.right);
|
||||
tmpi.mul(scr.size.x);
|
||||
tmpi.addMul(scr.side.up, scr.size.y);
|
||||
tmpf.set(tmpi);
|
||||
|
||||
mid.set(x + 0.5, y + 0.5, z + 0.5);
|
||||
mid.addMul(tmpf, 0.5f);
|
||||
tmpf.set(scr.side.left);
|
||||
mid.addMul(tmpf, 0.5f);
|
||||
tmpf.set(scr.side.down);
|
||||
mid.addMul(tmpf, 0.5f);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(mid.x, mid.y, mid.z);
|
||||
|
||||
switch(scr.side) {
|
||||
case BOTTOM:
|
||||
glRotatef(90.f, 1.f, 0.f, 0.f);
|
||||
break;
|
||||
|
||||
case TOP:
|
||||
glRotatef(-90.f, 1.f, 0.f, 0.f);
|
||||
break;
|
||||
|
||||
case NORTH:
|
||||
glRotatef(180.f, 0.f, 1.f, 0.f);
|
||||
break;
|
||||
|
||||
case SOUTH:
|
||||
break;
|
||||
|
||||
case WEST:
|
||||
glRotatef(-90.f, 0.f, 1.f, 0.f);
|
||||
break;
|
||||
|
||||
case EAST:
|
||||
glRotatef(90.f, 0.f, 1.f, 0.f);
|
||||
break;
|
||||
}
|
||||
|
||||
float sw = ((float) scr.size.x) * 0.5f - 2.f / 16.f;
|
||||
float sh = ((float) scr.size.y) * 0.5f - 2.f / 16.f;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, scr.browser.getTextureID());
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f); glTexCoord2f(0.f, 1.f); glVertex3f(-sw, -sh, 0.505f);
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f); glTexCoord2f(1.f, 1.f); glVertex3f( sw, -sh, 0.505f);
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f); glTexCoord2f(1.f, 0.f); glVertex3f( sw, sh, 0.505f);
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f); glTexCoord2f(0.f, 0.f); glVertex3f(-sw, sh, 0.505f);
|
||||
glEnd();
|
||||
GlStateManager.bindTexture(0); //Minecraft does shit with mah texture otherwise...
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
if(false) {
|
||||
//Bounding box debugging
|
||||
glPushMatrix();
|
||||
glTranslated(-rendererDispatcher.entityX, -rendererDispatcher.entityY, -rendererDispatcher.entityZ);
|
||||
renderAABB(te.getRenderBoundingBox());
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
//Re-enable lighting
|
||||
RenderHelper.enableStandardItemLighting();
|
||||
setLightmapDisabled(false);
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
public void renderAABB(AxisAlignedBB bb) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glColor4f(0.f, 0.5f, 1.f, 0.75f);
|
||||
glDepthMask(false);
|
||||
|
||||
Tessellator t = Tessellator.getInstance();
|
||||
BufferBuilder vb = t.getBuffer();
|
||||
vb.begin(GL_QUADS, DefaultVertexFormats.POSITION);
|
||||
|
||||
//Bottom
|
||||
vb.pos(bb.minX, bb.minY, bb.minZ).endVertex();
|
||||
vb.pos(bb.maxX, bb.minY, bb.minZ).endVertex();
|
||||
vb.pos(bb.maxX, bb.minY, bb.maxZ).endVertex();
|
||||
vb.pos(bb.minX, bb.minY, bb.maxZ).endVertex();
|
||||
|
||||
//Top
|
||||
vb.pos(bb.minX, bb.maxY, bb.minZ).endVertex();
|
||||
vb.pos(bb.maxX, bb.maxY, bb.minZ).endVertex();
|
||||
vb.pos(bb.maxX, bb.maxY, bb.maxZ).endVertex();
|
||||
vb.pos(bb.minX, bb.maxY, bb.maxZ).endVertex();
|
||||
|
||||
//Left
|
||||
vb.pos(bb.minX, bb.minY, bb.minZ).endVertex();
|
||||
vb.pos(bb.minX, bb.minY, bb.maxZ).endVertex();
|
||||
vb.pos(bb.minX, bb.maxY, bb.maxZ).endVertex();
|
||||
vb.pos(bb.minX, bb.maxY, bb.minZ).endVertex();
|
||||
|
||||
//Right
|
||||
vb.pos(bb.maxX, bb.minY, bb.minZ).endVertex();
|
||||
vb.pos(bb.maxX, bb.minY, bb.maxZ).endVertex();
|
||||
vb.pos(bb.maxX, bb.maxY, bb.maxZ).endVertex();
|
||||
vb.pos(bb.maxX, bb.maxY, bb.minZ).endVertex();
|
||||
|
||||
//Front
|
||||
vb.pos(bb.minX, bb.minY, bb.minZ).endVertex();
|
||||
vb.pos(bb.maxX, bb.minY, bb.minZ).endVertex();
|
||||
vb.pos(bb.maxX, bb.maxY, bb.minZ).endVertex();
|
||||
vb.pos(bb.minX, bb.maxY, bb.minZ).endVertex();
|
||||
|
||||
//Back
|
||||
vb.pos(bb.minX, bb.minY, bb.maxZ).endVertex();
|
||||
vb.pos(bb.maxX, bb.minY, bb.maxZ).endVertex();
|
||||
vb.pos(bb.maxX, bb.maxY, bb.maxZ).endVertex();
|
||||
vb.pos(bb.minX, bb.maxY, bb.maxZ).endVertex();
|
||||
t.draw();
|
||||
|
||||
glDepthMask(true);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGlobalRenderer(TileEntityScreen te) {
|
||||
//I don't like making it a global renderer for performance reasons,
|
||||
//but Minecraft's AABB-in-view-frustum checking is crappy as hell.
|
||||
return te.isLoaded();
|
||||
}
|
||||
|
||||
}
|
||||
36
src/main/java/net/montoyo/wd/core/DefaultPeripheral.java
Normal file
36
src/main/java/net/montoyo/wd/core/DefaultPeripheral.java
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.core;
|
||||
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
import net.montoyo.wd.entity.TileEntityKeyboard;
|
||||
import net.montoyo.wd.entity.TileEntityPeripheralBase;
|
||||
import net.montoyo.wd.entity.TileEntityRCtrl;
|
||||
|
||||
public enum DefaultPeripheral implements IStringSerializable {
|
||||
|
||||
KEYBOARD("keyboard", TileEntityKeyboard.class),
|
||||
REMOTE_CONTROLLER("remotectrl", TileEntityRCtrl.class),
|
||||
CC_INTERFACE("ccinterface", null),
|
||||
OC_INTERFACE("cointerface", null);
|
||||
|
||||
private final String name;
|
||||
private final Class<? extends TileEntityPeripheralBase> teClass;
|
||||
|
||||
DefaultPeripheral(String name, Class<? extends TileEntityPeripheralBase> te) {
|
||||
this.name = name;
|
||||
teClass = te;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Class<? extends TileEntityPeripheralBase> getTEClass() {
|
||||
return teClass;
|
||||
}
|
||||
|
||||
}
|
||||
17
src/main/java/net/montoyo/wd/core/IPeripheral.java
Normal file
17
src/main/java/net/montoyo/wd/core/IPeripheral.java
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.core;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
|
||||
public interface IPeripheral {
|
||||
|
||||
boolean connect(World world, BlockPos blockPos, IBlockState blockState, Vector3i screenPos, BlockSide screenSide);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.core;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
|
||||
public class MissingPermissionException extends Exception {
|
||||
|
||||
private final int permission;
|
||||
private final EntityPlayerMP player;
|
||||
|
||||
public MissingPermissionException(int p, EntityPlayerMP ply) {
|
||||
super("Player " + ply.getName() + " is missing permission " + p);
|
||||
permission = p;
|
||||
player = ply;
|
||||
}
|
||||
|
||||
public int getPermission() {
|
||||
return permission;
|
||||
}
|
||||
|
||||
public EntityPlayerMP getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
}
|
||||
20
src/main/java/net/montoyo/wd/core/ScreenRights.java
Normal file
20
src/main/java/net/montoyo/wd/core/ScreenRights.java
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.core;
|
||||
|
||||
public class ScreenRights {
|
||||
|
||||
public static final int CHANGE_URL = 1;
|
||||
public static final int CLICK = 2;
|
||||
public static final int MANAGE_FRIEND_LIST = 4;
|
||||
public static final int MANAGE_OTHER_RIGHTS = 8;
|
||||
public static final int MANAGE_UPGRADES = 16;
|
||||
public static final int CHANGE_RESOLUTION = 32;
|
||||
|
||||
public static final int NONE = 0;
|
||||
public static final int ALL = 0xFF;
|
||||
public static final int DEFAULTS = CHANGE_URL | CLICK | MANAGE_UPGRADES | CHANGE_RESOLUTION;
|
||||
|
||||
}
|
||||
22
src/main/java/net/montoyo/wd/core/WDCreativeTab.java
Normal file
22
src/main/java/net/montoyo/wd/core/WDCreativeTab.java
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.core;
|
||||
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
|
||||
public class WDCreativeTab extends CreativeTabs {
|
||||
|
||||
public WDCreativeTab() {
|
||||
super("webdisplays");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getTabIconItem() {
|
||||
return new ItemStack(WebDisplays.INSTANCE.blockScreen);
|
||||
}
|
||||
|
||||
}
|
||||
38
src/main/java/net/montoyo/wd/data/GuiData.java
Normal file
38
src/main/java/net/montoyo/wd/data/GuiData.java
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.data;
|
||||
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.net.CMessageOpenGui;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public abstract class GuiData {
|
||||
|
||||
private static final HashMap<String, Class<? extends GuiData>> dataTable = new HashMap<String, Class<? extends GuiData>>();
|
||||
static {
|
||||
dataTable.put("SetURL", SetURLData.class);
|
||||
dataTable.put("ScreenConfig", ScreenConfigData.class);
|
||||
dataTable.put("Keyboard", KeyboardData.class);
|
||||
}
|
||||
|
||||
public static Class<? extends GuiData> classOf(String name) {
|
||||
return dataTable.get(name);
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public abstract GuiScreen createGui(GuiScreen old, World world);
|
||||
public abstract String getName();
|
||||
|
||||
public void sendTo(EntityPlayerMP player) {
|
||||
WebDisplays.NET_HANDLER.sendTo(new CMessageOpenGui(this), player);
|
||||
}
|
||||
|
||||
}
|
||||
55
src/main/java/net/montoyo/wd/data/KeyboardData.java
Normal file
55
src/main/java/net/montoyo/wd/data/KeyboardData.java
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.data;
|
||||
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.montoyo.wd.client.gui.GuiKeyboard;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
|
||||
public class KeyboardData extends GuiData {
|
||||
|
||||
public Vector3i pos;
|
||||
public BlockSide side;
|
||||
public int kbX;
|
||||
public int kbY;
|
||||
public int kbZ;
|
||||
|
||||
public KeyboardData() {
|
||||
}
|
||||
|
||||
public KeyboardData(TileEntityScreen tes, BlockSide side, BlockPos kbPos) {
|
||||
pos = new Vector3i(tes.getPos());
|
||||
this.side = side;
|
||||
kbX = kbPos.getX();
|
||||
kbY = kbPos.getY();
|
||||
kbZ = kbPos.getZ();
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public GuiScreen createGui(GuiScreen old, World world) {
|
||||
TileEntity te = world.getTileEntity(pos.toBlock());
|
||||
if(te == null || !(te instanceof TileEntityScreen)) {
|
||||
Log.error("TileEntity at %s is not a screen; can't open keyboard!", pos.toString());
|
||||
return null;
|
||||
}
|
||||
|
||||
return new GuiKeyboard((TileEntityScreen) te, side, new BlockPos(kbX, kbY, kbZ));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Keyboard";
|
||||
}
|
||||
|
||||
}
|
||||
87
src/main/java/net/montoyo/wd/data/ScreenConfigData.java
Normal file
87
src/main/java/net/montoyo/wd/data/ScreenConfigData.java
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.data;
|
||||
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.gui.GuiScreenConfig;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.net.CMessageOpenGui;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
import net.montoyo.wd.utilities.NameUUIDPair;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
|
||||
public class ScreenConfigData extends GuiData {
|
||||
|
||||
public boolean onlyUpdate;
|
||||
public Vector3i pos;
|
||||
public BlockSide side;
|
||||
public NameUUIDPair owner;
|
||||
public NameUUIDPair[] friends;
|
||||
public int friendRights;
|
||||
public int otherRights;
|
||||
|
||||
public ScreenConfigData() {
|
||||
}
|
||||
|
||||
public ScreenConfigData(Vector3i pos, BlockSide side, TileEntityScreen.Screen scr) {
|
||||
this.pos = pos;
|
||||
this.side = side;
|
||||
owner = scr.owner;
|
||||
friends = scr.friends.toArray(new NameUUIDPair[0]);
|
||||
friendRights = scr.friendRights;
|
||||
otherRights = scr.otherRights;
|
||||
onlyUpdate = false;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public GuiScreen createGui(GuiScreen old, World world) {
|
||||
if(old != null && old instanceof GuiScreenConfig) {
|
||||
GuiScreenConfig gsc = (GuiScreenConfig) old;
|
||||
|
||||
if(gsc.isScreen(pos, side)) {
|
||||
gsc.updateFriends(friends);
|
||||
gsc.updateFriendRights(friendRights);
|
||||
gsc.updateOtherRights(otherRights);
|
||||
gsc.updateMyRights();
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if(onlyUpdate)
|
||||
return null;
|
||||
|
||||
TileEntity te = world.getTileEntity(pos.toBlock());
|
||||
if(te == null || !(te instanceof TileEntityScreen)) {
|
||||
Log.error("TileEntity at %s is not a screen; can't open gui!", pos.toString());
|
||||
return null;
|
||||
}
|
||||
|
||||
return new GuiScreenConfig((TileEntityScreen) te, side, owner, friends, friendRights, otherRights);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "ScreenConfig";
|
||||
}
|
||||
|
||||
public ScreenConfigData updateOnly() {
|
||||
onlyUpdate = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void sendTo(NetworkRegistry.TargetPoint tp) {
|
||||
WebDisplays.NET_HANDLER.sendToAllAround(new CMessageOpenGui(this), tp);
|
||||
}
|
||||
|
||||
}
|
||||
50
src/main/java/net/montoyo/wd/data/SetURLData.java
Normal file
50
src/main/java/net/montoyo/wd/data/SetURLData.java
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.data;
|
||||
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.montoyo.wd.client.gui.GuiSetURL2;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
|
||||
public class SetURLData extends GuiData {
|
||||
|
||||
public Vector3i pos;
|
||||
public BlockSide side;
|
||||
public String url;
|
||||
|
||||
public SetURLData() {
|
||||
}
|
||||
|
||||
public SetURLData(Vector3i pos, BlockSide side, String url) {
|
||||
this.pos = pos;
|
||||
this.side = side;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public GuiScreen createGui(GuiScreen old, World world) {
|
||||
TileEntity te = world.getTileEntity(pos.toBlock());
|
||||
if(te == null || !(te instanceof TileEntityScreen)) {
|
||||
Log.error("TileEntity at %s is not a screen; can't open gui!", pos.toString());
|
||||
return null;
|
||||
}
|
||||
|
||||
return new GuiSetURL2((TileEntityScreen) te, side, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "SetURL";
|
||||
}
|
||||
|
||||
}
|
||||
67
src/main/java/net/montoyo/wd/entity/TileEntityKeyboard.java
Normal file
67
src/main/java/net/montoyo/wd/entity/TileEntityKeyboard.java
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.entity;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.data.KeyboardData;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Util;
|
||||
|
||||
public class TileEntityKeyboard extends TileEntityPeripheralBase {
|
||||
|
||||
private static final String RANDOM_CHARS = "AZERTYUIOPQSDFGHJKLMWXCVBNazertyuiopqsdfghjklmwxcvbn0123456789"; //Yes I have an AZERTY keyboard, u care?
|
||||
|
||||
@Override
|
||||
public boolean onRightClick(EntityPlayer player, EnumHand hand, BlockSide side) {
|
||||
if(world.isRemote)
|
||||
return true;
|
||||
|
||||
if(!isScreenChunkLoaded()) {
|
||||
Util.toast(player, "chunkUnloaded");
|
||||
return true;
|
||||
}
|
||||
|
||||
TileEntityScreen tes = getConnectedScreen();
|
||||
if(tes == null) {
|
||||
Util.toast(player, "notLinked");
|
||||
return true;
|
||||
}
|
||||
|
||||
TileEntityScreen.Screen scr = tes.getScreen(screenSide);
|
||||
if((scr.rightsFor(player) & ScreenRights.CLICK) == 0) {
|
||||
Util.toast(player, "restrictions");
|
||||
return true;
|
||||
}
|
||||
|
||||
(new KeyboardData(tes, screenSide, pos)).sendTo((EntityPlayerMP) player);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void simulateCat(Entity ent) {
|
||||
if(isScreenChunkLoaded()) {
|
||||
TileEntityScreen tes = getConnectedScreen();
|
||||
|
||||
if(tes != null) {
|
||||
TileEntityScreen.Screen scr = tes.getScreen(screenSide);
|
||||
boolean ok;
|
||||
|
||||
if(ent instanceof EntityPlayer)
|
||||
ok = (scr.rightsFor((EntityPlayer) ent) & ScreenRights.CLICK) != 0;
|
||||
else
|
||||
ok = (scr.otherRights & ScreenRights.CLICK) != 0;
|
||||
|
||||
if(ok) {
|
||||
char rnd = RANDOM_CHARS.charAt((int) (Math.random() * ((double) RANDOM_CHARS.length())));
|
||||
tes.type(screenSide, "t" + rnd, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.entity;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.montoyo.wd.core.IPeripheral;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class TileEntityPeripheralBase extends TileEntity implements IPeripheral {
|
||||
|
||||
protected Vector3i screenPos;
|
||||
protected BlockSide screenSide;
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound tag) {
|
||||
super.readFromNBT(tag);
|
||||
|
||||
if(tag.hasKey("WDScreen", 10)) {
|
||||
NBTTagCompound scr = tag.getCompoundTag("WDScreen");
|
||||
screenPos = new Vector3i(scr.getInteger("X"), scr.getInteger("Y"), scr.getInteger("Z"));
|
||||
screenSide = BlockSide.values()[scr.getByte("Side")];
|
||||
} else {
|
||||
screenPos = null;
|
||||
screenSide = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound tag) {
|
||||
super.writeToNBT(tag);
|
||||
|
||||
if(screenPos != null && screenSide != null) {
|
||||
NBTTagCompound scr = new NBTTagCompound();
|
||||
scr.setInteger("X", screenPos.x);
|
||||
scr.setInteger("Y", screenPos.y);
|
||||
scr.setInteger("Z", screenPos.z);
|
||||
scr.setByte("Side", (byte) screenSide.ordinal());
|
||||
|
||||
tag.setTag("WDScreen", scr);
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connect(World world_, BlockPos blockPos, IBlockState blockState, Vector3i pos, BlockSide side) {
|
||||
TileEntity te = world.getTileEntity(pos.toBlock());
|
||||
if(te == null || !(te instanceof TileEntityScreen)) {
|
||||
Log.error("TileEntityPeripheralBase.connect(): Tile entity at %s is not a screen!", pos.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(((TileEntityScreen) te).getScreen(side) == null) {
|
||||
Log.error("TileEntityPeripheralBase.connect(): There is no screen at %s on side %s!", pos.toString(), side.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
screenPos = pos;
|
||||
screenSide = side;
|
||||
markDirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isLinked() {
|
||||
return screenPos != null && screenSide != null;
|
||||
}
|
||||
|
||||
public boolean isScreenChunkLoaded() {
|
||||
if(screenPos == null || screenSide == null)
|
||||
return true;
|
||||
|
||||
Chunk chunk = world.getChunkProvider().getLoadedChunk(screenPos.x >> 4, screenPos.z >> 4);
|
||||
return chunk != null && !chunk.isEmpty();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TileEntityScreen getConnectedScreen() {
|
||||
if(screenPos == null || screenSide == null)
|
||||
return null;
|
||||
|
||||
TileEntity te = world.getTileEntity(screenPos.toBlock());
|
||||
if(te == null || !(te instanceof TileEntityScreen) || ((TileEntityScreen) te).getScreen(screenSide) == null) {
|
||||
screenPos = null;
|
||||
screenSide = null;
|
||||
markDirty();
|
||||
return null;
|
||||
}
|
||||
|
||||
return (TileEntityScreen) te;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Vector3i getScreenPos() {
|
||||
return screenPos;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BlockSide getScreenSide() {
|
||||
return screenSide;
|
||||
}
|
||||
|
||||
public boolean onRightClick(EntityPlayer player, EnumHand hand, BlockSide side) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
43
src/main/java/net/montoyo/wd/entity/TileEntityRCtrl.java
Normal file
43
src/main/java/net/montoyo/wd/entity/TileEntityRCtrl.java
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.entity;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.data.SetURLData;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Util;
|
||||
|
||||
public class TileEntityRCtrl extends TileEntityPeripheralBase {
|
||||
|
||||
@Override
|
||||
public boolean onRightClick(EntityPlayer player, EnumHand hand, BlockSide side) {
|
||||
if(world.isRemote)
|
||||
return true;
|
||||
|
||||
if(!isScreenChunkLoaded()) {
|
||||
Util.toast(player, "chunkUnloaded");
|
||||
return true;
|
||||
}
|
||||
|
||||
TileEntityScreen tes = getConnectedScreen();
|
||||
if(tes == null) {
|
||||
Util.toast(player, "notLinked");
|
||||
return true;
|
||||
}
|
||||
|
||||
TileEntityScreen.Screen scr = tes.getScreen(screenSide);
|
||||
if((scr.rightsFor(player) & ScreenRights.CHANGE_URL) == 0) {
|
||||
Util.toast(player, "restrictions");
|
||||
return true;
|
||||
}
|
||||
|
||||
(new SetURLData(screenPos, screenSide, scr.url)).sendTo((EntityPlayerMP) player);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
539
src/main/java/net/montoyo/wd/entity/TileEntityScreen.java
Normal file
539
src/main/java/net/montoyo/wd/entity/TileEntityScreen.java
Normal file
|
|
@ -0,0 +1,539 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.entity;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
import net.montoyo.mcef.api.IBrowser;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.block.BlockScreen;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.data.ScreenConfigData;
|
||||
import net.montoyo.wd.net.CMessageAddScreen;
|
||||
import net.montoyo.wd.net.CMessageScreenUpdate;
|
||||
import net.montoyo.wd.net.SMessageRequestTEData;
|
||||
import net.montoyo.wd.utilities.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
public class TileEntityScreen extends TileEntity {
|
||||
|
||||
public static class Screen {
|
||||
|
||||
private static final String YT_REGEX1 = "^https?\\://(?:www\\.)?youtube\\.com/watch.+$"; //TODO: Fix embedded videos sound/distance
|
||||
private static final String YT_REGEX2 = "^https?\\://(?:www\\.)?youtu\\.be/[a-zA-Z0-9_\\-]+.*$";
|
||||
|
||||
public BlockSide side;
|
||||
public Vector2i size;
|
||||
public Vector2i resolution;
|
||||
public String url;
|
||||
public boolean isYouTube = false;
|
||||
public NameUUIDPair owner;
|
||||
public ArrayList<NameUUIDPair> friends;
|
||||
public int friendRights;
|
||||
public int otherRights;
|
||||
public IBrowser browser;
|
||||
|
||||
public static boolean isYouTubeURL(String url) {
|
||||
return url.matches(YT_REGEX1) || url.matches(YT_REGEX2);
|
||||
}
|
||||
|
||||
public static Screen deserialize(NBTTagCompound tag) {
|
||||
Screen ret = new Screen();
|
||||
ret.side = BlockSide.values()[tag.getByte("Side")];
|
||||
ret.size = new Vector2i(tag.getInteger("Width"), tag.getInteger("Height"));
|
||||
ret.resolution = new Vector2i(tag.getInteger("ResolutionX"), tag.getInteger("ResolutionY"));
|
||||
ret.url = tag.getString("URL");
|
||||
ret.isYouTube = isYouTubeURL(ret.url);
|
||||
|
||||
if(ret.resolution.x <= 0 || ret.resolution.y <= 0) {
|
||||
float psx = ((float) ret.size.x) * 16.f - 4.f;
|
||||
float psy = ((float) ret.size.y) * 16.f - 4.f;
|
||||
psx *= 8.f; //TODO: Use ratio in config file
|
||||
psy *= 8.f;
|
||||
|
||||
ret.resolution.x = (int) psx;
|
||||
ret.resolution.y = (int) psy;
|
||||
}
|
||||
|
||||
if(tag.hasKey("OwnerName")) {
|
||||
String name = tag.getString("OwnerName");
|
||||
UUID uuid = tag.getUniqueId("OwnerUUID");
|
||||
ret.owner = new NameUUIDPair(name, uuid);
|
||||
}
|
||||
|
||||
NBTTagList friends = tag.getTagList("Friends", 10);
|
||||
ret.friends = new ArrayList<NameUUIDPair>(friends.tagCount());
|
||||
|
||||
for(int i = 0; i < friends.tagCount(); i++) {
|
||||
NBTTagCompound nf = friends.getCompoundTagAt(i);
|
||||
NameUUIDPair pair = new NameUUIDPair(nf.getString("Name"), nf.getUniqueId("UUID"));
|
||||
ret.friends.add(pair);
|
||||
}
|
||||
|
||||
ret.friendRights = tag.getByte("FriendRights");
|
||||
ret.otherRights = tag.getByte("OtherRights");
|
||||
return ret;
|
||||
}
|
||||
|
||||
public NBTTagCompound serialize() {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setByte("Side", (byte) side.ordinal());
|
||||
tag.setInteger("Width", size.x);
|
||||
tag.setInteger("Height", size.y);
|
||||
tag.setInteger("ResolutionX", resolution.x);
|
||||
tag.setInteger("ResolutionY", resolution.y);
|
||||
tag.setString("URL", url);
|
||||
|
||||
if(owner == null)
|
||||
Log.warning("Found TES with NO OWNER!!");
|
||||
else {
|
||||
tag.setString("OwnerName", owner.name);
|
||||
tag.setUniqueId("OwnerUUID", owner.uuid);
|
||||
}
|
||||
|
||||
NBTTagList list = new NBTTagList();
|
||||
for(NameUUIDPair f: friends) {
|
||||
NBTTagCompound nf = new NBTTagCompound();
|
||||
nf.setString("Name", f.name);
|
||||
nf.setUniqueId("UUID", f.uuid);
|
||||
|
||||
list.appendTag(nf);
|
||||
}
|
||||
|
||||
tag.setTag("Friends", list);
|
||||
tag.setByte("FriendRights", (byte) friendRights);
|
||||
tag.setByte("OtherRights", (byte) otherRights);
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setOwner(EntityPlayer ply) {
|
||||
owner = new NameUUIDPair(ply.getGameProfile());
|
||||
}
|
||||
|
||||
public int rightsFor(EntityPlayer ply) {
|
||||
UUID uuid = ply.getGameProfile().getId();
|
||||
if(owner.uuid.equals(uuid))
|
||||
return ScreenRights.ALL;
|
||||
|
||||
for(NameUUIDPair f: friends) {
|
||||
if(f.uuid.equals(uuid))
|
||||
return friendRights;
|
||||
}
|
||||
|
||||
return otherRights;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ArrayList<Screen> screens = new ArrayList<Screen>();
|
||||
private AxisAlignedBB renderBB = new AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
|
||||
private boolean loaded = true;
|
||||
public float ytVolume = 100.0f;
|
||||
|
||||
public boolean isLoaded() {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
for(Screen scr: screens) {
|
||||
if(scr.browser != null) {
|
||||
scr.browser.close();
|
||||
scr.browser = null;
|
||||
}
|
||||
}
|
||||
|
||||
loaded = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound tag) {
|
||||
super.readFromNBT(tag);
|
||||
|
||||
NBTTagList list = tag.getTagList("WDScreens", 10);
|
||||
if(list.hasNoTags())
|
||||
return;
|
||||
|
||||
screens.clear();
|
||||
for(int i = 0; i < list.tagCount(); i++)
|
||||
screens.add(Screen.deserialize(list.getCompoundTagAt(i)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound tag) {
|
||||
super.writeToNBT(tag);
|
||||
|
||||
NBTTagList list = new NBTTagList();
|
||||
for(Screen scr: screens)
|
||||
list.appendTag(scr.serialize());
|
||||
|
||||
tag.setTag("WDScreens", list);
|
||||
return tag;
|
||||
}
|
||||
|
||||
public NetworkRegistry.TargetPoint point() {
|
||||
return new NetworkRegistry.TargetPoint(world.provider.getDimension(), (double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), 64.0);
|
||||
}
|
||||
|
||||
public Screen addScreen(BlockSide side, Vector2i size, Vector2i resolution, boolean sendUpdate) {
|
||||
for(Screen scr: screens) {
|
||||
if(scr.side == side)
|
||||
return scr;
|
||||
}
|
||||
|
||||
Screen ret = new Screen();
|
||||
ret.side = side;
|
||||
ret.size = size;
|
||||
ret.url = WebDisplays.INSTANCE.homePage;
|
||||
ret.friends = new ArrayList<NameUUIDPair>();
|
||||
ret.friendRights = ScreenRights.DEFAULTS;
|
||||
ret.otherRights = ScreenRights.DEFAULTS;
|
||||
|
||||
if(resolution == null || resolution.x < 1 || resolution.y < 1) {
|
||||
float psx = ((float) size.x) * 16.f - 4.f;
|
||||
float psy = ((float) size.y) * 16.f - 4.f;
|
||||
psx *= 8.f; //TODO: Use ratio in config file
|
||||
psy *= 8.f;
|
||||
|
||||
ret.resolution = new Vector2i((int) psx, (int) psy);
|
||||
} else
|
||||
ret.resolution = resolution;
|
||||
|
||||
if(sendUpdate && !world.isRemote) {
|
||||
CMessageAddScreen msg = new CMessageAddScreen(this, ret);
|
||||
WebDisplays.NET_HANDLER.sendToAllAround(msg, point());
|
||||
}
|
||||
|
||||
screens.add(ret);
|
||||
|
||||
if(world.isRemote)
|
||||
updateAABB();
|
||||
else
|
||||
markDirty();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Screen getScreen(BlockSide side) {
|
||||
for(Screen scr: screens) {
|
||||
if(scr.side == side)
|
||||
return scr;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int screenCount() {
|
||||
return screens.size();
|
||||
}
|
||||
|
||||
public Screen getScreen(int idx) {
|
||||
return screens.get(idx);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
screens.clear();
|
||||
|
||||
if(!world.isRemote)
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void requestData(EntityPlayerMP ep) {
|
||||
if(!world.isRemote)
|
||||
WebDisplays.NET_HANDLER.sendTo(new CMessageAddScreen(this), ep);
|
||||
}
|
||||
|
||||
public void setScreenURL(BlockSide side, String url) {
|
||||
Screen scr = getScreen(side);
|
||||
if(scr == null) {
|
||||
Log.error("Attempt to change URL of non-existing screen on side %s", side.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
scr.url = url;
|
||||
scr.isYouTube = Screen.isYouTubeURL(url);
|
||||
|
||||
if(world.isRemote) {
|
||||
if(scr.browser != null)
|
||||
scr.browser.loadURL(url);
|
||||
} else {
|
||||
WebDisplays.NET_HANDLER.sendToAllAround(CMessageScreenUpdate.setURL(this, side, url), point());
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeScreen(BlockSide side) {
|
||||
int idx = -1;
|
||||
for(int i = 0; i < screens.size(); i++) {
|
||||
if(screens.get(i).side == side) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(idx < 0) {
|
||||
Log.error("Tried to delete non-existing screen on side %s", side.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(world.isRemote) {
|
||||
if(screens.get(idx).browser != null) {
|
||||
screens.get(idx).browser.close();
|
||||
screens.get(idx).browser = null;
|
||||
}
|
||||
} else
|
||||
WebDisplays.NET_HANDLER.sendToAllAround(new CMessageScreenUpdate(this, side), point()); //Delete the screen
|
||||
|
||||
screens.remove(idx);
|
||||
|
||||
if(!world.isRemote) {
|
||||
if(screens.isEmpty()) //No more screens: remove tile entity
|
||||
world.setBlockState(getPos(), WebDisplays.INSTANCE.blockScreen.getDefaultState().withProperty(BlockScreen.hasTE, false));
|
||||
else
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public void setResolution(BlockSide side, Vector2i res) {
|
||||
if(res.x < 1 || res.y < 1) {
|
||||
Log.warning("Call to TileEntityScreen.setResolution(%s) with suspicious values X=%d and Y=%d", side.toString(), res.x, res.y);
|
||||
return;
|
||||
}
|
||||
|
||||
Screen scr = getScreen(side);
|
||||
if(scr == null) {
|
||||
Log.error("Tried to change resolution of non-existing screen on side %s", side.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
scr.resolution = res;
|
||||
|
||||
if(world.isRemote) {
|
||||
WebDisplays.PROXY.screenUpdateResolutionInGui(new Vector3i(getPos()), side, res);
|
||||
|
||||
if(scr.browser != null) {
|
||||
scr.browser.close();
|
||||
scr.browser = null; //Will be re-created by renderer
|
||||
}
|
||||
} else {
|
||||
WebDisplays.NET_HANDLER.sendToAllAround(CMessageScreenUpdate.setResolution(this, side, res), point());
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public void click(BlockSide side, Vector2i vec) {
|
||||
Screen scr = getScreen(side);
|
||||
if(scr == null) {
|
||||
Log.error("Attempt click non-existing screen of side %s", side.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(world.isRemote) {
|
||||
if(scr.browser != null) {
|
||||
scr.browser.injectMouseMove(vec.x, vec.y, 0, false);
|
||||
scr.browser.injectMouseButton(vec.x, vec.y, 0, 1, true, 1);
|
||||
scr.browser.injectMouseButton(vec.x, vec.y, 0, 1, false, 1);
|
||||
}
|
||||
} else
|
||||
WebDisplays.NET_HANDLER.sendToAllAround(CMessageScreenUpdate.click(this, side, vec), point());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
if(world.isRemote) {
|
||||
WebDisplays.NET_HANDLER.sendToServer(new SMessageRequestTEData(this));
|
||||
WebDisplays.PROXY.trackScreen(this, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkUnload() {
|
||||
if(world.isRemote) {
|
||||
WebDisplays.PROXY.trackScreen(this, false);
|
||||
|
||||
for(Screen scr: screens) {
|
||||
if(scr.browser != null) {
|
||||
scr.browser.close();
|
||||
scr.browser = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAABB() {
|
||||
Vector3i origin = new Vector3i(pos);
|
||||
Vector3i tmp = new Vector3i();
|
||||
AABB aabb = new AABB(origin);
|
||||
|
||||
for(Screen scr: screens) {
|
||||
tmp.set(origin);
|
||||
tmp.addMul(scr.side.right, scr.size.x);
|
||||
tmp.addMul(scr.side.up, scr.size.y);
|
||||
tmp.add(scr.side.forward);
|
||||
|
||||
aabb.expand(tmp);
|
||||
}
|
||||
|
||||
renderBB = aabb.toMc().expand(0.1, 0.1, 0.1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getRenderBoundingBox() {
|
||||
return renderBB;
|
||||
}
|
||||
|
||||
public void updateTrackDistance(double d) {
|
||||
boolean needsComputation = true;
|
||||
float vol = -1.f;
|
||||
String jsCode = null;
|
||||
|
||||
for(Screen scr: screens) {
|
||||
if(scr.isYouTube && scr.browser != null && !scr.browser.isPageLoading()) {
|
||||
if(needsComputation) {
|
||||
float dist = (float) Math.sqrt(d);
|
||||
if(dist <= 10.f)
|
||||
vol = 100.f;
|
||||
else if(dist >= 30.f)
|
||||
vol = 0.f;
|
||||
else
|
||||
vol = (1.f - (dist - 10.f) / 20.f) * 100.f;
|
||||
|
||||
if(Math.abs(ytVolume - vol) < 0.5f)
|
||||
return; //Delta is too small
|
||||
|
||||
ytVolume = vol;
|
||||
int intPart = (int) vol; //Manually convert to string, probably faster in that case...
|
||||
int fracPart = ((int) (vol * 100.f)) - intPart * 100;
|
||||
//jsCode = "yt.player.getPlayerByElement(document.getElementById(\"movie_player\")).setVolume(" + intPart + '.' + fracPart + ')';
|
||||
//jsCode = "console.log(document.getElementById(\"movie_player\"))";
|
||||
jsCode = "document.getElementById(\"movie_player\").setVolume(" + intPart + '.' + fracPart + ')';
|
||||
//Log.info(jsCode);
|
||||
needsComputation = false;
|
||||
}
|
||||
|
||||
scr.browser.runJS(jsCode, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*@Override
|
||||
public void validate() {
|
||||
super.validate();
|
||||
|
||||
if(world.isRemote)
|
||||
Log.info("===> TES( VALIDATE) %s", getPos().toString());
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
super.invalidate();
|
||||
|
||||
if(world.isRemote) {
|
||||
Log.info("===> TES(INVALIDATE) %s", getPos().toString());
|
||||
onChunkUnload();
|
||||
}
|
||||
}
|
||||
|
||||
public void addFriend(EntityPlayerMP ply, BlockSide side, NameUUIDPair pair) {
|
||||
if(!world.isRemote) {
|
||||
Screen scr = getScreen(side);
|
||||
if(scr == null) {
|
||||
Log.error("Tried to add friend to invalid screen side %s", side.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(!scr.friends.contains(pair)) {
|
||||
scr.friends.add(pair);
|
||||
(new ScreenConfigData(new Vector3i(pos), side, scr)).updateOnly().sendTo(point());
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeFriend(EntityPlayerMP ply, BlockSide side, NameUUIDPair pair) {
|
||||
if(!world.isRemote) {
|
||||
Screen scr = getScreen(side);
|
||||
if(scr == null) {
|
||||
Log.error("Tried to remove friend from invalid screen side %s", side.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(scr.friends.remove(pair)) {
|
||||
(new ScreenConfigData(new Vector3i(pos), side, scr)).updateOnly().sendTo(point());
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setRights(EntityPlayerMP ply, BlockSide side, int fr, int or) {
|
||||
if(!world.isRemote) {
|
||||
Screen scr = getScreen(side);
|
||||
if(scr == null) {
|
||||
Log.error("Tried to change rights of invalid screen on side %s", side.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
scr.friendRights = fr;
|
||||
scr.otherRights = or;
|
||||
(new ScreenConfigData(new Vector3i(pos), side, scr)).updateOnly().sendTo(point());
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public void type(BlockSide side, String text, BlockPos soundPos) {
|
||||
Screen scr = getScreen(side);
|
||||
if(scr == null) {
|
||||
Log.error("Tried to type on invalid screen on side %s", side.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(world.isRemote) {
|
||||
if(scr.browser != null) {
|
||||
try {
|
||||
String[] events = text.split("" + ((char) 1));
|
||||
|
||||
for(String ev: events) {
|
||||
char action = ev.charAt(0);
|
||||
|
||||
if(action == 'p')
|
||||
scr.browser.injectKeyPressed(ev.charAt(1), 0);
|
||||
else if(action == 'r')
|
||||
scr.browser.injectKeyReleased(ev.charAt(1), 0);
|
||||
else if(action == 't') {
|
||||
for(int i = 1; i < ev.length(); i++)
|
||||
scr.browser.injectKeyTyped(ev.charAt(i), 0);
|
||||
} else
|
||||
throw new RuntimeException("Invalid control key '" + action + '\'');
|
||||
}
|
||||
} catch(Throwable t) {
|
||||
Log.warningEx("Suspicious keyboard type packet received...", t);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
WebDisplays.NET_HANDLER.sendToAllAround(CMessageScreenUpdate.type(this, side, text), point());
|
||||
|
||||
if(soundPos != null) {
|
||||
double x = (double) soundPos.getX();
|
||||
double y = (double) soundPos.getY();
|
||||
double z = (double) soundPos.getZ();
|
||||
|
||||
world.playSound(null, x + 0.5, y + 0.5, z + 0.5, WebDisplays.INSTANCE.soundTyping, SoundCategory.BLOCKS, 0.25f, 1.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
137
src/main/java/net/montoyo/wd/item/ItemLinker.java
Normal file
137
src/main/java/net/montoyo/wd/item/ItemLinker.java
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.item;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.block.BlockScreen;
|
||||
import net.montoyo.wd.core.IPeripheral;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Multiblock;
|
||||
import net.montoyo.wd.utilities.Util;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class ItemLinker extends Item {
|
||||
|
||||
public ItemLinker() {
|
||||
setUnlocalizedName("webdisplays.linker");
|
||||
setRegistryName("linker");
|
||||
setMaxStackSize(1);
|
||||
setCreativeTab(WebDisplays.CREATIVE_TAB);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos_, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
|
||||
if(player.isSneaking())
|
||||
return EnumActionResult.PASS;
|
||||
|
||||
if(world.isRemote)
|
||||
return EnumActionResult.SUCCESS;
|
||||
|
||||
ItemStack stack = player.getHeldItem(hand);
|
||||
if(stack.hasTagCompound()) {
|
||||
NBTTagCompound tag = stack.getTagCompound();
|
||||
|
||||
if(tag.hasKey("ScreenX") && tag.hasKey("ScreenY") && tag.hasKey("ScreenZ") && tag.hasKey("ScreenSide")) {
|
||||
IBlockState state = world.getBlockState(pos_);
|
||||
IPeripheral target;
|
||||
|
||||
if(state.getBlock() instanceof IPeripheral)
|
||||
target = (IPeripheral) state.getBlock();
|
||||
else {
|
||||
TileEntity te = world.getTileEntity(pos_);
|
||||
if(te == null || !(te instanceof IPeripheral)) {
|
||||
Util.toast(player, "peripheral");
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
target = (IPeripheral) te;
|
||||
}
|
||||
|
||||
Vector3i tePos = new Vector3i(tag.getInteger("ScreenX"), tag.getInteger("ScreenY"), tag.getInteger("ScreenZ"));
|
||||
BlockSide scrSide = BlockSide.values()[tag.getByte("ScreenSide")];
|
||||
|
||||
if(target.connect(world, pos_, state, tePos, scrSide))
|
||||
Util.toast(player, TextFormatting.AQUA, "linked");
|
||||
else
|
||||
Util.toast(player, "linkError");
|
||||
|
||||
stack.setTagCompound(null);
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if(!(world.getBlockState(pos_).getBlock() instanceof BlockScreen)) {
|
||||
Util.toast(player, "notAScreen");
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
Vector3i pos = new Vector3i(pos_);
|
||||
BlockSide side = BlockSide.values()[facing.ordinal()];
|
||||
Multiblock.findOrigin(world, pos, side, null);
|
||||
|
||||
TileEntity te = world.getTileEntity(pos.toBlock());
|
||||
if(te == null || !(te instanceof TileEntityScreen)) {
|
||||
Util.toast(player, "turnOn");
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
TileEntityScreen.Screen scr = ((TileEntityScreen) te).getScreen(side);
|
||||
if(scr == null)
|
||||
Util.toast(player, "turnOn");
|
||||
else if((scr.rightsFor(player) & ScreenRights.MANAGE_UPGRADES) == 0)
|
||||
Util.toast(player, "restrictions");
|
||||
else {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setInteger("ScreenX", pos.x);
|
||||
tag.setInteger("ScreenY", pos.y);
|
||||
tag.setInteger("ScreenZ", pos.z);
|
||||
tag.setByte("ScreenSide", (byte) side.ordinal());
|
||||
|
||||
stack.setTagCompound(tag);
|
||||
Util.toast(player, TextFormatting.AQUA, "screenSet2");
|
||||
}
|
||||
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void addInformation(ItemStack stack, @Nullable World world, List<String> tt, ITooltipFlag ttFlag) {
|
||||
if(stack.hasTagCompound()) {
|
||||
NBTTagCompound tag = stack.getTagCompound();
|
||||
|
||||
if(tag.hasKey("ScreenX") && tag.hasKey("ScreenY") && tag.hasKey("ScreenZ") && tag.hasKey("ScreenSide")) {
|
||||
tt.add(I18n.format("webdisplays.linker.selectPeripheral"));
|
||||
tt.add(I18n.format("webdisplays.linker.posInfo", tag.getInteger("ScreenX"), tag.getInteger("ScreenY"), tag.getInteger("ScreenZ")));
|
||||
tt.add(I18n.format("webdisplays.linker.sideInfo", BlockSide.values()[tag.getByte("ScreenSide")].toString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
tt.add(I18n.format("webdisplays.linker.selectScreen"));
|
||||
}
|
||||
|
||||
}
|
||||
59
src/main/java/net/montoyo/wd/item/ItemMinePad2.java
Normal file
59
src/main/java/net/montoyo/wd/item/ItemMinePad2.java
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.item;
|
||||
|
||||
import com.mojang.realmsclient.gui.ChatFormatting;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
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.EnumHand;
|
||||
import net.minecraft.world.World;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class ItemMinePad2 extends Item {
|
||||
|
||||
public ItemMinePad2() {
|
||||
setUnlocalizedName("webdisplays.minepad");
|
||||
setRegistryName("minepad");
|
||||
setMaxStackSize(1);
|
||||
setFull3D();
|
||||
setCreativeTab(WebDisplays.CREATIVE_TAB);
|
||||
}
|
||||
|
||||
private static String getURL(ItemStack is) {
|
||||
if(is.getTagCompound() == null || !is.getTagCompound().hasKey("PadURL"))
|
||||
return WebDisplays.INSTANCE.homePage;
|
||||
else
|
||||
return is.getTagCompound().getString("PadURL");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer ply, EnumHand hand) {
|
||||
ItemStack is = ply.getHeldItem(hand);
|
||||
|
||||
if(world.isRemote) {
|
||||
if(ply.isSneaking())
|
||||
WebDisplays.PROXY.displaySetPadURLGui(getURL(is));
|
||||
else if(is.getTagCompound() != null && is.getTagCompound().hasKey("PadID"))
|
||||
WebDisplays.PROXY.openMinePadGui(is.getTagCompound().getInteger("PadID"));
|
||||
}
|
||||
|
||||
return ActionResult.newResult(EnumActionResult.SUCCESS, is);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInformation(ItemStack is, @Nullable World world, List<String> tt, ITooltipFlag ttFlags) {
|
||||
if(is == null || is.getTagCompound() == null || !is.getTagCompound().hasKey("PadID"))
|
||||
tt.add("" + ChatFormatting.ITALIC + ChatFormatting.GRAY + I18n.format("webdisplays.minepad.turnon"));
|
||||
}
|
||||
|
||||
}
|
||||
121
src/main/java/net/montoyo/wd/item/ItemOwnershipThief.java
Normal file
121
src/main/java/net/montoyo/wd/item/ItemOwnershipThief.java
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.item;
|
||||
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.block.BlockScreen;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.utilities.*;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class ItemOwnershipThief extends Item {
|
||||
|
||||
public ItemOwnershipThief() {
|
||||
setUnlocalizedName("webdisplays.ownerthief");
|
||||
setRegistryName("ownerthief");
|
||||
setMaxStackSize(1);
|
||||
setCreativeTab(WebDisplays.CREATIVE_TAB);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos_, EnumHand hand, EnumFacing side_, float hitX, float hitY, float hitZ) {
|
||||
if(player.isSneaking())
|
||||
return EnumActionResult.PASS;
|
||||
|
||||
if(world.isRemote)
|
||||
return EnumActionResult.SUCCESS;
|
||||
|
||||
ItemStack stack = player.getHeldItem(hand);
|
||||
if(stack.hasTagCompound()) {
|
||||
NBTTagCompound tag = stack.getTagCompound();
|
||||
|
||||
if(tag.hasKey("PosX") && tag.hasKey("PosY") && tag.hasKey("PosZ") && tag.hasKey("Side")) {
|
||||
BlockPos bp = new BlockPos(tag.getInteger("PosX"), tag.getInteger("PosY"), tag.getInteger("PosZ"));
|
||||
BlockSide side = BlockSide.values()[tag.getByte("Side")];
|
||||
|
||||
if(!(world.getBlockState(bp).getBlock() instanceof BlockScreen))
|
||||
return EnumActionResult.SUCCESS;
|
||||
|
||||
TileEntity te = world.getTileEntity(bp);
|
||||
if(te == null || !(te instanceof TileEntityScreen))
|
||||
return EnumActionResult.SUCCESS;
|
||||
|
||||
TileEntityScreen.Screen scr = ((TileEntityScreen) te).getScreen(side);
|
||||
if(scr == null)
|
||||
return EnumActionResult.SUCCESS;
|
||||
|
||||
Log.warning("Owner of screen at %d %d %d, side %s was changed from %s (UUID %s) to %s (UUID %s)", bp.getX(), bp.getY(), bp.getZ(), side.toString(), scr.owner.name, scr.owner.uuid.toString(), player.getName(), player.getGameProfile().getId().toString());
|
||||
scr.setOwner(player);
|
||||
player.setHeldItem(hand, ItemStack.EMPTY);
|
||||
Util.toast(player, TextFormatting.AQUA, "newOwner");
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if(!(world.getBlockState(pos_).getBlock() instanceof BlockScreen))
|
||||
return EnumActionResult.SUCCESS;
|
||||
|
||||
Vector3i pos = new Vector3i(pos_);
|
||||
BlockSide side = BlockSide.values()[side_.ordinal()];
|
||||
Multiblock.findOrigin(world, pos, side, null);
|
||||
|
||||
TileEntity te = world.getTileEntity(pos.toBlock());
|
||||
if(te == null || !(te instanceof TileEntityScreen)) {
|
||||
Util.toast(player, "turnOn");
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
if(((TileEntityScreen) te).getScreen(side) == null)
|
||||
Util.toast(player, "turnOn");
|
||||
else {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setInteger("PosX", pos.x);
|
||||
tag.setInteger("PosY", pos.y);
|
||||
tag.setInteger("PosZ", pos.z);
|
||||
tag.setByte("Side", (byte) side.ordinal());
|
||||
|
||||
stack.setTagCompound(tag);
|
||||
Util.toast(player, TextFormatting.AQUA, "screenSet");
|
||||
Log.warning("Player %s (UUID %s) created an Ownership Thief item for screen at %d %d %d, side %s!", player.getName(), player.getGameProfile().getId().toString(), pos.x, pos.y, pos.z, side.toString());
|
||||
}
|
||||
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void addInformation(ItemStack stack, @Nullable World world, List<String> tt, ITooltipFlag ttFlags) {
|
||||
if(stack.hasTagCompound()) {
|
||||
NBTTagCompound tag = stack.getTagCompound();
|
||||
|
||||
if(tag.hasKey("PosX") && tag.hasKey("PosY") && tag.hasKey("PosZ") && tag.hasKey("Side")) {
|
||||
tt.add("Screen pos: " + tag.getInteger("PosX") + ", " + tag.getInteger("PosY") + ", " + tag.getInteger("PosZ"));
|
||||
tt.add("Screen side: " + BlockSide.values()[tag.getByte("Side")].toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
tt.add("" + TextFormatting.RED + "WARNING: Admin tool");
|
||||
tt.add("Right click on screen");
|
||||
tt.add("and give to new owner.");
|
||||
}
|
||||
|
||||
}
|
||||
51
src/main/java/net/montoyo/wd/item/ItemPeripheral.java
Normal file
51
src/main/java/net/montoyo/wd/item/ItemPeripheral.java
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.item;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemMultiTexture;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.World;
|
||||
import net.montoyo.wd.block.BlockKeyboardRight;
|
||||
import net.montoyo.wd.core.DefaultPeripheral;
|
||||
|
||||
public class ItemPeripheral extends ItemMultiTexture {
|
||||
|
||||
public ItemPeripheral(Block block) {
|
||||
super(block, block, new ItemMultiTexture.Mapper() {
|
||||
@Override
|
||||
public String apply(ItemStack is) {
|
||||
return DefaultPeripheral.values()[is.getMetadata()].getName();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlaceBlockOnSide(World world, BlockPos pos_, EnumFacing side, EntityPlayer player, ItemStack stack) {
|
||||
if(stack.getMetadata() != 0)
|
||||
return true;
|
||||
|
||||
//Special checks for the keyboard
|
||||
BlockPos pos = pos_.add(side.getDirectionVec());
|
||||
if(world.isAirBlock(pos.down()) || !BlockKeyboardRight.checkNeighborhood(world, pos, null))
|
||||
return false;
|
||||
|
||||
int f = MathHelper.floor(((double) (player.rotationYaw * 4.0f / 360.0f)) + 2.5) & 3;
|
||||
Vec3i dir = EnumFacing.getHorizontal(f).rotateY().getDirectionVec();
|
||||
BlockPos left = pos.add(dir);
|
||||
BlockPos right = pos.subtract(dir);
|
||||
|
||||
if(world.isAirBlock(right) && !world.isAirBlock(right.down()) && BlockKeyboardRight.checkNeighborhood(world, right, null))
|
||||
return true;
|
||||
else
|
||||
return world.isAirBlock(left) && !world.isAirBlock(left.down()) && BlockKeyboardRight.checkNeighborhood(world, left, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.item;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
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 net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.block.BlockScreen;
|
||||
import net.montoyo.wd.data.ScreenConfigData;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Multiblock;
|
||||
import net.montoyo.wd.utilities.Util;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
|
||||
public class ItemScreenConfigurator extends Item {
|
||||
|
||||
public ItemScreenConfigurator() {
|
||||
setUnlocalizedName("webdisplays.screencfg");
|
||||
setRegistryName("screencfg");
|
||||
setMaxStackSize(1);
|
||||
setCreativeTab(WebDisplays.CREATIVE_TAB);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing side_, float hitX, float hitY, float hitZ) {
|
||||
if(player.isSneaking() || !(world.getBlockState(pos).getBlock() instanceof BlockScreen))
|
||||
return EnumActionResult.PASS;
|
||||
|
||||
if(world.isRemote)
|
||||
return EnumActionResult.SUCCESS;
|
||||
|
||||
Vector3i origin = new Vector3i(pos);
|
||||
BlockSide side = BlockSide.values()[side_.ordinal()];
|
||||
|
||||
Multiblock.findOrigin(world, origin, side, null);
|
||||
TileEntity te = world.getTileEntity(origin.toBlock());
|
||||
|
||||
if(te == null || !(te instanceof TileEntityScreen)) {
|
||||
Util.toast(player, "turnOn");
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
TileEntityScreen.Screen scr = ((TileEntityScreen) te).getScreen(side);
|
||||
if(scr == null)
|
||||
Util.toast(player, "turnOn");
|
||||
else
|
||||
(new ScreenConfigData(origin, side, scr)).sendTo((EntityPlayerMP) player);
|
||||
|
||||
return EnumActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
59
src/main/java/net/montoyo/wd/net/CMessageACResult.java
Normal file
59
src/main/java/net/montoyo/wd/net/CMessageACResult.java
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.net;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.utilities.NameUUIDPair;
|
||||
|
||||
@Message(messageId = 6, side = Side.CLIENT)
|
||||
public class CMessageACResult implements IMessage, Runnable {
|
||||
|
||||
private NameUUIDPair[] result;
|
||||
|
||||
public CMessageACResult() {
|
||||
}
|
||||
|
||||
public CMessageACResult(GameProfile gp) {
|
||||
result = new NameUUIDPair[] { new NameUUIDPair(gp) };
|
||||
}
|
||||
|
||||
public CMessageACResult(GameProfile[] gps) {
|
||||
result = new NameUUIDPair[gps.length];
|
||||
|
||||
for(int i = 0; i < gps.length; i++)
|
||||
result[i] = new NameUUIDPair(gps[i]);
|
||||
}
|
||||
|
||||
public CMessageACResult(NameUUIDPair[] pairs) {
|
||||
result = pairs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
int cnt = buf.readByte();
|
||||
result = new NameUUIDPair[cnt];
|
||||
|
||||
for(int i = 0; i < cnt; i++)
|
||||
result[i] = new NameUUIDPair(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf) {
|
||||
buf.writeByte(result.length);
|
||||
|
||||
for(int i = 0; i < result.length; i++)
|
||||
result[i].writeTo(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
WebDisplays.PROXY.onAutocompleteResult(result);
|
||||
}
|
||||
|
||||
}
|
||||
98
src/main/java/net/montoyo/wd/net/CMessageAddScreen.java
Normal file
98
src/main/java/net/montoyo/wd/net/CMessageAddScreen.java
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.net;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.fml.common.network.ByteBufUtils;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.montoyo.wd.SharedProxy;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
import net.montoyo.wd.utilities.Vector2i;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
|
||||
@Message(messageId = 0, side = Side.CLIENT)
|
||||
public class CMessageAddScreen implements IMessage, Runnable {
|
||||
|
||||
private boolean clear;
|
||||
private Vector3i pos;
|
||||
private TileEntityScreen.Screen[] screens;
|
||||
|
||||
public CMessageAddScreen() {
|
||||
}
|
||||
|
||||
public CMessageAddScreen(TileEntityScreen tes) {
|
||||
clear = true;
|
||||
pos = new Vector3i(tes.getPos());
|
||||
screens = new TileEntityScreen.Screen[tes.screenCount()];
|
||||
|
||||
for(int i = 0; i < tes.screenCount(); i++)
|
||||
screens[i] = tes.getScreen(i);
|
||||
}
|
||||
|
||||
public CMessageAddScreen(TileEntityScreen tes, TileEntityScreen.Screen ... toSend) {
|
||||
clear = false;
|
||||
pos = new Vector3i(tes.getPos());
|
||||
screens = toSend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
clear = buf.readBoolean();
|
||||
pos = new Vector3i(buf);
|
||||
int cnt = buf.readByte() & 7;
|
||||
|
||||
screens = new TileEntityScreen.Screen[cnt];
|
||||
for(int i = 0; i < cnt; i++) {
|
||||
screens[i] = new TileEntityScreen.Screen();
|
||||
screens[i].side = BlockSide.values()[buf.readByte()];
|
||||
screens[i].size = new Vector2i(buf);
|
||||
screens[i].url = ByteBufUtils.readUTF8String(buf);
|
||||
screens[i].resolution = new Vector2i(buf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf) {
|
||||
buf.writeBoolean(clear);
|
||||
pos.writeTo(buf);
|
||||
buf.writeByte(screens.length);
|
||||
|
||||
for(TileEntityScreen.Screen scr: screens) {
|
||||
buf.writeByte(scr.side.ordinal());
|
||||
scr.size.writeTo(buf);
|
||||
ByteBufUtils.writeUTF8String(buf, scr.url);
|
||||
scr.resolution.writeTo(buf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
TileEntity te = WebDisplays.PROXY.getWorld(SharedProxy.CURRENT_DIMENSION).getTileEntity(pos.toBlock());
|
||||
if(te == null || !(te instanceof TileEntityScreen)) {
|
||||
if(clear)
|
||||
Log.error("CMessageAddScreen: Can't add screen to invalid tile entity at %s", pos.toString());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
TileEntityScreen tes = (TileEntityScreen) te;
|
||||
if(clear)
|
||||
tes.clear();
|
||||
|
||||
for(TileEntityScreen.Screen entry: screens) {
|
||||
TileEntityScreen.Screen scr = tes.addScreen(entry.side, entry.size, entry.resolution, false);
|
||||
scr.url = entry.url;
|
||||
|
||||
if(scr.browser != null)
|
||||
scr.browser.loadURL(entry.url);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
52
src/main/java/net/montoyo/wd/net/CMessageOpenGui.java
Normal file
52
src/main/java/net/montoyo/wd/net/CMessageOpenGui.java
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.net;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraftforge.fml.common.network.ByteBufUtils;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.montoyo.mcef.utilities.Log;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.data.GuiData;
|
||||
import net.montoyo.wd.utilities.Util;
|
||||
|
||||
@Message(messageId = 3, side = Side.CLIENT)
|
||||
public class CMessageOpenGui implements IMessage, Runnable {
|
||||
|
||||
private GuiData data;
|
||||
|
||||
public CMessageOpenGui() {
|
||||
}
|
||||
|
||||
public CMessageOpenGui(GuiData data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
String name = ByteBufUtils.readUTF8String(buf);
|
||||
Class<? extends GuiData> cls = GuiData.classOf(name);
|
||||
|
||||
if(cls == null) {
|
||||
Log.error("Could not create GuiData of type %s because it doesn't exist!", name);
|
||||
return;
|
||||
}
|
||||
|
||||
data = (GuiData) Util.unserialize(buf, cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf) {
|
||||
ByteBufUtils.writeUTF8String(buf, data.getName());
|
||||
Util.serialize(buf, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
WebDisplays.PROXY.displayGui(data);
|
||||
}
|
||||
|
||||
}
|
||||
147
src/main/java/net/montoyo/wd/net/CMessageScreenUpdate.java
Normal file
147
src/main/java/net/montoyo/wd/net/CMessageScreenUpdate.java
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.net;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.fml.common.network.ByteBufUtils;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.montoyo.wd.SharedProxy;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
import net.montoyo.wd.utilities.Vector2i;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
|
||||
@Message(messageId = 4, side = Side.CLIENT)
|
||||
public class CMessageScreenUpdate implements IMessage, Runnable {
|
||||
|
||||
public static final int UPDATE_URL = 0;
|
||||
public static final int UPDATE_RESOLUTION = 1;
|
||||
public static final int UPDATE_DELETE = 2;
|
||||
public static final int UPDATE_CLICK = 3;
|
||||
public static final int UPDATE_TYPE = 4;
|
||||
|
||||
private Vector3i pos;
|
||||
private BlockSide side;
|
||||
private int action;
|
||||
private String url;
|
||||
private Vector2i resolution;
|
||||
private Vector2i click;
|
||||
private String text;
|
||||
|
||||
public CMessageScreenUpdate() {
|
||||
}
|
||||
|
||||
public static CMessageScreenUpdate setURL(TileEntityScreen tes, BlockSide side, String url) {
|
||||
CMessageScreenUpdate ret = new CMessageScreenUpdate();
|
||||
ret.pos = new Vector3i(tes.getPos());
|
||||
ret.side = side;
|
||||
ret.action = UPDATE_URL;
|
||||
ret.url = url;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static CMessageScreenUpdate setResolution(TileEntityScreen tes, BlockSide side, Vector2i res) {
|
||||
CMessageScreenUpdate ret = new CMessageScreenUpdate();
|
||||
ret.pos = new Vector3i(tes.getPos());
|
||||
ret.side = side;
|
||||
ret.action = UPDATE_RESOLUTION;
|
||||
ret.resolution = res;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static CMessageScreenUpdate click(TileEntityScreen tes, BlockSide side, Vector2i pos) {
|
||||
CMessageScreenUpdate ret = new CMessageScreenUpdate();
|
||||
ret.pos = new Vector3i(tes.getPos());
|
||||
ret.side = side;
|
||||
ret.action = UPDATE_CLICK;
|
||||
ret.click = pos;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public CMessageScreenUpdate(TileEntityScreen tes, BlockSide side) {
|
||||
pos = new Vector3i(tes.getPos());
|
||||
this.side = side;
|
||||
action = UPDATE_DELETE;
|
||||
}
|
||||
|
||||
public static CMessageScreenUpdate type(TileEntityScreen tes, BlockSide side, String text) {
|
||||
CMessageScreenUpdate ret = new CMessageScreenUpdate();
|
||||
ret.pos = new Vector3i(tes.getPos());
|
||||
ret.side = side;
|
||||
ret.text = text;
|
||||
ret.action = UPDATE_TYPE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
pos = new Vector3i(buf);
|
||||
side = BlockSide.values()[buf.readByte()];
|
||||
action = buf.readByte();
|
||||
|
||||
if(action == UPDATE_URL)
|
||||
url = ByteBufUtils.readUTF8String(buf);
|
||||
else if(action == UPDATE_CLICK)
|
||||
click = new Vector2i(buf);
|
||||
else if(action == UPDATE_RESOLUTION)
|
||||
resolution = new Vector2i(buf);
|
||||
else if(action == UPDATE_TYPE)
|
||||
text = ByteBufUtils.readUTF8String(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf) {
|
||||
pos.writeTo(buf);
|
||||
buf.writeByte(side.ordinal());
|
||||
buf.writeByte(action);
|
||||
|
||||
if(action == UPDATE_URL)
|
||||
ByteBufUtils.writeUTF8String(buf, url);
|
||||
else if(action == UPDATE_CLICK)
|
||||
click.writeTo(buf);
|
||||
else if(action == UPDATE_RESOLUTION)
|
||||
resolution.writeTo(buf);
|
||||
else if(action == UPDATE_TYPE)
|
||||
ByteBufUtils.writeUTF8String(buf, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
TileEntity te = WebDisplays.PROXY.getWorld(SharedProxy.CURRENT_DIMENSION).getTileEntity(pos.toBlock());
|
||||
if(te == null || !(te instanceof TileEntityScreen)) {
|
||||
Log.error("CMessageScreenUpdate: TileEntity at %s is not a screen!", pos.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
TileEntityScreen tes = (TileEntityScreen) te;
|
||||
/*TileEntityScreen.Screen scr = tes.getScreen(side);
|
||||
if(scr == null) {
|
||||
Log.error("CMessageScreenUpdate: No screen on side %s at %s", side.toString(), pos.toString());
|
||||
return;
|
||||
}*/
|
||||
|
||||
if(action == UPDATE_URL)
|
||||
tes.setScreenURL(side, url);
|
||||
else if(action == UPDATE_CLICK)
|
||||
tes.click(side, click);
|
||||
else if(action == UPDATE_DELETE)
|
||||
tes.removeScreen(side);
|
||||
else if(action == UPDATE_RESOLUTION)
|
||||
tes.setResolution(side, resolution);
|
||||
else if(action == UPDATE_TYPE)
|
||||
tes.type(side, text, null);
|
||||
else
|
||||
Log.warning("===> TODO"); //TODO
|
||||
}
|
||||
|
||||
}
|
||||
20
src/main/java/net/montoyo/wd/net/DefaultHandler.java
Normal file
20
src/main/java/net/montoyo/wd/net/DefaultHandler.java
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.net;
|
||||
|
||||
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.montoyo.wd.WebDisplays;
|
||||
|
||||
public class DefaultHandler implements IMessageHandler<IMessage, IMessage> {
|
||||
|
||||
@Override
|
||||
public IMessage onMessage(IMessage message, MessageContext ctx) {
|
||||
WebDisplays.PROXY.enqueue((Runnable) message);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
21
src/main/java/net/montoyo/wd/net/Message.java
Normal file
21
src/main/java/net/montoyo/wd/net/Message.java
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.net;
|
||||
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Message {
|
||||
|
||||
int messageId();
|
||||
Side side();
|
||||
|
||||
}
|
||||
66
src/main/java/net/montoyo/wd/net/Messages.java
Normal file
66
src/main/java/net/montoyo/wd/net/Messages.java
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.net;
|
||||
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Messages {
|
||||
|
||||
private static DefaultHandler DEFAULT_HANDLER = new DefaultHandler();
|
||||
private static Class<? extends IMessage>[] messages;
|
||||
static {
|
||||
ArrayList<Class<? extends IMessage>> l = new ArrayList<Class<? extends IMessage>>();
|
||||
l.add(CMessageAddScreen.class);
|
||||
l.add(SMessageRequestTEData.class);
|
||||
l.add(SMessageScreenCtrl.class);
|
||||
l.add(CMessageOpenGui.class);
|
||||
l.add(CMessageScreenUpdate.class);
|
||||
l.add(SMessageACQuery.class);
|
||||
l.add(CMessageACResult.class);
|
||||
l.add(SMessagePadCtrl.class);
|
||||
|
||||
messages = l.toArray(new Class[0]);
|
||||
}
|
||||
|
||||
public static void registerAll(SimpleNetworkWrapper wrapper) {
|
||||
for(Class<? extends IMessage> md: messages) {
|
||||
Message data = md.getAnnotation(Message.class);
|
||||
if(data == null)
|
||||
throw new RuntimeException("Missing @Message annotation for message class " + md.getSimpleName());
|
||||
|
||||
Class<?>[] classes = md.getClasses();
|
||||
Class<? extends IMessageHandler> handler = null;
|
||||
|
||||
for(Class<?> cls: classes) {
|
||||
if(cls.getSimpleName().equals("Handler") && Modifier.isStatic(cls.getModifiers()) && IMessageHandler.class.isAssignableFrom(cls)) {
|
||||
handler = (Class<? extends IMessageHandler>) cls;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IMessageHandler handlerInst;
|
||||
if(handler == null) {
|
||||
if(Runnable.class.isAssignableFrom(md))
|
||||
handlerInst = DEFAULT_HANDLER;
|
||||
else
|
||||
throw new RuntimeException("Could not find message handler for message " + md.getSimpleName());
|
||||
} else {
|
||||
try {
|
||||
handlerInst = handler.newInstance();
|
||||
} catch(Throwable t) {
|
||||
throw new RuntimeException("Could not instantiate message handler for message " + md.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.registerMessage(handlerInst, md, data.messageId(), data.side());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
89
src/main/java/net/montoyo/wd/net/SMessageACQuery.java
Normal file
89
src/main/java/net/montoyo/wd/net/SMessageACQuery.java
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.net;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.fml.common.network.ByteBufUtils;
|
||||
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 net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.utilities.NameUUIDPair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@Message(messageId = 5, side = Side.SERVER)
|
||||
public class SMessageACQuery implements IMessage, Runnable {
|
||||
|
||||
private EntityPlayerMP player;
|
||||
private String beginning;
|
||||
private boolean matchExact;
|
||||
|
||||
public SMessageACQuery() {
|
||||
}
|
||||
|
||||
public SMessageACQuery(String beg, boolean exact) {
|
||||
beginning = beg;
|
||||
matchExact = exact;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
beginning = ByteBufUtils.readUTF8String(buf);
|
||||
matchExact = buf.readBoolean();
|
||||
|
||||
if(!matchExact)
|
||||
beginning = beginning.toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf) {
|
||||
ByteBufUtils.writeUTF8String(buf, beginning);
|
||||
buf.writeBoolean(matchExact);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
GameProfile[] profiles = WebDisplays.PROXY.getOnlineGameProfiles();
|
||||
|
||||
if(matchExact) {
|
||||
for(GameProfile gp : profiles) {
|
||||
if(gp.getName().equals(beginning)) {
|
||||
WebDisplays.NET_HANDLER.sendTo(new CMessageACResult(gp), player);
|
||||
return;
|
||||
}
|
||||
|
||||
WebDisplays.NET_HANDLER.sendTo(new CMessageACResult(new NameUUIDPair[0]), player);
|
||||
}
|
||||
} else {
|
||||
ArrayList<NameUUIDPair> results = new ArrayList<NameUUIDPair>();
|
||||
|
||||
for(GameProfile gp : profiles) {
|
||||
if(gp.getName().toLowerCase().startsWith(beginning)) {
|
||||
results.add(new NameUUIDPair(gp));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WebDisplays.NET_HANDLER.sendTo(new CMessageACResult(results.toArray(new NameUUIDPair[0])), player);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Handler implements IMessageHandler<SMessageACQuery, IMessage> {
|
||||
|
||||
@Override
|
||||
public IMessage onMessage(SMessageACQuery msg, MessageContext ctx) {
|
||||
msg.player = ctx.getServerHandler().player;
|
||||
((WorldServer) msg.player.world).addScheduledTask(msg);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
106
src/main/java/net/montoyo/wd/net/SMessagePadCtrl.java
Normal file
106
src/main/java/net/montoyo/wd/net/SMessagePadCtrl.java
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.net;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.fml.common.network.ByteBufUtils;
|
||||
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 net.montoyo.wd.WebDisplays;
|
||||
|
||||
@Message(messageId = 7, side = Side.SERVER)
|
||||
public class SMessagePadCtrl implements IMessage, Runnable {
|
||||
|
||||
private int id;
|
||||
private String url;
|
||||
private EntityPlayer player;
|
||||
|
||||
public SMessagePadCtrl() {
|
||||
}
|
||||
|
||||
public SMessagePadCtrl(String url) {
|
||||
id = -1;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public SMessagePadCtrl(int id, String url) {
|
||||
this.id = id;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
private boolean matchesMinePadID(ItemStack is) {
|
||||
return is.getItem() == WebDisplays.INSTANCE.itemMinePad && is.getTagCompound() != null && is.getTagCompound().hasKey("PadID") && is.getTagCompound().getInteger("PadID") == id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if(id < 0) {
|
||||
ItemStack is = player.getHeldItem(EnumHand.MAIN_HAND);
|
||||
|
||||
if(is.getItem() == WebDisplays.INSTANCE.itemMinePad) {
|
||||
if(url.isEmpty())
|
||||
is.setTagCompound(null); //Shutdown
|
||||
else {
|
||||
//TODO: Check if site is not blacklisted
|
||||
if(is.getTagCompound() == null)
|
||||
is.setTagCompound(new NBTTagCompound());
|
||||
|
||||
if(!is.getTagCompound().hasKey("PadID"))
|
||||
is.getTagCompound().setInteger("PadID", WebDisplays.getNextAvailablePadID());
|
||||
|
||||
is.getTagCompound().setString("PadURL", url);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NonNullList<ItemStack> inv = player.inventory.mainInventory;
|
||||
ItemStack target = null;
|
||||
|
||||
for(int i = 0; i < 9; i++) {
|
||||
if(matchesMinePadID(inv.get(i))) {
|
||||
target = inv.get(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(target == null && matchesMinePadID(player.inventory.offHandInventory.get(0)))
|
||||
target = player.inventory.offHandInventory.get(0);
|
||||
|
||||
if(target != null)
|
||||
target.getTagCompound().setString("PadURL", url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
id = buf.readInt();
|
||||
url = ByteBufUtils.readUTF8String(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf) {
|
||||
buf.writeInt(id);
|
||||
ByteBufUtils.writeUTF8String(buf, url);
|
||||
}
|
||||
|
||||
public static class Handler implements IMessageHandler<SMessagePadCtrl, IMessage> {
|
||||
|
||||
@Override
|
||||
public IMessage onMessage(SMessagePadCtrl msg, MessageContext ctx) {
|
||||
msg.player = ctx.getServerHandler().player;
|
||||
((WorldServer) msg.player.world).addScheduledTask(msg);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
77
src/main/java/net/montoyo/wd/net/SMessageRequestTEData.java
Normal file
77
src/main/java/net/montoyo/wd/net/SMessageRequestTEData.java
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.net;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.WorldServer;
|
||||
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 net.montoyo.mcef.utilities.Log;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
|
||||
@Message(messageId = 1, side = Side.SERVER)
|
||||
public class SMessageRequestTEData implements IMessage, Runnable {
|
||||
|
||||
private int dim;
|
||||
private Vector3i pos;
|
||||
private EntityPlayerMP player;
|
||||
|
||||
public SMessageRequestTEData() {
|
||||
}
|
||||
|
||||
public SMessageRequestTEData(TileEntity te) {
|
||||
dim = te.getWorld().provider.getDimension();
|
||||
pos = new Vector3i(te.getPos());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
dim = buf.readInt();
|
||||
pos = new Vector3i(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf) {
|
||||
buf.writeInt(dim);
|
||||
pos.writeTo(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if(player.world.provider.getDimension() != dim)
|
||||
return;
|
||||
|
||||
BlockPos bp = pos.toBlock();
|
||||
if(player.getDistanceSq(bp) > 512.0 * 512.0)
|
||||
return;
|
||||
|
||||
TileEntity te = player.world.getTileEntity(bp);
|
||||
if(te == null) {
|
||||
Log.error("MesageRequestTEData: Can't request data of null tile entity at %s", pos.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
if(te instanceof TileEntityScreen)
|
||||
((TileEntityScreen) te).requestData(player);
|
||||
}
|
||||
|
||||
public static class Handler implements IMessageHandler<SMessageRequestTEData, IMessage> {
|
||||
|
||||
@Override
|
||||
public IMessage onMessage(SMessageRequestTEData message, MessageContext ctx) {
|
||||
message.player = ctx.getServerHandler().player;
|
||||
((WorldServer) message.player.world).addScheduledTask(message);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
223
src/main/java/net/montoyo/wd/net/SMessageScreenCtrl.java
Normal file
223
src/main/java/net/montoyo/wd/net/SMessageScreenCtrl.java
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.net;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.fml.common.network.ByteBufUtils;
|
||||
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 net.montoyo.wd.core.MissingPermissionException;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.utilities.*;
|
||||
|
||||
@Message(messageId = 2, side = Side.SERVER)
|
||||
public class SMessageScreenCtrl implements IMessage, Runnable {
|
||||
|
||||
public static final int CTRL_SET_URL = 0;
|
||||
public static final int CTRL_SHUT_DOWN = 1;
|
||||
public static final int CTRL_ADD_FRIEND = 2;
|
||||
public static final int CTRL_REMOVE_FRIEND = 3;
|
||||
public static final int CTRL_SET_RIGHTS = 4;
|
||||
public static final int CTRL_SET_RESOLUTION = 5;
|
||||
public static final int CTRL_TYPE = 6;
|
||||
|
||||
private int ctrl;
|
||||
private int dim;
|
||||
private Vector3i pos;
|
||||
private BlockSide side;
|
||||
private String url;
|
||||
private NameUUIDPair friend;
|
||||
private EntityPlayerMP player;
|
||||
private int friendRights;
|
||||
private int otherRights;
|
||||
private Vector2i resolution;
|
||||
private String text;
|
||||
private BlockPos soundPos;
|
||||
|
||||
public SMessageScreenCtrl() {
|
||||
}
|
||||
|
||||
public SMessageScreenCtrl(TileEntityScreen tes, BlockSide side, String url) {
|
||||
ctrl = CTRL_SET_URL;
|
||||
dim = tes.getWorld().provider.getDimension();
|
||||
pos = new Vector3i(tes.getPos());
|
||||
this.side = side;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public SMessageScreenCtrl(TileEntityScreen tes, BlockSide side) {
|
||||
ctrl = CTRL_SHUT_DOWN;
|
||||
dim = tes.getWorld().provider.getDimension();
|
||||
pos = new Vector3i(tes.getPos());
|
||||
this.side = side;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public SMessageScreenCtrl(TileEntityScreen tes, BlockSide side, NameUUIDPair friend, boolean del) {
|
||||
ctrl = del ? CTRL_REMOVE_FRIEND : CTRL_ADD_FRIEND;
|
||||
dim = tes.getWorld().provider.getDimension();
|
||||
pos = new Vector3i(tes.getPos());
|
||||
this.side = side;
|
||||
this.friend = friend;
|
||||
}
|
||||
|
||||
public SMessageScreenCtrl(TileEntityScreen tes, BlockSide side, int fr, int or) {
|
||||
ctrl = CTRL_SET_RIGHTS;
|
||||
dim = tes.getWorld().provider.getDimension();
|
||||
pos = new Vector3i(tes.getPos());
|
||||
this.side = side;
|
||||
friendRights = fr;
|
||||
otherRights = or;
|
||||
}
|
||||
|
||||
public SMessageScreenCtrl(TileEntityScreen tes, BlockSide side, Vector2i res) {
|
||||
ctrl = CTRL_SET_RESOLUTION;
|
||||
dim = tes.getWorld().provider.getDimension();
|
||||
pos = new Vector3i(tes.getPos());
|
||||
this.side = side;
|
||||
resolution = res;
|
||||
}
|
||||
|
||||
public static SMessageScreenCtrl type(TileEntityScreen tes, BlockSide side, String text, BlockPos soundPos) {
|
||||
SMessageScreenCtrl ret = new SMessageScreenCtrl();
|
||||
ret.ctrl = CTRL_TYPE;
|
||||
ret.pos = new Vector3i(tes.getPos());
|
||||
ret.dim = tes.getWorld().provider.getDimension();
|
||||
ret.side = side;
|
||||
ret.text = text;
|
||||
ret.soundPos = soundPos;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buf) {
|
||||
ctrl = buf.readByte();
|
||||
dim = buf.readInt();
|
||||
pos = new Vector3i(buf);
|
||||
side = BlockSide.values()[buf.readByte()];
|
||||
|
||||
if(ctrl == CTRL_SET_URL)
|
||||
url = ByteBufUtils.readUTF8String(buf);
|
||||
else if(ctrl == CTRL_ADD_FRIEND || ctrl == CTRL_REMOVE_FRIEND)
|
||||
friend = new NameUUIDPair(buf);
|
||||
else if(ctrl == CTRL_SET_RIGHTS) {
|
||||
friendRights = buf.readByte();
|
||||
otherRights = buf.readByte();
|
||||
} else if(ctrl == CTRL_SET_RESOLUTION)
|
||||
resolution = new Vector2i(buf);
|
||||
else if(ctrl == CTRL_TYPE) {
|
||||
text = ByteBufUtils.readUTF8String(buf);
|
||||
|
||||
int sx = buf.readInt();
|
||||
int sy = buf.readInt();
|
||||
int sz = buf.readInt();
|
||||
soundPos = new BlockPos(sx, sy, sz);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf) {
|
||||
buf.writeByte(ctrl);
|
||||
buf.writeInt(dim);
|
||||
pos.writeTo(buf);
|
||||
buf.writeByte(side.ordinal());
|
||||
|
||||
if(ctrl == CTRL_SET_URL)
|
||||
ByteBufUtils.writeUTF8String(buf, url);
|
||||
else if(ctrl == CTRL_ADD_FRIEND || ctrl == CTRL_REMOVE_FRIEND)
|
||||
friend.writeTo(buf);
|
||||
else if(ctrl == CTRL_SET_RIGHTS) {
|
||||
buf.writeByte(friendRights);
|
||||
buf.writeByte(otherRights);
|
||||
} else if(ctrl == CTRL_SET_RESOLUTION)
|
||||
resolution.writeTo(buf);
|
||||
else if(ctrl == CTRL_TYPE) {
|
||||
ByteBufUtils.writeUTF8String(buf, text);
|
||||
buf.writeInt(soundPos.getX());
|
||||
buf.writeInt(soundPos.getY());
|
||||
buf.writeInt(soundPos.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
runUnsafe();
|
||||
} catch(MissingPermissionException e) {
|
||||
Log.errorEx("I have reasons to believe %s (UUID %s) is a hacker, but don't take my word for it...", e, e.getPlayer().getName(), e.getPlayer().getGameProfile().getId().toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkPermission(TileEntityScreen scr, int right) throws MissingPermissionException {
|
||||
int prights = scr.getScreen(side).rightsFor(player);
|
||||
if((prights & right) == 0)
|
||||
throw new MissingPermissionException(right, player);
|
||||
}
|
||||
|
||||
private void runUnsafe() throws MissingPermissionException {
|
||||
World world = player.world;
|
||||
BlockPos bp = pos.toBlock();
|
||||
|
||||
if(world.provider.getDimension() != dim || player.getDistanceSq(bp) > 512.0 * 512.0)
|
||||
return; //Out of range
|
||||
|
||||
TileEntity te = world.getTileEntity(bp);
|
||||
if(te == null || !(te instanceof TileEntityScreen)) {
|
||||
Log.error("TileEntity at %s is not a screen; can't change url!", pos.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
TileEntityScreen tes = (TileEntityScreen) te;
|
||||
|
||||
if(ctrl == CTRL_SET_URL) {
|
||||
checkPermission(tes, ScreenRights.CHANGE_URL);
|
||||
tes.setScreenURL(side, url);
|
||||
} else if(ctrl == CTRL_SHUT_DOWN) {
|
||||
checkPermission(tes, ScreenRights.CHANGE_URL);
|
||||
tes.removeScreen(side);
|
||||
} else if(ctrl == CTRL_ADD_FRIEND) {
|
||||
checkPermission(tes, ScreenRights.MANAGE_FRIEND_LIST);
|
||||
tes.addFriend(player, side, friend);
|
||||
} else if(ctrl == CTRL_REMOVE_FRIEND) {
|
||||
checkPermission(tes, ScreenRights.MANAGE_FRIEND_LIST);
|
||||
tes.removeFriend(player, side, friend);
|
||||
} else if(ctrl == CTRL_SET_RIGHTS) {
|
||||
TileEntityScreen.Screen scr = tes.getScreen(side);
|
||||
int fr = scr.owner.uuid.equals(player.getGameProfile().getId()) ? friendRights : scr.friendRights;
|
||||
int or = (scr.rightsFor(player) & ScreenRights.MANAGE_OTHER_RIGHTS) == 0 ? scr.otherRights : otherRights;
|
||||
|
||||
if(scr.friendRights != fr || scr.otherRights != or)
|
||||
tes.setRights(player, side, fr, or);
|
||||
} else if(ctrl == CTRL_SET_RESOLUTION) {
|
||||
checkPermission(tes, ScreenRights.CHANGE_RESOLUTION);
|
||||
tes.setResolution(side, resolution);
|
||||
} else if(ctrl == CTRL_TYPE) {
|
||||
checkPermission(tes, ScreenRights.CLICK);
|
||||
tes.type(side, text, soundPos);
|
||||
} else
|
||||
Log.info("SMessageScreenCtrl: TODO"); //TODO: other ctrl messages
|
||||
}
|
||||
|
||||
public static class Handler implements IMessageHandler<SMessageScreenCtrl, IMessage> {
|
||||
|
||||
@Override
|
||||
public IMessage onMessage(SMessageScreenCtrl message, MessageContext ctx) {
|
||||
message.player = ctx.getServerHandler().player;
|
||||
((WorldServer) message.player.world).addScheduledTask(message);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
77
src/main/java/net/montoyo/wd/utilities/AABB.java
Normal file
77
src/main/java/net/montoyo/wd/utilities/AABB.java
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.utilities;
|
||||
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
|
||||
public class AABB {
|
||||
|
||||
public final Vector3i start;
|
||||
public final Vector3i end;
|
||||
|
||||
public AABB() {
|
||||
start = new Vector3i();
|
||||
end = new Vector3i();
|
||||
}
|
||||
|
||||
public AABB(Vector3i pos) {
|
||||
start = pos.clone();
|
||||
end = pos.clone();
|
||||
}
|
||||
|
||||
public AABB(Vector3i a, Vector3i b) {
|
||||
start = new Vector3i();
|
||||
end = new Vector3i();
|
||||
|
||||
start.x = Math.min(a.x, b.x);
|
||||
start.y = Math.min(a.y, b.y);
|
||||
start.z = Math.min(a.z, b.z);
|
||||
end.x = Math.max(a.x, b.x);
|
||||
end.y = Math.max(a.y, b.y);
|
||||
end.z = Math.max(a.z, b.z);
|
||||
}
|
||||
|
||||
public AABB(AxisAlignedBB bb) {
|
||||
start = new Vector3i();
|
||||
end = new Vector3i();
|
||||
|
||||
start.x = (int) bb.minX;
|
||||
start.y = (int) bb.minY;
|
||||
start.z = (int) bb.minZ;
|
||||
end.x = (int) Math.ceil(bb.maxX);
|
||||
end.y = (int) Math.ceil(bb.maxY);
|
||||
end.z = (int) Math.ceil(bb.maxZ);
|
||||
}
|
||||
|
||||
public AABB expand(Vector3i vec) {
|
||||
if(vec.x > end.x)
|
||||
end.x = vec.x;
|
||||
else if(vec.x < start.x)
|
||||
start.x = vec.x;
|
||||
|
||||
if(vec.y > end.y)
|
||||
end.y = vec.y;
|
||||
else if(vec.y < start.y)
|
||||
start.y = vec.y;
|
||||
|
||||
if(vec.z > end.z)
|
||||
end.z = vec.z;
|
||||
else if(vec.z < start.z)
|
||||
start.z = vec.z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public AABB move(Vector3i start) {
|
||||
end.sub(this.start).add(start);
|
||||
this.start.set(start);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AxisAlignedBB toMc() {
|
||||
return new AxisAlignedBB((double) start.x, (double) start.y, (double) start.z, (double) end.x, (double) end.y, (double) end.z);
|
||||
}
|
||||
|
||||
}
|
||||
48
src/main/java/net/montoyo/wd/utilities/BlockSide.java
Normal file
48
src/main/java/net/montoyo/wd/utilities/BlockSide.java
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.utilities;
|
||||
|
||||
public enum BlockSide {
|
||||
|
||||
BOTTOM(new Vector3i( 0, 0, -1), new Vector3i( 1, 0, 0), new Vector3i( 0, -1, 0)),
|
||||
TOP (new Vector3i( 0, 0, -1), new Vector3i( 1, 0, 0), new Vector3i( 0, 1, 0)),
|
||||
NORTH (new Vector3i( 0, 1, 0), new Vector3i(-1, 0, 0), new Vector3i( 0, 0, -1)),
|
||||
SOUTH (new Vector3i( 0, 1, 0), new Vector3i( 1, 0, 0), new Vector3i( 0, 0, 1)),
|
||||
WEST (new Vector3i( 0, 1, 0), new Vector3i( 0, 0, 1), new Vector3i(-1, 0, 0)),
|
||||
EAST (new Vector3i( 0, 1, 0), new Vector3i( 0, 0, -1), new Vector3i( 1, 0, 0));
|
||||
|
||||
public final Vector3i up;
|
||||
public final Vector3i right;
|
||||
public final Vector3i forward;
|
||||
public final Vector3i down;
|
||||
public final Vector3i left;
|
||||
public final Vector3i backward;
|
||||
|
||||
BlockSide(Vector3i u, Vector3i r, Vector3i f) {
|
||||
up = u;
|
||||
right = r;
|
||||
forward = f;
|
||||
down = u.clone().neg();
|
||||
left = r.clone().neg();
|
||||
backward = f.clone().neg();
|
||||
}
|
||||
|
||||
public BlockSide reverse()
|
||||
{
|
||||
int side = ordinal();
|
||||
int div = side / 2;
|
||||
int rest = 1 - side % 2;
|
||||
|
||||
return values()[div * 2 + rest];
|
||||
}
|
||||
|
||||
public static int reverse(int side) {
|
||||
int div = side / 2;
|
||||
int rest = 1 - side % 2;
|
||||
|
||||
return div * 2 + rest;
|
||||
}
|
||||
|
||||
}
|
||||
15
src/main/java/net/montoyo/wd/utilities/DontSerialize.java
Normal file
15
src/main/java/net/montoyo/wd/utilities/DontSerialize.java
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.utilities;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DontSerialize {
|
||||
}
|
||||
36
src/main/java/net/montoyo/wd/utilities/Log.java
Normal file
36
src/main/java/net/montoyo/wd/utilities/Log.java
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.utilities;
|
||||
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import org.apache.logging.log4j.Level;
|
||||
|
||||
public class Log {
|
||||
|
||||
public static void info(String what, Object ... data) {
|
||||
FMLLog.log("WebDisplays", Level.INFO, what, data);
|
||||
}
|
||||
|
||||
public static void warning(String what, Object ... data) {
|
||||
FMLLog.log("WebDisplays", Level.WARN, what, data);
|
||||
}
|
||||
|
||||
public static void error(String what, Object ... data) {
|
||||
FMLLog.log("WebDisplays", Level.ERROR, what, data);
|
||||
}
|
||||
|
||||
public static void infoEx(String what, Throwable e, Object ... data) {
|
||||
FMLLog.log("WebDisplays", Level.INFO, e, what, data);
|
||||
}
|
||||
|
||||
public static void warningEx(String what, Throwable e, Object ... data) {
|
||||
FMLLog.log("WebDisplays", Level.WARN, e, what, data);
|
||||
}
|
||||
|
||||
public static void errorEx(String what, Throwable e, Object ... data) {
|
||||
FMLLog.log("WebDisplays", Level.ERROR, e, what, data);
|
||||
}
|
||||
|
||||
}
|
||||
178
src/main/java/net/montoyo/wd/utilities/Multiblock.java
Normal file
178
src/main/java/net/montoyo/wd/utilities/Multiblock.java
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.utilities;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.montoyo.wd.block.BlockScreen;
|
||||
|
||||
public class Multiblock {
|
||||
|
||||
public static enum OverrideAction {
|
||||
NONE,
|
||||
SIMULATE,
|
||||
IGNORE;
|
||||
}
|
||||
|
||||
public static class BlockOverride {
|
||||
final Vector3i pos;
|
||||
final OverrideAction action;
|
||||
|
||||
public BlockOverride(Vector3i p, OverrideAction act) {
|
||||
pos = p;
|
||||
action = act;
|
||||
}
|
||||
|
||||
public boolean apply(Vector3i bp, boolean originalResult) {
|
||||
if(action == OverrideAction.NONE || !bp.equals(pos))
|
||||
return originalResult;
|
||||
else if(action == OverrideAction.SIMULATE)
|
||||
return true;
|
||||
else //action == OverrideAction.IGNORE
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final BlockOverride NULL_OVERRIDE = new BlockOverride(null, OverrideAction.NONE);
|
||||
|
||||
//Modifies pos
|
||||
public static void findOrigin(IBlockAccess world, Vector3i pos, BlockSide side, BlockOverride override)
|
||||
{
|
||||
if(override == null)
|
||||
override = NULL_OVERRIDE;
|
||||
|
||||
BlockPos.MutableBlockPos bp = new BlockPos.MutableBlockPos();
|
||||
|
||||
//Go left
|
||||
do {
|
||||
pos.add(side.left);
|
||||
pos.toBlock(bp);
|
||||
} while(override.apply(pos, world.getBlockState(bp).getBlock() instanceof BlockScreen));
|
||||
|
||||
pos.add(side.right);
|
||||
|
||||
//Go down
|
||||
do {
|
||||
pos.add(side.down);
|
||||
pos.toBlock(bp);
|
||||
} while(override.apply(pos, world.getBlockState(bp).getBlock() instanceof BlockScreen));
|
||||
|
||||
pos.add(side.up);
|
||||
}
|
||||
|
||||
//Origin stays constant
|
||||
public static Vector2i measure(IBlockAccess world, Vector3i origin, BlockSide side)
|
||||
{
|
||||
Vector2i ret = new Vector2i();
|
||||
Vector3i pos = origin.clone();
|
||||
|
||||
BlockPos.MutableBlockPos bp = new BlockPos.MutableBlockPos();
|
||||
pos.toBlock(bp);
|
||||
|
||||
//Go up
|
||||
do {
|
||||
pos.add(side.up);
|
||||
pos.toBlock(bp);
|
||||
ret.y++;
|
||||
} while(world.getBlockState(bp).getBlock() instanceof BlockScreen);
|
||||
|
||||
pos.add(side.down);
|
||||
|
||||
//Go right
|
||||
do {
|
||||
pos.add(side.right);
|
||||
pos.toBlock(bp);
|
||||
ret.x++;
|
||||
} while(world.getBlockState(bp).getBlock() instanceof BlockScreen);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//Origin and size stays constant.
|
||||
//Returns null if structure is okay, otherwise the erroring block pos.
|
||||
public static Vector3i check(IBlockAccess world, Vector3i origin, Vector2i size, BlockSide side)
|
||||
{
|
||||
Vector3i pos = origin.clone();
|
||||
BlockPos.MutableBlockPos bp = new BlockPos.MutableBlockPos();
|
||||
|
||||
//Check inner
|
||||
for(int y = 0; y < size.y; y++) {
|
||||
for(int x = 0; x < size.x; x++) {
|
||||
pos.toBlock(bp);
|
||||
if(!(world.getBlockState(bp).getBlock() instanceof BlockScreen))
|
||||
return pos; //Hole
|
||||
|
||||
pos.add(side.forward);
|
||||
pos.toBlock(bp);
|
||||
if(world.getBlockState(bp).getBlock() instanceof BlockScreen)
|
||||
return pos; //Back should be empty
|
||||
|
||||
pos.addMul(side.backward, 2);
|
||||
pos.toBlock(bp);
|
||||
if(world.getBlockState(bp).getBlock() instanceof BlockScreen)
|
||||
return pos; //Front should be empty
|
||||
|
||||
pos.add(side.forward);
|
||||
pos.add(side.right);
|
||||
}
|
||||
|
||||
pos.addMul(side.left, size.x);
|
||||
pos.add(side.up);
|
||||
}
|
||||
|
||||
//Check left edge
|
||||
pos.set(origin);
|
||||
pos.add(side.left);
|
||||
|
||||
for(int y = 0; y < size.y; y++) {
|
||||
pos.toBlock(bp);
|
||||
if(world.getBlockState(bp).getBlock() instanceof BlockScreen)
|
||||
return pos; //Left edge should be empty
|
||||
|
||||
pos.add(side.up);
|
||||
}
|
||||
|
||||
//Check right edge
|
||||
pos.set(origin);
|
||||
pos.addMul(side.right, size.x);
|
||||
|
||||
for(int y = 0; y < size.y; y++) {
|
||||
pos.toBlock(bp);
|
||||
if(world.getBlockState(bp).getBlock() instanceof BlockScreen)
|
||||
return pos; //Left edge should be empty
|
||||
|
||||
pos.add(side.up);
|
||||
}
|
||||
|
||||
//Check bottom edge
|
||||
pos.set(origin);
|
||||
pos.add(side.down);
|
||||
|
||||
for(int x = 0; x < size.x; x++) {
|
||||
pos.toBlock(bp);
|
||||
if(world.getBlockState(bp).getBlock() instanceof BlockScreen)
|
||||
return pos; //Left edge should be empty
|
||||
|
||||
pos.add(side.right);
|
||||
}
|
||||
|
||||
//Check top edge
|
||||
pos.set(origin);
|
||||
pos.addMul(side.up, size.y);
|
||||
|
||||
for(int x = 0; x < size.x; x++) {
|
||||
pos.toBlock(bp);
|
||||
if(world.getBlockState(bp).getBlock() instanceof BlockScreen)
|
||||
return pos; //Left edge should be empty
|
||||
|
||||
pos.add(side.right);
|
||||
}
|
||||
|
||||
//All good.
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
72
src/main/java/net/montoyo/wd/utilities/NameUUIDPair.java
Normal file
72
src/main/java/net/montoyo/wd/utilities/NameUUIDPair.java
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.utilities;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraftforge.fml.common.network.ByteBufUtils;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class NameUUIDPair {
|
||||
|
||||
public final String name;
|
||||
public final UUID uuid;
|
||||
|
||||
public NameUUIDPair() {
|
||||
name = "";
|
||||
uuid = new UUID(0L, 0L);
|
||||
}
|
||||
|
||||
public NameUUIDPair(String name, UUID uuid) {
|
||||
this.name = name;
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public NameUUIDPair(GameProfile profile) {
|
||||
name = profile.getName();
|
||||
uuid = profile.getId();
|
||||
}
|
||||
|
||||
public NameUUIDPair(ByteBuf bb) {
|
||||
name = ByteBufUtils.readUTF8String(bb);
|
||||
|
||||
long msb = bb.readLong();
|
||||
long lsb = bb.readLong();
|
||||
uuid = new UUID(msb, lsb);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public UUID getUUID() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj == null || !(obj instanceof NameUUIDPair))
|
||||
return false;
|
||||
|
||||
return ((NameUUIDPair) obj).uuid.equals(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return uuid.hashCode();
|
||||
}
|
||||
|
||||
public boolean isBlank() {
|
||||
return name.isEmpty() && uuid.getMostSignificantBits() == 0L && uuid.getLeastSignificantBits() == 0L;
|
||||
}
|
||||
|
||||
public void writeTo(ByteBuf bb) {
|
||||
ByteBufUtils.writeUTF8String(bb, name);
|
||||
bb.writeLong(uuid.getMostSignificantBits());
|
||||
bb.writeLong(uuid.getLeastSignificantBits());
|
||||
}
|
||||
|
||||
}
|
||||
224
src/main/java/net/montoyo/wd/utilities/Util.java
Normal file
224
src/main/java/net/montoyo/wd/utilities/Util.java
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.utilities;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.*;
|
||||
import net.minecraft.util.text.*;
|
||||
import net.minecraftforge.fml.common.network.ByteBufUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Util {
|
||||
|
||||
public static void serialize(ByteBuf bb, Object f) {
|
||||
Class<?> cls = f.getClass();
|
||||
|
||||
if(cls == Integer.class || cls == Integer.TYPE)
|
||||
bb.writeInt((Integer) f);
|
||||
else if(cls == Float.class || cls == Float.TYPE)
|
||||
bb.writeFloat((Float) f);
|
||||
else if(cls == Double.class || cls == Double.TYPE)
|
||||
bb.writeDouble((Double) f);
|
||||
else if(cls == Boolean.class || cls == Boolean.TYPE)
|
||||
bb.writeBoolean((Boolean) f);
|
||||
else if(cls == String.class)
|
||||
ByteBufUtils.writeUTF8String(bb, (String) f);
|
||||
else if(cls == NameUUIDPair.class)
|
||||
((NameUUIDPair) f).writeTo(bb);
|
||||
else if(cls.isEnum())
|
||||
bb.writeByte(((Enum<?>) f).ordinal());
|
||||
else if(cls.isArray()) {
|
||||
Object[] ray = (Object[]) f;
|
||||
|
||||
bb.writeInt(ray.length);
|
||||
for (int i = 0; i < ray.length; i++)
|
||||
serialize(bb, ray[i]);
|
||||
} else if(!cls.isPrimitive()) {
|
||||
Field[] fields = cls.getFields();
|
||||
|
||||
for(int i = 0; i < fields.length; i++) {
|
||||
try {
|
||||
if(fields[i].getAnnotation(DontSerialize.class) == null && !Modifier.isStatic(fields[i].getModifiers()))
|
||||
serialize(bb, fields[i].get(f));
|
||||
} catch(IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("Caught IllegalAccessException for %s.%s", cls.getName(), fields[i].getName()));
|
||||
}
|
||||
}
|
||||
} else
|
||||
throw new RuntimeException(String.format("Cannot transmit class %s over network!", cls.getName()));
|
||||
}
|
||||
|
||||
public static Object unserialize(ByteBuf bb, Class cls) {
|
||||
if(cls == Integer.class || cls == Integer.TYPE)
|
||||
return bb.readInt();
|
||||
else if(cls == Float.class || cls == Float.TYPE)
|
||||
return bb.readFloat();
|
||||
else if(cls == Double.class || cls == Double.TYPE)
|
||||
return bb.readDouble();
|
||||
else if(cls == Boolean.class || cls == Boolean.TYPE)
|
||||
return bb.readBoolean();
|
||||
else if(cls == String.class)
|
||||
return ByteBufUtils.readUTF8String(bb);
|
||||
else if(cls == NameUUIDPair.class)
|
||||
return new NameUUIDPair(bb);
|
||||
else if(cls.isEnum())
|
||||
return cls.getEnumConstants()[bb.readByte()];
|
||||
else if(cls.isArray()) {
|
||||
Object[] ray = new Object[bb.readInt()];
|
||||
|
||||
for(int i = 0; i < ray.length; i++)
|
||||
ray[i] = unserialize(bb, cls.getComponentType());
|
||||
|
||||
return Arrays.copyOf(ray, ray.length, cls);
|
||||
} else if(!cls.isPrimitive()) {
|
||||
Object ret;
|
||||
Field[] fields = cls.getFields();
|
||||
|
||||
try {
|
||||
ret = cls.newInstance();
|
||||
} catch(InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("Caught InstantiationException for class %s", cls.getName()));
|
||||
} catch(IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(String.format("Caught IllegalAccessException for class %s", cls.getName()));
|
||||
}
|
||||
|
||||
for(int i = 0; i < fields.length; i++) {
|
||||
try {
|
||||
if(fields[i].getAnnotation(DontSerialize.class) == null && !Modifier.isStatic(fields[i].getModifiers()))
|
||||
fields[i].set(ret, unserialize(bb, fields[i].getType()));
|
||||
} catch(IllegalAccessException e) {
|
||||
throw new RuntimeException(String.format("Caught IllegalAccessException for %s.%s", cls.getName(), fields[i].getName()));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
} else
|
||||
throw new RuntimeException(String.format("Cannot unserialize class %s!", cls.getName()));
|
||||
}
|
||||
|
||||
public static NBTBase serialize(Object f) {
|
||||
Class<?> cls = f.getClass();
|
||||
|
||||
if(cls == Integer.class)
|
||||
return new NBTTagInt((Integer) f);
|
||||
else if(cls == Float.class)
|
||||
return new NBTTagFloat((Float) f);
|
||||
else if(cls == Double.class)
|
||||
return new NBTTagDouble((Double) f);
|
||||
else if(cls == String.class)
|
||||
return new NBTTagString((String) f);
|
||||
else if(cls.isEnum())
|
||||
return new NBTTagInt(((Enum<?>) f).ordinal());
|
||||
else if(cls.isArray()) {
|
||||
Object[] ray = (Object[]) f;
|
||||
NBTTagList ret = new NBTTagList();
|
||||
|
||||
for(int i = 0; i < ray.length; i++)
|
||||
ret.appendTag(serialize(ray[i]));
|
||||
|
||||
return ret;
|
||||
} else
|
||||
throw new RuntimeException(String.format("Cannot save class %s as NBT!", cls.getName()));
|
||||
}
|
||||
|
||||
public static Object unserialize(NBTBase nbt, Class cls) {
|
||||
if(cls == Integer.class || cls == Integer.TYPE)
|
||||
return ((NBTTagInt) nbt).getInt();
|
||||
else if(cls == Float.class || cls == Float.TYPE)
|
||||
return ((NBTTagFloat) nbt).getFloat();
|
||||
else if(cls == Double.class || cls == Double.TYPE)
|
||||
return ((NBTTagDouble) nbt).getDouble();
|
||||
else if(cls == String.class)
|
||||
return ((NBTTagString) nbt).getString();
|
||||
else if(cls.isEnum())
|
||||
return cls.getEnumConstants()[((NBTTagInt) nbt).getInt()];
|
||||
else if(cls.isArray()) {
|
||||
NBTTagList lst = (NBTTagList) nbt;
|
||||
Object[] ray = new Object[lst.tagCount()];
|
||||
|
||||
for(int i = 0; lst.tagCount() > 0; i++)
|
||||
ray[i] = unserialize(lst.removeTag(0), cls.getComponentType());
|
||||
|
||||
return Arrays.copyOf(ray, ray.length, cls);
|
||||
} else
|
||||
throw new RuntimeException(String.format("Cannot load class %s from NBT!", cls.getName()));
|
||||
}
|
||||
|
||||
public static String[] commaSplit(String str) {
|
||||
ArrayList<String> lst = new ArrayList<String>();
|
||||
String out = "";
|
||||
boolean escape = false;
|
||||
|
||||
for(int i = 0; i < str.length(); i++) {
|
||||
char c = str.charAt(i);
|
||||
|
||||
if(c == '\\' && !escape) {
|
||||
escape = true;
|
||||
continue; //Otherwise it'll set escape back to false
|
||||
} else if(c == ',' && !escape) {
|
||||
lst.add(out);
|
||||
out = "";
|
||||
} else
|
||||
out += c;
|
||||
|
||||
if(escape)
|
||||
escape = false;
|
||||
}
|
||||
|
||||
lst.add(out);
|
||||
|
||||
String[] ret = new String[lst.size()];
|
||||
return lst.toArray(ret);
|
||||
}
|
||||
|
||||
public static String addSlashes(String str) {
|
||||
String out = "";
|
||||
for(int i = 0; i < str.length(); i++) {
|
||||
char c = str.charAt(i);
|
||||
|
||||
if(c == '\\')
|
||||
out += "\\\\";
|
||||
else if(c == '\"')
|
||||
out += "\\\"";
|
||||
else
|
||||
out += c;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
public static int scrambleKey(int idx)
|
||||
{
|
||||
idx = idx * 0x9E3779B9;
|
||||
return idx ^ (idx >> 16);
|
||||
}
|
||||
|
||||
public static void toast(EntityPlayer player, String key, Object ... data) {
|
||||
toast(player, TextFormatting.RED, key, data);
|
||||
}
|
||||
|
||||
public static void toast(EntityPlayer player, TextFormatting color, String key, Object ... data) {
|
||||
ITextComponent root = new TextComponentString("[WebDisplays] ");
|
||||
root.setStyle((new Style()).setColor(color));
|
||||
root.appendSibling(new TextComponentTranslation("webdisplays.message." + key, data));
|
||||
|
||||
player.sendMessage(root);
|
||||
}
|
||||
|
||||
public static void silentClose(Object obj) {
|
||||
try {
|
||||
obj.getClass().getMethod("close").invoke(obj);
|
||||
} catch(Throwable t) {}
|
||||
}
|
||||
|
||||
}
|
||||
44
src/main/java/net/montoyo/wd/utilities/Vector2i.java
Normal file
44
src/main/java/net/montoyo/wd/utilities/Vector2i.java
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.utilities;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class Vector2i {
|
||||
|
||||
public int x;
|
||||
public int y;
|
||||
|
||||
public Vector2i()
|
||||
{
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
public Vector2i(int val)
|
||||
{
|
||||
x = val;
|
||||
y = val;
|
||||
}
|
||||
|
||||
public Vector2i(int x, int y)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public Vector2i(ByteBuf bb)
|
||||
{
|
||||
x = bb.readInt();
|
||||
y = bb.readInt();
|
||||
}
|
||||
|
||||
public void writeTo(ByteBuf bb)
|
||||
{
|
||||
bb.writeInt(x);
|
||||
bb.writeInt(y);
|
||||
}
|
||||
|
||||
}
|
||||
186
src/main/java/net/montoyo/wd/utilities/Vector3f.java
Normal file
186
src/main/java/net/montoyo/wd/utilities/Vector3f.java
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.utilities;
|
||||
|
||||
public class Vector3f {
|
||||
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
|
||||
public Vector3f() {
|
||||
x = 0.f;
|
||||
y = 0.f;
|
||||
z = 0.f;
|
||||
}
|
||||
|
||||
public Vector3f(float val) {
|
||||
x = val;
|
||||
y = val;
|
||||
z = val;
|
||||
}
|
||||
|
||||
public Vector3f(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f clone() {
|
||||
return new Vector3f(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ((37 + Float.floatToRawIntBits(x)) * 31 + Float.floatToRawIntBits(y)) * 43 + Float.floatToRawIntBits(z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof Vector3f) {
|
||||
Vector3f src = (Vector3f) o;
|
||||
|
||||
return (src.x == x && src.y == y && src.z == z);
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
//Add
|
||||
public Vector3f add(Vector3f src) {
|
||||
x += src.x;
|
||||
y += src.y;
|
||||
z += src.z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f addMul(Vector3f src, float m) {
|
||||
x += src.x * m;
|
||||
y += src.y * m;
|
||||
z += src.z * m;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f add(float x, float y, float z) {
|
||||
this.x += x;
|
||||
this.y += y;
|
||||
this.z += z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f add(float xyz) {
|
||||
x += xyz;
|
||||
y += xyz;
|
||||
z += xyz;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
//Sub
|
||||
public Vector3f sub(Vector3f src) {
|
||||
x -= src.x;
|
||||
y -= src.y;
|
||||
z -= src.z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f sub(float x, float y, float z) {
|
||||
this.x -= x;
|
||||
this.y -= y;
|
||||
this.z -= z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f sub(float xyz) {
|
||||
x -= xyz;
|
||||
y -= xyz;
|
||||
z -= xyz;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
//Mul
|
||||
public Vector3f neg() {
|
||||
x = -x;
|
||||
y = -y;
|
||||
z = -z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f mul(float val) {
|
||||
x *= val;
|
||||
y *= val;
|
||||
z *= val;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f div(float val) {
|
||||
x /= val;
|
||||
y /= val;
|
||||
z /= val;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f set(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f set(float xyz) {
|
||||
x = xyz;
|
||||
y = xyz;
|
||||
z = xyz;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public float dot(Vector3f vec) {
|
||||
return x * vec.x + y * vec.y + z * vec.z;
|
||||
}
|
||||
|
||||
public Vector3f set(double x, double y, double z) {
|
||||
this.x = (float) x;
|
||||
this.y = (float) y;
|
||||
this.z = (float) z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f set(int x, int y, int z) {
|
||||
this.x = (float) x;
|
||||
this.y = (float) y;
|
||||
this.z = (float) z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f set(Vector3f vec) {
|
||||
x = vec.x;
|
||||
y = vec.y;
|
||||
z = vec.z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f set(Vector3i vec) {
|
||||
x = (float) vec.x;
|
||||
y = (float) vec.y;
|
||||
z = (float) vec.z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
228
src/main/java/net/montoyo/wd/utilities/Vector3i.java
Normal file
228
src/main/java/net/montoyo/wd/utilities/Vector3i.java
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.utilities;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class Vector3i {
|
||||
|
||||
public int x;
|
||||
public int y;
|
||||
public int z;
|
||||
|
||||
public Vector3i() {
|
||||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
}
|
||||
|
||||
public Vector3i(int val) {
|
||||
x = val;
|
||||
y = val;
|
||||
z = val;
|
||||
}
|
||||
|
||||
public Vector3i(int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public Vector3i(BlockPos bp) {
|
||||
x = bp.getX();
|
||||
y = bp.getY();
|
||||
z = bp.getZ();
|
||||
}
|
||||
|
||||
public Vector3i(ByteBuf bb) {
|
||||
x = bb.readInt();
|
||||
y = bb.readInt();
|
||||
z = bb.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3i clone() {
|
||||
return new Vector3i(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ((37 + x) * 31 + y) * 43 + z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if(o instanceof Vector3i) {
|
||||
Vector3i src = (Vector3i) o;
|
||||
|
||||
return (src.x == x && src.y == y && src.z == z);
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "X: " + x + ", Y: " + y + ", Z: " + z;
|
||||
}
|
||||
|
||||
//Add
|
||||
public Vector3i add(Vector3i src) {
|
||||
x += src.x;
|
||||
y += src.y;
|
||||
z += src.z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3i addMul(Vector3i src, int mul) {
|
||||
x += src.x * mul;
|
||||
y += src.y * mul;
|
||||
z += src.z * mul;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3i add(int x, int y, int z) {
|
||||
this.x += x;
|
||||
this.y += y;
|
||||
this.z += z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3i add(int xyz) {
|
||||
x += xyz;
|
||||
y += xyz;
|
||||
z += xyz;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
//Sub
|
||||
public Vector3i sub(Vector3i src) {
|
||||
x -= src.x;
|
||||
y -= src.y;
|
||||
z -= src.z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3i sub(int x, int y, int z) {
|
||||
this.x -= x;
|
||||
this.y -= y;
|
||||
this.z -= z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3i sub(int xyz) {
|
||||
x -= xyz;
|
||||
y -= xyz;
|
||||
z -= xyz;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
//Mul
|
||||
public Vector3i neg() {
|
||||
x = -x;
|
||||
y = -y;
|
||||
z = -z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3i mul(int val) {
|
||||
x *= val;
|
||||
y *= val;
|
||||
z *= val;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3i div(int val) {
|
||||
x /= val;
|
||||
y /= val;
|
||||
z /= val;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3i set(int x, int y, int z)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3i set(double x, double y, double z)
|
||||
{
|
||||
this.x = (int) x;
|
||||
this.y = (int) y;
|
||||
this.z = (int) z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3i set(float x, float y, float z)
|
||||
{
|
||||
this.x = (int) x;
|
||||
this.y = (int) y;
|
||||
this.z = (int) z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3i set(int val)
|
||||
{
|
||||
x = val;
|
||||
y = val;
|
||||
z = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3i set(Vector3i val)
|
||||
{
|
||||
x = val.x;
|
||||
y = val.y;
|
||||
z = val.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3i set(Vector3f vec)
|
||||
{
|
||||
this.x = (int) vec.x;
|
||||
this.y = (int) vec.y;
|
||||
this.z = (int) vec.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f toFloat() {
|
||||
return new Vector3f((float) x, (float) y, (float) z);
|
||||
}
|
||||
public BlockPos toBlock() {
|
||||
return new BlockPos(x, y, z);
|
||||
}
|
||||
|
||||
public void toBlock(BlockPos.MutableBlockPos bp) {
|
||||
bp.setPos(x, y, z);
|
||||
}
|
||||
|
||||
public int getChunkLocalPos()
|
||||
{
|
||||
int lx = x & 15;
|
||||
int ly = y & 255;
|
||||
int lz = z & 15;
|
||||
|
||||
return (ly << 8) | (lz << 4) | lx;
|
||||
}
|
||||
|
||||
public void writeTo(ByteBuf bb) {
|
||||
bb.writeInt(x);
|
||||
bb.writeInt(y);
|
||||
bb.writeInt(z);
|
||||
}
|
||||
|
||||
}
|
||||
79
src/main/java/net/montoyo/wd/utilities/VideoType.java
Normal file
79
src/main/java/net/montoyo/wd/utilities/VideoType.java
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.utilities;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.net.URL;
|
||||
|
||||
public enum VideoType {
|
||||
|
||||
YOUTUBE("document.getElementById(\"movie_player\").setVolume(", ")"),
|
||||
YOUTUBE_EMBED("", "");
|
||||
|
||||
private final String volumePrefix;
|
||||
private final String volumeSuffix;
|
||||
private final int volumeCap;
|
||||
|
||||
VideoType(String prefix, String suffix) {
|
||||
volumePrefix = prefix;
|
||||
volumeSuffix = suffix;
|
||||
volumeCap = prefix.length() + 5 + suffix.length();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VideoType getTypeFromURL(@Nonnull URL url) {
|
||||
String loHost = url.getHost().toLowerCase();
|
||||
if(loHost.equals("youtu.be"))
|
||||
return url.getPath().length() > 1 ? YOUTUBE : null;
|
||||
else if(!loHost.equals("www.youtube.com") && !loHost.equals("youtube.com"))
|
||||
return null;
|
||||
|
||||
String loPath = url.getPath().toLowerCase();
|
||||
if(loPath.equals("/watch")) {
|
||||
if(url.getQuery() != null && (url.getQuery().startsWith("v=") || url.getQuery().contains("&v=")))
|
||||
return YOUTUBE;
|
||||
} else if(loPath.startsWith("/embed/"))
|
||||
return loPath.length() > 7 ? YOUTUBE_EMBED : null;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public String getVideoIDFromURL(@Nonnull URL url) {
|
||||
if(this == YOUTUBE) {
|
||||
if(url.getHost().equalsIgnoreCase("youtu.be"))
|
||||
return url.getPath().substring(1);
|
||||
|
||||
String args[] = url.getQuery().split("&");
|
||||
for(String arg : args) {
|
||||
if(arg.startsWith("v="))
|
||||
return arg.substring(2);
|
||||
}
|
||||
} else if(this == YOUTUBE_EMBED)
|
||||
return url.getPath().substring(7);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public String getURLFromID(@Nonnull String vid, boolean autoplay) {
|
||||
String format;
|
||||
if(this == YOUTUBE)
|
||||
format = autoplay ? "https://www.youtube.com/watch?v=%s&autoplay=1" : "https://www.youtube.com/watch?v=%s";
|
||||
else if(this == YOUTUBE_EMBED)
|
||||
format = autoplay ? "https://www.youtube.com/embed/%s?autoplay=1" : "https://www.youtube.com/embed/%s";
|
||||
else
|
||||
return "";
|
||||
|
||||
return String.format(format, vid);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public String getVolumeJSQuery(int volInt, int volFrac) {
|
||||
return (new StringBuilder(volumeCap)).append(volumePrefix).append(volInt).append('.').append(volFrac).append(volumeSuffix).toString();
|
||||
}
|
||||
|
||||
}
|
||||
56
src/main/resources/assets/mcef/html/home.html
Normal file
56
src/main/resources/assets/mcef/html/home.html
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link href="http://fonts.googleapis.com/css?family=Roboto+Slab:400,700" rel="stylesheet" type="text/css">
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: "Roboto Slab", serif;
|
||||
background-color: #405FFF;
|
||||
color: white;
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
font-weight: 700;
|
||||
padding: 10px;
|
||||
border: 1px solid white;
|
||||
font-size: 16pt;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
background-color: white;
|
||||
color: #405FFF;
|
||||
}
|
||||
|
||||
#pic {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
window.mcefQuery({
|
||||
"request": "username",
|
||||
"persistent": false,
|
||||
"onSuccess": function(msg) {
|
||||
$("#username").html(msg);
|
||||
$("#pic").html("<img src=\"https://minotar.net/avatar/" + msg + "/70.png\" />");
|
||||
},
|
||||
|
||||
"onFailure": function(err, msg) {
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
Hello, <span id="username">?</span>! <div id="pic"></div><br /><br /><br /><br />
|
||||
<center><a href="http://google.com">Google!</a> <a href="http://youtube.com">YouTube!</a></center>
|
||||
</body>
|
||||
</html>
|
||||
6
src/main/resources/assets/mcef/html/jquery.js
vendored
Normal file
6
src/main/resources/assets/mcef/html/jquery.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
src/main/resources/assets/mcef/html/jquery.tube.js
Normal file
2
src/main/resources/assets/mcef/html/jquery.tube.js
Normal file
File diff suppressed because one or more lines are too long
15
src/main/resources/assets/mcef/html/test.html
Normal file
15
src/main/resources/assets/mcef/html/test.html
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="jquery.js"></script>
|
||||
<script type="text/javascript" src="jquery.tube.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$("#example_video").player({video: "iP6XpLQM2Cs"});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="example_video">Loading, please wait...</div>
|
||||
</body>
|
||||
</html>
|
||||
1588
src/main/resources/assets/mcef/mime.types
Normal file
1588
src/main/resources/assets/mcef/mime.types
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=0": { "model": "webdisplays:kb_right" },
|
||||
"facing=1": { "model": "webdisplays:kb_right", "y": 90.0 },
|
||||
"facing=2": { "model": "webdisplays:kb_right", "y": 180.0 },
|
||||
"facing=3": { "model": "webdisplays:kb_right", "y": 270.0 }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=0,type=keyboard": { "model": "webdisplays:kb_left" },
|
||||
"facing=1,type=keyboard": { "model": "webdisplays:kb_left", "y": 90.0 },
|
||||
"facing=2,type=keyboard": { "model": "webdisplays:kb_left", "y": 180.0 },
|
||||
"facing=3,type=keyboard": { "model": "webdisplays:kb_left", "y": 270.0 },
|
||||
|
||||
"facing=0,type=remotectrl": { "model": "webdisplays:peripheral" },
|
||||
"facing=1,type=remotectrl": { "model": "webdisplays:peripheral" },
|
||||
"facing=2,type=remotectrl": { "model": "webdisplays:peripheral" },
|
||||
"facing=3,type=remotectrl": { "model": "webdisplays:peripheral" },
|
||||
|
||||
"facing=0,type=ccinterface": { "model": "webdisplays:peripheral" },
|
||||
"facing=1,type=ccinterface": { "model": "webdisplays:peripheral" },
|
||||
"facing=2,type=ccinterface": { "model": "webdisplays:peripheral" },
|
||||
"facing=3,type=ccinterface": { "model": "webdisplays:peripheral" },
|
||||
|
||||
"facing=0,type=cointerface": { "model": "webdisplays:peripheral" },
|
||||
"facing=1,type=cointerface": { "model": "webdisplays:peripheral" },
|
||||
"facing=2,type=cointerface": { "model": "webdisplays:peripheral" },
|
||||
"facing=3,type=cointerface": { "model": "webdisplays:peripheral" }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"variants": {
|
||||
"normal": { "model": "webdisplays:screen" },
|
||||
"inventory": { "model": "webdisplays:screen_item" }
|
||||
}
|
||||
}
|
||||
38
src/main/resources/assets/webdisplays/gui/keyboard.json
Normal file
38
src/main/resources/assets/webdisplays/gui/keyboard.json
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"controls": [
|
||||
{
|
||||
"type": "Label",
|
||||
"x": 5,
|
||||
"y": 5,
|
||||
"label": "$webdisplays.gui.keyboard.hooked",
|
||||
"color": "yellow",
|
||||
"name": "lblInfo",
|
||||
"visible": "1 - showWarning"
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
"label": "$webdisplays.gui.keyboard.warning1",
|
||||
"color": "red",
|
||||
"visible": "showWarning"
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
"label": "$webdisplays.gui.keyboard.warning2",
|
||||
"color": "red",
|
||||
"visible": "showWarning"
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
"label": "$webdisplays.gui.keyboard.warning3",
|
||||
"color": "red",
|
||||
"visible": "showWarning"
|
||||
},
|
||||
{
|
||||
"type": "Button",
|
||||
"name": "btnOk",
|
||||
"label": "$webdisplays.gui.keyboard.gotcha",
|
||||
"visible": "showWarning",
|
||||
"disabled": "1 - showWarning"
|
||||
}
|
||||
]
|
||||
}
|
||||
180
src/main/resources/assets/webdisplays/gui/screencfg.json
Normal file
180
src/main/resources/assets/webdisplays/gui/screencfg.json
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
{
|
||||
"controls": [
|
||||
{
|
||||
"type": "Label",
|
||||
"name": "lblOwner",
|
||||
"label": "$webdisplays.gui.screencfg.owner",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"shadowed": true
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
"label": "$webdisplays.gui.screencfg.friends",
|
||||
"x": 0,
|
||||
"y": 12
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"name": "lstFriends",
|
||||
"x": 0,
|
||||
"y": 24,
|
||||
"width": 100,
|
||||
"height": 170,
|
||||
"selectionColor": "red"
|
||||
},
|
||||
{
|
||||
"type": "TextField",
|
||||
"name": "tfFriend",
|
||||
"x": 0,
|
||||
"y": 198,
|
||||
"width": 76,
|
||||
"maxLength": 128
|
||||
},
|
||||
{
|
||||
"type": "Button",
|
||||
"name": "btnAdd",
|
||||
"x": 80,
|
||||
"y": 199,
|
||||
"width": 20,
|
||||
"label": "+"
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
"x": 104,
|
||||
"y": 12,
|
||||
"label": "$webdisplays.gui.screencfg.permissions"
|
||||
},
|
||||
{
|
||||
"type": "ControlGroup",
|
||||
"name": "grpFriends",
|
||||
"x": 104,
|
||||
"y": 24,
|
||||
"label": "$webdisplays.gui.screencfg.friends",
|
||||
"width": 150,
|
||||
"height": 112,
|
||||
"childs": [
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "boxFSetUrl",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"label": "$webdisplays.gui.screencfg.seturl"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "boxFClick",
|
||||
"x": 0,
|
||||
"y": 16,
|
||||
"label": "$webdisplays.gui.screencfg.click"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "boxFFriends",
|
||||
"x": 0,
|
||||
"y": 32,
|
||||
"label": "$webdisplays.gui.screencfg.friendlist"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "boxFOthers",
|
||||
"x": 0,
|
||||
"y": 48,
|
||||
"label": "$webdisplays.gui.screencfg.otherrights"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "boxFUpgrades",
|
||||
"x": 0,
|
||||
"y": 64,
|
||||
"label": "$webdisplays.gui.screencfg.mupgrades"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "boxFResolution",
|
||||
"x": 0,
|
||||
"y": 80,
|
||||
"label": "$webdisplays.gui.screencfg.mres"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ControlGroup",
|
||||
"name": "grpOthers",
|
||||
"x": 104,
|
||||
"y": 140,
|
||||
"label": "$webdisplays.gui.screencfg.others",
|
||||
"width": 150,
|
||||
"height": 80,
|
||||
"childs": [
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "boxOSetUrl",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"label": "$webdisplays.gui.screencfg.seturl"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "boxOClick",
|
||||
"x": 0,
|
||||
"y": 16,
|
||||
"label": "$webdisplays.gui.screencfg.click"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "boxOUpgrades",
|
||||
"x": 0,
|
||||
"y": 32,
|
||||
"label": "$webdisplays.gui.screencfg.mupgrades"
|
||||
},
|
||||
{
|
||||
"type": "CheckBox",
|
||||
"name": "boxOResolution",
|
||||
"x": 0,
|
||||
"y": 48,
|
||||
"label": "$webdisplays.gui.screencfg.mres"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
"x": 258,
|
||||
"y": 12,
|
||||
"label": "$webdisplays.gui.screencfg.upgrades"
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
"x": 258,
|
||||
"y": 40,
|
||||
"label": "$webdisplays.gui.screencfg.resolution"
|
||||
},
|
||||
{
|
||||
"type": "TextField",
|
||||
"name": "tfResX",
|
||||
"x": 260,
|
||||
"y": 52,
|
||||
"width": 40,
|
||||
"maxLength": 4
|
||||
},
|
||||
{
|
||||
"type": "TextField",
|
||||
"name": "tfResY",
|
||||
"x": 304,
|
||||
"y": 52,
|
||||
"width": 40,
|
||||
"maxLength": 4
|
||||
},
|
||||
{
|
||||
"type": "Button",
|
||||
"name": "btnSetRes",
|
||||
"x": 260,
|
||||
"y": 78,
|
||||
"width": 84,
|
||||
"label": "$webdisplays.gui.screencfg.setres",
|
||||
"disabled": true
|
||||
}
|
||||
],
|
||||
|
||||
"center": true
|
||||
}
|
||||
56
src/main/resources/assets/webdisplays/gui/seturl.json
Normal file
56
src/main/resources/assets/webdisplays/gui/seturl.json
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"controls": [
|
||||
{
|
||||
"type": "Label",
|
||||
"label": "$webdisplays.gui.seturl.url",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"shadowed": true
|
||||
},
|
||||
{
|
||||
"type": "TextField",
|
||||
"name": "tfURL",
|
||||
"x": 0,
|
||||
"y": 12,
|
||||
"width": 272,
|
||||
"maxLength": 65535
|
||||
},
|
||||
{
|
||||
"type": "Button",
|
||||
"name": "btnYT",
|
||||
"label": "YT",
|
||||
"x": 276,
|
||||
"y": 13,
|
||||
"width": 20,
|
||||
"shiftColor": [ 255, 100, 100 ]
|
||||
},
|
||||
{
|
||||
"type": "Button",
|
||||
"name": "btnShutDown",
|
||||
"label": "$webdisplays.gui.seturl.shutdown",
|
||||
"x": 0,
|
||||
"y": 38,
|
||||
"width": 96,
|
||||
"visible": "isPad",
|
||||
"disabled": "1 - isPad"
|
||||
},
|
||||
{
|
||||
"type": "Button",
|
||||
"name": "btnCancel",
|
||||
"label": "$webdisplays.gui.seturl.cancel",
|
||||
"x": "isPad & 100 | 0",
|
||||
"y": 38,
|
||||
"width": "isPad & 96 | 146"
|
||||
},
|
||||
{
|
||||
"type": "Button",
|
||||
"name": "btnOk",
|
||||
"label": "$webdisplays.gui.seturl.ok",
|
||||
"x": "isPad & 200 | 150",
|
||||
"y": 38,
|
||||
"width": "isPad & 96 | 146"
|
||||
}
|
||||
],
|
||||
|
||||
"center": true
|
||||
}
|
||||
51
src/main/resources/assets/webdisplays/lang/en_US.lang
Normal file
51
src/main/resources/assets/webdisplays/lang/en_US.lang
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
itemGroup.webdisplays=§5Web Displays
|
||||
tile.webdisplays.screen.name=Web Screen
|
||||
tile.webdisplays.peripheral.keyboard.name=Keyboard
|
||||
tile.webdisplays.peripheral.remotectrl.name=Remote Controller
|
||||
tile.webdisplays.peripheral.ccinterface.name=ComputerCraft Interface
|
||||
tile.webdisplays.peripheral.cointerface.name=OpenComputers Interface
|
||||
item.webdisplays.screencfg.name=Screen Configurator
|
||||
item.webdisplays.ownerthief.name=Ownership Thief [ADMIN]
|
||||
item.webdisplays.linker.name=Linking Tool
|
||||
item.webdisplays.stonekey.name=Stone Key
|
||||
item.webdisplays.minepad.name=minePad
|
||||
webdisplays.message.tooSmall=Too small! Minimum size is 2x2.
|
||||
webdisplays.message.invalid=Structure is invalid; look at %s.
|
||||
webdisplays.message.turnOn=You need to turn the screen on first!
|
||||
webdisplays.message.screenSet=Screen set! Now give the item to the new owner...
|
||||
webdisplays.message.newOwner=You are now the owner of this screen!
|
||||
webdisplays.message.restrictions=You are not allowed to do this :(
|
||||
webdisplays.message.peripheral=This is not a peripheral!
|
||||
webdisplays.message.linked=Linked!
|
||||
webdisplays.message.linkError=Link error :( Check logs...
|
||||
webdisplays.message.notAScreen=Please right click on the screen first...
|
||||
webdisplays.message.screenSet2=Screen set! Now right click on the peripheral...
|
||||
webdisplays.message.chunkUnloaded=The chunk the screen in placed it is not loaded!
|
||||
webdisplays.message.notLinked=This peripheral has not been linked yet.
|
||||
webdisplays.gui.screencfg.owner=Screen owner:
|
||||
webdisplays.gui.screencfg.friends=Friends:
|
||||
webdisplays.gui.screencfg.permissions=Permissions:
|
||||
webdisplays.gui.screencfg.seturl=Change URL
|
||||
webdisplays.gui.screencfg.click=Click & type
|
||||
webdisplays.gui.screencfg.friendlist=Manage friends
|
||||
webdisplays.gui.screencfg.otherrights=Manage others
|
||||
webdisplays.gui.screencfg.mupgrades=Upgrade & link
|
||||
webdisplays.gui.screencfg.mres=Change resolution
|
||||
webdisplays.gui.screencfg.others=Others
|
||||
webdisplays.gui.screencfg.upgrades=Upgrades:
|
||||
webdisplays.gui.screencfg.resolution=Resolution:
|
||||
webdisplays.gui.screencfg.setres=Set Resolution
|
||||
webdisplays.linker.selectScreen=Right click on a screen
|
||||
webdisplays.linker.selectPeripheral=Right click on a peripheral
|
||||
webdisplays.linker.posInfo=Screen pos: %d %d %d
|
||||
webdisplays.linker.sideInfo=Side: %s
|
||||
webdisplays.gui.seturl.url=URL:
|
||||
webdisplays.gui.seturl.ok=OK
|
||||
webdisplays.gui.seturl.cancel=Cancel
|
||||
webdisplays.gui.seturl.shutdown=Shut down
|
||||
webdisplays.minepad.turnon=Sneak and right-click to turn on
|
||||
webdisplays.gui.keyboard.hooked=Keyboard hooked. Press escape to leave.
|
||||
webdisplays.gui.keyboard.warning1=WARNING! Typed data are sent in PLAIN TEXT to the server.
|
||||
webdisplays.gui.keyboard.warning2=This means anyone can know what you're up to.
|
||||
webdisplays.gui.keyboard.warning3=NEVER write one of your passwords using this keyboard.
|
||||
webdisplays.gui.keyboard.gotcha=Got ya
|
||||
503
src/main/resources/assets/webdisplays/models/block/kb_left.json
Normal file
503
src/main/resources/assets/webdisplays/models/block/kb_left.json
Normal file
|
|
@ -0,0 +1,503 @@
|
|||
{
|
||||
"__comment": "Model absolutely not generated using MrCrayfish's Model Creator (http://mrcrayfish.com/modelcreator/)",
|
||||
"textures": {
|
||||
"particle": "webdisplays:blocks/kb_key",
|
||||
"0": "webdisplays:blocks/kb_base",
|
||||
"1": "webdisplays:blocks/kb_key"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Base",
|
||||
"from": [ 0.0, 0.0, 3.0 ],
|
||||
"to": [ 16.0, 1.0, 16.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 1.0 ] },
|
||||
"east": { "texture": "#0", "uv": [ 0.0, 0.0, 13.0, 1.0 ] },
|
||||
"south": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 1.0 ] },
|
||||
"west": { "texture": "#0", "uv": [ 0.0, 0.0, 13.0, 1.0 ] },
|
||||
"up": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 13.0 ] },
|
||||
"down": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 13.0 ], "cullface": "down" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key1",
|
||||
"from": [ 1.0, 1.0, 4.0 ],
|
||||
"to": [ 2.0, 2.0, 5.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key2",
|
||||
"from": [ 4.0, 1.0, 4.0 ],
|
||||
"to": [ 5.0, 2.0, 5.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key3",
|
||||
"from": [ 6.0, 1.0, 4.0 ],
|
||||
"to": [ 7.0, 2.0, 5.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key4",
|
||||
"from": [ 8.0, 1.0, 4.0 ],
|
||||
"to": [ 9.0, 2.0, 5.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key5",
|
||||
"from": [ 10.0, 1.0, 4.0 ],
|
||||
"to": [ 11.0, 2.0, 5.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key6",
|
||||
"from": [ 13.0, 1.0, 4.0 ],
|
||||
"to": [ 14.0, 2.0, 5.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key7",
|
||||
"from": [ 15.0, 1.0, 4.0 ],
|
||||
"to": [ 16.0, 2.0, 5.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key8",
|
||||
"from": [ 1.0, 1.0, 6.0 ],
|
||||
"to": [ 2.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key9",
|
||||
"from": [ 3.0, 1.0, 6.0 ],
|
||||
"to": [ 4.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key10",
|
||||
"from": [ 5.0, 1.0, 6.0 ],
|
||||
"to": [ 6.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key11",
|
||||
"from": [ 7.0, 1.0, 6.0 ],
|
||||
"to": [ 8.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key12",
|
||||
"from": [ 9.0, 1.0, 6.0 ],
|
||||
"to": [ 10.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key13",
|
||||
"from": [ 11.0, 1.0, 6.0 ],
|
||||
"to": [ 12.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key14",
|
||||
"from": [ 13.0, 1.0, 6.0 ],
|
||||
"to": [ 14.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key15",
|
||||
"from": [ 15.0, 1.0, 6.0 ],
|
||||
"to": [ 16.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key16",
|
||||
"from": [ 1.0, 1.0, 8.0 ],
|
||||
"to": [ 3.0, 2.0, 9.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key17",
|
||||
"from": [ 4.0, 1.0, 8.0 ],
|
||||
"to": [ 5.0, 2.0, 9.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key18",
|
||||
"from": [ 6.0, 1.0, 8.0 ],
|
||||
"to": [ 7.0, 2.0, 9.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key19",
|
||||
"from": [ 8.0, 1.0, 8.0 ],
|
||||
"to": [ 9.0, 2.0, 9.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key20",
|
||||
"from": [ 10.0, 1.0, 8.0 ],
|
||||
"to": [ 11.0, 2.0, 9.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key21",
|
||||
"from": [ 12.0, 1.0, 8.0 ],
|
||||
"to": [ 13.0, 2.0, 9.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key22",
|
||||
"from": [ 14.0, 1.0, 8.0 ],
|
||||
"to": [ 15.0, 2.0, 9.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key23",
|
||||
"from": [ 1.0, 1.0, 10.0 ],
|
||||
"to": [ 4.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 3.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 3.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 3.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key24",
|
||||
"from": [ 5.0, 1.0, 10.0 ],
|
||||
"to": [ 6.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key25",
|
||||
"from": [ 7.0, 1.0, 10.0 ],
|
||||
"to": [ 8.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key26",
|
||||
"from": [ 9.0, 1.0, 10.0 ],
|
||||
"to": [ 10.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key27",
|
||||
"from": [ 11.0, 1.0, 10.0 ],
|
||||
"to": [ 12.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key28",
|
||||
"from": [ 13.0, 1.0, 10.0 ],
|
||||
"to": [ 14.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key29",
|
||||
"from": [ 15.0, 1.0, 10.0 ],
|
||||
"to": [ 16.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key30",
|
||||
"from": [ 1.0, 1.0, 12.0 ],
|
||||
"to": [ 3.0, 2.0, 13.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key31",
|
||||
"from": [ 4.0, 1.0, 12.0 ],
|
||||
"to": [ 5.0, 2.0, 13.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key32",
|
||||
"from": [ 6.0, 1.0, 12.0 ],
|
||||
"to": [ 7.0, 2.0, 13.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key33",
|
||||
"from": [ 8.0, 1.0, 12.0 ],
|
||||
"to": [ 9.0, 2.0, 13.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key34",
|
||||
"from": [ 10.0, 1.0, 12.0 ],
|
||||
"to": [ 11.0, 2.0, 13.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key35",
|
||||
"from": [ 12.0, 1.0, 12.0 ],
|
||||
"to": [ 13.0, 2.0, 13.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key36",
|
||||
"from": [ 14.0, 1.0, 12.0 ],
|
||||
"to": [ 15.0, 2.0, 13.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key37",
|
||||
"from": [ 1.0, 1.0, 14.0 ],
|
||||
"to": [ 3.0, 2.0, 15.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key38",
|
||||
"from": [ 4.0, 1.0, 14.0 ],
|
||||
"to": [ 6.0, 2.0, 15.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key39",
|
||||
"from": [ 7.0, 1.0, 14.0 ],
|
||||
"to": [ 9.0, 2.0, 15.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key40",
|
||||
"from": [ 10.0, 1.0, 14.0 ],
|
||||
"to": [ 16.0, 2.0, 15.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 6.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 6.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 6.0, 1.0 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
477
src/main/resources/assets/webdisplays/models/block/kb_right.json
Normal file
477
src/main/resources/assets/webdisplays/models/block/kb_right.json
Normal file
|
|
@ -0,0 +1,477 @@
|
|||
{
|
||||
"__comment": "Model absolutely not generated using MrCrayfish's Model Creator (http://mrcrayfish.com/modelcreator/)",
|
||||
"textures": {
|
||||
"particle": "webdisplays:blocks/kb_key",
|
||||
"0": "webdisplays:blocks/kb_base",
|
||||
"1": "webdisplays:blocks/kb_key"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Base",
|
||||
"from": [ 0.0, 0.0, 3.0 ],
|
||||
"to": [ 16.0, 1.0, 16.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 1.0 ] },
|
||||
"east": { "texture": "#0", "uv": [ 0.0, 0.0, 13.0, 1.0 ] },
|
||||
"south": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 1.0 ] },
|
||||
"west": { "texture": "#0", "uv": [ 0.0, 0.0, 13.0, 1.0 ] },
|
||||
"up": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 13.0 ] },
|
||||
"down": { "texture": "#0", "uv": [ 0.0, 0.0, 16.0, 13.0 ], "cullface": "down" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key1",
|
||||
"from": [ 1.0, 1.0, 4.0 ],
|
||||
"to": [ 2.0, 2.0, 5.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key2",
|
||||
"from": [ 3.0, 1.0, 4.0 ],
|
||||
"to": [ 4.0, 2.0, 5.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key3",
|
||||
"from": [ 6.0, 1.0, 4.0 ],
|
||||
"to": [ 7.0, 2.0, 5.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key4",
|
||||
"from": [ 8.0, 1.0, 4.0 ],
|
||||
"to": [ 9.0, 2.0, 5.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key5",
|
||||
"from": [ 10.0, 1.0, 4.0 ],
|
||||
"to": [ 11.0, 2.0, 5.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key6",
|
||||
"from": [ 12.0, 1.0, 4.0 ],
|
||||
"to": [ 13.0, 2.0, 5.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key7",
|
||||
"from": [ 1.0, 1.0, 6.0 ],
|
||||
"to": [ 2.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key8",
|
||||
"from": [ 3.0, 1.0, 6.0 ],
|
||||
"to": [ 4.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key9",
|
||||
"from": [ 5.0, 1.0, 6.0 ],
|
||||
"to": [ 6.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key10",
|
||||
"from": [ 7.0, 1.0, 6.0 ],
|
||||
"to": [ 8.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key11",
|
||||
"from": [ 9.0, 1.0, 6.0 ],
|
||||
"to": [ 11.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key12",
|
||||
"from": [ 12.0, 1.0, 6.0 ],
|
||||
"to": [ 13.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key13",
|
||||
"from": [ 14.0, 1.0, 6.0 ],
|
||||
"to": [ 15.0, 2.0, 7.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key14",
|
||||
"from": [ 0.0, 1.0, 8.0 ],
|
||||
"to": [ 1.0, 2.0, 9.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key15",
|
||||
"from": [ 2.0, 1.0, 8.0 ],
|
||||
"to": [ 3.0, 2.0, 9.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key16",
|
||||
"from": [ 4.0, 1.0, 8.0 ],
|
||||
"to": [ 5.0, 2.0, 9.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key17",
|
||||
"from": [ 6.0, 1.0, 8.0 ],
|
||||
"to": [ 7.0, 2.0, 9.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key18",
|
||||
"from": [ 8.0, 1.0, 8.0 ],
|
||||
"to": [ 11.0, 2.0, 9.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 3.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 3.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 3.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key19",
|
||||
"from": [ 12.0, 1.0, 8.0 ],
|
||||
"to": [ 13.0, 2.0, 9.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key20",
|
||||
"from": [ 14.0, 1.0, 8.0 ],
|
||||
"to": [ 15.0, 2.0, 9.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key21",
|
||||
"from": [ 1.0, 1.0, 10.0 ],
|
||||
"to": [ 2.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key22",
|
||||
"from": [ 3.0, 1.0, 10.0 ],
|
||||
"to": [ 4.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key23",
|
||||
"from": [ 5.0, 1.0, 10.0 ],
|
||||
"to": [ 6.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key24",
|
||||
"from": [ 7.0, 1.0, 10.0 ],
|
||||
"to": [ 8.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key25",
|
||||
"from": [ 9.0, 1.0, 9.0 ],
|
||||
"to": [ 11.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 0.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key26",
|
||||
"from": [ 12.0, 1.0, 10.0 ],
|
||||
"to": [ 13.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key27",
|
||||
"from": [ 14.0, 1.0, 10.0 ],
|
||||
"to": [ 15.0, 2.0, 11.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key29",
|
||||
"from": [ 0.0, 1.0, 12.0 ],
|
||||
"to": [ 1.0, 2.0, 13.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key30",
|
||||
"from": [ 2.0, 1.0, 12.0 ],
|
||||
"to": [ 3.0, 2.0, 13.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key31",
|
||||
"from": [ 4.0, 1.0, 12.0 ],
|
||||
"to": [ 5.0, 2.0, 13.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key32",
|
||||
"from": [ 6.0, 1.0, 12.0 ],
|
||||
"to": [ 7.0, 2.0, 13.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key33",
|
||||
"from": [ 8.0, 1.0, 12.0 ],
|
||||
"to": [ 11.0, 2.0, 13.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 3.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 3.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 3.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key34",
|
||||
"from": [ 13.0, 1.0, 13.0 ],
|
||||
"to": [ 14.0, 2.0, 14.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key35",
|
||||
"from": [ 0.0, 1.0, 14.0 ],
|
||||
"to": [ 2.0, 2.0, 15.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key36",
|
||||
"from": [ 3.0, 1.0, 14.0 ],
|
||||
"to": [ 5.0, 2.0, 15.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key37",
|
||||
"from": [ 6.0, 1.0, 14.0 ],
|
||||
"to": [ 8.0, 2.0, 15.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key38",
|
||||
"from": [ 9.0, 1.0, 14.0 ],
|
||||
"to": [ 11.0, 2.0, 15.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Key39",
|
||||
"from": [ 12.0, 1.0, 14.0 ],
|
||||
"to": [ 15.0, 2.0, 15.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#1", "uv": [ 0.0, 0.0, 3.0, 1.0 ] },
|
||||
"east": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"south": { "texture": "#1", "uv": [ 0.0, 0.0, 3.0, 1.0 ] },
|
||||
"west": { "texture": "#1", "uv": [ 0.0, 0.0, 1.0, 1.0 ] },
|
||||
"up": { "texture": "#1", "uv": [ 0.0, 0.0, 3.0, 1.0 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "block/cube_all",
|
||||
"textures": {
|
||||
"all": "webdisplays:blocks/rctrl"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "block/cube_all",
|
||||
"textures": {
|
||||
"all": "webdisplays:blocks/screen15"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "webdisplays:items/kb_inv"
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user