commit 3316f7b6953a5d129ab12d74fadca35c0cfe13f2 Author: Matthew Messinger Date: Sat Aug 1 18:36:33 2015 -0400 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..110f1aef --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.gradle/ +.settings/ +bin/ +build/ +run/ +.classpath +.project \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..f74db51d --- /dev/null +++ b/build.gradle @@ -0,0 +1,56 @@ +buildscript { + repositories { + mavenCentral() + maven { + name = "forge" + url = "http://files.minecraftforge.net/maven" + } + maven { + name = "sonatype" + url = "https://oss.sonatype.org/content/repositories/snapshots/" + } + maven { + name = 'minecrell' + url = "http://repo.minecrell.net/snapshots" + } + } + dependencies { + classpath 'net.minecrell:VanillaGradle:3.0-SNAPSHOT' + } +} +evaluationDependsOnChildren() +apply plugin: 'net.minecrell.vanilla' + +archivesBaseName = "mod_minelp" +version = "1.8-UNOFFICIAL_mc1.8" + +minecraft { + version = "1.8" + mappings = 'snapshot_20150606' + clientTweaker = 'com.mumfrey.liteloader.launch.LiteLoaderTweaker' + // fix reobf issues + srgExtra "FD: com/voxelmodpack/common/properties/gui/GuiVoxelBoxSettingsPanel/zLevel bub/e" + srgExtra "FD: com/voxelmodpack/common/gui/GuiControl/zLevel bub/e" + srgExtra "FD: com/voxelmodpack/common/gui/GuiScreenEx/zLevel bub/e" +} +project(':voxellib').dependencies { + compile fileTree("libs") +} +dependencies { + compile project(':voxellib') +} +jar { + extension 'litemod' +} +task standaloneJar(type:Jar, dependsOn: [reobf, project(':voxellib').reobf]) { + extension "litemod" + from zipTree(jar.archivePath) + from project(':voxellib').jar.archivePath + classifier 'standalone' +} +artifacts { + archives standaloneJar +} +reobf { + setSrgMcp() +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..30d399d8 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..87f3af33 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Thu Jul 23 18:28:01 EDT 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-bin.zip diff --git a/gradlew b/gradlew new file mode 100644 index 00000000..91a7e269 --- /dev/null +++ b/gradlew @@ -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 "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..8a0b282a --- /dev/null +++ b/gradlew.bat @@ -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 diff --git a/libs/liteloader-1.8-SNAPSHOT-mcpnames.jar b/libs/liteloader-1.8-SNAPSHOT-mcpnames.jar new file mode 100644 index 00000000..069697c9 Binary files /dev/null and b/libs/liteloader-1.8-SNAPSHOT-mcpnames.jar differ diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..63efbc54 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include ':voxellib' \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/minelp/LiteModMineLittlePony.java b/src/main/java/com/minelittlepony/minelp/LiteModMineLittlePony.java new file mode 100644 index 00000000..f2299fea --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/LiteModMineLittlePony.java @@ -0,0 +1,20 @@ +package com.minelittlepony.minelp; + +import com.voxelmodpack.common.VoxelCommonLiteMod; + +public class LiteModMineLittlePony extends VoxelCommonLiteMod { + + public LiteModMineLittlePony() { + super("com.minelittlepony.minelp.MineLittlePony"); + } + + @Override + public String getVersion() { + return MineLittlePony.MOD_VERSION; + } + + @Override + public String getName() { + return MineLittlePony.MOD_NAME; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/MineLittlePony.java b/src/main/java/com/minelittlepony/minelp/MineLittlePony.java new file mode 100644 index 00000000..b3214e3a --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/MineLittlePony.java @@ -0,0 +1,179 @@ +package com.minelittlepony.minelp; + +import java.io.File; + +import org.lwjgl.input.Keyboard; + +import com.minelittlepony.minelp.gui.MineLittlePonyGUI; +import com.minelittlepony.minelp.gui.MineLittlePonyGUIMob; +import com.minelittlepony.minelp.hdskins.gui.EntityPonyModel; +import com.minelittlepony.minelp.hdskins.gui.GuiSkinsMineLP; +import com.minelittlepony.minelp.hdskins.gui.RenderPonyModel; +import com.minelittlepony.minelp.renderer.RenderPonySkeleton; +import com.minelittlepony.minelp.renderer.RenderPonyVillager; +import com.minelittlepony.minelp.renderer.RenderPonyZombie; +import com.minelittlepony.minelp.util.MineLPLogger; +import com.mumfrey.liteloader.InitCompleteListener; +import com.mumfrey.liteloader.core.LiteLoader; +import com.mumfrey.liteloader.util.ModUtilities; +import com.voxelmodpack.common.properties.ModConfig; +import com.voxelmodpack.common.properties.gui.SettingsPanelManager; +import com.voxelmodpack.hdskins.HDSkinManager; +import com.voxelmodpack.hdskins.gui.GuiSkins; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiMainMenu; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.settings.KeyBinding; +import net.minecraft.entity.monster.EntityPigZombie; +import net.minecraft.entity.monster.EntitySkeleton; +import net.minecraft.entity.monster.EntityZombie; +import net.minecraft.entity.passive.EntityVillager; + +public class MineLittlePony implements InitCompleteListener { + public static final String MOD_VERSION = "1.8-UNOFFICIAL"; + public static final String MOD_NAME = "Mine Little Pony"; + public static final String SKIN_SERVER_URL = "minelpskins.voxelmodpack.com"; + public static final String GATEWAY_URL = "minelpskinmanager.voxelmodpack.com"; + public static final String UPLOAD_URL = "http://minelpskinmanager.voxelmodpack.com/"; + private static final KeyBinding guiKeybinding = new KeyBinding("Settings", Keyboard.KEY_F9, "Mine Little Pony"); + private static final KeyBinding skinKeybinding = new KeyBinding("Skin Manager", Keyboard.KEY_F1, "Mine Little Pony"); + private PonyConfig config; + private PonyManager ponyManager; + private String spUsername; + private static MineLittlePony instance; + + public MineLittlePony() { + instance = this; + } + + public static MineLittlePony getInstance() { + return instance; + } + + @Override + public String getName() { + return MOD_NAME; + } + + @Override + public String getVersion() { + return MOD_VERSION; + } + + @Override + public void upgradeSettings(String version, File configPath, File oldConfigPath) {} + + @Override + public void init(File configPath) { + LiteLoader.getInput().registerKeyBinding(guiKeybinding); + LiteLoader.getInput().registerKeyBinding(skinKeybinding); + SettingsPanelManager.addSettingsPanel("Pony", MineLittlePonyGUI.class); + SettingsPanelManager.addSettingsPanel("Pony Mobs", MineLittlePonyGUIMob.class); + this.ponyManager = PonyManager.getInstance(); + this.config = new PonyConfig(); + + int readInt = this.config.getIntPropertySafe("ponylevel", 0, 2); + this.ponyManager.setPonyLevel(PonyLevel.parse(readInt)); + MineLPLogger.info("Pony level is set to %d.", Integer.valueOf(readInt)); + + readInt = this.config.getIntPropertySafe("sizes", 0, 1); + this.ponyManager.setUseSizes(readInt); + MineLPLogger.info("Different pony sizes are %s.", readInt == 0 ? "disabled" : "enabled"); + + readInt = this.config.getIntPropertySafe("ponyarmor", 0, 1); + this.ponyManager.setPonyArmor(readInt); + MineLPLogger.info("Pony armor is %s.", readInt == 0 ? "disabled" : "enabled"); + + readInt = this.config.getIntPropertySafe("snuzzles", 0, 1); + this.ponyManager.setShowSnuzzles(readInt); + MineLPLogger.info("Snuzzels are %s.", readInt == 0 ? "disabled (You are a bad pony)" : "enabled"); + + readInt = this.config.getIntPropertySafe("hd", 0, 1); + this.ponyManager.setHD(readInt); + MineLPLogger.info("MineLittlePony skin server is %s.", readInt == 0 ? "disabled" : "enabled"); + + readInt = this.config.getIntPropertySafe("showscale", 0, 1); + this.ponyManager.setShowScale(readInt); + MineLPLogger.info("Show-accurate scaling is %s.", readInt == 0 ? "disabled" : "enabled"); + + readInt = this.config.getIntPropertySafe("villagers", 0, 1); + this.ponyManager.setPonyVillagers(readInt); + MineLPLogger.info("Pony villagers are %s.", readInt == 0 ? "disabled" : "enabled"); + + readInt = this.config.getIntPropertySafe("zombies", 0, 1); + this.ponyManager.setPonyZombies(readInt); + MineLPLogger.info("Pony zombies are %s.", readInt == 0 ? "disabled" : "enabled"); + + readInt = this.config.getIntPropertySafe("pigzombies", 0, 1); + this.ponyManager.setPonyPigzombies(readInt); + MineLPLogger.info("Pony pigzombies are %s.", readInt == 0 ? "disabled" : "enabled"); + + readInt = this.config.getIntPropertySafe("skeletons", 0, 1); + this.ponyManager.setPonySkeletons(readInt); + MineLPLogger.info("Pony skeletons are %s.", readInt == 0 ? "disabled" : "enabled"); + } + + @Override + public void onInitCompleted(Minecraft minecraft, LiteLoader loader) { + this.spUsername = minecraft.getSession().getUsername(); + if (this.ponyManager.getHD() == 1) { + HDSkinManager.clearSkinCache(); + HDSkinManager.setSkinUrl(SKIN_SERVER_URL); + HDSkinManager.setGatewayURL(GATEWAY_URL); + MineLPLogger.info("Set MineLP skin server URL."); + } + RenderManager rm = minecraft.getRenderManager(); + ModUtilities.addRenderer(EntityPonyModel.class, new RenderPonyModel(rm)); + if (this.ponyManager.getPonyVillagers() == 1) { + ModUtilities.addRenderer(EntityVillager.class, new RenderPonyVillager(rm)); + MineLPLogger.info("Villagers are now ponies."); + } + + if (this.ponyManager.getPonyZombies() == 1) { + ModUtilities.addRenderer(EntityZombie.class, new RenderPonyZombie(rm)); + MineLPLogger.info("Zombies are now ponies."); + } + + if (this.ponyManager.getPonyPigzombies() == 1) { + ModUtilities.addRenderer(EntityPigZombie.class, new RenderPonyZombie(rm)); + MineLPLogger.info("Zombie pigmen are now ponies."); + } + + if (this.ponyManager.getPonySkeletons() == 1) { + ModUtilities.addRenderer(EntitySkeleton.class, new RenderPonySkeleton(rm)); + MineLPLogger.info("Skeletons are now ponies."); + } + + } + + @Override + public void onTick(Minecraft minecraft, float partialTicks, boolean inGame, boolean clock) { + this.ponyManager.setPonyLevel(PonyLevel.parse(this.config.getIntProperty("ponylevel"))); + this.ponyManager.setUseSizes(this.config.getIntProperty("sizes")); + this.ponyManager.setPonyArmor(this.config.getIntProperty("ponyarmor")); + this.ponyManager.setShowSnuzzles(this.config.getIntProperty("snuzzles")); + this.ponyManager.setShowScale(this.config.getIntProperty("showscale")); + if (inGame && minecraft.currentScreen == null && guiKeybinding.isPressed()) { + minecraft.displayGuiScreen(new MineLittlePonyGUI()); + } + // if (Keyboard.isKeyDown(Keyboard.KEY_O)) { + // ponyManager.initmodels(); + // } + + if (!inGame && minecraft.currentScreen != null + && (minecraft.currentScreen instanceof GuiMainMenu && Keyboard.isKeyDown(skinKeybinding.getKeyCode()) + || minecraft.currentScreen instanceof GuiSkins)) { + minecraft.displayGuiScreen(new GuiSkinsMineLP()); + } + + } + + public static ModConfig getConfig() { + return getInstance().config; + } + + public static String getSPUsername() { + return getInstance().spUsername; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/Pony.java b/src/main/java/com/minelittlepony/minelp/Pony.java new file mode 100644 index 00000000..ba0cac35 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/Pony.java @@ -0,0 +1,447 @@ +package com.minelittlepony.minelp; + +import java.awt.Color; +import java.awt.image.BufferedImage; + +import javax.imageio.ImageIO; + +import com.minelittlepony.minelp.model.PMAPI; +import com.minelittlepony.minelp.model.PlayerModel; +import com.minelittlepony.minelp.util.MineLPLogger; +import com.voxelmodpack.common.runtime.PrivateFields; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.renderer.ThreadDownloadImageData; +import net.minecraft.client.renderer.texture.ITextureObject; +import net.minecraft.util.BlockPos; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +public class Pony { + public static PonyManager ponyManager = PonyManager.getInstance(); + public Pony.PonyRace race; + public boolean advancedTexturing; + public ResourceLocation textureResourceLocation; + public boolean isSpPlayer; + public boolean isPony; + public boolean isPonySkin; + public boolean isPegasus; + public boolean isUnicorn; + public boolean isFlying; + public boolean isGlow; + public int glowColor; + public boolean isMale; + public int size; + public int wantTail; + public boolean isVillager; + public int villagerProfession; + public float defaultYOffset; + boolean pegasusFlying; + @SuppressWarnings("unused") + private final int dangerzone; + private float previousFallDistance; + private static int ponyCount = 0; + private final int ponyId; + private int skinCheckCount; + private boolean skinChecked; + private boolean newSkinSize; + + public Pony(AbstractClientPlayer player) { + this.race = Pony.PonyRace.EARTH; + this.isSpPlayer = false; + this.isPony = false; + this.isPonySkin = false; + this.isPegasus = false; + this.isUnicorn = false; + this.isFlying = false; + this.isGlow = false; + this.glowColor = -12303190; + this.isMale = false; + this.size = 1; + this.wantTail = 0; + this.isVillager = false; + this.villagerProfession = 1; + this.defaultYOffset = 1.62F; + this.pegasusFlying = false; + this.dangerzone = 2; + this.previousFallDistance = 0.0F; + this.skinCheckCount = 0; + this.skinChecked = false; + this.ponyId = ++ponyCount; + this.textureResourceLocation = player.getLocationSkin(); + MineLPLogger.debug("+ Initialising new pony #%d for player %s (%s) with resource location %s.", this.ponyId, + player.getCommandSenderName(), player.getUniqueID(), this.textureResourceLocation); + this.checkSkin(this.textureResourceLocation); + } + + public Pony(ResourceLocation aTextureResourceLocation) { + this.race = Pony.PonyRace.EARTH; + this.isSpPlayer = false; + this.isPony = false; + this.isPonySkin = false; + this.isPegasus = false; + this.isUnicorn = false; + this.isFlying = false; + this.isGlow = false; + this.glowColor = -12303190; + this.isMale = false; + this.size = 1; + this.wantTail = 0; + this.isVillager = false; + this.villagerProfession = 1; + this.defaultYOffset = 1.62F; + this.pegasusFlying = false; + this.dangerzone = 2; + this.previousFallDistance = 0.0F; + this.skinCheckCount = 0; + this.skinChecked = false; + this.ponyId = ++ponyCount; + this.textureResourceLocation = aTextureResourceLocation; + + MineLPLogger.debug("+ Initialising new pony #%d with resource location %s.", this.ponyId, + this.textureResourceLocation); + this.checkSkin(this.textureResourceLocation); + } + + public void invalidateSkinCheck() { + this.resetValues(); + this.skinChecked = false; + } + + public void checkSkin() { + if (!this.skinChecked) { + this.checkSkin(this.textureResourceLocation); + } + + } + + public void checkSkin(ResourceLocation textureResourceLocation) { + BufferedImage skinImage = this.getBufferedImage(textureResourceLocation); + if (skinImage != null) { + this.checkSkin(skinImage); + } + + } + + public BufferedImage getBufferedImage(ResourceLocation textureResourceLocation) { + BufferedImage skinImage = null; + + try { + skinImage = ImageIO.read(Minecraft.getMinecraft().getResourceManager().getResource(textureResourceLocation) + .getInputStream()); + MineLPLogger.debug("Obtained skin from resource location %s", textureResourceLocation); + this.checkSkin(skinImage); + } catch (Exception var6) { + Exception e = var6; + + try { + ITextureObject e2 = Minecraft.getMinecraft().getTextureManager().getTexture(textureResourceLocation); + if (e2 instanceof ThreadDownloadImageData) { + skinImage = PrivateFields.downloadedImage.get((ThreadDownloadImageData) e2); + if (skinImage != null) { + MineLPLogger.debug(e, "Successfully reflected downloadedImage from texture object"); + this.checkSkin(skinImage); + } + } + } catch (Exception var5) { + ; + } + } + + return skinImage; + } + + public void checkSkin(BufferedImage bufferedimage) { + MineLPLogger.debug("\tStart skin check #%d for pony #%d with image %s.", ++this.skinCheckCount, this.ponyId); + this.resetValues(); + Color flagPix = new Color(bufferedimage.getRGB(0, 0), true); + Color applejack = new Color(249, 177, 49, 255); + Color dashie = new Color(136, 202, 240, 255); + Color twilight = new Color(209, 159, 228, 255); + Color celestia = new Color(254, 249, 252, 255); + Color zecora = new Color(208, 204, 207, 255); + Color changeling = new Color(40, 43, 41, 255); + if (flagPix.equals(applejack)) { + this.isPony = true; + this.isPonySkin = true; + this.race = Pony.PonyRace.EARTH; + } + + if (flagPix.equals(zecora)) { + this.isPony = true; + this.isPonySkin = true; + this.race = Pony.PonyRace.ZEBRA; + } + + if (flagPix.equals(dashie)) { + this.isPony = true; + this.isPonySkin = true; + this.isPegasus = true; + this.race = Pony.PonyRace.PEGASUS; + } + + if (flagPix.equals(twilight)) { + this.isPony = true; + this.isPonySkin = true; + this.isUnicorn = true; + this.race = Pony.PonyRace.UNICORN; + } + + if (flagPix.equals(celestia)) { + this.isPony = true; + this.isPonySkin = true; + this.isPegasus = true; + this.isUnicorn = true; + this.race = Pony.PonyRace.ALICORN; + } + + if (flagPix.equals(changeling)) { + this.isPony = true; + this.isPonySkin = true; + this.isPegasus = true; + this.isUnicorn = true; + this.race = Pony.PonyRace.CHANGELING; + } + + Color tailcolor = new Color(bufferedimage.getRGB(1, 0), true); + Color tailcolor1 = new Color(66, 88, 68, 255); + Color tailcolor2 = new Color(70, 142, 136, 255); + Color tailcolor3 = new Color(83, 75, 118, 255); + Color tailcolor4 = new Color(138, 107, 127, 255); + if (tailcolor.equals(tailcolor1)) { + this.wantTail = 4; + } else if (tailcolor.equals(tailcolor2)) { + this.wantTail = 3; + } else if (tailcolor.equals(tailcolor3)) { + this.wantTail = 2; + } else if (tailcolor.equals(tailcolor4)) { + this.wantTail = 1; + } else { + this.wantTail = 0; + } + + Color gendercolor = new Color(bufferedimage.getRGB(2, 0), true); + Color gendercolor1 = new Color(255, 255, 255, 255); + if (gendercolor.equals(gendercolor1)) { + this.isMale = true; + } else { + this.isMale = false; + } + + Color sizecolor = new Color(bufferedimage.getRGB(3, 0), true); + Color scootaloo = new Color(255, 190, 83); + Color bigmac = new Color(206, 50, 84); + Color luna = new Color(42, 60, 120); + if (ponyManager.getUseSizes() == 1) { + if (sizecolor.equals(scootaloo)) { + this.size = 0; + } else if (sizecolor.equals(bigmac)) { + this.size = 2; + } else if (sizecolor.equals(luna)) { + this.size = 3; + } else { + this.size = 1; + } + } + + Color black = new Color(0, 0, 0); + int scaleFactor = bufferedimage.getHeight() / 32; + int tileSize = 8 * scaleFactor; + Color advcutiecolor = new Color(bufferedimage.getRGB(tileSize / 2, 0), true); + if (advcutiecolor.getAlpha() == 0) { + this.advancedTexturing = false; + } else { + this.advancedTexturing = false; + + for (int tempGlowColor = tileSize / 2; tempGlowColor < tileSize; ++tempGlowColor) { + for (int y = 0; y < tileSize; ++y) { + Color aColor = new Color(bufferedimage.getRGB(tempGlowColor, y), true); + if (!aColor.equals(black)) { + this.advancedTexturing = true; + } + } + } + } + + Color var27 = new Color(bufferedimage.getRGB(0, 1), true); + if (!var27.equals(black) && var27.getAlpha() != 0) { + this.glowColor = var27.getRGB(); + } else { + this.glowColor = -12303190; + } + + this.newSkinSize = bufferedimage.getWidth() == bufferedimage.getHeight(); + this.skinChecked = true; + MineLPLogger.debug( + "\tSkin check #%d for pony #%d completed. {IsPony:%b, Race:%s, FlagPixel:%s, AdvancedTexturing:%b}", + this.skinCheckCount, this.ponyId, this.isPony, this.race, flagPix, this.advancedTexturing); + } + + protected void resetValues() { + this.isPony = false; + this.isPonySkin = false; + this.isPegasus = false; + this.isUnicorn = false; + this.isPonySkin = false; + this.isMale = false; + this.wantTail = 0; + this.size = 1; + } + + public boolean isPony() { + return this.isPony; + } + + public boolean isPonySkin() { + return this.isPonySkin; + } + + public boolean isUnicorn() { + return this.isUnicorn; + } + + public boolean isPegasus() { + return this.isPegasus; + } + + public Pony.PonyRace getRace() { + return this.race; + } + + public int wantTail() { + return this.wantTail; + } + + public boolean isMale() { + return this.isMale; + } + + public int size() { + return ponyManager.getUseSizes() == 1 ? this.size : 1; + } + + public boolean advancedTexturing() { + return this.advancedTexturing; + } + + public boolean isFlying() { + return this.isFlying; + } + + public boolean isGlow() { + return this.isGlow; + } + + public int glowColor() { + return this.glowColor; + } + + public int villagerProfession() { + return this.villagerProfession; + } + + public boolean isPegasusFlying(double posX, double posY, double posZ, float fallDistance, boolean isJumping, + boolean onGround, World equestria) { + if (!this.isPegasus) { + return pegasusFlying = false; + } else if (isJumping) { + return true; + } else { + boolean falling = fallDistance > 0; + boolean levitating = fallDistance == this.previousFallDistance; + boolean standingOnAir; + if (falling && !levitating) { + standingOnAir = this.standingOnAir(posX, posY, posZ, 1.5F, equestria); + } else { + standingOnAir = this.standingOnAir(posX, posY, posZ, 1.0F, equestria); + } + + if (!standingOnAir) { + return pegasusFlying = false; + } else if (this.pegasusFlying) { + return true; + } else if (levitating) { + return pegasusFlying = true; + } else { + this.previousFallDistance = fallDistance; + if (fallDistance < 2.0F) { + return false; + } else { + return pegasusFlying = true; + } + } + } + } + + public boolean standingOnAir(double posX, double posY, double posZ, float range, World equestria) { + boolean foundSolidBlock = false; + int y; + if (this.isSpPlayer) { + y = MathHelper.floor_double(posY - this.defaultYOffset - 0.009999999776482582D); + } else { + y = MathHelper.floor_double(posY - 0.009999999776482582D); + } + + for (float shiftX = 0.0F - range; shiftX < range * 2.0F; shiftX += range) { + for (float shiftZ = 0.0F - range; shiftZ < range * 2.0F; shiftZ += range) { + int x = MathHelper.floor_double(posX + shiftX); + int z = MathHelper.floor_double(posZ + shiftZ); + if (!equestria.isAirBlock(new BlockPos(x, y, z))) { + foundSolidBlock = true; + } + } + } + + return !foundSolidBlock; + } + + public PlayerModel getModel() { + return getModel(false); + } + + public PlayerModel getModel(boolean ignorePony) { + boolean is_a_pony = false; + switch (ignorePony ? PonyLevel.MIXED : ponyManager.getPonyLevel()) { + case HUMANS: + is_a_pony = false; + break; + case MIXED: + is_a_pony = isPonySkin; + break; + case PONIES: + is_a_pony = true; + } + + PlayerModel model; + if (is_a_pony) { + model = newSkinSize ? PMAPI.newPonyAdv_64 : PMAPI.newPonyAdv; + } else { + model = newSkinSize ? PMAPI.human_64 : PMAPI.human; + } + return model; + } + + public ResourceLocation getTextureResourceLocation() { + return this.textureResourceLocation; + } + + public void setVillager(int profession) { + this.isVillager = true; + this.villagerProfession = profession; + } + + public void setIsPonySkin(boolean b) { + this.isPonySkin = false; + } + + public static enum PonyRace { + EARTH, + PEGASUS, + UNICORN, + ALICORN, + CHANGELING, + ZEBRA; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/PonyConfig.java b/src/main/java/com/minelittlepony/minelp/PonyConfig.java new file mode 100644 index 00000000..c1c4fb44 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/PonyConfig.java @@ -0,0 +1,73 @@ +package com.minelittlepony.minelp; + +import com.minelittlepony.minelp.util.MineLPLogger; +import com.voxelmodpack.common.properties.ModConfig; + +public class PonyConfig extends ModConfig { + @Override + protected void setDefaults() { + this.defaults.setProperty("ponylevel", "2"); + this.defaults.setProperty("sizes", "1"); + this.defaults.setProperty("ponyarmor", "1"); + this.defaults.setProperty("snuzzles", "1"); + this.defaults.setProperty("hd", "1"); + this.defaults.setProperty("showscale", "1"); + this.defaults.setProperty("eqg", "0"); + this.defaults.setProperty("villagers", "1"); + this.defaults.setProperty("zombies", "1"); + this.defaults.setProperty("pigzombies", "1"); + this.defaults.setProperty("skeletons", "1"); + this.defaults.setProperty("oldSkinUploaded", "0"); + } + + public PonyConfig() { + super("Mine Little Pony", "minelittlepony.properties"); + } + + @Override + public String getOptionDisplayString(String binding) { + return ""; + } + + public int getIntPropertySafe(String key) { + return this.getIntPropertySafe(key, Integer.MIN_VALUE, Integer.MAX_VALUE); + } + + public int getIntPropertySafe(String key, int minValue, int maxValue) { + int value; + try { + value = this.getIntProperty(key); + } catch (Exception var9) { + try { + boolean e2 = this.getBoolProperty(key); + if (e2) { + value = 1; + } else { + value = 0; + } + } catch (Exception var8) { + int defaultValue1 = this.getDefaultIntProperty(key); + this.setProperty(key, defaultValue1); + MineLPLogger.error("Invalid value for config key \"%s\", using default value %d", + new Object[] { key, Integer.valueOf(defaultValue1) }); + return defaultValue1; + } + } + + if (value >= minValue && value <= maxValue) { + return value; + } else { + int defaultValue = value = this.getDefaultIntProperty(key); + this.setProperty(key, defaultValue); + MineLPLogger.error( + "Invalid value for config key \"%s\", using default value %d. Found %d, expected value between %d and %d.", + new Object[] { key, Integer.valueOf(defaultValue), Integer.valueOf(value), + Integer.valueOf(minValue), Integer.valueOf(maxValue) }); + return defaultValue; + } + } + + public boolean isSet(String key) { + return this.config.containsKey(key); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/PonyLevel.java b/src/main/java/com/minelittlepony/minelp/PonyLevel.java new file mode 100644 index 00000000..be7371d6 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/PonyLevel.java @@ -0,0 +1,23 @@ +package com.minelittlepony.minelp; + +public enum PonyLevel { + PONIES, + HUMANS, + MIXED; + + private static final PonyLevel[] oldValues = { HUMANS, MIXED, PONIES }; + + public static PonyLevel parse(int intValue) { + if (intValue < 0) + intValue = 0; + if (intValue > 2) + intValue = 2; + // it's an old value + return oldValues[intValue]; + } + + @Override + public String toString() { + return name().toString(); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/PonyManager.java b/src/main/java/com/minelittlepony/minelp/PonyManager.java new file mode 100644 index 00000000..132843e3 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/PonyManager.java @@ -0,0 +1,262 @@ +package com.minelittlepony.minelp; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.minelittlepony.minelp.model.PMAPI; +import com.minelittlepony.minelp.util.MineLPLogger; + +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.entity.passive.EntityVillager; +import net.minecraft.util.ResourceLocation; + +public class PonyManager { + public static final String RESOURCE_NAMESPACE = "minelittlepony"; + public static final ResourceLocation zombiePonyResource = new ResourceLocation("minelittlepony", + "textures/entity/zombie/zombie_pony.png"); + public static final ResourceLocation zombieVillagerPonyResource = new ResourceLocation("minelittlepony", + "textures/entity/zombie/zombie_villager_pony.png"); + public static final ResourceLocation zombiePigmanPonyResource = new ResourceLocation("minelittlepony", + "textures/entity/zombie_pigman_pony.png"); + public static final ResourceLocation skeletonPonyResource = new ResourceLocation("minelittlepony", + "textures/entity/skeleton/skeleton_pony.png"); + public static final ResourceLocation skeletonWitherPonyResource = new ResourceLocation("minelittlepony", + "textures/entity/skeleton/skeleton_wither_pony.png"); + public static final ResourceLocation defaultPonyResourceLocation = new ResourceLocation("minelittlepony", + "textures/entity/pony/charpony.png"); + public static List backgroundPonyResourceLocations = new ArrayList(); + public static List villagerResourceLocations; + private static final int MAX_BGPONY_COUNT = 141; + private static int numberOfPonies; + private Map ponyResourceRegistry = new HashMap(); + private Map backgroudPonyResourceRegistry = new HashMap(); + private PonyLevel ponyLevel = PonyLevel.PONIES; + private int useSizes = 1; + private int ponyArmor = 1; + private int showSnuzzles = 1; + private int showScale = 1; + private int ponyVillagers = 1; + private int ponyZombies = 1; + private int ponyPigzombies = 1; + private int ponySkeletons = 1; + private int useHDSkinServer = 1; + private static PonyManager instance; + + private PonyManager() { + initmodels(); + } + + public void initmodels() { + MineLPLogger.info("Initializing models..."); + PMAPI.init(); + MineLPLogger.info("Done initializing models."); + } + + public static PonyManager getInstance() { + if (instance == null) { + instance = new PonyManager(); + } + + return instance; + } + + private Pony getPonyFromResourceRegistry(ResourceLocation skinResourceLocation, AbstractClientPlayer player) { + Pony myLittlePony; + if (!this.ponyResourceRegistry.containsKey(skinResourceLocation)) { + if (player != null) { + myLittlePony = new Pony(player); + } else { + myLittlePony = new Pony(skinResourceLocation); + } + + this.ponyResourceRegistry.put(skinResourceLocation, myLittlePony); + } else { + myLittlePony = this.ponyResourceRegistry.get(skinResourceLocation); + } + + return myLittlePony; + } + + public Pony getPonyFromResourceRegistry(ResourceLocation skinResourceLocation) { + return this.getPonyFromResourceRegistry(skinResourceLocation, (AbstractClientPlayer) null); + } + + public Pony getPonyFromResourceRegistry(AbstractClientPlayer player) { + Pony myLittlePony = this.getPonyFromResourceRegistry(player.getLocationSkin(), player); + if (this.ponyLevel == PonyLevel.PONIES && !myLittlePony.isPonySkin()) { + myLittlePony = this.getPonyFromBackgroundResourceRegistry(player); + } + + if (player.getCommandSenderName().equals(MineLittlePony.getSPUsername())) { + myLittlePony.isSpPlayer = true; + } + + return myLittlePony; + } + + public Pony getPonyFromResourceRegistry(EntityVillager entity) { + int profession = entity.getProfession(); + + ResourceLocation villagerResourceLocation; + try { + villagerResourceLocation = villagerResourceLocations.get(profession); + } catch (IndexOutOfBoundsException var5) { + villagerResourceLocation = villagerResourceLocations.get(5); + } + + Pony myLittlePony = this.getPonyFromResourceRegistry(villagerResourceLocation); + myLittlePony.setVillager(profession); + return myLittlePony; + } + + private ResourceLocation getBackgroundPonyResource(String username) { + if (numberOfPonies > 0) { + int backgroundIndex = username.hashCode() % this.getNumberOfPonies(); + if (backgroundIndex < 0) { + backgroundIndex += this.getNumberOfPonies(); + } + + return backgroundPonyResourceLocations.get(backgroundIndex); + } else { + return defaultPonyResourceLocation; + } + } + + public Pony getPonyFromBackgroundResourceRegistry(AbstractClientPlayer player) { + ResourceLocation textureResourceLocation; + if (player.getCommandSenderName() == MineLittlePony.getSPUsername()) { + textureResourceLocation = defaultPonyResourceLocation; + } else { + textureResourceLocation = this.getBackgroundPonyResource(player.getCommandSenderName()); + } + + Pony myLittlePony; + if (!this.backgroudPonyResourceRegistry.containsKey(textureResourceLocation)) { + myLittlePony = new Pony(textureResourceLocation); + this.backgroudPonyResourceRegistry.put(textureResourceLocation, myLittlePony); + } else { + myLittlePony = this.backgroudPonyResourceRegistry.get(textureResourceLocation); + } + + return myLittlePony; + } + + public int getHD() { + return this.useHDSkinServer; + } + + public int getNumberOfPonies() { + return numberOfPonies; + } + + public int getPonyArmor() { + return this.ponyArmor; + } + + public PonyLevel getPonyLevel() { + return this.ponyLevel; + } + + public int getPonyPigzombies() { + return this.ponyPigzombies; + } + + public int getPonySkeletons() { + return this.ponySkeletons; + } + + public int getPonyVillagers() { + return this.ponyVillagers; + } + + public int getPonyZombies() { + return this.ponyZombies; + } + + public int getShowScale() { + return this.showScale; + } + + public int getShowSnuzzles() { + return this.showSnuzzles; + } + + public int getUseSizes() { + return this.useSizes; + } + + public void setHD(int useHDSkinServer) { + this.useHDSkinServer = useHDSkinServer; + } + + public void setPonyArmor(int ponyArmor) { + this.ponyArmor = ponyArmor; + } + + public void setPonyLevel(PonyLevel ponyLevel) { + this.ponyLevel = ponyLevel; + } + + public void setPonyPigzombies(int ponyPigzombies) { + this.ponyPigzombies = ponyPigzombies; + } + + public void setPonySkeletons(int ponySkeletons) { + this.ponySkeletons = ponySkeletons; + } + + public void setPonyVillagers(int ponyVillagers) { + this.ponyVillagers = ponyVillagers; + } + + public void setPonyZombies(int ponyZombies) { + this.ponyZombies = ponyZombies; + } + + public void setShowScale(int showScale) { + this.showScale = showScale; + } + + public void setShowSnuzzles(int showSnuzzles) { + this.showSnuzzles = showSnuzzles; + } + + public void setUseSizes(int useSizes) { + this.useSizes = useSizes; + } + + static { + for (int check = 0; check < MAX_BGPONY_COUNT; ++check) { + backgroundPonyResourceLocations + .add(new ResourceLocation("minelittlepony", "textures/entity/pony/bpony_" + check + ".png")); + } + + numberOfPonies = backgroundPonyResourceLocations.size(); + MineLPLogger.info("Detected %d of %d background ponies installed.", + new Object[] { Integer.valueOf(numberOfPonies), Integer.valueOf(MAX_BGPONY_COUNT) }); + villagerResourceLocations = new ArrayList(); + villagerResourceLocations + .add(new ResourceLocation("minelittlepony", "textures/entity/villager/farmer_pony.png")); + villagerResourceLocations + .add(new ResourceLocation("minelittlepony", "textures/entity/villager/librarian_pony.png")); + villagerResourceLocations + .add(new ResourceLocation("minelittlepony", "textures/entity/villager/priest_pony.png")); + villagerResourceLocations + .add(new ResourceLocation("minelittlepony", "textures/entity/villager/smith_pony.png")); + villagerResourceLocations + .add(new ResourceLocation("minelittlepony", "textures/entity/villager/butcher_pony.png")); + villagerResourceLocations + .add(new ResourceLocation("minelittlepony", "textures/entity/villager/villager_pony.png")); + } + + public static enum PonyRace { + EARTH, + PEGASUS, + UNICORN, + ALICORN, + CHANGELING, + ZEBRA; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/gui/FakeVoxelPropertyCheckBox.java b/src/main/java/com/minelittlepony/minelp/gui/FakeVoxelPropertyCheckBox.java new file mode 100644 index 00000000..b883c5ac --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/gui/FakeVoxelPropertyCheckBox.java @@ -0,0 +1,77 @@ +package com.minelittlepony.minelp.gui; + +import com.voxelmodpack.common.LiteModVoxelCommon; +import com.voxelmodpack.common.gui.interfaces.IExtendedGui; +import com.voxelmodpack.common.properties.VoxelProperty; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProvider; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProviderInteger; + +public class FakeVoxelPropertyCheckBox extends VoxelProperty { + private int width = 11; + + public FakeVoxelPropertyCheckBox(IVoxelPropertyProvider propertyProvider, String binding, String text, int xPos, + int yPos) { + super(propertyProvider, binding, text, xPos, yPos); + this.width = this.fontRenderer.getStringWidth(this.displayText) + 20; + } + + @Override + public void draw(IExtendedGui host, int mouseX, int mouseY) { + this.drawString(this.fontRenderer, this.displayText, this.xPosition + 20, this.yPosition + 2, 16777215); + boolean overButton = this.mouseOver(mouseX, mouseY); + boolean checked = true; + + try { + int e = this.propertyProvider.getIntProperty(this.propertyBinding); + if (e < 2 && e > -1) { + if (e == 0) { + checked = false; + } else { + checked = true; + } + } + } catch (Exception var7) { + ; + } + + host.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, this.xPosition, this.yPosition, + this.xPosition + 11, this.yPosition + 11, 0, overButton ? 16 : 0, 16, overButton ? 32 : 16, 4); + host.drawTexturedModalRect(LiteModVoxelCommon.GUIPARTS, this.xPosition, this.yPosition, this.xPosition + 10, + this.yPosition + 10, checked ? 12 : 0, 52, checked ? 23 : 11, 63); + } + + @Override + public void mouseClicked(int mouseX, int mouseY) { + if (this.mouseOver(mouseX, mouseY)) { + boolean checked = true; + + try { + int e = this.propertyProvider.getIntProperty(this.propertyBinding); + if (e < 2 && e > -1) { + if (e == 0) { + checked = false; + } else { + checked = true; + } + } + } catch (Exception var5) { + ; + } + + if (checked) { + this.propertyProvider.setProperty(this.propertyBinding, 0); + } else { + this.propertyProvider.setProperty(this.propertyBinding, 1); + } + } + + } + + public boolean mouseOver(int mouseX, int mouseY) { + return mouseX > this.xPosition && mouseX < this.xPosition + this.width && mouseY > this.yPosition + && mouseY < this.yPosition + 11; + } + + @Override + public void keyTyped(char keyChar, int keyCode) {} +} diff --git a/src/main/java/com/minelittlepony/minelp/gui/MineLittlePonyGUI.java b/src/main/java/com/minelittlepony/minelp/gui/MineLittlePonyGUI.java new file mode 100644 index 00000000..18626ba1 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/gui/MineLittlePonyGUI.java @@ -0,0 +1,25 @@ +package com.minelittlepony.minelp.gui; + +import com.minelittlepony.minelp.MineLittlePony; +import com.voxelmodpack.common.properties.VoxelPropertyLabel; +import com.voxelmodpack.common.properties.gui.GuiVoxelBoxSettingsPanel; + +public class MineLittlePonyGUI extends GuiVoxelBoxSettingsPanel { + public MineLittlePonyGUI() { + // PonyManager ponyManager = PonyManager.getInstance(); + this.config = MineLittlePony.getConfig(); + byte col1 = 30; + this.properties.add(new VoxelPropertyIntSlider(this.config, "ponylevel", "Pony Level", PANEL_LEFT, PANEL_TOP + 24)); + this.properties.add(new VoxelPropertyLabel("Pony Options", PANEL_LEFT + 15, PANEL_TOP + 58)); + this.properties.add(new FakeVoxelPropertyCheckBox(this.config, "hd", "Enable MineLP skin server (requires restart)", PANEL_LEFT + col1, PANEL_TOP + 72)); + this.properties.add(new FakeVoxelPropertyCheckBox(this.config, "sizes", "Allow all different sizes of pony", PANEL_LEFT + col1, PANEL_TOP + 90)); + this.properties.add(new FakeVoxelPropertyCheckBox(this.config, "ponyarmor", "Use Mine Little Pony compatible armor", PANEL_LEFT + col1, PANEL_TOP + 108)); + this.properties.add(new FakeVoxelPropertyCheckBox(this.config, "snuzzles", "Display snuzzles on ponies", PANEL_LEFT + col1, PANEL_TOP + 126)); + this.properties.add(new FakeVoxelPropertyCheckBox(this.config, "showscale", "Use show-accurate scaling", PANEL_LEFT + col1, PANEL_TOP + 144)); + } + + @Override + public String getPanelTitle() { + return "Mine Little Pony Settings"; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/gui/MineLittlePonyGUIMob.java b/src/main/java/com/minelittlepony/minelp/gui/MineLittlePonyGUIMob.java new file mode 100644 index 00000000..73593586 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/gui/MineLittlePonyGUIMob.java @@ -0,0 +1,24 @@ +package com.minelittlepony.minelp.gui; + +import com.minelittlepony.minelp.MineLittlePony; +import com.voxelmodpack.common.properties.VoxelPropertyLabel; +import com.voxelmodpack.common.properties.gui.GuiVoxelBoxSettingsPanel; + +public class MineLittlePonyGUIMob extends GuiVoxelBoxSettingsPanel { + public MineLittlePonyGUIMob() { + // PonyManager ponyManager = PonyManager.getInstance(); + this.config = MineLittlePony.getConfig(); + byte col1 = 30; + this.properties.add(new VoxelPropertyLabel("If you make any changes here, you must restart", PANEL_LEFT + 15, PANEL_TOP + 11, 16737894)); + this.properties.add(new VoxelPropertyLabel("Minecraft before they will take effect!", PANEL_LEFT + 15, PANEL_TOP + 23, 16737894)); + this.properties.add(new FakeVoxelPropertyCheckBox(this.config, "villagers", "Ponify villagers", PANEL_LEFT + col1, PANEL_TOP + 42)); + this.properties.add(new FakeVoxelPropertyCheckBox(this.config, "zombies", "Ponify zombies", PANEL_LEFT + col1, PANEL_TOP + 60)); + this.properties.add(new FakeVoxelPropertyCheckBox(this.config, "pigzombies", "Ponify zombie pigmen", PANEL_LEFT + col1, PANEL_TOP + 78)); + this.properties.add(new FakeVoxelPropertyCheckBox(this.config, "skeletons", "Ponify skeletons", PANEL_LEFT + col1, PANEL_TOP + 96)); + } + + @Override + public String getPanelTitle() { + return "Mine Little Pony Mob Settings"; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/gui/VoxelPropertyIntSlider.java b/src/main/java/com/minelittlepony/minelp/gui/VoxelPropertyIntSlider.java new file mode 100644 index 00000000..10c3ac1e --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/gui/VoxelPropertyIntSlider.java @@ -0,0 +1,175 @@ +package com.minelittlepony.minelp.gui; + +import org.lwjgl.input.Mouse; + +import com.voxelmodpack.common.LiteModVoxelCommon; +import com.voxelmodpack.common.gui.interfaces.IExtendedGui; +import com.voxelmodpack.common.properties.VoxelProperty; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProviderInteger; + +import net.minecraft.util.MathHelper; + +public class VoxelPropertyIntSlider extends VoxelProperty { + int minValue; + int maxValue; + float value; + boolean overReset; + boolean overSlide; + boolean overBar; + boolean setBar; + boolean dragging; + int offset; + String minText; + String midText; + String maxText; + String labelText; + + public VoxelPropertyIntSlider(IVoxelPropertyProviderInteger parent, String binding, String text, String minText, + String maxText, int xPos, int yPos, int min, int max) { + this(parent, binding, text, minText, maxText, xPos, yPos); + this.minValue = min; + this.maxValue = max; + } + + public VoxelPropertyIntSlider(IVoxelPropertyProviderInteger parent, String binding, String text, int xPos, int yPos, + float min, float max) { + this(parent, binding, text, xPos, yPos); + } + + public VoxelPropertyIntSlider(IVoxelPropertyProviderInteger parent, String binding, String text, String minText, + String maxText, int xPos, int yPos) { + this(parent, binding, text, xPos, yPos); + this.minText = minText; + this.maxText = maxText; + } + + public VoxelPropertyIntSlider(IVoxelPropertyProviderInteger parent, String binding, String text, int xPos, + int yPos) { + super(parent, binding, text, xPos, yPos); + this.minValue = 0; + this.maxValue = 2; + this.value = 2.0F; + this.overReset = false; + this.overSlide = false; + this.overBar = false; + this.setBar = false; + this.dragging = false; + this.offset = 0; + this.minText = "Humans"; + this.midText = "Mix"; + this.maxText = "Ponies"; + } + + @Override + public void draw(IExtendedGui gui, int mouseX, int mouseY) { + this.overReset = this.mouseOverReset(mouseX, mouseY); + int outset = this.overReset ? 1 : 0; + int v = this.overReset ? 16 : 0; + drawRect(this.xPosition + 160 - outset, this.yPosition + 11 - outset, this.xPosition + 212 + outset, + this.yPosition + 26 + outset, -16777216); + gui.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, this.xPosition + 159 - outset, + this.yPosition + 10 - outset, this.xPosition + 213 + outset, this.yPosition + 27 + outset, 0, v, 16, + 16 + v, 4); + this.drawString(this.mc.fontRendererObj, "Default", this.xPosition + 169, this.yPosition + 15, + this.overReset ? 16777215 : 10066329); + int sliderLeft = this.xPosition + 48; + int sliderRight = this.xPosition + 124; + int sliderXPos = sliderLeft + 32; + int sliderXPos2 = sliderLeft + 45; + int sliderYPos = this.yPosition + 12; + int sliderYPos2 = this.yPosition + 25; + int sliderMinX = sliderLeft - (sliderXPos + sliderXPos2) / 2 + 5; + int sliderMaxX = sliderRight - (sliderXPos + sliderXPos2) / 2 - 5; + this.drawHorizontalLine(sliderLeft, sliderRight, this.yPosition + 18, -6710887); + this.drawVerticalLine(this.xPosition + 86, this.yPosition + 14, this.yPosition + 22, -6710887); + this.drawVerticalLine(sliderLeft, this.yPosition + 14, this.yPosition + 22, -6710887); + this.drawVerticalLine(sliderRight, this.yPosition + 14, this.yPosition + 22, -6710887); + if (this.displayText != null) { + this.drawString(this.mc.fontRendererObj, this.displayText, this.xPosition + 15, this.yPosition - 14, 10079487); + } + + this.drawString(this.mc.fontRendererObj, this.minText, this.xPosition + 35, this.yPosition, 16777215); + if (this.midText != null) { + this.drawString(this.mc.fontRendererObj, this.midText, this.xPosition + 80, this.yPosition, 16777215); + } + + if (this.maxText != null) { + this.drawString(this.mc.fontRendererObj, this.maxText, this.xPosition + 110, this.yPosition, 16777215); + } else { + float scale = (this.value + 1.0F) / 2.0F; + int displayValue = MathHelper.ceiling_float_int( + (this.minValue + (this.maxValue - this.minValue) * scale) * 100.0F); + this.drawString(this.mc.fontRendererObj, displayValue + "%", this.xPosition + 130, this.yPosition + 15, + 16777215); + } + + this.overSlide = this.mouseIn(mouseX, mouseY, sliderXPos, sliderYPos, sliderXPos2, sliderYPos2); + this.overBar = this.mouseIn(mouseX, mouseY, sliderLeft, sliderYPos, sliderRight, sliderYPos2) + && !this.overSlide; + if (this.dragging) { + if (Mouse.isButtonDown(0)) { + this.offset = Math.min(Math.max(mouseX - (sliderXPos + sliderXPos2) / 2, sliderMinX), sliderMaxX); + this.value = (float) this.offset / (float) sliderMaxX; + } else { + this.value = (float) this.offset / (float) sliderMaxX; + this.propertyProvider.setProperty(this.propertyBinding, + Math.round(this.value) + 1); + this.dragging = false; + } + } else { + this.offset = (this.propertyProvider.getIntProperty(this.propertyBinding) + - 1) * sliderMaxX; + this.value = (float) this.offset / (float) sliderMaxX; + } + + if (this.setBar) { + this.offset = mouseX - (sliderXPos + sliderXPos2) / 2; + this.value = (float) this.offset / (float) sliderMaxX; + this.propertyProvider.setProperty(this.propertyBinding, + Math.round(this.value) + 1); + this.setBar = false; + this.dragging = true; + } + + if (this.offset > sliderMaxX) { + this.offset = sliderMaxX; + } + + if (this.offset < sliderMinX) { + this.offset = sliderMinX; + } + + drawRect(sliderXPos2 - 1 + this.offset, sliderYPos2 - 1, sliderXPos + 1 + this.offset, sliderYPos + 1, + -16777216); + gui.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, sliderXPos + this.offset, sliderYPos, + sliderXPos2 + this.offset, sliderYPos2, 0, !this.overSlide && !this.dragging ? 0 : 16, 16, + !this.overSlide && !this.dragging ? 16 : 32, 4); + } + + protected boolean mouseIn(int mouseX, int mouseY, int x1, int y1, int x2, int y2) { + return mouseX > x1 + this.offset && mouseX < x2 + this.offset && mouseY > y1 && mouseY < y2; + } + + protected boolean mouseOverReset(int mouseX, int mouseY) { + return mouseX > this.xPosition + 159 && mouseX < this.xPosition + 213 && mouseY > this.yPosition + 10 + && mouseY < this.yPosition + 27; + } + + @Override + public void mouseClicked(int mouseX, int mouseY) { + if (this.overSlide) { + this.dragging = true; + this.playClickSound(this.mc.getSoundHandler()); + } else if (this.overBar) { + this.setBar = true; + this.playClickSound(this.mc.getSoundHandler()); + } else if (this.overReset) { + this.propertyProvider.setProperty(this.propertyBinding, 2); + this.playClickSound(this.mc.getSoundHandler()); + } + + } + + @Override + public void keyTyped(char keyChar, int keyCode) {} +} diff --git a/src/main/java/com/minelittlepony/minelp/hdskins/gui/EntityPonyModel.java b/src/main/java/com/minelittlepony/minelp/hdskins/gui/EntityPonyModel.java new file mode 100644 index 00000000..9d3086c1 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/hdskins/gui/EntityPonyModel.java @@ -0,0 +1,10 @@ +package com.minelittlepony.minelp.hdskins.gui; + +import com.mojang.authlib.GameProfile; +import com.voxelmodpack.hdskins.gui.EntityPlayerModel; + +public class EntityPonyModel extends EntityPlayerModel { + public EntityPonyModel(GameProfile profile) { + super(profile); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/hdskins/gui/GuiSkinsMineLP.java b/src/main/java/com/minelittlepony/minelp/hdskins/gui/GuiSkinsMineLP.java new file mode 100644 index 00000000..8f2a65e1 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/hdskins/gui/GuiSkinsMineLP.java @@ -0,0 +1,684 @@ +package com.minelittlepony.minelp.hdskins.gui; + +import static net.minecraft.client.renderer.GlStateManager.*; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.DoubleBuffer; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + +import javax.imageio.ImageIO; +import javax.swing.JFileChooser; + +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.glu.GLU; + +import com.minelittlepony.minelp.PonyManager; +import com.minelittlepony.minelp.util.MineLPLogger; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.exceptions.AuthenticationException; +import com.mojang.authlib.minecraft.MinecraftSessionService; +import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; +import com.mumfrey.liteloader.util.log.LiteLoaderLogger; +import com.voxelmodpack.common.net.upload.IUploadCompleteCallback; +import com.voxelmodpack.common.net.upload.ThreadMultipartPostUpload; +import com.voxelmodpack.common.net.upload.awt.IOpenFileCallback; +import com.voxelmodpack.common.net.upload.awt.ThreadOpenFilePNG; +import com.voxelmodpack.hdskins.gui.EntityPlayerModel; +import com.voxelmodpack.hdskins.mod.HDSkinsModCore; +import com.voxelmodpack.voxelmenu.IPanoramaRenderer; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiMainMenu; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Session; + +public class GuiSkinsMineLP extends GuiScreen implements IUploadCompleteCallback, IOpenFileCallback, IPanoramaRenderer { + private static final ResourceLocation vignette = new ResourceLocation("textures/misc/vignette.png"); + private static final int MAX_SKIN_DIMENSION = 8192; + private static final String skinServerId = "7853dfddc358333843ad55a2c7485c4aa0380a51"; + private int updateCounter = 0; + private ResourceLocation viewportTexture; + private IPanoramaRenderer panoramaRenderer; + private static final ResourceLocation[] cubemapTextures = { + new ResourceLocation("hdskins", "textures/cubemaps/cubemap0_0.png"), + new ResourceLocation("hdskins", "textures/cubemaps/cubemap0_1.png"), + new ResourceLocation("hdskins", "textures/cubemaps/cubemap0_2.png"), + new ResourceLocation("hdskins", "textures/cubemaps/cubemap0_3.png"), + new ResourceLocation("hdskins", "textures/cubemaps/cubemap0_4.png"), + new ResourceLocation("hdskins", "textures/cubemaps/cubemap0_5.png") }; + private GuiButton btnBrowse; + private GuiButton btnUpload; + private GuiButton btnClear; + private GuiButton btnBack; + private EntityPonyModel localPlayer; + private EntityPonyModel remotePlayer; + protected DoubleBuffer doubleBuffer; + private String screenTitle; + private String uploadError; + private volatile String skinMessage = "Choose a file"; + private String skinUploadMessage = "Uploading skin please wait..."; + private volatile boolean fetchingSkin; + private volatile boolean uploadingSkin; + private volatile boolean pendingRemoteSkinRefresh; + private volatile boolean throttledByMojang; + private int refreshCounter = -1; + private ThreadOpenFilePNG openFileThread; + private ThreadMultipartPostUpload threadSkinUpload; + private Object skinLock = new Object(); + private File pendingSkinFile; + private File selectedSkin; + private BufferedImage pendingSkinImage; + private float uploadOpacity = 0.0F; + private float lastPartialTick; + + public GuiSkinsMineLP() { + Minecraft minecraft = Minecraft.getMinecraft(); + this.screenTitle = "Skin Manager"; + GameProfile profile = minecraft.getSession().getProfile(); + this.localPlayer = new EntityPonyModel(profile); + this.remotePlayer = new EntityPonyModel(profile); + RenderManager rm = Minecraft.getMinecraft().getRenderManager(); + rm.renderEngine = minecraft.getTextureManager(); + rm.options = minecraft.gameSettings; + rm.livingPlayer = this.localPlayer; + this.setRemoteSkin(); + this.fetchingSkin = true; + this.panoramaRenderer = HDSkinsModCore.getPanoramaRenderer(this); + } + + @Override + public void updateScreen() { + ++this.updateCounter; + this.panoramaRenderer.updatePanorama(); + this.localPlayer.updateModel(); + this.remotePlayer.updateModel(); + if (this.fetchingSkin && this.remotePlayer.isTextureSetupComplete()) { + this.fetchingSkin = false; + this.btnClear.enabled = true; + } + + synchronized (this.skinLock) { + if (this.pendingSkinFile != null) { + this.localPlayer.setLocalSkin(this.pendingSkinFile); + this.selectedSkin = this.pendingSkinFile; + this.pendingSkinFile = null; + MineLPLogger.debug("Invalidating old local skin, checking updated local skin"); + PonyManager.getInstance().getPonyFromResourceRegistry(this.localPlayer.getSkinTexture()) + .checkSkin(this.pendingSkinImage); + this.pendingSkinImage = null; + this.btnUpload.enabled = true; + } + } + + if (this.pendingRemoteSkinRefresh) { + this.pendingRemoteSkinRefresh = false; + this.fetchingSkin = true; + this.btnClear.enabled = false; + this.setRemoteSkin(); + MineLPLogger.debug("Invalidating old remove skin, checking updated remote skin"); + PonyManager.getInstance().getPonyFromResourceRegistry(this.remotePlayer.getSkinTexture()) + .invalidateSkinCheck(); + } + + if (this.throttledByMojang) { + if (this.refreshCounter == -1) { + this.refreshCounter = 200; + } else if (this.refreshCounter > 0) { + --this.refreshCounter; + } else { + this.refreshCounter = -1; + this.throttledByMojang = false; + this.setRemoteSkin(); + } + } + + } + + private void setRemoteSkin() { + try { + this.remotePlayer.setRemoteSkin(); + } catch (Exception var2) { + var2.printStackTrace(); + this.throttledByMojang = true; + } + + } + + @Override + public void updatePanorama() {} + + @Override + public int getUpdateCounter() { + return this.updateCounter; + } + + @Override + public void setWorldAndResolution(Minecraft par1Minecraft, int par2, int par3) { + super.setWorldAndResolution(par1Minecraft, par2, par3); + this.panoramaRenderer.setPanoramaResolution(par1Minecraft, par2, par3); + } + + @Override + public void setPanoramaResolution(Minecraft minecraft, int width, int height) {} + + protected List getControlList() { + return this.buttonList; + } + + @Override + public void initGui() { + super.initGui(); + this.panoramaRenderer.initPanoramaRenderer(); + this.getControlList().clear(); + this.getControlList().add(this.btnBrowse = new GuiButton(0, 30, this.height - 36, 60, 20, "Browse...")); + this.getControlList() + .add(this.btnUpload = new GuiButton(1, this.width / 2 - 24, this.height / 2 - 10, 48, 20, ">>")); + this.getControlList().add(this.btnClear = new GuiButton(2, this.width - 90, this.height - 36, 60, 20, "Clear")); + this.getControlList() + .add(this.btnBack = new GuiButton(3, this.width / 2 - 50, this.height - 36, 100, 20, "Close")); + this.btnUpload.enabled = false; + this.btnBrowse.enabled = !this.mc.isFullScreen(); + } + + @Override + public void initPanoramaRenderer() { + this.viewportTexture = this.mc.getTextureManager().getDynamicTextureLocation("skinpanorama", + new DynamicTexture(256, 256)); + } + + @Override + public void onGuiClosed() { + super.onGuiClosed(); + this.localPlayer.releaseTextures(); + this.remotePlayer.releaseTextures(); + PonyManager.getInstance().getPonyFromResourceRegistry(this.localPlayer.getSkinTexture()).invalidateSkinCheck(); + PonyManager.getInstance().getPonyFromResourceRegistry(this.remotePlayer.getSkinTexture()).invalidateSkinCheck(); + } + + @Override + public void onFileOpenDialogClosed(JFileChooser fileDialog, int dialogResult) { + this.openFileThread = null; + if (dialogResult == 0) { + this.loadLocalFile(fileDialog.getSelectedFile()); + } + + } + + private void loadLocalFile(File skinFile) { + if (!skinFile.exists()) { + this.skinMessage = "File not readable"; + } else { + BufferedImage chosenImage; + try { + chosenImage = ImageIO.read(skinFile); + } catch (IOException var6) { + this.skinMessage = "Error opening skin file"; + var6.printStackTrace(); + return; + } + + if (chosenImage == null) { + this.skinMessage = "Error opening skin file"; + } else if (isPowerOfTwo(chosenImage.getWidth()) + && (chosenImage.getWidth() == chosenImage.getHeight() * 2 + || chosenImage.getWidth() == chosenImage.getHeight()) + && chosenImage.getWidth() <= MAX_SKIN_DIMENSION + && chosenImage.getHeight() <= MAX_SKIN_DIMENSION) { + synchronized (this.skinLock) { + this.pendingSkinFile = skinFile; + this.pendingSkinImage = chosenImage; + } + } else { + this.skinMessage = "Not a valid skin file"; + } + } + } + + @Override + protected void actionPerformed(GuiButton guiButton) { + if (this.openFileThread == null && !this.uploadingSkin) { + if (this.uploadError != null) { + this.uploadError = null; + } else { + if (guiButton.id == this.btnBrowse.id) { + this.selectedSkin = null; + this.localPlayer.releaseTextures(); + this.openFileThread = new ThreadOpenFilePNG(this.mc, "Choose skin", this); + this.openFileThread.start(); + } + + if (guiButton.id == this.btnUpload.id) { + if (this.selectedSkin != null) { + this.uploadSkin(this.mc.getSession(), this.selectedSkin); + this.btnUpload.enabled = false; + } else { + this.setUploadError("Please select a skin first"); + } + } + + if (guiButton.id == this.btnClear.id && this.remotePlayer.isTextureSetupComplete()) { + this.clearUploadedSkin(this.mc.getSession()); + this.btnUpload.enabled = this.selectedSkin != null; + } + + if (guiButton.id == this.btnBack.id) { + this.mc.displayGuiScreen(new GuiMainMenu()); + } + + } + } + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int button) throws IOException { + if (this.uploadError != null) { + this.uploadError = null; + } else { + super.mouseClicked(mouseX, mouseY, button); + byte top = 30; + int bottom = this.height - 40; + int mid = this.width / 2; + if ((mouseX > 30 && mouseX < mid - 30 || mouseX > mid + 30 && mouseX < this.width - 30) && mouseY > top + && mouseY < bottom) { + this.localPlayer.swingArm(); + this.remotePlayer.swingArm(); + } + + } + } + + @Override + protected void keyTyped(char keyChar, int keyCode) throws IOException { + if (this.openFileThread == null && !this.uploadingSkin) { + super.keyTyped(keyChar, keyCode); + } + } + + public void setupCubemapCamera() { + matrixMode(5889); + pushMatrix(); + loadIdentity(); + GLU.gluPerspective(150.0F, 1.0F, 0.05F, 10.0F); + matrixMode(5888); + pushMatrix(); + loadIdentity(); + } + + public void revertPanoramaMatrix() { + matrixMode(5889); + popMatrix(); + matrixMode(5888); + popMatrix(); + } + + private void renderCubeMapTexture(int mouseX, int mouseY, float partialTick) { + this.setupCubemapCamera(); + color(1.0F, 1.0F, 1.0F, 1.0F); + rotate(180.0F, 1.0F, 0.0F, 0.0F); + GL11.glEnable(3042); + GL11.glDisable(3008); + GL11.glDisable(2884); + depthMask(false); + blendFunc(770, 771); + byte blendIterations = 8; + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer wr = tessellator.getWorldRenderer(); + + for (int blendPass = 0; blendPass < blendIterations * blendIterations; ++blendPass) { + pushMatrix(); + float offsetX = ((float) (blendPass % blendIterations) / (float) blendIterations - 0.5F) / 64.0F; + float offsetY = ((float) (blendPass / blendIterations) / (float) blendIterations - 0.5F) / 64.0F; + float offsetZ = 0.0F; + translate(offsetX, offsetY, offsetZ); + rotate(MathHelper.sin((this.updateCounter + 200 + partialTick) / 400.0F) * 25.0F + 20.0F, 1.0F, + 0.0F, 0.0F); + rotate(-(this.updateCounter + 200 + partialTick) * 0.1F, 0.0F, 1.0F, 0.0F); + + for (int cubeSide = 0; cubeSide < 6; ++cubeSide) { + pushMatrix(); + if (cubeSide == 1) { + rotate(90.0F, 0.0F, 1.0F, 0.0F); + } + + if (cubeSide == 2) { + rotate(180.0F, 0.0F, 1.0F, 0.0F); + } + + if (cubeSide == 3) { + rotate(-90.0F, 0.0F, 1.0F, 0.0F); + } + + if (cubeSide == 4) { + rotate(90.0F, 1.0F, 0.0F, 0.0F); + } + + if (cubeSide == 5) { + rotate(-90.0F, 1.0F, 0.0F, 0.0F); + } + + this.mc.getTextureManager().bindTexture(cubemapTextures[cubeSide]); + wr.startDrawingQuads(); + wr.setColorRGBA_I(16777215, 255 / (blendPass + 1)); + wr.addVertexWithUV(-1.0D, -1.0D, 1.0D, 0.0D, 0.0D); + wr.addVertexWithUV(1.0D, -1.0D, 1.0D, 1.0D, 0.0D); + wr.addVertexWithUV(1.0D, 1.0D, 1.0D, 1.0D, 1.0D); + wr.addVertexWithUV(-1.0D, 1.0D, 1.0D, 0.0D, 1.0D); + tessellator.draw(); + popMatrix(); + } + + popMatrix(); + colorMask(true, true, true, false); + } + + wr.setTranslation(0.0D, 0.0D, 0.0D); + colorMask(true, true, true, true); + depthMask(true); + GL11.glEnable(2884); + GL11.glEnable(3008); + GL11.glEnable(2929); + this.revertPanoramaMatrix(); + } + + private void rotateAndBlurCubemap(float partialTick) { + this.mc.getTextureManager().bindTexture(this.viewportTexture); + GL11.glCopyTexSubImage2D(3553, 0, 0, 0, 0, 0, 256, 256); + GL11.glEnable(3042); + blendFunc(770, 771); + colorMask(true, true, true, false); + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer wr = tessellator.getWorldRenderer(); + wr.startDrawingQuads(); + byte blurPasses = 4; + + for (int blurPass = 0; blurPass < blurPasses; ++blurPass) { + wr.setColorRGBA_F(1.0F, 1.0F, 1.0F, 1.0F / (blurPass + 1)); + float var7 = (blurPass - blurPasses / 2) / 256.0F; + wr.addVertexWithUV(this.width, this.height, this.zLevel, 0.0F + var7, 0.0D); + wr.addVertexWithUV(this.width, 0.0D, this.zLevel, 1.0F + var7, 0.0D); + wr.addVertexWithUV(0.0D, 0.0D, this.zLevel, 1.0F + var7, 1.0D); + wr.addVertexWithUV(0.0D, this.height, this.zLevel, 0.0F + var7, 1.0D); + } + + tessellator.draw(); + colorMask(true, true, true, true); + GL11.glDisable(3042); + } + + @Override + public boolean renderPanorama(int mouseX, int mouseY, float partialTicks) { + GL11.glViewport(0, 0, 256, 256); + this.renderCubeMapTexture(mouseX, mouseY, partialTicks); + GL11.glDisable(3553); + GL11.glEnable(3553); + + for (int tessellator = 0; tessellator < 8; ++tessellator) { + this.rotateAndBlurCubemap(partialTicks); + } + + GL11.glViewport(0, 0, this.mc.displayWidth, this.mc.displayHeight); + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer wr = tessellator.getWorldRenderer(); + wr.startDrawingQuads(); + float aspect = this.width > this.height ? 120.0F / this.width : 120.0F / this.height; + float uSample = this.height * aspect / 256.0F; + float vSample = this.width * aspect / 256.0F; + GL11.glTexParameteri(3553, 10241, 9729); + GL11.glTexParameteri(3553, 10240, 9729); + wr.setColorRGBA_F(1.0F, 1.0F, 1.0F, 1.0F); + wr.addVertexWithUV(0.0D, this.height, this.zLevel, 0.5F - uSample, 0.5F + vSample); + wr.addVertexWithUV(this.width, this.height, this.zLevel, 0.5F - uSample, 0.5F - vSample); + wr.addVertexWithUV(this.width, 0.0D, this.zLevel, 0.5F + uSample, 0.5F - vSample); + wr.addVertexWithUV(0.0D, 0.0D, this.zLevel, 0.5F + uSample, 0.5F + vSample); + tessellator.draw(); + return true; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTick) { + float deltaTime = this.updateCounter + partialTick - this.lastPartialTick; + this.lastPartialTick = this.updateCounter + partialTick; + GL11.glDisable(2912); + this.mc.entityRenderer.disableLightmap(); + this.panoramaRenderer.renderPanorama(mouseX, mouseY, partialTick); + byte top = 30; + int bottom = this.height - 40; + int mid = this.width / 2; + int horizon = this.height / 2 + this.height / 5; + GL11.glPushAttrib(1048575); + Gui.drawRect(30, top, mid - 30, bottom, Integer.MIN_VALUE); + Gui.drawRect(mid + 30, top, this.width - 30, bottom, Integer.MIN_VALUE); + this.drawGradientRect(30, horizon, mid - 30, bottom, -2130706433, 16777215); + this.drawGradientRect(mid + 30, horizon, this.width - 30, bottom, -2130706433, 16777215); + super.drawScreen(mouseX, mouseY, partialTick); + popAttrib(); + this.enableClipping(30, bottom); + float yPos = this.height * 0.75F; + float xPos1 = this.width * 0.25F; + float xPos2 = this.width * 0.75F; + float scale = this.height * 0.25F; + this.renderPlayerModel(this.localPlayer, xPos1, yPos, scale, xPos1 - mouseX, yPos - scale * 1.8F - mouseY, + partialTick); + this.renderPlayerModel(this.remotePlayer, xPos2, yPos, scale, xPos2 - mouseX, yPos - scale * 1.8F - mouseY, + partialTick); + this.disableClipping(); + this.drawCenteredString(this.fontRendererObj, this.screenTitle, this.width / 2, 10, 16777215); + this.fontRendererObj.drawStringWithShadow("Local Skin", 34, 34, 16777215); + this.fontRendererObj.drawStringWithShadow("Server Skin", this.width / 2 + 34, 34, 16777215); + GL11.glDisable(2929); + depthMask(false); + this.drawGradientRect(30, this.height - 60, mid - 30, bottom, 0, -520093697); + this.drawGradientRect(mid + 30, this.height - 60, this.width - 30, bottom, 0, -520093697); + int labelwidth = (this.width / 2 - 80) / 2; + int opacity; + if (!this.localPlayer.isUsingLocalTexture()) { + opacity = this.fontRendererObj.getStringWidth(this.skinMessage) / 2; + Gui.drawRect(40, this.height / 2 - 12, this.width / 2 - 40, this.height / 2 + 12, -1342177280); + this.fontRendererObj.drawStringWithShadow(this.skinMessage, (int) (xPos1 - opacity), this.height / 2 - 4, + 16777215); + } + + if (this.fetchingSkin) { + String opacity1; + if (this.throttledByMojang) { + opacity1 = "\u00a7cMojang API Error!"; + String stringWidth = "Please wait 1 minute"; + int stringWidth1 = this.fontRendererObj.getStringWidth(opacity1) / 2; + int stringWidth2 = this.fontRendererObj.getStringWidth(stringWidth) / 2; + Gui.drawRect((int) (xPos2 - labelwidth), this.height / 2 - 16, this.width - 40, this.height / 2 + 16, + -1342177280); + this.fontRendererObj.drawStringWithShadow(opacity1, (int) (xPos2 - stringWidth1), this.height / 2 - 10, + 16777215); + this.fontRendererObj.drawStringWithShadow(stringWidth, (int) (xPos2 - stringWidth2), + this.height / 2 + 2, 16777215); + } else { + opacity1 = "Fetching skin..."; + int stringWidth1 = this.fontRendererObj.getStringWidth(opacity1) / 2; + Gui.drawRect((int) (xPos2 - labelwidth), this.height / 2 - 12, this.width - 40, this.height / 2 + 12, + -1342177280); + this.fontRendererObj.drawStringWithShadow(opacity1, (int) (xPos2 - stringWidth1), this.height / 2 - 4, + 16777215); + } + } + + if (this.uploadingSkin || this.uploadOpacity > 0.0F) { + if (!this.uploadingSkin) { + this.uploadOpacity -= deltaTime * 0.05F; + } else if (this.uploadOpacity < 1.0F) { + this.uploadOpacity += deltaTime * 0.1F; + } + + if (this.uploadOpacity > 1.0F) { + this.uploadOpacity = 1.0F; + } + + opacity = Math.min(180, (int) (this.uploadOpacity * 180.0F)) & 255; + if (this.uploadOpacity > 0.0F) { + Gui.drawRect(0, 0, this.width, this.height, opacity << 24 | 0); + if (this.uploadingSkin) { + this.drawCenteredString(this.fontRendererObj, this.skinUploadMessage, this.width / 2, + this.height / 2, opacity << 24 | 16777215); + } + } + } + + if (this.uploadError != null) { + Gui.drawRect(0, 0, this.width, this.height, -1342177280); + this.drawCenteredString(this.fontRendererObj, "Uploading skin failed", this.width / 2, this.height / 2 - 10, + -171); + this.drawCenteredString(this.fontRendererObj, this.uploadError, this.width / 2, this.height / 2 + 2, + -43691); + } + + depthMask(true); + GL11.glEnable(2929); + } + + protected void renderVignette(int mouseX, int mouseY, float partialTick) { + GL11.glDisable(2929); + depthMask(false); + blendFunc(1, 774); + color(1.0F, 1.0F, 1.0F, 1.0F); + this.mc.getTextureManager().bindTexture(vignette); + GL11.glLogicOp(5386); + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer wr = tessellator.getWorldRenderer(); + wr.startDrawingQuads(); + wr.addVertexWithUV(0.0D, this.height, -90.0D, 0.0D, 1.0D); + wr.addVertexWithUV(this.width, this.height, -90.0D, 1.0D, 1.0D); + wr.addVertexWithUV(this.width, 0.0D, -90.0D, 1.0D, 0.0D); + wr.addVertexWithUV(0.0D, 0.0D, -90.0D, 0.0D, 0.0D); + tessellator.draw(); + depthMask(true); + GL11.glDisable(3058); + GL11.glEnable(2929); + color(1.0F, 1.0F, 1.0F, 1.0F); + blendFunc(770, 771); + } + + public void renderPlayerModel(EntityPlayerModel thePlayer, float xPosition, float yPosition, float scale, + float mouseX, float mouseY, float partialTick) { + GL11.glEnable(2903); + pushMatrix(); + translate(xPosition, yPosition, 300.0F); + scale(-scale, scale, scale); + rotate(180.0F, 0.0F, 0.0F, 1.0F); + rotate(135.0F, 0.0F, 1.0F, 0.0F); + RenderHelper.enableStandardItemLighting(); + rotate(-135.0F, 0.0F, 1.0F, 0.0F); + rotate(15.0F, 1.0F, 0.0F, 0.0F); + rotate((this.updateCounter + partialTick) * 2.5F, 0.0F, 1.0F, 0.0F); + thePlayer.rotationPitch = -((float) Math.atan(mouseY / 40.0F)) * 20.0F; + translate(0.0D, thePlayer.getYOffset(), 0.0D); + RenderManager rm = Minecraft.getMinecraft().getRenderManager(); + rm.playerViewY = 180.0F; + rm.renderEntityWithPosYaw(thePlayer, 0.0D, 0.0D, 0.0D, 1.0F, 1.0F); + popMatrix(); + RenderHelper.disableStandardItemLighting(); + GL11.glDisable('\u803a'); + } + + protected final void enableClipping(int yTop, int yBottom) { + if (this.doubleBuffer == null) { + this.doubleBuffer = BufferUtils.createByteBuffer(32).asDoubleBuffer(); + } + + this.doubleBuffer.clear(); + this.doubleBuffer.put(0.0D).put(1.0D).put(0.0D).put((-yTop)).flip(); + GL11.glClipPlane(12288, this.doubleBuffer); + this.doubleBuffer.clear(); + this.doubleBuffer.put(0.0D).put(-1.0D).put(0.0D).put(yBottom).flip(); + GL11.glClipPlane(12289, this.doubleBuffer); + GL11.glEnable(12288); + GL11.glEnable(12289); + } + + protected final void disableClipping() { + GL11.glDisable(12289); + GL11.glDisable(12288); + } + + public static boolean isPowerOfTwo(int number) { + return number != 0 && (number & number - 1) == 0; + } + + private boolean clearUploadedSkin(Session session) { + if (!this.registerServerConnection(session, skinServerId)) { + return false; + } else { + HashMap sourceData = new HashMap(); + sourceData.put("user", session.getUsername()); + sourceData.put("uuid", session.getPlayerID()); + sourceData.put("clear", "1"); + this.uploadError = null; + this.uploadingSkin = true; + this.skinUploadMessage = "Sending request to server please wait..."; + this.threadSkinUpload = new ThreadMultipartPostUpload("http://minelpskinmanager.voxelmodpack.com/", + sourceData, this); + this.threadSkinUpload.start(); + return true; + } + } + + private boolean uploadSkin(Session session, File skinFile) { + if (!this.registerServerConnection(session, skinServerId)) { + return false; + } else { + HashMap sourceData = new HashMap(); + sourceData.put("user", session.getUsername()); + sourceData.put("uuid", session.getPlayerID()); + sourceData.put("skin", skinFile); + this.uploadError = null; + this.uploadingSkin = true; + this.skinUploadMessage = "Uploading skin please wait..."; + this.threadSkinUpload = new ThreadMultipartPostUpload("http://minelpskinmanager.voxelmodpack.com/", + sourceData, this); + this.threadSkinUpload.start(); + return true; + } + } + + private void setUploadError(String error) { + this.uploadError = error.startsWith("ERROR: ") ? error.substring(7) : error; + this.btnUpload.enabled = true; + } + + @Override + public void onUploadComplete(String response) { + LiteLoaderLogger.info("Upload completed with: %s", new Object[] { response }); + this.uploadingSkin = false; + this.threadSkinUpload = null; + if (!response.equalsIgnoreCase("OK")) { + this.setUploadError(response); + } else { + this.pendingRemoteSkinRefresh = true; + } + } + + private boolean registerServerConnection(Session session, String serverId) { + try { + MinecraftSessionService e = (new YggdrasilAuthenticationService(this.mc.getProxy(), + UUID.randomUUID().toString())).createMinecraftSessionService(); + e.joinServer(session.getProfile(), session.getToken(), serverId); + return true; + } catch (AuthenticationException var4) { + this.setUploadError(var4.toString()); + var4.printStackTrace(); + return false; + } + } +} diff --git a/src/main/java/com/minelittlepony/minelp/hdskins/gui/NewGuiSkinsMineLP.java b/src/main/java/com/minelittlepony/minelp/hdskins/gui/NewGuiSkinsMineLP.java new file mode 100644 index 00000000..3420035e --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/hdskins/gui/NewGuiSkinsMineLP.java @@ -0,0 +1,48 @@ +package com.minelittlepony.minelp.hdskins.gui; + +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import com.minelittlepony.minelp.PonyManager; +import com.minelittlepony.minelp.util.MineLPLogger; +import com.mojang.authlib.GameProfile; +import com.voxelmodpack.hdskins.gui.GuiSkins; + +import net.minecraft.client.Minecraft; + +class dGuiSkinsMineLP extends GuiSkins { + + public dGuiSkinsMineLP() { + GameProfile profile = Minecraft.getMinecraft().getSession().getProfile(); + this.localPlayer = new EntityPonyModel(profile); + this.remotePlayer = new EntityPonyModel(profile); + } + + @Override + protected void setLocalSkin(File pendingSkin) { + super.setLocalSkin(pendingSkin); + MineLPLogger.debug("Invalidating old local skin, checking updated local skin"); + try { + PonyManager.getInstance().getPonyFromResourceRegistry(this.localPlayer.getSkinTexture()).checkSkin(ImageIO.read(pendingSkin)); + } catch (IOException e) { + MineLPLogger.error(e, "Unable to read file {}", pendingSkin.getName()); + } + + } + + @Override + protected void setRemoteSkin() { + super.setRemoteSkin(); + PonyManager.getInstance().getPonyFromResourceRegistry(this.remotePlayer.getSkinTexture()).invalidateSkinCheck(); + } + + @Override + public void onGuiClosed() { + super.onGuiClosed(); + PonyManager.getInstance().getPonyFromResourceRegistry(this.localPlayer.getSkinTexture()).invalidateSkinCheck(); + PonyManager.getInstance().getPonyFromResourceRegistry(this.remotePlayer.getSkinTexture()).invalidateSkinCheck(); + + } +} diff --git a/src/main/java/com/minelittlepony/minelp/hdskins/gui/RenderPonyModel.java b/src/main/java/com/minelittlepony/minelp/hdskins/gui/RenderPonyModel.java new file mode 100644 index 00000000..a3331e54 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/hdskins/gui/RenderPonyModel.java @@ -0,0 +1,37 @@ +package com.minelittlepony.minelp.hdskins.gui; + +import com.minelittlepony.minelp.Pony; +import com.minelittlepony.minelp.PonyManager; +import com.minelittlepony.minelp.model.PlayerModel; +import com.voxelmodpack.hdskins.gui.EntityPlayerModel; +import com.voxelmodpack.hdskins.gui.RenderPlayerModel; + +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.EntityLivingBase; + +public class RenderPonyModel extends RenderPlayerModel { + + public RenderPonyModel(RenderManager renderer) { + super(renderer); + } + + @Override + protected void renderModel(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4, float par5, float par6, float par7) { + this.bindEntityTexture(par1EntityLivingBase); + EntityPlayerModel playerModelEntity = (EntityPlayerModel) par1EntityLivingBase; + Pony thePony = PonyManager.getInstance().getPonyFromResourceRegistry(this.getEntityTexture(playerModelEntity)); + thePony.checkSkin(); + PlayerModel pm = thePony.getModel(true); + this.mainModel = pm.model; + pm.model.isFlying = thePony.isFlying = false; + pm.model.isPegasus = thePony.isPegasus(); + pm.model.isUnicorn = thePony.isUnicorn(); + pm.model.isMale = thePony.isMale(); + pm.model.size = thePony.size(); + pm.model.glowColor = thePony.glowColor(); + pm.model.wantTail = thePony.wantTail(); + pm.model.isVillager = false; + this.mainModel.render(par1EntityLivingBase, par2, par3, par4, par5, par6, par7); + } + +} diff --git a/src/main/java/com/minelittlepony/minelp/model/ModelArmor.java b/src/main/java/com/minelittlepony/minelp/model/ModelArmor.java new file mode 100644 index 00000000..4184aa10 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/ModelArmor.java @@ -0,0 +1,21 @@ +package com.minelittlepony.minelp.model; + +public abstract class ModelArmor { + public final String path; + public ModelPony base; + public ModelPony modelArmorChestplate; + public ModelPony modelArmor; + + public ModelArmor(String path) { + this.path = path; + } + + public float layer() { + return 1; + }; + + public int subimage(int slot) { + return slot == 2 ? 2 : 1; + } + +} diff --git a/src/main/java/com/minelittlepony/minelp/model/ModelHornGlow.java b/src/main/java/com/minelittlepony/minelp/model/ModelHornGlow.java new file mode 100644 index 00000000..8f84bd71 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/ModelHornGlow.java @@ -0,0 +1,106 @@ +package com.minelittlepony.minelp.model; + +import com.minelittlepony.minelp.renderer.HornGlowRenderer; +import net.minecraft.client.model.PositionTextureVertex; +import net.minecraft.client.model.TexturedQuad; +import net.minecraft.client.renderer.Tessellator; + +public class ModelHornGlow { + private PositionTextureVertex[] vertexPositions; + private TexturedQuad[] quadList; + public final float posX1; + public final float posY1; + public final float posZ1; + public final float posX2; + public final float posY2; + public final float posZ2; + public String field_78247_g; + + @SuppressWarnings("unused") + public ModelHornGlow(HornGlowRenderer par1ModelRenderer, int par2, int par3, float par4, float par5, float par6, + int par7, int par8, int par9, float par10) { + this.posX1 = par4; + this.posY1 = par5; + this.posZ1 = par6; + this.posX2 = par4 + par7; + this.posY2 = par5 + par8; + this.posZ2 = par6 + par9; + this.vertexPositions = new PositionTextureVertex[8]; + this.quadList = new TexturedQuad[6]; + float var11 = par4 + par7; + float var12 = par5 + par8; + float var13 = par6 + par9; + float halfpar4 = par4 + par7 * 0.05F; + float halfpar6 = par6 + par9 * 0.05F; + float halfvar11 = par4 + par7 * 0.95F; + float halfvar13 = par6 + par9 * 0.95F; + par4 -= par10; + par5 -= par10; + par6 -= par10; + var11 += par10; + var12 += par10; + var13 += par10; + float xcentre = (par4 + var11) / 2.0F; + float zcentre = (par6 + var13) / 2.0F; + if (par1ModelRenderer.mirror) { + float var26 = var11; + var11 = par4; + par4 = var26; + } + + PositionTextureVertex var32 = new PositionTextureVertex(halfpar4, par5, halfpar6, 0.0F, 0.0F); + PositionTextureVertex var15 = new PositionTextureVertex(halfvar11, par5, halfpar6, 0.0F, 8.0F); + PositionTextureVertex var16 = new PositionTextureVertex(var11, var12, par6, 8.0F, 8.0F); + PositionTextureVertex var17 = new PositionTextureVertex(par4, var12, par6, 8.0F, 0.0F); + PositionTextureVertex var18 = new PositionTextureVertex(halfpar4, par5, halfvar13, 0.0F, 0.0F); + PositionTextureVertex var19 = new PositionTextureVertex(halfvar11, par5, halfvar13, 0.0F, 8.0F); + PositionTextureVertex var20 = new PositionTextureVertex(var11, var12, var13, 8.0F, 8.0F); + PositionTextureVertex var21 = new PositionTextureVertex(par4, var12, var13, 8.0F, 0.0F); + this.vertexPositions[0] = var32; + this.vertexPositions[1] = var15; + this.vertexPositions[2] = var16; + this.vertexPositions[3] = var17; + this.vertexPositions[4] = var18; + this.vertexPositions[5] = var19; + this.vertexPositions[6] = var20; + this.vertexPositions[7] = var21; + this.quadList[0] = new TexturedQuad(new PositionTextureVertex[] { var19, var15, var16, var20 }, + par2 + par9 + par7, par3 + par9, par2 + par9 + par7 + par9, par3 + par9 + par8, + par1ModelRenderer.textureWidth, par1ModelRenderer.textureHeight); + this.quadList[1] = new TexturedQuad(new PositionTextureVertex[] { var32, var18, var21, var17 }, par2, + par3 + par9, par2 + par9, par3 + par9 + par8, par1ModelRenderer.textureWidth, + par1ModelRenderer.textureHeight); + this.quadList[2] = new TexturedQuad(new PositionTextureVertex[] { var19, var18, var32, var15 }, par2 + par9, + par3, par2 + par9 + par7, par3 + par9, par1ModelRenderer.textureWidth, par1ModelRenderer.textureHeight); + this.quadList[3] = new TexturedQuad(new PositionTextureVertex[] { var16, var17, var21, var20 }, + par2 + par9 + par7, par3 + par9, par2 + par9 + par7 + par7, par3, par1ModelRenderer.textureWidth, + par1ModelRenderer.textureHeight); + this.quadList[4] = new TexturedQuad(new PositionTextureVertex[] { var15, var32, var17, var16 }, par2 + par9, + par3 + par9, par2 + par9 + par7, par3 + par9 + par8, par1ModelRenderer.textureWidth, + par1ModelRenderer.textureHeight); + this.quadList[5] = new TexturedQuad(new PositionTextureVertex[] { var18, var19, var20, var21 }, + par2 + par9 + par7 + par9, par3 + par9, par2 + par9 + par7 + par9 + par7, par3 + par9 + par8, + par1ModelRenderer.textureWidth, par1ModelRenderer.textureHeight); + if (par1ModelRenderer.mirror) { + TexturedQuad[] var22 = this.quadList; + + for (TexturedQuad var25 : var22) { + var25.flipFace(); + } + } + + } + + public void render(Tessellator par1Tessellator, float par2) { + TexturedQuad[] var3 = this.quadList; + for (TexturedQuad var6 : var3) { + var6.draw(par1Tessellator.getWorldRenderer(), par2); + } + + } + + public ModelHornGlow func_78244_a(String par1Str) { + this.field_78247_g = par1Str; + return this; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/model/ModelPony.java b/src/main/java/com/minelittlepony/minelp/model/ModelPony.java new file mode 100644 index 00000000..46c2e71f --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/ModelPony.java @@ -0,0 +1,219 @@ +package com.minelittlepony.minelp.model; + +import static net.minecraft.client.renderer.GlStateManager.*; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL14; + +import com.minelittlepony.minelp.PonyManager; +import com.minelittlepony.minelp.renderer.AniParams; + +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.model.ModelPlayer; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EnumPlayerModelParts; +import net.minecraft.init.Items; +import net.minecraft.item.EnumAction; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; + +public abstract class ModelPony extends ModelPlayer { + public String texture; + protected float strech = 0.0F; + protected float scale = 0.0625F; + public boolean issneak = false; + public boolean isArmour = false; + public int glowColor = -12303190; + public final float pi = 3.141593F; + public boolean isPegasus; + public boolean isUnicorn; + public boolean isMale; + public int wantTail; + public int size; + public boolean isVillager; + public int villagerProfession; + public boolean isFlying; + public boolean isGlow; + public boolean isSleeping; + public int heldItemLeft; + public int heldItemRight; + public boolean aimedBow; + + public ModelPony(String texture) { + super(0, false); + this.texture = texture; + } + + public void setStrech(float strech) { + this.strech = strech; + } + + public final void init() { + init(0); + } + + public final void init(float var1) { + init(var1, 0); + } + + public abstract void init(float var1, float var2); + + public void animate(AniParams var1) {}; + + public void render(AniParams var1) {}; + + @Override + public void render(Entity player, float Move, float Moveswing, float Loop, float Right, float Down, float Scale) { + PonyManager.getInstance(); + if (player instanceof AbstractClientPlayer) { + setModelVisibilities((AbstractClientPlayer) player); + } + if (!doCancelRender()) { + AniParams ani = new AniParams(Move, Moveswing, Loop, Right, Down); + this.animate(ani); + this.render(ani); + } else { + super.render(player, Move, Moveswing, Loop, Right, Down, Scale); + } + } + + private void setModelVisibilities(AbstractClientPlayer clientPlayer) { + ModelPlayer modelplayer = this; + + if (clientPlayer.isSpectator()) { + modelplayer.setInvisible(false); + modelplayer.bipedHead.showModel = true; + modelplayer.bipedHeadwear.showModel = true; + } else { + ItemStack itemstack = clientPlayer.inventory.getCurrentItem(); + modelplayer.setInvisible(true); + modelplayer.bipedHeadwear.showModel = clientPlayer.isWearing(EnumPlayerModelParts.HAT); + modelplayer.bipedBodyWear.showModel = clientPlayer.isWearing(EnumPlayerModelParts.JACKET); + modelplayer.bipedLeftLegwear.showModel = clientPlayer.isWearing(EnumPlayerModelParts.LEFT_PANTS_LEG); + modelplayer.bipedRightLegwear.showModel = clientPlayer.isWearing(EnumPlayerModelParts.RIGHT_PANTS_LEG); + modelplayer.bipedLeftArmwear.showModel = clientPlayer.isWearing(EnumPlayerModelParts.LEFT_SLEEVE); + modelplayer.bipedRightArmwear.showModel = clientPlayer.isWearing(EnumPlayerModelParts.RIGHT_SLEEVE); + modelplayer.heldItemLeft = 0; + modelplayer.aimedBow = false; + modelplayer.isSneak = clientPlayer.isSneaking(); + + if (itemstack == null) { + modelplayer.heldItemRight = 0; + } else { + modelplayer.heldItemRight = 1; + + if (clientPlayer.getItemInUseCount() > 0) { + EnumAction enumaction = itemstack.getItemUseAction(); + + if (enumaction == EnumAction.BLOCK) { + modelplayer.heldItemRight = 3; + } else if (enumaction == EnumAction.BOW) { + modelplayer.aimedBow = true; + } + } + } + } + } + + public void renderDrop(RenderManager rendermanager, ItemRenderer itemrenderer, EntityLivingBase entity) {} + + protected void renderDrop(ItemRenderer itemrenderer, EntityLivingBase entity, ModelRenderer box, + float scalefactor, float posx, float posy, float posz) { + ItemStack drop = entity.getHeldItem(); + if (drop != null) { + pushMatrix(); + if (box != null) { + box.postRender(scalefactor * 0.0625F); + } + + translate(posx, posy, posz); + EnumAction playerAction = null; + if (entity instanceof EntityPlayer) { + EntityPlayer is3D = (EntityPlayer) entity; + if (is3D.fishEntity != null) { + drop = new ItemStack(Items.stick); + } + + if (is3D.getItemInUseCount() > 0) { + playerAction = drop.getItemUseAction(); + } + } + + if (drop.getItem() == Items.bow) { + rotate(-20.0F, 0.0F, 1.0F, 0.0F); + rotate(45.0F, 0.0F, 1.0F, 0.0F); + } else if (drop.getItem().isFull3D()) { + if (drop.getItem().shouldRotateAroundWhenRendering()) { + rotate(180.0F, 0.0F, 0.0F, 1.0F); + translate(0.0F, -0.125F, 0.0F); + } + + if (playerAction == EnumAction.BLOCK && entity instanceof EntityPlayer + && ((EntityPlayer) entity).getItemInUseCount() > 0) { + translate(0.05F, 0.0F, -0.1F); + rotate(-50.0F, 0.0F, 1.0F, 0.0F); + rotate(-10.0F, 1.0F, 0.0F, 0.0F); + rotate(-60.0F, 0.0F, 0.0F, 1.0F); + } + } + + float g; + float b; + int var20; + + var20 = drop.getItem().getColorFromItemStack(drop, 0); + float var19 = (var20 >> 16 & 255) / 255.0F; + g = (var20 >> 8 & 255) / 255.0F; + b = (var20 & 255) / 255.0F; + color(var19, g, b, 1.0F); + itemrenderer.renderItem(entity, drop, TransformType.THIRD_PERSON); + + if (isUnicorn && glowColor != 0) { + this.renderItemGlow(itemrenderer, entity, drop); + } + + popMatrix(); + } + } + + public void renderItemGlow(ItemRenderer itemRenderer, EntityLivingBase entity, ItemStack drop) { + // FIXME doesn't blend + pushMatrix(); + GL11.glPushAttrib(24577); + GL11.glDisable(2896); + float red = (glowColor >> 16 & 255) / 255.0F; + float green = (glowColor >> 8 & 255) / 255.0F; + float blue = (glowColor & 255) / 255.0F; + float alpha = 0.2F; + enableBlend(); + GL11.glEnable(3042); + GL14.glBlendColor(red, green, blue, alpha); + blendFunc('\u8001', 1); + color(red, green, blue, alpha); + // translate(1.1F, 1.1F, 1.1F); + if (!(drop.getItem() instanceof ItemBlock) || !drop.getItem().isFull3D()) { + translate(0.02F, -0.06F, -0.02F); + } + // itemRenderer.renderItem(entity, drop, TransformType.THIRD_PERSON); + popAttrib(); + popMatrix(); + } + + public void renderEars(EntityLivingBase entity, float par2) {} + + public void renderCloak(EntityPlayer player, float par2) {} + + public void renderStaticCloak(EntityLiving player, float par2) {} + + protected boolean doCancelRender() { + return false; + } + +} diff --git a/src/main/java/com/minelittlepony/minelp/model/PMAPI.java b/src/main/java/com/minelittlepony/minelp/model/PMAPI.java new file mode 100644 index 00000000..5475e980 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/PMAPI.java @@ -0,0 +1,55 @@ +package com.minelittlepony.minelp.model; + +import java.lang.reflect.Field; + +import com.minelittlepony.minelp.model.pony.pm_Human; +import com.minelittlepony.minelp.model.pony.pm_newPonyAdv; +import com.minelittlepony.minelp.model.pony.pm_skeletonPony; +import com.minelittlepony.minelp.model.pony.pm_zombiePony; +import com.minelittlepony.minelp.model.pony.armor.pma_Human; +import com.minelittlepony.minelp.model.pony.armor.pma_newPony; +import com.minelittlepony.minelp.model.pony.armor.pma_skeletonPony; +import com.minelittlepony.minelp.model.pony.armor.pma_zombiePony; + +public final class PMAPI { + + public static PlayerModel newPonyAdv = new PlayerModel("newPonyAdv", new pm_newPonyAdv("/mob/char.png"), 0) + .setTextureHeight(32) + .setArmor(new pma_newPony("minelittlepony:textures/models/armor/")) + .setURL("http://skins.minecraft.net/MinecraftSkins/%NAME%.png") + .setScale(0.9375F); + public static PlayerModel newPonyAdv_64 = new PlayerModel("newPonyAdv", new pm_newPonyAdv("/mob/char.png"), 0) + .setArmor(new pma_newPony("minelittlepony:textures/models/armor/")) + .setURL("http://skins.minecraft.net/MinecraftSkins/%NAME%.png") + .setScale(0.9375F); + public static PlayerModel zombiePony = new PlayerModel("zombiePony", new pm_zombiePony("/mob/char.png"), 0) + .setTextureHeight(32) + .setArmor(new pma_zombiePony("minelittlepony:textures/models/armor/")) + .setURL("http://skins.minecraft.net/MinecraftSkins/%NAME%.png") + .setScale(0.9375F); + public static PlayerModel skeletonPony = new PlayerModel("skeletonPony", new pm_skeletonPony("/mob/char.png"), 0) + .setTextureHeight(32) + .setArmor(new pma_skeletonPony("minelittlepony:textures/models/armor/")) + .setURL("http://skins.minecraft.net/MinecraftSkins/%NAME%.png") + .setScale(0.9375F); + public static PlayerModel human = new PlayerModel("Human", new pm_Human("/mob/char.png"), 1) + .setTextureHeight(32) + .setArmor(new pma_Human("minecraft:textures/models/armor/")) + .setURL("http://skins.minecraft.net/MinecraftSkins/%NAME%.png") + .setScale(0.9375F); + public static PlayerModel human_64 = new PlayerModel("Human", new pm_Human("/mob/char.png"), 1) + .setArmor(new pma_Human("minecraft:textures/models/armor/")) + .setURL("http://skins.minecraft.net/MinecraftSkins/%NAME%.png") + .setScale(0.9375F); + + public static void init() { + for (Field field : PMAPI.class.getFields()) { + try { + PlayerModel model = (PlayerModel) field.get(null); + model.init(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/main/java/com/minelittlepony/minelp/model/PlayerModel.java b/src/main/java/com/minelittlepony/minelp/model/PlayerModel.java new file mode 100644 index 00000000..9b966f57 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/PlayerModel.java @@ -0,0 +1,80 @@ +package com.minelittlepony.minelp.model; + +import com.minelittlepony.minelp.model.ModelArmor; +import com.minelittlepony.minelp.model.ModelPony; +import java.text.DecimalFormat; + +public class PlayerModel { + public final int id; + public String name; + public String url; + public ModelPony model; + public ModelArmor armor; + public float width = 0.6F; + public float height = 1.8F; + public float shadowsize = 0.5F; + public float thirdpersondistance = 4.0F; + public float yoffset = 1.62F; + public float globalscale = 1.0F; + + public PlayerModel(String name, ModelPony model, int manual_id) { + this.name = name; + this.model = model; + this.id = manual_id; + } + + public PlayerModel setTextureHeight(int height) { + model.textureHeight = height; + return this; + } + + public PlayerModel setArmor(ModelArmor armor) { + this.armor = armor; + return this; + } + + public PlayerModel setURL(String url) { + this.url = url; + return this; + } + + public PlayerModel setShadow(float size) { + this.shadowsize = size; + return this; + } + + public PlayerModel setSize(float width, float height) { + this.width = width; + this.height = height; + return this; + } + + public PlayerModel setOffset(float offset) { + this.yoffset = offset; + return this; + } + + public PlayerModel setDistance(float distance) { + this.thirdpersondistance = distance; + return this; + } + + public PlayerModel setScale(float scale) { + this.globalscale = scale; + return this; + } + + public boolean hasArmor() { + return this.armor != null && this.armor.base != null && this.armor.path != null; + } + + public String getSize(DecimalFormat df) { + return df.format(this.width) + " * " + df.format(this.height) + " * " + df.format(this.width); + } + + public void init() { + model.init(); + armor.modelArmorChestplate.init(0.0F, 1.0F); + armor.modelArmor.init(0.0F, 0.5F); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/model/ScalableModelBox.java b/src/main/java/com/minelittlepony/minelp/model/ScalableModelBox.java new file mode 100644 index 00000000..a4dd90ae --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/ScalableModelBox.java @@ -0,0 +1,84 @@ +package com.minelittlepony.minelp.model; + +import com.minelittlepony.minelp.renderer.ScalableModelRenderer; +import net.minecraft.client.model.PositionTextureVertex; +import net.minecraft.client.model.TexturedQuad; +import net.minecraft.client.renderer.Tessellator; + +public class ScalableModelBox { + private PositionTextureVertex[] vertexPositions; + private TexturedQuad[] quadList; + public final float posX1; + public final float posY1; + public final float posZ1; + public final float posX2; + public final float posY2; + public final float posZ2; + public String field_78247_g; + + public ScalableModelBox(ScalableModelRenderer par1ModelRenderer, int par2, int par3, float par4, float par5, float par6, int par7, int par8, int par9, float par10) { + this.posX1 = par4; + this.posY1 = par5; + this.posZ1 = par6; + this.posX2 = par4 + par7; + this.posY2 = par5 + par8; + this.posZ2 = par6 + par9; + this.vertexPositions = new PositionTextureVertex[8]; + this.quadList = new TexturedQuad[6]; + float var11 = par4 + par7; + float var12 = par5 + par8; + float var13 = par6 + par9; + par4 -= par10; + par5 -= par10; + par6 -= par10; + var11 += par10; + var12 += par10; + var13 += par10; + if(par1ModelRenderer.mirror) { + float var23 = var11; + var11 = par4; + par4 = var23; + } + + PositionTextureVertex var231 = new PositionTextureVertex(par4, par5, par6, 0.0F, 0.0F); + PositionTextureVertex var15 = new PositionTextureVertex(var11, par5, par6, 0.0F, 8.0F); + PositionTextureVertex var16 = new PositionTextureVertex(var11, var12, par6, 8.0F, 8.0F); + PositionTextureVertex var17 = new PositionTextureVertex(par4, var12, par6, 8.0F, 0.0F); + PositionTextureVertex var18 = new PositionTextureVertex(par4, par5, var13, 0.0F, 0.0F); + PositionTextureVertex var19 = new PositionTextureVertex(var11, par5, var13, 0.0F, 8.0F); + PositionTextureVertex var20 = new PositionTextureVertex(var11, var12, var13, 8.0F, 8.0F); + PositionTextureVertex var21 = new PositionTextureVertex(par4, var12, var13, 8.0F, 0.0F); + this.vertexPositions[0] = var231; + this.vertexPositions[1] = var15; + this.vertexPositions[2] = var16; + this.vertexPositions[3] = var17; + this.vertexPositions[4] = var18; + this.vertexPositions[5] = var19; + this.vertexPositions[6] = var20; + this.vertexPositions[7] = var21; + this.quadList[0] = new TexturedQuad(new PositionTextureVertex[]{var19, var15, var16, var20}, par2 + par9 + par7, par3 + par9, par2 + par9 + par7 + par9, par3 + par9 + par8, par1ModelRenderer.textureWidth, par1ModelRenderer.textureHeight); + this.quadList[1] = new TexturedQuad(new PositionTextureVertex[]{var231, var18, var21, var17}, par2, par3 + par9, par2 + par9, par3 + par9 + par8, par1ModelRenderer.textureWidth, par1ModelRenderer.textureHeight); + this.quadList[2] = new TexturedQuad(new PositionTextureVertex[]{var19, var18, var231, var15}, par2 + par9, par3, par2 + par9 + par7, par3 + par9, par1ModelRenderer.textureWidth, par1ModelRenderer.textureHeight); + this.quadList[3] = new TexturedQuad(new PositionTextureVertex[]{var16, var17, var21, var20}, par2 + par9 + par7, par3 + par9, par2 + par9 + par7 + par7, par3, par1ModelRenderer.textureWidth, par1ModelRenderer.textureHeight); + this.quadList[4] = new TexturedQuad(new PositionTextureVertex[]{var15, var231, var17, var16}, par2 + par9, par3 + par9, par2 + par9 + par7, par3 + par9 + par8, par1ModelRenderer.textureWidth, par1ModelRenderer.textureHeight); + this.quadList[5] = new TexturedQuad(new PositionTextureVertex[]{var18, var19, var20, var21}, par2 + par9 + par7 + par9, par3 + par9, par2 + par9 + par7 + par9 + par7, par3 + par9 + par8, par1ModelRenderer.textureWidth, par1ModelRenderer.textureHeight); + if(par1ModelRenderer.mirror) { + for (TexturedQuad element : this.quadList) { + element.flipFace(); + } + } + + } + + public void render(Tessellator par1Tessellator, float par2) { + for (TexturedQuad element : this.quadList) { + element.draw(par1Tessellator.getWorldRenderer(), par2); + } + + } + + public ScalableModelBox func_78244_a(String par1Str) { + this.field_78247_g = par1Str; + return this; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/model/pony/armor/pm_newPonyArmor.java b/src/main/java/com/minelittlepony/minelp/model/pony/armor/pm_newPonyArmor.java new file mode 100644 index 00000000..6c5c8a8d --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/pony/armor/pm_newPonyArmor.java @@ -0,0 +1,311 @@ +package com.minelittlepony.minelp.model.pony.armor; + +import com.minelittlepony.minelp.model.pony.pm_newPonyAdv; +import com.minelittlepony.minelp.renderer.AniParams; + +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.MathHelper; + +public class pm_newPonyArmor extends pm_newPonyAdv { + public ModelRenderer Bodypiece; + public ModelRenderer extBody; + public ModelRenderer[] extHead; + public ModelRenderer[] extLegs; + + public pm_newPonyArmor(String texture) { + super(texture); + this.isArmour = true; + this.textureHeight = 32; + } + + @Override + public void animate(AniParams aniparams) { + this.checkRainboom(aniparams.swing); + this.rotateHead(aniparams.horz, aniparams.vert); + float bodySwingRotation = 0.0F; + if (this.swingProgress > -9990.0F && !this.isUnicorn) { + bodySwingRotation = MathHelper.sin(MathHelper.sqrt_float(this.swingProgress) * 3.1415927F * 2.0F) * 0.2F; + } + + this.bipedBody.rotateAngleY = bodySwingRotation * 0.2F; + this.Bodypiece.rotateAngleY = bodySwingRotation * 0.2F; + this.extBody.rotateAngleY = bodySwingRotation * 0.2F; + this.setLegs(aniparams.move, aniparams.swing, aniparams.tick); + this.holdItem(); + this.swingItem(this.swingProgress); + if (this.issneak && !this.isFlying) { + this.adjustBody(BODY_ROTATE_ANGLE_X_SNEAK, BODY_RP_Y_SNEAK, BODY_RP_Z_SNEAK); + this.sneakLegs(); + this.setHead(0.0F, 6.0F, -2.0F); + } else { + this.adjustBody(BODY_ROTATE_ANGLE_X_NOTSNEAK, BODY_RP_Y_NOTSNEAK, + BODY_RP_Z_NOTSNEAK); + this.bipedRightLeg.rotationPointY = FRONT_LEG_RP_Y_NOTSNEAK; + this.bipedLeftLeg.rotationPointY = FRONT_LEG_RP_Y_NOTSNEAK; + this.extLegs[0].rotationPointY = FRONT_LEG_RP_Y_NOTSNEAK; + this.extLegs[1].rotationPointY = FRONT_LEG_RP_Y_NOTSNEAK; + this.swingArms(aniparams.tick); + this.setHead(0.0F, 0.0F, 0.0F); + } + + if (this.isSleeping) { + this.ponySleep(); + } + + if (this.aimedBow) { + this.aimBow(aniparams.tick); + } + + this.fixSpecialRotationPoints(aniparams.move); + } + + @Override + protected void setHead(float posX, float posY, float posZ) { + this.setRotationPoint(this.bipedHead, posX, posY, posZ); + this.setRotationPoint(this.bipedHeadwear, posX, posY, posZ); + this.setRotationPoint(this.extHead[0], posX, posY, posZ); + this.setRotationPoint(this.extHead[1], posX, posY, posZ); + } + + @Override + protected void rotateHead(float horz, float vert) { + float headRotateAngleY; + float headRotateAngleX; + if (this.isSleeping) { + headRotateAngleY = 1.4F; + headRotateAngleX = 0.1F; + } else { + headRotateAngleY = horz / 57.29578F; + headRotateAngleX = vert / 57.29578F; + } + + if (headRotateAngleX > 0.5F) { + headRotateAngleX = 0.5F; + } + + if (headRotateAngleX < -0.5F) { + headRotateAngleX = -0.5F; + } + + this.bipedHead.rotateAngleY = headRotateAngleY; + this.bipedHead.rotateAngleX = headRotateAngleX; + this.extHead[0].rotateAngleY = headRotateAngleY; + this.extHead[0].rotateAngleX = headRotateAngleX; + this.extHead[1].rotateAngleY = headRotateAngleY; + this.extHead[1].rotateAngleX = headRotateAngleX; + this.bipedHeadwear.rotateAngleY = headRotateAngleY; + this.bipedHeadwear.rotateAngleX = headRotateAngleX; + } + + @Override + protected void adjustBody(float rotateAngleX, float rotationPointY, float rotationPointZ) { + this.bipedBody.rotateAngleX = rotateAngleX; + this.bipedBody.rotationPointY = rotationPointY; + this.bipedBody.rotationPointZ = rotationPointZ; + this.Bodypiece.rotateAngleX = rotateAngleX; + this.Bodypiece.rotationPointY = rotationPointY; + this.Bodypiece.rotationPointZ = rotationPointZ; + this.extBody.rotateAngleX = rotateAngleX; + this.extBody.rotationPointY = rotationPointY; + this.extBody.rotationPointZ = rotationPointZ; + } + + protected void ridingPony() { + this.setHead(this.bipedHead.rotationPointX + 0.0F, this.bipedHead.rotationPointY + RIDING_SHIFT_Y, + this.bipedHead.rotationPointZ + RIDING_SHIFT_Z); + this.shiftRotationPoint(this.bipedBody, 0.0F, RIDING_SHIFT_Y, RIDING_SHIFT_Z); + this.shiftRotationPoint(this.Bodypiece, 0.0F, RIDING_SHIFT_Y, RIDING_SHIFT_Z); + this.shiftRotationPoint(this.extBody, 0.0F, RIDING_SHIFT_Y, RIDING_SHIFT_Z); + this.shiftRotationPoint(this.bipedLeftArm, 0.0F, RIDING_SHIFT_Y, RIDING_SHIFT_Z); + this.shiftRotationPoint(this.bipedRightArm, 0.0F, RIDING_SHIFT_Y, RIDING_SHIFT_Z); + this.shiftRotationPoint(this.bipedLeftLeg, 0.0F, RIDING_SHIFT_Y, RIDING_SHIFT_Z); + this.shiftRotationPoint(this.bipedRightLeg, 0.0F, RIDING_SHIFT_Y, RIDING_SHIFT_Z); + this.shiftRotationPoint(this.extLegs[0], 0.0F, RIDING_SHIFT_Y, RIDING_SHIFT_Z); + this.shiftRotationPoint(this.extLegs[1], 0.0F, RIDING_SHIFT_Y, RIDING_SHIFT_Z); + } + + @Override + protected void renderHead() { + this.bipedHead.render(this.scale); + this.extHead[0].render(this.scale); + this.extHead[1].render(this.scale); + this.bipedHeadwear.render(this.scale); + } + + @Override + protected void renderNeck() {} + + @Override + protected void renderBody() { + this.bipedBody.render(this.scale); + this.Bodypiece.render(this.scale); + this.extBody.render(this.scale); + } + + @Override + protected void renderTail() {} + + @Override + protected void renderLegs() { + this.bipedLeftArm.render(this.scale); + this.bipedRightArm.render(this.scale); + this.bipedLeftLeg.render(this.scale); + this.bipedRightLeg.render(this.scale); + this.extLegs[0].render(this.scale); + this.extLegs[1].render(this.scale); + } + + @Override + protected void initTextures() { + this.extHead = new ModelRenderer[2]; + this.extLegs = new ModelRenderer[2]; + this.initHeadTextures(); + this.initBodyTextures(); + this.initLegTextures(); + } + + @Override + protected void initHeadTextures() { + this.bipedHead = new ModelRenderer(this, 0, 0); + this.bipedHeadwear = new ModelRenderer(this, 32, 0); + this.extHead[0] = new ModelRenderer(this, 0, 0); + this.extHead[1] = new ModelRenderer(this, 0, 4); + } + + @Override + protected void initBodyTextures() { + this.bipedBody = new ModelRenderer(this, 16, 16); + this.Bodypiece = new ModelRenderer(this, 0, 0); + this.extBody = new ModelRenderer(this, 16, 8); + } + + @Override + protected void initLegTextures() { + this.bipedRightArm = new ModelRenderer(this, 0, 16); + this.bipedLeftArm = new ModelRenderer(this, 0, 16); + this.bipedLeftArm.mirror = true; + this.bipedRightLeg = new ModelRenderer(this, 0, 16); + this.bipedLeftLeg = new ModelRenderer(this, 0, 16); + this.bipedLeftLeg.mirror = true; + this.SteveArm = new ModelRenderer(this, 0, 16); + this.unicornarm = new ModelRenderer(this, 0, 16); + this.extLegs[0] = new ModelRenderer(this, 48, 8); + this.extLegs[1] = new ModelRenderer(this, 48, 8); + this.extLegs[1].mirror = true; + } + + @Override + protected void initPositions(float yOffset, float stretch) { + this.initHeadPositions(yOffset, stretch); + this.initBodyPositions(yOffset, stretch); + this.initLegPositions(yOffset, stretch); + } + + @Override + protected void initHeadPositions(float yOffset, float stretch) { + this.bipedHead.addBox(-4.0F + HEAD_CENTRE_X, -4.0F + HEAD_CENTRE_Y, + -4.0F + HEAD_CENTRE_Z, 8, 8, 8, + stretch * 1.1F); + this.bipedHead.setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.extHead[0].addBox(-4.0F + HEAD_CENTRE_X, -6.0F + HEAD_CENTRE_Y, + 1.0F + HEAD_CENTRE_Z, 2, 2, + 2, stretch * 0.5F); + this.extHead[0].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, + HEAD_RP_Z); + this.extHead[1].addBox(2.0F + HEAD_CENTRE_X, -6.0F + HEAD_CENTRE_Y, + 1.0F + HEAD_CENTRE_Z, 2, 2, + 2, stretch * 0.5F); + this.extHead[1].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, + HEAD_RP_Z); + this.bipedHeadwear.addBox(-4.0F + HEAD_CENTRE_X, -4.0F + HEAD_CENTRE_Y, + -4.0F + HEAD_CENTRE_Z, 8, 8, 8, + stretch * 1.1F + 0.5F); + this.bipedHeadwear.setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, + HEAD_RP_Z); + } + + @Override + protected void initBodyPositions(float yOffset, float stretch) { + this.bipedBody.addBox(-4.0F, 4.0F, -2.0F, 8, 8, 4, stretch); + this.bipedBody.setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.Bodypiece.addBox(-4.0F, 4.0F, 6.0F, 8, 8, 8, stretch); + this.Bodypiece.setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, + HEAD_RP_Z); + this.extBody.addBox(-4.0F, 4.0F, -2.0F, 8, 8, 16, stretch); + this.extBody.setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, + HEAD_RP_Z); + } + + @Override + protected void initLegPositions(float yOffset, float stretch) { + super.initLegPositions(yOffset, stretch); + this.extLegs[0].addBox(-2.0F + THIRDP_ARM_CENTRE_X, -6.0F + THIRDP_ARM_CENTRE_Y, + -2.0F + THIRDP_ARM_CENTRE_Z, 4, 12, 4, stretch); + this.extLegs[0].setRotationPoint(-3.0F, 0.0F + yOffset, 0.0F); + this.extLegs[1].addBox(-2.0F + THIRDP_ARM_CENTRE_X, -6.0F + THIRDP_ARM_CENTRE_Y, + -2.0F + THIRDP_ARM_CENTRE_Z, 4, 12, 4, stretch); + this.extLegs[1].setRotationPoint(3.0F, 0.0F + yOffset, 0.0F); + } + + protected void syncLegs() { + this.extLegs[0].rotateAngleX = this.bipedRightLeg.rotateAngleX; + this.extLegs[0].rotateAngleY = this.bipedRightLeg.rotateAngleY; + this.extLegs[0].rotateAngleZ = this.bipedRightLeg.rotateAngleZ; + this.extLegs[0].rotationPointX = this.bipedRightLeg.rotationPointX; + this.extLegs[0].rotationPointY = this.bipedRightLeg.rotationPointY; + this.extLegs[0].rotationPointZ = this.bipedRightLeg.rotationPointZ; + this.extLegs[1].rotateAngleX = this.bipedLeftLeg.rotateAngleX; + this.extLegs[1].rotateAngleY = this.bipedLeftLeg.rotateAngleY; + this.extLegs[1].rotateAngleZ = this.bipedLeftLeg.rotateAngleZ; + this.extLegs[1].rotationPointX = this.bipedLeftLeg.rotationPointX; + this.extLegs[1].rotationPointY = this.bipedLeftLeg.rotationPointY; + this.extLegs[1].rotationPointZ = this.bipedLeftLeg.rotationPointZ; + } + + @Override + protected void rotateLegs(float move, float swing, float tick) { + super.rotateLegs(move, swing, tick); + this.syncLegs(); + } + + @Override + protected void adjustLegs() { + super.adjustLegs(); + this.syncLegs(); + } + + @Override + protected void sneakLegs() { + super.sneakLegs(); + this.syncLegs(); + } + + @Override + protected void ponySleep() { + super.ponySleep(); + this.syncLegs(); + } + + @Override + public void renderDrop(RenderManager rendermanager, ItemRenderer itemrenderer, EntityLivingBase entity) { + this.renderDrop(itemrenderer, entity, this.bipedRightArm, 1.0F, -0.0625F, 0.8375F, 0.0625F); + } + + @Override + public void setInvisible(boolean invisible) { + super.setInvisible(invisible); + this.bipedLeftArm.showModel = invisible; + this.bipedRightArm.showModel = invisible; + this.Bodypiece.showModel = invisible; + extBody.showModel = invisible; + for (ModelRenderer m : extHead) { + m.showModel = invisible; + } + for (ModelRenderer m : extLegs) { + m.showModel = invisible; + } + } +} diff --git a/src/main/java/com/minelittlepony/minelp/model/pony/armor/pm_skeletonPonyArmor.java b/src/main/java/com/minelittlepony/minelp/model/pony/armor/pm_skeletonPonyArmor.java new file mode 100644 index 00000000..5c741d34 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/pony/armor/pm_skeletonPonyArmor.java @@ -0,0 +1,100 @@ +package com.minelittlepony.minelp.model.pony.armor; + +import com.minelittlepony.minelp.model.pony.armor.pm_newPonyArmor; + +import net.minecraft.util.MathHelper; + +public class pm_skeletonPonyArmor extends pm_newPonyArmor { + public pm_skeletonPonyArmor(String texture) { + super(texture); + } + + @Override + protected void rotateLegs(float move, float swing, float tick) { + float rightArmRotateAngleX; + float leftArmRotateAngleX; + float rightLegRotateAngleX; + float leftLegRotateAngleX; + float var8; + float var9; + if (this.isFlying && this.isPegasus) { + if (this.rainboom) { + rightArmRotateAngleX = ROTATE_270; + leftArmRotateAngleX = ROTATE_270; + rightLegRotateAngleX = ROTATE_90; + leftLegRotateAngleX = ROTATE_90; + } else { + rightArmRotateAngleX = MathHelper.sin(0.0F - swing * 0.5F); + leftArmRotateAngleX = MathHelper.sin(0.0F - swing * 0.5F); + rightLegRotateAngleX = MathHelper.sin(swing * 0.5F); + leftLegRotateAngleX = MathHelper.sin(swing * 0.5F); + } + + this.bipedRightArm.rotateAngleY = 0.2F; + this.SteveArm.rotateAngleY = 0.2F; + this.bipedLeftArm.rotateAngleY = -0.2F; + this.bipedRightLeg.rotateAngleY = -0.2F; + this.bipedLeftLeg.rotateAngleY = 0.2F; + } else { + var8 = (float) Math.pow(swing, 16.0D); + this.getClass(); + var9 = 3.1415927F * var8 * 0.5F; + this.getClass(); + float laQuad = 3.1415927F * var8; + this.getClass(); + float rlQuad = 3.1415927F * var8 * 0.2F; + this.getClass(); + float llQuad = 3.1415927F * var8 * -0.4F; + rightArmRotateAngleX = MathHelper.cos(move * 0.6662F + 3.1415927F + var9) * 0.6F * swing; + leftArmRotateAngleX = MathHelper.cos(move * 0.6662F + laQuad) * 0.6F * swing; + rightLegRotateAngleX = MathHelper.cos(move * 0.6662F + rlQuad) * 0.6F * swing; + leftLegRotateAngleX = MathHelper.cos(move * 0.6662F + 3.1415927F + llQuad) * 0.6F * swing; + this.bipedRightArm.rotateAngleY = 0.0F; + this.SteveArm.rotateAngleY = 0.0F; + this.unicornarm.rotateAngleY = 0.0F; + this.bipedLeftArm.rotateAngleY = 0.0F; + this.bipedRightLeg.rotateAngleY = 0.0F; + this.bipedLeftLeg.rotateAngleY = 0.0F; + } + + this.bipedRightArm.rotateAngleX = rightArmRotateAngleX; + this.SteveArm.rotateAngleX = rightArmRotateAngleX; + this.unicornarm.rotateAngleX = 0.0F; + this.bipedLeftArm.rotateAngleX = leftArmRotateAngleX; + this.bipedRightLeg.rotateAngleX = rightLegRotateAngleX; + this.bipedLeftLeg.rotateAngleX = leftLegRotateAngleX; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.SteveArm.rotateAngleZ = 0.0F; + this.unicornarm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + if (this.heldItemRight != 0) { + var8 = MathHelper.sin(this.swingProgress * 3.1415927F); + var9 = MathHelper.sin((1.0F - (1.0F - this.swingProgress) * (1.0F - this.swingProgress)) * 3.1415927F); + if (this.glowColor == 0) { + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedRightArm.rotateAngleY = 0.1F - var8 * 0.6F; + this.bipedRightArm.rotateAngleX = -1.5707964F; + this.bipedRightArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.bipedRightArm.rotateAngleZ += MathHelper.cos(tick * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(tick * 0.067F) * 0.1F; + } else { + this.unicornarm.rotateAngleZ = 0.0F; + this.unicornarm.rotateAngleY = 0.1F - var8 * 0.6F; + this.unicornarm.rotateAngleX = -1.5707964F; + this.unicornarm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.unicornarm.rotateAngleZ += MathHelper.cos(tick * 0.09F) * 0.05F + 0.05F; + this.unicornarm.rotateAngleX += MathHelper.sin(tick * 0.067F) * 0.1F; + } + } + + this.syncLegs(); + } + + @Override + protected void fixSpecialRotationPoints(float move) { + if (this.heldItemRight != 0 && this.glowColor == 0) { + this.setRotationPoint(this.bipedRightArm, -1.5F, 9.5F, 4.0F); + } + + } +} diff --git a/src/main/java/com/minelittlepony/minelp/model/pony/armor/pm_zombiePonyArmor.java b/src/main/java/com/minelittlepony/minelp/model/pony/armor/pm_zombiePonyArmor.java new file mode 100644 index 00000000..f9fa2a34 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/pony/armor/pm_zombiePonyArmor.java @@ -0,0 +1,104 @@ +package com.minelittlepony.minelp.model.pony.armor; + +import com.minelittlepony.minelp.model.pony.armor.pm_newPonyArmor; + +import net.minecraft.util.MathHelper; + +public class pm_zombiePonyArmor extends pm_newPonyArmor { + public pm_zombiePonyArmor(String texture) { + super(texture); + } + + @Override + protected void rotateLegs(float move, float swing, float tick) { + float rightArmRotateAngleX; + float leftArmRotateAngleX; + float rightLegRotateAngleX; + float leftLegRotateAngleX; + float var8; + float var9; + if (this.isFlying && this.isPegasus) { + if (this.rainboom) { + rightArmRotateAngleX = ROTATE_270; + leftArmRotateAngleX = ROTATE_270; + rightLegRotateAngleX = ROTATE_90; + leftLegRotateAngleX = ROTATE_90; + } else { + rightArmRotateAngleX = MathHelper.sin(0.0F - swing * 0.5F); + leftArmRotateAngleX = MathHelper.sin(0.0F - swing * 0.5F); + rightLegRotateAngleX = MathHelper.sin(swing * 0.5F); + leftLegRotateAngleX = MathHelper.sin(swing * 0.5F); + } + + this.bipedRightArm.rotateAngleY = 0.2F; + this.SteveArm.rotateAngleY = 0.2F; + this.bipedLeftArm.rotateAngleY = -0.2F; + this.bipedRightLeg.rotateAngleY = -0.2F; + this.bipedLeftLeg.rotateAngleY = 0.2F; + } else { + var8 = (float) Math.pow(swing, 16.0D); + this.getClass(); + var9 = 3.1415927F * var8 * 0.5F; + this.getClass(); + float laQuad = 3.1415927F * var8; + this.getClass(); + float rlQuad = 3.1415927F * var8 * 0.2F; + this.getClass(); + float llQuad = 3.1415927F * var8 * -0.4F; + rightArmRotateAngleX = MathHelper.cos(move * 0.6662F + 3.1415927F + var9) * 0.45F * swing; + leftArmRotateAngleX = MathHelper.cos(move * 0.6662F + laQuad) * 0.45F * swing; + rightLegRotateAngleX = MathHelper.cos(move * 0.6662F + rlQuad) * 0.45F * swing; + leftLegRotateAngleX = MathHelper.cos(move * 0.6662F + 3.1415927F + llQuad) * 0.45F * swing; + this.bipedRightArm.rotateAngleY = 0.0F; + this.SteveArm.rotateAngleY = 0.0F; + this.unicornarm.rotateAngleY = 0.0F; + this.bipedLeftArm.rotateAngleY = 0.0F; + this.bipedRightLeg.rotateAngleY = 0.0F; + this.bipedLeftLeg.rotateAngleY = 0.0F; + } + + this.bipedRightArm.rotateAngleX = rightArmRotateAngleX; + this.SteveArm.rotateAngleX = rightArmRotateAngleX; + this.unicornarm.rotateAngleX = 0.0F; + this.bipedLeftArm.rotateAngleX = leftArmRotateAngleX; + this.bipedRightLeg.rotateAngleX = rightLegRotateAngleX; + this.bipedLeftLeg.rotateAngleX = leftLegRotateAngleX; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.SteveArm.rotateAngleZ = 0.0F; + this.unicornarm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + if (this.heldItemRight == 0) { + var8 = MathHelper.sin(this.swingProgress * 3.1415927F); + var9 = MathHelper.sin((1.0F - (1.0F - this.swingProgress) * (1.0F - this.swingProgress)) * 3.1415927F); + if (MathHelper.sin(move / 20.0F) < 0.0F) { + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedRightArm.rotateAngleY = 0.1F - var8 * 0.6F; + this.bipedRightArm.rotateAngleX = -1.5707964F; + this.bipedRightArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.bipedRightArm.rotateAngleZ += MathHelper.cos(tick * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(tick * 0.067F) * 0.1F; + } else { + this.bipedLeftArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleY = -(0.1F - var8 * 0.6F); + this.bipedLeftArm.rotateAngleX = -1.5707964F; + this.bipedLeftArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.bipedLeftArm.rotateAngleZ += MathHelper.cos(tick * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleX += MathHelper.sin(tick * 0.067F) * 0.1F; + } + } + + this.syncLegs(); + } + + @Override + protected void fixSpecialRotationPoints(float move) { + if (this.heldItemRight == 0) { + if (MathHelper.sin(move / 20.0F) < 0.0F) { + this.shiftRotationPoint(this.bipedRightArm, 0.5F, 1.5F, 3.0F); + } else { + this.shiftRotationPoint(this.bipedLeftArm, -0.5F, 1.5F, 3.0F); + } + } + + } +} diff --git a/src/main/java/com/minelittlepony/minelp/model/pony/armor/pma_Human.java b/src/main/java/com/minelittlepony/minelp/model/pony/armor/pma_Human.java new file mode 100644 index 00000000..2b0afcf5 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/pony/armor/pma_Human.java @@ -0,0 +1,14 @@ +package com.minelittlepony.minelp.model.pony.armor; + +import com.minelittlepony.minelp.model.ModelArmor; +import com.minelittlepony.minelp.model.pony.pm_Human; + +public class pma_Human extends ModelArmor { + + public pma_Human(String path) { + super(path); + this.modelArmorChestplate = new pm_Human(path); + this.modelArmor = new pm_Human(path); + } + +} diff --git a/src/main/java/com/minelittlepony/minelp/model/pony/armor/pma_newPony.java b/src/main/java/com/minelittlepony/minelp/model/pony/armor/pma_newPony.java new file mode 100644 index 00000000..56a4aa67 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/pony/armor/pma_newPony.java @@ -0,0 +1,11 @@ +package com.minelittlepony.minelp.model.pony.armor; + +import com.minelittlepony.minelp.model.ModelArmor; + +public class pma_newPony extends ModelArmor { + public pma_newPony(String path) { + super(path); + this.modelArmorChestplate = new pm_newPonyArmor(path); + this.modelArmor = new pm_newPonyArmor(path); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/model/pony/armor/pma_skeletonPony.java b/src/main/java/com/minelittlepony/minelp/model/pony/armor/pma_skeletonPony.java new file mode 100644 index 00000000..ffd7cc4b --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/pony/armor/pma_skeletonPony.java @@ -0,0 +1,12 @@ +package com.minelittlepony.minelp.model.pony.armor; + +import com.minelittlepony.minelp.model.ModelArmor; + +public class pma_skeletonPony extends ModelArmor { + + public pma_skeletonPony(String path) { + super(path); + this.modelArmorChestplate = new pm_skeletonPonyArmor(path); + this.modelArmor = new pm_skeletonPonyArmor(path); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/model/pony/armor/pma_zombiePony.java b/src/main/java/com/minelittlepony/minelp/model/pony/armor/pma_zombiePony.java new file mode 100644 index 00000000..45ddad5d --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/pony/armor/pma_zombiePony.java @@ -0,0 +1,12 @@ +package com.minelittlepony.minelp.model.pony.armor; + +import com.minelittlepony.minelp.model.ModelArmor; + +public class pma_zombiePony extends ModelArmor { + + public pma_zombiePony(String path) { + super(path); + this.modelArmorChestplate = new pm_zombiePonyArmor(path); + this.modelArmor = new pm_zombiePonyArmor(path); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/model/pony/pm_Human.java b/src/main/java/com/minelittlepony/minelp/model/pony/pm_Human.java new file mode 100644 index 00000000..d0a38700 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/pony/pm_Human.java @@ -0,0 +1,152 @@ +package com.minelittlepony.minelp.model.pony; + +import org.lwjgl.opengl.GL11; + +import com.minelittlepony.minelp.model.ModelPony; +import com.minelittlepony.minelp.renderer.AniParams; + +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.MathHelper; + +public class pm_Human extends ModelPony { + + public ModelRenderer bipedEars; + public ModelRenderer cloak; + + public pm_Human(String texture) { + super(texture); + } + + @Override + public void init(float yoffset, float stretch) { + this.cloak = new ModelRenderer(this, 0, 0); + this.cloak.addBox(-5.0F, 0.0F, -1.0F, 10, 16, 1, stretch); + this.bipedEars = new ModelRenderer(this, 24, 0); + this.bipedEars.addBox(-3.0F, -6.0F, -1.0F, 6, 6, 1, stretch); + this.bipedHead = new ModelRenderer(this, 0, 0); + this.bipedHead.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, stretch); + this.bipedHead.setRotationPoint(0.0F, 0.0F + yoffset, 0.0F); + this.bipedHeadwear = new ModelRenderer(this, 32, 0); + this.bipedHeadwear.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, stretch + 0.5F); + this.bipedHeadwear.setRotationPoint(0.0F, 0.0F + yoffset, 0.0F); + this.bipedBody = new ModelRenderer(this, 16, 16); + this.bipedBody.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, stretch); + this.bipedBody.setRotationPoint(0.0F, 0.0F + yoffset, 0.0F); + this.bipedRightArm = new ModelRenderer(this, 40, 16); + this.bipedRightArm.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, stretch); + this.bipedRightArm.setRotationPoint(-5.0F, 2.0F + yoffset, 0.0F); + this.bipedLeftArm = new ModelRenderer(this, 40, 16); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, stretch); + this.bipedLeftArm.setRotationPoint(5.0F, 2.0F + yoffset, 0.0F); + this.bipedRightLeg = new ModelRenderer(this, 0, 16); + this.bipedRightLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, stretch); + this.bipedRightLeg.setRotationPoint(-2.0F, 12.0F + yoffset, 0.0F); + this.bipedLeftLeg = new ModelRenderer(this, 0, 16); + this.bipedLeftLeg.mirror = true; + this.bipedLeftLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, stretch); + this.bipedLeftLeg.setRotationPoint(2.0F, 12.0F + yoffset, 0.0F); + } + + @Override + public void animate(AniParams ani) {} + + @Override + public void render(AniParams ani) {} + + @Override + protected boolean doCancelRender() { + return true; + } + + + @Override + public void renderDrop(RenderManager rendermanager, ItemRenderer itemrenderer, EntityLivingBase entity) { + this.renderDrop(itemrenderer, entity, this.bipedRightArm, 1.0F, -0.0625F, 0.4375F, 0.0625F); + } + + @Override + public void renderEars(EntityLivingBase entity, float par2) { + for (int i = 0; i < 2; ++i) { + float f1 = entity.renderYawOffset + (entity.prevRenderYawOffset - entity.renderYawOffset) * par2 + - (entity.prevRenderYawOffset + (entity.renderYawOffset - entity.prevRenderYawOffset) * par2); + float f2 = entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * par2; + GL11.glPushMatrix(); + GL11.glRotatef(f1, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(f2, 1.0F, 0.0F, 0.0F); + GL11.glTranslatef(0.375F * (i * 2 - 1), 0.0F, 0.0F); + GL11.glTranslatef(0.0F, -0.375F, 0.0F); + GL11.glRotatef(-f2, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(-f1, 0.0F, 1.0F, 0.0F); + float f7 = 1.333333F; + GL11.glScalef(f7, f7, f7); + this.bipedEars.rotateAngleY = this.bipedHead.rotateAngleY; + this.bipedEars.rotateAngleX = this.bipedHead.rotateAngleX; + this.bipedEars.rotationPointX = 0.0F; + this.bipedEars.rotationPointY = 0.0F; + this.bipedEars.render(0.0625F); + GL11.glPopMatrix(); + } + + } + + @Override + public void renderCloak(EntityPlayer player, float par2) { + this.renderCape(par2); + GL11.glPushMatrix(); + GL11.glTranslatef(0.0F, 0.0F, 0.125F); + double d = player.prevChasingPosX + (player.chasingPosX - player.prevChasingPosX) * par2 + - (player.prevPosX + (player.posX - player.prevPosX) * par2); + double d1 = player.prevChasingPosY + (player.chasingPosY - player.prevChasingPosY) * par2 + - (player.prevPosY + (player.posY - player.prevPosY) * par2); + double d2 = player.prevChasingPosZ + (player.chasingPosZ - player.prevChasingPosZ) * par2 + - (player.prevPosZ + (player.posZ - player.prevPosZ) * par2); + float f10 = player.prevRenderYawOffset + (player.renderYawOffset - player.prevRenderYawOffset) * par2; + double d3 = MathHelper.sin(f10 * 3.1415927F / 180.0F); + double d4 = (-MathHelper.cos(f10 * 3.1415927F / 180.0F)); + float f12 = (float) d1 * 10.0F; + if (f12 < -6.0F) { + f12 = -6.0F; + } + + if (f12 > 32.0F) { + f12 = 32.0F; + } + + float f13 = (float) (d * d3 + d2 * d4) * 100.0F; + float f14 = (float) (d * d4 - d2 * d3) * 100.0F; + if (f13 < 0.0F) { + f13 = 0.0F; + } + + float f15 = player.prevCameraYaw + (player.cameraYaw - player.prevCameraYaw) * par2; + f12 += MathHelper.sin((player.prevDistanceWalkedModified + + (player.distanceWalkedModified - player.prevDistanceWalkedModified) * par2) * 6.0F) * 32.0F * f15; + if (player.isSneaking()) { + f12 += 25.0F; + } + + GL11.glRotatef(6.0F + f13 / 2.0F + f12, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(f14 / 2.0F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(-f14 / 2.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F); + this.cloak.render(0.0625F); + GL11.glPopMatrix(); + } + + @Override + public void renderStaticCloak(EntityLiving player, float par2) { + GL11.glPushMatrix(); + GL11.glTranslatef(0.0F, 0.0F, 0.125F); + GL11.glRotatef(3.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(2.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F); + this.cloak.render(0.0625F); + GL11.glPopMatrix(); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/model/pony/pm_newPonyAdv.java b/src/main/java/com/minelittlepony/minelp/model/pony/pm_newPonyAdv.java new file mode 100644 index 00000000..35b0d46a --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/pony/pm_newPonyAdv.java @@ -0,0 +1,1707 @@ +package com.minelittlepony.minelp.model.pony; + +import static net.minecraft.client.renderer.GlStateManager.*; + +import java.util.Random; + +import org.lwjgl.opengl.GL11; + +import com.minelittlepony.minelp.PonyManager; +import com.minelittlepony.minelp.model.ModelPony; +import com.minelittlepony.minelp.model.PMAPI; +import com.minelittlepony.minelp.renderer.AniParams; +import com.minelittlepony.minelp.renderer.CompressiveRendering; +import com.minelittlepony.minelp.renderer.HornGlowRenderer; +import com.minelittlepony.minelp.renderer.PlaneRenderer; + +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.MathHelper; + +public class pm_newPonyAdv extends ModelPony { + + protected static final float HEAD_CENTRE_X = 0.0F; + protected static final float HEAD_CENTRE_Y = -1.0F; + protected static final float HEAD_CENTRE_Z = -2.0F; + protected static final float BODY_CENTRE_X = 0.0F; + protected static final float BODY_CENTRE_Y = 8.0F; + protected static final float BODY_CENTRE_Z = 6.0F; + protected static final float THIRDP_ARM_CENTRE_X = 0.0F; + protected static final float THIRDP_ARM_CENTRE_Y = 10.0F; + protected static final float THIRDP_ARM_CENTRE_Z = 0.0F; + protected static final float FIRSTP_ARM_CENTRE_X = -1.0F; + protected static final float FIRSTP_ARM_CENTRE_Y = 4.0F; + protected static final float FIRSTP_ARM_CENTRE_Z = 0.0F; + protected static final float HEAD_RP_X = 0.0F; + protected static final float HEAD_RP_Y = 0.0F; + protected static final float HEAD_RP_Z = 0.0F; + protected static final float BODY_RP_Y_SNEAK = 7.0F; + protected static final float BODY_RP_Y_NOTSNEAK = 0.0F; + protected static final float BODY_RP_Z_SNEAK = -4.0F; + protected static final float BODY_RP_Z_NOTSNEAK = 0.0F; + protected static final float FRONT_LEG_RP_Y_SNEAK = 7.0F; + protected static final float FRONT_LEG_RP_Y_NOTSNEAK = 8.0F; + protected static final float WING_FOLDED_RP_Y = 13.0F; + protected static final float WING_FOLDED_RP_Z = -3.0F; + protected static final float LEFT_WING_RP_Y_SNEAK = 10.5F; + protected static final float LEFT_WING_RP_Y_NOTSNEAK = 5.5F; + protected static final float LEFT_WING_RP_Z_SNEAK = 2.0F; + protected static final float LEFT_WING_RP_Z_NOTSNEAK = 3.0F; + protected static final float RIGHT_WING_RP_Y_SNEAK = 11.5F; + protected static final float RIGHT_WING_RP_Y_NOTSNEAK = 6.5F; + protected static final float RIGHT_WING_RP_Z_SNEAK = 2.0F; + protected static final float RIGHT_WING_RP_Z_NOTSNEAK = 3.0F; + protected static final float TAIL_RP_X = 0.0F; + protected static final float TAIL_RP_Y = 0.8F; + protected static final float TAIL_RP_Z = 0.0F; + protected static final float TAIL_RP_Z_SNEAK = 10.0F; + protected static final float TAIL_RP_Z_NOTSNEAK = 14.0F; + protected static final float LEFT_WING_EXT_RP_X = 4.5F; + protected static final float LEFT_WING_EXT_RP_Y = 5.0F; + protected static final float LEFT_WING_EXT_RP_Z = 6.0F; + protected static final float RIGHT_WING_EXT_RP_X = -4.5F; + protected static final float RIGHT_WING_EXT_RP_Y = 5.0F; + protected static final float RIGHT_WING_EXT_RP_Z = 6.0F; + protected static final float BODY_ROTATE_ANGLE_X_SNEAK = 0.4F; + protected static final float BODY_ROTATE_ANGLE_X_NOTSNEAK = 0.0F; + protected static final float EXT_WING_ROTATE_ANGLE_X = 2.5F; + protected static final float LEFT_WING_ROTATE_ANGLE_Z_SNEAK = -6.0F; + protected static final float RIGHT_WING_ROTATE_ANGLE_Z_SNEAK = 6.0F; + protected static final float SNEAK_LEG_X_ROTATION_ADJUSTMENT = 0.4F; + protected static final float ROTATE_270 = 4.712F; + protected static final float ROTATE_90 = 1.571F; + protected static final float RIDING_SHIFT_Y = -10.0F; + protected static final float RIDING_SHIFT_Z = -10.0F; + + protected boolean rainboom; + protected final float Pi = 3.1415927F; + private float WingRotateAngleZ; + protected float NeckRotX = 0.166F; + public int tailstop = 0; + + public ModelRenderer bipedCape; + public ModelRenderer[] headpiece;// horn? ears? + public HornGlowRenderer[] hornglow; + public PlaneRenderer[] Bodypiece; + public PlaneRenderer[] VillagerBagPiece; + public PlaneRenderer VillagerApron; + public PlaneRenderer VillagerTrinket; + public PlaneRenderer[] BodypieceNeck; + public PlaneRenderer[] MuzzleFemale; + public PlaneRenderer[] MuzzleMale; + public ModelRenderer SteveArm; + public ModelRenderer unicornarm; + public PlaneRenderer[] Tail; + public ModelRenderer[] LeftWing; + public ModelRenderer[] RightWing; + public ModelRenderer[] LeftWingExt; + public ModelRenderer[] RightWingExt; + public CompressiveRendering CompressiveLeftWing; + public CompressiveRendering CompressiveRightWing; + + public pm_newPonyAdv(String texture) { + super(texture); + } + + @Override + public void init(float yOffset, float stretch) { + this.initTextures(); + this.initPositions(yOffset, stretch); + } + + @Override + public void animate(AniParams aniparams) { + this.checkRainboom(aniparams.swing); + this.rotateHead(aniparams.horz, aniparams.vert); + this.swingTailZ(aniparams.move, aniparams.swing); + float bodySwingRotation = 0.0F; + if (this.swingProgress > -9990.0F && (!this.isUnicorn || this.glowColor == 0)) { + bodySwingRotation = MathHelper.sin(MathHelper.sqrt_float(this.swingProgress) * 3.1415927F * 2.0F) * 0.2F; + } + + this.bipedBody.rotateAngleY = bodySwingRotation * 0.2F; + + int k1; + for (k1 = 0; k1 < this.Bodypiece.length; ++k1) { + this.Bodypiece[k1].rotateAngleY = bodySwingRotation * 0.2F; + } + + for (k1 = 0; k1 < this.VillagerBagPiece.length; ++k1) { + this.VillagerBagPiece[k1].rotateAngleY = bodySwingRotation * 0.2F; + } + + this.VillagerBagPiece[4].rotateAngleY += 4.712389F; + this.VillagerBagPiece[5].rotateAngleY += 4.712389F; + this.VillagerBagPiece[6].rotateAngleY += 4.712389F; + this.VillagerBagPiece[7].rotateAngleY += 4.712389F; + this.VillagerApron.rotateAngleY = bodySwingRotation * 0.2F; + this.VillagerTrinket.rotateAngleY = bodySwingRotation * 0.2F; + + for (k1 = 0; k1 < this.BodypieceNeck.length; ++k1) { + this.BodypieceNeck[k1].rotateAngleY = bodySwingRotation * 0.2F; + } + + for (k1 = 0; k1 < this.LeftWing.length; ++k1) { + this.LeftWing[k1].rotateAngleY = bodySwingRotation * 0.2F; + } + + for (k1 = 0; k1 < this.RightWing.length; ++k1) { + this.RightWing[k1].rotateAngleY = bodySwingRotation * 0.2F; + } + + this.tailstop = 0; + this.tailstop = this.Tail.length - this.wantTail * 5; + if (this.tailstop <= 1) { + this.tailstop = 0; + } + + for (k1 = 0; k1 < this.tailstop; ++k1) { + this.Tail[k1].rotateAngleY = bodySwingRotation; + } + + this.setLegs(aniparams.move, aniparams.swing, aniparams.tick); + this.holdItem(); + this.swingItem(this.swingProgress); + if (this.issneak && !this.isFlying) { + this.adjustBody(BODY_ROTATE_ANGLE_X_SNEAK, BODY_RP_Y_SNEAK, BODY_RP_Z_SNEAK); + this.animatePegasusWingsSneaking(); + this.sneakLegs(); + this.setHead(0.0F, 6.0F, -2.0F); + this.sneakTail(); + } else { + this.adjustBody(BODY_ROTATE_ANGLE_X_NOTSNEAK, BODY_RP_Y_NOTSNEAK, BODY_RP_Z_NOTSNEAK); + if (this.isPegasus) { + this.animatePegasusWingsNotSneaking(aniparams.tick); + } + + this.bipedRightLeg.rotationPointY = FRONT_LEG_RP_Y_NOTSNEAK; + this.bipedLeftLeg.rotationPointY = FRONT_LEG_RP_Y_NOTSNEAK; + this.swingArms(aniparams.tick); + this.setHead(0.0F, 0.0F, 0.0F); + this.tailstop = 0; + this.tailstop = this.Tail.length - this.wantTail * 5; + if (this.tailstop <= 1) { + this.tailstop = 0; + } + + for (k1 = 0; k1 < this.tailstop; ++k1) { + this.setRotationPoint(this.Tail[k1], TAIL_RP_X, TAIL_RP_Y, TAIL_RP_Z_NOTSNEAK); + if (this.rainboom) { + this.Tail[k1].rotateAngleX = ROTATE_90 + 0.1F * MathHelper.sin(aniparams.move); + } else { + this.Tail[k1].rotateAngleX = 0.5F * aniparams.swing; + } + } + + if (!this.rainboom) { + this.swingTailX(aniparams.tick); + } + } + + if (this.rainboom) { + this.tailstop = 0; + this.tailstop = this.Tail.length - this.wantTail * 5; + if (this.tailstop <= 1) { + this.tailstop = 0; + } + + for (k1 = 0; k1 < this.tailstop; ++k1) { + this.Tail[k1].rotationPointY += 6.0F; + ++this.Tail[k1].rotationPointZ; + } + } + + if (this.isSleeping) { + this.ponySleep(); + } + + if (this.aimedBow) { + this.aimBow(aniparams.tick); + } + + this.fixSpecialRotations(); + this.fixSpecialRotationPoints(aniparams.move); + + animateWears(); + } + + private void animateWears() { + copyModelAngles(bipedLeftArm, bipedLeftArmwear); + copyModelAngles(bipedRightArm, bipedRightArmwear); + copyModelAngles(bipedLeftLeg, bipedLeftLegwear); + copyModelAngles(bipedRightLeg, bipedRightLegwear); + copyModelAngles(bipedBody, bipedBodyWear); + } + + protected void checkRainboom(float swing) { + if (this.isPegasus && this.isFlying && swing >= 0.9999F) { + this.rainboom = true; + } else { + this.rainboom = false; + } + + } + + protected void setHead(float posX, float posY, float posZ) { + this.setRotationPoint(this.bipedHead, posX, posY, posZ); + this.setRotationPoint(this.bipedHeadwear, posX, posY, posZ); + + int j6; + for (j6 = 0; j6 < this.headpiece.length; ++j6) { + this.setRotationPoint(this.headpiece[j6], posX, posY, posZ); + } + + for (j6 = 0; j6 < this.hornglow.length; ++j6) { + this.setRotationPoint(this.hornglow[j6], posX, posY, posZ); + } + + if (this.isMale) { + for (j6 = 0; j6 < this.MuzzleMale.length; ++j6) { + this.setRotationPoint(this.MuzzleMale[j6], posX, posY, posZ); + } + } else { + for (j6 = 0; j6 < this.MuzzleFemale.length; ++j6) { + this.setRotationPoint(this.MuzzleFemale[j6], posX, posY, posZ); + } + } + + } + + protected void rotateHead(float horz, float vert) { + float headRotateAngleY; + float headRotateAngleX; + if (this.isSleeping) { + headRotateAngleY = 1.4F; + headRotateAngleX = 0.1F; + } else { + headRotateAngleY = horz / 57.29578F; + headRotateAngleX = vert / 57.29578F; + } + + if (headRotateAngleX > 0.5F) { + headRotateAngleX = 0.5F; + } + + if (headRotateAngleX < -0.5F) { + headRotateAngleX = -0.5F; + } + + this.bipedHead.rotateAngleY = headRotateAngleY; + this.bipedHead.rotateAngleX = headRotateAngleX; + int i; + if (this.isMale) { + for (i = 0; i < this.MuzzleMale.length; ++i) { + this.MuzzleMale[i].rotateAngleY = headRotateAngleY; + this.MuzzleMale[i].rotateAngleX = headRotateAngleX; + } + } else { + for (i = 0; i < this.MuzzleFemale.length; ++i) { + this.MuzzleFemale[i].rotateAngleY = headRotateAngleY; + this.MuzzleFemale[i].rotateAngleX = headRotateAngleX; + } + } + + this.headpiece[0].rotateAngleY = headRotateAngleY; + this.headpiece[0].rotateAngleX = headRotateAngleX; + this.headpiece[1].rotateAngleY = headRotateAngleY; + this.headpiece[1].rotateAngleX = headRotateAngleX; + this.headpiece[2].rotateAngleY = headRotateAngleY; + this.headpiece[2].rotateAngleX = headRotateAngleX; + this.hornglow[0].rotateAngleY = headRotateAngleY; + this.hornglow[0].rotateAngleX = headRotateAngleX; + this.hornglow[1].rotateAngleY = headRotateAngleY; + this.hornglow[1].rotateAngleX = headRotateAngleX; + this.bipedHeadwear.rotateAngleY = headRotateAngleY; + this.bipedHeadwear.rotateAngleX = headRotateAngleX; + this.headpiece[2].rotateAngleX = headRotateAngleX + 0.5F; + this.hornglow[0].rotateAngleX = headRotateAngleX + 0.5F; + this.hornglow[1].rotateAngleX = headRotateAngleX + 0.5F; + } + + protected void setLegs(float move, float swing, float tick) { + this.rotateLegs(move, swing, tick); + this.adjustLegs(); + } + + protected void rotateLegs(float move, float swing, float tick) { + float rightArmRotateAngleX; + float leftArmRotateAngleX; + float rightLegRotateAngleX; + float leftLegRotateAngleX; + if (this.isFlying && this.isPegasus) { + if (this.rainboom) { + rightArmRotateAngleX = ROTATE_270; + leftArmRotateAngleX = ROTATE_270; + rightLegRotateAngleX = ROTATE_90; + leftLegRotateAngleX = ROTATE_90; + } else { + rightArmRotateAngleX = MathHelper.sin(0.0F - swing * 0.5F); + leftArmRotateAngleX = MathHelper.sin(0.0F - swing * 0.5F); + rightLegRotateAngleX = MathHelper.sin(swing * 0.5F); + leftLegRotateAngleX = MathHelper.sin(swing * 0.5F); + } + + this.SteveArm.rotateAngleY = 0.2F; + this.bipedRightArm.rotateAngleY = 0.2F; + this.bipedLeftArm.rotateAngleY = -0.2F; + this.bipedRightLeg.rotateAngleY = -0.2F; + this.bipedLeftLeg.rotateAngleY = 0.2F; + + } else { + float swag = (float) Math.pow(swing, 16.0D); + this.getClass(); + float raQuad = 3.1415927F * swag * 0.5F; + this.getClass(); + float laQuad = 3.1415927F * swag; + this.getClass(); + float rlQuad = 3.1415927F * swag * 0.2F; + this.getClass(); + float llQuad = 3.1415927F * swag * -0.4F; + rightArmRotateAngleX = MathHelper.cos(move * 0.6662F + 3.1415927F + raQuad) * 0.45F * swing; + leftArmRotateAngleX = MathHelper.cos(move * 0.6662F + laQuad) * 0.45F * swing; + rightLegRotateAngleX = MathHelper.cos(move * 0.6662F + rlQuad) * 0.45F * swing; + leftLegRotateAngleX = MathHelper.cos(move * 0.6662F + 3.1415927F + llQuad) * 0.45F * swing; + this.SteveArm.rotateAngleY = 0.0F; + this.unicornarm.rotateAngleY = 0.0F; + + this.bipedRightArm.rotateAngleY = 0.0F; + this.bipedLeftArm.rotateAngleY = 0.0F; + this.bipedRightLeg.rotateAngleY = 0.0F; + this.bipedLeftLeg.rotateAngleY = 0.0F; + } + + this.bipedRightArm.rotateAngleX = rightArmRotateAngleX; + this.SteveArm.rotateAngleX = rightArmRotateAngleX; + this.unicornarm.rotateAngleX = 0.0F; + + this.bipedLeftArm.rotateAngleX = leftArmRotateAngleX; + this.bipedRightLeg.rotateAngleX = rightLegRotateAngleX; + this.bipedLeftLeg.rotateAngleX = leftLegRotateAngleX; + this.bipedRightArm.rotateAngleZ = 0.0F; + + this.SteveArm.rotateAngleZ = 0.0F; + this.unicornarm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + } + + protected void adjustLegs() { + float sinBodyRotateAngleYFactor = MathHelper.sin(this.bipedBody.rotateAngleY) * 5.0F; + float cosBodyRotateAngleYFactor = MathHelper.cos(this.bipedBody.rotateAngleY) * 5.0F; + float legOutset = 4.0F; + if (this.issneak && !this.isFlying) { + legOutset = 0.0F; + } + + if (this.isSleeping) { + legOutset = 2.6F; + } + + if (this.rainboom) { + this.bipedRightArm.rotationPointZ = sinBodyRotateAngleYFactor + + 2.0F; + this.SteveArm.rotationPointZ = sinBodyRotateAngleYFactor + 2.0F; + this.bipedLeftArm.rotationPointZ = 0.0F - sinBodyRotateAngleYFactor + 2.0F; + } else { + this.bipedRightArm.rotationPointZ = sinBodyRotateAngleYFactor + 1.0F; + this.SteveArm.rotationPointZ = sinBodyRotateAngleYFactor + 1.0F; + this.bipedLeftArm.rotationPointZ = 0.0F - sinBodyRotateAngleYFactor + 1.0F; + } + this.SteveArm.rotationPointX = 0.0F - cosBodyRotateAngleYFactor; + + this.bipedRightArm.rotationPointX = 0.0F - cosBodyRotateAngleYFactor - 1.0F + legOutset; + this.bipedLeftArm.rotationPointX = cosBodyRotateAngleYFactor + 1.0F - legOutset; + this.bipedRightLeg.rotationPointX = 0.0F - cosBodyRotateAngleYFactor - 1.0F + legOutset; + this.bipedLeftLeg.rotationPointX = cosBodyRotateAngleYFactor + 1.0F - legOutset; + + this.bipedRightArm.rotateAngleY += this.bipedBody.rotateAngleY; + this.bipedLeftArm.rotateAngleY += this.bipedBody.rotateAngleY; + this.bipedLeftArm.rotateAngleX += this.bipedBody.rotateAngleY; + + this.bipedRightArm.rotationPointY = 8.0F; + this.bipedLeftArm.rotationPointY = 8.0F; + this.bipedRightLeg.rotationPointZ = 10.0F; + this.bipedLeftLeg.rotationPointZ = 10.0F; + } + + protected void swingTailZ(float move, float swing) { + this.tailstop = 0; + this.tailstop = this.Tail.length - this.wantTail * 5; + if (this.tailstop <= 1) { + this.tailstop = 0; + } + + for (int j = 0; j < this.tailstop; ++j) { + if (this.rainboom) { + this.Tail[j].rotateAngleZ = 0.0F; + } else { + this.Tail[j].rotateAngleZ = MathHelper.cos(move * 0.8F) * 0.2F * swing; + } + } + + } + + protected void swingTailX(float tick) { + float sinTickFactor = MathHelper.sin(tick * 0.067F) * 0.05F; + this.tailstop = 0; + this.tailstop = this.Tail.length - this.wantTail * 5; + if (this.tailstop <= 1) { + this.tailstop = 0; + } + + for (int l6 = 0; l6 < this.tailstop; ++l6) { + this.Tail[l6].rotateAngleX += sinTickFactor; + } + + } + + protected void holdItem() { + if (this.heldItemRight != 0 && !this.rainboom && (!this.isUnicorn || this.glowColor == 0)) { + this.bipedRightArm.rotateAngleX = this.bipedRightArm.rotateAngleX * 0.5F - 0.3141593F; + this.SteveArm.rotateAngleX = this.SteveArm.rotateAngleX * 0.5F - 0.3141593F; + } + + } + + protected void swingItem(float swingProgress) { + if (swingProgress > -9990.0F && !this.isSleeping) { + float f16 = 1.0F - swingProgress; + f16 *= f16 * f16; + f16 = 1.0F - f16; + float f22 = MathHelper.sin(f16 * 3.1415927F); + float f28 = MathHelper.sin(swingProgress * 3.1415927F); + float f33 = f28 * -(this.bipedHead.rotateAngleX - 0.7F) * 0.75F; + if (this.isUnicorn && this.glowColor != 0 && this.heldItemRight != 0) { + this.unicornarm.rotateAngleX = (float) (this.unicornarm.rotateAngleX + - (f22 * 1.2D + f33)); + this.unicornarm.rotateAngleY += this.bipedBody.rotateAngleY * 2.0F; + this.unicornarm.rotateAngleZ = f28 * -0.4F; + } else { + this.bipedRightArm.rotateAngleX = (float) (this.bipedRightArm.rotateAngleX + - (f22 * 1.2D + f33)); + this.bipedRightArm.rotateAngleY += this.bipedBody.rotateAngleY * 2.0F; + this.bipedRightArm.rotateAngleZ = f28 * -0.4F; + this.SteveArm.rotateAngleX = (float) (this.SteveArm.rotateAngleX + - (f22 * 1.2D + f33)); + this.SteveArm.rotateAngleY += this.bipedBody.rotateAngleY * + 2.0F; + this.SteveArm.rotateAngleZ = f28 * -0.4F; + } + } + + } + + protected void swingArms(float tick) { + if (this.heldItemRight != 0 && !this.isSleeping) { + float cosTickFactor = MathHelper.cos(tick * 0.09F) * 0.05F + 0.05F; + float sinTickFactor = MathHelper.sin(tick * 0.067F) * 0.05F; + if (this.isUnicorn && this.glowColor != 0) { + this.unicornarm.rotateAngleZ += cosTickFactor; + this.unicornarm.rotateAngleX += sinTickFactor; + } else { + this.bipedRightArm.rotateAngleZ += cosTickFactor; + this.bipedRightArm.rotateAngleX += sinTickFactor; + this.SteveArm.rotateAngleZ += cosTickFactor; + this.SteveArm.rotateAngleX += sinTickFactor; + } + } + + } + + protected void adjustBody(float rotateAngleX, float rotationPointY, float rotationPointZ) { + this.adjustBodyComponents(rotateAngleX, rotationPointY, rotationPointZ); + this.adjustNeck(rotateAngleX, rotationPointY, rotationPointZ); + } + + protected void adjustBodyComponents(float rotateAngleX, float rotationPointY, float rotationPointZ) { + this.bipedBody.rotateAngleX = rotateAngleX; + this.bipedBody.rotationPointY = rotationPointY; + this.bipedBody.rotationPointZ = rotationPointZ; + + int k3; + for (k3 = 0; k3 < this.Bodypiece.length; ++k3) { + this.Bodypiece[k3].rotateAngleX = rotateAngleX; + this.Bodypiece[k3].rotationPointY = rotationPointY; + this.Bodypiece[k3].rotationPointZ = rotationPointZ; + } + + for (k3 = 0; k3 < this.VillagerBagPiece.length; ++k3) { + this.VillagerBagPiece[k3].rotateAngleX = rotateAngleX; + this.VillagerBagPiece[k3].rotationPointY = rotationPointY; + this.VillagerBagPiece[k3].rotationPointZ = rotationPointZ; + } + + this.VillagerApron.rotateAngleX = rotateAngleX; + this.VillagerApron.rotationPointY = rotationPointY; + this.VillagerApron.rotationPointZ = rotationPointZ; + this.VillagerTrinket.rotateAngleX = rotateAngleX; + this.VillagerTrinket.rotationPointY = rotationPointY; + this.VillagerTrinket.rotationPointZ = rotationPointZ; + } + + protected void adjustNeck(float rotateAngleX, float rotationPointY, float rotationPointZ) { + for (int k3 = 0; k3 < this.BodypieceNeck.length; ++k3) { + this.BodypieceNeck[k3].rotateAngleX = this.NeckRotX + rotateAngleX; + this.BodypieceNeck[k3].rotationPointY = rotationPointY; + this.BodypieceNeck[k3].rotationPointZ = rotationPointZ; + } + + } + + protected void sneakLegs() { + this.SteveArm.rotateAngleX += SNEAK_LEG_X_ROTATION_ADJUSTMENT; + this.unicornarm.rotateAngleX += SNEAK_LEG_X_ROTATION_ADJUSTMENT; + + this.bipedRightArm.rotateAngleX -= SNEAK_LEG_X_ROTATION_ADJUSTMENT; + this.bipedLeftArm.rotateAngleX -= SNEAK_LEG_X_ROTATION_ADJUSTMENT; + this.bipedRightLeg.rotationPointY = FRONT_LEG_RP_Y_SNEAK; + this.bipedLeftLeg.rotationPointY = FRONT_LEG_RP_Y_SNEAK; + + } + + protected void sneakTail() { + this.tailstop = 0; + this.tailstop = this.Tail.length - this.wantTail * 5; + if (this.tailstop <= 1) { + this.tailstop = 0; + } + + for (int i7 = 0; i7 < this.tailstop; ++i7) { + this.setRotationPoint(this.Tail[i7], TAIL_RP_X, TAIL_RP_Y, TAIL_RP_Z_SNEAK); + this.Tail[i7].rotateAngleX = 0.0F; + } + + } + + protected void ponySleep() { + this.bipedRightArm.rotateAngleX = ROTATE_270; + this.bipedLeftArm.rotateAngleX = ROTATE_270; + this.bipedRightLeg.rotateAngleX = ROTATE_90; + this.bipedLeftLeg.rotateAngleX = ROTATE_90; + float headPosX; + float headPosY; + float headPosZ; + if (this.issneak) { + headPosY = 2.0F; + headPosZ = -1.0F; + headPosX = 1.0F; + } else { + headPosY = 2.0F; + headPosZ = 1.0F; + headPosX = 1.0F; + } + + this.setHead(headPosX, headPosY, headPosZ); + this.shiftRotationPoint(this.bipedRightArm, 0.0F, 2.0F, 6.0F); + this.shiftRotationPoint(this.bipedLeftArm, 0.0F, 2.0F, 6.0F); + this.shiftRotationPoint(this.bipedRightLeg, 0.0F, 2.0F, -8.0F); + this.shiftRotationPoint(this.bipedLeftLeg, 0.0F, 2.0F, -8.0F); + } + + protected void aimBow(float tick) { + if (this.isUnicorn && this.glowColor != 0) { + this.aimBowUnicorn(tick); + } else { + this.aimBowPony(tick); + } + + } + + protected void aimBowPony(float tick) { + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedRightArm.rotateAngleY = -0.06F + this.bipedHead.rotateAngleY; + this.bipedRightArm.rotateAngleX = ROTATE_270 + this.bipedHead.rotateAngleX; + this.bipedRightArm.rotateAngleZ += MathHelper.cos(tick * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(tick * 0.067F) * 0.05F; + this.shiftRotationPoint(this.bipedRightArm, 0.0F, 0.0F, 1.0F); + + this.bipedRightArmwear.rotateAngleZ = 0.0F; + this.bipedRightArmwear.rotateAngleY = -0.06F + this.bipedHead.rotateAngleY; + this.bipedRightArmwear.rotateAngleX = ROTATE_270 + this.bipedHead.rotateAngleX; + this.bipedRightArmwear.rotateAngleZ += MathHelper.cos(tick * 0.09F) * 0.05F + 0.05F; + this.bipedRightArmwear.rotateAngleX += MathHelper.sin(tick * 0.067F) * 0.05F; + this.shiftRotationPoint(this.bipedRightArmwear, 0.0F, 0.0F, 1.0F); + } + + protected void aimBowUnicorn(float tick) { + this.unicornarm.rotateAngleZ = 0.0F; + this.unicornarm.rotateAngleY = -0.06F + this.bipedHead.rotateAngleY; + this.unicornarm.rotateAngleX = ROTATE_270 + this.bipedHead.rotateAngleX; + this.unicornarm.rotateAngleZ += MathHelper.cos(tick * 0.09F) * 0.05F + 0.05F; + this.unicornarm.rotateAngleX += MathHelper.sin(tick * 0.067F) * 0.05F; + } + + protected void animatePegasusWingsSneaking() { + int k5; + for (k5 = 0; k5 < this.LeftWingExt.length; ++k5) { + this.LeftWingExt[k5].rotationPointY = LEFT_WING_RP_Y_SNEAK; + this.LeftWingExt[k5].rotationPointZ = LEFT_WING_RP_Z_SNEAK; + this.LeftWingExt[k5].rotateAngleX = EXT_WING_ROTATE_ANGLE_X; + this.LeftWingExt[k5].rotateAngleZ = LEFT_WING_ROTATE_ANGLE_Z_SNEAK; + } + + for (k5 = 0; k5 < this.LeftWingExt.length; ++k5) { + this.RightWingExt[k5].rotationPointY = RIGHT_WING_RP_Y_SNEAK; + this.RightWingExt[k5].rotationPointZ = RIGHT_WING_RP_Z_SNEAK; + this.RightWingExt[k5].rotateAngleX = EXT_WING_ROTATE_ANGLE_X; + this.RightWingExt[k5].rotateAngleZ = RIGHT_WING_ROTATE_ANGLE_Z_SNEAK; + } + + } + + protected void animatePegasusWingsNotSneaking(float tick) { + int l5; + if (!this.isFlying) { + for (l5 = 0; l5 < this.LeftWing.length; ++l5) { + this.LeftWing[l5].rotationPointY = WING_FOLDED_RP_Y; + this.LeftWing[l5].rotationPointZ = WING_FOLDED_RP_Z; + } + + for (l5 = 0; l5 < this.RightWing.length; ++l5) { + this.RightWing[l5].rotationPointY = WING_FOLDED_RP_Y; + this.RightWing[l5].rotationPointZ = WING_FOLDED_RP_Z; + } + } else { + this.WingRotateAngleZ = MathHelper.sin(tick * 0.536F) * 1.0F; + + for (l5 = 0; l5 < this.LeftWingExt.length; ++l5) { + this.LeftWingExt[l5].rotateAngleX = EXT_WING_ROTATE_ANGLE_X; + this.LeftWingExt[l5].rotateAngleZ = -this.WingRotateAngleZ - ROTATE_270 - 0.4F; + this.LeftWingExt[l5].rotationPointY = LEFT_WING_RP_Y_NOTSNEAK; + this.LeftWingExt[l5].rotationPointZ = LEFT_WING_RP_Z_NOTSNEAK; + } + + for (l5 = 0; l5 < this.RightWingExt.length; ++l5) { + this.RightWingExt[l5].rotateAngleX = EXT_WING_ROTATE_ANGLE_X; + this.RightWingExt[l5].rotateAngleZ = this.WingRotateAngleZ + ROTATE_270 + 0.4F; + this.RightWingExt[l5].rotationPointY = RIGHT_WING_RP_Y_NOTSNEAK; + this.RightWingExt[l5].rotationPointZ = RIGHT_WING_RP_Z_NOTSNEAK; + } + } + + } + + protected void fixSpecialRotations() { + this.LeftWingExt[1].rotateAngleX -= 0.85F; + this.LeftWingExt[2].rotateAngleX -= 0.75F; + this.LeftWingExt[3].rotateAngleX -= 0.5F; + this.LeftWingExt[5].rotateAngleX -= 0.85F; + this.RightWingExt[1].rotateAngleX -= 0.85F; + this.RightWingExt[2].rotateAngleX -= 0.75F; + this.RightWingExt[3].rotateAngleX -= 0.5F; + this.RightWingExt[5].rotateAngleX -= 0.85F; + this.Bodypiece[9].rotateAngleX += 0.5F; + this.Bodypiece[10].rotateAngleX += 0.5F; + this.Bodypiece[11].rotateAngleX += 0.5F; + this.Bodypiece[12].rotateAngleX += 0.5F; + this.Bodypiece[13].rotateAngleX += 0.5F; + } + + @Override + public void setRotationAngles(float p_78087_1_, float p_78087_2_, float p_78087_3_, float p_78087_4_, + float p_78087_5_, float p_78087_6_, Entity p_78087_7_) { + // TODO Auto-generated method stub + super.setRotationAngles(p_78087_1_, p_78087_2_, p_78087_3_, + p_78087_4_, p_78087_5_, p_78087_6_, p_78087_7_); + copyModelAngles(this.bipedRightArm, this.SteveArm); + } + + protected void fixSpecialRotationPoints(float move) {} + + public void shiftRotationPoint(PlaneRenderer aPlaneRenderer, float shiftX, float shiftY, float shiftZ) { + aPlaneRenderer.rotationPointX += shiftX; + aPlaneRenderer.rotationPointY += shiftY; + aPlaneRenderer.rotationPointZ += shiftZ; + } + + public void shiftRotationPoint(ModelRenderer aRenderer, float shiftX, float shiftY, float shiftZ) { + aRenderer.rotationPointX += shiftX; + aRenderer.rotationPointY += shiftY; + aRenderer.rotationPointZ += shiftZ; + } + + public void setRotationPoint(HornGlowRenderer aRenderer, float setX, float setY, float setZ) { + aRenderer.rotationPointX = setX; + aRenderer.rotationPointY = setY; + aRenderer.rotationPointZ = setZ; + } + + public void setRotationPoint(PlaneRenderer aPlaneRenderer, float setX, float setY, float setZ) { + aPlaneRenderer.rotationPointX = setX; + aPlaneRenderer.rotationPointY = setY; + aPlaneRenderer.rotationPointZ = setZ; + } + + public void setRotationPoint(ModelRenderer aRenderer, float setX, float setY, float setZ) { + aRenderer.rotationPointX = setX; + aRenderer.rotationPointY = setY; + aRenderer.rotationPointZ = setZ; + } + + @Override + public void render(AniParams aniparams) { + if (this.isRiding && !this.isArmour) { + translate(0.0F, -0.56F, -0.46F); + } + + if (this.isSleeping && !this.isArmour) { + rotate(90.0F, 0.0F, 1.0F, 0.0F); + rotate(270.0F, 0.0F, 0.0F, 1.0F); + rotate(90.0F, 0.0F, 1.0F, 0.0F); + rotate(180.0F, 0.0F, 0.0F, 1.0F); + rotate(180.0F, 0.0F, 1.0F, 0.0F); + } + + if (this.size == 0) { + if (this.issneak && !this.isFlying && !this.isArmour) { + translate(0.0F, -0.12F, 0.0F); + } + + if (this.isSleeping && !this.isArmour) { + translate(0.0F, -1.0F, 0.25F); + } + + pushMatrix(); + translate(0.0F, 0.76F, 0.0F); + scale(0.9F, 0.9F, 0.9F); + this.renderHead(); + if (this.issneak && !this.isFlying) { + translate(0.0F, -0.01F, 0.15F); + } + + this.renderNeck(); + popMatrix(); + + pushMatrix(); + translate(0.0F, 0.76F, -0.04F); + scale(0.6F, 0.6F, 0.6F); + this.renderBody(); + this.renderTail(); + popMatrix(); + + pushMatrix(); + translate(0.0F, 0.89F, 0.0F); + scale(0.6F, 0.41F, 0.6F); + if (this.issneak && !this.isFlying) { + translate(0.0F, 0.12F, 0.0F); + } + + if (this.rainboom) { + translate(0.0F, -0.08F, 0.0F); + } + + this.renderLegs(); + popMatrix(); + + } else if (this.size == 2) { + if (this.isSleeping && !this.isArmour) { + translate(0.0F, -0.47F, 0.2F); + } + + pushMatrix(); + translate(0.0F, -0.17F, -0.04F); + if (this.isSleeping && !this.isArmour) { + translate(0.0F, 0.0F, -0.1F); + } + + if (this.issneak && !this.isFlying) { + translate(0.0F, 0.15F, 0.0F); + } + + this.renderHead(); + popMatrix(); + pushMatrix(); + translate(0.0F, -0.15F, -0.07F); + if (this.issneak && !this.isFlying) { + translate(0.0F, 0.0F, -0.05F); + } + + this.renderNeck(); + popMatrix(); + pushMatrix(); + translate(0.0F, -0.2F, -0.04F); + scale(1.15F, 1.2F, 1.2F); + this.renderBody(); + popMatrix(); + pushMatrix(); + translate(0.0F, -0.2F, 0.08F); + this.renderTail(); + popMatrix(); + pushMatrix(); + translate(0.0F, -0.14F, 0.0F); + scale(1.15F, 1.12F, 1.15F); + this.renderLegs(); + popMatrix(); + } else if (this.size == 3) { + if (this.isSleeping && !this.isArmour) { + translate(0.0F, -0.43F, 0.25F); + } + + pushMatrix(); + translate(0.0F, -0.15F, 0.01F); + if (this.issneak && !this.isFlying) { + translate(0.0F, 0.05F, 0.0F); + } + + this.renderHead(); + popMatrix(); + pushMatrix(); + translate(0.0F, -0.19F, -0.01F); + scale(1.0F, 1.1F, 1.0F); + if (this.issneak && !this.isFlying) { + translate(0.0F, -0.06F, -0.04F); + } + + this.renderNeck(); + popMatrix(); + pushMatrix(); + translate(0.0F, -0.1F, 0.0F); + scale(1.0F, 1.0F, 1.0F); + this.renderBody(); + this.renderTail(); + popMatrix(); + pushMatrix(); + translate(0.0F, -0.25F, 0.03F); + scale(1.0F, 1.18F, 1.0F); + if (this.rainboom) { + translate(0.0F, 0.05F, 0.0F); + } + + this.renderLegs(); + popMatrix(); + } else { + if (this.isSleeping && !this.isArmour) { + translate(0.0F, -0.535F, 0.25F); + } + + this.renderHead(); + this.renderNeck(); + this.renderBody(); + this.renderTail(); + this.renderLegs(); + } + + } + + protected void renderHead() { + this.bipedHead.render(this.scale); + this.headpiece[0].render(this.scale); + this.headpiece[1].render(this.scale); + if (PonyManager.getInstance().getShowSnuzzles() == 1) { + int red; + if (this.isMale) { + for (red = 0; red < this.MuzzleMale.length; ++red) { + this.MuzzleMale[red].render(this.scale); + } + } else { + for (red = 0; red < this.MuzzleFemale.length; ++red) { + this.MuzzleFemale[red].render(this.scale); + } + } + } + + this.bipedHeadwear.render(this.scale); + if (this.isUnicorn) { + this.headpiece[2].render(this.scale); + if (this.heldItemRight != 0 && this.glowColor != 0) { + GL11.glPushAttrib(24577); + GL11.glDisable(3553); + GL11.glDisable(2896); + GL11.glEnable(3042); + float var4 = (this.glowColor >> 16 & 255) / 255.0F; + float green = (this.glowColor >> 8 & 255) / 255.0F; + float blue = (this.glowColor & 255) / 255.0F; + blendFunc(770, 1); + color(var4, green, blue, 0.4F); + this.hornglow[0].render(this.scale); + color(var4, green, blue, 0.2F); + this.hornglow[1].render(this.scale); + popAttrib(); + } + } + + } + + protected void renderNeck() { + for (PlaneRenderer element : this.BodypieceNeck) { + element.render(this.scale); + } + + } + + protected void renderBody() { + this.bipedBody.render(this.scale); + if (this.textureHeight == 64) { + this.bipedBodyWear.render(this.scale); + } + int k1; + for (k1 = 0; k1 < this.Bodypiece.length; ++k1) { + this.Bodypiece[k1].render(this.scale); + } + + if (this.isVillager) { + if (this.villagerProfession < 2) { + for (k1 = 0; k1 < this.VillagerBagPiece.length; ++k1) { + this.VillagerBagPiece[k1].render(this.scale); + } + } else if (this.villagerProfession == 2) { + this.VillagerTrinket.render(this.scale); + } else if (this.villagerProfession > 2) { + this.VillagerApron.render(this.scale); + } + } + + if (this.isPegasus) { + if (!this.isFlying && !this.issneak) { + this.setExtendingWings(true); + + for (k1 = 0; k1 < this.LeftWing.length; ++k1) { + this.LeftWing[k1].render(this.scale); + } + + for (k1 = 0; k1 < this.RightWing.length; ++k1) { + this.RightWing[k1].render(this.scale); + } + } else { + this.setExtendingWings(false); + + for (k1 = 0; k1 < this.LeftWingExt.length; ++k1) { + this.LeftWingExt[k1].render(this.scale); + } + + for (k1 = 0; k1 < this.RightWingExt.length; ++k1) { + this.RightWingExt[k1].render(this.scale); + } + } + } + + } + + protected void renderTail() { + int var3 = this.Tail.length - this.wantTail * 5; + if (var3 <= 1) { + var3 = 0; + } + + for (int k = 0; k < var3; ++k) { + this.Tail[k].render(this.scale); + } + + } + + protected void renderLegs() { + this.bipedLeftArm.render(this.scale); + this.bipedRightArm.render(this.scale); + this.bipedLeftLeg.render(this.scale); + this.bipedRightLeg.render(this.scale); + if (this.textureHeight == 64) { + this.bipedLeftArmwear.render(this.scale); + this.bipedRightArmwear.render(this.scale); + this.bipedLeftLegwear.render(this.scale); + this.bipedRightLegwear.render(this.scale); + } + } + + @Override + public void renderRightArm() { + copyModelAngles(PMAPI.human.model.bipedRightArm, SteveArm); + this.SteveArm.render(this.scale); + copyModelAngles(PMAPI.human.model.bipedRightArm, unicornarm); + this.unicornarm.showModel = this.bipedRightArmwear.showModel; + this.unicornarm.render(this.scale); + + } + + protected void initTextures() { + this.Tail = new PlaneRenderer[21]; + this.headpiece = new ModelRenderer[3]; + this.hornglow = new HornGlowRenderer[2]; + this.MuzzleFemale = new PlaneRenderer[10]; + this.MuzzleMale = new PlaneRenderer[5]; + this.Bodypiece = new PlaneRenderer[14]; + this.VillagerBagPiece = new PlaneRenderer[14]; + this.BodypieceNeck = new PlaneRenderer[4]; + this.LeftWing = new ModelRenderer[3]; + this.RightWing = new ModelRenderer[3]; + this.LeftWingExt = new ModelRenderer[6]; + this.RightWingExt = new ModelRenderer[6]; + this.initHeadTextures(); + this.initMuzzleTextures(); + this.initBodyTextures(); + this.initLegTextures(); + this.initTailTextures(); + this.initWingTextures(); + } + + protected void initHeadTextures() { + this.bipedCape = new ModelRenderer(this, 0, 0); + this.bipedHead = new ModelRenderer(this, 0, 0); + this.headpiece[0] = new ModelRenderer(this, 12, 16); + this.headpiece[1] = new ModelRenderer(this, 12, 16); + this.headpiece[1].mirror = true; + this.headpiece[2] = new ModelRenderer(this, 0, 3); + this.hornglow[0] = new HornGlowRenderer(this, 0, 3); + this.hornglow[1] = new HornGlowRenderer(this, 0, 3); + this.bipedHeadwear = new ModelRenderer(this, 32, 0); + this.boxList.remove(this.headpiece[2]); + } + + protected void initMuzzleTextures() { + this.MuzzleFemale[0] = new PlaneRenderer(this, 10, 14); + this.MuzzleFemale[1] = new PlaneRenderer(this, 11, 13); + this.MuzzleFemale[2] = new PlaneRenderer(this, 9, 14); + this.MuzzleFemale[3] = new PlaneRenderer(this, 14, 14); + this.MuzzleFemale[4] = new PlaneRenderer(this, 11, 12); + this.MuzzleFemale[5] = new PlaneRenderer(this, 18, 7); + this.MuzzleFemale[6] = new PlaneRenderer(this, 9, 14); + this.MuzzleFemale[7] = new PlaneRenderer(this, 14, 14); + this.MuzzleFemale[8] = new PlaneRenderer(this, 11, 12); + this.MuzzleFemale[9] = new PlaneRenderer(this, 12, 12); + this.MuzzleMale[0] = new PlaneRenderer(this, 10, 13); + this.MuzzleMale[1] = new PlaneRenderer(this, 10, 13); + this.MuzzleMale[2] = new PlaneRenderer(this, 18, 7); + this.MuzzleMale[3] = new PlaneRenderer(this, 10, 13); + this.MuzzleMale[4] = new PlaneRenderer(this, 13, 13); + } + + protected void initBodyTextures() { + this.bipedBody = new ModelRenderer(this, 16, 16); + if (this.textureHeight == 64) { + this.bipedBodyWear = new ModelRenderer(this, 16, 32); + } + + this.Bodypiece[0] = new PlaneRenderer(this, 24, 0); + this.Bodypiece[1] = new PlaneRenderer(this, 24, 0); + + this.Bodypiece[0] = new PlaneRenderer(this, 24, 0); + this.Bodypiece[1] = new PlaneRenderer(this, 24, 0); + this.Bodypiece[2] = new PlaneRenderer(this, 32, 20); + this.Bodypiece[2].mirrorxy = true; + this.Bodypiece[3] = new PlaneRenderer(this, 56, 0); + this.Bodypiece[4] = new PlaneRenderer(this, 4, 0); + this.Bodypiece[5] = new PlaneRenderer(this, 4, 0); + this.Bodypiece[6] = new PlaneRenderer(this, 36, 16); + this.Bodypiece[7] = new PlaneRenderer(this, 36, 16); + this.Bodypiece[8] = new PlaneRenderer(this, 36, 16); + this.Bodypiece[9] = new PlaneRenderer(this, 32, 0); + this.Bodypiece[10] = new PlaneRenderer(this, 32, 0); + this.Bodypiece[11] = new PlaneRenderer(this, 32, 0); + this.Bodypiece[11].mirror = true; + this.Bodypiece[12] = new PlaneRenderer(this, 32, 0); + this.Bodypiece[13] = new PlaneRenderer(this, 32, 0); + // neck + this.BodypieceNeck[0] = new PlaneRenderer(this, 0, 8); + this.BodypieceNeck[1] = new PlaneRenderer(this, 0, 8); + this.BodypieceNeck[2] = new PlaneRenderer(this, 0, 8); + this.BodypieceNeck[3] = new PlaneRenderer(this, 0, 8); + + this.VillagerBagPiece[0] = new PlaneRenderer(this, 56, 19); + this.VillagerBagPiece[1] = new PlaneRenderer(this, 56, 19); + this.VillagerBagPiece[2] = new PlaneRenderer(this, 56, 19); + this.VillagerBagPiece[3] = new PlaneRenderer(this, 56, 19); + this.VillagerBagPiece[4] = new PlaneRenderer(this, 56, 16); + this.VillagerBagPiece[5] = new PlaneRenderer(this, 56, 16); + this.VillagerBagPiece[6] = new PlaneRenderer(this, 56, 22); + this.VillagerBagPiece[7] = new PlaneRenderer(this, 56, 22); + this.VillagerBagPiece[8] = new PlaneRenderer(this, 56, 25); + this.VillagerBagPiece[9] = new PlaneRenderer(this, 56, 25); + this.VillagerBagPiece[10] = new PlaneRenderer(this, 59, 25); + this.VillagerBagPiece[11] = new PlaneRenderer(this, 59, 25); + this.VillagerBagPiece[12] = new PlaneRenderer(this, 56, 31); + this.VillagerBagPiece[13] = new PlaneRenderer(this, 56, 31); + this.VillagerApron = new PlaneRenderer(this, 56, 16); + this.VillagerTrinket = new PlaneRenderer(this, 0, 3); + } + + protected void initLegTextures() { + this.bipedRightArm = new ModelRenderer(this, 40, 16); + this.bipedRightLeg = new ModelRenderer(this, 0, 16); + + if (this.textureHeight == 64) { + this.bipedLeftArm = new ModelRenderer(this, 32, 48); + this.bipedLeftLeg = new ModelRenderer(this, 32, 48); + + this.bipedRightArmwear = new ModelRenderer(this, 40, 32); + this.bipedLeftArmwear = new ModelRenderer(this, 48, 48); + this.bipedRightLegwear = new ModelRenderer(this, 0, 32); + this.bipedLeftLegwear = new ModelRenderer(this, 0, 48); + } else { + this.bipedLeftArm = new ModelRenderer(this, 40, 16); + this.bipedLeftArm.mirror = true; + this.bipedLeftLeg = new ModelRenderer(this, 0, 16); + this.bipedLeftLeg.mirror = true; + } + this.SteveArm = new ModelRenderer(this, 40, 16); + this.unicornarm = new ModelRenderer(this, 40, 32); + this.boxList.remove(this.SteveArm); + this.boxList.remove(this.unicornarm); + } + + protected void initTailTextures() { + // upper + this.Tail[0] = new PlaneRenderer(this, 32, 0); + this.Tail[1] = new PlaneRenderer(this, 36, 0); + this.Tail[2] = new PlaneRenderer(this, 32, 0); + this.Tail[3] = new PlaneRenderer(this, 36, 0); + this.Tail[4] = new PlaneRenderer(this, 32, 0); + this.Tail[5] = new PlaneRenderer(this, 32, 0); + this.Tail[6] = new PlaneRenderer(this, 36, 4); + this.Tail[7] = new PlaneRenderer(this, 32, 4); + this.Tail[8] = new PlaneRenderer(this, 36, 4); + this.Tail[9] = new PlaneRenderer(this, 32, 4); + this.Tail[10] = new PlaneRenderer(this, 32, 0); + this.Tail[11] = new PlaneRenderer(this, 36, 0); + this.Tail[12] = new PlaneRenderer(this, 32, 0); + this.Tail[13] = new PlaneRenderer(this, 36, 0); + this.Tail[14] = new PlaneRenderer(this, 32, 0); + this.Tail[15] = new PlaneRenderer(this, 32, 0); + this.Tail[16] = new PlaneRenderer(this, 36, 4); + this.Tail[17] = new PlaneRenderer(this, 32, 4); + this.Tail[18] = new PlaneRenderer(this, 36, 4); + this.Tail[19] = new PlaneRenderer(this, 32, 4); + this.Tail[20] = new PlaneRenderer(this, 32, 0); + } + + protected void initWingTextures() { + this.LeftWing[0] = new ModelRenderer(this, 56, 16); + this.LeftWing[0].mirror = true; + this.LeftWing[1] = new ModelRenderer(this, 56, 16); + this.LeftWing[1].mirror = true; + this.LeftWing[2] = new ModelRenderer(this, 56, 16); + this.LeftWing[2].mirror = true; + this.RightWing[0] = new ModelRenderer(this, 56, 16); + this.RightWing[1] = new ModelRenderer(this, 56, 16); + this.RightWing[2] = new ModelRenderer(this, 56, 16); + this.LeftWingExt[0] = new ModelRenderer(this, 56, 19); + this.LeftWingExt[0].mirror = true; + this.LeftWingExt[1] = new ModelRenderer(this, 56, 19); + this.LeftWingExt[1].mirror = true; + this.LeftWingExt[2] = new ModelRenderer(this, 56, 19); + this.LeftWingExt[2].mirror = true; + this.LeftWingExt[3] = new ModelRenderer(this, 56, 19); + this.LeftWingExt[3].mirror = true; + this.LeftWingExt[4] = new ModelRenderer(this, 56, 19); + this.LeftWingExt[4].mirror = true; + this.LeftWingExt[5] = new ModelRenderer(this, 56, 19); + this.LeftWingExt[5].mirror = true; + this.RightWingExt[0] = new ModelRenderer(this, 56, 19); + this.RightWingExt[1] = new ModelRenderer(this, 56, 19); + this.RightWingExt[2] = new ModelRenderer(this, 56, 19); + this.RightWingExt[3] = new ModelRenderer(this, 56, 19); + this.RightWingExt[4] = new ModelRenderer(this, 56, 19); + this.RightWingExt[5] = new ModelRenderer(this, 56, 19); + this.compressWings(); + } + + protected void initPositions(float yOffset, float stretch) { + this.initHeadPositions(yOffset, stretch); + this.initMuzzlePositions(yOffset, stretch); + this.initBodyPositions(yOffset, stretch); + this.initLegPositions(yOffset, stretch); + this.initTailPositions(yOffset, stretch); + this.initWingPositions(yOffset, stretch); + } + + protected void initHeadPositions(float yOffset, float stretch) { + this.bipedCape.addBox(-5.0F, 0.0F, -1.0F, 10, 16, 1, stretch); + this.bipedHead.addBox(-4.0F + HEAD_CENTRE_X, -4 + HEAD_CENTRE_Y, -4.0F + HEAD_CENTRE_Z, + 8, 8, 8, stretch); + this.bipedHead.setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.headpiece[0].addBox(-4.0F + HEAD_CENTRE_X, -6.0F + HEAD_CENTRE_Y, 1.0F + HEAD_CENTRE_Z, 2, 2, 2, stretch); + this.headpiece[0].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.headpiece[1].addBox(2.0F + HEAD_CENTRE_X, -6.0F + HEAD_CENTRE_Y, 1.0F + HEAD_CENTRE_Z, 2, 2, 2, stretch); + this.headpiece[1].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.headpiece[2].addBox(-0.5F + HEAD_CENTRE_X, -10.0F + HEAD_CENTRE_Y, -1.5F + HEAD_CENTRE_Z, 1, 4, 1, + stretch); + this.headpiece[2].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.hornglow[0].addBox(-0.5F + HEAD_CENTRE_X, -10.0F + HEAD_CENTRE_Y, -1.5F + HEAD_CENTRE_Z, 1, 4, 1, + stretch + 0.5F); + this.hornglow[0].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.hornglow[1].addBox(-0.5F + HEAD_CENTRE_X, -10.0F + HEAD_CENTRE_Y, -1.5F + HEAD_CENTRE_Z, 1, 3, 1, + stretch + 0.8F); + this.hornglow[1].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.bipedHeadwear.addBox(-4.0F + HEAD_CENTRE_X, -4.0F + HEAD_CENTRE_Y, -4.0F + HEAD_CENTRE_Z, 8, 8, 8, + stretch + 0.5F); + this.bipedHeadwear.setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + } + + protected void initMuzzlePositions(float yOffset, float stretch) { + this.MuzzleFemale[0].addBackPlane(-2.0F + HEAD_CENTRE_X, 2.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 4, 2, 0, stretch); + this.MuzzleFemale[0].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.MuzzleFemale[1].addBackPlane(-1.0F + HEAD_CENTRE_X, 1.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 2, 1, 0, stretch); + this.MuzzleFemale[1].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.MuzzleFemale[2].addTopPlane(-2.0F + HEAD_CENTRE_X, 2.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 1, 0, 1, stretch); + this.MuzzleFemale[2].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.MuzzleFemale[3].addTopPlane(1.0F + HEAD_CENTRE_X, 2.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 1, 0, 1, stretch); + this.MuzzleFemale[3].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.MuzzleFemale[4].addTopPlane(-1.0F + HEAD_CENTRE_X, 1.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 2, 0, 1, stretch); + this.MuzzleFemale[4].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.MuzzleFemale[5].addBottomPlane(-2.0F + HEAD_CENTRE_X, 4.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 4, 0, 1, stretch); + this.MuzzleFemale[5].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.MuzzleFemale[6].addSidePlane(-2.0F + HEAD_CENTRE_X, 2.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 0, 2, 1, stretch); + this.MuzzleFemale[6].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.MuzzleFemale[7].addSidePlane(2.0F + HEAD_CENTRE_X, 2.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 0, 2, 1, stretch); + this.MuzzleFemale[7].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.MuzzleFemale[8].addSidePlane(-1.0F + HEAD_CENTRE_X, 1.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 0, 1, 1, stretch); + this.MuzzleFemale[8].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.MuzzleFemale[9].addSidePlane(1.0F + HEAD_CENTRE_X, 1.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 0, 1, 1, stretch); + this.MuzzleFemale[9].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.MuzzleMale[0].addBackPlane(-2.0F + HEAD_CENTRE_X, 1.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 4, 3, 0, stretch); + this.MuzzleMale[0].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.MuzzleMale[1].addTopPlane(-2.0F + HEAD_CENTRE_X, 1.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 4, 0, 1, stretch); + this.MuzzleMale[1].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.MuzzleMale[2].addBottomPlane(-2.0F + HEAD_CENTRE_X, 4.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 4, 0, 1, stretch); + this.MuzzleMale[2].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.MuzzleMale[3].addSidePlane(-2.0F + HEAD_CENTRE_X, 1.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 0, 3, 1, stretch); + this.MuzzleMale[3].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.MuzzleMale[4].addSidePlane(2.0F + HEAD_CENTRE_X, 1.0F + HEAD_CENTRE_Y, + -5.0F + HEAD_CENTRE_Z, 0, 3, 1, stretch); + this.MuzzleMale[4].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + } + + protected void initBodyPositions(float yOffset, float stretch) { + this.bipedBody.addBox(-4.0F, 4.0F, -2.0F, 8, 8, 4, stretch); + this.bipedBody.setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.bipedBodyWear.addBox(-4.0F, 4.0F, -2.0F, 8, 8, 4, stretch + 0.25F); + this.bipedBodyWear.setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + + this.Bodypiece[0].addSidePlane(-4.0F + BODY_CENTRE_X, -4.0F + BODY_CENTRE_Y, + -4.0F + BODY_CENTRE_Z, 0, 8, 8, stretch); + this.Bodypiece[0].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.Bodypiece[1].addSidePlane(4.0F + BODY_CENTRE_X, -4.0F + BODY_CENTRE_Y, + -4.0F + BODY_CENTRE_Z, 0, 8, 8, stretch); + this.Bodypiece[1].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.Bodypiece[2].addTopPlane(-4.0F + BODY_CENTRE_X, -4.0F + BODY_CENTRE_Y, + -4.0F + BODY_CENTRE_Z, 8, 0, 12, stretch); + this.Bodypiece[2].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.Bodypiece[3].addBottomPlane(-4.0F + BODY_CENTRE_X, 4.0F + BODY_CENTRE_Y, + -4.0F + BODY_CENTRE_Z, 8, 0, 8, stretch); + this.Bodypiece[3].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.Bodypiece[4].addSidePlane(-4.0F + BODY_CENTRE_X, -4.0F + BODY_CENTRE_Y, + 4.0F + BODY_CENTRE_Z, 0, 8, 4, stretch); + this.Bodypiece[4].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.Bodypiece[5].addSidePlane(4.0F + BODY_CENTRE_X, -4.0F + BODY_CENTRE_Y, 4.0F + BODY_CENTRE_Z, + 0, 8, 4, stretch); + this.Bodypiece[5].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.Bodypiece[6].addBackPlane(-4.0F + BODY_CENTRE_X, -4.0F + BODY_CENTRE_Y, + 8.0F + BODY_CENTRE_Z, 8, 4, 0, stretch); + this.Bodypiece[6].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.Bodypiece[7].addBackPlane(-4.0F + BODY_CENTRE_X, 0.0F + BODY_CENTRE_Y, 8.0F + BODY_CENTRE_Z, + 8, 4, 0, stretch); + this.Bodypiece[7].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.Bodypiece[8].addBottomPlane(-4.0F + BODY_CENTRE_X, 4.0F + BODY_CENTRE_Y, + 4.0F + BODY_CENTRE_Z, 8, 0, 4, stretch); + this.Bodypiece[8].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.Bodypiece[9].addTopPlane(-1.0F + BODY_CENTRE_X, 2.0F + BODY_CENTRE_Y, 2.0F + BODY_CENTRE_Z, + 2, 0, 6, stretch); + this.Bodypiece[9].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.Bodypiece[10].addBottomPlane(-1.0F + BODY_CENTRE_X, 4.0F + BODY_CENTRE_Y, + 2.0F + BODY_CENTRE_Z, 2, 0, 6, stretch); + this.Bodypiece[10].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.Bodypiece[11].addSidePlane(-1.0F + BODY_CENTRE_X, 2.0F + BODY_CENTRE_Y, + 2.0F + BODY_CENTRE_Z, 0, 2, 6, stretch); + this.Bodypiece[11].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.Bodypiece[12].addSidePlane(1.0F + BODY_CENTRE_X, 2.0F + BODY_CENTRE_Y, 2.0F + BODY_CENTRE_Z, + 0, 2, 6, stretch); + this.Bodypiece[12].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.Bodypiece[13].addBackPlane(-1.0F + BODY_CENTRE_X, 2.0F + BODY_CENTRE_Y, + 8.0F + BODY_CENTRE_Z, 2, 2, 0, stretch); + this.Bodypiece[13].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerBagPiece[0].addSidePlane(-7.0F + BODY_CENTRE_X, -5.0F + BODY_CENTRE_Y, + -4.0F + BODY_CENTRE_Z, 0, 6, 8, stretch); + this.VillagerBagPiece[0].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerBagPiece[1].addSidePlane(-4.0F + BODY_CENTRE_X, -5.0F + BODY_CENTRE_Y, + -4.0F + BODY_CENTRE_Z, 0, 6, 8, stretch); + this.VillagerBagPiece[1].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerBagPiece[2].addSidePlane(4.0F + BODY_CENTRE_X, -5.0F + BODY_CENTRE_Y, + -4.0F + BODY_CENTRE_Z, 0, 6, 8, stretch); + this.VillagerBagPiece[2].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerBagPiece[3].addSidePlane(7.0F + BODY_CENTRE_X, -5.0F + BODY_CENTRE_Y, + -4.0F + BODY_CENTRE_Z, 0, 6, 8, stretch); + this.VillagerBagPiece[3].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerBagPiece[4].addTopPlane(2.0F + BODY_CENTRE_X, -5.0F + BODY_CENTRE_Y, + -2.0F + BODY_CENTRE_Z, 8, 0, 3, stretch); + this.VillagerBagPiece[4].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerBagPiece[5].addTopPlane(2.0F + BODY_CENTRE_X, -5.0F + BODY_CENTRE_Y, + -13.0F + BODY_CENTRE_Z, 8, 0, 3, stretch); + this.VillagerBagPiece[5].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerBagPiece[6].addBottomPlane(2.0F + BODY_CENTRE_X, 1.0F + BODY_CENTRE_Y, + -2.0F + BODY_CENTRE_Z, 8, 0, 3, stretch); + this.VillagerBagPiece[6].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerBagPiece[7].addBottomPlane(2.0F + BODY_CENTRE_X, 1.0F + BODY_CENTRE_Y, + -13.0F + BODY_CENTRE_Z, 8, 0, 3, stretch); + this.VillagerBagPiece[7].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerBagPiece[8].addBackPlane(-7.0F + BODY_CENTRE_X, -5.0F + BODY_CENTRE_Y, + -4.0F + BODY_CENTRE_Z, 3, 6, 0, stretch); + this.VillagerBagPiece[8].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerBagPiece[9].addBackPlane(4.0F + BODY_CENTRE_X, -5.0F + BODY_CENTRE_Y, + -4.0F + BODY_CENTRE_Z, 3, 6, 0, stretch); + this.VillagerBagPiece[9].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerBagPiece[10].addBackPlane(-7.0F + BODY_CENTRE_X, -5.0F + BODY_CENTRE_Y, + 4.0F + BODY_CENTRE_Z, 3, 6, 0, stretch); + this.VillagerBagPiece[10].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerBagPiece[11].addBackPlane(4.0F + BODY_CENTRE_X, -5.0F + BODY_CENTRE_Y, + 4.0F + BODY_CENTRE_Z, 3, 6, 0, stretch); + this.VillagerBagPiece[11].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerBagPiece[12].addTopPlane(-4.0F + BODY_CENTRE_X, -4.5F + BODY_CENTRE_Y, + -1.0F + BODY_CENTRE_Z, 8, 0, 1, stretch); + this.VillagerBagPiece[13].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerBagPiece[13].addTopPlane(-4.0F + BODY_CENTRE_X, -4.5F + BODY_CENTRE_Y, + 0.0F + BODY_CENTRE_Z, 8, 0, 1, stretch); + this.VillagerBagPiece[13].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerApron.addBackPlane(-4.0F + BODY_CENTRE_X, -4.0F + BODY_CENTRE_Y, + -9.0F + BODY_CENTRE_Z, 8, 10, 0, stretch); + this.VillagerApron.setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.VillagerTrinket.addBackPlane(-2.0F + BODY_CENTRE_X, -4.0F + BODY_CENTRE_Y, + -9.0F + BODY_CENTRE_Z, 4, 5, 0, stretch); + this.VillagerTrinket.setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.BodypieceNeck[0].addBackPlane(-2.0F + BODY_CENTRE_X, -6.8F + BODY_CENTRE_Y, + -8.8F + BODY_CENTRE_Z, 4, 4, 0, stretch); + this.BodypieceNeck[0].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.BodypieceNeck[1].addBackPlane(-2.0F + BODY_CENTRE_X, -6.8F + BODY_CENTRE_Y, + -4.8F + BODY_CENTRE_Z, 4, 4, 0, stretch); + this.BodypieceNeck[1].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.BodypieceNeck[2].addSidePlane(-2.0F + BODY_CENTRE_X, -6.8F + BODY_CENTRE_Y, + -8.8F + BODY_CENTRE_Z, 0, 4, 4, stretch); + this.BodypieceNeck[2].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.BodypieceNeck[3].addSidePlane(2.0F + BODY_CENTRE_X, -6.8F + BODY_CENTRE_Y, + -8.8F + BODY_CENTRE_Z, 0, 4, 4, stretch); + this.BodypieceNeck[3].setRotationPoint(HEAD_RP_X, HEAD_RP_Y + yOffset, HEAD_RP_Z); + this.BodypieceNeck[0].rotateAngleX = this.NeckRotX; + this.BodypieceNeck[1].rotateAngleX = this.NeckRotX; + this.BodypieceNeck[2].rotateAngleX = this.NeckRotX; + this.BodypieceNeck[3].rotateAngleX = this.NeckRotX; + } + + protected void initLegPositions(float yOffset, float stretch) { + this.bipedRightArm.addBox(-2.0F + THIRDP_ARM_CENTRE_X, -6.0F + THIRDP_ARM_CENTRE_Y, -2.0F + THIRDP_ARM_CENTRE_Z, + 4, + 12, 4, stretch); + this.bipedRightArm.setRotationPoint(-3.0F, 8.0F + yOffset, 0.0F); + if (bipedRightArmwear != null) { + this.bipedRightArmwear.addBox(-2.0F + THIRDP_ARM_CENTRE_X, -6.0F + THIRDP_ARM_CENTRE_Y, + -2.0F + THIRDP_ARM_CENTRE_Z, 4, + 12, 4, stretch + 0.25f); + this.bipedRightArmwear.setRotationPoint(-3.0F, 8.0F + yOffset, 0.0F); + } + this.bipedLeftArm.addBox(-2.0F + THIRDP_ARM_CENTRE_X, -6.0F + THIRDP_ARM_CENTRE_Y, -2.0F + THIRDP_ARM_CENTRE_Z, + 4, + 12, 4, stretch); + this.bipedLeftArm.setRotationPoint(3.0F, 8.0F + yOffset, 0.0F); + if (this.bipedLeftArmwear != null) { + this.bipedLeftArmwear.addBox(-2.0F + THIRDP_ARM_CENTRE_X, -6.0F + THIRDP_ARM_CENTRE_Y, + -2.0F + THIRDP_ARM_CENTRE_Z, 4, + 12, 4, stretch + 0.25f); + this.bipedLeftArmwear.setRotationPoint(3.0F, 8.0F + yOffset, 0.0F); + } + this.bipedRightLeg.addBox(-2.0F + THIRDP_ARM_CENTRE_X, -6.0F + THIRDP_ARM_CENTRE_Y, -2.0F + THIRDP_ARM_CENTRE_Z, + 4, 12, 4, stretch); + this.bipedRightLeg.setRotationPoint(-3.0F, 0.0F + yOffset, 0.0F); + + if (bipedRightLegwear != null) { + this.bipedRightLegwear.addBox(-2.0F + THIRDP_ARM_CENTRE_X, -6.0F + THIRDP_ARM_CENTRE_Y, + -2.0F + THIRDP_ARM_CENTRE_Z, + 4, 12, 4, stretch + 0.25f); + this.bipedRightLegwear.setRotationPoint(-3.0F, 0.0F + yOffset, 0.0F); + + } + + this.bipedLeftLeg.addBox(-2.0F + THIRDP_ARM_CENTRE_X, -6.0F + THIRDP_ARM_CENTRE_Y, -2.0F + THIRDP_ARM_CENTRE_Z, + 4, 12, 4, stretch); + if (this.bipedLeftLegwear != null) { + this.bipedLeftLegwear.addBox(-2.0F + THIRDP_ARM_CENTRE_X, -6.0F + THIRDP_ARM_CENTRE_Y, + -2.0F + THIRDP_ARM_CENTRE_Z, + 4, 12, 4, stretch + 0.25f); + } + this.SteveArm.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, stretch); + this.SteveArm.setRotationPoint(-5.0F, 2.0F + yOffset, 0.0F); + this.unicornarm.addBox(-2.0F + FIRSTP_ARM_CENTRE_X, -6.0F + FIRSTP_ARM_CENTRE_Y, -2.0F + FIRSTP_ARM_CENTRE_Z, 4, + 12, 4, stretch + .25f); + this.unicornarm.setRotationPoint(-5.0F, 2.0F + yOffset, 0.0F); + } + + protected void initTailPositions(float yOffset, float stretch) { + this.Tail[0].addTopPlane(-2.0F, 1.0F, 2.0F, 4, 0, 4, stretch); + this.Tail[0].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[1].addSidePlane(-2.0F, 1.0F, 2.0F, 0, 4, 4, stretch); + this.Tail[1].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[2].addBackPlane(-2.0F, 1.0F, 2.0F, 4, 4, 0, stretch); + this.Tail[2].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[3].addSidePlane(2.0F, 1.0F, 2.0F, 0, 4, 4, stretch); + this.Tail[3].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[4].addBackPlane(-2.0F, 1.0F, 6.0F, 4, 4, 0, stretch); + this.Tail[4].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[5].addTopPlane(-2.0F, 5.0F, 2.0F, 4, 0, 4, stretch); + this.Tail[5].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[6].addSidePlane(-2.0F, 5.0F, 2.0F, 0, 4, 4, stretch); + this.Tail[6].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[7].addBackPlane(-2.0F, 5.0F, 2.0F, 4, 4, 0, stretch); + this.Tail[7].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[8].addSidePlane(2.0F, 5.0F, 2.0F, 0, 4, 4, stretch); + this.Tail[8].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[9].addBackPlane(-2.0F, 5.0F, 6.0F, 4, 4, 0, stretch); + this.Tail[9].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[10].addTopPlane(-2.0F, 9.0F, 2.0F, 4, 0, 4, stretch); + this.Tail[10].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[11].addSidePlane(-2.0F, 9.0F, 2.0F, 0, 4, 4, stretch); + this.Tail[11].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[12].addBackPlane(-2.0F, 9.0F, 2.0F, 4, 4, 0, stretch); + this.Tail[12].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[13].addSidePlane(2.0F, 9.0F, 2.0F, 0, 4, 4, stretch); + this.Tail[13].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[14].addBackPlane(-2.0F, 9.0F, 6.0F, 4, 4, 0, stretch); + this.Tail[14].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[15].addTopPlane(-2.0F, 13.0F, 2.0F, 4, 0, 4, stretch); + this.Tail[15].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[16].addSidePlane(-2.0F, 13.0F, 2.0F, 0, 4, 4, stretch); + this.Tail[16].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[17].addBackPlane(-2.0F, 13.0F, 2.0F, 4, 4, 0, stretch); + this.Tail[17].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[18].addSidePlane(2.0F, 13.0F, 2.0F, 0, 4, 4, stretch); + this.Tail[18].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[19].addBackPlane(-2.0F, 13.0F, 6.0F, 4, 4, 0, stretch); + this.Tail[19].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + this.Tail[20].addTopPlane(-2.0F, 17.0F, 2.0F, 4, 0, 4, stretch); + this.Tail[20].setRotationPoint(TAIL_RP_X, TAIL_RP_Y + yOffset, TAIL_RP_Z); + } + + protected void initWingPositions(float yOffset, float stretch) { + this.LeftWing[0].addBox(4.0F, 5.0F, 2.0F, 2, 6, 2, stretch); + this.LeftWing[0].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z); + this.LeftWing[0].rotateAngleX = ROTATE_90; + this.LeftWing[1].addBox(4.0F, 5.0F, 4.0F, 2, 8, 2, stretch); + this.LeftWing[1].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z); + this.LeftWing[1].rotateAngleX = ROTATE_90; + this.LeftWing[2].addBox(4.0F, 5.0F, 6.0F, 2, 6, 2, stretch); + this.LeftWing[2].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z); + this.LeftWing[2].rotateAngleX = ROTATE_90; + this.RightWing[0].addBox(-6.0F, 5.0F, 2.0F, 2, 6, 2, stretch); + this.RightWing[0].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z); + this.RightWing[0].rotateAngleX = ROTATE_90; + this.RightWing[1].addBox(-6.0F, 5.0F, 4.0F, 2, 8, 2, stretch); + this.RightWing[1].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z); + this.RightWing[1].rotateAngleX = ROTATE_90; + this.RightWing[2].addBox(-6.0F, 5.0F, 6.0F, 2, 6, 2, stretch); + this.RightWing[2].setRotationPoint(HEAD_RP_X, WING_FOLDED_RP_Y + yOffset, WING_FOLDED_RP_Z); + this.RightWing[2].rotateAngleX = ROTATE_90; + this.LeftWingExt[0].addBox(0.0F, 6.0F, 0.0F, 1, 8, 2, stretch + 0.1F); + this.LeftWingExt[0].setRotationPoint(LEFT_WING_EXT_RP_X, LEFT_WING_EXT_RP_Y + yOffset, + LEFT_WING_EXT_RP_Z); + this.LeftWingExt[1].addBox(0.0F, -1.2F, -0.2F, 1, 8, 2, stretch - 0.2F); + this.LeftWingExt[1].setRotationPoint(LEFT_WING_EXT_RP_X, LEFT_WING_EXT_RP_Y + yOffset, + LEFT_WING_EXT_RP_Z); + this.LeftWingExt[2].addBox(0.0F, 1.8F, 1.3F, 1, 8, 2, stretch - 0.1F); + this.LeftWingExt[2].setRotationPoint(LEFT_WING_EXT_RP_X, LEFT_WING_EXT_RP_Y + yOffset, + LEFT_WING_EXT_RP_Z); + this.LeftWingExt[3].addBox(0.0F, 5.0F, 2.0F, 1, 8, 2, stretch); + this.LeftWingExt[3].setRotationPoint(LEFT_WING_EXT_RP_X, LEFT_WING_EXT_RP_Y + yOffset, + LEFT_WING_EXT_RP_Z); + this.LeftWingExt[4].addBox(0.0F, 0.0F, -0.2F, 1, 6, 2, stretch + 0.3F); + this.LeftWingExt[4].setRotationPoint(LEFT_WING_EXT_RP_X, LEFT_WING_EXT_RP_Y + yOffset, + LEFT_WING_EXT_RP_Z); + this.LeftWingExt[5].addBox(0.0F, 0.0F, 0.2F, 1, 3, 2, stretch + 0.2F); + this.LeftWingExt[5].setRotationPoint(LEFT_WING_EXT_RP_X, LEFT_WING_EXT_RP_Y + yOffset, + LEFT_WING_EXT_RP_Z); + this.RightWingExt[0].addBox(0.0F, 6.0F, 0.0F, 1, 8, 2, stretch + 0.1F); + this.RightWingExt[0].setRotationPoint(RIGHT_WING_EXT_RP_X, RIGHT_WING_EXT_RP_Y + yOffset, + RIGHT_WING_EXT_RP_Z); + this.RightWingExt[1].addBox(0.0F, -1.2F, -0.2F, 1, 8, 2, stretch - 0.2F); + this.RightWingExt[1].setRotationPoint(RIGHT_WING_EXT_RP_X, RIGHT_WING_EXT_RP_Y + yOffset, + RIGHT_WING_EXT_RP_Z); + this.RightWingExt[2].addBox(0.0F, 1.8F, 1.3F, 1, 8, 2, stretch - 0.1F); + this.RightWingExt[2].setRotationPoint(RIGHT_WING_EXT_RP_X, RIGHT_WING_EXT_RP_Y + yOffset, + RIGHT_WING_EXT_RP_Z); + this.RightWingExt[3].addBox(0.0F, 5.0F, 2.0F, 1, 8, 2, stretch); + this.RightWingExt[3].setRotationPoint(RIGHT_WING_EXT_RP_X, RIGHT_WING_EXT_RP_Y + yOffset, + RIGHT_WING_EXT_RP_Z); + this.RightWingExt[4].addBox(0.0F, 0.0F, -0.2F, 1, 6, 2, stretch + 0.3F); + this.RightWingExt[4].setRotationPoint(RIGHT_WING_EXT_RP_X, RIGHT_WING_EXT_RP_Y + yOffset, + RIGHT_WING_EXT_RP_Z); + this.RightWingExt[5].addBox(0.0F, 0.0F, 0.2F, 1, 3, 2, stretch + 0.2F); + this.RightWingExt[5].setRotationPoint(RIGHT_WING_EXT_RP_X, RIGHT_WING_EXT_RP_Y + yOffset, + RIGHT_WING_EXT_RP_Z); + } + + @Override + public void renderDrop(RenderManager rendermanager, ItemRenderer itemrenderer, EntityLivingBase entity) { + + if (!this.isSleeping) { + if (this.isUnicorn && this.glowColor != 0) { + if (this.aimedBow) { + this.renderDrop(itemrenderer, entity, this.unicornarm, 1.0F, 0.15F, 0.9375F, 0.0625F); + } else if (this.size == 0) { + this.renderDrop(itemrenderer, entity, this.unicornarm, 1.0F, 0.35F, 0.5375F, -0.8F); + } else { + this.renderDrop(itemrenderer, entity, this.unicornarm, 1.0F, 0.35F, 0.5375F, -0.45F); + } + } else if (this.size == 0) { + this.renderDrop(itemrenderer, entity, this.bipedRightArm, 1.0F, 0.08F, 0.8375F, 0.0625F); + } else { + this.renderDrop(itemrenderer, entity, this.bipedRightArm, 1.0F, -0.0625F, 0.8375F, 0.0625F); + } + } + } + + @Override + public void renderCloak(EntityPlayer player, float par2) { + pushMatrix(); + translate(0.0F, 0.24F, 0.0F); + if (this.size == 0) { + translate(0.0F, 0.67F, -0.04F); + scale(0.6F, 0.6F, 0.6F); + } else if (this.size == 2) { + translate(0.0F, -0.14F, -0.1F); + scale(1.15F, 1.2F, 1.2F); + if (this.issneak && !this.isFlying) { + translate(0.0F, 0.03F, 0.0F); + } + } else if (this.size == 3) { + translate(0.0F, -0.09F, 0.0F); + scale(1.0F, 1.0F, 1.0F); + if (this.issneak && !this.isFlying) { + translate(0.0F, 0.03F, 0.0F); + } + } + + if (this.issneak && !this.isFlying) { + translate(0.0F, 0.4F, -0.12F); + } + double d = player.prevChasingPosX + (player.chasingPosX - player.prevChasingPosX) * par2 + - (player.prevPosX + (player.posX - player.prevPosX) * par2); + double d1 = player.prevChasingPosY + (player.chasingPosY - player.prevChasingPosY) * par2 + - (player.prevPosY + (player.posY - player.prevPosY) * par2); + double d2 = player.prevChasingPosZ + (player.chasingPosZ - player.prevChasingPosZ) * par2 + - (player.prevPosZ + (player.posZ - player.prevPosZ) * par2); + float f10 = player.prevRenderYawOffset + (player.renderYawOffset - player.prevRenderYawOffset) * par2; + double d3 = MathHelper.sin(f10 * 3.1415927F / 180.0F); + double d4 = (-MathHelper.cos(f10 * 3.1415927F / 180.0F)); + float f12 = (float) d1 * 10.0F; + if (f12 < -6.0F) { + f12 = -6.0F; + } + + if (f12 > 32.0F) { + f12 = 32.0F; + } + + float f13 = (float) (d * d3 + d2 * d4) * 100.0F; + float f14 = (float) (d * d4 - d2 * d3) * 100.0F; + if (f13 < 0.0F) { + f13 = 0.0F; + } + + float f15 = player.prevCameraYaw + (player.cameraYaw - player.prevCameraYaw) * par2; + f12 += MathHelper.sin((player.prevDistanceWalkedModified + + (player.distanceWalkedModified - player.prevDistanceWalkedModified) * par2) * 6.0F) * 32.0F * f15; + if (player.isSneaking()) { + f12 += 25.0F; + } + + rotate(2.0F + f13 / 12.0F + f12, 1.0F, 0.0F, 0.0F); + rotate(f14 / 2.0F, 0.0F, 0.0F, 1.0F); + rotate(-f14 / 2.0F, 0.0F, 1.0F, 0.0F); + rotate(180.0F, 0.0F, 0.0F, 1.0F); + rotate(90.0F, 1.0F, 0.0F, 0.0F); + this.bipedCape.render(0.0625F); + popMatrix(); + } + + @Override + public void renderStaticCloak(EntityLiving player, float par2) { + pushMatrix(); + translate(0.0F, 0.24F, 0.0F); + if (this.size == 0) { + translate(0.0F, 0.67F, -0.04F); + scale(0.6F, 0.6F, 0.6F); + } else if (this.size == 2) { + translate(0.0F, -0.14F, -0.1F); + scale(1.15F, 1.2F, 1.2F); + if (this.issneak && !this.isFlying) { + translate(0.0F, 0.03F, 0.0F); + } + } else if (this.size == 3) { + translate(0.0F, -0.09F, 0.0F); + scale(1.0F, 1.0F, 1.0F); + if (this.issneak && !this.isFlying) { + translate(0.0F, 0.03F, 0.0F); + } + } + + if (this.issneak && !this.isFlying) { + translate(0.0F, 0.4F, -0.12F); + } + + rotate(3.0F, 1.0F, 0.0F, 0.0F); + rotate(2.0F, 0.0F, 1.0F, 0.0F); + rotate(180.0F, 0.0F, 0.0F, 1.0F); + rotate(90.0F, 1.0F, 0.0F, 0.0F); + this.bipedCape.render(0.0625F); + popMatrix(); + } + + protected void compressWings() { + this.CompressiveLeftWing = new CompressiveRendering(this); + this.CompressiveRightWing = new CompressiveRendering(this); + this.CompressiveLeftWing.addCompressed(this.LeftWing[0]); + this.CompressiveLeftWing.addCompressed(this.LeftWing[1]); + this.CompressiveLeftWing.addCompressed(this.LeftWing[2]); + this.CompressiveRightWing.addCompressed(this.RightWing[0]); + this.CompressiveRightWing.addCompressed(this.RightWing[1]); + this.CompressiveRightWing.addCompressed(this.RightWing[2]); + this.CompressiveLeftWing.addExpanded(this.LeftWingExt[0]); + this.CompressiveLeftWing.addExpanded(this.LeftWingExt[1]); + this.CompressiveLeftWing.addExpanded(this.LeftWingExt[2]); + this.CompressiveLeftWing.addExpanded(this.LeftWingExt[3]); + this.CompressiveLeftWing.addExpanded(this.LeftWingExt[4]); + this.CompressiveLeftWing.addExpanded(this.LeftWingExt[5]); + this.CompressiveRightWing.addExpanded(this.RightWingExt[0]); + this.CompressiveRightWing.addExpanded(this.RightWingExt[1]); + this.CompressiveRightWing.addExpanded(this.RightWingExt[2]); + this.CompressiveRightWing.addExpanded(this.RightWingExt[3]); + this.CompressiveRightWing.addExpanded(this.RightWingExt[4]); + this.CompressiveRightWing.addExpanded(this.RightWingExt[5]); + this.CompressiveLeftWing.setChance(2); + this.CompressiveRightWing.setChance(2); + } + + @Override + public ModelRenderer getRandomModelBox(Random par1Random) { + Object part = this.boxList.get(par1Random.nextInt(this.boxList.size())); + return part instanceof ModelRenderer ? (ModelRenderer) part + : ((CompressiveRendering) part).getARenderer(par1Random); + } + + public void setExtendingWings(boolean isCompressed) { + this.CompressiveLeftWing.setIsCompressed(isCompressed); + this.CompressiveRightWing.setIsCompressed(isCompressed); + } + + public void setHasWings_Compression(boolean pegasus) { + if (pegasus) { + this.CompressiveLeftWing.init_Safe(); + this.CompressiveRightWing.init_Safe(); + } else { + this.CompressiveLeftWing.deInit_Safe(); + this.CompressiveRightWing.deInit_Safe(); + } + } + +} diff --git a/src/main/java/com/minelittlepony/minelp/model/pony/pm_skeletonPony.java b/src/main/java/com/minelittlepony/minelp/model/pony/pm_skeletonPony.java new file mode 100644 index 00000000..922fd608 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/pony/pm_skeletonPony.java @@ -0,0 +1,136 @@ +package com.minelittlepony.minelp.model.pony; + +import static net.minecraft.client.renderer.GlStateManager.*; + +import net.minecraft.util.MathHelper; + +public class pm_skeletonPony extends pm_newPonyAdv { + + public pm_skeletonPony(String texture) { + super(texture); + } + + @Override + protected void rotateLegs(float move, float swing, float tick) { + float rightArmRotateAngleX; + float leftArmRotateAngleX; + float rightLegRotateAngleX; + float leftLegRotateAngleX; + float var8; + float var9; + if (this.isFlying && this.isPegasus) { + if (this.rainboom) { + rightArmRotateAngleX = ROTATE_270; + leftArmRotateAngleX = ROTATE_270; + rightLegRotateAngleX = ROTATE_90; + leftLegRotateAngleX = ROTATE_90; + } else { + rightArmRotateAngleX = MathHelper.sin(0.0F - swing * 0.5F); + leftArmRotateAngleX = MathHelper.sin(0.0F - swing * 0.5F); + rightLegRotateAngleX = MathHelper.sin(swing * 0.5F); + leftLegRotateAngleX = MathHelper.sin(swing * 0.5F); + } + + this.bipedRightArm.rotateAngleY = 0.2F; + this.SteveArm.rotateAngleY = 0.2F; + this.bipedLeftArm.rotateAngleY = -0.2F; + this.bipedRightLeg.rotateAngleY = -0.2F; + this.bipedLeftLeg.rotateAngleY = 0.2F; + } else { + var8 = (float) Math.pow(swing, 16.0D); + this.getClass(); + var9 = 3.1415927F * var8 * 0.5F; + this.getClass(); + float laQuad = 3.1415927F * var8; + this.getClass(); + float rlQuad = 3.1415927F * var8 * 0.2F; + this.getClass(); + float llQuad = 3.1415927F * var8 * -0.4F; + rightArmRotateAngleX = MathHelper.cos(move * 0.6662F + 3.1415927F + var9) * 0.6F * swing; + leftArmRotateAngleX = MathHelper.cos(move * 0.6662F + laQuad) * 0.6F * swing; + rightLegRotateAngleX = MathHelper.cos(move * 0.6662F + rlQuad) * 0.6F * swing; + leftLegRotateAngleX = MathHelper.cos(move * 0.6662F + 3.1415927F + llQuad) * 0.6F * swing; + this.bipedRightArm.rotateAngleY = 0.0F; + this.SteveArm.rotateAngleY = 0.0F; + this.unicornarm.rotateAngleY = 0.0F; + this.bipedLeftArm.rotateAngleY = 0.0F; + this.bipedRightLeg.rotateAngleY = 0.0F; + this.bipedLeftLeg.rotateAngleY = 0.0F; + } + + this.bipedRightArm.rotateAngleX = rightArmRotateAngleX; + this.SteveArm.rotateAngleX = rightArmRotateAngleX; + this.unicornarm.rotateAngleX = rightArmRotateAngleX; + this.bipedLeftArm.rotateAngleX = leftArmRotateAngleX; + this.bipedRightLeg.rotateAngleX = rightLegRotateAngleX; + this.bipedLeftLeg.rotateAngleX = leftLegRotateAngleX; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.SteveArm.rotateAngleZ = 0.0F; + this.unicornarm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + if (this.heldItemRight != 0) { + var8 = MathHelper.sin(this.swingProgress * 3.1415927F); + var9 = MathHelper.sin((1.0F - (1.0F - this.swingProgress) * (1.0F - this.swingProgress)) * 3.1415927F); + if (this.glowColor == 0) { + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedRightArm.rotateAngleY = 0.1F - var8 * 0.6F; + this.bipedRightArm.rotateAngleX = -1.5707964F; + this.bipedRightArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.bipedRightArm.rotateAngleZ += MathHelper.cos(tick * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(tick * 0.067F) * 0.1F; + } else { + this.unicornarm.rotationPointX = -7.0F; + this.unicornarm.rotationPointY = 12.0F; + this.unicornarm.rotationPointZ = -2.0F; + this.unicornarm.rotateAngleZ = 0.0F; + this.unicornarm.rotateAngleY = 0.1F - var8 * 0.6F; + this.unicornarm.rotateAngleX = -1.5707964F; + this.unicornarm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.unicornarm.rotateAngleZ += MathHelper.cos(tick * 0.09F) * 0.05F + 0.05F; + this.unicornarm.rotateAngleX += MathHelper.sin(tick * 0.067F) * 0.1F; + } + } + + } + + @Override + protected void fixSpecialRotationPoints(float move) { + if (this.heldItemRight != 0 && this.glowColor == 0) { + this.setRotationPoint(this.bipedRightArm, -1.5F, 9.5F, 4.0F); + } + + } + + @Override + protected void renderLegs() { + pushMatrix(); + translate(0.05F, -0.21F, -0.0F); + scale(0.5F, 1.15F, 0.5F); + this.bipedLeftArm.render(this.scale); + popMatrix(); + + pushMatrix(); + if (this.heldItemRight != 0 && this.glowColor == 0) { + translate(-0.1F, 0.3F, 0.1F); + scale(0.5F, 0.5F, 1.2F); + } else { + translate(-0.05F, -0.21F, -0.0F); + scale(0.5F, 1.2F, 0.5F); + } + + this.bipedRightArm.render(this.scale); + popMatrix(); + + pushMatrix(); + translate(0.05F, -0.21F, 0.35F); + scale(0.5F, 1.2F, 0.5F); + this.bipedLeftLeg.render(this.scale); + popMatrix(); + + pushMatrix(); + translate(-0.05F, -0.21F, 0.35F); + scale(0.5F, 1.15F, 0.5F); + this.bipedRightLeg.render(this.scale); + popMatrix(); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/model/pony/pm_zombiePony.java b/src/main/java/com/minelittlepony/minelp/model/pony/pm_zombiePony.java new file mode 100644 index 00000000..2928ebf2 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/model/pony/pm_zombiePony.java @@ -0,0 +1,104 @@ +package com.minelittlepony.minelp.model.pony; + +import com.minelittlepony.minelp.model.pony.pm_newPonyAdv; + +import net.minecraft.util.MathHelper; + +public class pm_zombiePony extends pm_newPonyAdv { + + public pm_zombiePony(String texture) { + super(texture); + } + + @Override + protected void rotateLegs(float move, float swing, float tick) { + float rightArmRotateAngleX; + float leftArmRotateAngleX; + float rightLegRotateAngleX; + float leftLegRotateAngleX; + float var8; + float var9; + if (this.isFlying && this.isPegasus) { + if (this.rainboom) { + rightArmRotateAngleX = ROTATE_270; + leftArmRotateAngleX = ROTATE_270; + rightLegRotateAngleX = ROTATE_90; + leftLegRotateAngleX = ROTATE_90; + } else { + rightArmRotateAngleX = MathHelper.sin(0.0F - swing * 0.5F); + leftArmRotateAngleX = MathHelper.sin(0.0F - swing * 0.5F); + rightLegRotateAngleX = MathHelper.sin(swing * 0.5F); + leftLegRotateAngleX = MathHelper.sin(swing * 0.5F); + } + + this.bipedRightArm.rotateAngleY = 0.2F; + this.SteveArm.rotateAngleY = 0.2F; + this.bipedLeftArm.rotateAngleY = -0.2F; + this.bipedRightLeg.rotateAngleY = -0.2F; + this.bipedLeftLeg.rotateAngleY = 0.2F; + } else { + var8 = (float) Math.pow(swing, 16.0D); + this.getClass(); + var9 = 3.1415927F * var8 * 0.5F; + this.getClass(); + float laQuad = 3.1415927F * var8; + this.getClass(); + float rlQuad = 3.1415927F * var8 * 0.2F; + this.getClass(); + float llQuad = 3.1415927F * var8 * -0.4F; + rightArmRotateAngleX = MathHelper.cos(move * 0.6662F + 3.1415927F + var9) * 0.45F * swing; + leftArmRotateAngleX = MathHelper.cos(move * 0.6662F + laQuad) * 0.45F * swing; + rightLegRotateAngleX = MathHelper.cos(move * 0.6662F + rlQuad) * 0.45F * swing; + leftLegRotateAngleX = MathHelper.cos(move * 0.6662F + 3.1415927F + llQuad) * 0.45F * swing; + this.bipedRightArm.rotateAngleY = 0.0F; + this.SteveArm.rotateAngleY = 0.0F; + this.unicornarm.rotateAngleY = 0.0F; + this.bipedLeftArm.rotateAngleY = 0.0F; + this.bipedRightLeg.rotateAngleY = 0.0F; + this.bipedLeftLeg.rotateAngleY = 0.0F; + } + + this.bipedRightArm.rotateAngleX = rightArmRotateAngleX; + this.SteveArm.rotateAngleX = rightArmRotateAngleX; + this.unicornarm.rotateAngleX = 0.0F; + this.bipedLeftArm.rotateAngleX = leftArmRotateAngleX; + this.bipedRightLeg.rotateAngleX = rightLegRotateAngleX; + this.bipedLeftLeg.rotateAngleX = leftLegRotateAngleX; + this.bipedRightArm.rotateAngleZ = 0.0F; + this.SteveArm.rotateAngleZ = 0.0F; + this.unicornarm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleZ = 0.0F; + if (this.heldItemRight == 0) { + var8 = MathHelper.sin(this.swingProgress * (float) Math.PI); + var9 = MathHelper.sin((1.0F - (1.0F - this.swingProgress) * (1.0F - this.swingProgress)) * (float) Math.PI); + if (MathHelper.sin(move / 20.0F) < 0.0F) { + this.bipedRightArm.rotateAngleZ = 0.0F; + this.bipedRightArm.rotateAngleY = 0.1F - var8 * 0.6F; + this.bipedRightArm.rotateAngleX = -1.5707964F; + this.bipedRightArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.bipedRightArm.rotateAngleZ += MathHelper.cos(tick * 0.09F) * 0.05F + 0.05F; + this.bipedRightArm.rotateAngleX += MathHelper.sin(tick * 0.067F) * 0.1F; + } else { + this.bipedLeftArm.rotateAngleZ = 0.0F; + this.bipedLeftArm.rotateAngleY = -(0.1F - var8 * 0.6F); + this.bipedLeftArm.rotateAngleX = -1.5707964F; + this.bipedLeftArm.rotateAngleX -= var8 * 1.2F - var9 * 0.4F; + this.bipedLeftArm.rotateAngleZ += MathHelper.cos(tick * 0.09F) * 0.05F + 0.05F; + this.bipedLeftArm.rotateAngleX += MathHelper.sin(tick * 0.067F) * 0.1F; + } + } + + } + + @Override + protected void fixSpecialRotationPoints(float move) { + if (this.heldItemRight == 0) { + if (MathHelper.sin(move / 20.0F) < 0.0F) { + this.shiftRotationPoint(this.bipedRightArm, 0.5F, 1.5F, 3.0F); + } else { + this.shiftRotationPoint(this.bipedLeftArm, -0.5F, 1.5F, 3.0F); + } + } + + } +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/AniParams.java b/src/main/java/com/minelittlepony/minelp/renderer/AniParams.java new file mode 100644 index 00000000..cc69d90a --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/AniParams.java @@ -0,0 +1,18 @@ +package com.minelittlepony.minelp.renderer; + +public class AniParams { + + public float move; + public float swing; + public float tick; + public float horz; + public float vert; + + public AniParams(float move, float swing, float tick, float horz, float vert) { + this.move = move; + this.swing = swing; + this.tick = tick; + this.horz = horz; + this.vert = vert; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/CompressiveRendering.java b/src/main/java/com/minelittlepony/minelp/renderer/CompressiveRendering.java new file mode 100644 index 00000000..b6d5e317 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/CompressiveRendering.java @@ -0,0 +1,89 @@ +package com.minelittlepony.minelp.renderer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Random; +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; + +public class CompressiveRendering { + private boolean isCompressed; + private int chance = 1; + private Collection me; + private ArrayList expanded; + private ArrayList compressed; + private ModelBase model; + + public CompressiveRendering(ModelBase model) { + this.model = model; + this.expanded = new ArrayList(1); + this.compressed = new ArrayList(1); + model.boxList.remove(this.compressed); + } + + public void addExpanded(ModelRenderer expanded) { + this.model.boxList.remove(expanded); + this.expanded.add(expanded); + } + + public void addExpanded(ModelRenderer expanded, int weighted) { + this.model.boxList.remove(expanded); + this.expanded.addAll(Collections.nCopies(weighted, expanded)); + } + + public void addCompressed(ModelRenderer compressed) { + this.model.boxList.remove(compressed); + this.compressed.add(compressed); + } + + public void addCompressed(ModelRenderer compressed, int weighted) { + this.model.boxList.remove(compressed); + this.compressed.addAll(Collections.nCopies(weighted, compressed)); + } + + public void setChance(int chance) { + this.chance = chance; + } + + public int getChance() { + return this.chance; + } + + public void init() { + this.me = Collections.nCopies(this.chance, this); + this.model.boxList.addAll(this.me); + } + + public void deInit() { + this.model.boxList.removeAll(this.me); + this.me = null; + } + + public void init_Safe() { + if (this.me == null) { + this.init(); + } + + } + + public void deInit_Safe() { + if (this.me != null) { + this.deInit(); + } + + } + + public void setIsCompressed(boolean isCompressed) { + this.isCompressed = isCompressed; + } + + public boolean getIsCompressed() { + return this.isCompressed; + } + + public ModelRenderer getARenderer(Random rand) { + return this.isCompressed ? (ModelRenderer) this.compressed.get(rand.nextInt(this.compressed.size())) + : (ModelRenderer) this.expanded.get(rand.nextInt(this.expanded.size())); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/HornGlowRenderer.java b/src/main/java/com/minelittlepony/minelp/renderer/HornGlowRenderer.java new file mode 100644 index 00000000..833c7f57 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/HornGlowRenderer.java @@ -0,0 +1,235 @@ +package com.minelittlepony.minelp.renderer; + +import com.minelittlepony.minelp.model.ModelHornGlow; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.TextureOffset; +import net.minecraft.client.renderer.GLAllocation; +import net.minecraft.client.renderer.Tessellator; +import org.lwjgl.opengl.GL11; + +public class HornGlowRenderer { + public float textureWidth; + public float textureHeight; + private int textureOffsetX; + private int textureOffsetY; + public float rotationPointX; + public float rotationPointY; + public float rotationPointZ; + public float rotateAngleX; + public float rotateAngleY; + public float rotateAngleZ; + private boolean compiled; + private int displayList; + public boolean mirror; + public boolean showModel; + public boolean isHidden; + public List cubeList; + public List childModels; + public final String boxName; + private ModelBase baseModel; + + public HornGlowRenderer(ModelBase par1ModelBase, String par2Str) { + this.textureWidth = 64.0F; + this.textureHeight = 32.0F; + this.compiled = false; + this.displayList = 0; + this.mirror = false; + this.showModel = true; + this.isHidden = false; + this.cubeList = new ArrayList(); + this.baseModel = par1ModelBase; + this.boxName = par2Str; + this.setTextureSize(par1ModelBase.textureWidth, par1ModelBase.textureHeight); + } + + public HornGlowRenderer(ModelBase par1ModelBase) { + this(par1ModelBase, (String) null); + } + + public HornGlowRenderer(ModelBase par1ModelBase, int par2, int par3) { + this(par1ModelBase); + this.setTextureOffset(par2, par3); + } + + public void addChild(HornGlowRenderer par1ModelRenderer) { + if (this.childModels == null) { + this.childModels = new ArrayList(); + } + + this.childModels.add(par1ModelRenderer); + } + + public HornGlowRenderer setTextureOffset(int par1, int par2) { + this.textureOffsetX = par1; + this.textureOffsetY = par2; + return this; + } + + public HornGlowRenderer addBox(String par1Str, float par2, float par3, float par4, int par5, int par6, int par7) { + par1Str = this.boxName + "." + par1Str; + TextureOffset var8 = this.baseModel.getTextureOffset(par1Str); + this.setTextureOffset(var8.textureOffsetX, var8.textureOffsetY); + this.cubeList.add((new ModelHornGlow(this, this.textureOffsetX, this.textureOffsetY, par2, par3, par4, par5, + par6, par7, 0.0F)).func_78244_a(par1Str)); + return this; + } + + public HornGlowRenderer addBox(float par1, float par2, float par3, int par4, int par5, int par6) { + this.cubeList.add(new ModelHornGlow(this, this.textureOffsetX, this.textureOffsetY, par1, par2, par3, par4, + par5, par6, 0.0F)); + return this; + } + + public void addBox(float par1, float par2, float par3, int par4, int par5, int par6, float par7) { + this.cubeList.add(new ModelHornGlow(this, this.textureOffsetX, this.textureOffsetY, par1, par2, par3, par4, + par5, par6, par7)); + } + + public void setRotationPoint(float par1, float par2, float par3) { + this.rotationPointX = par1; + this.rotationPointY = par2; + this.rotationPointZ = par3; + } + + public void render(float par1) { + if (!this.isHidden && this.showModel) { + if (!this.compiled) { + this.compileDisplayList(par1); + } + + Iterator var2; + HornGlowRenderer var3; + if (this.rotateAngleX == 0.0F && this.rotateAngleY == 0.0F && this.rotateAngleZ == 0.0F) { + if (this.rotationPointX == 0.0F && this.rotationPointY == 0.0F && this.rotationPointZ == 0.0F) { + GL11.glCallList(this.displayList); + if (this.childModels != null) { + var2 = this.childModels.iterator(); + + while (var2.hasNext()) { + var3 = var2.next(); + var3.render(par1); + } + } + } else { + GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, + this.rotationPointZ * par1); + GL11.glCallList(this.displayList); + if (this.childModels != null) { + var2 = this.childModels.iterator(); + + while (var2.hasNext()) { + var3 = var2.next(); + var3.render(par1); + } + } + + GL11.glTranslatef(-this.rotationPointX * par1, -this.rotationPointY * par1, + -this.rotationPointZ * par1); + } + } else { + GL11.glPushMatrix(); + GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1); + if (this.rotateAngleZ != 0.0F) { + GL11.glRotatef(this.rotateAngleZ * 57.295776F, 0.0F, 0.0F, 1.0F); + } + + if (this.rotateAngleY != 0.0F) { + GL11.glRotatef(this.rotateAngleY * 57.295776F, 0.0F, 1.0F, 0.0F); + } + + if (this.rotateAngleX != 0.0F) { + GL11.glRotatef(this.rotateAngleX * 57.295776F, 1.0F, 0.0F, 0.0F); + } + + GL11.glCallList(this.displayList); + if (this.childModels != null) { + var2 = this.childModels.iterator(); + + while (var2.hasNext()) { + var3 = var2.next(); + var3.render(par1); + } + } + + GL11.glPopMatrix(); + } + } + + } + + public void renderWithRotation(float par1) { + if (!this.isHidden && this.showModel) { + if (!this.compiled) { + this.compileDisplayList(par1); + } + + GL11.glPushMatrix(); + GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1); + if (this.rotateAngleY != 0.0F) { + GL11.glRotatef(this.rotateAngleY * 57.295776F, 0.0F, 1.0F, 0.0F); + } + + if (this.rotateAngleX != 0.0F) { + GL11.glRotatef(this.rotateAngleX * 57.295776F, 1.0F, 0.0F, 0.0F); + } + + if (this.rotateAngleZ != 0.0F) { + GL11.glRotatef(this.rotateAngleZ * 57.295776F, 0.0F, 0.0F, 1.0F); + } + + GL11.glCallList(this.displayList); + GL11.glPopMatrix(); + } + + } + + public void postRender(float par1) { + if (!this.isHidden && this.showModel) { + if (!this.compiled) { + this.compileDisplayList(par1); + } + + if (this.rotateAngleX == 0.0F && this.rotateAngleY == 0.0F && this.rotateAngleZ == 0.0F) { + if (this.rotationPointX != 0.0F || this.rotationPointY != 0.0F || this.rotationPointZ != 0.0F) { + GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, + this.rotationPointZ * par1); + } + } else { + GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1); + if (this.rotateAngleZ != 0.0F) { + GL11.glRotatef(this.rotateAngleZ * 57.295776F, 0.0F, 0.0F, 1.0F); + } + + if (this.rotateAngleY != 0.0F) { + GL11.glRotatef(this.rotateAngleY * 57.295776F, 0.0F, 1.0F, 0.0F); + } + + if (this.rotateAngleX != 0.0F) { + GL11.glRotatef(this.rotateAngleX * 57.295776F, 1.0F, 0.0F, 0.0F); + } + } + } + + } + + private void compileDisplayList(float par1) { + this.displayList = GLAllocation.generateDisplayLists(1); + GL11.glNewList(this.displayList, 4864); + Tessellator var2 = Tessellator.getInstance(); + for (ModelHornGlow var4 : cubeList) { + var4.render(var2, par1); + } + + GL11.glEndList(); + this.compiled = true; + } + + public HornGlowRenderer setTextureSize(int par1, int par2) { + this.textureWidth = par1; + this.textureHeight = par2; + return this; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/IRenderPony.java b/src/main/java/com/minelittlepony/minelp/renderer/IRenderPony.java new file mode 100644 index 00000000..9488cd32 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/IRenderPony.java @@ -0,0 +1,8 @@ +package com.minelittlepony.minelp.renderer; + +import com.minelittlepony.minelp.model.PlayerModel; + +public interface IRenderPony { + + PlayerModel getPony(); +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/PlaneRenderer.java b/src/main/java/com/minelittlepony/minelp/renderer/PlaneRenderer.java new file mode 100644 index 00000000..85d8d7b5 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/PlaneRenderer.java @@ -0,0 +1,444 @@ +package com.minelittlepony.minelp.renderer; + +import static net.minecraft.client.renderer.GlStateManager.*; +import org.lwjgl.opengl.GL11; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.model.PositionTextureVertex; +import net.minecraft.client.model.TexturedQuad; +import net.minecraft.client.renderer.GLAllocation; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; + +public class PlaneRenderer { + public float textureWidth; + public float textureHeight; + private PositionTextureVertex[] corners; + private TexturedQuad[] faces; + private int textureOffsetX; + private int textureOffsetY; + public float rotationPointX; + public float rotationPointY; + public float rotationPointZ; + public float rotateAngleX; + public float rotateAngleY; + public float rotateAngleZ; + public float field_35977_i; + public float field_35975_j; + public float field_35976_k; + public float field_35973_l; + public float field_35974_m; + public float field_35972_n; + private boolean compiled = false; + private int displayList = 0; + public boolean mirror = false; + public boolean mirrory = false; + public boolean mirrorxy = false; + public boolean showModel = true; + public boolean isHidden = false; + + public PlaneRenderer(ModelBase modelbase, int i, int j) { + this.textureOffsetX = i; + this.textureOffsetY = j; + this.textureWidth = modelbase.textureWidth; + this.textureHeight = modelbase.textureHeight; + } + + public void addBackPlane(float f, float f1, float f2, int i, int j, int k) { + this.addBackPlane(f, f1, f2, i, j, k, 0.0F); + } + + public void addSidePlane(float f, float f1, float f2, int i, int j, int k) { + this.addSidePlane(f, f1, f2, i, j, k, 0.0F); + } + + public void addTopPlane(float f, float f1, float f2, int i, int j, int k) { + this.addTopPlane(f, f1, f2, i, j, k, 0.0F); + } + + public void addBottomPlane(float f, float f1, float f2, int i, int j, int k) { + this.addBottomPlane(f, f1, f2, i, j, k, 0.0F); + } + + public void addBackPlane(float f, float f1, float f2, int i, int j, int k, float f3) { + this.field_35977_i = f; + this.field_35975_j = f1; + this.field_35976_k = f2; + this.field_35973_l = f + i; + this.field_35974_m = f1 + j; + this.field_35972_n = f2 + k; + this.corners = new PositionTextureVertex[8]; + this.faces = new TexturedQuad[1]; + float f4 = f + i; + float f5 = f1 + j; + float f6 = f2 + k; + f -= f3; + f1 -= f3; + f2 -= f3; + f4 += f3; + f5 += f3; + f6 += f3; + if (this.mirror) { + float positiontexturevertex = f4; + f4 = f; + f = positiontexturevertex; + } + + PositionTextureVertex positiontexturevertex = new PositionTextureVertex(f, f1, f2, 0.0F, 0.0F); + PositionTextureVertex positiontexturevertex1 = new PositionTextureVertex(f4, f1, f2, 0.0F, 8.0F); + PositionTextureVertex positiontexturevertex2 = new PositionTextureVertex(f4, f5, f2, 8.0F, 8.0F); + PositionTextureVertex positiontexturevertex3 = new PositionTextureVertex(f, f5, f2, 8.0F, 0.0F); + PositionTextureVertex positiontexturevertex4 = new PositionTextureVertex(f, f1, f6, 0.0F, 0.0F); + PositionTextureVertex positiontexturevertex5 = new PositionTextureVertex(f4, f1, f6, 0.0F, 8.0F); + PositionTextureVertex positiontexturevertex6 = new PositionTextureVertex(f4, f5, f6, 8.0F, 8.0F); + PositionTextureVertex positiontexturevertex7 = new PositionTextureVertex(f, f5, f6, 8.0F, 0.0F); + this.corners[0] = positiontexturevertex; + this.corners[1] = positiontexturevertex1; + this.corners[2] = positiontexturevertex2; + this.corners[3] = positiontexturevertex3; + this.corners[4] = positiontexturevertex4; + this.corners[5] = positiontexturevertex5; + this.corners[6] = positiontexturevertex6; + this.corners[7] = positiontexturevertex7; + this.faces[0] = new TexturedQuad( + new PositionTextureVertex[] { + positiontexturevertex1, + positiontexturevertex, + positiontexturevertex3, + positiontexturevertex2 }, + this.textureOffsetX, this.textureOffsetY, + this.textureOffsetX + i, this.textureOffsetY + j, + this.textureWidth, this.textureHeight); + if (this.mirror) { + this.faces[0].flipFace(); + } + + } + + public void addSidePlane(float f, float f1, float f2, int i, int j, int k, float f3) { + this.field_35977_i = f; + this.field_35975_j = f1; + this.field_35976_k = f2; + this.field_35973_l = f + i; + this.field_35974_m = f1 + j; + this.field_35972_n = f2 + k; + this.corners = new PositionTextureVertex[8]; + this.faces = new TexturedQuad[1]; + float f4 = f + i; + float f5 = f1 + j; + float f6 = f2 + k; + f -= f3; + f1 -= f3; + f2 -= f3; + f4 += f3; + f5 += f3; + f6 += f3; + if (this.mirror) { + float positiontexturevertex = f4; + f4 = f; + f = positiontexturevertex; + } + + PositionTextureVertex positiontexturevertex = new PositionTextureVertex(f, f1, f2, 0.0F, 0.0F); + PositionTextureVertex positiontexturevertex1 = new PositionTextureVertex(f4, f1, f2, 0.0F, 8.0F); + PositionTextureVertex positiontexturevertex2 = new PositionTextureVertex(f4, f5, f2, 8.0F, 8.0F); + PositionTextureVertex positiontexturevertex3 = new PositionTextureVertex(f, f5, f2, 8.0F, 0.0F); + PositionTextureVertex positiontexturevertex4 = new PositionTextureVertex(f, f1, f6, 0.0F, 0.0F); + PositionTextureVertex positiontexturevertex5 = new PositionTextureVertex(f4, f1, f6, 0.0F, 8.0F); + PositionTextureVertex positiontexturevertex6 = new PositionTextureVertex(f4, f5, f6, 8.0F, 8.0F); + PositionTextureVertex positiontexturevertex7 = new PositionTextureVertex(f, f5, f6, 8.0F, 0.0F); + this.corners[0] = positiontexturevertex; + this.corners[1] = positiontexturevertex1; + this.corners[2] = positiontexturevertex2; + this.corners[3] = positiontexturevertex3; + this.corners[4] = positiontexturevertex4; + this.corners[5] = positiontexturevertex5; + this.corners[6] = positiontexturevertex6; + this.corners[7] = positiontexturevertex7; + this.faces[0] = new TexturedQuad( + new PositionTextureVertex[] { + positiontexturevertex5, + positiontexturevertex1, + positiontexturevertex2, + positiontexturevertex6 }, + this.textureOffsetX, this.textureOffsetY, + this.textureOffsetX + k, this.textureOffsetY + j, + this.textureWidth, this.textureHeight); + if (this.mirror) { + this.faces[0].flipFace(); + } + + } + + public void addTopPlane(float f, float f1, float f2, int i, int j, int k, float f3) { + this.field_35977_i = f; + this.field_35975_j = f1; + this.field_35976_k = f2; + this.field_35973_l = f + i; + this.field_35974_m = f1 + j; + this.field_35972_n = f2 + k; + this.corners = new PositionTextureVertex[8]; + this.faces = new TexturedQuad[1]; + float f4 = f + i; + float f5 = f1 + j; + float f6 = f2 + k; + f -= f3; + f1 -= f3; + f2 -= f3; + f4 += f3; + f5 += f3; + f6 += f3; + float vertex; + if (this.mirror) { + vertex = f4; + f4 = f; + f = vertex; + } + + if (this.mirrory) { + vertex = f6; + f6 = f2; + f2 = vertex; + } + + if (this.mirrorxy) { + vertex = f6; + f6 = f2; + f2 = vertex; + vertex = f4; + f4 = f; + f = vertex; + } + + PositionTextureVertex positiontexturevertex = new PositionTextureVertex(f, f1, f2, 0.0F, 0.0F); + PositionTextureVertex positiontexturevertex1 = new PositionTextureVertex(f4, f1, f2, 0.0F, 8.0F); + PositionTextureVertex positiontexturevertex2 = new PositionTextureVertex(f4, f5, f2, 8.0F, 8.0F); + PositionTextureVertex positiontexturevertex3 = new PositionTextureVertex(f, f5, f2, 8.0F, 0.0F); + PositionTextureVertex positiontexturevertex4 = new PositionTextureVertex(f, f1, f6, 0.0F, 0.0F); + PositionTextureVertex positiontexturevertex5 = new PositionTextureVertex(f4, f1, f6, 0.0F, 8.0F); + PositionTextureVertex positiontexturevertex6 = new PositionTextureVertex(f4, f5, f6, 8.0F, 8.0F); + PositionTextureVertex positiontexturevertex7 = new PositionTextureVertex(f, f5, f6, 8.0F, 0.0F); + this.corners[0] = positiontexturevertex; + this.corners[1] = positiontexturevertex1; + this.corners[2] = positiontexturevertex2; + this.corners[3] = positiontexturevertex3; + this.corners[4] = positiontexturevertex4; + this.corners[5] = positiontexturevertex5; + this.corners[6] = positiontexturevertex6; + this.corners[7] = positiontexturevertex7; + this.faces[0] = new TexturedQuad( + new PositionTextureVertex[] { + positiontexturevertex5, + positiontexturevertex4, + positiontexturevertex, + positiontexturevertex1 }, + this.textureOffsetX, this.textureOffsetY, + this.textureOffsetX + i, this.textureOffsetY + k, + this.textureWidth, this.textureHeight); + if (this.mirror || this.mirrory) { + this.faces[0].flipFace(); + } + + } + + public void addBottomPlane(float f, float f1, float f2, int i, int j, int k, float f3) { + this.field_35977_i = f; + this.field_35975_j = f1; + this.field_35976_k = f2; + this.field_35973_l = f + i; + this.field_35974_m = f1 + j; + this.field_35972_n = f2 + k; + this.corners = new PositionTextureVertex[8]; + this.faces = new TexturedQuad[1]; + float f4 = f + i; + float f5 = f1 + j; + float f6 = f2 + k; + f -= f3; + f1 -= f3; + f2 -= f3; + f4 += f3; + f5 += f3; + f6 += f3; + float vertex; + if (this.mirror) { + vertex = f4; + f4 = f; + f = vertex; + } + + if (this.mirrory) { + vertex = f6; + f6 = f2; + f2 = vertex; + } + + if (this.mirrorxy) { + vertex = f6; + f6 = f2; + f2 = vertex; + vertex = f4; + f4 = f; + f = vertex; + } + + PositionTextureVertex positiontexturevertex = new PositionTextureVertex(f, f1, f2, 0.0F, 0.0F); + PositionTextureVertex positiontexturevertex1 = new PositionTextureVertex(f4, f1, f2, 0.0F, 8.0F); + PositionTextureVertex positiontexturevertex2 = new PositionTextureVertex(f4, f5, f2, 8.0F, 8.0F); + PositionTextureVertex positiontexturevertex3 = new PositionTextureVertex(f, f5, f2, 8.0F, 0.0F); + PositionTextureVertex positiontexturevertex4 = new PositionTextureVertex(f, f1, f6, 0.0F, 0.0F); + PositionTextureVertex positiontexturevertex5 = new PositionTextureVertex(f4, f1, f6, 0.0F, 8.0F); + PositionTextureVertex positiontexturevertex6 = new PositionTextureVertex(f4, f5, f6, 8.0F, 8.0F); + PositionTextureVertex positiontexturevertex7 = new PositionTextureVertex(f, f5, f6, 8.0F, 0.0F); + this.corners[0] = positiontexturevertex; + this.corners[1] = positiontexturevertex1; + this.corners[2] = positiontexturevertex2; + this.corners[3] = positiontexturevertex3; + this.corners[4] = positiontexturevertex4; + this.corners[5] = positiontexturevertex5; + this.corners[6] = positiontexturevertex6; + this.corners[7] = positiontexturevertex7; + this.faces[0] = new TexturedQuad( + new PositionTextureVertex[] { + positiontexturevertex2, + positiontexturevertex3, + positiontexturevertex7, + positiontexturevertex6 }, + this.textureOffsetX, this.textureOffsetY, + this.textureOffsetX + i, this.textureOffsetY + k, + this.textureWidth, this.textureHeight); + if (this.mirror || this.mirrory) { + this.faces[0].flipFace(); + } + + } + + public void setRotationPoint(float f, float f1, float f2) { + this.rotationPointX = f; + this.rotationPointY = f1; + this.rotationPointZ = f2; + } + + public void render(float f) { + if (!this.isHidden) { + if (this.showModel) { + if (!this.compiled) { + this.compileDisplayList(f); + } + + if (this.rotateAngleX == 0.0F && this.rotateAngleY == 0.0F && this.rotateAngleZ == 0.0F) { + if (this.rotationPointX == 0.0F && this.rotationPointY == 0.0F && this.rotationPointZ == 0.0F) { + callList(this.displayList); + } else { + translate(this.rotationPointX * f, this.rotationPointY * f, this.rotationPointZ * f); + callList(this.displayList); + translate(-this.rotationPointX * f, -this.rotationPointY * f, -this.rotationPointZ * f); + } + } else { + pushMatrix(); + translate(this.rotationPointX * f, this.rotationPointY * f, this.rotationPointZ * f); + if (this.rotateAngleZ != 0.0F) { + rotate(this.rotateAngleZ * 57.29578F, 0.0F, 0.0F, 1.0F); + } + + if (this.rotateAngleY != 0.0F) { + rotate(this.rotateAngleY * 57.29578F, 0.0F, 1.0F, 0.0F); + } + + if (this.rotateAngleX != 0.0F) { + rotate(this.rotateAngleX * 57.29578F, 1.0F, 0.0F, 0.0F); + } + + callList(this.displayList); + popMatrix(); + } + + } + } + } + + public void renderWithRotation(float f) { + if (!this.isHidden) { + if (this.showModel) { + if (!this.compiled) { + this.compileDisplayList(f); + } + + pushMatrix(); + translate(this.rotationPointX * f, this.rotationPointY * f, this.rotationPointZ * f); + if (this.rotateAngleY != 0.0F) { + rotate(this.rotateAngleY * 57.29578F, 0.0F, 1.0F, 0.0F); + } + + if (this.rotateAngleX != 0.0F) { + rotate(this.rotateAngleX * 57.29578F, 1.0F, 0.0F, 0.0F); + } + + if (this.rotateAngleZ != 0.0F) { + rotate(this.rotateAngleZ * 57.29578F, 0.0F, 0.0F, 1.0F); + } + + callList(this.displayList); + popMatrix(); + } + } + } + + public void postRender(float f) { + if (!this.isHidden) { + if (this.showModel) { + if (!this.compiled) { + this.compileDisplayList(f); + } + + if (this.rotateAngleX == 0.0F && this.rotateAngleY == 0.0F && this.rotateAngleZ == 0.0F) { + if (this.rotationPointX != 0.0F || this.rotationPointY != 0.0F || this.rotationPointZ != 0.0F) { + translate(this.rotationPointX * f, this.rotationPointY * f, this.rotationPointZ * f); + } + } else { + translate(this.rotationPointX * f, this.rotationPointY * f, this.rotationPointZ * f); + if (this.rotateAngleZ != 0.0F) { + rotate(this.rotateAngleZ * 57.29578F, 0.0F, 0.0F, 1.0F); + } + + if (this.rotateAngleY != 0.0F) { + rotate(this.rotateAngleY * 57.29578F, 0.0F, 1.0F, 0.0F); + } + + if (this.rotateAngleX != 0.0F) { + rotate(this.rotateAngleX * 57.29578F, 1.0F, 0.0F, 0.0F); + } + } + + } + } + } + + private void compileDisplayList(float f) { + this.displayList = GLAllocation.generateDisplayLists(1); + GL11.glNewList(this.displayList, 4864); + WorldRenderer wr = Tessellator.getInstance().getWorldRenderer(); + + for (TexturedQuad face : this.faces) { + face.draw(wr, f); + } + + GL11.glEndList(); + this.compiled = true; + } + + public PlaneRenderer setTextureSize(int i, int j) { + this.textureWidth = i; + this.textureHeight = j; + return this; + } + + public void setToModel(ModelRenderer modelrenderer) { + this.rotationPointX = modelrenderer.rotationPointX; + this.rotationPointY = modelrenderer.rotationPointY; + this.rotationPointZ = modelrenderer.rotationPointZ; + this.rotateAngleX = modelrenderer.rotateAngleX; + this.rotateAngleY = modelrenderer.rotateAngleY; + this.rotateAngleZ = modelrenderer.rotateAngleZ; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/RenderPony.java b/src/main/java/com/minelittlepony/minelp/renderer/RenderPony.java new file mode 100644 index 00000000..5aaf58b8 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/RenderPony.java @@ -0,0 +1,150 @@ +package com.minelittlepony.minelp.renderer; + +import static net.minecraft.client.renderer.GlStateManager.scale; + +import com.minelittlepony.minelp.Pony; +import com.minelittlepony.minelp.PonyManager; +import com.minelittlepony.minelp.model.PMAPI; +import com.minelittlepony.minelp.model.PlayerModel; +import com.minelittlepony.minelp.model.pony.pm_Human; +import com.minelittlepony.minelp.model.pony.pm_newPonyAdv; +import com.minelittlepony.minelp.renderer.layer.LayerHeldPonyItem; +import com.minelittlepony.minelp.renderer.layer.LayerPonyArmor; +import com.minelittlepony.minelp.renderer.layer.LayerPonySkull; +import com.minelittlepony.minelp.util.MineLPPrivateFields; +import com.mumfrey.liteloader.transformers.AppendInsns; +import com.mumfrey.liteloader.transformers.Obfuscated; + +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.entity.RenderPlayer; +import net.minecraft.client.renderer.entity.RendererLivingEntity; +import net.minecraft.client.renderer.entity.layers.LayerArrow; +import net.minecraft.entity.Entity; +import net.minecraft.item.EnumAction; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +public abstract class RenderPony extends RendererLivingEntity implements IRenderPony { + @SuppressWarnings("unused") + private static RenderPlayer __TARGET; + private PlayerModel playerModel; + + private RenderPony(RenderManager renderManager) { + super(renderManager, null, 0.5F); + throw new InstantiationError("Overlay classes must not be instantiated"); + } + + @AppendInsns("") + private void init(RenderManager renderManager, boolean useSmallArms) { + this.playerModel = PMAPI.newPonyAdv; + this.mainModel = this.playerModel.model; + this.shadowSize = this.playerModel.shadowsize; + this.layerRenderers.clear(); + + this.addLayer(new LayerPonyArmor(this)); + this.addLayer(new LayerHeldPonyItem(this)); + this.addLayer(new LayerArrow(this)); + this.addLayer(new LayerPonySkull(this)); + } + + @Obfuscated({ "a", "func_180596_a" }) + public void doRender(AbstractClientPlayer player, double x, double y, double z, float yaw, float partialTicks) { + ItemStack currentItemStack = player.inventory.getCurrentItem(); + Pony thePony = PonyManager.getInstance().getPonyFromResourceRegistry(player); + this.playerModel = this.getModel(player); + this.mainModel = this.playerModel.model; + this.playerModel.armor.modelArmorChestplate.heldItemRight = this.playerModel.armor.modelArmor.heldItemRight = this.playerModel.model.heldItemRight = currentItemStack == null + ? 0 : 1; + if (currentItemStack != null && player.getItemInUseCount() > 0) { + EnumAction yOrigin = currentItemStack.getItemUseAction(); + if (yOrigin == EnumAction.BLOCK) { + this.playerModel.armor.modelArmorChestplate.heldItemRight = this.playerModel.armor.modelArmor.heldItemRight = this.playerModel.model.heldItemRight = 3; + } else if (yOrigin == EnumAction.BOW) { + this.playerModel.armor.modelArmorChestplate.aimedBow = this.playerModel.armor.modelArmor.aimedBow = this.playerModel.model.aimedBow = true; + } + } + + this.playerModel.armor.modelArmorChestplate.issneak = this.playerModel.armor.modelArmor.issneak = this.playerModel.model.issneak = player.isSneaking(); + this.playerModel.armor.modelArmorChestplate.isFlying = this.playerModel.armor.modelArmor.isFlying = this.playerModel.model.isFlying = thePony.isFlying = player.capabilities.isFlying + || thePony.isPegasusFlying(player.posX, player.posY, player.posZ, player.fallDistance, + MineLPPrivateFields.isJumping.get(player).booleanValue(), player.onGround, this.renderManager.worldObj); + this.playerModel.armor.modelArmorChestplate.isPegasus = this.playerModel.armor.modelArmor.isPegasus = this.playerModel.model.isPegasus = thePony + .isPegasus(); + if (this.playerModel.model instanceof pm_newPonyAdv) { + ((pm_newPonyAdv) this.playerModel.model).setHasWings_Compression(thePony.isPegasus()); + } + + this.playerModel.armor.modelArmorChestplate.isUnicorn = this.playerModel.armor.modelArmor.isUnicorn = this.playerModel.model.isUnicorn = thePony.isUnicorn(); + this.playerModel.armor.modelArmorChestplate.isMale = this.playerModel.armor.modelArmor.isMale = this.playerModel.model.isMale = thePony.isMale(); + this.playerModel.armor.modelArmorChestplate.size = this.playerModel.armor.modelArmor.size = this.playerModel.model.size = thePony.size(); + if (PonyManager.getInstance().getShowScale() == 1) { + if (this.playerModel != PMAPI.human) { + if (thePony.size() == 0) { + this.shadowSize = 0.25F; + } else if (thePony.size() == 1) { + this.shadowSize = 0.4F; + } else if (thePony.size() == 2) { + this.shadowSize = 0.45F; + } else if (thePony.size() == 3) { + this.shadowSize = 0.5F; + } else { + this.shadowSize = 0.5F; + } + } else { + this.shadowSize = 0.5F; + } + } else { + this.shadowSize = 0.5F; + } + + double yOrigin1 = y; + if (player.isSneaking() && !(player instanceof EntityPlayerSP)) { + yOrigin1 -= 0.125D; + } + + this.playerModel.model.glowColor = thePony.glowColor(); + this.playerModel.armor.modelArmorChestplate.isSleeping = this.playerModel.armor.modelArmor.isSleeping = this.playerModel.model.isSleeping = player.isPlayerSleeping(); + this.playerModel.armor.modelArmorChestplate.swingProgress = this.playerModel.armor.modelArmor.swingProgress = this.playerModel.model.swingProgress; + this.playerModel.model.wantTail = thePony.wantTail(); + this.playerModel.armor.modelArmorChestplate.isVillager = this.playerModel.armor.modelArmor.isVillager = this.playerModel.model.isVillager = false; + super.doRender(player, x, yOrigin1, z, yaw, partialTicks); + this.playerModel.armor.modelArmorChestplate.aimedBow = this.playerModel.armor.modelArmor.aimedBow = this.playerModel.model.aimedBow = false; + this.playerModel.armor.modelArmorChestplate.issneak = this.playerModel.armor.modelArmor.issneak = this.playerModel.model.issneak = false; + this.playerModel.armor.modelArmorChestplate.heldItemRight = this.playerModel.armor.modelArmor.heldItemRight = this.playerModel.model.heldItemRight = 0; + } + + @AppendInsns("renderLivingAt") + @Obfuscated({ "a", "func_77039_a" }) + public void setupPlayerScale(AbstractClientPlayer player, double xPosition, double yPosition, double zPosition) { + + if (PonyManager.getInstance().getShowScale() == 1 && !(playerModel.model instanceof pm_Human)) { + if (this.playerModel.model.size == 2) { + scale(0.9F, 0.9F, 0.9F); + } else if (this.playerModel.model.size == 1 || this.playerModel.model.size == 0) { + scale(0.8F, 0.8F, 0.8F); + } + } + } + + public ResourceLocation getEntityTexture(AbstractClientPlayer player) { + Pony thePony = PonyManager.getInstance().getPonyFromResourceRegistry(player); + return thePony.getTextureResourceLocation(); + } + + @Override + public ResourceLocation getEntityTexture(Entity entity) { + return this.getEntityTexture((AbstractClientPlayer) entity); + } + + protected PlayerModel getModel(AbstractClientPlayer player) { + Pony thePony = PonyManager.getInstance().getPonyFromResourceRegistry(player); + return thePony.getModel(); + } + + @Override + public PlayerModel getPony() { + return this.playerModel; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/RenderPonyMob.java b/src/main/java/com/minelittlepony/minelp/renderer/RenderPonyMob.java new file mode 100644 index 00000000..e22dee43 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/RenderPonyMob.java @@ -0,0 +1,135 @@ +package com.minelittlepony.minelp.renderer; + +import com.minelittlepony.minelp.PonyManager; +import com.minelittlepony.minelp.model.ModelPony; +import com.minelittlepony.minelp.model.PlayerModel; +import com.minelittlepony.minelp.model.pony.pm_newPonyAdv; +import com.minelittlepony.minelp.renderer.layer.LayerHeldPonyItem; +import com.minelittlepony.minelp.renderer.layer.LayerPonyArmor; +import com.minelittlepony.minelp.renderer.layer.LayerPonySkull; + +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityPigZombie; +import net.minecraft.entity.monster.EntitySkeleton; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +public abstract class RenderPonyMob extends RenderLiving implements IRenderPony { + protected ModelPony mobModel; + protected PlayerModel playerModel; + + public RenderPonyMob(RenderManager renderManager, PlayerModel playerModel) { + super(renderManager, playerModel.model, playerModel.shadowsize); + this.mobModel = playerModel.model; + this.playerModel = playerModel; + + this.addLayer(new LayerPonyArmor(this)); + this.addLayer(new LayerHeldPonyItem(this)); + // this.addLayer(new LayerArrow(this)); + this.addLayer(new LayerPonySkull(this)); + } + + @Override + public void doRender(EntityLiving entity, double xPosition, double yPosition, double zPosition, float yaw, + float partialTicks) { + ItemStack heldItem = entity.getHeldItem(); + this.playerModel.armor.modelArmorChestplate.heldItemRight = this.playerModel.armor.modelArmor.heldItemRight = this.playerModel.model.heldItemRight = heldItem == null + ? 0 : 1; + if (entity.isChild()) { + this.playerModel.armor.modelArmorChestplate.size = this.playerModel.armor.modelArmor.size = this.playerModel.model.size = 0; + } else { + this.playerModel.armor.modelArmorChestplate.size = this.playerModel.armor.modelArmor.size = this.playerModel.model.size = 1; + } + + this.playerModel.armor.modelArmorChestplate.issneak = this.playerModel.armor.modelArmor.issneak = this.playerModel.model.issneak = false; + this.playerModel.armor.modelArmorChestplate.isFlying = this.playerModel.armor.modelArmor.isFlying = this.playerModel.model.isFlying = false; + this.playerModel.armor.modelArmorChestplate.isPegasus = this.playerModel.armor.modelArmor.isPegasus = this.playerModel.model.isPegasus = false; + if (this.playerModel.model instanceof pm_newPonyAdv) { + ((pm_newPonyAdv) this.playerModel.model).setHasWings_Compression(false); + } + + if (entity instanceof EntitySkeleton) { + this.playerModel.armor.modelArmorChestplate.glowColor = this.playerModel.armor.modelArmor.glowColor = this.playerModel.model.glowColor = 0; + switch (entity.getEntityId() % 3) { + case 0: + this.playerModel.armor.modelArmorChestplate.glowColor = this.playerModel.armor.modelArmor.glowColor = this.playerModel.model.glowColor = -10066211; + case 1: + this.playerModel.armor.modelArmorChestplate.isUnicorn = this.playerModel.armor.modelArmor.isUnicorn = this.playerModel.model.isUnicorn = true; + break; + case 2: + this.playerModel.armor.modelArmorChestplate.isUnicorn = this.playerModel.armor.modelArmor.isUnicorn = this.playerModel.model.isUnicorn = false; + } + } else { + this.playerModel.armor.modelArmorChestplate.isUnicorn = this.playerModel.armor.modelArmor.isUnicorn = this.playerModel.model.isUnicorn = false; + } + + if (entity instanceof EntityPigZombie) { + this.playerModel.armor.modelArmorChestplate.isMale = this.playerModel.armor.modelArmor.isMale = this.playerModel.model.isMale = true; + } else { + this.playerModel.armor.modelArmorChestplate.isMale = this.playerModel.armor.modelArmor.isMale = this.playerModel.model.isMale = false; + } + + if (entity instanceof EntitySkeleton) { + this.playerModel.model.wantTail = 4; + } else { + this.playerModel.model.wantTail = 0; + } + + this.playerModel.armor.modelArmorChestplate.isSleeping = this.playerModel.armor.modelArmor.isSleeping = this.playerModel.model.isSleeping = false; + this.playerModel.model.isVillager = false; + if (PonyManager.getInstance().getShowScale() == 1) { + this.shadowSize = 0.4F; + } + + double yOrigin = yPosition; + if (entity.isSneaking()) { + yOrigin -= 0.125D; + } + + super.doRender(entity, xPosition, yOrigin, zPosition, yaw, partialTicks); + this.playerModel.armor.modelArmorChestplate.aimedBow = this.playerModel.armor.modelArmor.aimedBow = this.playerModel.model.aimedBow = false; + this.playerModel.armor.modelArmorChestplate.issneak = this.playerModel.armor.modelArmor.issneak = this.playerModel.model.issneak = false; + this.playerModel.armor.modelArmorChestplate.heldItemRight = this.playerModel.armor.modelArmor.heldItemRight = this.playerModel.model.heldItemRight = 0; + } + + @SuppressWarnings("unchecked") + @Override + public void doRender(Entity entity, double xPosition, double yPosition, double zPosition, float yaw, + float partialTicks) { + this.doRender((T) entity, xPosition, yPosition, zPosition, yaw, partialTicks); + } + + protected abstract ResourceLocation getEntityTexture(T var1); + + @SuppressWarnings("unchecked") + @Override + protected ResourceLocation getEntityTexture(Entity var1) { + return this.getEntityTexture((T) var1); + } + + protected void preRenderCallback(T t, float partick) {} + + @SuppressWarnings("unchecked") + @Override + protected void preRenderCallback(EntityLivingBase entitylivingbaseIn, float partialTickTime) { + preRenderCallback((T) entitylivingbaseIn, partialTickTime); + } + + protected void rotateCorpse(T entity, float xPosition, float yPosition, float zPosition) {} + + @SuppressWarnings("unchecked") + @Override + protected void rotateCorpse(EntityLivingBase entity, float xPosition, float yPosition, float zPosition) { + this.rotateCorpse((T) entity, xPosition, yPosition, zPosition); + super.rotateCorpse(entity, xPosition, yPosition, zPosition); + } + + @Override + public PlayerModel getPony() { + return playerModel; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/RenderPonySkeleton.java b/src/main/java/com/minelittlepony/minelp/renderer/RenderPonySkeleton.java new file mode 100644 index 00000000..5dc9158e --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/RenderPonySkeleton.java @@ -0,0 +1,43 @@ +package com.minelittlepony.minelp.renderer; + +import org.lwjgl.opengl.GL11; + +import com.minelittlepony.minelp.PonyManager; +import com.minelittlepony.minelp.model.PMAPI; + +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.entity.layers.LayerBipedArmor; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntitySkeleton; +import net.minecraft.util.ResourceLocation; + +public class RenderPonySkeleton extends RenderPonyMob { + public RenderPonySkeleton(RenderManager rm) { + super(rm, PMAPI.skeletonPony); + addLayer(new LayerBipedArmor(this) { + @Override + protected void func_177177_a() { + this.field_177189_c = PMAPI.skeletonPony.model; + this.field_177186_d = PMAPI.skeletonPony.model; + } + }); + } + + @Override + protected void preRenderCallback(EntitySkeleton skeleton, float partialTicks) { + if (skeleton.getSkeletonType() == 1) { + GL11.glScalef(1.2F, 1.2F, 1.2F); + } + + } + + protected void a(EntityLivingBase entity, float partialTicks) { + this.preRenderCallback((EntitySkeleton) entity, partialTicks); + } + + @Override + protected ResourceLocation getEntityTexture(EntitySkeleton skeleton) { + return skeleton.getSkeletonType() == 1 ? PonyManager.skeletonWitherPonyResource + : PonyManager.skeletonPonyResource; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/RenderPonyVillager.java b/src/main/java/com/minelittlepony/minelp/renderer/RenderPonyVillager.java new file mode 100644 index 00000000..77ab6a03 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/RenderPonyVillager.java @@ -0,0 +1,41 @@ +package com.minelittlepony.minelp.renderer; + +import org.lwjgl.opengl.GL11; + +import com.minelittlepony.minelp.Pony; +import com.minelittlepony.minelp.PonyManager; +import com.minelittlepony.minelp.model.PMAPI; + +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.passive.EntityVillager; +import net.minecraft.util.ResourceLocation; + +public class RenderPonyVillager extends RenderPonyMob { + + public RenderPonyVillager(RenderManager rm) { + super(rm, PMAPI.newPonyAdv); + } + + @Override + protected void preRenderCallback(EntityVillager villager, float partialTicks) { + if (villager.getGrowingAge() < 0) { + this.mobModel.size = 0; + this.shadowSize = 0.25F; + } else { + this.mobModel.size = 1; + if (PonyManager.getInstance().getShowScale() == 1) { + this.shadowSize = 0.4F; + } else { + this.shadowSize = 0.5F; + } + } + + GL11.glScalef(0.9375F, 0.9375F, 0.9375F); + } + + @Override + protected ResourceLocation getEntityTexture(EntityVillager villager) { + Pony aVillagerPony = PonyManager.getInstance().getPonyFromResourceRegistry(villager); + return aVillagerPony.getTextureResourceLocation(); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/RenderPonyZombie.java b/src/main/java/com/minelittlepony/minelp/renderer/RenderPonyZombie.java new file mode 100644 index 00000000..a02a394b --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/RenderPonyZombie.java @@ -0,0 +1,31 @@ +package com.minelittlepony.minelp.renderer; + +import com.minelittlepony.minelp.PonyManager; +import com.minelittlepony.minelp.model.PMAPI; + +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.monster.EntityPigZombie; +import net.minecraft.entity.monster.EntityZombie; +import net.minecraft.util.ResourceLocation; + +public class RenderPonyZombie extends RenderPonyMob { + + public RenderPonyZombie(RenderManager rendermanager) { + super(rendermanager, PMAPI.zombiePony); + } + + @Override + protected void rotateCorpse(EntityZombie zombie, float xPosition, float yPosition, float zPosition) { + if (zombie.isConverting()) { + yPosition += (float) (Math.cos(zombie.ticksExisted * 3.25D) * 3.141592653589793D * 0.25D); + } + } + + @Override + protected ResourceLocation getEntityTexture(EntityZombie zombie) { + return zombie instanceof EntityPigZombie ? PonyManager.zombiePigmanPonyResource + : (zombie.isVillager() ? PonyManager.zombieVillagerPonyResource + : PonyManager.zombiePonyResource); + } + +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/ScalableModelRenderer.java b/src/main/java/com/minelittlepony/minelp/renderer/ScalableModelRenderer.java new file mode 100644 index 00000000..da628a67 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/ScalableModelRenderer.java @@ -0,0 +1,313 @@ +package com.minelittlepony.minelp.renderer; + +import java.util.ArrayList; +import java.util.List; + +import org.lwjgl.opengl.GL11; + +import com.minelittlepony.minelp.model.ScalableModelBox; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.model.TextureOffset; +import net.minecraft.client.renderer.GLAllocation; +import net.minecraft.client.renderer.Tessellator; + +public class ScalableModelRenderer extends ModelRenderer { + public float textureWidth; + public float textureHeight; + private int textureOffsetX; + private int textureOffsetY; + public float rotationPointX; + public float rotationPointY; + public float rotationPointZ; + public float rotateAngleX; + public float rotateAngleY; + public float rotateAngleZ; + private boolean compiled; + private int displayList; + public boolean mirror; + public boolean showModel; + public boolean isHidden; + public List cubeList; + public List childModels; + public final String boxName; + private ModelBase baseModel; + public float offsetX; + public float offsetY; + public float offsetZ; + + @SuppressWarnings("unchecked") + public ScalableModelRenderer(ModelBase par1ModelBase, String par2Str) { + super(par1ModelBase); + this.textureWidth = 64.0F; + this.textureHeight = 32.0F; + this.showModel = true; + this.cubeList = new ArrayList(); + this.baseModel = par1ModelBase; + par1ModelBase.boxList.add(this); + this.boxName = par2Str; + this.setTextureSize(par1ModelBase.textureWidth, par1ModelBase.textureHeight); + } + + public ScalableModelRenderer(ModelBase par1ModelBase) { + this(par1ModelBase, (String) null); + } + + public ScalableModelRenderer(ModelBase par1ModelBase, int par2, int par3) { + this(par1ModelBase); + this.setTextureOffset(par2, par3); + } + + public void addChild(ScalableModelRenderer par1ModelRenderer) { + if (this.childModels == null) { + this.childModels = new ArrayList(); + } + + this.childModels.add(par1ModelRenderer); + } + + @Override + public ScalableModelRenderer setTextureOffset(int par1, int par2) { + this.textureOffsetX = par1; + this.textureOffsetY = par2; + return this; + } + + @Override + public ScalableModelRenderer addBox(String par1Str, float par2, float par3, float par4, int par5, int par6, + int par7) { + par1Str = this.boxName + "." + par1Str; + TextureOffset var8 = this.baseModel.getTextureOffset(par1Str); + this.setTextureOffset(var8.textureOffsetX, var8.textureOffsetY); + this.cubeList.add((new ScalableModelBox(this, this.textureOffsetX, this.textureOffsetY, par2, par3, par4, par5, + par6, par7, 0.0F)).func_78244_a(par1Str)); + return this; + } + + @Override + public ScalableModelRenderer addBox(float par1, float par2, float par3, int par4, int par5, int par6) { + this.cubeList.add(new ScalableModelBox(this, this.textureOffsetX, this.textureOffsetY, par1, par2, par3, par4, + par5, par6, 0.0F)); + return this; + } + + @Override + public void addBox(float par1, float par2, float par3, int par4, int par5, int par6, float par7) { + this.cubeList.add(new ScalableModelBox(this, this.textureOffsetX, this.textureOffsetY, par1, par2, par3, par4, + par5, par6, par7)); + } + + @Override + public void setRotationPoint(float par1, float par2, float par3) { + this.rotationPointX = par1; + this.rotationPointY = par2; + this.rotationPointZ = par3; + } + + @Override + public void render(float par1) { + if (!this.isHidden && this.showModel) { + if (!this.compiled) { + this.compileDisplayList(par1); + } + + GL11.glTranslatef(this.offsetX, this.offsetY, this.offsetZ); + int var2; + if (this.rotateAngleX == 0.0F && this.rotateAngleY == 0.0F && this.rotateAngleZ == 0.0F) { + if (this.rotationPointX == 0.0F && this.rotationPointY == 0.0F && this.rotationPointZ == 0.0F) { + GL11.glCallList(this.displayList); + if (this.childModels != null) { + for (var2 = 0; var2 < this.childModels.size(); ++var2) { + this.childModels.get(var2).render(par1); + } + } + } else { + GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, + this.rotationPointZ * par1); + GL11.glCallList(this.displayList); + if (this.childModels != null) { + for (var2 = 0; var2 < this.childModels.size(); ++var2) { + this.childModels.get(var2).render(par1); + } + } + + GL11.glTranslatef(-this.rotationPointX * par1, -this.rotationPointY * par1, + -this.rotationPointZ * par1); + } + } else { + GL11.glPushMatrix(); + GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1); + if (this.rotateAngleZ != 0.0F) { + GL11.glRotatef(this.rotateAngleZ * 57.295776F, 0.0F, 0.0F, 1.0F); + } + + if (this.rotateAngleY != 0.0F) { + GL11.glRotatef(this.rotateAngleY * 57.295776F, 0.0F, 1.0F, 0.0F); + } + + if (this.rotateAngleX != 0.0F) { + GL11.glRotatef(this.rotateAngleX * 57.295776F, 1.0F, 0.0F, 0.0F); + } + + GL11.glCallList(this.displayList); + if (this.childModels != null) { + for (var2 = 0; var2 < this.childModels.size(); ++var2) { + this.childModels.get(var2).render(par1); + } + } + + GL11.glPopMatrix(); + } + + GL11.glTranslatef(-this.offsetX, -this.offsetY, -this.offsetZ); + } + + } + + public void render(float par1, float scaleX, float scaleY, float scaleZ) { + if (!this.isHidden && this.showModel) { + if (!this.compiled) { + this.compileDisplayList(par1); + } + + GL11.glTranslatef(this.offsetX, this.offsetY, this.offsetZ); + int var2; + if (this.rotateAngleX == 0.0F && this.rotateAngleY == 0.0F && this.rotateAngleZ == 0.0F) { + if (this.rotationPointX == 0.0F && this.rotationPointY == 0.0F && this.rotationPointZ == 0.0F) { + GL11.glPushMatrix(); + GL11.glScalef(scaleX, scaleY, scaleZ); + GL11.glCallList(this.displayList); + if (this.childModels != null) { + for (var2 = 0; var2 < this.childModels.size(); ++var2) { + this.childModels.get(var2).render(par1); + } + } + + GL11.glPopMatrix(); + } else { + GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, + this.rotationPointZ * par1); + GL11.glPushMatrix(); + GL11.glScalef(scaleX, scaleY, scaleZ); + GL11.glCallList(this.displayList); + if (this.childModels != null) { + for (var2 = 0; var2 < this.childModels.size(); ++var2) { + this.childModels.get(var2).render(par1); + } + } + + GL11.glPopMatrix(); + GL11.glTranslatef(-this.rotationPointX * par1, -this.rotationPointY * par1, + -this.rotationPointZ * par1); + } + } else { + GL11.glPushMatrix(); + GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1); + if (this.rotateAngleZ != 0.0F) { + GL11.glRotatef(this.rotateAngleZ * 57.295776F, 0.0F, 0.0F, 1.0F); + } + + if (this.rotateAngleY != 0.0F) { + GL11.glRotatef(this.rotateAngleY * 57.295776F, 0.0F, 1.0F, 0.0F); + } + + if (this.rotateAngleX != 0.0F) { + GL11.glRotatef(this.rotateAngleX * 57.295776F, 1.0F, 0.0F, 0.0F); + } + + GL11.glPushMatrix(); + GL11.glScalef(scaleX, scaleY, scaleZ); + GL11.glCallList(this.displayList); + if (this.childModels != null) { + for (var2 = 0; var2 < this.childModels.size(); ++var2) { + this.childModels.get(var2).render(par1); + } + } + + GL11.glPopMatrix(); + GL11.glPopMatrix(); + } + + GL11.glTranslatef(-this.offsetX, -this.offsetY, -this.offsetZ); + } + + } + + @Override + public void renderWithRotation(float par1) { + if (!this.isHidden && this.showModel) { + if (!this.compiled) { + this.compileDisplayList(par1); + } + + GL11.glPushMatrix(); + GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1); + if (this.rotateAngleY != 0.0F) { + GL11.glRotatef(this.rotateAngleY * 57.295776F, 0.0F, 1.0F, 0.0F); + } + + if (this.rotateAngleX != 0.0F) { + GL11.glRotatef(this.rotateAngleX * 57.295776F, 1.0F, 0.0F, 0.0F); + } + + if (this.rotateAngleZ != 0.0F) { + GL11.glRotatef(this.rotateAngleZ * 57.295776F, 0.0F, 0.0F, 1.0F); + } + + GL11.glCallList(this.displayList); + GL11.glPopMatrix(); + } + + } + + @Override + public void postRender(float par1) { + if (!this.isHidden && this.showModel) { + if (!this.compiled) { + this.compileDisplayList(par1); + } + + if (this.rotateAngleX == 0.0F && this.rotateAngleY == 0.0F && this.rotateAngleZ == 0.0F) { + if (this.rotationPointX != 0.0F || this.rotationPointY != 0.0F || this.rotationPointZ != 0.0F) { + GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, + this.rotationPointZ * par1); + } + } else { + GL11.glTranslatef(this.rotationPointX * par1, this.rotationPointY * par1, this.rotationPointZ * par1); + if (this.rotateAngleZ != 0.0F) { + GL11.glRotatef(this.rotateAngleZ * 57.295776F, 0.0F, 0.0F, 1.0F); + } + + if (this.rotateAngleY != 0.0F) { + GL11.glRotatef(this.rotateAngleY * 57.295776F, 0.0F, 1.0F, 0.0F); + } + + if (this.rotateAngleX != 0.0F) { + GL11.glRotatef(this.rotateAngleX * 57.295776F, 1.0F, 0.0F, 0.0F); + } + } + } + + } + + private void compileDisplayList(float par1) { + this.displayList = GLAllocation.generateDisplayLists(1); + GL11.glNewList(this.displayList, 4864); + Tessellator var2 = Tessellator.getInstance(); + + for (int var3 = 0; var3 < this.cubeList.size(); ++var3) { + this.cubeList.get(var3).render(var2, par1); + } + + GL11.glEndList(); + this.compiled = true; + } + + @Override + public ScalableModelRenderer setTextureSize(int par1, int par2) { + this.textureWidth = par1; + this.textureHeight = par2; + return this; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/layer/LayerHeldPonyItem.java b/src/main/java/com/minelittlepony/minelp/renderer/layer/LayerHeldPonyItem.java new file mode 100644 index 00000000..0b976c52 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/layer/LayerHeldPonyItem.java @@ -0,0 +1,31 @@ +package com.minelittlepony.minelp.renderer.layer; + +import com.minelittlepony.minelp.model.ModelPony; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.entity.RendererLivingEntity; +import net.minecraft.client.renderer.entity.layers.LayerRenderer; +import net.minecraft.entity.EntityLivingBase; + +public class LayerHeldPonyItem implements LayerRenderer { + + private final RendererLivingEntity livingPonyEntity; + + public LayerHeldPonyItem(RendererLivingEntity livingPony) { + this.livingPonyEntity = livingPony; + } + + @Override + public void doRenderLayer(EntityLivingBase entitylivingbaseIn, float p_177141_2_, float p_177141_3_, + float partialTicks, float p_177141_5_, float p_177141_6_, float p_177141_7_, float scale) { + ModelPony pony = (ModelPony) livingPonyEntity.getMainModel(); + Minecraft mc = Minecraft.getMinecraft(); + pony.renderDrop(mc.getRenderManager(), mc.getItemRenderer(), entitylivingbaseIn); + } + + @Override + public boolean shouldCombineTextures() { + return false; + } + +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/layer/LayerPonyArmor.java b/src/main/java/com/minelittlepony/minelp/renderer/layer/LayerPonyArmor.java new file mode 100644 index 00000000..dbee2f40 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/layer/LayerPonyArmor.java @@ -0,0 +1,295 @@ +package com.minelittlepony.minelp.renderer.layer; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Map; + +import com.google.common.collect.Maps; +import com.minelittlepony.minelp.PonyManager; +import com.minelittlepony.minelp.model.ModelPony; +import com.minelittlepony.minelp.model.PlayerModel; +import com.minelittlepony.minelp.model.pony.pm_Human; +import com.minelittlepony.minelp.model.pony.pm_newPonyAdv; +import com.minelittlepony.minelp.model.pony.armor.pm_newPonyArmor; +import com.minelittlepony.minelp.renderer.IRenderPony; +import com.minelittlepony.minelp.util.MineLPReflection; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.entity.RendererLivingEntity; +import net.minecraft.client.renderer.entity.layers.LayerBipedArmor; +import net.minecraft.client.renderer.entity.layers.LayerRenderer; +import net.minecraft.client.renderer.texture.TextureUtil; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemArmor.ArmorMaterial; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; + +public class LayerPonyArmor implements LayerRenderer { + + private static final ResourceLocation ENCHANTED_ITEM_GLINT_RES = new ResourceLocation( + "textures/misc/enchanted_item_glint.png"); + + private static final Map field_110859_k = Maps.newHashMap(); + private static final Map ponyArmorMap = Maps.newHashMap(); + private static final Map onlyPonyArmorMap = Maps.newHashMap(); + private static final String[] bipedArmorFilenamePrefix = { "leather", "chainmail", "iron", "gold", "diamond" }; + + private static HashSet ponyArmors = new HashSet(); + + private RendererLivingEntity renderer; + private LayerBipedArmor humanArmor; + private PlayerModel pony; + + public LayerPonyArmor(RendererLivingEntity entity) { + this.renderer = entity; + this.humanArmor = new LayerBipedArmor(entity); + } + + @Override + public void doRenderLayer(EntityLivingBase entitylivingbaseIn, float p_177141_2_, float p_177141_3_, + float partialTicks, float p_177141_5_, float p_177141_6_, float p_177141_7_, float scale) { + pony = ((IRenderPony) renderer).getPony(); + if (pony.model instanceof pm_Human) { + humanArmor.doRenderLayer(entitylivingbaseIn, p_177141_2_, p_177141_3_, partialTicks, p_177141_5_, + p_177141_6_, p_177141_7_, scale); + } else { + renderArmor(entitylivingbaseIn, p_177141_2_, p_177141_3_, partialTicks, p_177141_5_, p_177141_6_, + p_177141_7_, scale, 4); + renderArmor(entitylivingbaseIn, p_177141_2_, p_177141_3_, partialTicks, p_177141_5_, p_177141_6_, + p_177141_7_, scale, 3); + renderArmor(entitylivingbaseIn, p_177141_2_, p_177141_3_, partialTicks, p_177141_5_, p_177141_6_, + p_177141_7_, scale, 2); + renderArmor(entitylivingbaseIn, p_177141_2_, p_177141_3_, partialTicks, p_177141_5_, p_177141_6_, + p_177141_7_, scale, 1); + } + } + + private void renderArmor(EntityLivingBase entitylivingbaseIn, float p_177141_2_, float p_177141_3_, + float partialTicks, float p_177141_5_, float p_177141_6_, float p_177141_7_, float scale, int armorSlot) { + ItemStack itemstack = entitylivingbaseIn.getCurrentArmor(armorSlot - 1); + + if (itemstack != null && itemstack.getItem() instanceof ItemArmor) { + ItemArmor itemarmor = (ItemArmor) itemstack.getItem(); + + ModelPony modelbase = armorSlot > 2 ? pony.armor.modelArmorChestplate : pony.armor.modelArmor; + modelbase.setModelAttributes(this.renderer.getMainModel()); + modelbase.setLivingAnimations(entitylivingbaseIn, p_177141_2_, p_177141_3_, partialTicks); + prepareToRender((pm_newPonyArmor) modelbase, armorSlot); + this.bindPonyArmorTexture(itemarmor, armorSlot, null); + if (itemarmor.getArmorMaterial() == ArmorMaterial.LEATHER) { + int j = itemarmor.getColor(itemstack); + float f7 = (j >> 16 & 255) / 255.0F; + float f8 = (j >> 8 & 255) / 255.0F; + float f9 = (j & 255) / 255.0F; + GlStateManager.color(f7, f8, f9, 1); + modelbase.render(entitylivingbaseIn, p_177141_2_, p_177141_3_, p_177141_5_, p_177141_6_, p_177141_7_, + scale); + + bindPonyArmorTexture(itemarmor, armorSlot, "overlay"); + } + GlStateManager.color(1, 1, 1, 1); + modelbase.render(entitylivingbaseIn, p_177141_2_, p_177141_3_, p_177141_5_, p_177141_6_, p_177141_7_, + scale); + + if (itemstack.isItemEnchanted()) { + this.renderEnchantment(entitylivingbaseIn, modelbase, p_177141_2_, p_177141_3_, partialTicks, + p_177141_5_, p_177141_6_, p_177141_7_, scale); + } + } + } + + private void prepareToRender(pm_newPonyArmor model, int slot) { + model.setInvisible(false); + + switch (slot) { + // feet + case 1: + model.bipedRightArm.showModel = true; + model.bipedLeftArm.showModel = true; + for (ModelRenderer m : model.extLegs) { + m.showModel = true; + } + model.bipedRightLeg.showModel = true; + model.bipedLeftLeg.showModel = true; + break; + // legs + case 2: + model.bipedRightLeg.showModel = true; + model.bipedLeftLeg.showModel = true; + model.bipedRightArm.showModel = true; + model.bipedLeftArm.showModel = true; + model.Bodypiece.showModel = true; + model.extBody.showModel = true; + model.bipedBody.showModel = true; + break; + // chest + case 3: + model.bipedRightLeg.showModel = true; + model.bipedLeftLeg.showModel = true; + model.bipedRightArm.showModel = true; + model.bipedLeftArm.showModel = true; + model.extBody.showModel = true; + break; + // head + case 4: + model.bipedHead.showModel = true; + for (ModelRenderer m : model.extHead) { + m.showModel = true; + } + } + } + + private void renderEnchantment(EntityLivingBase entitylivingbaseIn, ModelBase modelbaseIn, float p_177183_3_, + float p_177183_4_, float p_177183_5_, float p_177183_6_, float p_177183_7_, float p_177183_8_, + float p_177183_9_) { + float f7 = entitylivingbaseIn.ticksExisted + p_177183_5_; + this.renderer.bindTexture(ENCHANTED_ITEM_GLINT_RES); + GlStateManager.enableBlend(); + GlStateManager.depthFunc(514); + GlStateManager.depthMask(false); + float f8 = 0.5F; + GlStateManager.color(f8, f8, f8, 1.0F); + + for (int i = 0; i < 2; ++i) { + GlStateManager.disableLighting(); + GlStateManager.blendFunc(768, 1); + float f9 = 0.76F; + GlStateManager.color(0.5F * f9, 0.25F * f9, 0.8F * f9, 1.0F); + GlStateManager.matrixMode(5890); + GlStateManager.loadIdentity(); + float f10 = 0.33333334F; + GlStateManager.scale(f10, f10, f10); + GlStateManager.rotate(30.0F - i * 60.0F, 0.0F, 0.0F, 1.0F); + GlStateManager.translate(0.0F, f7 * (0.001F + i * 0.003F) * 20.0F, 0.0F); + GlStateManager.matrixMode(5888); + modelbaseIn.render(entitylivingbaseIn, p_177183_3_, p_177183_4_, p_177183_6_, p_177183_7_, p_177183_8_, + p_177183_9_); + } + + GlStateManager.matrixMode(5890); + GlStateManager.loadIdentity(); + GlStateManager.matrixMode(5888); + GlStateManager.enableLighting(); + GlStateManager.depthMask(true); + GlStateManager.depthFunc(515); + GlStateManager.disableBlend(); + } + + @Override + public boolean shouldCombineTextures() { + return false; + } + + protected boolean bindPonyArmorTexture(ItemArmor armorPiece, int slot, String overlay) { + String overlayText = ""; + if (overlay != null) { + overlayText = String.format("_%s", overlay); + } + + String path = this.pony.armor.path + + bipedArmorFilenamePrefix[armorPiece.getArmorMaterial().ordinal()] + + "_layer_" + this.pony.armor.subimage(slot) + overlayText + ".png"; + if (PonyManager.getInstance().getPonyArmor() == 1 && this.pony.model instanceof pm_newPonyAdv) { + Object[] armorResourceAndState = this.getPonyResourceLocation(path); + renderer.bindTexture((ResourceLocation) armorResourceAndState[0]); + return ((Boolean) armorResourceAndState[1]).booleanValue(); + } else { + // this.a(RenderBiped.func_110858_a(armorPiece., slot, overlay)); + return false; + } + } + + protected boolean bindForgeArmorTexture(Entity playerEntity, ItemStack armorStack, ItemArmor armorPiece, int slot, + String overlay) { + String path = ""; + + try { + path = String.format("textures/models/armor/%s_layer_%d%s.png", + bipedArmorFilenamePrefix[armorPiece.renderIndex], + Integer.valueOf(slot == 2 ? 2 : 1), + overlay == null ? "" : String.format("_%s", overlay)); + } catch (ArrayIndexOutOfBoundsException var10) {} + + path = (String) MineLPReflection.forgeAPI.invokeMethod("ForgeHooksClient.getArmorTexture", (Object) null, + playerEntity, armorStack, path, Integer.valueOf(slot), overlay); + boolean ponyArmor; + if (ponyArmors.contains(path)) { + ponyArmor = this.bindPonyArmorTexture(armorPiece, slot, overlay); + } else { + ponyArmor = false; + ResourceLocation forgeResourceLocation; + if (PonyManager.getInstance().getPonyArmor() == 1 && this.pony.model instanceof pm_newPonyAdv) { + Object[] armorResourceAndState = this.getPonyResourceLocation(path); + forgeResourceLocation = (ResourceLocation) armorResourceAndState[0]; + ponyArmor = ((Boolean) armorResourceAndState[1]).booleanValue(); + } else { + forgeResourceLocation = field_110859_k.get(path); + if (forgeResourceLocation == null) { + forgeResourceLocation = new ResourceLocation(path); + field_110859_k.put(path, forgeResourceLocation); + } + + ponyArmor = false; + } + + renderer.bindTexture(forgeResourceLocation); + } + + return ponyArmor; + } + + protected Object[] getPonyResourceLocation(String path) { + boolean ponyArmor = false; + String ponyPath = path.replace(".png", "_pony.png"); + ResourceLocation ponyResourceLocation = ponyArmorMap.get(path); + if (ponyResourceLocation == null) { + ResourceLocation ponyArmorResource = new ResourceLocation(ponyPath); + + try { + TextureUtil.readImageData(Minecraft.getMinecraft().getResourceManager(), ponyArmorResource); + if (ponyArmorResource != null) { + ponyResourceLocation = ponyArmorResource; + ponyArmorMap.put(path, ponyArmorResource); + onlyPonyArmorMap.put(path, ponyArmorResource); + ponyArmor = true; + } + } catch (IOException var7) { + ponyResourceLocation = field_110859_k.get(path); + if (ponyResourceLocation == null) { + ponyResourceLocation = new ResourceLocation(path); + field_110859_k.put(path, ponyResourceLocation); + } + + ponyArmorMap.put(path, ponyResourceLocation); + ponyArmor = false; + } + } else { + ponyArmor = true; + ponyResourceLocation = onlyPonyArmorMap.get(path); + if (ponyResourceLocation == null) { + ponyResourceLocation = ponyArmorMap.get(path); + ponyArmor = false; + } + } + + return new Object[] { ponyResourceLocation, Boolean.valueOf(ponyArmor) }; + } + + static { + MineLPReflection.preCall(); + + for (int i = 1; i <= 2; ++i) { + for (String prefix : bipedArmorFilenamePrefix) { + ponyArmors.add("textures/models/armor/" + prefix + "_layer_" + i + ".png"); + } + } + + ponyArmors.add("textures/models/armor/leather_layer_1_overlay.png"); + ponyArmors.add("textures/models/armor/leather_layer_2_overlay.png"); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/layer/LayerPonyCape.java b/src/main/java/com/minelittlepony/minelp/renderer/layer/LayerPonyCape.java new file mode 100644 index 00000000..6ece77a3 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/layer/LayerPonyCape.java @@ -0,0 +1,29 @@ +package com.minelittlepony.minelp.renderer.layer; + +import com.minelittlepony.minelp.model.ModelPony; + +import net.minecraft.client.renderer.entity.RendererLivingEntity; +import net.minecraft.client.renderer.entity.layers.LayerRenderer; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; + +public class LayerPonyCape implements LayerRenderer { + + private RendererLivingEntity renderer; + + public LayerPonyCape(RendererLivingEntity entity) { + renderer = entity; + } + + @Override + public void doRenderLayer(EntityLivingBase entitylivingbaseIn, float p_177141_2_, float p_177141_3_, + float partialTicks, float p_177141_5_, float p_177141_6_, float p_177141_7_, float scale) { + ((ModelPony) renderer.getMainModel()).renderCloak((EntityPlayer) entitylivingbaseIn, partialTicks); + } + + @Override + public boolean shouldCombineTextures() { + return false; + } + +} diff --git a/src/main/java/com/minelittlepony/minelp/renderer/layer/LayerPonySkull.java b/src/main/java/com/minelittlepony/minelp/renderer/layer/LayerPonySkull.java new file mode 100644 index 00000000..211a716d --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/renderer/layer/LayerPonySkull.java @@ -0,0 +1,117 @@ +package com.minelittlepony.minelp.renderer.layer; + +import static net.minecraft.client.renderer.GlStateManager.*; + +import com.minelittlepony.minelp.model.ModelPony; +import com.minelittlepony.minelp.model.PlayerModel; +import com.minelittlepony.minelp.model.pony.pm_newPonyAdv; +import com.minelittlepony.minelp.renderer.IRenderPony; +import com.mojang.authlib.GameProfile; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; +import net.minecraft.client.renderer.entity.RendererLivingEntity; +import net.minecraft.client.renderer.entity.layers.LayerRenderer; +import net.minecraft.client.renderer.tileentity.TileEntitySkullRenderer; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityZombie; +import net.minecraft.entity.passive.EntityVillager; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTUtil; +import net.minecraft.tileentity.TileEntitySkull; +import net.minecraft.util.EnumFacing; + +public class LayerPonySkull implements LayerRenderer { + + private RendererLivingEntity renderer; + + public LayerPonySkull(RendererLivingEntity renderPony) { + this.renderer = renderPony; + } + + @Override + public void doRenderLayer(EntityLivingBase entity, float p_177141_2_, float p_177141_3_, + float partialTicks, float p_177141_5_, float p_177141_6_, float p_177141_7_, float scale) { + ItemStack itemstack = entity.getCurrentArmor(3); + if (itemstack != null && itemstack.getItem() != null) { + ModelPony model = getModel().model; + Item item = itemstack.getItem(); + + pushMatrix(); + boolean isVillager = entity instanceof EntityVillager + || entity instanceof EntityZombie && ((EntityZombie) entity).isVillager(); + if (!isVillager && entity.isChild()) { + scale(0.7, 0.7, 0.7); + } + if (model instanceof pm_newPonyAdv) { + if (model.size == 0) { + translate(0.0F, 0.76F, 0.0F); + scale(0.9, 0.9, 0.9); + } + } + model.bipedHead.postRender(0.0625f); + if (model instanceof pm_newPonyAdv) { + translate(0, .2, 0); + } + color(1, 1, 1, 1); + if (item instanceof ItemBlock) { + renderBlock(entity, itemstack, isVillager); + } else if (item == Items.skull) { + if (model instanceof pm_newPonyAdv) { + translate(0, 0, -.15); + } + renderSkull(itemstack, isVillager); + } + popMatrix(); + } + + } + + private void renderBlock(EntityLivingBase entity, ItemStack itemstack, boolean isVillager) { + // translate(0, -0.25, 0); + rotate(180, 0, 1, 0); + scale(0.625, -0.625, -0.625); + translate(0, 0.4, -0.21); + + Minecraft.getMinecraft().getItemRenderer().renderItem(entity, itemstack, TransformType.HEAD); + } + + private void renderSkull(ItemStack itemstack, boolean isVillager) { + float f = 1.1875f; + scale(f, -f, -f); + if (isVillager) { + translate(0, 0.0625, 0); + } + translate(0, 0, -.05f); + GameProfile profile = null; + + if (itemstack.hasTagCompound()) { + NBTTagCompound nbt = itemstack.getTagCompound(); + + if (nbt.hasKey("SkullOwner", 10)) { + profile = NBTUtil.readGameProfileFromNBT(nbt.getCompoundTag("SkullOwner")); + } else if (nbt.hasKey("SkullOwner", 8)) { + profile = TileEntitySkull.updateGameprofile(new GameProfile(null, nbt.getString("SkullOwner"))); + nbt.setTag("SkullOwner", NBTUtil.writeGameProfile(new NBTTagCompound(), profile)); + } + } + + TileEntitySkullRenderer.instance.renderSkull(-0.5F, 0.0F, -0.45F, EnumFacing.UP, 180.0F, + itemstack.getMetadata(), profile, -1); + + } + + private PlayerModel getModel() { + return ((IRenderPony) renderer).getPony(); + } + + @Override + public boolean shouldCombineTextures() { + return true; + } + +} diff --git a/src/main/java/com/minelittlepony/minelp/transformers/RenderPlayerTransformer.java b/src/main/java/com/minelittlepony/minelp/transformers/RenderPlayerTransformer.java new file mode 100644 index 00000000..5d69ee4a --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/transformers/RenderPlayerTransformer.java @@ -0,0 +1,12 @@ +package com.minelittlepony.minelp.transformers; + +import com.mumfrey.liteloader.transformers.ClassOverlayTransformer; + +public class RenderPlayerTransformer extends ClassOverlayTransformer { + + private static final String overlayClassName = "com.minelittlepony.minelp.renderer.RenderPony"; + + public RenderPlayerTransformer() { + super(overlayClassName); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/util/MineLPLogger.java b/src/main/java/com/minelittlepony/minelp/util/MineLPLogger.java new file mode 100644 index 00000000..2ae0c454 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/util/MineLPLogger.java @@ -0,0 +1,75 @@ +package com.minelittlepony.minelp.util; + +import com.mumfrey.liteloader.util.log.LiteLoaderLogger; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class MineLPLogger { + private static Logger logger = LogManager.getLogger("MineLittlePony"); + + public static Logger getLogger() { + return logger; + } + + private static void log(Level level, String format, Object... data) { + logger.log(level, "MineLittlePony> " + String.format(format, data)); + } + + private static void log(Level level, Throwable t, String format, Object... data) { + logger.log(level, "MineLittlePony> " + String.format(format, data), t); + } + + public static void info(String message) { + log(Level.INFO, message, new Object[0]); + } + + public static void info(String message, Object... data) { + log(Level.INFO, message, data); + } + + public static void debug(String message) { + if(LiteLoaderLogger.DEBUG) { + log(Level.INFO, message, new Object[0]); + } + + } + + public static void debug(String message, Object... data) { + if(LiteLoaderLogger.DEBUG) { + log(Level.INFO, message, data); + } + + } + + public static void debug(Throwable t, String message, Object... data) { + if(LiteLoaderLogger.DEBUG) { + log(Level.INFO, message, new Object[]{data, t}); + } + + } + + public static void warn(String message) { + log(Level.WARN, message, new Object[0]); + } + + public static void warn(String message, Object... data) { + log(Level.WARN, message, data); + } + + public static void warn(Throwable t, String message, Object... data) { + log(Level.WARN, t, message, data); + } + + public static void error(String message) { + log(Level.ERROR, message, new Object[0]); + } + + public static void error(String message, Object... data) { + log(Level.ERROR, message, data); + } + + public static void error(Throwable t, String message, Object... data) { + log(Level.ERROR, t, message, data); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/util/MineLPObf.java b/src/main/java/com/minelittlepony/minelp/util/MineLPObf.java new file mode 100644 index 00000000..dcb2075f --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/util/MineLPObf.java @@ -0,0 +1,17 @@ +package com.minelittlepony.minelp.util; + +import com.mumfrey.liteloader.core.runtime.Obf; + +public class MineLPObf extends Obf { + + public static final MineLPObf isJumping = new MineLPObf("field_70703_bu", "aW", "isJumping"); + public static final MineLPObf ARMOR_TEXTURE_RES_MAP = new MineLPObf("field_177191_j", "j", "ARMOR_TEXTURE_RES_MAP"); + + protected MineLPObf(String seargeName, String obfName, String mcpName) { + super(seargeName, obfName, mcpName); + } + + protected MineLPObf(String seargeName, String obfName) { + super(seargeName, obfName, seargeName); + } +} diff --git a/src/main/java/com/minelittlepony/minelp/util/MineLPPrivateFields.java b/src/main/java/com/minelittlepony/minelp/util/MineLPPrivateFields.java new file mode 100644 index 00000000..3eded698 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/util/MineLPPrivateFields.java @@ -0,0 +1,22 @@ +package com.minelittlepony.minelp.util; + +import java.util.Map; + +import com.mumfrey.liteloader.core.runtime.Obf; +import com.mumfrey.liteloader.util.PrivateFields; + +import net.minecraft.client.renderer.entity.layers.LayerArmorBase; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.ResourceLocation; + +public class MineLPPrivateFields extends PrivateFields { + public static final MineLPPrivateFields isJumping = new MineLPPrivateFields( + EntityLivingBase.class, MineLPObf.isJumping); + public static final MineLPPrivateFields> ARMOR_TEXTURE_RES_MAP = new MineLPPrivateFields>( + LayerArmorBase.class, MineLPObf.ARMOR_TEXTURE_RES_MAP); + + protected MineLPPrivateFields(Class

owner, Obf obf) { + super(owner, obf); + } + +} diff --git a/src/main/java/com/minelittlepony/minelp/util/MineLPRData.java b/src/main/java/com/minelittlepony/minelp/util/MineLPRData.java new file mode 100644 index 00000000..8c6ce99a --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/util/MineLPRData.java @@ -0,0 +1,210 @@ +package com.minelittlepony.minelp.util; + +import com.minelittlepony.minelp.util.MineLPLogger; +import com.minelittlepony.minelp.util.MineLPReflection; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class MineLPRData { + public boolean installed = false; + public boolean compatible = false; + public HashMap> classes = new HashMap>(); + public HashMap> constructors = new HashMap>(); + public HashMap methods = new HashMap(); + public HashMap fields = new HashMap(); + public HashMap objects = new HashMap(); + + public Object getInstance(String constructorName, Object... params) { + try { + if (this.constructors.containsKey(constructorName)) { + Constructor e = this.constructors.get(constructorName); + if (params != null && params.length != 0) { + return e.newInstance(params); + } + + return e.newInstance(new Object[0]); + } + + MineLPLogger.error("Unknown requested constructor \"%s\"", new Object[] { constructorName }); + } catch (Exception var4) { + var4.printStackTrace(); + MineLPLogger.error("Error when trying to get constructor \"%s\"", new Object[] { constructorName }); + } + + return null; + } + + public boolean isInstance(String className, Object object) { + return this.getClass(className).isInstance(object); + } + + public Object getField(String fieldName, Object object) { + try { + if (this.fields.containsKey(fieldName)) { + Field e = this.fields.get(fieldName); + return e.get(object); + } + + MineLPLogger.error("Unknown requested field \"%s\"", new Object[] { fieldName }); + } catch (Exception var4) { + var4.printStackTrace(); + MineLPLogger.error("Error when trying to get field \"%s\"", new Object[] { fieldName }); + } + + return null; + } + + public boolean setField(String fieldName, Object object, Object value) { + try { + if (this.fields.containsKey(fieldName)) { + Field e = this.fields.get(fieldName); + e.set(object, value); + return true; + } else { + MineLPLogger.error("Unknown requested field \"%s\"", new Object[] { fieldName }); + return false; + } + } catch (Exception var5) { + var5.printStackTrace(); + MineLPLogger.error("Error when trying to set field \"%s\"", new Object[] { fieldName }); + return false; + } + } + + public Object invokeMethod(String methodName, Object object, Object... params) { + try { + if (this.methods.containsKey(methodName)) { + Method e = this.methods.get(methodName); + return params != null ? e.invoke(object, params) : e.invoke(object, new Object[0]); + } else { + MineLPLogger.error("Unknown requested method \"%s\"", new Object[] { methodName }); + return null; + } + } catch (Exception var5) { + var5.printStackTrace(); + MineLPLogger.error("Method \"%s\" failed to be invoked", new Object[] { methodName }); + MineLPLogger.error( + "Types: " + MineLPReflection.getStringFromTypes(MineLPReflection.getTypesFromObjects(params))); + MineLPLogger.error("Values: " + params.toString()); + return null; + } + } + + public Class getClass(String className) { + return this.classes.containsKey(className) ? (Class) this.classes.get(className) : null; + } + + public Constructor getConstructor(String constructorName) { + return this.constructors.containsKey(constructorName) ? (Constructor) this.constructors.get(constructorName) + : null; + } + + public Method getMethod(String methodName) { + return this.methods.containsKey(methodName) ? (Method) this.methods.get(methodName) : null; + } + + public Field getField(String fieldName) { + return this.fields.containsKey(fieldName) ? (Field) this.fields.get(fieldName) : null; + } + + public Object getObject(String objectName) { + Object object = null; + if (this.objects.containsKey(objectName)) { + object = this.objects.get(objectName); + } + + if (object == null) { + MineLPLogger.error("Object \"%s\" is NULL", new Object[] { objectName }); + } + + return object; + } + + public void putClass(String className, Class clazz) { + this.classes.put(className, clazz); + } + + public void putConstructor(String constructorName, Constructor constructor) { + this.constructors.put(constructorName, constructor); + } + + public void putMethod(String methodName, Method method) { + this.methods.put(methodName, method); + } + + public void putField(String fieldName, Field field) { + this.fields.put(fieldName, field); + } + + public void putObject(String objectName, Object object) { + this.objects.put(objectName, object); + } + + public void removeClass(String className) { + this.classes.remove(className); + } + + public void removeConstructor(String constructorName) { + this.constructors.remove(constructorName); + } + + public void removeMethod(String methodName) { + this.methods.remove(methodName); + } + + public void removeField(String fieldName) { + this.fields.remove(fieldName); + } + + public void removeObject(String objectName) { + this.objects.remove(objectName); + } + + public boolean hasClass(String className) { + return this.classes.containsKey(className); + } + + public boolean hasConstructor(String constructorName) { + return this.constructors.containsKey(constructorName); + } + + public boolean hasMethod(String methodName) { + return this.methods.containsKey(methodName); + } + + public boolean hasField(String fieldName) { + return this.fields.containsKey(fieldName); + } + + public boolean hasObject(String objectName) { + return this.objects.containsKey(objectName); + } + + public boolean removeNullData() { + boolean nullDataPresent = false; + nullDataPresent |= this.removeNullData(this.classes); + nullDataPresent |= this.removeNullData(this.constructors); + nullDataPresent |= this.removeNullData(this.methods); + nullDataPresent |= this.removeNullData(this.fields); + return nullDataPresent; + } + + private boolean removeNullData(Map map) { + // boolean nullDataPresent = false; + Iterator var3 = map.keySet().iterator(); + + while (var3.hasNext()) { + Object key = var3.next(); + if (map.get(key) == null) { + this.constructors.remove(key); + // nullDataPresent = true; + } + } + + return false; + } +} diff --git a/src/main/java/com/minelittlepony/minelp/util/MineLPReflection.java b/src/main/java/com/minelittlepony/minelp/util/MineLPReflection.java new file mode 100644 index 00000000..ac257371 --- /dev/null +++ b/src/main/java/com/minelittlepony/minelp/util/MineLPReflection.java @@ -0,0 +1,508 @@ +package com.minelittlepony.minelp.util; + +import com.minelittlepony.minelp.util.MineLPLogger; +import com.minelittlepony.minelp.util.MineLPRData; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import net.minecraft.client.Minecraft; +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.renderer.RenderGlobal; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.entity.RenderBiped; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.MovingObjectPosition; + +public class MineLPReflection { + public static MineLPRData forgeAPI; + + public static void preCall() {} + + private static boolean reflectForgeAPI(MineLPRData data) { + MineLPLogger.info("Checking ForgeAPI..."); + Class forgeAPIIItemRendererItemRenderType; + Class forgeAPIIItemRendererItemRendererHelper; + Class forgeAPIIItemRenderer; + Class forgeAPIMinecraftForgeClient; + Class forgeAPIForgeHooksClient; + Class[] reflectedForgeAPIClasses = new Class[] { + forgeAPIIItemRendererItemRenderType = getClass( + "net.minecraftforge.client.IItemRenderer$ItemRenderType"), + forgeAPIIItemRendererItemRendererHelper = getClass( + "net.minecraftforge.client.IItemRenderer$ItemRendererHelper"), + forgeAPIIItemRenderer = getClass("net.minecraftforge.client.IItemRenderer"), + forgeAPIMinecraftForgeClient = getClass("net.minecraftforge.client.MinecraftForgeClient"), + forgeAPIForgeHooksClient = getClass("net.minecraftforge.client.ForgeHooksClient"), + getClass("net.minecraft.src.RenderBiped") }; + data.installed = false; + int var9 = reflectedForgeAPIClasses.length; + byte o = 0; + if (o < var9) { + Class enumConstants = reflectedForgeAPIClasses[o]; + if (enumConstants == null) { + return false; + } + + data.installed = true; + } + + data.putClass("ForgeHooksClient", forgeAPIForgeHooksClient); + data.putClass("IItemRenderer", forgeAPIIItemRenderer); + data.putClass("MinecraftForgeClient", forgeAPIMinecraftForgeClient); + data.putClass("IItemRenderer$ItemRenderType", forgeAPIIItemRendererItemRenderType); + data.putClass("IItemRenderer$ItemRendererHelper", forgeAPIIItemRendererItemRendererHelper); + Method m; + data.putMethod("ForgeHooksClient.getArmorModel", m = getMethod(forgeAPIForgeHooksClient, "getArmorModel", + new Class[] { EntityLivingBase.class, ItemStack.class, Integer.TYPE, ModelBiped.class })); + if (m == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Method " + stringMethod(m)); + data.putMethod("ForgeHooksClient.getArmorTexture", + m = getMethod(forgeAPIForgeHooksClient, "getArmorTexture", + new Class[] { Entity.class, ItemStack.class, String.class, Integer.TYPE, String.class })); + if (m == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Method " + stringMethod(m)); + data.putMethod("ForgeHooksClient.orientBedCamera", m = getMethod(forgeAPIForgeHooksClient, + "orientBedCamera", new Class[] { Minecraft.class, EntityLivingBase.class })); + if (m == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Method " + stringMethod(m)); + data.putMethod("ForgeHooksClient.setRenderPass", + m = getMethod(forgeAPIForgeHooksClient, "setRenderPass", new Class[] { Integer.TYPE })); + if (m == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Method " + stringMethod(m)); + data.putMethod("ForgeHooksClient.onDrawBlockHighlight", + m = getMethod(forgeAPIForgeHooksClient, "onDrawBlockHighlight", + new Class[] { RenderGlobal.class, EntityPlayer.class, + MovingObjectPosition.class, Integer.TYPE, ItemStack.class, + Float.TYPE })); + if (m == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Method " + stringMethod(m)); + data.putMethod("ForgeHooksClient.dispatchRenderLast", + m = getMethod(forgeAPIForgeHooksClient, "dispatchRenderLast", + new Class[] { RenderGlobal.class, Float.TYPE })); + if (m == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Method " + stringMethod(m)); + data.putMethod("MinecraftForgeClient.getItemRenderer", + m = getMethod(forgeAPIMinecraftForgeClient, "getItemRenderer", + new Class[] { ItemStack.class, forgeAPIIItemRendererItemRenderType })); + if (m == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Method " + stringMethod(m)); + data.putMethod("IItemRenderer.shouldUseRenderHelper", + m = getMethod(forgeAPIIItemRenderer, "shouldUseRenderHelper", + new Class[] { forgeAPIIItemRendererItemRenderType, ItemStack.class, + forgeAPIIItemRendererItemRendererHelper })); + if (m == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Method " + stringMethod(m)); + data.putMethod("Item.getRenderPasses", m = getMethod(Item.class, + "getRenderPasses", new Class[] { Integer.TYPE })); + if (m == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Method " + stringMethod(m)); + data.putMethod("RenderBiped.getArmorResource", + m = getMethod(RenderBiped.class, "getArmorResource", + new Class[] { Entity.class, ItemStack.class, Integer.TYPE, + String.class })); + if (m == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Method " + stringMethod(m)); + data.putMethod("Entity.canRiderInteract", + m = getMethod(Entity.class, "canRiderInteract", new Class[0])); + if (m == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Method " + stringMethod(m)); + data.putMethod("RenderGlobal.drawBlockDamageTexture", + m = getMethod(RenderGlobal.class, "drawBlockDamageTexture", + new Class[] { Tessellator.class, + EntityLivingBase.class, Float.TYPE })); + if (m == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Method " + stringMethod(m)); + Object[] enumConstants1 = forgeAPIIItemRendererItemRenderType + .getEnumConstants(); + Object o1; + data.putObject("IItemRenderer$ItemRenderType.ENTITY", + o1 = enumConstants1[0]); + if (o1 == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Object " + o1.toString()); + data.putObject("IItemRenderer$ItemRenderType.EQUIPPED", + o1 = enumConstants1[1]); + if (o1 == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Object " + o1.toString()); + data.putObject( + "IItemRenderer$ItemRenderType.EQUIPPED_FIRST_PERSON", + o1 = enumConstants1[2]); + if (o1 == null) { + return false; + } else { + MineLPLogger + .debug("ForgeAPI Object " + o1.toString()); + data.putObject( + "IItemRenderer$ItemRenderType.INVENTORY", + o1 = enumConstants1[3]); + if (o1 == null) { + return false; + } else { + MineLPLogger.debug( + "ForgeAPI Object " + o1.toString()); + data.putObject( + "IItemRenderer$ItemRenderType.FIRST_PERSON_MAP", + o1 = enumConstants1[4]); + if (o1 == null) { + return false; + } else { + MineLPLogger.debug( + "ForgeAPI Object " + o1.toString()); + enumConstants1 = forgeAPIIItemRendererItemRendererHelper + .getEnumConstants(); + data.putObject( + "IItemRenderer$ItemRendererHelper.ENTITY_ROTATION", + o1 = enumConstants1[0]); + if (o1 == null) { + return false; + } else { + MineLPLogger.debug("ForgeAPI Object " + + o1.toString()); + data.putObject( + "IItemRenderer$ItemRendererHelper.ENTITY_BOBBING", + o1 = enumConstants1[1]); + if (o1 == null) { + return false; + } else { + MineLPLogger + .debug("ForgeAPI Object " + + o1.toString()); + data.putObject( + "IItemRenderer$ItemRendererHelper.EQUIPPED_BLOCK", + o1 = enumConstants1[2]); + if (o1 == null) { + return false; + } else { + MineLPLogger.debug( + "ForgeAPI Object " + o1 + .toString()); + data.putObject( + "IItemRenderer$ItemRendererHelper.BLOCK_3D", + o1 = enumConstants1[3]); + if (o1 == null) { + return false; + } else { + MineLPLogger + .debug("ForgeAPI Object " + + o1.toString()); + data.putObject( + "IItemRenderer$ItemRendererHelper.INVENTORY_BLOCK", + o1 = enumConstants1[4]); + if (o1 == null) { + return false; + } else { + MineLPLogger + .debug("ForgeAPI Object " + + o1.toString()); + if (forgeAPI + .removeNullData()) { + MineLPLogger.warn( + "ForgeAPI reflection returned some nulls"); + } + + return true; + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + public static Class getClass(String className) { + try { + return Class.forName(className); + } catch (Exception var2) { + return null; + } + } + + public static Constructor getConstructor(Class clazz, Class... types) { + try { + Constructor e = null; + + try { + if (types != null && types.length != 0) { + e = clazz.getConstructor(types); + } else { + e = clazz.getConstructor(new Class[0]); + } + } catch (Exception var4) { + ; + } + + return e; + } catch (Exception var5) { + MineLPLogger.error("Failed to match Constructor for class \"%s\"", new Object[] { clazz.getName() }); + var5.printStackTrace(); + return null; + } + } + + public static Field getField(Class clazz, String fieldName) { + Object ex = null; + + try { + Field e = null; + + try { + e = clazz.getField(fieldName); + } catch (Exception var5) { + e = null; + } + + if (e == null) { + e = clazz.getDeclaredField(fieldName); + } + + e.setAccessible(true); + return e; + } catch (SecurityException var6) { + ex = var6; + } catch (NoSuchFieldException var7) { + ex = var7; + } catch (Exception var8) { + ex = var8; + } + + if (ex != null) { + MineLPLogger.error("Failed to match Field \"%s\" in %s", new Object[] { fieldName, clazz.getName() }); + ((Exception) ex).printStackTrace(); + } + + return null; + } + + public static Method getMethod(Class clazz, String methodName, Class... types) { + try { + Method e = null; + + try { + e = clazz.getMethod(methodName, types); + } catch (Exception var5) { + ; + } + + if (e == null) { + if (types != null && types.length != 0) { + e = clazz.getDeclaredMethod(methodName, types); + } else { + e = clazz.getDeclaredMethod(methodName, new Class[0]); + } + } + + e.setAccessible(true); + return e; + } catch (Exception var6) { + MineLPLogger.error("Failed to match method \"%s\" in %s", new Object[] { methodName, clazz.getName() }); + MineLPLogger.error("Types: " + getStringFromTypes(types)); + var6.printStackTrace(); + return null; + } + } + + public static String getStringFromTypes(Class... types) { + String temp = ""; + temp = temp + "("; + boolean first = true; + Class[] var3 = types; + int var4 = types.length; + + for (int var5 = 0; var5 < var4; ++var5) { + Class c = var3[var5]; + if (!first) { + temp = temp + ","; + } else { + first = false; + } + + temp = temp + c.getName(); + } + + temp = temp + ")"; + return temp; + } + + public static Class[] getTypesFromObjects(Object... objects) { + Class[] types = new Class[objects.length]; + + for (int i = 0; i < objects.length; ++i) { + types[i] = objects[i].getClass(); + } + + return types; + } + + public static void printClass(Class c) { + printClass(c, true); + } + + public static void printClass(Class c, boolean declared) { + printClass(c, declared, 0); + } + + public static void printClass(Class c, boolean declared, int indent) { + String indentation = ""; + int i; + if (indent > 0) { + char[] lineFormat = new char[indent]; + + for (i = 0; i < indent; ++i) { + lineFormat[i] = 32; + } + + indentation = String.valueOf(lineFormat); + } + + String var10 = indentation + "%03d"; + System.out.println(indentation + c.getName()); + System.out.println(indentation + "Nested Classes:"); + Class[] var6 = c.getClasses(); + int var7 = var6.length; + + int var8; + for (var8 = 0; var8 < var7; ++var8) { + Class f = var6[var8]; + printClass(f, declared, indent + 1); + } + + System.out.println(indentation + "Constructors:"); + i = 0; + Constructor[] var11 = c.getConstructors(); + var7 = var11.length; + + for (var8 = 0; var8 < var7; ++var8) { + Constructor var14 = var11[var8]; + System.out.println( + String.format(var10, new Object[] { Integer.valueOf(i) }) + " " + stringConstructor(var14)); + ++i; + } + + System.out.println(indentation + "Methods:"); + i = 0; + Method[] var12 = c.getMethods(); + var7 = var12.length; + + Method var15; + for (var8 = 0; var8 < var7; ++var8) { + var15 = var12[var8]; + System.out.println(String.format(var10, new Object[] { Integer.valueOf(i) }) + " " + stringMethod(var15)); + ++i; + } + + System.out.println(indentation + "Fields:"); + i = 0; + Field[] var13 = c.getFields(); + var7 = var13.length; + + Field var16; + for (var8 = 0; var8 < var7; ++var8) { + var16 = var13[var8]; + System.out.println(String.format(var10, new Object[] { Integer.valueOf(i) }) + " " + stringField(var16)); + ++i; + } + + if (declared) { + System.out.println(indentation + "Declared Methods:"); + i = 0; + var12 = c.getDeclaredMethods(); + var7 = var12.length; + + for (var8 = 0; var8 < var7; ++var8) { + var15 = var12[var8]; + System.out + .println(String.format(var10, new Object[] { Integer.valueOf(i) }) + " " + stringMethod(var15)); + ++i; + } + + System.out.println(indentation + "Declared Fields:"); + i = 0; + var13 = c.getDeclaredFields(); + var7 = var13.length; + + for (var8 = 0; var8 < var7; ++var8) { + var16 = var13[var8]; + System.out + .println(String.format(var10, new Object[] { Integer.valueOf(i) }) + " " + stringField(var16)); + ++i; + } + } + + } + + public static String stringConstructor(Constructor c) { + return Modifier.toString(c.getModifiers()) + " " + c.getName() + getStringFromTypes(c.getParameterTypes()) + + (c.getExceptionTypes().length > 0 ? " throws " + c.getExceptionTypes() : ""); + } + + public static String stringMethod(Method m) { + return Modifier.toString(m.getModifiers()) + " " + + (m.getReturnType() != null ? m.getReturnType().getName() : "void") + " " + m.getName() + + getStringFromTypes(m.getParameterTypes()) + + (m.getExceptionTypes().length > 0 ? " throws " + getStringFromTypes(m.getExceptionTypes()) : ""); + } + + public static String stringField(Field f) { + return Modifier.toString(f.getModifiers()) + " " + f.getType().getName() + " " + f.getName(); + } + + static { + MineLPLogger.info("Checking compatibilities..."); + forgeAPI = new MineLPRData(); + forgeAPI.compatible = reflectForgeAPI(forgeAPI); + MineLPLogger.info("Compatibility Check Done!"); + if (forgeAPI.installed) { + MineLPLogger.info( + "ForgeAPI " + (forgeAPI.compatible ? "Installed and Compatible" : "Installed but Incompatible")); + } + + } +} diff --git a/src/main/java/com/mumfrey/liteloader/core/LiteLoaderFriend.java b/src/main/java/com/mumfrey/liteloader/core/LiteLoaderFriend.java new file mode 100644 index 00000000..646e5d65 --- /dev/null +++ b/src/main/java/com/mumfrey/liteloader/core/LiteLoaderFriend.java @@ -0,0 +1,12 @@ +package com.mumfrey.liteloader.core; + +import com.mumfrey.liteloader.LiteMod; +import com.mumfrey.liteloader.core.LiteLoader; +import com.mumfrey.liteloader.core.api.LoadableModFileFriend; +import java.io.File; + +public abstract class LiteLoaderFriend { + public static void loadMod(String identifier, Class mod, File jarFile) throws InstantiationException, IllegalAccessException { + LiteLoader.getInstance().mods.loadMod(identifier, mod, LoadableModFileFriend.getLoadableModFile(jarFile)); + } +} diff --git a/src/main/java/com/mumfrey/liteloader/core/api/LoadableModFileFriend.java b/src/main/java/com/mumfrey/liteloader/core/api/LoadableModFileFriend.java new file mode 100644 index 00000000..8b3efe1d --- /dev/null +++ b/src/main/java/com/mumfrey/liteloader/core/api/LoadableModFileFriend.java @@ -0,0 +1,11 @@ +package com.mumfrey.liteloader.core.api; + +import com.mumfrey.liteloader.core.api.LoadableModFile; +import com.mumfrey.liteloader.interfaces.LoadableMod; +import java.io.File; + +public class LoadableModFileFriend { + public static LoadableMod getLoadableModFile(File jarFile) { + return new LoadableModFile(jarFile, (String)null); + } +} diff --git a/src/main/java/com/voxelmodpack/common/VoxelCommonLiteMod.java b/src/main/java/com/voxelmodpack/common/VoxelCommonLiteMod.java new file mode 100644 index 00000000..d156a4a4 --- /dev/null +++ b/src/main/java/com/voxelmodpack/common/VoxelCommonLiteMod.java @@ -0,0 +1,133 @@ +package com.voxelmodpack.common; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; + +import com.google.common.io.ByteSink; +import com.google.common.io.Files; +import com.mumfrey.liteloader.Configurable; +import com.mumfrey.liteloader.LiteMod; +import com.mumfrey.liteloader.core.LiteLoader; +import com.mumfrey.liteloader.core.LiteLoaderFriend; +import com.mumfrey.liteloader.launch.ClassPathUtilities; +import com.mumfrey.liteloader.modconfig.ConfigManager; +import com.mumfrey.liteloader.modconfig.ConfigPanel; +import com.mumfrey.liteloader.util.log.LiteLoaderLogger; + +import net.minecraft.launchwrapper.Launch; + +public abstract class VoxelCommonLiteMod implements LiteMod, Configurable { + private String bundledJarName = "voxelcommon-2.3.1.jar"; + private final String voxelCommonClassName = "com.voxelmodpack.common.LiteModVoxelCommon"; + private final String modClassName; + private LiteMod mod; + + public VoxelCommonLiteMod(String modClassName) { + this.bundledJarName = LiteLoader.getInstance().getModMetaData(this, "voxelCommonJarName", this.bundledJarName); + this.modClassName = modClassName; + } + + @Override + public void init(File configPath) { + try { + this.getClass(); + Class.forName(voxelCommonClassName, false, Launch.class.getClassLoader()); + } catch (Throwable var4) { + this.getClass(); + if (!this.extractAndInjectMod("VoxelLib", voxelCommonClassName, this.bundledJarName, + Files.createTempDir())) { + return; + } + } + + try { + Class th = Class.forName(this.modClassName); + this.mod = (LiteMod) th.newInstance(); + this.mod.init(configPath); + if (this.mod instanceof Configurable && ((Configurable) this.mod).getConfigPanelClass() != null) { + this.registerConfigurable(); + } + + LiteLoader.getInterfaceManager().registerListener(this.mod); + } catch (Throwable var3) { + var3.printStackTrace(); + } + + } + + public void registerConfigurable() + throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + Field configManagerField = LiteLoader.class.getDeclaredField("configManager"); + configManagerField.setAccessible(true); + ConfigManager mgr = (ConfigManager) configManagerField.get(LiteLoader.getInstance()); + mgr.registerMod(this); + } + + @Override + public Class getConfigPanelClass() { + return this.mod != null && this.mod instanceof Configurable ? ((Configurable) this.mod).getConfigPanelClass() + : null; + } + + @Override + public void upgradeSettings(String version, File configPath, File oldConfigPath) { + if (this.mod != null) { + this.mod.upgradeSettings(version, configPath, oldConfigPath); + } + + } + + @SuppressWarnings("unchecked") + private boolean extractAndInjectMod(String libraryName, String className, String resourceName, File libPath) { + if ("true".equals(System.getProperty("VoxelCommon.Injected"))) { + LiteLoaderLogger.warning("%s jar was already injected, skipping injection.", libraryName); + return true; + } else { + File jarFile = new File(libPath, resourceName); + if (!jarFile.exists()) { + LiteLoaderLogger.info("%s jar does not exist, attempting to extract to %s", + libraryName, libPath.getAbsolutePath()); + if (!extractFile("/" + resourceName, jarFile)) { + LiteLoaderLogger.warning("%s jar could not be extracted, %s may not function correctly (or at all)", + libraryName, this.getName()); + return false; + } + } + + if (jarFile.exists()) { + LiteLoaderLogger.info("%s jar exists, attempting to inject into classpath", libraryName); + + try { + ClassPathUtilities.injectIntoClassPath(Launch.classLoader, jarFile.toURI().toURL()); + LiteLoaderFriend.loadMod(libraryName, (Class) Class.forName(className), jarFile); + } catch (Exception var7) { + var7.printStackTrace(); + return false; + } + + System.setProperty("VoxelCommon.Injected", "true"); + LiteLoaderLogger.info("%s jar was successfully extracted", libraryName); + return true; + } else { + LiteLoaderLogger.warning("%s jar was not detected, %s may not function correctly (or at all)", + libraryName, this.getName()); + return false; + } + } + } + + private static boolean extractFile(String resourceName, File outputFile) { + try { + InputStream ex = VoxelCommonLiteMod.class.getResourceAsStream(resourceName); + ByteSink sink = Files.asByteSink(outputFile); + sink.writeFrom(ex); + return true; + } catch (NullPointerException var4) { + return false; + } catch (IOException var5) { + return false; + } + } +} diff --git a/src/main/java/com/voxelmodpack/hdskins/HDPrivateFields.java b/src/main/java/com/voxelmodpack/hdskins/HDPrivateFields.java new file mode 100644 index 00000000..b7a10d3a --- /dev/null +++ b/src/main/java/com/voxelmodpack/hdskins/HDPrivateFields.java @@ -0,0 +1,33 @@ +package com.voxelmodpack.hdskins; + +import java.util.Map; + +import com.google.common.cache.Cache; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; +import com.mumfrey.liteloader.core.runtime.Obf; +import com.mumfrey.liteloader.util.PrivateFields; + +import net.minecraft.client.resources.SkinManager; + +public class HDPrivateFields extends PrivateFields { + + public static PrivateFields>> skinCacheLoader = new HDPrivateFields>>( + SkinManager.class, HDObf.skinLoadingCache); + + protected HDPrivateFields(Class

owner, Obf obf) { + super(owner, obf); + } + + private static class HDObf extends Obf { + private static Obf skinLoadingCache = new HDObf("field_152798_f", "e", "skinCacheLoader"); + + protected HDObf(String seargeName, String obfName, String mcpName) { + super(seargeName, obfName, mcpName); + // TODO Auto-generated constructor stub + } + + } + +} diff --git a/src/main/java/com/voxelmodpack/hdskins/HDSkinDownload.java b/src/main/java/com/voxelmodpack/hdskins/HDSkinDownload.java new file mode 100644 index 00000000..3a117beb --- /dev/null +++ b/src/main/java/com/voxelmodpack/hdskins/HDSkinDownload.java @@ -0,0 +1,70 @@ +package com.voxelmodpack.hdskins; + +import java.awt.image.BufferedImage; +import java.net.HttpURLConnection; +import java.net.Proxy; +import java.net.URL; + +import javax.imageio.ImageIO; + +import com.mumfrey.liteloader.util.log.LiteLoaderLogger; +import com.voxelmodpack.common.runtime.PrivateFields; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.IImageBuffer; +import net.minecraft.client.renderer.ThreadDownloadImageData; + +class HDSkinDownload extends Thread { + private final ThreadDownloadImageData image; + private final IImageBuffer imageBuffer; + private final String skinUrl; + private final Thread originalThread; + + HDSkinDownload(ThreadDownloadImageData image, IImageBuffer imageBuffer, String url) { + this.image = image; + this.imageBuffer = imageBuffer != null ? imageBuffer : (IImageBuffer) PrivateFields.imageBuffer.get(image); + this.originalThread = PrivateFields.imageThread.get(image); + this.skinUrl = url; + } + + @Override + public void run() { + Proxy proxy = Minecraft.getMinecraft().getProxy(); + if (!this.tryDownload(proxy, this.skinUrl) && this.originalThread != null) { + this.originalThread.run(); + } + + } + + boolean tryDownload(Proxy proxy, String strUrl) { + HttpURLConnection httpConnection = null; + + try { + LiteLoaderLogger.debug("Downloading HD Skin from %s", strUrl); + URL ex = new URL(strUrl); + httpConnection = (HttpURLConnection) ex.openConnection(proxy); + httpConnection.addRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"); + httpConnection.setDoInput(true); + httpConnection.setDoOutput(false); + httpConnection.connect(); + if (httpConnection.getResponseCode() / 100 == 2) { + BufferedImage image1 = ImageIO.read(httpConnection.getInputStream()); + if (this.imageBuffer != null) { + image1 = this.imageBuffer.parseUserSkin(image1); + } + + this.image.setBufferedImage(image1); + return true; + } + } catch (Exception var10) { + return false; + } finally { + if (httpConnection != null) { + httpConnection.disconnect(); + } + + } + + return false; + } +} diff --git a/src/main/java/com/voxelmodpack/hdskins/HDSkinManager.java b/src/main/java/com/voxelmodpack/hdskins/HDSkinManager.java new file mode 100644 index 00000000..66145212 --- /dev/null +++ b/src/main/java/com/voxelmodpack/hdskins/HDSkinManager.java @@ -0,0 +1,234 @@ +package com.voxelmodpack.hdskins; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; + +import com.google.common.cache.Cache; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.InsecureTextureException; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; +import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; +import com.mojang.authlib.minecraft.MinecraftSessionService; +import com.mumfrey.liteloader.core.LiteLoader; +import com.mumfrey.liteloader.transformers.event.EventInfo; +import com.mumfrey.liteloader.util.log.LiteLoaderLogger; +import com.voxelmodpack.common.runtime.PrivateFields; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.client.renderer.ThreadDownloadImageData; +import net.minecraft.client.renderer.texture.ITextureObject; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.resources.DefaultPlayerSkin; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.StringUtils; + +public final class HDSkinManager { + private static String gatewayUrl = "skinmanager.voxelmodpack.com"; + private static String skinUrl = "skins.voxelmodpack.com"; + private static Cache> skinsCache; + private static final BiMap playerHashes = HashBiMap.create(); + private static final Map> cachedTextures = new HashMap>(); + + public static void onDownloadSkin(EventInfo e) { + ThreadDownloadImageData imageDownload = e.getSource(); + if (imageDownload != null) { + String imageUrl = PrivateFields.imageUrl.get(imageDownload); + if (imageUrl != null) { + String hash = FilenameUtils.getBaseName(imageUrl); + String uuid = resolvePlayerIdFromHash(hash); + if (uuid == null) { + if (!(imageDownload instanceof PreviewTexture)) { + return; + } + + uuid = Minecraft.getMinecraft().getSession().getPlayerID(); + } + + Map textures = getCachedTexturesForId(uuid); + MinecraftProfileTexture skinTexture = textures.get(Type.SKIN); + if (skinTexture != null && skinTexture.getUrl().equals(imageUrl)) { + Thread imageThread = PrivateFields.imageThread.get(imageDownload); + if (imageThread != null) { + HDSkinDownload hdThread = new HDSkinDownload(imageDownload, new ImageBufferDownloadHD(), + getCustomSkinURLForId(uuid, imageDownload instanceof PreviewTexture)); + PrivateFields.imageThread.set(imageDownload, hdThread); + hdThread.setDaemon(true); + hdThread.start(); + e.cancel(); + } + } else { + LiteLoaderLogger.debug("Not a skin texture!"); + } + } + } + } + + private static String resolvePlayerIdFromHash(String hash) { + Minecraft mc = Minecraft.getMinecraft(); + Collection playersInfo = mc.getNetHandler().func_175106_d(); + String uuid; + // players + for (NetworkPlayerInfo player : playersInfo) { + GameProfile profile = player.getGameProfile(); + Map textures = getTexturesForProfile(mc, profile); + storeTexturesForProfile(profile, textures); + uuid = findUUID(profile, textures, hash); + if (uuid != null) + return uuid; + } + @SuppressWarnings("unchecked") + List players = mc.theWorld.playerEntities; + for (EntityPlayer player : players) { + GameProfile profile = player.getGameProfile(); + Map textures = getTexturesForProfile(mc, profile); + storeTexturesForProfile(profile, textures); + uuid = findUUID(profile, textures, hash); + if (uuid != null) + return uuid; + } + // skulls + for (Entry> e : getSkinsCache().asMap().entrySet()) { + GameProfile profile = e.getKey(); + Map textures = e.getValue(); + storeTexturesForProfile(profile, textures); + uuid = findUUID(profile, textures, hash); + if (uuid != null) + return uuid; + } + + return null; + } + + private static String findUUID(GameProfile profile, Map textures, String hash) { + for (MinecraftProfileTexture texture : textures.values()) { + if (hash.equals(texture.getHash())) { + String uuid = trimUUID(profile.getId()); + playerHashes.put(hash, uuid); + return uuid; + } + } + return null; + } + + private static void storeTexturesForProfile(GameProfile profile, Map textures) { + Map cached = getCachedTexturesForId(trimUUID(profile.getId())); + if (cached == null && textures != null && !textures.isEmpty()) { + LiteLoaderLogger.debug("Store textures for " + profile.getId()); + cachedTextures.put(trimUUID(profile.getId()), textures); + } + } + + private static Map getTexturesForProfile(Minecraft minecraft, GameProfile profile) { + LiteLoaderLogger.debug("Get textures for " + profile.getId(), new Object[0]); + Map cached = getCachedTexturesForId(trimUUID(profile.getId())); + if (cached != null) { + return cached; + } else { + MinecraftSessionService sessionService = minecraft.getSessionService(); + Map textures = null; + + try { + textures = sessionService.getTextures(profile, true); + } catch (InsecureTextureException var6) { + textures = sessionService.getTextures(profile, false); + } + + if ((textures == null || textures.isEmpty()) + && profile.getId().equals(minecraft.getSession().getProfile().getId())) { + textures = sessionService.getTextures(sessionService.fillProfileProperties(profile, false), false); + } + + storeTexturesForProfile(profile, textures); + + return textures; + } + } + + private static Cache> getSkinsCache() { + if (skinsCache == null) { + // final field isn't going to change + skinsCache = HDPrivateFields.skinCacheLoader.get(Minecraft.getMinecraft().getSkinManager()); + } + return skinsCache; + } + + private static Map getCachedTexturesForId(String uuid) { + return cachedTextures.get(uuid); + } + + private static String trimUUID(UUID uuid) { + return uuid.toString().replace("-", ""); + } + + public static void setSkinUrl(String skinUrl) { + HDSkinManager.skinUrl = skinUrl; + } + + public static void setGatewayURL(String gatewayURL) { + gatewayUrl = gatewayURL; + } + + public static String getSkinUrl() { + return String.format("http://%s/", skinUrl); + } + + public static String getGatewayUrl() { + return String.format("http://%s/", gatewayUrl); + } + + public static String getCustomSkinURLForId(String uuid, boolean gateway) { + uuid = StringUtils.stripControlCodes(uuid); + return String.format("http://%s/skins/%s.png", gateway ? gatewayUrl : skinUrl, uuid); + } + + public static String getCustomCloakURLForId(String uuid) { + return String.format("http://%s/capes/%s.png", skinUrl, StringUtils.stripControlCodes(uuid)); + } + + public static PreviewTexture getPreviewTexture(ResourceLocation skinResource, GameProfile profile) { + TextureManager textureManager = Minecraft.getMinecraft().getTextureManager(); + Object skinTexture = textureManager.getTexture(skinResource); + if (skinTexture == null) { + Map textures = getTexturesForProfile(Minecraft.getMinecraft(), profile); + MinecraftProfileTexture skin = textures.get(Type.SKIN); + if (skin == null) { + throw new RuntimeException("Could not get player skin URL from profile"); + } + + String url = skin.getUrl(); + skinTexture = new PreviewTexture(url, DefaultPlayerSkin.getDefaultSkin(profile.getId()), + new ImageBufferDownloadHD()); + textureManager.loadTexture(skinResource, (ITextureObject) skinTexture); + } + + return (PreviewTexture) skinTexture; + } + + public static void clearSkinCache() { + LiteLoaderLogger.info("Clearing local player skin cache", new Object[0]); + + try { + FileUtils.deleteDirectory(new File(LiteLoader.getAssetsDirectory(), "skins")); + } catch (IOException var1) { + var1.printStackTrace(); + } + // clear the maps, too + getSkinsCache().invalidateAll(); + cachedTextures.clear(); + playerHashes.clear(); + + } +} diff --git a/src/main/java/com/voxelmodpack/hdskins/ImageBufferDownloadHD.java b/src/main/java/com/voxelmodpack/hdskins/ImageBufferDownloadHD.java new file mode 100644 index 00000000..53f10f13 --- /dev/null +++ b/src/main/java/com/voxelmodpack/hdskins/ImageBufferDownloadHD.java @@ -0,0 +1,59 @@ +package com.voxelmodpack.hdskins; + +import java.awt.Graphics; +import java.awt.image.BufferedImage; +import java.awt.image.ImageObserver; + +import net.minecraft.client.renderer.IImageBuffer; + +public class ImageBufferDownloadHD implements IImageBuffer { + + private int scale; + private Graphics graphics; + private BufferedImage image; + + @Override + public BufferedImage parseUserSkin(BufferedImage downloadedImage) { + if (downloadedImage == null) { + return null; + } else { + int imageWidth = downloadedImage.getWidth(); + int imageHeight = downloadedImage.getHeight(); + if (imageHeight == imageWidth) { + return downloadedImage; + } else { + scale = imageWidth / 64; + image = new BufferedImage(imageWidth, imageWidth, BufferedImage.TYPE_INT_ARGB); + graphics = image.getGraphics(); + graphics.drawImage(downloadedImage, 0, 0, (ImageObserver) null); + + // copy layers + drawImage(24, 48, 20, 52, 4, 16, 8, 20); + drawImage(28, 48, 24, 52, 8, 16, 12, 20); + drawImage(20, 52, 16, 64, 8, 20, 12, 32); + drawImage(24, 52, 20, 64, 4, 20, 8, 32); + drawImage(28, 52, 24, 64, 0, 20, 4, 32); + drawImage(32, 52, 28, 64, 12, 20, 16, 32); + drawImage(40, 48, 36, 52, 44, 16, 48, 20); + drawImage(44, 48, 40, 52, 48, 16, 52, 20); + drawImage(36, 52, 32, 64, 48, 20, 52, 32); + drawImage(40, 52, 36, 64, 44, 20, 48, 32); + drawImage(44, 52, 40, 64, 40, 20, 44, 32); + drawImage(48, 52, 44, 64, 52, 20, 56, 32); + + graphics.dispose(); + return image; + } + } + } + + private void drawImage(int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2) { + graphics.drawImage(image, + dx1 * scale, dy1 * scale, dx2 * scale, dy2 * scale, + sx1 * scale, sy1 * scale, sx2 * scale, sy2 * scale, + null); + } + + @Override + public void skinAvailable() {} +} diff --git a/src/main/java/com/voxelmodpack/hdskins/PreviewTexture.java b/src/main/java/com/voxelmodpack/hdskins/PreviewTexture.java new file mode 100644 index 00000000..95d54b40 --- /dev/null +++ b/src/main/java/com/voxelmodpack/hdskins/PreviewTexture.java @@ -0,0 +1,19 @@ +package com.voxelmodpack.hdskins; + +import java.io.File; + +import com.voxelmodpack.common.runtime.PrivateFields; + +import net.minecraft.client.renderer.IImageBuffer; +import net.minecraft.client.renderer.ThreadDownloadImageData; +import net.minecraft.util.ResourceLocation; + +public class PreviewTexture extends ThreadDownloadImageData { + public PreviewTexture(String url, ResourceLocation fallbackTexture, IImageBuffer imageBuffer) { + super((File) null, url, fallbackTexture, imageBuffer); + } + + public boolean isTextureUploaded() { + return PrivateFields.downloadedImage.get(this) != null && this.getGlTextureId() > -1; + } +} diff --git a/src/main/java/com/voxelmodpack/hdskins/gui/EntityPlayerModel.java b/src/main/java/com/voxelmodpack/hdskins/gui/EntityPlayerModel.java new file mode 100644 index 00000000..9678e331 --- /dev/null +++ b/src/main/java/com/voxelmodpack/hdskins/gui/EntityPlayerModel.java @@ -0,0 +1,134 @@ +package com.voxelmodpack.hdskins.gui; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import com.mojang.authlib.GameProfile; +import com.voxelmodpack.common.gl.TextureHelper; +import com.voxelmodpack.hdskins.HDSkinManager; +import com.voxelmodpack.hdskins.PreviewTexture; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.resources.DefaultPlayerSkin; +import net.minecraft.entity.EntityLiving; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +public class EntityPlayerModel extends EntityLiving { + public static final ResourceLocation NOSKIN = new ResourceLocation("hdskins", "textures/mob/noskin.png"); + private PreviewTexture remoteSkinTexture; + private ResourceLocation remoteSkinResource; + private ResourceLocation localSkinResource; + private DynamicTexture localSkinTexture; + private TextureManager textureManager; + public final GameProfile profile; + public boolean isSwinging = false; + protected boolean remoteSkin = false; + protected boolean hasLocalTexture = false; + + public EntityPlayerModel(GameProfile profile) { + super((World) null); + this.profile = profile; + this.textureManager = Minecraft.getMinecraft().getTextureManager(); + this.remoteSkinResource = new ResourceLocation("skins/preview_" + this.profile.getName() + ".png"); + this.localSkinResource = NOSKIN; + TextureHelper.releaseTexture(this.remoteSkinResource); + } + + public void setRemoteSkin() { + this.remoteSkin = true; + if (this.remoteSkinTexture != null) { + TextureHelper.releaseTexture(this.remoteSkinResource); + } + + this.remoteSkinTexture = HDSkinManager.getPreviewTexture(this.remoteSkinResource, this.profile); + } + + public void setLocalSkin(File skinTextureFile) { + if (skinTextureFile.exists()) { + this.remoteSkin = false; + if (this.localSkinTexture != null) { + TextureHelper.releaseTexture(this.localSkinResource); + this.localSkinTexture = null; + } + + BufferedImage bufferedImage; + try { + bufferedImage = ImageIO.read(skinTextureFile); + } catch (IOException var4) { + this.localSkinResource = NOSKIN; + var4.printStackTrace(); + return; + } + + this.localSkinTexture = new DynamicTexture(bufferedImage); + this.localSkinResource = this.textureManager.getDynamicTextureLocation("localSkinPreview", + this.localSkinTexture); + this.hasLocalTexture = true; + } + + } + + public boolean usingRemoteSkin() { + return this.remoteSkin; + } + + public boolean isUsingLocalTexture() { + return !this.remoteSkin && this.hasLocalTexture; + } + + public float d(float par1) { + return 1.0F; + } + + public boolean isTextureSetupComplete() { + return this.remoteSkin && this.remoteSkinTexture != null ? this.remoteSkinTexture.isTextureUploaded() : false; + } + + public void releaseTextures() { + if (this.localSkinTexture != null) { + TextureHelper.releaseTexture(this.localSkinResource); + this.localSkinTexture = null; + this.localSkinResource = NOSKIN; + this.hasLocalTexture = false; + } + + } + + public ResourceLocation getSkinTexture() { + return this.remoteSkin ? (this.remoteSkinTexture != null ? this.remoteSkinResource + : DefaultPlayerSkin.getDefaultSkin(entityUniqueID)) : this.localSkinResource; + } + + public boolean hasCloak() { + return false; + } + + public void swingArm() { + if (!this.isSwinging || this.swingProgressInt >= 4 || this.swingProgressInt < 0) { + this.swingProgressInt = -1; + this.isSwinging = true; + } + + } + + public void updateModel() { + this.prevSwingProgress = this.swingProgress; + if (this.isSwinging) { + ++this.swingProgressInt; + if (this.swingProgressInt >= 8) { + this.swingProgressInt = 0; + this.isSwinging = false; + } + } else { + this.swingProgressInt = 0; + } + + this.swingProgress = this.swingProgressInt / 8.0F; + } +} diff --git a/src/main/java/com/voxelmodpack/hdskins/gui/GuiSkins.java b/src/main/java/com/voxelmodpack/hdskins/gui/GuiSkins.java new file mode 100644 index 00000000..de4e12d4 --- /dev/null +++ b/src/main/java/com/voxelmodpack/hdskins/gui/GuiSkins.java @@ -0,0 +1,638 @@ +package com.voxelmodpack.hdskins.gui; + +import static net.minecraft.client.renderer.GlStateManager.*; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.DoubleBuffer; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + +import javax.imageio.ImageIO; +import javax.swing.JFileChooser; + +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.glu.GLU; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.exceptions.AuthenticationException; +import com.mojang.authlib.minecraft.MinecraftSessionService; +import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; +import com.mumfrey.liteloader.util.log.LiteLoaderLogger; +import com.voxelmodpack.common.net.upload.IUploadCompleteCallback; +import com.voxelmodpack.common.net.upload.ThreadMultipartPostUpload; +import com.voxelmodpack.common.net.upload.awt.IOpenFileCallback; +import com.voxelmodpack.common.net.upload.awt.ThreadOpenFilePNG; +import com.voxelmodpack.hdskins.HDSkinManager; +import com.voxelmodpack.hdskins.mod.HDSkinsModCore; +import com.voxelmodpack.voxelmenu.IPanoramaRenderer; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiMainMenu; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Session; + +public class GuiSkins extends GuiScreen implements IUploadCompleteCallback, IOpenFileCallback, IPanoramaRenderer { + private static final ResourceLocation vignette = new ResourceLocation("textures/misc/vignette.png"); + private static final int MAX_SKIN_DIMENSION = 8192; + private static final String skinServerId = "7853dfddc358333843ad55a2c7485c4aa0380a51"; + private int updateCounter = 0; + private ResourceLocation viewportTexture; + private IPanoramaRenderer panoramaRenderer; + private static final ResourceLocation[] cubemapTextures = { + new ResourceLocation("hdskins", "textures/cubemaps/cubemap0_0.png"), + new ResourceLocation("hdskins", "textures/cubemaps/cubemap0_1.png"), + new ResourceLocation("hdskins", "textures/cubemaps/cubemap0_2.png"), + new ResourceLocation("hdskins", "textures/cubemaps/cubemap0_3.png"), + new ResourceLocation("hdskins", "textures/cubemaps/cubemap0_4.png"), + new ResourceLocation("hdskins", "textures/cubemaps/cubemap0_5.png") }; + private GuiButton btnBrowse; + private GuiButton btnUpload; + private GuiButton btnClear; + private GuiButton btnBack; + protected EntityPlayerModel localPlayer; + protected EntityPlayerModel remotePlayer; + protected DoubleBuffer doubleBuffer; + private String screenTitle; + private String uploadError; + private volatile String skinMessage = "Choose a file"; + private String skinUploadMessage = "Uploading skin please wait..."; + private volatile boolean fetchingSkin; + private volatile boolean uploadingSkin; + private volatile boolean pendingRemoteSkinRefresh; + private volatile boolean throttledByMojang; + private ThreadOpenFilePNG openFileThread; + private ThreadMultipartPostUpload threadSkinUpload; + private Object skinLock = new Object(); + private File pendingSkin; + private File selectedSkin; + private float uploadOpacity = 0.0F; + private float lastPartialTick; + + public GuiSkins() { + Minecraft minecraft = Minecraft.getMinecraft(); + this.screenTitle = "Skin Manager"; + GameProfile profile = minecraft.getSession().getProfile(); + this.localPlayer = new EntityPlayerModel(profile); + this.remotePlayer = new EntityPlayerModel(profile); + RenderManager rm = Minecraft.getMinecraft().getRenderManager(); + rm.renderEngine = minecraft.getTextureManager(); + rm.options = minecraft.gameSettings; + rm.livingPlayer = this.localPlayer; + + try { + this.remotePlayer.setRemoteSkin(); + } catch (Exception var4) { + var4.printStackTrace(); + this.throttledByMojang = true; + } + + this.fetchingSkin = true; + this.panoramaRenderer = HDSkinsModCore.getPanoramaRenderer(this); + } + + @Override + public void updateScreen() { + ++this.updateCounter; + this.panoramaRenderer.updatePanorama(); + this.localPlayer.updateModel(); + this.remotePlayer.updateModel(); + if (this.fetchingSkin && this.remotePlayer.isTextureSetupComplete()) { + this.fetchingSkin = false; + this.btnClear.enabled = true; + } + + synchronized (this.skinLock) { + if (this.pendingSkin != null) { + this.setLocalSkin(this.pendingSkin); + this.selectedSkin = this.pendingSkin; + this.pendingSkin = null; + } + } + + this.btnUpload.enabled = this.selectedSkin != null; + if (this.pendingRemoteSkinRefresh) { + this.pendingRemoteSkinRefresh = false; + this.fetchingSkin = true; + this.btnClear.enabled = false; + this.setRemoteSkin(); + } + + } + + protected void setLocalSkin(File pendingSkin) { + this.localPlayer.setLocalSkin(pendingSkin); + } + + protected void setRemoteSkin() { + this.remotePlayer.setRemoteSkin(); + } + + @Override + public void updatePanorama() {} + + @Override + public int getUpdateCounter() { + return this.updateCounter; + } + + @Override + public void setWorldAndResolution(Minecraft par1Minecraft, int par2, int par3) { + super.setWorldAndResolution(par1Minecraft, par2, par3); + this.panoramaRenderer.setPanoramaResolution(par1Minecraft, par2, par3); + } + + @Override + public void setPanoramaResolution(Minecraft minecraft, int width, int height) {} + + protected List getControlList() { + return this.buttonList; + } + + @Override + public void initGui() { + super.initGui(); + this.panoramaRenderer.initPanoramaRenderer(); + this.getControlList().clear(); + this.getControlList().add(this.btnBrowse = new GuiButton(0, 30, this.height - 36, 60, 20, "Browse...")); + this.getControlList() + .add(this.btnUpload = new GuiButton(1, this.width / 2 - 24, this.height / 2 - 10, 48, 20, ">>")); + this.getControlList().add(this.btnClear = new GuiButton(2, this.width - 90, this.height - 36, 60, 20, "Clear")); + this.getControlList() + .add(this.btnBack = new GuiButton(3, this.width / 2 - 50, this.height - 36, 100, 20, "Close")); + this.btnUpload.enabled = false; + this.btnBrowse.enabled = !this.mc.isFullScreen(); + } + + @Override + public void initPanoramaRenderer() { + this.viewportTexture = this.mc.getTextureManager().getDynamicTextureLocation("skinpanorama", + new DynamicTexture(256, 256)); + } + + @Override + public void onGuiClosed() { + super.onGuiClosed(); + this.localPlayer.releaseTextures(); + this.remotePlayer.releaseTextures(); + } + + @Override + public void onFileOpenDialogClosed(JFileChooser fileDialog, int dialogResult) { + this.openFileThread = null; + + try { + if (dialogResult == 0) { + File ex = fileDialog.getSelectedFile(); + if (!ex.exists()) { + this.skinMessage = "File not readable"; + return; + } + + BufferedImage chosenImage = ImageIO.read(ex); + if (!isPowerOfTwo(chosenImage.getWidth()) + || (chosenImage.getWidth() != chosenImage.getHeight() * 2 + && chosenImage.getWidth() != chosenImage.getHeight()) + || chosenImage.getWidth() > MAX_SKIN_DIMENSION + || chosenImage.getHeight() > MAX_SKIN_DIMENSION) { + this.skinMessage = "Not a valid skin file"; + return; + } + + synchronized (this.skinLock) { + this.pendingSkin = ex; + } + } + } catch (Exception var8) { + this.skinMessage = "Error opening skin file"; + var8.printStackTrace(); + } + + } + + @Override + protected void actionPerformed(GuiButton guiButton) { + if (this.openFileThread == null && !this.uploadingSkin) { + if (this.uploadError != null) { + this.uploadError = null; + } else { + if (guiButton.id == this.btnBrowse.id) { + this.selectedSkin = null; + this.localPlayer.releaseTextures(); + this.openFileThread = new ThreadOpenFilePNG(this.mc, "Choose skin", this); + this.openFileThread.start(); + } + + if (guiButton.id == this.btnUpload.id && this.selectedSkin != null) { + this.uploadSkin(this.mc.getSession(), this.selectedSkin); + this.selectedSkin = null; + } + + if (guiButton.id == this.btnClear.id && this.remotePlayer.isTextureSetupComplete()) { + this.clearUploadedSkin(this.mc.getSession()); + } + + if (guiButton.id == this.btnBack.id) { + this.mc.displayGuiScreen(new GuiMainMenu()); + } + + } + } + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int button) throws IOException { + if (this.uploadError != null) { + this.uploadError = null; + } else { + super.mouseClicked(mouseX, mouseY, button); + byte top = 30; + int bottom = this.height - 40; + int mid = this.width / 2; + if ((mouseX > 30 && mouseX < mid - 30 || mouseX > mid + 30 && mouseX < this.width - 30) && mouseY > top + && mouseY < bottom) { + this.localPlayer.swingArm(); + } else if (mouseX > mid + 30 && mouseY > top && mouseX < this.width - 30 && mouseY < bottom) { + this.remotePlayer.swingArm(); + } + + } + } + + @Override + protected void keyTyped(char keyChar, int keyCode) throws IOException { + if (this.openFileThread == null && !this.uploadingSkin) { + super.keyTyped(keyChar, keyCode); + } + } + + public void setupCubemapCamera() { + matrixMode(5889); + pushMatrix(); + loadIdentity(); + GLU.gluPerspective(150.0F, 1.0F, 0.05F, 10.0F); + matrixMode(5888); + pushMatrix(); + loadIdentity(); + } + + public void revertPanoramaMatrix() { + matrixMode(5889); + popMatrix(); + matrixMode(5888); + popMatrix(); + } + + private void renderCubeMapTexture(int mouseX, int mouseY, float partialTick) { + this.setupCubemapCamera(); + color(1.0F, 1.0F, 1.0F, 1.0F); + rotate(180.0F, 1.0F, 0.0F, 0.0F); + GL11.glEnable(3042); + GL11.glDisable(3008); + GL11.glDisable(2884); + depthMask(false); + blendFunc(770, 771); + byte blendIterations = 8; + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer wr = tessellator.getWorldRenderer(); + + for (int blendPass = 0; blendPass < blendIterations * blendIterations; ++blendPass) { + pushMatrix(); + float offsetX = ((float) (blendPass % blendIterations) / (float) blendIterations - 0.5F) / 64.0F; + float offsetY = ((float) (blendPass / blendIterations) / (float) blendIterations - 0.5F) / 64.0F; + float offsetZ = 0.0F; + translate(offsetX, offsetY, offsetZ); + rotate(MathHelper.sin((this.updateCounter + 200 + partialTick) / 400.0F) * 25.0F + 20.0F, 1.0F, + 0.0F, 0.0F); + rotate(-(this.updateCounter + 200 + partialTick) * 0.1F, 0.0F, 1.0F, 0.0F); + + for (int cubeSide = 0; cubeSide < 6; ++cubeSide) { + pushMatrix(); + if (cubeSide == 1) { + rotate(90.0F, 0.0F, 1.0F, 0.0F); + } + + if (cubeSide == 2) { + rotate(180.0F, 0.0F, 1.0F, 0.0F); + } + + if (cubeSide == 3) { + rotate(-90.0F, 0.0F, 1.0F, 0.0F); + } + + if (cubeSide == 4) { + rotate(90.0F, 1.0F, 0.0F, 0.0F); + } + + if (cubeSide == 5) { + rotate(-90.0F, 1.0F, 0.0F, 0.0F); + } + + this.mc.getTextureManager().bindTexture(cubemapTextures[cubeSide]); + wr.startDrawingQuads(); + wr.setColorRGBA_I(16777215, 255 / (blendPass + 1)); + wr.addVertexWithUV(-1.0D, -1.0D, 1.0D, 0.0D, 0.0D); + wr.addVertexWithUV(1.0D, -1.0D, 1.0D, 1.0D, 0.0D); + wr.addVertexWithUV(1.0D, 1.0D, 1.0D, 1.0D, 1.0D); + wr.addVertexWithUV(-1.0D, 1.0D, 1.0D, 0.0D, 1.0D); + tessellator.draw(); + popMatrix(); + } + + popMatrix(); + colorMask(true, true, true, false); + } + + wr.setTranslation(0.0D, 0.0D, 0.0D); + colorMask(true, true, true, true); + depthMask(true); + GL11.glEnable(2884); + GL11.glEnable(3008); + GL11.glEnable(2929); + this.revertPanoramaMatrix(); + } + + private void rotateAndBlurCubemap(float partialTick) { + this.mc.getTextureManager().bindTexture(this.viewportTexture); + GL11.glCopyTexSubImage2D(3553, 0, 0, 0, 0, 0, 256, 256); + GL11.glEnable(3042); + blendFunc(770, 771); + colorMask(true, true, true, false); + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer wr = tessellator.getWorldRenderer(); + wr.startDrawingQuads(); + byte blurPasses = 4; + + for (int blurPass = 0; blurPass < blurPasses; ++blurPass) { + wr.setColorRGBA_F(1.0F, 1.0F, 1.0F, 1.0F / (blurPass + 1)); + float var7 = (blurPass - blurPasses / 2) / 256.0F; + wr.addVertexWithUV(this.width, this.height, this.zLevel, 0.0F + var7, 0.0D); + wr.addVertexWithUV(this.width, 0.0D, this.zLevel, 1.0F + var7, 0.0D); + wr.addVertexWithUV(0.0D, 0.0D, this.zLevel, 1.0F + var7, 1.0D); + wr.addVertexWithUV(0.0D, this.height, this.zLevel, 0.0F + var7, 1.0D); + } + + tessellator.draw(); + colorMask(true, true, true, true); + GL11.glDisable(3042); + } + + @Override + public boolean renderPanorama(int mouseX, int mouseY, float partialTicks) { + viewport(0, 0, 256, 256); + this.renderCubeMapTexture(mouseX, mouseY, partialTicks); + GL11.glDisable(3553); + GL11.glEnable(3553); + + for (int tessellator = 0; tessellator < 8; ++tessellator) { + this.rotateAndBlurCubemap(partialTicks); + } + + viewport(0, 0, this.mc.displayWidth, this.mc.displayHeight); + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer wr = tessellator.getWorldRenderer(); + wr.startDrawingQuads(); + float aspect = this.width > this.height ? 120.0F / this.width : 120.0F / this.height; + float uSample = this.height * aspect / 256.0F; + float vSample = this.width * aspect / 256.0F; + GL11.glTexParameteri(3553, 10241, 9729); + GL11.glTexParameteri(3553, 10240, 9729); + wr.setColorRGBA_F(1.0F, 1.0F, 1.0F, 1.0F); + wr.addVertexWithUV(0.0D, this.height, this.zLevel, 0.5F - uSample, 0.5F + vSample); + wr.addVertexWithUV(this.width, this.height, this.zLevel, 0.5F - uSample, 0.5F - vSample); + wr.addVertexWithUV(this.width, 0.0D, this.zLevel, 0.5F + uSample, 0.5F - vSample); + wr.addVertexWithUV(0.0D, 0.0D, this.zLevel, 0.5F + uSample, 0.5F + vSample); + tessellator.draw(); + return true; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTick) { + float deltaTime = this.updateCounter + partialTick - this.lastPartialTick; + this.lastPartialTick = this.updateCounter + partialTick; + GL11.glDisable(2912); + this.mc.entityRenderer.disableLightmap(); + this.panoramaRenderer.renderPanorama(mouseX, mouseY, partialTick); + byte top = 30; + int bottom = this.height - 40; + int mid = this.width / 2; + int horizon = this.height / 2 + this.height / 5; + GL11.glPushAttrib(1048575); + Gui.drawRect(30, top, mid - 30, bottom, Integer.MIN_VALUE); + Gui.drawRect(mid + 30, top, this.width - 30, bottom, Integer.MIN_VALUE); + this.drawGradientRect(30, horizon, mid - 30, bottom, -2130706433, 16777215); + this.drawGradientRect(mid + 30, horizon, this.width - 30, bottom, -2130706433, 16777215); + super.drawScreen(mouseX, mouseY, partialTick); + popAttrib(); + this.enableClipping(30, bottom); + float yPos = this.height * 0.75F; + float xPos1 = this.width * 0.25F; + float xPos2 = this.width * 0.75F; + float scale = this.height * 0.25F; + this.renderPlayerModel(this.localPlayer, xPos1, yPos, scale, xPos1 - mouseX, yPos - scale * 1.8F - mouseY, + partialTick); + this.renderPlayerModel(this.remotePlayer, xPos2, yPos, scale, xPos2 - mouseX, yPos - scale * 1.8F - mouseY, + partialTick); + this.disableClipping(); + this.drawCenteredString(this.fontRendererObj, this.screenTitle, this.width / 2, 10, 16777215); + this.fontRendererObj.drawStringWithShadow("Local Skin", 34, 34, 16777215); + this.fontRendererObj.drawStringWithShadow("Server Skin", this.width / 2 + 34, 34, 16777215); + GL11.glDisable(2929); + depthMask(false); + this.drawGradientRect(30, this.height - 60, mid - 30, bottom, 0, -520093697); + this.drawGradientRect(mid + 30, this.height - 60, this.width - 30, bottom, 0, -520093697); + int labelwidth = (this.width / 2 - 80) / 2; + int opacity; + if (!this.localPlayer.isUsingLocalTexture()) { + opacity = this.fontRendererObj.getStringWidth(this.skinMessage) / 2; + Gui.drawRect(40, this.height / 2 - 12, this.width / 2 - 40, this.height / 2 + 12, -1342177280); + this.fontRendererObj.drawStringWithShadow(this.skinMessage, (int) (xPos1 - opacity), this.height / 2 - 4, + 16777215); + } + + if (this.fetchingSkin) { + String opacity1 = this.throttledByMojang ? "\u00a7cMojang API Error!" : "Fetching skin..."; + int stringWidth = this.fontRendererObj.getStringWidth(opacity1) / 2; + Gui.drawRect((int) (xPos2 - labelwidth), this.height / 2 - 12, this.width - 40, this.height / 2 + 12, + -1342177280); + this.fontRendererObj.drawStringWithShadow(opacity1, (int) (xPos2 - stringWidth), this.height / 2 - 4, + 16777215); + } + + if (this.uploadingSkin || this.uploadOpacity > 0.0F) { + if (!this.uploadingSkin) { + this.uploadOpacity -= deltaTime * 0.05F; + } else if (this.uploadOpacity < 1.0F) { + this.uploadOpacity += deltaTime * 0.1F; + } + + if (this.uploadOpacity > 1.0F) { + this.uploadOpacity = 1.0F; + } + + opacity = Math.min(180, (int) (this.uploadOpacity * 180.0F)) & 255; + if (this.uploadOpacity > 0.0F) { + Gui.drawRect(0, 0, this.width, this.height, opacity << 24 | 0); + if (this.uploadingSkin) { + this.drawCenteredString(this.fontRendererObj, this.skinUploadMessage, this.width / 2, + this.height / 2, opacity << 24 | 16777215); + } + } + } + + if (this.uploadError != null) { + Gui.drawRect(0, 0, this.width, this.height, -1342177280); + this.drawCenteredString(this.fontRendererObj, "Uploading skin failed", this.width / 2, this.height / 2 - 10, + -171); + this.drawCenteredString(this.fontRendererObj, this.uploadError, this.width / 2, this.height / 2 + 2, + -43691); + } + + depthMask(true); + GL11.glEnable(2929); + } + + protected void renderVignette(int mouseX, int mouseY, float partialTick) { + GL11.glDisable(2929); + depthMask(false); + blendFunc(1, 774); + color(1.0F, 1.0F, 1.0F, 1.0F); + this.mc.getTextureManager().bindTexture(vignette); + GL11.glLogicOp(5386); + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer wr = tessellator.getWorldRenderer(); + wr.startDrawingQuads(); + wr.addVertexWithUV(0.0D, this.height, -90.0D, 0.0D, 1.0D); + wr.addVertexWithUV(this.width, this.height, -90.0D, 1.0D, 1.0D); + wr.addVertexWithUV(this.width, 0.0D, -90.0D, 1.0D, 0.0D); + wr.addVertexWithUV(0.0D, 0.0D, -90.0D, 0.0D, 0.0D); + tessellator.draw(); + depthMask(true); + GL11.glDisable(3058); + GL11.glEnable(2929); + color(1.0F, 1.0F, 1.0F, 1.0F); + blendFunc(770, 771); + } + + public void renderPlayerModel(EntityPlayerModel thePlayer, float xPosition, float yPosition, float scale, + float mouseX, float mouseY, float partialTick) { + GL11.glEnable(2903); + pushMatrix(); + translate(xPosition, yPosition, 300.0F); + scale(-scale, scale, scale); + rotate(180.0F, 0.0F, 0.0F, 1.0F); + rotate(135.0F, 0.0F, 1.0F, 0.0F); + RenderHelper.enableStandardItemLighting(); + rotate(-135.0F, 0.0F, 1.0F, 0.0F); + rotate(15.0F, 1.0F, 0.0F, 0.0F); + rotate((this.updateCounter + partialTick) * 2.5F, 0.0F, 1.0F, 0.0F); + thePlayer.rotationPitch = -((float) Math.atan(mouseY / 40.0F)) * 20.0F; + translate(0.0F, thePlayer.getYOffset(), 0.0F); + RenderManager rm = Minecraft.getMinecraft().getRenderManager(); + rm.playerViewY = 180.0F; + rm.renderEntityWithPosYaw(thePlayer, 0.0D, 0.0D, 0.0D, 1.0F, 1.0F); + popMatrix(); + RenderHelper.disableStandardItemLighting(); + GL11.glDisable('\u803a'); + } + + protected final void enableClipping(int yTop, int yBottom) { + if (this.doubleBuffer == null) { + this.doubleBuffer = BufferUtils.createByteBuffer(32).asDoubleBuffer(); + } + + this.doubleBuffer.clear(); + this.doubleBuffer.put(0.0D).put(1.0D).put(0.0D).put((-yTop)).flip(); + GL11.glClipPlane(12288, this.doubleBuffer); + this.doubleBuffer.clear(); + this.doubleBuffer.put(0.0D).put(-1.0D).put(0.0D).put(yBottom).flip(); + GL11.glClipPlane(12289, this.doubleBuffer); + GL11.glEnable(12288); + GL11.glEnable(12289); + } + + protected final void disableClipping() { + GL11.glDisable(12289); + GL11.glDisable(12288); + } + + public static boolean isPowerOfTwo(int number) { + return number != 0 && (number & number - 1) == 0; + } + + private boolean clearUploadedSkin(Session session) { + if (!this.registerServerConnection(session, skinServerId)) { + return false; + } else { + HashMap sourceData = new HashMap(); + sourceData.put("user", session.getUsername()); + sourceData.put("uuid", session.getPlayerID()); + sourceData.put("clear", "1"); + this.uploadError = null; + this.uploadingSkin = true; + this.skinUploadMessage = "Sending request to server please wait..."; + this.threadSkinUpload = new ThreadMultipartPostUpload(HDSkinManager.getGatewayUrl(), sourceData, this); + this.threadSkinUpload.start(); + return true; + } + } + + private boolean uploadSkin(Session session, File skinFile) { + if (!this.registerServerConnection(session, skinServerId)) { + return false; + } else { + HashMap sourceData = new HashMap(); + sourceData.put("user", session.getUsername()); + sourceData.put("uuid", session.getPlayerID()); + sourceData.put("skin", skinFile); + this.uploadError = null; + this.uploadingSkin = true; + this.skinUploadMessage = "Uploading skin please wait..."; + this.threadSkinUpload = new ThreadMultipartPostUpload(HDSkinManager.getGatewayUrl(), sourceData, this); + this.threadSkinUpload.start(); + return true; + } + } + + private void setUploadError(String error) { + this.uploadError = error.startsWith("ERROR: ") ? error.substring(7) : error; + this.btnUpload.enabled = true; + } + + @Override + public void onUploadComplete(String response) { + LiteLoaderLogger.info("Upload completed with: %s", new Object[] { response }); + this.uploadingSkin = false; + this.threadSkinUpload = null; + if (!response.equalsIgnoreCase("OK")) { + this.setUploadError(response); + } else { + this.pendingRemoteSkinRefresh = true; + } + } + + private boolean registerServerConnection(Session session, String serverId) { + try { + MinecraftSessionService e = (new YggdrasilAuthenticationService(this.mc.getProxy(), + UUID.randomUUID().toString())).createMinecraftSessionService(); + e.joinServer(session.getProfile(), session.getToken(), serverId); + return true; + } catch (AuthenticationException var4) { + this.setUploadError(var4.toString()); + var4.printStackTrace(); + return false; + } + } +} diff --git a/src/main/java/com/voxelmodpack/hdskins/gui/HDSkinsConfigPanel.java b/src/main/java/com/voxelmodpack/hdskins/gui/HDSkinsConfigPanel.java new file mode 100644 index 00000000..5888b4fc --- /dev/null +++ b/src/main/java/com/voxelmodpack/hdskins/gui/HDSkinsConfigPanel.java @@ -0,0 +1,46 @@ +package com.voxelmodpack.hdskins.gui; + +import com.voxelmodpack.common.properties.VoxelPropertyToggleButton; +import com.voxelmodpack.common.properties.gui.GuiVoxelBoxSettingsPanel; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProviderBoolean; +import com.voxelmodpack.hdskins.HDSkinManager; + +public class HDSkinsConfigPanel extends GuiVoxelBoxSettingsPanel implements IVoxelPropertyProviderBoolean { + + public HDSkinsConfigPanel() { + this.properties.add(new VoxelPropertyToggleButton(this, "clear", "Clear local skin cache", 72, 8, 120, 70, 16)); + } + + @Override + public String getPanelTitle() { + return "HD Skins Settings"; + } + + @Override + public String getStringProperty(String propertyName) { + return null; + } + + @Override + public String getOptionDisplayString(String propertyName) { + return "Clear now"; + } + + @Override + public void toggleOption(String propertyName) { + HDSkinManager.clearSkinCache(); + } + + @Override + public String getDefaultPropertyValue(String propertyName) { + return null; + } + + @Override + public void setProperty(String propertyName, boolean value) {} + + @Override + public boolean getBoolProperty(String propertyName) { + return true; + } +} diff --git a/src/main/java/com/voxelmodpack/hdskins/gui/RenderPlayerModel.java b/src/main/java/com/voxelmodpack/hdskins/gui/RenderPlayerModel.java new file mode 100644 index 00000000..1ff6a9f2 --- /dev/null +++ b/src/main/java/com/voxelmodpack/hdskins/gui/RenderPlayerModel.java @@ -0,0 +1,64 @@ +package com.voxelmodpack.hdskins.gui; + +import static net.minecraft.client.renderer.GlStateManager.*; + +import org.lwjgl.opengl.GL11; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.model.ModelPlayer; +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.ResourceLocation; + +public class RenderPlayerModel extends RenderLiving { + + public RenderPlayerModel(RenderManager renderer) { + super(renderer, new ModelPlayer(0, false), 0.0F); + } + + @Override + protected ResourceLocation getEntityTexture(Entity var1) { + return ((EntityPlayerModel) var1).getSkinTexture(); + } + + @Override + protected boolean canRenderName(EntityLivingBase targetEntity) { + if (Minecraft.getMinecraft().thePlayer != null) { + return super.canRenderName(targetEntity); + } + return false; + } + + @Override + protected boolean setBrightness(EntityLivingBase entitylivingbaseIn, float partialTicks, boolean p_177092_3_) { + if (Minecraft.getMinecraft().theWorld != null) { + return super.setBrightness(entitylivingbaseIn, partialTicks, p_177092_3_); + } + return false; + } + + @Override + public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9) { + GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS); + this.doRender((EntityLiving) par1Entity, par2, par4, par6, par8, par9); + popAttrib(); + pushMatrix(); + scale(1.0F, -1.0F, 1.0F); + GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS); + this.doRender((EntityLiving) par1Entity, par2, par4, par6, par8, par9); + popAttrib(); + popMatrix(); + } + + @Override + protected void preRenderCallback(EntityLivingBase par1EntityLiving, float par2) { + this.renderCloak((EntityPlayerModel) par1EntityLiving, par2); + } + + protected void renderCloak(EntityPlayerModel entity, float par2) { + super.preRenderCallback(entity, par2); + } +} diff --git a/src/main/java/com/voxelmodpack/hdskins/mod/HDSkinsMod.java b/src/main/java/com/voxelmodpack/hdskins/mod/HDSkinsMod.java new file mode 100644 index 00000000..0c65b20b --- /dev/null +++ b/src/main/java/com/voxelmodpack/hdskins/mod/HDSkinsMod.java @@ -0,0 +1,7 @@ +package com.voxelmodpack.hdskins.mod; + +import com.mumfrey.liteloader.Configurable; +import com.mumfrey.liteloader.InitCompleteListener; + +public interface HDSkinsMod extends InitCompleteListener, Configurable { +} diff --git a/src/main/java/com/voxelmodpack/hdskins/mod/HDSkinsModCore.java b/src/main/java/com/voxelmodpack/hdskins/mod/HDSkinsModCore.java new file mode 100644 index 00000000..2a6850b8 --- /dev/null +++ b/src/main/java/com/voxelmodpack/hdskins/mod/HDSkinsModCore.java @@ -0,0 +1,79 @@ +package com.voxelmodpack.hdskins.mod; + +import java.io.File; +import java.lang.reflect.Method; + +import com.mumfrey.liteloader.core.LiteLoader; +import com.mumfrey.liteloader.modconfig.ConfigPanel; +import com.mumfrey.liteloader.util.ModUtilities; +import com.voxelmodpack.hdskins.HDSkinManager; +import com.voxelmodpack.hdskins.gui.EntityPlayerModel; +import com.voxelmodpack.hdskins.gui.GuiSkins; +import com.voxelmodpack.hdskins.gui.HDSkinsConfigPanel; +import com.voxelmodpack.hdskins.gui.RenderPlayerModel; +import com.voxelmodpack.voxelmenu.IPanoramaRenderer; + +import net.minecraft.client.Minecraft; + +public class HDSkinsModCore implements HDSkinsMod { + @Override + public String getName() { + return "HD Skins"; + } + + @Override + public String getVersion() { + return "4.0.0"; + } + + @Override + public void init(File configPath) { + try { + Class ex = Class.forName("com.thevoxelbox.voxelmenu.GuiMainMenuVoxelBox"); + Method mRegisterCustomScreen = ex.getDeclaredMethod("registerCustomScreen", + new Class[] { Class.class, String.class }); + mRegisterCustomScreen.invoke(null, GuiSkins.class, "HD Skins Manager"); + } catch (ClassNotFoundException var4) { + ; + } catch (Exception var5) { + var5.printStackTrace(); + } + + } + + @Override + public void upgradeSettings(String version, File configPath, File oldConfigPath) { + HDSkinManager.clearSkinCache(); + } + + @Override + public Class getConfigPanelClass() { + return HDSkinsConfigPanel.class; + } + + @Override + public void onInitCompleted(Minecraft minecraft, LiteLoader loader) { + ModUtilities.addRenderer(EntityPlayerModel.class, new RenderPlayerModel(minecraft.getRenderManager())); + } + + @Override + public void onTick(Minecraft minecraft, float partialTicks, boolean inGame, boolean clock) {} + + public static IPanoramaRenderer getPanoramaRenderer(IPanoramaRenderer fallbackRenderer) { + try { + Class ex = Class.forName("com.thevoxelbox.voxelmenu.VoxelMenuModCore"); + Method mGetPanoramaRenderer = ex.getDeclaredMethod("getPanoramaRenderer", new Class[0]); + IPanoramaRenderer panoramaRenderer = (IPanoramaRenderer) mGetPanoramaRenderer.invoke((Object) null, + new Object[0]); + if (panoramaRenderer != null) { + return panoramaRenderer; + } + } catch (ClassNotFoundException var4) { + ; + } catch (Exception var5) { + var5.printStackTrace(); + } + + return fallbackRenderer; + } +} diff --git a/src/main/java/com/voxelmodpack/hdskins/mod/LiteModHDSkins.java b/src/main/java/com/voxelmodpack/hdskins/mod/LiteModHDSkins.java new file mode 100644 index 00000000..8e6988ef --- /dev/null +++ b/src/main/java/com/voxelmodpack/hdskins/mod/LiteModHDSkins.java @@ -0,0 +1,19 @@ +package com.voxelmodpack.hdskins.mod; + +import com.voxelmodpack.common.VoxelCommonLiteMod; + +public class LiteModHDSkins extends VoxelCommonLiteMod { + public LiteModHDSkins() { + super("com.voxelmodpack.hdskins.mod.HDSkinsModCore"); + } + + @Override +public String getVersion() { + return "4.0.1"; + } + + @Override +public String getName() { + return "HDSkins"; + } +} diff --git a/src/main/java/com/voxelmodpack/voxelmenu/IPanoramaRenderer.java b/src/main/java/com/voxelmodpack/voxelmenu/IPanoramaRenderer.java new file mode 100644 index 00000000..b618d244 --- /dev/null +++ b/src/main/java/com/voxelmodpack/voxelmenu/IPanoramaRenderer.java @@ -0,0 +1,15 @@ +package com.voxelmodpack.voxelmenu; + +import net.minecraft.client.Minecraft; + +public interface IPanoramaRenderer { + void setPanoramaResolution(Minecraft var1, int var2, int var3); + + void initPanoramaRenderer(); + + void updatePanorama(); + + boolean renderPanorama(int var1, int var2, float var3); + + int getUpdateCounter(); +} diff --git a/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_0.png b/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_0.png new file mode 100644 index 00000000..64d152ed Binary files /dev/null and b/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_0.png differ diff --git a/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_1.png b/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_1.png new file mode 100644 index 00000000..8f8b83a4 Binary files /dev/null and b/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_1.png differ diff --git a/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_2.png b/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_2.png new file mode 100644 index 00000000..d27fab3f Binary files /dev/null and b/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_2.png differ diff --git a/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_3.png b/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_3.png new file mode 100644 index 00000000..18b5752f Binary files /dev/null and b/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_3.png differ diff --git a/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_4.png b/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_4.png new file mode 100644 index 00000000..b7692f23 Binary files /dev/null and b/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_4.png differ diff --git a/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_5.png b/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_5.png new file mode 100644 index 00000000..f05f3a12 Binary files /dev/null and b/src/main/resources/assets/hdskins/textures/cubemaps/cubemap0_5.png differ diff --git a/src/main/resources/assets/hdskins/textures/mob/noskin.png b/src/main/resources/assets/hdskins/textures/mob/noskin.png new file mode 100644 index 00000000..bb1ffcd2 Binary files /dev/null and b/src/main/resources/assets/hdskins/textures/mob/noskin.png differ diff --git a/src/main/resources/assets/hdskins/textures/mob/tempskin.png b/src/main/resources/assets/hdskins/textures/mob/tempskin.png new file mode 100644 index 00000000..bb1ffcd2 Binary files /dev/null and b/src/main/resources/assets/hdskins/textures/mob/tempskin.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_0.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_0.png new file mode 100644 index 00000000..f09db8c2 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_0.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_1.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_1.png new file mode 100644 index 00000000..2a689e35 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_1.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_10.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_10.png new file mode 100644 index 00000000..a15e33d6 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_10.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_100.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_100.png new file mode 100644 index 00000000..02022bdb Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_100.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_101.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_101.png new file mode 100644 index 00000000..35ee03e5 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_101.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_102.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_102.png new file mode 100644 index 00000000..e12ab761 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_102.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_103.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_103.png new file mode 100644 index 00000000..9a589d77 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_103.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_104.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_104.png new file mode 100644 index 00000000..012b56e5 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_104.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_105.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_105.png new file mode 100644 index 00000000..54e25fff Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_105.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_106.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_106.png new file mode 100644 index 00000000..23733d82 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_106.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_107.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_107.png new file mode 100644 index 00000000..c646d20d Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_107.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_108.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_108.png new file mode 100644 index 00000000..bcee5003 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_108.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_109.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_109.png new file mode 100644 index 00000000..1378a1f1 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_109.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_11.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_11.png new file mode 100644 index 00000000..722c85b3 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_11.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_110.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_110.png new file mode 100644 index 00000000..eedece46 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_110.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_111.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_111.png new file mode 100644 index 00000000..33ce0278 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_111.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_112.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_112.png new file mode 100644 index 00000000..b76f93a9 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_112.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_113.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_113.png new file mode 100644 index 00000000..96f94bc9 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_113.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_114.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_114.png new file mode 100644 index 00000000..a5e17a0d Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_114.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_115.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_115.png new file mode 100644 index 00000000..4074f48b Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_115.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_116.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_116.png new file mode 100644 index 00000000..584931a6 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_116.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_117.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_117.png new file mode 100644 index 00000000..e1d23711 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_117.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_118.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_118.png new file mode 100644 index 00000000..eed238fb Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_118.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_119.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_119.png new file mode 100644 index 00000000..c4f3f17f Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_119.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_12.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_12.png new file mode 100644 index 00000000..eca101f0 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_12.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_120.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_120.png new file mode 100644 index 00000000..543b7173 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_120.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_121.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_121.png new file mode 100644 index 00000000..f0ca5348 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_121.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_122.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_122.png new file mode 100644 index 00000000..e69ac87a Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_122.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_123.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_123.png new file mode 100644 index 00000000..f480b069 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_123.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_124.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_124.png new file mode 100644 index 00000000..0bed83c6 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_124.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_125.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_125.png new file mode 100644 index 00000000..71b31e89 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_125.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_126.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_126.png new file mode 100644 index 00000000..bbd93f40 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_126.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_127.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_127.png new file mode 100644 index 00000000..219e95f4 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_127.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_128.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_128.png new file mode 100644 index 00000000..c6e5fc48 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_128.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_129.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_129.png new file mode 100644 index 00000000..3e75dbbe Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_129.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_13.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_13.png new file mode 100644 index 00000000..1a3c02f8 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_13.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_130.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_130.png new file mode 100644 index 00000000..cf3baca5 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_130.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_131.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_131.png new file mode 100644 index 00000000..c4e8e3af Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_131.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_132.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_132.png new file mode 100644 index 00000000..ddc8a623 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_132.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_133.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_133.png new file mode 100644 index 00000000..e1beb070 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_133.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_134.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_134.png new file mode 100644 index 00000000..d54ee334 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_134.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_135.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_135.png new file mode 100644 index 00000000..e98348cb Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_135.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_136.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_136.png new file mode 100644 index 00000000..3cac82dc Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_136.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_137.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_137.png new file mode 100644 index 00000000..2fb6f1ea Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_137.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_138.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_138.png new file mode 100644 index 00000000..3aa5b829 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_138.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_139.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_139.png new file mode 100644 index 00000000..c3dc1fa0 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_139.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_14.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_14.png new file mode 100644 index 00000000..2eabf346 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_14.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_140.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_140.png new file mode 100644 index 00000000..52e65648 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_140.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_15.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_15.png new file mode 100644 index 00000000..236921a6 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_15.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_16.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_16.png new file mode 100644 index 00000000..1417a2df Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_16.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_17.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_17.png new file mode 100644 index 00000000..1a693ea3 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_17.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_18.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_18.png new file mode 100644 index 00000000..cd9bf70d Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_18.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_19.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_19.png new file mode 100644 index 00000000..23689330 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_19.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_2.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_2.png new file mode 100644 index 00000000..be35978a Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_2.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_20.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_20.png new file mode 100644 index 00000000..0f6a2970 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_20.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_21.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_21.png new file mode 100644 index 00000000..d56c101a Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_21.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_22.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_22.png new file mode 100644 index 00000000..3e994cd4 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_22.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_23.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_23.png new file mode 100644 index 00000000..05093365 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_23.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_24.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_24.png new file mode 100644 index 00000000..dede4229 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_24.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_25.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_25.png new file mode 100644 index 00000000..9a2b91b6 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_25.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_26.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_26.png new file mode 100644 index 00000000..0900c3ad Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_26.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_27.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_27.png new file mode 100644 index 00000000..6d439272 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_27.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_28.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_28.png new file mode 100644 index 00000000..e85ac79f Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_28.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_29.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_29.png new file mode 100644 index 00000000..a127bdf0 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_29.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_3.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_3.png new file mode 100644 index 00000000..38aa3c40 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_3.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_30.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_30.png new file mode 100644 index 00000000..8143db0d Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_30.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_31.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_31.png new file mode 100644 index 00000000..37b74f8a Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_31.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_32.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_32.png new file mode 100644 index 00000000..0963b812 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_32.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_33.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_33.png new file mode 100644 index 00000000..4e99d148 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_33.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_34.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_34.png new file mode 100644 index 00000000..6554d0c1 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_34.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_35.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_35.png new file mode 100644 index 00000000..8e8b608f Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_35.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_36.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_36.png new file mode 100644 index 00000000..6d1c4684 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_36.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_37.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_37.png new file mode 100644 index 00000000..13e8eb36 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_37.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_38.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_38.png new file mode 100644 index 00000000..722587b2 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_38.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_39.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_39.png new file mode 100644 index 00000000..cde68ee3 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_39.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_4.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_4.png new file mode 100644 index 00000000..9a009121 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_4.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_40.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_40.png new file mode 100644 index 00000000..c3d03bcb Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_40.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_41.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_41.png new file mode 100644 index 00000000..f886a589 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_41.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_42.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_42.png new file mode 100644 index 00000000..8d47d302 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_42.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_43.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_43.png new file mode 100644 index 00000000..a713c591 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_43.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_44.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_44.png new file mode 100644 index 00000000..8fc62db8 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_44.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_45.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_45.png new file mode 100644 index 00000000..bd547633 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_45.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_46.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_46.png new file mode 100644 index 00000000..490040cd Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_46.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_47.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_47.png new file mode 100644 index 00000000..fa7ea909 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_47.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_48.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_48.png new file mode 100644 index 00000000..a5ad8b8c Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_48.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_49.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_49.png new file mode 100644 index 00000000..a586fb67 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_49.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_5.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_5.png new file mode 100644 index 00000000..166a49bc Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_5.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_50.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_50.png new file mode 100644 index 00000000..72a62d2b Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_50.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_51.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_51.png new file mode 100644 index 00000000..67d2130f Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_51.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_52.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_52.png new file mode 100644 index 00000000..eeab7d00 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_52.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_53.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_53.png new file mode 100644 index 00000000..8b8dad22 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_53.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_54.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_54.png new file mode 100644 index 00000000..f0ac11d5 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_54.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_55.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_55.png new file mode 100644 index 00000000..3486b2ed Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_55.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_56.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_56.png new file mode 100644 index 00000000..82cf6298 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_56.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_57.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_57.png new file mode 100644 index 00000000..2d1dad03 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_57.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_58.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_58.png new file mode 100644 index 00000000..9fe5693d Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_58.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_59.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_59.png new file mode 100644 index 00000000..aacbe7c9 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_59.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_6.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_6.png new file mode 100644 index 00000000..ed572d2b Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_6.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_60.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_60.png new file mode 100644 index 00000000..ee62b0cd Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_60.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_61.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_61.png new file mode 100644 index 00000000..9dbbd951 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_61.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_62.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_62.png new file mode 100644 index 00000000..07a59e1d Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_62.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_63.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_63.png new file mode 100644 index 00000000..4b66a314 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_63.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_64.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_64.png new file mode 100644 index 00000000..8d8267e9 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_64.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_65.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_65.png new file mode 100644 index 00000000..6ab3da3f Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_65.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_66.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_66.png new file mode 100644 index 00000000..0571a38f Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_66.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_67.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_67.png new file mode 100644 index 00000000..ba023f8c Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_67.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_68.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_68.png new file mode 100644 index 00000000..80dcfe31 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_68.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_69.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_69.png new file mode 100644 index 00000000..763d6109 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_69.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_7.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_7.png new file mode 100644 index 00000000..a4a30163 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_7.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_70.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_70.png new file mode 100644 index 00000000..9b61e276 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_70.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_71.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_71.png new file mode 100644 index 00000000..f4aeb54c Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_71.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_72.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_72.png new file mode 100644 index 00000000..36aa1aa8 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_72.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_73.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_73.png new file mode 100644 index 00000000..fd4bc4f0 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_73.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_74.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_74.png new file mode 100644 index 00000000..97f180b4 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_74.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_75.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_75.png new file mode 100644 index 00000000..fa43291d Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_75.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_76.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_76.png new file mode 100644 index 00000000..8cf225ce Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_76.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_77.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_77.png new file mode 100644 index 00000000..a245dd82 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_77.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_78.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_78.png new file mode 100644 index 00000000..0645c67e Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_78.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_79.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_79.png new file mode 100644 index 00000000..d9d96e41 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_79.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_8.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_8.png new file mode 100644 index 00000000..1c19170a Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_8.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_80.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_80.png new file mode 100644 index 00000000..a988f8d4 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_80.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_81.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_81.png new file mode 100644 index 00000000..9bd7c285 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_81.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_82.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_82.png new file mode 100644 index 00000000..4d88c6bf Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_82.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_83.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_83.png new file mode 100644 index 00000000..26dda4af Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_83.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_84.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_84.png new file mode 100644 index 00000000..46c32405 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_84.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_85.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_85.png new file mode 100644 index 00000000..997debce Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_85.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_86.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_86.png new file mode 100644 index 00000000..279796d1 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_86.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_87.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_87.png new file mode 100644 index 00000000..5dbbca22 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_87.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_88.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_88.png new file mode 100644 index 00000000..fa063268 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_88.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_89.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_89.png new file mode 100644 index 00000000..bc596284 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_89.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_9.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_9.png new file mode 100644 index 00000000..a0610491 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_9.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_90.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_90.png new file mode 100644 index 00000000..2c000e44 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_90.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_91.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_91.png new file mode 100644 index 00000000..da6e38e1 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_91.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_92.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_92.png new file mode 100644 index 00000000..f153ec0d Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_92.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_93.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_93.png new file mode 100644 index 00000000..d05297e7 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_93.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_94.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_94.png new file mode 100644 index 00000000..c4d54484 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_94.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_95.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_95.png new file mode 100644 index 00000000..edd2b176 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_95.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_96.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_96.png new file mode 100644 index 00000000..7530cd3d Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_96.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_97.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_97.png new file mode 100644 index 00000000..76e28b40 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_97.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_98.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_98.png new file mode 100644 index 00000000..b28897df Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_98.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_99.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_99.png new file mode 100644 index 00000000..76b4d014 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/bpony_99.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/pony/charpony.png b/src/main/resources/assets/minelittlepony/textures/entity/pony/charpony.png new file mode 100644 index 00000000..1e1fa46d Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/pony/charpony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/skeleton/skeleton_pony.png b/src/main/resources/assets/minelittlepony/textures/entity/skeleton/skeleton_pony.png new file mode 100644 index 00000000..de1baabf Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/skeleton/skeleton_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/skeleton/skeleton_wither_pony.png b/src/main/resources/assets/minelittlepony/textures/entity/skeleton/skeleton_wither_pony.png new file mode 100644 index 00000000..07ce5bd9 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/skeleton/skeleton_wither_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/villager/butcher_pony.png b/src/main/resources/assets/minelittlepony/textures/entity/villager/butcher_pony.png new file mode 100644 index 00000000..6ac20003 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/villager/butcher_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/villager/farmer_pony.png b/src/main/resources/assets/minelittlepony/textures/entity/villager/farmer_pony.png new file mode 100644 index 00000000..664f49a5 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/villager/farmer_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/villager/librarian_pony.png b/src/main/resources/assets/minelittlepony/textures/entity/villager/librarian_pony.png new file mode 100644 index 00000000..a13f09b6 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/villager/librarian_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/villager/priest_pony.png b/src/main/resources/assets/minelittlepony/textures/entity/villager/priest_pony.png new file mode 100644 index 00000000..226d0e62 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/villager/priest_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/villager/smith_pony.png b/src/main/resources/assets/minelittlepony/textures/entity/villager/smith_pony.png new file mode 100644 index 00000000..b2254a80 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/villager/smith_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/villager/villager_pony.png b/src/main/resources/assets/minelittlepony/textures/entity/villager/villager_pony.png new file mode 100644 index 00000000..29832750 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/villager/villager_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/zombie/zombie_pony.png b/src/main/resources/assets/minelittlepony/textures/entity/zombie/zombie_pony.png new file mode 100644 index 00000000..e1136eb3 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/zombie/zombie_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/zombie/zombie_villager_pony.png b/src/main/resources/assets/minelittlepony/textures/entity/zombie/zombie_villager_pony.png new file mode 100644 index 00000000..9702ffd9 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/zombie/zombie_villager_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/entity/zombie_pigman_pony.png b/src/main/resources/assets/minelittlepony/textures/entity/zombie_pigman_pony.png new file mode 100644 index 00000000..1fee7e7b Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/entity/zombie_pigman_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/models/armor/chainmail_layer_1_pony.png b/src/main/resources/assets/minelittlepony/textures/models/armor/chainmail_layer_1_pony.png new file mode 100644 index 00000000..efe93b43 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/models/armor/chainmail_layer_1_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/models/armor/chainmail_layer_2_pony.png b/src/main/resources/assets/minelittlepony/textures/models/armor/chainmail_layer_2_pony.png new file mode 100644 index 00000000..4e853e22 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/models/armor/chainmail_layer_2_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/models/armor/diamond_layer_1_pony.png b/src/main/resources/assets/minelittlepony/textures/models/armor/diamond_layer_1_pony.png new file mode 100644 index 00000000..5a0c1631 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/models/armor/diamond_layer_1_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/models/armor/diamond_layer_2_pony.png b/src/main/resources/assets/minelittlepony/textures/models/armor/diamond_layer_2_pony.png new file mode 100644 index 00000000..61ee1f8b Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/models/armor/diamond_layer_2_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/models/armor/gold_layer_1_pony.png b/src/main/resources/assets/minelittlepony/textures/models/armor/gold_layer_1_pony.png new file mode 100644 index 00000000..d11b7293 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/models/armor/gold_layer_1_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/models/armor/gold_layer_2_pony.png b/src/main/resources/assets/minelittlepony/textures/models/armor/gold_layer_2_pony.png new file mode 100644 index 00000000..731977f7 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/models/armor/gold_layer_2_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/models/armor/iron_layer_1_pony.png b/src/main/resources/assets/minelittlepony/textures/models/armor/iron_layer_1_pony.png new file mode 100644 index 00000000..64049dff Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/models/armor/iron_layer_1_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/models/armor/iron_layer_2_pony.png b/src/main/resources/assets/minelittlepony/textures/models/armor/iron_layer_2_pony.png new file mode 100644 index 00000000..37d6d916 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/models/armor/iron_layer_2_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/models/armor/leather_layer_1_overlay_pony.png b/src/main/resources/assets/minelittlepony/textures/models/armor/leather_layer_1_overlay_pony.png new file mode 100644 index 00000000..e1396966 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/models/armor/leather_layer_1_overlay_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/models/armor/leather_layer_1_pony.png b/src/main/resources/assets/minelittlepony/textures/models/armor/leather_layer_1_pony.png new file mode 100644 index 00000000..619ea19e Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/models/armor/leather_layer_1_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/models/armor/leather_layer_2_overlay_pony.png b/src/main/resources/assets/minelittlepony/textures/models/armor/leather_layer_2_overlay_pony.png new file mode 100644 index 00000000..05fdfc68 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/models/armor/leather_layer_2_overlay_pony.png differ diff --git a/src/main/resources/assets/minelittlepony/textures/models/armor/leather_layer_2_pony.png b/src/main/resources/assets/minelittlepony/textures/models/armor/leather_layer_2_pony.png new file mode 100644 index 00000000..24c714b0 Binary files /dev/null and b/src/main/resources/assets/minelittlepony/textures/models/armor/leather_layer_2_pony.png differ diff --git a/src/main/resources/assets/voxelcommon/textures/gui/guiparts.png b/src/main/resources/assets/voxelcommon/textures/gui/guiparts.png new file mode 100644 index 00000000..9f93565f Binary files /dev/null and b/src/main/resources/assets/voxelcommon/textures/gui/guiparts.png differ diff --git a/src/main/resources/events.json b/src/main/resources/events.json new file mode 100644 index 00000000..2bd4a8fd --- /dev/null +++ b/src/main/resources/events.json @@ -0,0 +1,28 @@ +{ + "obfuscation": { + "classes": [ + { "id": "ThreadDownloadImageData", "mcp": "net.minecraft.client.renderer.ThreadDownloadImageData", "obf": "ctq"}, + { "id": "HDSkinManager", "mcp": "com.voxelmodpack.hdskins.HDSkinManager" } + ], + "methods": [ + { "id": "loadTextureFromServer", "mcp": "loadTextureFromServer", "srg": "func_152433_a", "obf": "d" } + ] + }, + "descriptors": [ + { "id": "start", "owner": "java.lang.Thread", "name": "start", "return": "VOID", "args": [] }, + { "id": "loadTextureFromServer", "owner": "${ThreadDownloadImageData}", "name": "${loadTextureFromServer}", "return": "VOID", "args": [] }, + { "id": "onDownloadSkin", "owner": "${HDSkinManager}", "name": "onDownloadSkin" } + ], + "events": [ + { + "name": "onDownloadSkin", + "cancellable": "true", + "injections": [{ + "type": "INVOKE", + "method": "${loadTextureFromServer}", + "target": "${start}" + }], + "listeners": [ "${onDownloadSkin}" ] + } + ] +} diff --git a/src/main/resources/litemod.json b/src/main/resources/litemod.json new file mode 100644 index 00000000..d2d2b89c --- /dev/null +++ b/src/main/resources/litemod.json @@ -0,0 +1,12 @@ +{ + "name": "minelp", + "mcversion": "1.8", + "version": "1.8-UNOFFICIAL", + "revision": "185.15", + "author": "Verdana, Rene_Z, Mumfrey, JoyJoy", + "voxelCommonJarName": "voxelcommon-2.4.0.jar", + "classTransformerClasses": "com.minelittlepony.minelp.transformers.RenderPlayerTransformer", + "description": "Mine Little Pony turns players and mobs into ponies", + "description.minelittlepony": "Mine Little Pony turns players and mobs into ponies", + "description.hdskins": "Seperate skin server for Mine Little Pony that also supports HD skins. Access via Skin Manager key binding (default: F1) in the main menu." +} diff --git a/voxellib/build.gradle b/voxellib/build.gradle new file mode 100644 index 00000000..669bacf4 --- /dev/null +++ b/voxellib/build.gradle @@ -0,0 +1,17 @@ +apply plugin: 'net.minecrell.vanilla' + +archivesBaseName = "lib_voxelcommon" +version = "4.4.0-mc1.8" + +minecraft { + version = "1.8" + mappings = 'snapshot_20150606' + clientTweaker = 'com.mumfrey.liteloader.launch.LiteLoaderTweaker' +} +jar { + extension 'litemod' + archiveName = 'voxelcommon-2.4.0.jar' +} +reobf { + setSrgMcp() +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/LiteModVoxelCommon.java b/voxellib/src/main/java/com/voxelmodpack/common/LiteModVoxelCommon.java new file mode 100644 index 00000000..8e9c4c61 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/LiteModVoxelCommon.java @@ -0,0 +1,131 @@ +package com.voxelmodpack.common; + +import java.io.File; +import java.util.LinkedList; +import java.util.List; + +import com.google.common.collect.ImmutableList; +import com.mumfrey.liteloader.PacketHandler; +import com.mumfrey.liteloader.Priority; +import com.voxelmodpack.common.interfaces.ITimeHandler; + +import net.minecraft.client.Minecraft; +import net.minecraft.network.INetHandler; +import net.minecraft.network.Packet; +import net.minecraft.network.play.INetHandlerPlayClient; +import net.minecraft.network.play.server.S03PacketTimeUpdate; +import net.minecraft.util.ResourceLocation; + +/** + * Main mod class for VoxelCommon + * + * @author Adam Mummery-Smith + */ +@Priority(0) +public class LiteModVoxelCommon implements PacketHandler { + public static final String VERSION = "2.4.0"; + + public static final ResourceLocation GUIPARTS = new ResourceLocation("voxelcommon", "textures/gui/guiparts.png"); + + private static List timeHandlers = new LinkedList(); + + /* + * (non-Javadoc) + * @see com.mumfrey.liteloader.LiteMod#getName() + */ + @Override + public String getName() { + return "VoxelLib"; + } + + /* + * (non-Javadoc) + * @see com.mumfrey.liteloader.LiteMod#getVersion() + */ + @Override + public String getVersion() { + return LiteModVoxelCommon.VERSION; + } + + /* + * (non-Javadoc) + * @see com.mumfrey.liteloader.LiteMod#init(java.io.File) + */ + // @SuppressWarnings("unchecked") + @Override + public void init(File configPath) { + /* + * try { Class voxelPacketListenerClass = (Class)Class.forName( + * "com.voxelmodpack.voxelpacket.client.VoxelPacketListener"); LiteMod + * voxelPacketListener = voxelPacketListenerClass.newInstance(); + * voxelPacketListener.init(configPath); + * LiteLoader.getInterfaceManager().registerListener(voxelPacketListener + * ); } catch (Throwable th) { th.printStackTrace(); } + */ + } + + /* + * (non-Javadoc) + * @see com.mumfrey.liteloader.LiteMod#upgradeSettings(java.lang.String, + * java.io.File, java.io.File) + */ + @Override + public void upgradeSettings(String version, File configPath, File oldConfigPath) {} + + @Override + public List> getHandledPackets() { + return ImmutableList.> of( + S03PacketTimeUpdate.class); + } + + @Override + public boolean handlePacket(INetHandler netHandler, Packet packet) { + S03PacketTimeUpdate timeUpdatePacket = (S03PacketTimeUpdate) packet; + LiteModVoxelCommon.updateTime(netHandler, timeUpdatePacket.func_149366_c(), timeUpdatePacket.func_149365_d()); + return false; + } + + public static void registerTimeHandler(ITimeHandler timeHandler) { + if (!LiteModVoxelCommon.timeHandlers.contains(timeHandler)) { + LiteModVoxelCommon.timeHandlers.add(timeHandler); + } + } + + public static void updateTime(long totalTime, long worldTime) { + Minecraft mc = Minecraft.getMinecraft(); + if (mc.thePlayer != null && mc.thePlayer.sendQueue != null) { + LiteModVoxelCommon.updateTime(mc.thePlayer.sendQueue, totalTime, worldTime); + } + } + + /** + * @param netHandler + * @param totalTime + * @param worldTime + */ + private static void updateTime(INetHandler netHandler, long totalTime, long worldTime) { + boolean frozen = worldTime < 0L; + worldTime = Math.abs(worldTime); + + long inTotalTime = totalTime; + long inWorldTime = worldTime; + + for (ITimeHandler timeHandler : LiteModVoxelCommon.timeHandlers) { + timeHandler.onTimeUpdate(totalTime, worldTime); + } + + for (ITimeHandler timeHandler : LiteModVoxelCommon.timeHandlers) { + if (timeHandler.isFreezingTime()) { + frozen = true; + totalTime = timeHandler.getFrozenTotalTime(inTotalTime); + worldTime = timeHandler.getFrozenWorldTime(inWorldTime); + break; + } + + worldTime += timeHandler.getTimeOffset(); + } + + ((INetHandlerPlayClient) netHandler).handleTimeUpdate(new S03PacketTimeUpdate(totalTime, worldTime, !frozen)); + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gl/FBO.java b/voxellib/src/main/java/com/voxelmodpack/common/gl/FBO.java new file mode 100644 index 00000000..61b598e8 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gl/FBO.java @@ -0,0 +1,309 @@ +package com.voxelmodpack.common.gl; + +import static com.mumfrey.liteloader.gl.GL.*; + +import java.awt.image.BufferedImage; + +import org.lwjgl.opengl.ContextCapabilities; +import org.lwjgl.opengl.GLContext; + +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; +import static org.lwjgl.opengl.EXTFramebufferObject.*; +import static org.lwjgl.opengl.ARBFramebufferObject.*; + +/** + * Object-oriented wrapper for basic OpenGL FBOs with only a colour and depth + * buffer + * + * @author Adam Mummery-Smith + */ +public class FBO { + private static boolean supported = false; + + private static boolean useARB = false; + + /** + * This FBO is created + */ + private boolean created; + + /** + * FBO is bound + */ + private boolean active; + + /** + * Handle to the depth buffer resource + */ + private int depthBuffer; + + /** + * Handle to the frame buffer resource + */ + private int frameBuffer; + + /** + * Handle to the FBOs texture assigned by the renderer + */ + private DynamicTexture texture; + + /** + * Width and height for the current frame buffer, used so we know to + * regenerate it if the frame size changes + */ + private int frameBufferWidth, frameBufferHeight; + + /** + * Helper function to check that FBOs are supported + * + * @return True if EXT or ARB framebuffer support is available on the + * hardware + */ + public static boolean detectFBOCapabilities() { + ContextCapabilities capabilities = GLContext.getCapabilities(); + + if (capabilities.GL_ARB_framebuffer_object) { + supported = true; + useARB = true; + return true; + } else if (capabilities.GL_EXT_framebuffer_object) { + supported = true; + return true; + } + + supported = false; + return false; + } + + /** + * Create a new FBO, the internal FBO itself is not created until the first + * call to Begin() is made + * + * @param renderEngine Minecraft render engine + */ + public FBO() { + detectFBOCapabilities(); + } + + /** + * Get whether FBO is supported by the graphics hardware + */ + public static boolean isSupported() { + return supported; + } + + /** + * Begin + * + * @param width + * @param height + */ + public void begin(int width, int height) { + if (!supported) { + return; + } + + if (width < 1 || height < 1) { + throw new IllegalArgumentException("Attempted to create an FBO with zero or negative size"); + } + + if (this.created && (width != this.frameBufferWidth || height != this.frameBufferHeight)) { + this.dispose(); + } + + if (!this.created) { + this.created = true; + this.frameBufferWidth = width; + this.frameBufferHeight = height; + + BufferedImage textureImage = new BufferedImage(this.frameBufferWidth, this.frameBufferHeight, + BufferedImage.TYPE_INT_RGB); + this.texture = new DynamicTexture(textureImage); + + if (useARB) { + this.frameBuffer = glGenFramebuffers(); + this.depthBuffer = glGenRenderbuffers(); + + glBindFramebuffer(GL_FRAMEBUFFER, this.frameBuffer); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + this.texture.getGlTextureId(), 0); + + glBindRenderbuffer(GL_RENDERBUFFER, this.depthBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, this.frameBufferWidth, + this.frameBufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, this.depthBuffer); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + } else { + this.frameBuffer = glGenFramebuffersEXT(); + this.depthBuffer = glGenRenderbuffersEXT(); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this.frameBuffer); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, + this.texture.getGlTextureId(), 0); + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, this.depthBuffer); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, this.frameBufferWidth, + this.frameBufferHeight); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, + this.depthBuffer); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } + } + + this.bind(); + } + + /** + * + */ + public void bind() { + if (!supported) { + return; + } + + if (this.created && this.checkFBO()) { + if (useARB) { + glBindFramebuffer(GL_FRAMEBUFFER, this.frameBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, this.depthBuffer); + } else { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this.frameBuffer); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, this.depthBuffer); + } + + glPushAttrib(GL_VIEWPORT_BIT); + glViewport(0, 0, this.frameBufferWidth, this.frameBufferHeight); + glClear(GL_COLOR_BUFFER_BIT); + this.active = true; + } + // else + // { + // System.err.println("Bad fbo"); + // } + } + + public void end() { + if (supported && this.active) { + if (useARB) { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + } else { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } + + glPopAttrib(); + this.active = false; + } + } + + public void dispose() { + if (!supported) { + return; + } + + this.end(); + + if (this.texture != null) { + glDeleteTextures(this.texture.getGlTextureId()); + } + + if (useARB) { + glDeleteRenderbuffers(this.depthBuffer); + glDeleteFramebuffers(this.frameBuffer); + } else { + glDeleteRenderbuffersEXT(this.depthBuffer); + glDeleteFramebuffersEXT(this.frameBuffer); + } + + this.depthBuffer = 0; + this.texture = null; + this.frameBuffer = 0; + this.created = false; + } + + /** + * FBO completeness check + * + * @param fboID + * @return + */ + private boolean checkFBO() { + if (useARB) { + glBindFramebuffer(GL_FRAMEBUFFER, this.frameBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, this.depthBuffer); + } else { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this.frameBuffer); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, this.depthBuffer); + } + + int frameBufferStatus = useARB ? glCheckFramebufferStatus(GL_FRAMEBUFFER) + : glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + + // status + switch (frameBufferStatus) { + case GL_FRAMEBUFFER_COMPLETE_EXT: + return true; + + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: + case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: + return false; + + default: + throw new RuntimeException("Unexpected reply from glCheckFramebufferStatus: " + frameBufferStatus); + } + } + + /** + * Draw this FBO + * + * @param x + * @param y + * @param x2 + * @param y2 + * @param z + * @param alpha + */ + public void draw(int x, int y, int x2, int y2, int z, float alpha) { + this.draw(x, y, x2, y2, z, alpha, 0.0, 0.0, 1.0, 1.0); + } + + /** + * @param x + * @param y + * @param x2 + * @param y2 + * @param z + * @param alpha + * @param u + * @param v + * @param u2 + * @param v2 + */ + public void draw(double x, double y, double x2, double y2, double z, float alpha, double u, double v, double u2, + double v2) { + if (supported && this.created) { + glEnableTexture2D(); + glBindTexture2D(this.texture.getGlTextureId()); + glColor4f(1, 1, 1, alpha); + + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldRender = tessellator.getWorldRenderer(); + worldRender.startDrawingQuads(); + worldRender.addVertexWithUV(x, y2, z, u, v); + worldRender.addVertexWithUV(x2, y2, z, u2, v); + worldRender.addVertexWithUV(x2, y, z, u2, v2); + worldRender.addVertexWithUV(x, y, z, u, v2); + tessellator.draw(); + } + } +} \ No newline at end of file diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gl/TextureHelper.java b/voxellib/src/main/java/com/voxelmodpack/common/gl/TextureHelper.java new file mode 100644 index 00000000..dc7d6572 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gl/TextureHelper.java @@ -0,0 +1,28 @@ +package com.voxelmodpack.common.gl; + +import static com.mumfrey.liteloader.gl.GL.*; + +import java.util.Map; + +import com.voxelmodpack.common.runtime.PrivateFields; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.renderer.texture.ITextureObject; +import net.minecraft.util.ResourceLocation; + +public abstract class TextureHelper { + public static void releaseTexture(ResourceLocation resource) { + TextureManager textureManager = Minecraft.getMinecraft().getTextureManager(); + ITextureObject textureObject = textureManager.getTexture(resource); + + if (textureObject != null) { + int textureName = textureObject.getGlTextureId(); + glDeleteTextures(textureName); + + Map resourceToTextureMap = PrivateFields.resourceToTextureMap + .get(textureManager); + resourceToTextureMap.remove(resource); + } + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiCheckBox.java b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiCheckBox.java new file mode 100644 index 00000000..6d5fcfd4 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiCheckBox.java @@ -0,0 +1,164 @@ +package com.voxelmodpack.common.gui; + +import static com.mumfrey.liteloader.gl.GL.glColor4f; + +import com.voxelmodpack.common.LiteModVoxelCommon; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; + +/** + * Simple checkbox-like control + * + * @author Adam Mummery-Smith + */ +public class GuiCheckBox extends GuiControl { + public enum DisplayStyle { + Button, + CheckBox, + KeyboardKey + } + + public DisplayStyle Style = DisplayStyle.CheckBox; + + /** + * True if the checkbox is checked + */ + public boolean checked; + + /** + * Make a new check box control, automatically size the control to fit the + * specified text + * + * @param id Control ID + * @param xPosition X location for the control + * @param yPosition Y location for the control + * @param displayText Text to display + * @param checked Initially checked value + */ + public GuiCheckBox(int id, int xPosition, int yPosition, String displayText, boolean checked) { + super(id, xPosition, yPosition, displayText); + + this.setWidth(Minecraft.getMinecraft().fontRendererObj.getStringWidth(displayText) + 20); + this.checked = checked; + } + + /** + * Make a new check box control, automatically size the control to fit the + * specified text + * + * @param id Control ID + * @param xPosition X location for the control + * @param yPosition Y location for the control + * @param displayText Text to display + * @param checked Initially checked value + */ + public GuiCheckBox(int id, int xPosition, int yPosition, String displayText, boolean checked, DisplayStyle style) { + super(id, xPosition, yPosition, displayText); + + this.setWidth(Minecraft.getMinecraft().fontRendererObj.getStringWidth(displayText) + 20); + this.checked = checked; + this.Style = style; + } + + /** + * Make a new check box control of the specified size + * + * @param id Control ID + * @param xPosition X location for the control + * @param yPosition Y location for the control + * @param width Width for the control (text may overflow or underflow) + * @param height Height for the control (check box and text will be centered + * vertically within this height) + * @param displayText Text to display + * @param checked Initially checked value + */ + public GuiCheckBox(int id, int xPosition, int yPosition, int width, int height, String displayText, + boolean checked) { + super(id, xPosition, yPosition, width, height, displayText); + + this.checked = checked; + } + + /** + * Make a new check box control of the specified size + * + * @param id Control ID + * @param xPosition X location for the control + * @param yPosition Y location for the control + * @param width Width for the control (text may overflow or underflow) + * @param height Height for the control (check box and text will be centered + * vertically within this height) + * @param displayText Text to display + * @param checked Initially checked value + */ + public GuiCheckBox(int id, int xPosition, int yPosition, int width, int height, String displayText, boolean checked, + DisplayStyle style) { + super(id, xPosition, yPosition, width, height, displayText); + + this.checked = checked; + this.Style = style; + } + + public void drawCheckboxAt(Minecraft minecraft, int mouseX, int mouseY, int yPos) { + this.setYPosition(yPos); + this.drawButton(minecraft, mouseX, mouseY); + } + + /** + * Draw the control + * + * @param minecraft Minecraft instance + * @param mouseX Mouse x coordinate + * @param mouseY Mouse y coordinate + */ + @Override + public void drawButton(Minecraft minecraft, int mouseX, int mouseY) { + // Control not visible + if (!this.isVisible()) + return; + + boolean mouseOver = mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width + && mouseY < this.yPosition + this.height; + + if (this.Style == DisplayStyle.Button) { + super.drawButton(minecraft, mouseX, mouseY); + } else if (this.Style == DisplayStyle.CheckBox) { + minecraft.getTextureManager().bindTexture(LiteModVoxelCommon.GUIPARTS); + glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + int u = this.checked ? 12 : 0; + int y = this.yPosition + (this.height - 12) / 2; + + this.drawTexturedModalRect(this.xPosition, y, this.xPosition + 12, y + 12, u, 52, u + 12, 64); + this.mouseDragged(minecraft, mouseX, mouseY); + this.drawString(minecraft.fontRendererObj, this.displayString, this.xPosition + 16, + this.yPosition + (this.height - 8) / 2, + this.isEnabled() ? (mouseOver ? 0xa0ffff : 0xe0e0e0) : 0xffa0a0a0); + } else { + Gui.drawRect(this.xPosition, this.yPosition, this.xPosition + this.width, this.yPosition + this.height, + this.checked ? 0xFFFFFF00 : 0xFF808080); + Gui.drawRect(this.xPosition + 1, this.yPosition + 1, this.xPosition + this.width - 1, + this.yPosition + this.height - 1, mouseOver ? 0xFF333333 : 0xFF000000); + this.drawCenteredString(minecraft.fontRendererObj, this.displayString, this.xPosition + (this.width / 2), + this.yPosition + (this.height - 8) / 2, + this.isEnabled() ? (mouseOver ? 0xa0ffff : (this.checked ? 0xFFFFFF00 : 0xe0e0e0)) : 0xffa0a0a0); + } + } + + /** + * @param minecraft + * @param mouseX + * @param mouseY + * @return + */ + @Override + public boolean mousePressed(Minecraft minecraft, int mouseX, int mouseY) { + if (super.mousePressed(minecraft, mouseX, mouseY)) { + this.checked = !this.checked; + return true; + } + + return false; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiControl.java b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiControl.java new file mode 100644 index 00000000..a047a270 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiControl.java @@ -0,0 +1,104 @@ +package com.voxelmodpack.common.gui; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; + +/** + * Vestigial abstraction class, not really required any more since MCP updates + * so quickly but has some handy convenience methods + * + * @author Adam Mummery-Smith + */ +public class GuiControl extends GuiButton { + /** + * Scale factor which translates texture pixel coordinates to relative + * coordinates + */ + protected static float texMapScale = 0.00390625F; + + public GuiControl(int id, int xPosition, int yPosition, String displayText) { + super(id, xPosition, yPosition, displayText); + } + + public GuiControl(int id, int xPosition, int yPosition, int controlWidth, int controlHeight, String displayText) { + super(id, xPosition, yPosition, controlWidth, controlHeight, displayText); + } + + /** + * Draws a textured rectangle with custom UV coordinates + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + */ + public void drawTexturedModalRect(int x, int y, int x2, int y2, int u, int v, int u2, int v2) { + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldRender = tessellator.getWorldRenderer(); + worldRender.startDrawingQuads(); + worldRender.addVertexWithUV(x, y2, this.getZLevel(), (u) * texMapScale, (v2) * texMapScale); + worldRender.addVertexWithUV(x2, y2, this.getZLevel(), (u2) * texMapScale, (v2) * texMapScale); + worldRender.addVertexWithUV(x2, y, this.getZLevel(), (u2) * texMapScale, (v) * texMapScale); + worldRender.addVertexWithUV(x, y, this.getZLevel(), (u) * texMapScale, (v) * texMapScale); + tessellator.draw(); + } + + public final int getID() { + return this.id; + } + + public final int getHeight() { + return this.height; + } + + public final void setHeight(int newHeight) { + this.height = newHeight; + } + + public final int getXPosition() { + return this.xPosition; + } + + public final void setXPosition(int newXPosition) { + this.xPosition = newXPosition; + } + + public final int getYPosition() { + return this.yPosition; + } + + public final void setYPosition(int newYPosition) { + this.yPosition = newYPosition; + } + + public final boolean isEnabled() { + return this.enabled; + } + + public final void setEnabled(boolean newEnabled) { + this.enabled = newEnabled; + } + + public final boolean isVisible() { + return this.visible; + } + + public final void setVisible(boolean newVisible) { + this.visible = newVisible; + } + + protected final float getZLevel() { + return this.zLevel; + } + + @Override + public void drawString(FontRenderer fontRendererIn, String text, int x, int y, int color) { + super.drawString(fontRendererIn, text, x, y, color); + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiControlEx.java b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiControlEx.java new file mode 100644 index 00000000..e67e1460 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiControlEx.java @@ -0,0 +1,399 @@ +package com.voxelmodpack.common.gui; + +import static com.mumfrey.liteloader.gl.GL.*; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; + +/** + * GuiControlEx is the base class for additional controls. It includes some + * advanced drawing methods which are used by several derived classes + * + * @author Adam Mummery-Smith + */ +public abstract class GuiControlEx extends GuiControl { + /** + * Used by some controls to indicate the manner in which they have handled a + * keypress + */ + public enum KeyHandledState { + /** + * The control did not handle the keypress + */ + None, + + /** + * The control handled the keypress and the container should do no + * further processing + */ + Handled, + + /** + * The control handled the keypress and the container should call + * actionPerformed + */ + ActionPerformed + } + + /** + * Set by parent screen to enable cursor flash etc + */ + public int updateCounter; + + /** + * Reference to the minecraft game instance + */ + protected Minecraft mc; + + /** + * Flag indicating whether an action was performed, to support GuiScreenEx's + * callback mechanism + */ + protected boolean actionPerformed; + + /** + * Flag tracking whether an item was double-clicked + */ + protected boolean doubleClicked; + + /** + * Constructor, passes through to GuiButton constructor + * + * @param minecraft Minecraft game instance + * @param controlId Control's ID (used for actionPerformed) + * @param xPos Control X position (left) + * @param yPos Control Y position (top) + * @param controlWidth Control width + * @param controlHeight Control height + * @param displayText Control display text + */ + public GuiControlEx(Minecraft minecraft, int controlId, int xPos, int yPos, int controlWidth, int controlHeight, + String displayText) { + super(controlId, xPos, yPos, controlWidth, controlHeight, displayText); + this.mc = minecraft; + } + + /** + * Override from GuiButton, handle this call and forward it to DrawControl + * for neatness + * + * @param minecraft Reference to the minecraft game instance + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + */ + @Override + public final void drawButton(Minecraft minecraft, int mouseX, int mouseY) { + this.drawControl(minecraft, mouseX, mouseY); + } + + /** + * Draw the control + * + * @param minecraft Reference to the minecraft game instance + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + */ + protected abstract void drawControl(Minecraft minecraft, int mouseX, int mouseY); + + /** + * GuiControlEx returns true from mousePressed if the mouse was captured, + * NOT if an action was performed. Containers should call this function + * afterwards to determine whether an action was performed. + * + * @return True if actionPerformed should be dispatched + */ + public boolean getActionPerformed() { + return this.actionPerformed; + } + + /** + * Get whether an actionPerformed was a double-click event + * + * @return + */ + public boolean getDoubleClicked(boolean resetDoubleClicked) { + boolean result = this.doubleClicked; + if (resetDoubleClicked) + this.doubleClicked = false; + return result; + } + + /** + * Draws a line between two points with the specified width and colour + * + * @param x1 Origin x coordinate + * @param y1 Origin y coordinate + * @param x2 End x coordinate + * @param y2 End y coordinate + * @param width Line width in pixels + * @param colour Line colour + */ + protected void drawLine(int x1, int y1, int x2, int y2, int width, int colour) { + this.drawArrow(x1, y1, x2, y2, width, colour, false, 0); + } + + /** + * Draws an arrow between two points with the specified width and colour + * + * @param x1 Origin x coordinate + * @param y1 Origin y coordinate + * @param x2 End x coordinate + * @param y2 End y coordinate + * @param width Line width in pixels + * @param arrowHeadSize Size of the arrow head + * @param colour Colour + */ + protected void drawArrow(int x1, int y1, int x2, int y2, int width, int arrowHeadSize, int colour) { + this.drawArrow(x1, y1, x2, y2, width, colour, true, arrowHeadSize); + } + + /** + * Internal function for drawing lines and arrows + * + * @param x1 Origin x coordinate + * @param y1 Origin y coordinate + * @param x2 End x coordinate + * @param y2 End y coordinate + * @param width Line width in pixels + * @param colour Colour + * @param arrowHead True to draw an arrow, otherwise draws a line + * @param arrowHeadSize Size of the arrow head + */ + private void drawArrow(int x1, int y1, int x2, int y2, int width, int colour, boolean arrowHead, + int arrowHeadSize) { + // Calculate the line length and angle defined by the specified points + int length = (int) Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2)); + float angle = (float) Math.toDegrees(Math.atan2(y2 - y1, x2 - x1)); + + // Local rotation + glPushMatrix(); + glTranslatef(x1, y1, 0.0f); + glRotatef(angle, 0.0f, 0.0f, 1.0f); + + // Calc coordinates for the line and arrow points + x1 = 0; + x2 = length - (arrowHead ? arrowHeadSize : 0); + y1 = (int) (width * -0.5); + y2 = y1 + width; + + // Calc colour components + float f = (colour >> 24 & 0xff) / 255F; + float f1 = (colour >> 16 & 0xff) / 255F; + float f2 = (colour >> 8 & 0xff) / 255F; + float f3 = (colour & 0xff) / 255F; + + glEnableBlend(); + glDisableTexture2D(); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(f1, f2, f3, f); + + // Draw the line + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldRender = tessellator.getWorldRenderer(); + worldRender.startDrawingQuads(); + worldRender.addVertex(x1, y2, 0.0D); + worldRender.addVertex(x2, y2, 0.0D); + worldRender.addVertex(x2, y1, 0.0D); + worldRender.addVertex(x1, y1, 0.0D); + tessellator.draw(); + + // If an arrow then draw the arrow head + if (arrowHead && arrowHeadSize > 0) { + worldRender.startDrawing(4); + worldRender.addVertex(x2, 0 - arrowHeadSize / 2, 0); + worldRender.addVertex(x2, arrowHeadSize / 2, 0); + worldRender.addVertex(length, 0, 0); + tessellator.draw(); + } + + glEnableTexture2D(); + glDisableBlend(); + + glPopMatrix(); + } + + /** + * Set the texmap scale factor + * + * @param textureSize + */ + public void setTexMapSize(int textureSize) { + texMapScale = 1F / textureSize; + } + + /** + * Draws a textured rectangle at 90 degrees + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + */ + public void drawTexturedModalRectRot(int x, int y, int x2, int y2, int u, int v, int u2, int v2) { + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldRender = tessellator.getWorldRenderer(); + worldRender.startDrawingQuads(); + worldRender.addVertexWithUV(x2, y2, this.getZLevel(), (u) * texMapScale, (v2) * texMapScale); + worldRender.addVertexWithUV(x2, y, this.getZLevel(), (u2) * texMapScale, (v2) * texMapScale); + worldRender.addVertexWithUV(x, y, this.getZLevel(), (u2) * texMapScale, (v) * texMapScale); + worldRender.addVertexWithUV(x, y2, this.getZLevel(), (u) * texMapScale, (v) * texMapScale); + tessellator.draw(); + } + + /** + * Draws a textured rectangle at 90 degrees + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param width Width of texture to draw + * @param height Height of texture to draw + */ + public void drawTexturedModalRectRot(int x, int y, int u, int v, int width, int height) { + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldRender = tessellator.getWorldRenderer(); + worldRender.startDrawingQuads(); + worldRender.addVertexWithUV(x + height, y + width, this.getZLevel(), (u) * texMapScale, + (v + height) * texMapScale); + worldRender.addVertexWithUV(x + height, y, this.getZLevel(), (u + width) * texMapScale, + (v + height) * texMapScale); + worldRender.addVertexWithUV(x, y, this.getZLevel(), (u + width) * texMapScale, (v) * texMapScale); + worldRender.addVertexWithUV(x, y + width, this.getZLevel(), (u) * texMapScale, (v) * texMapScale); + tessellator.draw(); + } + + /** + * Draws a tesselated rectangle where the texture is stretched horizontally + * but vertical scaling is achieved by splitting the texture in half and + * repeating the middle pixels + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + */ + public void drawTessellatedModalRectV(int x, int y, int x2, int y2, int u, int v, int u2, int v2) { + int tileSize = ((v2 - v) / 2); + int vMidTop = v + tileSize; + int vMidBtm = vMidTop + 1; + + this.drawTexturedModalRect(x, y, x2, y + tileSize, u, v, u2, vMidTop); + this.drawTexturedModalRect(x, y + tileSize, x2, y2 - tileSize + 1, u, vMidTop, u2, vMidBtm); + this.drawTexturedModalRect(x, y2 - tileSize + 1, x2, y2, u, vMidBtm, u2, v2); + } + + /** + * Draws a tesselated rectangle where the texture is stretched vertically + * but horizontal scaling is achieved by splitting the texture in half and + * repeating the middle pixels + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + */ + public void drawTessellatedModalRectH(int x, int y, int x2, int y2, int u, int v, int u2, int v2) { + int tileSize = ((u2 - u) / 2); + int uMidLeft = u + tileSize; + int uMidRight = uMidLeft + 1; + + this.drawTexturedModalRect(x, y, x + tileSize, y2, u, v, uMidLeft, v2); + this.drawTexturedModalRect(x + tileSize, y, x2 - tileSize + 1, y2, uMidLeft, v, uMidRight, v2); + this.drawTexturedModalRect(x2 - tileSize + 1, y, x2, y2, uMidRight, v, u2, v2); + } + + /** + * Draws a tesselated rectangle where the texture is stretched vertically + * and horizontally but the middle pixels are repeated whilst the joining + * pixels are stretched. + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + */ + public void drawTessellatedModalBorderRect(int x, int y, int x2, int y2, int u, int v, int u2, int v2) { + this.drawTessellatedModalBorderRect(x, y, x2, y2, u, v, u2, v2, + Math.min(((x2 - x) / 2) - 1, ((y2 - y) / 2) - 1)); + } + + /** + * Draws a tesselated rectangle where the texture is stretched vertically + * and horizontally but the middle pixels are repeated whilst the joining + * pixels are stretched. Bordersize specifies the portion of the texture + * which will remain unstretched. + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + * @param borderSize Number of pixels to leave unstretched, must be less + * than half of the width or height (whichever is smallest) + */ + public void drawTessellatedModalBorderRect(int x, int y, int x2, int y2, int u, int v, int u2, int v2, + int borderSize) { + int tileSize = Math.min(((u2 - u) / 2) - 1, ((v2 - v) / 2) - 1); + + int ul = u + tileSize, ur = u2 - tileSize, vt = v + tileSize, vb = v2 - tileSize; + int xl = x + borderSize, xr = x2 - borderSize, yt = y + borderSize, yb = y2 - borderSize; + + this.drawTexturedModalRect(x, y, xl, yt, u, v, ul, vt); + this.drawTexturedModalRect(xl, y, xr, yt, ul, v, ur, vt); + this.drawTexturedModalRect(xr, y, x2, yt, ur, v, u2, vt); + this.drawTexturedModalRect(x, yb, xl, y2, u, vb, ul, v2); + this.drawTexturedModalRect(xl, yb, xr, y2, ul, vb, ur, v2); + this.drawTexturedModalRect(xr, yb, x2, y2, ur, vb, u2, v2); + this.drawTexturedModalRect(x, yt, xl, yb, u, vt, ul, vb); + this.drawTexturedModalRect(xr, yt, x2, yb, ur, vt, u2, vb); + this.drawTexturedModalRect(xl, yt, xr, yb, ul, vt, ur, vb); + } + + /** + * Draw a string but cut it off if it's too long to fit in the specified + * width + * + * @param fontrenderer + * @param s + * @param x + * @param y + * @param width + * @param colour + */ + public static void drawStringWithEllipsis(FontRenderer fontrenderer, String s, int x, int y, int width, + int colour) { + if (fontrenderer.getStringWidth(s) <= width) { + fontrenderer.drawStringWithShadow(s, x, y, colour); + } else if (width < 8) { + fontrenderer.drawStringWithShadow("..", x, y, colour); + } else { + String trimmedText = s; + + while (fontrenderer.getStringWidth(trimmedText) > width - 8 && trimmedText.length() > 0) + trimmedText = trimmedText.substring(0, trimmedText.length() - 1); + + fontrenderer.drawStringWithShadow(trimmedText + "...", x, y, colour); + } + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiDialogBox.java b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiDialogBox.java new file mode 100644 index 00000000..096f067e --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiDialogBox.java @@ -0,0 +1,366 @@ +package com.voxelmodpack.common.gui; + +import java.awt.Point; +import java.io.IOException; + +import org.lwjgl.input.Keyboard; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.resources.I18n; + +/** + * Base class for GUI Screens which behave like dialog boxes + * + * @author Adam Mummery-Smith + */ +public abstract class GuiDialogBox extends GuiScreenEx { + public static int lastScreenWidth, lastScreenHeight; + + public enum DialogResult { + /** + * No result (maybe the dialog was not closed yet?) + */ + None, + + /** + * Dialog result OK (user clicked OK or pressed RETURN) + */ + OK, + + /** + * Dialog result Cancel (user clicked Cancel or pressed ESCAPE) + */ + Cancel, + + Yes, + + No + } + + private GuiScreen parentScreen; + + /** + * Parent screen which will be notified when this dialog is closed + */ + // protected GuiScreenEx parentScreenEx; + + /** + * Dialog box buttons + */ + protected GuiButton btnOk, btnCancel; + + /** + * Dialog box position and size + */ + protected int dialogX, dialogY, dialogWidth, dialogHeight; + + /** + * Title to display at the top of the dialog box + */ + protected String dialogTitle; + + /** + * True to centre the title + */ + protected boolean centreTitle = true; + + /** + * Colour for the window title + */ + protected int dialogTitleColour = 0xFFFFFF00; + + /** + * Dialog result based on the user's action + */ + public DialogResult dialogResult = DialogResult.None; + + /** + * This dialog box can be moved + */ + protected boolean movable = false; + + protected boolean dragging = false; + + protected Point dragOffset = new Point(0, 0); + + @SuppressWarnings("unused") + private boolean generateMouseDragEvents; + + /** + * Constructor, create a new GuiDialogBox + * + * @param parentScreen Screen which owns this dialog + * @param width + * @param height + * @param windowTitle + */ + public GuiDialogBox(GuiScreen parentScreen, int width, int height, String windowTitle) { + this.parentScreen = parentScreen; + this.dialogWidth = width; + this.dialogHeight = height; + this.dialogTitle = windowTitle; + + this.generateMouseDragEvents = true; + } + + /** + * Close the dialog box and display the parent screen (if it is available, + * otherwise clear the gui) + */ + protected void closeDialog() { + this.mc.displayGuiScreen(this.getParentScreen()); + } + + /** + * Handle a button event + * + * @param guibutton Button or control which sourced the event + */ + @Override + protected void actionPerformed(GuiButton guibutton) { + if (guibutton.id == this.btnCancel.id) { + this.dialogResult = DialogResult.Cancel; + this.closeDialog(); + } + if (guibutton.id == this.btnOk.id) { + if (this.validateDialog()) { + this.dialogResult = DialogResult.OK; + this.onSubmit(); + this.closeDialog(); + } + } + } + + /** + * Handle a keyboard event + */ + @Override + protected final void keyTyped(char keyChar, int keyCode) { + if (keyCode == Keyboard.KEY_ESCAPE) { + this.actionPerformed(this.btnCancel); + } else if (keyCode == Keyboard.KEY_RETURN) { + this.actionPerformed(this.btnOk); + } else { + this.onKeyTyped(keyChar, keyCode); + } + } + + /* + * (non-Javadoc) + * @see net.eq2online.macros.gui.shared.GuiScreenEx#mouseClicked(int, int, + * int) + */ + @Override + protected final void mouseClicked(int mouseX, int mouseY, int button) throws IOException { + if (button == 0 && this.movable && mouseX > this.dialogX && mouseX < this.dialogX + this.dialogWidth + && mouseY > this.dialogY - 18 && mouseY < this.dialogY) { + this.dragOffset = new Point(mouseX - this.dialogX, mouseY - this.dialogY); + this.dragging = true; + } else { + this.mouseClickedEx(mouseX, mouseY, button); + } + } + + /** + * @param mouseX + * @param mouseY + * @param button + * @throws IOException + */ + protected void mouseClickedEx(int mouseX, int mouseY, int button) throws IOException { + super.mouseClicked(mouseX, mouseY, button); + } + + /* + * (non-Javadoc) + * @see net.minecraft.client.gui.GuiScreen#mouseReleased(int, int, int) + */ + @Override + protected void mouseReleased(int mouseX, int mouseY, int button) { + if (this.dragging) { + this.dialogX = mouseX - this.dragOffset.x; + this.dialogY = mouseY - this.dragOffset.y; + this.initGui(); + } + + if (button == 0 && this.dragging) { + if (this.dialogX < 0) + this.dialogX = 0; + if (this.dialogX > this.width) + this.dialogX = this.width - this.dialogWidth; + if (this.dialogY < 9) + this.dialogY = 18; + if (this.dialogY > this.height) + this.dialogY = this.height - this.dialogHeight; + this.initGui(); + this.dragging = false; + return; + } + + super.mouseReleased(mouseX, mouseY, button); + } + + /** + * Initialise the dialog box + */ + @Override + public final void initGui() { + super.initGui(); + + Keyboard.enableRepeatEvents(true); + + // Call to owner since the owner is still drawn whilst we are being + // displayed + if (this.getParentScreen() != null) + this.getParentScreen().initGui(); + + if (!this.dragging) { + // Draw the dialog centered unless moved by the parent + this.dialogX = (this.width - this.dialogWidth) / 2; + this.dialogY = (this.height - this.dialogHeight) / 2; + } + + this.btnOk = new GuiButton(-1, this.dialogX + this.dialogWidth - 62, this.dialogY + this.dialogHeight - 22, 60, + 20, I18n.format("gui.done")); + this.btnCancel = new GuiButton(-2, this.dialogX + this.dialogWidth - 124, this.dialogY + this.dialogHeight - 22, + 60, 20, I18n.format("gui.cancel")); + + this.buttonList.clear(); + this.buttonList.add(this.btnOk); + this.buttonList.add(this.btnCancel); + + lastScreenWidth = this.width; + lastScreenHeight = this.height; + + this.onInitDialog(); + } + + @Override + public final void onGuiClosed() { + this.onDialogClosed(); + + Keyboard.enableRepeatEvents(false); + + super.onGuiClosed(); + } + + @Override + public void setWorldAndResolution(Minecraft minecraft, int width, int height) { + super.setWorldAndResolution(minecraft, width, height); + + if (this.getParentScreen() != null) { + this.getParentScreen().setWorldAndResolution(minecraft, width, height); + } + } + + @Override + public final void drawScreen(int mouseX, int mouseY, float partialTick) { + this.drawParentScreen(mouseX, mouseY, partialTick); + + int backColour = 0xAA000000; + int backColour2 = 0xCC333333; + + // Header + drawRect(this.dialogX, this.dialogY - 18, this.dialogX + this.dialogWidth, this.dialogY, backColour2); + + if (this.centreTitle) + this.drawCenteredString(this.mc.fontRendererObj, this.dialogTitle, this.dialogX + (this.dialogWidth / 2), + this.dialogY - 13, this.dialogTitleColour); + else + this.drawString(this.mc.fontRendererObj, this.dialogTitle, this.dialogX + 5, this.dialogY - 13, + this.dialogTitleColour); + + // Dialog body + drawRect(this.dialogX, this.dialogY, this.dialogX + this.dialogWidth, this.dialogY + this.dialogHeight, + backColour); + + // Subclasses + this.drawDialog(mouseX, mouseY, partialTick); + + // Superclass (buttons etc.) + super.drawScreen(mouseX, mouseY, partialTick); + + this.postRender(mouseX, mouseY, partialTick); + } + + @Override + public void updateScreen() { + if (this.getParentScreen() != null) { + this.getParentScreen().updateScreen(); + } + + super.updateScreen(); + } + + /** + * @param partialTick + */ + public void drawParentScreen(int mouseX, int mouseY, float partialTick) { + if (this.getParentScreen() != null) { + this.getParentScreen().drawScreen(0, 0, partialTick); + drawRect(0, 0, this.width, this.height, 0xAA000000); + } else if (this.mc.theWorld == null) { + this.drawDefaultBackground(); + } + } + + /** + * Stub for subclasses, draw any additional dialog features + * + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + * @param f + */ + protected void drawDialog(int mouseX, int mouseY, float f) { + + } + + /** + * Stub for subclasses, draw any additional dialog features + * + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + * @param f + */ + protected void postRender(int mouseX, int mouseY, float f) { + + } + + /** + * Stub for subclasses, perform any tasks required when the dialog is + * validated and about to be submitted + */ + public abstract void onSubmit(); + + /** + * Stub for subclasses, return true if the dialog can be submitted in its + * current state, or false to prevent submission + * + * @return + */ + public abstract boolean validateDialog(); + + /** + * Stub for subclasses, handle a key typed event + * + * @param keyChar + * @param keyCode + */ + protected void onKeyTyped(char keyChar, int keyCode) {} + + /** + * Stub for subclasses, perform any required initialisation + */ + protected void onInitDialog() {} + + /** + * Stub for subclasses, the gui was closed + */ + protected void onDialogClosed() {} + + public GuiScreen getParentScreen() { + return this.parentScreen; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiDialogBoxConfirm.java b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiDialogBoxConfirm.java new file mode 100644 index 00000000..998820ae --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiDialogBoxConfirm.java @@ -0,0 +1,97 @@ +package com.voxelmodpack.common.gui; + +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.resources.I18n; + +/** + * Confirmation dialog box, displays a message and yes/no buttons + * + * @author Adam Mummery-Smith + * @param + */ +public class GuiDialogBoxConfirm extends GuiDialogBox { + /** + * Message text to display + */ + private String messageText1, messageText2; + + /** + * Metadata for this confirmation, so that the calling class knows what's + * being confirmed! + */ + private T metaData; + + /** + * Constructor with metadata + * + * @param parentScreen Screen which owns this dialog + * @param windowTitle Dialog title + * @param line1 Label line 1 + * @param line2 Label line 2 + * @param metaData Metadata supplied by the owning gui + */ + public GuiDialogBoxConfirm(GuiScreen parentScreen, String windowTitle, String line1, String line2, T metaData) { + this(parentScreen, windowTitle, line1, line2); + this.metaData = metaData; + } + + /** + * Constructor with no metadata + * + * @param parentScreen Screen which owns this dialog + * @param windowTitle Dialog title + * @param line1 Label line 1 + * @param line2 Label line 2 + */ + public GuiDialogBoxConfirm(GuiScreen parentScreen, String windowTitle, String line1, String line2) { + super(parentScreen, 320, 80, windowTitle); + + // Set local labels + this.messageText1 = line1; + this.messageText2 = line2; + } + + /** + * Get the meta data passed to this dialog when it was created + * + * @return Meta data (if any) + */ + public T GetMetaData() { + return this.metaData; + } + + @Override + protected void onInitDialog() { + this.btnOk.displayString = I18n.format("gui.yes"); + this.btnCancel.displayString = I18n.format("gui.no"); + } + + @Override + public void onSubmit() {} + + @Override + public boolean validateDialog() { + return true; + } + + @Override + protected void drawDialog(int mouseX, int mouseY, float f) { + // Label + drawCenteredString(this.fontRendererObj, this.messageText1, this.dialogX + (this.dialogWidth / 2), + this.dialogY + 18, 0xFFFFAA00); + drawCenteredString(this.fontRendererObj, this.messageText2, this.dialogX + (this.dialogWidth / 2), + this.dialogY + 32, 0xFFFFAA00); + } + + /* + * (non-Javadoc) + * @see net.eq2online.macros.gui.shared.GuiDialogBox#KeyTyped(char, int) + */ + @Override + protected void onKeyTyped(char keyChar, int keyCode) { + if (keyChar == 'y' || keyChar == 'Y') + actionPerformed(this.btnOk); + if (keyChar == 'n' || keyChar == 'N') + actionPerformed(this.btnCancel); + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiScreenEx.java b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiScreenEx.java new file mode 100644 index 00000000..bd19a9df --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiScreenEx.java @@ -0,0 +1,139 @@ +package com.voxelmodpack.common.gui; + +import static com.mumfrey.liteloader.gl.GL.*; + +import com.voxelmodpack.common.gui.interfaces.IExtendedGui; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.util.ResourceLocation; + +/** + * Class with many extra ways of drawing rectangular images + */ +public abstract class GuiScreenEx extends GuiScreen implements IExtendedGui { + public static float texMapScale = 1F / 256F; + + /* + * (non-Javadoc) + * @see + * com.voxelmodpack.common.gui.IExtendedGui#drawTessellatedModalBorderRect( + * net.minecraft.src.ResourceLocation, int, int, int, int, int, int, int, + * int, int, int) + */ + @Override + public void drawTessellatedModalBorderRect(ResourceLocation texture, int textureSize, int x, int y, int x2, int y2, + int u, int v, int u2, int v2, int borderSize) { + this.drawTessellatedModalBorderRect(texture, textureSize, x, y, x2, y2, u, v, u2, v2, borderSize, true); + } + + /* + * (non-Javadoc) + * @see + * com.voxelmodpack.common.gui.IExtendedGui#drawTessellatedModalBorderRect( + * net.minecraft.src.ResourceLocation, int, int, int, int, int, int, int, + * int, int, int, boolean) + */ + @Override + public void drawTessellatedModalBorderRect(ResourceLocation texture, int textureSize, int x, int y, int x2, int y2, + int u, int v, int u2, int v2, int borderSize, boolean setcolor) { + int tileSize = Math.min(((u2 - u) / 2) - 1, ((v2 - v) / 2) - 1); + + int ul = u + tileSize, ur = u2 - tileSize, vt = v + tileSize, vb = v2 - tileSize; + int xl = x + borderSize, xr = x2 - borderSize, yt = y + borderSize, yb = y2 - borderSize; + + this.setTexMapSize(textureSize); + + Minecraft.getMinecraft().getTextureManager().bindTexture(texture); + + if (setcolor) + glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + this.drawTexturedModalRect(x, y, xl, yt, u, v, ul, vt); + this.drawTexturedModalRect(xl, y, xr, yt, ul, v, ur, vt); + this.drawTexturedModalRect(xr, y, x2, yt, ur, v, u2, vt); + this.drawTexturedModalRect(x, yb, xl, y2, u, vb, ul, v2); + this.drawTexturedModalRect(xl, yb, xr, y2, ul, vb, ur, v2); + this.drawTexturedModalRect(xr, yb, x2, y2, ur, vb, u2, v2); + this.drawTexturedModalRect(x, yt, xl, yb, u, vt, ul, vb); + this.drawTexturedModalRect(xr, yt, x2, yb, ur, vt, u2, vb); + this.drawTexturedModalRect(xl, yt, xr, yb, ul, vt, ur, vb); + } + + /* + * (non-Javadoc) + * @see com.voxelmodpack.common.gui.IExtendedGui#drawTexturedModalRect(net. + * minecraft.src.ResourceLocation, int, int, int, int, int, int, int, int) + */ + @Override + public void drawTexturedModalRect(ResourceLocation texture, int x, int y, int x2, int y2, int u, int v, int u2, + int v2) { + glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + Minecraft.getMinecraft().getTextureManager().bindTexture(texture); + + this.drawTexturedModalRect(x, y, x2, y2, u, v, u2, v2); + } + + /* + * (non-Javadoc) + * @see com.voxelmodpack.common.gui.IExtendedGui#drawTexturedModalRect(int, + * int, int, int, int, int, int, int) + */ + @Override + public void drawTexturedModalRect(int x, int y, int x2, int y2, int u, int v, int u2, int v2) { + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldRender = tessellator.getWorldRenderer(); + worldRender.startDrawingQuads(); + worldRender.addVertexWithUV(x, y2, this.zLevel, u * texMapScale, v2 * texMapScale); + worldRender.addVertexWithUV(x2, y2, this.zLevel, u2 * texMapScale, v2 * texMapScale); + worldRender.addVertexWithUV(x2, y, this.zLevel, u2 * texMapScale, v * texMapScale); + worldRender.addVertexWithUV(x, y, this.zLevel, u * texMapScale, v * texMapScale); + tessellator.draw(); + } + + /** + * Draws a solid color rectangle with the specified coordinates and color. + */ + @SuppressWarnings("cast") + public void drawDepthRect(int x1, int y1, int x2, int y2, int color) { + if (x1 < x2) { + int xTemp = x1; + x1 = x2; + x2 = xTemp; + } + + if (y1 < y2) { + int yTemp = y1; + y1 = y2; + y2 = yTemp; + } + + float alpha = (color >> 24 & 255) / 255.0F; + float red = (color >> 16 & 255) / 255.0F; + float green = (color >> 8 & 255) / 255.0F; + float blue = (color & 255) / 255.0F; + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldRender = tessellator.getWorldRenderer(); + glEnableBlend(); + glDisableTexture2D(); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(red, green, blue, alpha); + worldRender.startDrawingQuads(); + worldRender.addVertex(x1, y2, this.zLevel); + worldRender.addVertex(x2, y2, this.zLevel); + worldRender.addVertex(x2, y1, this.zLevel); + worldRender.addVertex(x1, y1, this.zLevel); + tessellator.draw(); + glEnableTexture2D(); + glDisableBlend(); + } + + /** + * @param textureSize + */ + protected void setTexMapSize(int textureSize) { + GuiScreenEx.texMapScale = 1F / textureSize; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiScrollBar.java b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiScrollBar.java new file mode 100644 index 00000000..daaa1158 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiScrollBar.java @@ -0,0 +1,386 @@ +package com.voxelmodpack.common.gui; + +import static com.mumfrey.liteloader.gl.GL.*; +import net.minecraft.client.Minecraft; + +import com.voxelmodpack.common.LiteModVoxelCommon; + +/** + * General-purpose scrollbar control + * + * @author Adam Mummery-Smith + */ +public class GuiScrollBar extends GuiControlEx { + public enum ScrollBarOrientation { + Vertical, + Horizontal + } + + protected ScrollBarOrientation orientation; + + /** + * Scroll bar minimum value + */ + protected int min; + + /** + * Scroll bar maximum value + */ + protected int max; + + /** + * Scroll bar current value + */ + protected int value; + + /** + * Current visual position of the scroll button relative to the scroll tray + */ + protected int buttonPos = 0; + + /** + * Size of the scroll button + */ + protected int scrollButtonSize = 20; + + /** + * Total scrollable distance + */ + protected int traySize; + + /** + * Mousedown offset relative to the scroll button, used for mouse drag delta + * calculations + */ + protected int dragOffset; + + /** + * Mousedown state, track whether holding down the drag button, up button, + * or down button + */ + protected int mouseDownState = 0; + + /** + * Used to track a small delay before activating scroll on the up/down + * buttons + */ + protected int mouseDownTime = 0; + + /** + * Make a new scrollbar control + * + * @param minecraft Reference to the minecraft game instance + * @param controlId Control ID, used for handling actionPerformed dispatches + * @param xPos Control's X position + * @param yPos Control's Y position + * @param controlWidth Width of the control (also the height of the buttons) + * @param controlHeight Height of the control + * @param minValue Minimum scroll value + * @param maxValue Maximum scroll value + */ + public GuiScrollBar(Minecraft minecraft, int controlId, int xPos, int yPos, int controlWidth, int controlHeight, + int minValue, int maxValue, ScrollBarOrientation orientation) { + super(minecraft, controlId, xPos, yPos, controlWidth, controlHeight, ""); + + this.orientation = orientation; + + this.value = this.min = minValue; + this.max = Math.max(this.min, maxValue); + + this.traySize = this.getLargeDimension() - (this.getSmallDimension() * 2) - this.scrollButtonSize; + } + + protected int getLargeDimension() { + return (this.orientation == ScrollBarOrientation.Vertical) ? this.height : this.width; + } + + protected int getSmallDimension() { + return (this.orientation == ScrollBarOrientation.Vertical) ? this.width : this.height; + } + + /** + * Get the current value of the control + * + * @return current value + */ + public int getValue() { + return this.value; + } + + /** + * Set the current control value + * + * @param value New value (will be clamped within current min and max values + */ + public void setValue(int value) { + this.value = value; + this.updateValue(); + } + + /** + * Set the minimum value for the control, the current value will be clamped + * between min and max + * + * @param value + */ + public void setMin(int value) { + this.min = value; + this.max = Math.max(this.min, this.max); + this.updateValue(); + } + + /** + * Set the maximum value for the control, the current value will be clamped + * between min and max. + * + * @param value + */ + public void setMax(int value) { + this.max = value; + this.min = Math.min(this.max, this.min); + this.updateValue(); + } + + /** + * Set the control's position + * + * @param left New left, X coordinate + * @param top New top, Y coordinate + */ + public void setPosition(int left, int top) { + this.setXPosition(left); + this.setYPosition(top); + } + + /** + * Set the size of the control + * + * @param controlWidth New width for the control. Minimum 60 pixels + * @param controlHeight New height for the control. Minimum 8 pixels + */ + public void setSize(int controlWidth, int controlHeight) { + this.setWidth(controlWidth); + this.setHeight(controlHeight); + this.traySize = this.getLargeDimension() - (this.getSmallDimension() * 2) - this.scrollButtonSize; + this.updateValue(); + } + + /** + * Set the size and position of the control + * + * @param left New left, X coordinate + * @param top New top, Y coordinate + * @param controlWidth New width for the control. Minimum 60 pixels + * @param controlHeight New height for the control. Minimum 8 pixels + */ + public void setSizeAndPosition(int left, int top, int controlWidth, int controlHeight) { + this.setPosition(left, top); + this.setSize(controlWidth, controlHeight); + } + + /** + * Clamp the value between max and min and update the button position + */ + private void updateValue() { + if (this.value < this.min) + this.value = this.min; + if (this.value > this.max) + this.value = this.max; + + this.buttonPos = (int) (((float) (this.value - this.min) / (float) (this.max - this.min)) * this.traySize); + } + + /** + * Draw the control + * + * @param minecraft Minecraft game instance + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + */ + @Override + protected void drawControl(Minecraft minecraft, int mouseX, int mouseY) { + if (!this.isVisible()) + return; + + float opacity = this.isEnabled() ? 1.0F : 0.3F; + + glColor4f(opacity, opacity, opacity, opacity); + + // Calc mouseover state of buttons + boolean mouseOverUpButton = this.mouseDownState == 3 || this.mouseIsOverButton(3, mouseX, mouseY); + boolean mouseOverDownButton = this.mouseDownState == 2 || this.mouseIsOverButton(2, mouseX, mouseY); + boolean mouseOverButton = this.mouseDownState == 1 || this.mouseIsOverButton(1, mouseX, mouseY); + + // V coordinates based on button hover states + int upButtonHoverState = 0 + (this.getHoverState(mouseOverUpButton) * 16); + int downButtonHoverState = 0 + (this.getHoverState(mouseOverDownButton) * 16); + int buttonHoverState = 0 + (this.getHoverState(mouseOverButton) * 16); + + if (this.orientation == ScrollBarOrientation.Vertical) { + minecraft.getTextureManager().bindTexture(LiteModVoxelCommon.GUIPARTS); + this.setTexMapSize(256); + + this.drawTessellatedModalBorderRect(this.xPosition, this.yPosition, this.xPosition + this.width, + this.yPosition + this.width, 0, upButtonHoverState, 16, upButtonHoverState + 16, 4); + this.drawTessellatedModalBorderRect(this.xPosition, this.yPosition + this.height - this.width, + this.xPosition + this.width, this.yPosition + this.height, 0, downButtonHoverState, 16, + downButtonHoverState + 16, 4); + + // Slider tray + this.drawTessellatedModalBorderRect(this.xPosition + 1, this.yPosition + this.width, + this.xPosition + this.width - 1, this.yPosition + this.height - this.width, 0, 0, 16, 16, 4); + + // Button icons + this.drawTexturedModalRect(this.xPosition + 1, this.yPosition + 1, this.xPosition + this.width - 2, + this.yPosition + this.width - 2, 36, 0, 54, 18); + this.drawTexturedModalRect(this.xPosition + 1, this.yPosition + this.height - this.width + 1, + this.xPosition + this.width - 2, this.yPosition + this.height - 1, 18, 0, 36, 18); + } + + // Handle mouse dragged event + this.mouseDragged(minecraft, mouseX, mouseY); + + minecraft.getTextureManager().bindTexture(LiteModVoxelCommon.GUIPARTS); + + if (this.orientation == ScrollBarOrientation.Vertical) { + this.drawTessellatedModalBorderRect(this.xPosition, this.yPosition + this.width + this.buttonPos, + this.xPosition + this.width, this.yPosition + this.width + this.buttonPos + this.scrollButtonSize, + 0, buttonHoverState, 16, buttonHoverState + 16, 4); + } + } + + protected boolean mouseIsOverButton(int button, int mouseX, int mouseY) { + int buttonX = 0, buttonY = 0, buttonWidth = this.getSmallDimension(), buttonHeight = this.getSmallDimension(); + mouseX -= this.xPosition; + mouseY -= this.yPosition; + + if (mouseX < 0 || mouseY < 0 || mouseX > this.width || mouseY > this.height) + return false; + + if (button == 2) // down button + { + if (this.orientation == ScrollBarOrientation.Vertical) + buttonY = this.getLargeDimension() - this.getSmallDimension(); + if (this.orientation == ScrollBarOrientation.Horizontal) + buttonX = this.getLargeDimension() - this.getSmallDimension(); + } else if (button == 1) // drag button + { + if (this.orientation == ScrollBarOrientation.Vertical) { + buttonY = this.getSmallDimension() + this.buttonPos; + buttonHeight = this.scrollButtonSize; + } + if (this.orientation == ScrollBarOrientation.Horizontal) { + buttonX = this.getSmallDimension() + this.buttonPos; + buttonWidth = this.scrollButtonSize; + } + } + + return (mouseX >= buttonX && mouseY >= buttonY && mouseX < buttonX + buttonWidth + && mouseY < buttonY + buttonHeight); + } + + /** + * Handle mouse dragged event + * + * @param minecraft Minecraft game instance + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + */ + @Override + protected void mouseDragged(Minecraft minecraft, int mouseX, int mouseY) { + if (!this.isVisible()) + return; + + if (this.mouseDownState > 0) { + int mouseDownTicks = this.updateCounter - this.mouseDownTime; + + if (this.mouseDownState == 1) { + int mPos = (this.orientation == ScrollBarOrientation.Vertical) ? mouseY - this.yPosition + : mouseX - this.xPosition; + this.value = (int) (((float) (mPos - this.dragOffset - this.getSmallDimension()) + / (float) this.traySize) * (this.max - this.min)) + this.min; + } else if (this.mouseDownState == 2 && mouseDownTicks > 6) { + this.value += 4; + } else if (this.mouseDownState == 3 && mouseDownTicks > 6) { + this.value -= 4; + } + + this.updateValue(); + } + } + + /** + * Handle mouse released event + * + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + */ + @Override + public void mouseReleased(int mouseX, int mouseY) { + this.mouseDownState = 0; + } + + /** + * Mouse pressed event + * + * @param minecraft Minecraft game instance + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + */ + @Override + public boolean mousePressed(Minecraft minecraft, int mouseX, int mouseY) { + this.actionPerformed = false; + boolean returnValue = false; + + if (super.mousePressed(minecraft, mouseX, mouseY)) { + // Adjust coords relative to control + mouseX -= this.xPosition; + mouseY -= this.yPosition; + + if (this.orientation == ScrollBarOrientation.Horizontal) { + int mouseT = mouseY; + mouseY = mouseX; + mouseX = mouseT; + } + + // Counter starts now and we wait 10 seconds for mousedown effects + // to kick in + this.mouseDownTime = this.updateCounter; + + if (mouseY < this.getSmallDimension()) // up button + { + this.mouseDownState = 3; + this.value -= 4; + this.actionPerformed = true; + } else if (mouseY > this.getLargeDimension() - this.getSmallDimension()) // down + // button + { + this.mouseDownState = 2; + this.value += 4; + this.actionPerformed = true; + } else if (mouseY > this.buttonPos + this.getSmallDimension() + && mouseY < this.buttonPos + this.getSmallDimension() + this.scrollButtonSize) // drag + // button + { + this.mouseDownState = 1; + this.dragOffset = mouseY - this.buttonPos - this.getSmallDimension(); + returnValue = true; + } else if (mouseY < this.buttonPos + this.getSmallDimension()) // upper + // tray + { + this.value -= 40; + this.actionPerformed = true; + } else if (mouseY > this.buttonPos + this.getSmallDimension() + this.scrollButtonSize) // lower + // tray + { + this.value += 40; + this.actionPerformed = true; + } + + // Clamp value and update slider position + this.updateValue(); + } + + return this.actionPerformed || returnValue; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiTextFieldEx.java b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiTextFieldEx.java new file mode 100644 index 00000000..352f81f8 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gui/GuiTextFieldEx.java @@ -0,0 +1,176 @@ +package com.voxelmodpack.common.gui; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiTextField; + +import org.lwjgl.input.Keyboard; + +import com.mumfrey.liteloader.client.overlays.IGuiTextField; + +/** + * 'Dynamic' text field which supports resizing and moving and also syntax + * highlight + * + * @author Adam Mummery-Smith + */ +public class GuiTextFieldEx extends GuiTextField { + /** + * Width member is private in the superclass + */ + protected int xPos, yPos, width, height; + + /** + * Allowed character filter for this text box + */ + public String allowedCharacters; + + public int minStringLength = 0; + + protected FontRenderer fontRenderer; + + /** + * Constructor + * + * @param parentScreen Parent screen + * @param fontrenderer Font renderer + * @param xPos X location + * @param yPos Y location + * @param width Control width + * @param height Control height + * @param initialText Text to initially set + */ + public GuiTextFieldEx(int id, FontRenderer fontrenderer, int xPos, int yPos, int width, int height, + String initialText, String allowedCharacters, int maxStringLength) { + super(id, fontrenderer, xPos, yPos, width, height); + this.allowedCharacters = allowedCharacters; + this.setMaxStringLength(maxStringLength); + this.setText(initialText); + + this.width = width; + } + + /** + * Constructor + * + * @param parentScreen Parent screen + * @param fontrenderer Font renderer + * @param xPos X location + * @param yPos Y location + * @param width Control width + * @param height Control height + * @param initialText Text to initially set + */ + public GuiTextFieldEx(int id, FontRenderer fontrenderer, int xPos, int yPos, int width, int height, + String initialText) { + super(id, fontrenderer, xPos, yPos, width, height); + this.setMaxStringLength(65536); + this.setText(initialText); + + this.width = width; + } + + /** + * Constructor + * + * @param parentScreen Parent screen + * @param fontrenderer Font renderer + * @param xPos X location + * @param yPos Y location + * @param width Control width + * @param height Control height + * @param initialText Text to initially set + */ + public GuiTextFieldEx(int id, FontRenderer fontrenderer, int xPos, int yPos, int width, int height, + int initialValue, int digits) { + super(id, fontrenderer, xPos, yPos, width, height); + this.setMaxStringLength(digits); + this.setText(String.valueOf(initialValue)); + this.allowedCharacters = "0123456789"; + this.width = width; + } + + @Override + public boolean textboxKeyTyped(char keyChar, int keyCode) { + if ((this.allowedCharacters == null || this.allowedCharacters.indexOf(keyChar) >= 0) || + keyCode == Keyboard.KEY_LEFT || keyCode == Keyboard.KEY_RIGHT || + keyCode == Keyboard.KEY_HOME || keyCode == Keyboard.KEY_END || + keyCode == Keyboard.KEY_DELETE || keyCode == Keyboard.KEY_BACK) { + return super.textboxKeyTyped(keyChar, keyCode); + } + + return false; + } + + /* + * (non-Javadoc) + * @see net.minecraft.src.GuiTextField#func_50038_e() + */ + @Override + public void setCursorPositionEnd() { + try { + super.setCursorPositionEnd(); + } catch (Exception ex) {} + } + + public void setSizeAndPosition(int xPos, int yPos, int width, int height) { + this.setPosition(xPos, yPos); + this.setSize(width, height); + } + + public void setSize(int width, int height) { + ((IGuiTextField) this).setInternalWidth(width); + ((IGuiTextField) this).setHeight(height); + + this.width = width; + this.height = height; + } + + public void setPosition(int xPos, int yPos) { + ((IGuiTextField) this).setXPosition(xPos); + ((IGuiTextField) this).setYPosition(yPos); + + this.xPos = xPos; + this.yPos = yPos; + } + + public void scrollToEnd() { + this.setCursorPosition(0); + this.setCursorPosition(this.getText().length()); + } + + /* + * (non-Javadoc) + * @see net.minecraft.src.GuiTextField#func_50032_g(int) + */ + @Override + public void setCursorPosition(int cursorPos) { + super.setCursorPosition(cursorPos); + super.setCursorPosition(cursorPos); + } + + /** + * Synchronise private members from the superclass using reflection + */ + protected void syncMembers() { + this.xPos = ((IGuiTextField) this).getXPosition(); + this.yPos = ((IGuiTextField) this).getYPosition(); + this.width = ((IGuiTextField) this).getInternalWidth(); + this.height = ((IGuiTextField) this).getHeight(); + } + + public void drawTextBoxAt(int yPos) { + try { + ((IGuiTextField) this).setYPosition(yPos); + this.yPos = yPos; + this.drawTextBox(); + } catch (Exception ex) {} + } + + public int getIntValue(int defaultValue) { + try { + return Integer.parseInt(this.getText()); + } catch (Exception ex) { + return defaultValue; + } + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IDragDrop.java b/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IDragDrop.java new file mode 100644 index 00000000..bbc35802 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IDragDrop.java @@ -0,0 +1,66 @@ +package com.voxelmodpack.common.gui.interfaces; + +/** + * Interface for controls or other objects which support drag/drop sourcing and + * destination capabilities + * + * @author Adam Mummery-Smith + */ +public interface IDragDrop { + /** + * Get whether this object is a valid drag target + * + * @return true if the object can have draggable items dropped into it + */ + public abstract boolean getIsValidDragTarget(); + + /** + * Get whether this object is a valid drag source + * + * @return true if this object can source drag events + */ + public abstract boolean getIsValidDragSource(); + + /** + * Add the specified target to this object's list of targets + * + * @param target DragTarget to add, the object MUST support drag targets + */ + public abstract void addDragTarget(IDragDrop target); + + /** + * Add the specified target to this object's list of targets and create a + * mutual (bi-directional) linkage if specified + * + * @param target Target to add + * @param mutual Set true to create a mutual (bi-directional) linkage + */ + public abstract void addDragTarget(IDragDrop target, boolean mutual); + + /** + * Remove the specified object from this object's list of targets + * + * @param target Drag Target object to remove + */ + public abstract void removeDragTarget(IDragDrop target); + + /** + * Remove the specified object from this object's list of targets and this + * object from the other object's list of targets if specified + * + * @param target Drag Target object to remove + * @param mutual Set true to break the link mutually + */ + public abstract void removeDragTarget(IDragDrop target, boolean mutual); + + /** + * Perform a drag operation to this object + * + * @param source Object sourcing the drag event + * @param object Object being dragged + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + * @return True if the object was accepted + */ + public abstract boolean dragDrop(IDragDrop source, IListObject object, int mouseX, int mouseY); +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IExtendedGui.java b/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IExtendedGui.java new file mode 100644 index 00000000..1a3601b0 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IExtendedGui.java @@ -0,0 +1,81 @@ +package com.voxelmodpack.common.gui.interfaces; + +import net.minecraft.util.ResourceLocation; + +public interface IExtendedGui { + /** + * Draws a tesselated rectangle where the texture is stretched vertically + * and horizontally but the middle pixels are repeated whilst the joining + * pixels are stretched. Bordersize specifies the portion of the texture + * which will remain unstretched. + * + * @param texture Texture to use + * @param textureSize Size of the texture + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + * @param borderSize Number of pixels to leave unstretched, must be less + * than half of the width or height (whichever is smallest) + */ + public abstract void drawTessellatedModalBorderRect(ResourceLocation texture, int textureSize, int x, int y, int x2, + int y2, int u, int v, int u2, int v2, int borderSize); + + /** + * Draws a tesselated rectangle where the texture is stretched vertically + * and horizontally but the middle pixels are repeated whilst the joining + * pixels are stretched. Bordersize specifies the portion of the texture + * which will remain unstretched. + * + * @param texture Texture to use + * @param textureSize Size of the texture + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + * @param borderSize Number of pixels to leave unstretched, must be less + * than half of the width or height (whichever is smallest) + */ + public abstract void drawTessellatedModalBorderRect(ResourceLocation texture, int textureSize, int x, int y, int x2, + int y2, int u, int v, int u2, int v2, int borderSize, boolean setcolor); + + /** + * Advanced version of drawTexturedModalRect which supports separating the + * UV coordinates from the drawn width/height + * + * @param texture Texture to draw + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + */ + public abstract void drawTexturedModalRect(ResourceLocation texture, int x, int y, int x2, int y2, int u, int v, + int u2, int v2); + + /** + * Advanced version of drawTexturedModalRect which supports separating the + * UV coordinates from the drawn width/height + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + */ + public abstract void drawTexturedModalRect(int x, int y, int x2, int y2, int u, int v, int u2, int v2); +} \ No newline at end of file diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IListObject.java b/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IListObject.java new file mode 100644 index 00000000..af62198f --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IListObject.java @@ -0,0 +1,256 @@ +package com.voxelmodpack.common.gui.interfaces; + +import net.minecraft.client.Minecraft; + +import com.mumfrey.liteloader.util.render.Icon; + +/** + * Interface for items that can be added to listboxes + * + * @author Adam Mummery-Smith + */ +public interface IListObject { + /** + * Custom draw behaviours + */ + public enum CustomDrawBehaviour { + /** + * Don't custom draw, this object is completely owner-drawn + */ + NoCustomDraw, + + /** + * Combined custom draw, custom draw is called AFTER owner draw + */ + CustomDrawExtra, + + /** + * Custom draw only, no owner draw is performed and the item draws + * itself + */ + FullCustomDraw + } + + /** + * Get the custom draw behaviour for this object + * + * @return custom draw behaviour + */ + public abstract CustomDrawBehaviour getCustomDrawBehaviour(); + + /** + * Callback which is called if GetCustomDrawBegaviour returns + * CustomDrawExtra or FullCustomDraw + * + * @param iconEnabled True if icons are enabled in the container (owner) + * @param minecraft Minecraft game instance + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + * @param XPosition() X location of the control + * @param yPosition Y location of the control + * @param width control width + * @param height control height + */ + public abstract void drawCustom(boolean iconEnabled, Minecraft minecraft, int mouseX, int mouseY, int xPosition, + int yPosition, int width, int height, int updateCounter); + + /** + * @param iconEnabled True if icons are enabled in the container + * @param minecraft Minecraft game instance + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + * @param XPosition() X location of the control + * @param yPosition Y location of the control + * @param width control width + * @param height control height + * @return true if a custom action was performed + */ + public abstract boolean mousePressed(boolean iconEnabled, Minecraft minecraft, int mouseX, int mouseY, + int xPosition, int yPosition, int width, int height); + + /** + * Called when the mouse is released after a MousePressed event + * + * @param mouseX + * @param mouseY + */ + public abstract void mouseReleased(int mouseX, int mouseY); + + /** + * If a custom action was flagged after calling MousePressed, this function + * is called to retrieve the custom action + * + * @param bClear Set true to clear the custom action after it is read + * @return Custom action which was performed + */ + public abstract String getCustomAction(boolean bClear); + + /** + * True if the object has an icon + * + * @return True if the object has an icon + */ + public abstract boolean hasIcon(); + + /** + * Bind the icon texture for this object + */ + public abstract void bindIconTexture(); + + /** + * Get the icon ID for this object + * + * @return icon id + */ + public abstract Icon getIcon(); + + /** + * Get the icon's size on the texture + * + * @return + */ + public abstract int getIconSize(); + + /** + * Get the size of the texture map used for the object's icons + * + * @return + */ + public abstract int getIconTexmapSize(); + + /** + * Get the display text for the object + * + * @return Display text + */ + public abstract String getText(); + + /** + * Display name if different to text + * + * @return + */ + public abstract String getDisplayName(); + + /** + * Get the object's ID, object-specific identifier + * + * @return + */ + public abstract int getID(); + + /** + * Get the arbitrary data associated with the object + * + * @return object's data or NULL if no data + */ + public abstract Object getData(); + + /** + * Return true if this item is draggable + * + * @return true if this item is draggable + */ + public abstract boolean getDraggable(); + + /** + * True if this object supports in-place editing + * + * @return + */ + public abstract boolean getCanEditInPlace(); + + /** + * True if this object is currently in-place editing + * + * @return + */ + public abstract boolean getEditingInPlace(); + + /** + * Tell this object to begin editing in-place + */ + public abstract void beginEditInPlace(); + + /** + * Tell this object to end editing in-place + */ + public abstract void endEditInPlace(); + + /** + * Key typed handler for editing in-place + * + * @param keyChar Key character that was entered + * @param keyCode Key scan code + * @return + */ + public abstract boolean editInPlaceKeyTyped(char keyChar, int keyCode); + + /** + * @param iconEnabled True if icons are enabled in the container + * @param minecraft Minecraft game instance + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + * @param XPosition() X location of the control + * @param yPosition Y location of the control + * @param width control width + * @param height control height + * @return true if the mouse was captured + */ + public abstract boolean editInPlaceMousePressed(boolean iconEnabled, Minecraft minecraft, int mouseX, int mouseY, + int xPosition, int yPosition, int width, int height); + + /** + * Callback which is called if GetEditingInPlace is true + * + * @param iconEnabled True if icons are enabled in the container (owner) + * @param minecraft Minecraft game instance + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + * @param XPosition() X location of the control + * @param yPosition Y location of the control + * @param width control width + * @param height control height + */ + public abstract void editInPlaceDraw(boolean iconEnabled, Minecraft minecraft, int mouseX, int mouseY, + int xPosition, int yPosition, int width, int height, int updateCounter); + + /** + * Set the texture name of the icon for this object. + */ + public abstract void setIconTexture(String newTexture); + + /** + * Set the icon ID for this object + */ + public abstract void setIconID(int newIconId); + + /** + * Set the display text for the object + */ + public abstract void setText(String newText); + + /** + * Set the display name for this object + * + * @param newDisplayName + */ + public abstract void setDisplayName(String newDisplayName); + + /** + * Set the object's ID, object-specific identifier + */ + public abstract void setID(int newId); + + /** + * Set the arbitrary data associated with the object + */ + public abstract void setData(Object newData); + + /** + * Get the serialised representation of this list entry + * + * @return + */ + public abstract String serialise(); +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IMouseEventListener.java b/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IMouseEventListener.java new file mode 100644 index 00000000..72d2f557 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IMouseEventListener.java @@ -0,0 +1,33 @@ +package com.voxelmodpack.common.gui.interfaces; + +public interface IMouseEventListener { + /** + * Called when a mouse button is pressed + * + * @param provider + * @param mouseX + * @param mouseY + * @param mouseButton + */ + public abstract void mousePressed(IMouseEventProvider provider, int mouseX, int mouseY, int mouseButton); + + /** + * Called when a mouse button is released + * + * @param provider + * @param mouseX + * @param mouseY + * @param mouseButton + */ + public abstract void mouseReleased(IMouseEventProvider provider, int mouseX, int mouseY, int mouseButton); + + /** + * Called when the mouse is moved + * + * @param provider + * @param mouseX + * @param mouseY + */ + public abstract void mouseMoved(IMouseEventProvider provider, int mouseX, int mouseY); + +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IMouseEventProvider.java b/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IMouseEventProvider.java new file mode 100644 index 00000000..69692135 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/gui/interfaces/IMouseEventProvider.java @@ -0,0 +1,13 @@ +package com.voxelmodpack.common.gui.interfaces; + +/** + * Interface for screens which can provide mouse events to multiple clients + * + * @author Adam Mummery-Smith + */ +public interface IMouseEventProvider { + /** + * Register a new mouse event listener for this provider instance + */ + public abstract void registerMouseListener(IMouseEventListener listener); +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/interfaces/INotifyable.java b/voxellib/src/main/java/com/voxelmodpack/common/interfaces/INotifyable.java new file mode 100644 index 00000000..a92f3d58 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/interfaces/INotifyable.java @@ -0,0 +1,12 @@ +package com.voxelmodpack.common.interfaces; + +/** + * @author Adam Mummery-Smith + */ +public interface INotifyable { + /** + * @param message + * @param params + */ + public abstract void notify(String message, Object... params); +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/interfaces/IRegionRenderer.java b/voxellib/src/main/java/com/voxelmodpack/common/interfaces/IRegionRenderer.java new file mode 100644 index 00000000..ec0a59b3 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/interfaces/IRegionRenderer.java @@ -0,0 +1,23 @@ +package com.voxelmodpack.common.interfaces; + +public interface IRegionRenderer { + /** + * Render a 3-dimensional region using the currently bound texture + * + * @param x1 First x coordinate + * @param y1 First y coordinate + * @param z1 First z coordinate + * @param x2 Second x coordinate + * @param y2 Second y coordinate + * @param z2 Second z coordinate + */ + public abstract void renderRegion3D(int x1, int y1, int z1, int x2, int y2, int z2); + + /** + * @param red + * @param green + * @param blue + * @param alpha + */ + public abstract void glColor4f(float red, float green, float blue, float alpha); +} \ No newline at end of file diff --git a/voxellib/src/main/java/com/voxelmodpack/common/interfaces/ITimeHandler.java b/voxellib/src/main/java/com/voxelmodpack/common/interfaces/ITimeHandler.java new file mode 100644 index 00000000..b565d98e --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/interfaces/ITimeHandler.java @@ -0,0 +1,48 @@ +package com.voxelmodpack.common.interfaces; + +/** + * Interface for mods which want to interact with inbound time + * + * @author Adam Mummery-Smith + */ +public interface ITimeHandler { + /** + * Called for every registered handler when a new time packet is received, + * lets each handler note the REAL (server) time + * + * @param totalTime + * @param worldTime + */ + public abstract void onTimeUpdate(long totalTime, long worldTime); + + /** + * Called for every registered handler until a handler returns TRUE. If a + * handler returns true then getFrozenTotalTime and getFrozenWorldTime are + * called and the frozen time overrides all other time adjustments + */ + public abstract boolean isFreezingTime(); + + /** + * If this handler returns TRUE in isFreezingTime then this method must + * return the frozen time + * + * @param totalTime + * @return + */ + public abstract long getFrozenTotalTime(long totalTime); + + /** + * If this handler returns TRUE in isFreezingTime then this method must + * return the frozen time + * + * @param worldTime + * @return + */ + public abstract long getFrozenWorldTime(long worldTime); + + /** + * If time is not frozen, this method should return the amount of time + * offset this handler wishes to apply + */ + public abstract long getTimeOffset(); +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/net/HttpFileRetriever.java b/voxellib/src/main/java/com/voxelmodpack/common/net/HttpFileRetriever.java new file mode 100644 index 00000000..a5b5bc13 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/net/HttpFileRetriever.java @@ -0,0 +1,224 @@ +package com.voxelmodpack.common.net; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; +import java.util.Map; +import java.util.Map.Entry; + +/** + * Object which retrieves files from a remote server using http + * + * @author Adam Mummery-Smith + */ +public class HttpFileRetriever extends Thread { + /** + * Callback which receives progress notifications + */ + private final IDownloadProgressWatcher progressWatcher; + + /** + * Callback which receives succeeded/failed notifications + */ + private final IDownloadCompletedWatcher completedWatcher; + + /** + * Source URL for the resource to download + */ + private final String sourceUrl; + + /** + * Additional headers to send with the request + */ + private final Map requestHeaders; + + /** + * File to download to + */ + private final File localFile; + + /** + * Maximum file size allowed for this resource + */ + private final int maxFileSize; + + /** + * Flag which can be set to cancel the download + */ + private volatile boolean cancelled; + + /** + * @param sourceUrl + * @param headers + * @param destinationFile + * @param maxFileSize + * @param progressWatcher + * @param completedWatcher + */ + private HttpFileRetriever(String sourceUrl, Map headers, File destinationFile, int maxFileSize, + IDownloadProgressWatcher progressWatcher, IDownloadCompletedWatcher completedWatcher) { + this.setDaemon(true); + + this.sourceUrl = sourceUrl; + this.requestHeaders = headers; + this.localFile = destinationFile; + this.maxFileSize = maxFileSize; + this.progressWatcher = progressWatcher; + this.completedWatcher = completedWatcher; + } + + /** + * Cancel this download + */ + public synchronized void cancel() { + this.cancelled = true; + } + + /* + * (non-Javadoc) + * @see java.lang.Thread#run() + */ + @Override + public void run() { + URLConnection http = null; + InputStream httpInputStream = null; + DataOutputStream fileOutputStream = null; + + if (this.progressWatcher != null) { + this.progressWatcher.resetProgressAndMessage("Downloading File"); + this.progressWatcher.resetProgressAndWorkingMessage("Making Request..."); + } + + try { + try { + byte[] buffer = new byte[4096]; + http = new URL(this.sourceUrl).openConnection(); + http.addRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"); // For + // CloudFlare + + float progress = 0.0F; + float progressMax = this.requestHeaders.entrySet().size(); + for (Entry header : this.requestHeaders.entrySet()) { + http.setRequestProperty(header.getKey(), header.getValue()); + + if (this.progressWatcher != null) { + this.progressWatcher.setProgress((int) (++progress / progressMax * 100.0F)); + } + } + + if (this.cancelled) { + if (this.progressWatcher != null) + this.progressWatcher.onCompleted(); + this.completedWatcher.onFailure(this.localFile); + return; + } + + httpInputStream = http.getInputStream(); + progressMax = http.getContentLength(); + int contentLength = http.getContentLength(); + + if (this.progressWatcher != null) + this.progressWatcher.resetProgressAndWorkingMessage(String.format("Downloading file (%.2f MB)...", + new Object[] { Float.valueOf(progressMax / 1000.0F / 1000.0F) })); + + if (this.localFile.exists()) { + long receivedBytes = this.localFile.length(); + + if (receivedBytes == contentLength) { + this.completedWatcher.onSuccess(this.localFile); + + if (this.progressWatcher != null) + this.progressWatcher.onCompleted(); + + return; + } + + System.out.println("Deleting " + this.localFile + " as it does not match what we currently have (" + + contentLength + " vs our " + receivedBytes + ")."); + this.localFile.delete(); + } + + fileOutputStream = new DataOutputStream(new FileOutputStream(this.localFile)); + + if (this.maxFileSize > 0 && progressMax > this.maxFileSize) { + if (this.progressWatcher != null) + this.progressWatcher.onCompleted(); + + throw new IOException("Filesize is bigger than maximum allowed (file is " + progress + ", limit is " + + this.maxFileSize + ")"); + } + + int readBytes; + + while ((readBytes = httpInputStream.read(buffer)) >= 0 && !this.cancelled) { + progress += readBytes; + + if (this.progressWatcher != null) + this.progressWatcher.setProgress((int) (progress / progressMax * 100.0F)); + + if (this.maxFileSize > 0 && progress > this.maxFileSize) { + if (this.progressWatcher != null) + this.progressWatcher.onCompleted(); + + throw new IOException("Filesize was bigger than maximum allowed (got >= " + progress + + ", limit was " + this.maxFileSize + ")"); + } + + fileOutputStream.write(buffer, 0, readBytes); + } + + if (this.cancelled) { + try { + fileOutputStream.close(); + this.localFile.delete(); + } catch (IOException ex) {} + + if (this.progressWatcher != null) + this.progressWatcher.onCompleted(); + this.completedWatcher.onFailure(this.localFile); + return; + } + + this.completedWatcher.onSuccess(this.localFile); + + if (this.progressWatcher != null) { + this.progressWatcher.onCompleted(); + return; + } + } catch (Throwable th) { + // th.printStackTrace(); + } + } finally { + try { + if (httpInputStream != null) + httpInputStream.close(); + } catch (IOException ex) {} + + try { + if (fileOutputStream != null) + fileOutputStream.close(); + } catch (IOException ex) {} + } + } + + /** + * @param sourceUrl + * @param headers + * @param destFile + * @param maxFileSize + * @param progressWatcher + * @param completedWatcher + * @return + */ + public static HttpFileRetriever beginDownloading(String sourceUrl, Map headers, File destFile, + int maxFileSize, IDownloadProgressWatcher progressWatcher, IDownloadCompletedWatcher completedWatcher) { + HttpFileRetriever downloadThread = new HttpFileRetriever(sourceUrl, headers, destFile, maxFileSize, + progressWatcher, completedWatcher); + downloadThread.start(); + return downloadThread; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/net/IDownloadCompletedWatcher.java b/voxellib/src/main/java/com/voxelmodpack/common/net/IDownloadCompletedWatcher.java new file mode 100644 index 00000000..b28f3c55 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/net/IDownloadCompletedWatcher.java @@ -0,0 +1,25 @@ +package com.voxelmodpack.common.net; + +import java.io.File; + +/** + * Interface for objects which want a callback on the success/failure of file + * downloads + * + * @author Adam Mummery-Smith + */ +public interface IDownloadCompletedWatcher { + /** + * Called if the download succeeds + * + * @param destFile + */ + public abstract void onSuccess(File destFile); + + /** + * Called if the download fails + * + * @param destFile + */ + public abstract void onFailure(File destFile); +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/net/IDownloadProgressWatcher.java b/voxellib/src/main/java/com/voxelmodpack/common/net/IDownloadProgressWatcher.java new file mode 100644 index 00000000..5639a0bc --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/net/IDownloadProgressWatcher.java @@ -0,0 +1,34 @@ +package com.voxelmodpack.common.net; + +/** + * Interface for objects which want a callback to monitor the progress of file + * downloads + * + * @author Adam Mummery-Smith + */ +public interface IDownloadProgressWatcher { + /** + * @param message + */ + public abstract void setMessage(String message); + + /** + * @param message + */ + public abstract void resetProgressAndMessage(String message); + + /** + * @param message + */ + public abstract void resetProgressAndWorkingMessage(String message); + + /** + * @param progress + */ + public abstract void setProgress(int progress); + + /** + * + */ + public abstract void onCompleted(); +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/net/upload/IUploadCompleteCallback.java b/voxellib/src/main/java/com/voxelmodpack/common/net/upload/IUploadCompleteCallback.java new file mode 100644 index 00000000..7601f36d --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/net/upload/IUploadCompleteCallback.java @@ -0,0 +1,5 @@ +package com.voxelmodpack.common.net.upload; + +public interface IUploadCompleteCallback { + public abstract void onUploadComplete(String response); +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/net/upload/ThreadMultipartPostUpload.java b/voxellib/src/main/java/com/voxelmodpack/common/net/upload/ThreadMultipartPostUpload.java new file mode 100644 index 00000000..c81fcfd8 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/net/upload/ThreadMultipartPostUpload.java @@ -0,0 +1,180 @@ +package com.voxelmodpack.common.net.upload; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Map; +import java.util.Map.Entry; + +/** + * Uploader for Multipart form data + * + * @author Adam Mummery-Smith + */ +public class ThreadMultipartPostUpload extends Thread { + protected final Map sourceData; + + protected final String method; + + protected final String authorization; + + protected final String urlString; + + protected final IUploadCompleteCallback callback; + + protected HttpURLConnection httpClient; + + protected static final String CRLF = "\r\n"; + + protected static final String twoHyphens = "--"; + + protected static final String boundary = "----------AaB03x"; + + public String response; + + public int httpResponseCode; + + public String httpResponse; + + public ThreadMultipartPostUpload(String method, String url, Map sourceData, String authorization, + IUploadCompleteCallback callback) { + this.method = method; + this.urlString = url; + this.sourceData = sourceData; + this.authorization = authorization; + this.callback = callback; + } + + public ThreadMultipartPostUpload(String url, Map sourceData, IUploadCompleteCallback callback) { + this("POST", url, sourceData, null, callback); + } + + public String getResponse() { + return this.response == null ? "" : this.response.trim(); + } + + @Override + public void run() { + try { + this.uploadMultipart(); + } catch (IOException ex) { + ex.printStackTrace(); + + try { + this.httpResponseCode = this.httpClient.getResponseCode(); + this.httpResponse = this.httpClient.getResponseMessage(); + } catch (Exception ex1) {} + } + + this.callback.onUploadComplete(this.getResponse()); + } + + protected void uploadMultipart() throws IOException { + // open a URL connection + URL url = new URL(this.urlString); + + // Open a HTTP connection to the URL + this.httpClient = (HttpURLConnection) url.openConnection(); + this.httpClient.setDoOutput(true); + this.httpClient.setUseCaches(false); + + this.httpClient.setRequestMethod(this.method); + this.httpClient.setRequestProperty("Connection", "Close"); + this.httpClient.addRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"); // For + // CloudFlare + + if (this.sourceData.size() > 0) { + this.httpClient.setRequestProperty("Content-Type", + "multipart/form-data, boundary=" + ThreadMultipartPostUpload.boundary); + } + + if (this.authorization != null) { + this.httpClient.addRequestProperty("Authorization", this.authorization); + } + + DataOutputStream outputStream = new DataOutputStream(this.httpClient.getOutputStream()); + + for (Entry data : this.sourceData.entrySet()) { + outputStream.writeBytes(ThreadMultipartPostUpload.twoHyphens + ThreadMultipartPostUpload.boundary + + ThreadMultipartPostUpload.CRLF); + + String paramName = data.getKey(); + Object paramData = data.getValue(); + + if (paramData instanceof File) { + File uploadFile = (File) paramData; + outputStream.writeBytes( + "Content-Disposition: form-data; name=\"" + paramName + "\"; filename=\"" + uploadFile.getName() + + "\"" + ThreadMultipartPostUpload.CRLF + ThreadMultipartPostUpload.CRLF); + this.writeFile(uploadFile, outputStream); + } else { + outputStream.writeBytes("Content-Disposition: form-data; name=\"" + paramName + "\"" + + ThreadMultipartPostUpload.CRLF + ThreadMultipartPostUpload.CRLF); + outputStream.writeBytes(paramData.toString()); + } + + outputStream.writeBytes(ThreadMultipartPostUpload.CRLF); + } + + outputStream.writeBytes(ThreadMultipartPostUpload.twoHyphens + ThreadMultipartPostUpload.boundary + + ThreadMultipartPostUpload.twoHyphens + ThreadMultipartPostUpload.CRLF); + outputStream.flush(); + + InputStream httpStream = this.httpClient.getInputStream(); + + try { + StringBuilder readString = new StringBuilder(); + BufferedReader reader = new BufferedReader(new InputStreamReader(httpStream)); + + String readLine; + while ((readLine = reader.readLine()) != null) { + readString.append(readLine).append("\n"); + } + + reader.close(); + this.response = readString.toString(); + } catch (IOException ex) { + ex.printStackTrace(); + } + + outputStream.close(); + + this.httpResponseCode = this.httpClient.getResponseCode(); + this.httpResponse = this.httpClient.getResponseMessage(); + } + + /** + * @param sourceFile + * @param outputStream + * @throws FileNotFoundException + * @throws IOException + */ + public void writeFile(File sourceFile, DataOutputStream outputStream) throws FileNotFoundException, IOException { + int bytesRead, bufferSize; + int maxBufferSize = 1 * 1024 * 1024; + + FileInputStream fileInputStream = new FileInputStream(sourceFile); + + int bytesAvailable = fileInputStream.available(); + bufferSize = Math.min(bytesAvailable, maxBufferSize); + byte[] buffer = new byte[bufferSize]; + + bytesRead = fileInputStream.read(buffer, 0, bufferSize); + + while (bytesRead > 0) { + outputStream.write(buffer, 0, bufferSize); + bytesAvailable = fileInputStream.available(); + bufferSize = Math.min(bytesAvailable, maxBufferSize); + bytesRead = fileInputStream.read(buffer, 0, bufferSize); + } + + fileInputStream.close(); + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/net/upload/awt/IOpenFileCallback.java b/voxellib/src/main/java/com/voxelmodpack/common/net/upload/awt/IOpenFileCallback.java new file mode 100644 index 00000000..62d270db --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/net/upload/awt/IOpenFileCallback.java @@ -0,0 +1,20 @@ +package com.voxelmodpack.common.net.upload.awt; + +import javax.swing.JFileChooser; + +/** + * Interface for objects which can receive a callback from ThreadOpenFile + * + * @author Adam Mummery-Smith + */ +public interface IOpenFileCallback { + + /** + * Callback method called when the "open file" dialog is closed + * + * @param fileDialog + * @param dialogResult + */ + public abstract void onFileOpenDialogClosed(JFileChooser fileDialog, int dialogResult); + +} \ No newline at end of file diff --git a/voxellib/src/main/java/com/voxelmodpack/common/net/upload/awt/ThreadOpenFile.java b/voxellib/src/main/java/com/voxelmodpack/common/net/upload/awt/ThreadOpenFile.java new file mode 100644 index 00000000..2c567b65 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/net/upload/awt/ThreadOpenFile.java @@ -0,0 +1,59 @@ +package com.voxelmodpack.common.net.upload.awt; + +import java.awt.Frame; + +import javax.swing.JFileChooser; +import javax.swing.filechooser.FileFilter; + +import net.minecraft.client.Minecraft; + +/** + * Base class for "open file" dialog threads + * + * @author Adam Mummery-Smith + */ +public abstract class ThreadOpenFile extends Thread { + /** + * Minecraft's AWT parent frame + */ + protected Frame parentFrame; + + protected String dialogTitle; + + /** + * Delegate to call back when the dialog box is closed + */ + protected final IOpenFileCallback parentScreen; + + /** + * @param minecraft + * @param callback + */ + protected ThreadOpenFile(Minecraft minecraft, String dialogTitle, IOpenFileCallback callback) + throws IllegalStateException { + if (minecraft.isFullScreen()) { + throw new IllegalStateException("Cannot open an awt window whilst minecraft is in full screen mode!"); + } + + this.parentScreen = callback; + this.dialogTitle = dialogTitle; + } + + @Override + public void run() { + JFileChooser fileDialog = new JFileChooser(); + fileDialog.setDialogTitle(this.dialogTitle); + fileDialog.setFileFilter(this.getFileFilter()); + + int dialogResult = fileDialog.showOpenDialog(this.parentFrame); + + this.parentScreen.onFileOpenDialogClosed(fileDialog, dialogResult); + } + + /** + * Subclasses should override this to return a file filter + * + * @return + */ + protected abstract FileFilter getFileFilter(); +} \ No newline at end of file diff --git a/voxellib/src/main/java/com/voxelmodpack/common/net/upload/awt/ThreadOpenFilePNG.java b/voxellib/src/main/java/com/voxelmodpack/common/net/upload/awt/ThreadOpenFilePNG.java new file mode 100644 index 00000000..3e9c5fd6 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/net/upload/awt/ThreadOpenFilePNG.java @@ -0,0 +1,43 @@ +package com.voxelmodpack.common.net.upload.awt; + +import java.io.File; + +import javax.swing.filechooser.FileFilter; + +import net.minecraft.client.Minecraft; + +/** + * Opens an awt "Open File" dialog with a PNG file filter + * + * @author Adam Mummery-Smith + */ +public class ThreadOpenFilePNG extends ThreadOpenFile { + /** + * @param minecraft + * @param dialogTitle + * @param callback + * @throws IllegalStateException + */ + public ThreadOpenFilePNG(Minecraft minecraft, String dialogTitle, IOpenFileCallback callback) + throws IllegalStateException { + super(minecraft, dialogTitle, callback); + } + + /** + * @return + */ + @Override + protected FileFilter getFileFilter() { + return new FileFilter() { + @Override + public String getDescription() { + return "PNG Files (*.png)"; + } + + @Override + public boolean accept(File f) { + return f.isDirectory() || f.getName().toLowerCase().endsWith(".png"); + } + }; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/ModConfig.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/ModConfig.java new file mode 100644 index 00000000..12763a6e --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/ModConfig.java @@ -0,0 +1,250 @@ +package com.voxelmodpack.common.properties; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.util.Properties; + +import com.mumfrey.liteloader.core.LiteLoader; +import com.mumfrey.liteloader.util.log.LiteLoaderLogger; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProviderBoolean; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProviderFloat; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProviderInteger; + +/** + * Configuration file for VoxelMods + */ +public abstract class ModConfig + implements IVoxelPropertyProviderFloat, IVoxelPropertyProviderInteger, IVoxelPropertyProviderBoolean { + /** + * Set of default properties Set these in setDefaults + */ + protected final Properties defaults = new Properties(); + + /** + * The runtime configuration + */ + protected Properties config; + + /** + * name of the mod that this belongs to + */ + protected final String modName; + + /** + * String path to the config file + */ + protected final String propertiesFileName; + + /** + * File that the configuration is held in + */ + protected File propertiesFile; + + /** + * @param modName Name of the mod that this will belong to + * @param propertiesFileName string path to the file that this uses + */ + public ModConfig(String modName, String propertiesFileName) { + this.modName = modName; + this.propertiesFileName = propertiesFileName; + this.setDefaults(); + LiteLoaderLogger.info("%s> Attempting to load/create the configuration.", this.modName); + this.loadConfig(); + } + + /** + * Use this to set the defaults in a config + */ + protected abstract void setDefaults(); + + /** + * Attemps to load the saved config file If the file cannot load the + * defaults are used If the file does not exist one is created with the + * defaults saved to it + */ + protected void loadConfig() { + this.config = new Properties(this.defaults); + + try { + this.propertiesFile = new File(LiteLoader.getCommonConfigFolder(), this.propertiesFileName); + + if (this.propertiesFile.exists()) { + LiteLoaderLogger.info("%s> Config file found, loading...", this.modName); + this.config.load(new FileInputStream(this.propertiesFile)); + } else { + LiteLoaderLogger.info("%s> No config file found, creating...", this.modName); + this.createConfig(); + } + } catch (Exception ex) { + LiteLoaderLogger.warning("%s> ERROR: %s", this.modName, ex.toString()); + } + } + + /** + * Create the config Only used to generate a new config file + */ + protected void createConfig() { + try { + this.config.putAll(this.defaults); + this.config.store(new FileWriter(this.propertiesFile), null); + } catch (Exception ex) { + LiteLoaderLogger.warning("%s> ERROR: %s", this.modName, ex.toString()); + } + } + + /** + * Set the given property to a float + * + * @param propertyName The property to change + * @param s The float value to set it to + */ + @Override + public void setProperty(String propertyName, float value) { + this.config.setProperty(propertyName, String.valueOf(value)); + this.saveConfig(); + } + + /** + * Set the given property to a int + * + * @param propertyName The property to change + * @param s The int value to set it to + */ + @Override + public void setProperty(String propertyName, int value) { + this.config.setProperty(propertyName, String.valueOf(value)); + this.saveConfig(); + } + + /** + * Set the given property to a boolean + * + * @param propertyName The property to change + * @param s The boolean value to set it to + */ + @Override + public void setProperty(String propertyName, boolean value) { + this.config.setProperty(propertyName, String.valueOf(value)); + this.saveConfig(); + } + + /** + * Set the given property to a string + * + * @param propertyName The property to change + * @param value The String to set it to + */ + public void setProperty(String propertyName, String value) { + this.config.setProperty(propertyName, value); + this.saveConfig(); + } + + /** + * @param propertyName The property that gets it's value returned + * @return A string value of the given property + */ + @Override + public String getStringProperty(String propertyName) { + return this.config.getProperty(propertyName); + } + + /** + * @param propertyName The property that gets it's value returned + * @return A float value of the given property + */ + @Override + public float getFloatProperty(String propertyName) { + return Float.parseFloat(this.config.getProperty(propertyName)); + } + + /** + * @param propertyName Name of the Property to get + * @param min the minimum that the property can be + * @param max the maximum that the property can be + * @return a float representation of the property that is within the min and + * max + */ + public float getClampedFloatProperty(String propertyName, float min, float max) { + float value = this.getFloatProperty(propertyName); + return Math.min(Math.max(value, min), max); + } + + /** + * @param propertyName The property that gets it's value returned + * @return A int value of the given property + */ + @Override + public int getIntProperty(String propertyName) { + return Integer.parseInt(this.config.getProperty(propertyName)); + } + + /** + * @param propertyName The property that gets it's value returned + * @return A boolean value of the given property + */ + @Override + public boolean getBoolProperty(String propertyName) { + return Boolean.parseBoolean(this.config.getProperty(propertyName)); + } + + /** + * @param propertyName The property that gets it's value returned + * @return A int value of the default for the given property + */ + @Override + public String getDefaultPropertyValue(String propertyName) { + return this.defaults.getProperty(propertyName); + } + + /** + * @param propertyName The property that gets it's value returned + * @return A float value of the default for the given property + */ + public float getDefaultFloatProperty(String propertyName) { + return Float.parseFloat(this.defaults.getProperty(propertyName)); + } + + /** + * @param propertyName The property that gets it's value returned + * @return A int value of the default for the given property + */ + public int getDefaultIntProperty(String propertyName) { + return Integer.parseInt(this.defaults.getProperty(propertyName)); + } + + /** + * @param propertyName The property that gets it's value returned + * @return A boolean value of the default for the given property + */ + public boolean getDefaultBoolProperty(String propertyName) { + return Boolean.parseBoolean(this.defaults.getProperty(propertyName)); + } + + /** + * Saves the configuration to file + */ + public void saveConfig() { + try { + this.config.store(new FileWriter(this.propertiesFile), null); + } catch (Exception e) { + LiteLoaderLogger.warning("%s> ERROR: %s", this.modName, e.toString()); + } + } + + /** + * Swaps the state of a boolean option + */ + @Override + public void toggleOption(String propertyName) { + this.setProperty(propertyName, !this.getBoolProperty(propertyName)); + } + + /** + * + */ + @Override + public String getOptionDisplayString(String propertyName) { + return ""; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelProperty.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelProperty.java new file mode 100644 index 00000000..ef813196 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelProperty.java @@ -0,0 +1,177 @@ +package com.voxelmodpack.common.properties; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.PositionedSoundRecord; +import net.minecraft.client.audio.SoundHandler; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.Gui; +import net.minecraft.util.ResourceLocation; + +import com.voxelmodpack.common.gui.interfaces.IExtendedGui; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProvider; + +/** + * Property superclass + * + * @author Adam Mummery-Smith + */ +public abstract class VoxelProperty extends Gui { + /** + * Font renderer reference + */ + protected FontRenderer fontRenderer; + + /** + * Underlying property provider for this property + */ + protected PropertyType propertyProvider; + + /** + * Name of the property this control is bound to + */ + protected String propertyBinding; + + /** + * Minecraft reference + */ + protected Minecraft mc = Minecraft.getMinecraft(); + + /** + * Display text (if any) for this property + */ + protected String displayText; + + /** + * X position + */ + protected int xPosition; + + /** + * Y position + */ + protected int yPosition; + + /** + * Cursor flash counter + */ + protected int cursorCounter; + + /** + * True if this control is has focus + */ + protected boolean focused; + + /** + * True if this control is visible + */ + protected boolean visible = true; + + /** + * @param propertyProvider + * @param binding + * @param displayText + * @param xPos + * @param yPos + */ + @SuppressWarnings("unchecked") + public VoxelProperty(IVoxelPropertyProvider propertyProvider, String binding, String displayText, int xPos, + int yPos) { + try { + this.propertyProvider = (PropertyType) propertyProvider; + } catch (ClassCastException ex) { + throw new RuntimeException(String.format("Can't create VoxelProperty for binding %s for panel %s", binding, + propertyProvider.getClass().getSimpleName())); + } + + this.fontRenderer = this.mc.fontRendererObj; + + this.propertyBinding = binding; + this.displayText = displayText; + this.xPosition = xPos; + this.yPosition = yPos; + } + + /** + * + */ + public void updateCursorCounter() { + this.cursorCounter++; + } + + /** + * Draw this property + * + * @param host + * @param mouseX + * @param mouseY + */ + public abstract void draw(IExtendedGui host, int mouseX, int mouseY); + + /** + * Handle mouse clicks on the property + * + * @param mouseX + * @param mouseY + */ + public abstract void mouseClicked(int mouseX, int mouseY); + + /** + * Handle keystrokes + * + * @param keyChar + * @param keyCode + */ + public abstract void keyTyped(char keyChar, int keyCode); + + /** + * Called when the containing GUI is closed + */ + public void onClosed() { + // stub + } + + /** + * Get whether this property is visible + */ + public boolean isVisible() { + return this.visible; + } + + /** + * Set whether this property is visible + */ + public void setVisible(boolean visible) { + this.visible = visible; + } + + /** + * @return + */ + public boolean isFocusable() { + return false; + } + + /** + * @return + */ + public boolean isFocused() { + return false; + } + + /** + * @param focus + */ + public void setFocused(boolean focus) {} + + /** + * @param soundHandler + */ + public void playClickSound(SoundHandler soundHandler) { + soundHandler.playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F)); + } + + @Override + public void drawString(FontRenderer fontRendererIn, String text, int x, int y, int color) { + super.drawString(fontRendererIn, text, x, y, color); + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyAbstractButton.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyAbstractButton.java new file mode 100644 index 00000000..0e779a7f --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyAbstractButton.java @@ -0,0 +1,69 @@ +package com.voxelmodpack.common.properties; + +import com.voxelmodpack.common.LiteModVoxelCommon; +import com.voxelmodpack.common.gui.interfaces.IExtendedGui; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProvider; + +public abstract class VoxelPropertyAbstractButton + extends VoxelProperty { + private int buttonOffset = 60; + private int buttonWidth = 70; + private int buttonHeight = 16; + + public VoxelPropertyAbstractButton(IVoxelPropertyProvider propertyProvider, String binding, String displayText, + int xPos, int yPos) { + this(propertyProvider, binding, displayText, xPos, yPos, 60, 70, 16); + } + + public VoxelPropertyAbstractButton(IVoxelPropertyProvider propertyProvider, String binding, String displayText, + int xPos, int yPos, int buttonOffset, int buttonWidth, int buttonHeight) { + super(propertyProvider, binding, displayText, xPos, yPos); + this.buttonOffset = buttonOffset; + this.buttonWidth = buttonWidth; + this.buttonHeight = buttonHeight; + } + + @Override + public void draw(IExtendedGui host, int mouseX, int mouseY) { + boolean overButton = this.mouseOver(mouseX, mouseY); + + int outset = overButton ? 1 : 0; + int v = overButton ? 16 : 0; + int colour = overButton ? 0xFFFFFF : 0x999999; + + drawRect(this.xPosition + this.buttonOffset + this.buttonWidth - 1, this.yPosition + this.buttonHeight, + this.xPosition + this.buttonOffset + 1, this.yPosition, 0xFF000000); + host.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, + this.xPosition + this.buttonOffset - outset, this.yPosition - 1 - outset, + this.xPosition + this.buttonOffset + this.buttonWidth + outset, + this.yPosition + 1 + this.buttonHeight + outset, 0, v, 16, v + 16, 4); + + this.drawString(this.fontRenderer, this.displayText, + (this.xPosition + this.buttonOffset + (this.buttonWidth / 2)) + - (this.fontRenderer.getStringWidth(this.displayText) / 2), + this.yPosition + 4, colour); + } + + @Override + public void mouseClicked(int mouseX, int mouseY) { + if (this.mouseOver(mouseX, mouseY)) { + this.onClick(); + } + } + + protected abstract void onClick(); + + /** + * @param mouseX + * @param mouseY + * @return + */ + public boolean mouseOver(int mouseX, int mouseY) { + return mouseX > this.xPosition + this.buttonOffset + && mouseX < this.xPosition + this.buttonOffset + this.buttonWidth && mouseY >= this.yPosition + && mouseY <= this.yPosition + this.buttonHeight; + } + + @Override + public void keyTyped(char keyChar, int keyCode) {} +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyAbstractTextField.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyAbstractTextField.java new file mode 100644 index 00000000..281e2b27 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyAbstractTextField.java @@ -0,0 +1,148 @@ +package com.voxelmodpack.common.properties; + +import org.lwjgl.input.Keyboard; + +import com.voxelmodpack.common.gui.interfaces.IExtendedGui; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProvider; + +/** + * Adapted from xTiming's text field code + * + * @author Adam Mummery-Smith + */ +public abstract class VoxelPropertyAbstractTextField + extends VoxelProperty { + protected String allowedCharacters = "0123456789"; + protected String fieldValue = "0"; + protected String defaultFieldValue = "0"; + protected int fieldOffset = 74; + protected int fieldWidth = 52; + protected int fieldHeight = 16; + + public VoxelPropertyAbstractTextField(IVoxelPropertyProvider propertyProvider, String binding, String displayText, + int xPos, int yPos, int fieldOffset) { + super(propertyProvider, binding, displayText, xPos, yPos); + + this.fieldValue = this.propertyProvider.getStringProperty(binding); + this.defaultFieldValue = this.propertyProvider.getDefaultPropertyValue(this.propertyBinding); + this.fieldOffset = fieldOffset; + } + + /** + * @param mouseX + * @param mouseY + * @param fieldValue + * @param focused + * @param field_146128_h + * @param field_146129_i + * @return + */ + @Override + public void draw(IExtendedGui host, int mouseX, int mouseY) { + drawRect(this.xPosition + this.fieldOffset + this.fieldWidth, this.yPosition + this.fieldHeight, + this.xPosition + this.fieldOffset, this.yPosition - 1, this.focused ? 0xFFFFFFFF : 0xFF999999); + drawRect(this.xPosition + this.fieldOffset + this.fieldWidth - 1, this.yPosition + this.fieldHeight - 1, + this.xPosition + this.fieldOffset + 1, this.yPosition, 0xFF000000); + + boolean optionCursor = this.focused && (this.cursorCounter / 6) % 2 == 0; + this.drawString(this.fontRenderer, this.displayText, this.xPosition, this.yPosition + 4, 0xFFFFFF); + this.drawString(this.fontRenderer, this.fieldValue + (optionCursor ? "_" : ""), + this.fieldValue.length() > 0 + ? (this.xPosition + this.fieldOffset + (this.fieldWidth / 2)) + - (this.fontRenderer.getStringWidth(this.fieldValue) / 2) + : this.xPosition + this.fieldOffset + (this.fieldWidth / 2) - 3, + this.yPosition + 4, 0xFFFFFF); + } + + /** + * @param keyChar + * @param keyCode + */ + @Override + public void keyTyped(char keyChar, int keyCode) { + if (this.focused) { + if (keyCode == Keyboard.KEY_RETURN || keyCode == Keyboard.KEY_NUMPADENTER || keyCode == Keyboard.KEY_ESCAPE) + this.onLostFocus(); + + if (keyCode == Keyboard.KEY_BACK && this.fieldValue.length() > 0) + this.fieldValue = this.fieldValue.substring(0, this.fieldValue.length() - 1); + + if (keyCode == Keyboard.KEY_PERIOD && this.allowedCharacters.indexOf('.') >= 0) { + if (this.fieldValue.indexOf(keyChar) >= 0) + return; + if (this.fieldValue.length() == 0) + this.fieldValue += "0"; + } + + if (this.allowedCharacters.indexOf(keyChar) >= 0 && this.fieldValue.length() < 4) + this.fieldValue += keyChar; + + if (this.checkInvalidValue()) + this.fieldValue = this.defaultFieldValue; + } + } + + /** + * @return + */ + protected abstract boolean checkInvalidValue(); + + /** + * @param mouseX + * @param mouseY + */ + @Override + public void mouseClicked(int mouseX, int mouseY) { + boolean mouseOver = this.mouseOver(mouseX, mouseY); + + if (!this.focused && mouseOver) { + this.playClickSound(this.mc.getSoundHandler()); + this.fieldValue = this.propertyProvider.getStringProperty(this.propertyBinding); + } else if (this.focused && !mouseOver) { + this.onLostFocus(); + } + + this.focused = mouseOver; + } + + @Override + public void onClosed() { + this.onLostFocus(); + } + + protected abstract void onLostFocus(); + + /** + * @param mouseX + * @param mouseY + * @return + */ + public boolean mouseOver(int mouseX, int mouseY) { + return mouseX > this.xPosition + this.fieldOffset + && mouseX < this.xPosition + this.fieldOffset + this.fieldWidth && mouseY > this.yPosition + && mouseY < this.yPosition + 15; + } + + public void update() { + this.fieldValue = this.propertyProvider.getStringProperty(this.propertyBinding); + } + + @Override + public boolean isFocusable() { + return true; + } + + @Override + public void setFocused(boolean focus) { + if (this.focused && !focus) { + this.onLostFocus(); + } + + this.focused = focus; + } + + @Override + public boolean isFocused() { + return this.focused; + } +} \ No newline at end of file diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyCheckBox.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyCheckBox.java new file mode 100644 index 00000000..52b7e98c --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyCheckBox.java @@ -0,0 +1,67 @@ +package com.voxelmodpack.common.properties; + +import com.voxelmodpack.common.LiteModVoxelCommon; +import com.voxelmodpack.common.gui.interfaces.IExtendedGui; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProviderBoolean; + +/** + * Adapted from xTiming's checkbox code + * + * @author Adam Mummery-Smith + */ +public class VoxelPropertyCheckBox extends VoxelPropertyToggleButton { + private int width = 11; + + private final VoxelPropertyCheckBox parent; + + public VoxelPropertyCheckBox(IVoxelPropertyProviderBoolean propertyProvider, String binding, String text, int xPos, + int yPos) { + this(propertyProvider, binding, text, xPos, yPos, null); + } + + public VoxelPropertyCheckBox(IVoxelPropertyProviderBoolean propertyProvider, String binding, String text, int xPos, + int yPos, VoxelPropertyCheckBox parent) { + super(propertyProvider, binding, text, xPos, yPos); + + this.width = this.fontRenderer.getStringWidth(this.displayText) + 20; + this.parent = parent; + } + + public VoxelPropertyCheckBox getParent() { + return this.parent; + } + + @Override + public void draw(IExtendedGui host, int mouseX, int mouseY) { + this.drawString(this.fontRenderer, this.displayText, this.xPosition + 20, this.yPosition + 2, + this.isParentChecked() ? 0xFFFFFF : 0x666666); + + boolean overButton = this.mouseOver(mouseX, mouseY); + boolean checked = this.isChecked(); + + host.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, this.xPosition, this.yPosition, + this.xPosition + 11, this.yPosition + 11, 0, overButton ? 16 : 0, 16, overButton ? 32 : 16, 4); + host.drawTexturedModalRect(LiteModVoxelCommon.GUIPARTS, this.xPosition, this.yPosition, this.xPosition + 10, + this.yPosition + 10, checked ? 12 : 0, 52, checked ? 23 : 11, 63); + } + + /** + * @return + */ + boolean isChecked() { + return this.isParentChecked() && this.propertyProvider.getBoolProperty(this.propertyBinding); + } + + /** + * @return + */ + boolean isParentChecked() { + return this.parent == null || this.parent.isChecked(); + } + + @Override + public boolean mouseOver(int mouseX, int mouseY) { + return this.isParentChecked() && mouseX > this.xPosition && mouseX < this.xPosition + this.width + && mouseY > this.yPosition && mouseY < this.yPosition + 11; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyFloatField.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyFloatField.java new file mode 100644 index 00000000..99197454 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyFloatField.java @@ -0,0 +1,40 @@ +package com.voxelmodpack.common.properties; + +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProvider; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProviderFloat; + +/** + * Adapted from xTiming's text field code + * + * @author Adam Mummery-Smith + */ +public class VoxelPropertyFloatField extends VoxelPropertyAbstractTextField { + private float minFieldValue = 0.1F; + + private float maxFieldValue = 10.0F; + + public VoxelPropertyFloatField(IVoxelPropertyProvider propertyProvider, String binding, String text, int xPos, + int yPos, int fieldOffset) { + super(propertyProvider, binding, text, xPos, yPos, fieldOffset); + this.allowedCharacters = "0123456789."; + } + + @Override + protected void onLostFocus() { + if (this.fieldValue.length() == 0) + this.fieldValue = this.propertyProvider.getDefaultPropertyValue(this.propertyBinding); + if (Float.valueOf(this.fieldValue) < this.minFieldValue) + this.fieldValue = String.valueOf(this.minFieldValue); + this.propertyProvider.setProperty(this.propertyBinding, Float.parseFloat(this.fieldValue)); + this.fieldValue = this.propertyProvider.getStringProperty(this.propertyBinding); + this.focused = false; + } + + /** + * @return + */ + @Override + protected boolean checkInvalidValue() { + return this.fieldValue.length() > 0 && Float.valueOf(this.fieldValue) > this.maxFieldValue; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyIntField.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyIntField.java new file mode 100644 index 00000000..022a4b2d --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyIntField.java @@ -0,0 +1,55 @@ +package com.voxelmodpack.common.properties; + +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProvider; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProviderInteger; + +/** + * Adapted from xTiming's text field code + * + * @author Adam Mummery-Smith + */ +public class VoxelPropertyIntField extends VoxelPropertyAbstractTextField { + private int minFieldValue = 1; + + private int maxFieldValue = 60; + + public VoxelPropertyIntField(IVoxelPropertyProvider propertyProvider, String binding, String text, int xPos, + int yPos, int fieldOffset) { + super(propertyProvider, binding, text, xPos, yPos, fieldOffset); + } + + @Override + protected void onLostFocus() { + if (this.fieldValue.length() == 0) + this.fieldValue = this.propertyProvider.getDefaultPropertyValue(this.propertyBinding); + if (Integer.valueOf(this.fieldValue) < this.minFieldValue) + this.fieldValue = String.valueOf(this.minFieldValue); + this.propertyProvider.setProperty(this.propertyBinding, Integer.parseInt(this.fieldValue)); + this.fieldValue = this.propertyProvider.getStringProperty(this.propertyBinding); + this.focused = false; + } + + /** + * @return + */ + @Override + protected boolean checkInvalidValue() { + return this.fieldValue.length() > 0 && Integer.valueOf(this.fieldValue) > this.maxFieldValue; + } + + public int getMinFieldValue() { + return this.minFieldValue; + } + + public void setMinFieldValue(int minFieldValue) { + this.minFieldValue = minFieldValue; + } + + public int getMaxFieldValue() { + return this.maxFieldValue; + } + + public void setMaxFieldValue(int maxFieldValue) { + this.maxFieldValue = maxFieldValue; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyKeyBinding.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyKeyBinding.java new file mode 100644 index 00000000..a297da7c --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyKeyBinding.java @@ -0,0 +1,102 @@ +package com.voxelmodpack.common.properties; + +import org.lwjgl.input.Keyboard; + +import com.voxelmodpack.common.LiteModVoxelCommon; +import com.voxelmodpack.common.gui.interfaces.IExtendedGui; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProvider; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProviderInteger; + +/** + * Adapted from xTiming's key bind button code + * + * @author Adam Mummery-Smith + */ +public class VoxelPropertyKeyBinding extends VoxelProperty { + private int buttonOffset = 60; + private int buttonWidth = 70; + private int buttonHeight = 16; + + /** + * @param parent + * @param binding + * @param displayText + * @param xPos + * @param yPos + */ + public VoxelPropertyKeyBinding(IVoxelPropertyProvider propertyProvider, String binding, String displayText, + int xPos, int yPos) { + super(propertyProvider, binding, displayText, xPos, yPos); + } + + /** + * @param mouseX + * @param mouseY + * @param displayText + * @param keyCode + * @param bindActive + * @param field_146128_h + * @param field_146129_i + * @return + */ + @Override + public void draw(IExtendedGui host, int mouseX, int mouseY) { + boolean overKey = this.focused || this.mouseOver(mouseX, mouseY); + int outset = overKey ? 1 : 0; + int v = overKey ? 16 : 0; + int keyCode = this.propertyProvider.getIntProperty(this.propertyBinding); + + this.drawString(this.fontRenderer, this.displayText, this.xPosition, this.yPosition + 4, 0xFFFFFF); + String fKey = this.focused ? "Press a key" : Keyboard.getKeyName(keyCode); + drawRect(this.xPosition + this.buttonOffset + this.buttonWidth - 1, this.yPosition + this.buttonHeight, + this.xPosition + this.buttonOffset + 1, this.yPosition, 0xFF000000); + host.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, + this.xPosition + this.buttonOffset - outset, this.yPosition - 1 - outset, + this.xPosition + this.buttonOffset + this.buttonWidth + outset, + this.yPosition + 1 + this.buttonHeight + outset, 0, v, 16, v + 16, 4); + this.drawString(this.fontRenderer, fKey, + (this.xPosition + this.buttonOffset + (this.buttonWidth / 2)) + - (this.fontRenderer.getStringWidth(fKey) / 2), + this.yPosition + 4, overKey || this.focused ? 0xFFFFFF : 0x999999); + } + + /* + * (non-Javadoc) + * @see + * com.voxelbox.voxelflight.VoxelFlightGUI.VoxelProperty#MouseClicked(int, + * int) + */ + @Override + public void mouseClicked(int mouseX, int mouseY) { + boolean mouseOver = this.mouseOver(mouseX, mouseY); + + if (!this.focused && mouseOver) + this.playClickSound(this.mc.getSoundHandler()); + + this.focused = mouseOver; + } + + /** + * @param mouseX + * @param mouseY + * @return + */ + public boolean mouseOver(int mouseX, int mouseY) { + return mouseX > this.xPosition + this.buttonOffset + && mouseX < this.xPosition + this.buttonOffset + this.buttonWidth && mouseY >= this.yPosition + && mouseY <= this.yPosition + this.buttonHeight; + } + + /* + * (non-Javadoc) + * @see com.voxelbox.voxelflight.VoxelFlightGUI.VoxelProperty#KeyTyped(char, + * int) + */ + @Override + public void keyTyped(char keyChar, int keyCode) { + if (this.focused) { + this.propertyProvider.setProperty(this.propertyBinding, keyCode); + this.focused = false; + } + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyLabel.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyLabel.java new file mode 100644 index 00000000..064a4bab --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyLabel.java @@ -0,0 +1,33 @@ +package com.voxelmodpack.common.properties; + +import com.voxelmodpack.common.gui.interfaces.IExtendedGui; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProvider; + +/** + * Label + * + * @author Adam Mummery-Smith + */ +public class VoxelPropertyLabel extends VoxelProperty { + private int colour = 0x99CCFF; + + public VoxelPropertyLabel(String displayText, int xPos, int yPos) { + this(displayText, xPos, yPos, 0x99CCFF); + } + + public VoxelPropertyLabel(String displayText, int xPos, int yPos, int colour) { + super(null, null, displayText, xPos, yPos); + this.colour = colour; + } + + @Override + public void draw(IExtendedGui host, int mouseX, int mouseY) { + this.drawString(this.mc.fontRendererObj, this.displayText, this.xPosition, this.yPosition, this.colour); + } + + @Override + public void mouseClicked(int mouseX, int mouseY) {} + + @Override + public void keyTyped(char keyChar, int keyCode) {} +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertySlider.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertySlider.java new file mode 100644 index 00000000..ffb36776 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertySlider.java @@ -0,0 +1,279 @@ +package com.voxelmodpack.common.properties; + +import org.lwjgl.input.Mouse; + +import com.voxelmodpack.common.LiteModVoxelCommon; +import com.voxelmodpack.common.gui.interfaces.IExtendedGui; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProvider; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProviderFloat; + +/** + * Rebuilt by anangrybeaver + * + * @author anangrybeaver + */ +public class VoxelPropertySlider extends VoxelProperty { + private float value = 0; + private float valueMin = -1; + private float valueMax = 1; + private float valueShift = -1; + private float valueScale; + + private float indicatorValue = 0; + + private int sliderHeight; + private int sliderWidth; + + private int handleXPos; + private int handleXPosMin; + private int handleXPosMax; + private int handleWidth; + private int handleHeight; + + private boolean snap = false; + + private boolean indicatorShow = false; + + private String minText = "Min"; + private String maxText = "Max"; + + @SuppressWarnings("unused") + private String labelText; + + public VoxelPropertySlider(IVoxelPropertyProvider propertyProvider, String binding, String text, int xPos, int yPos, + int w, int h, float minValue, float maxValue, boolean snap) { + this(propertyProvider, binding, text, xPos, yPos, w, h, snap); + + this.valueMax = maxValue; + this.valueMin = minValue; + + if (this.valueMax < this.valueMin || this.valueMax == this.valueMin) + this.valueMax = this.valueMin + 1; + + this.valueShift = this.valueMin; + + this.value = this.propertyProvider.getFloatProperty(binding) - this.valueShift; + this.valueScale = (this.handleXPosMax - this.handleXPosMin) / (this.valueMax - this.valueMin); + + if (this.propertyProvider.getFloatProperty(binding) < this.valueMin) + this.propertyProvider.setProperty(binding, this.valueMin); + + else if (this.propertyProvider.getFloatProperty(binding) > this.valueMax) + this.propertyProvider.setProperty(binding, this.valueMax); + } + + /** + * Creates a more defined Slider with given specifications. + * + * @param parent The GUI Element, "this" + * @param binding The numeral binding to be linked to. + * @param text Name of the slider. + * @param xPos x Coordinate + * @param yPos y coordinate + * @param w Width of the slider + * @param h Height of the slider + * @param minValue minimum value of the slider + * @param maxValue max value of the slider + * @param snap If it snaps to whole numbers. + */ + public VoxelPropertySlider(IVoxelPropertyProvider propertyProvider, String binding, String text, int xPos, int yPos, + int w, int h, float minValue, float maxValue, float indicatorValue, boolean snap) { + this(propertyProvider, binding, text, xPos, yPos, w, h, indicatorValue, snap); + + this.valueMax = maxValue; + this.valueMin = minValue; + + if (this.valueMax < this.valueMin || this.valueMax == this.valueMin) + this.valueMax = this.valueMin + 1; + + this.valueShift = this.valueMin; + + this.value = this.propertyProvider.getFloatProperty(binding) - this.valueShift; + this.valueScale = (this.handleXPosMax - this.handleXPosMin) / (this.valueMax - this.valueMin); + + if (this.propertyProvider.getFloatProperty(binding) < this.valueMin) + this.propertyProvider.setProperty(binding, this.valueMin); + + else if (this.propertyProvider.getFloatProperty(binding) > this.valueMax) + this.propertyProvider.setProperty(binding, this.valueMax); + + } + + /** + * Creates a generic Slider with given specifications. + * + * @param parent The GUI Element, "this" + * @param binding The numeral binding to be linked to. + * @param text Name of the slider. + * @param xPos x Coordinate + * @param yPos y coordinate + * @param w Width of the slider + * @param h Height of the slider + * @param indicatorValue The value of a visible indicator on the slider. + * @param snap If it snaps to whole numbers. + */ + public VoxelPropertySlider(IVoxelPropertyProvider propertyProvider, String binding, String text, int xPos, int yPos, + int w, int h, float indicatorValue, boolean snap) { + this(propertyProvider, binding, text, xPos, yPos, w, h, snap); + + this.indicatorValue = indicatorValue; + this.indicatorShow = true; + } + + /** + * Creates a generic Slider with given specifications. + * + * @param parent The GUI Element, "this" + * @param binding The numeral binding to be linked to. + * @param displayText Name of the slider. + * @param xPos x Coordinate + * @param yPos y coordinate + * @param w Width of the slider + * @param h Height of the slider + * @param snap If it snaps to whole numbers. + */ + public VoxelPropertySlider(IVoxelPropertyProvider propertyProvider, String binding, String displayText, int xPos, + int yPos, int w, int h, boolean snap) { + super(propertyProvider, binding, displayText, xPos, yPos); + + this.sliderHeight = h; + this.sliderWidth = w; + + this.handleWidth = this.sliderHeight - 2; + this.handleHeight = this.sliderHeight + 4; + + this.handleXPos = this.xPosition; + this.handleXPosMin = this.xPosition + 2; + this.handleXPosMax = this.xPosition + this.sliderWidth - this.handleWidth - 2; + + this.value = this.propertyProvider.getFloatProperty(binding) - this.valueShift; + this.valueScale = (this.handleXPosMax - this.handleXPosMin) / (this.valueMax - this.valueMin); + + this.snap = snap; + } + + public VoxelPropertySlider(IVoxelPropertyProvider propertyProvider, String binding, String displayText, + String minText, String maxText, int xPos, int yPos, float min, float max) { + this(propertyProvider, binding, displayText, xPos, yPos, min, max); + + this.minText = minText; + this.maxText = maxText; + } + + public VoxelPropertySlider(IVoxelPropertyProvider propertyProvider, String binding, String displayText, int xPos, + int yPos, float min, float max) { + this(propertyProvider, binding, displayText, xPos, yPos); + + this.valueMin = min; + this.valueMax = max; + + if (this.valueMax < this.valueMin || this.valueMax == this.valueMin) + this.valueMax = this.valueMin + 1; + + this.valueShift = this.valueMin; + + this.value = this.propertyProvider.getFloatProperty(binding) - this.valueShift; + this.valueScale = (this.handleXPosMax - this.handleXPosMin) / (this.valueMax - this.valueMin); + + } + + public VoxelPropertySlider(IVoxelPropertyProvider propertyProvider, String binding, String displayText, + String minText, String maxText, int xPos, int yPos) { + this(propertyProvider, binding, displayText, xPos, yPos); + + this.minText = minText; + this.maxText = maxText; + } + + public VoxelPropertySlider(IVoxelPropertyProvider propertyProvider, String binding, String displayText, int xPos, + int yPos) { + this(propertyProvider, binding, displayText, xPos, yPos, 100, 8, false); + } + + @Override + public void draw(IExtendedGui host, int mouseX, int mouseY) { + if (Mouse.isButtonDown(0)) { + if (this.focused) { + this.moveHandle(mouseX); + } + } else { + this.focused = false; + } + + this.handleXPos = (int) (this.handleXPosMin + (this.value * this.valueScale)); + + int mintextX = this.fontRenderer.getStringWidth(this.minText); + + this.fontRenderer.drawStringWithShadow(this.displayText, this.xPosition, this.yPosition - 12, 0xFFFFFF); + this.fontRenderer.drawStringWithShadow(this.minText, this.xPosition - mintextX - 2, this.yPosition, 0xFFFFFF); + this.fontRenderer.drawStringWithShadow(this.maxText, this.xPosition + this.sliderWidth + 2, this.yPosition, + 0xFFFFFF); + + host.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, this.xPosition, this.yPosition, + this.xPosition + this.sliderWidth, this.yPosition + this.sliderHeight, 1, 114, 127, 119, 2); + + if (this.indicatorShow) + this.drawIndicator(host); + this.drawHandle(host); + } + + /** + * Draws an indicator for a value on the slider. + */ + private void drawIndicator(IExtendedGui host) { + int xPosZero = (int) (this.handleXPosMin + ((this.indicatorValue + Math.abs(this.valueMin)) * this.valueScale)); + + host.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, xPosZero - 1, this.yPosition + 1, + xPosZero + this.handleWidth + 1, this.yPosition + this.sliderHeight - 1, 1, 33, 15, 47, 3); + host.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, xPosZero, this.yPosition + 1, + xPosZero + this.handleWidth, this.yPosition + this.sliderHeight - 1, 0, 121, 128, 128, 2); + } + + /** + * Draws the handle for the slider. + */ + private void drawHandle(IExtendedGui host) { + host.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, this.handleXPos - 1, this.yPosition - 2, + this.handleXPos + this.handleWidth + 1, this.yPosition + this.handleHeight - 2, 17, 33, 31, 47, 3); + host.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, this.handleXPos, this.yPosition - 2, + this.handleXPos + this.handleWidth, this.yPosition + this.handleHeight - 2, 0, 121, 128, 128, 3); + } + + /** + * @param mouseX + * @param mouseY + * @param x1 + * @param y1 + * @param x2 + * @param y2 + */ + protected boolean mouseIn(int mouseX, int mouseY, int x1, int y1, int x2, int y2) { + return mouseX > x1 && mouseX < x2 && mouseY > y1 && mouseY < y2; + } + + @SuppressWarnings("cast") + public void moveHandle(int mouseX) { + mouseX -= (this.handleWidth / 2); + + if (mouseX < this.handleXPosMin || ((mouseX - this.handleXPosMin) / this.valueScale) < 0) + this.value = 0; + else if (mouseX > this.handleXPosMin + (this.handleXPosMax - this.handleXPosMin) + || ((mouseX - this.handleXPosMin) / this.valueScale) > (this.valueMax - this.valueMin)) + this.value = (this.valueMax - this.valueMin); + else if (this.snap) + this.value = (int) ((mouseX - this.handleXPosMin) / this.valueScale); + else + this.value = (float) ((mouseX - this.handleXPosMin) / this.valueScale); + + this.propertyProvider.setProperty(this.propertyBinding, this.value + this.valueShift); + } + + @Override + public void mouseClicked(int mouseX, int mouseY) { + this.focused = this.mouseIn(mouseX, mouseY, this.xPosition, this.yPosition, this.xPosition + this.sliderWidth, + this.yPosition + this.sliderHeight); + } + + @Override + public void keyTyped(char keyChar, int keyCode) {} +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertySliderOld.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertySliderOld.java new file mode 100644 index 00000000..18e9425f --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertySliderOld.java @@ -0,0 +1,188 @@ +package com.voxelmodpack.common.properties; + +import net.minecraft.util.MathHelper; + +import org.lwjgl.input.Mouse; + +import com.voxelmodpack.common.LiteModVoxelCommon; +import com.voxelmodpack.common.gui.interfaces.IExtendedGui; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProvider; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProviderFloat; + +/** + * @author xTiming + */ +public class VoxelPropertySliderOld extends VoxelProperty { + float minValue = -1.0F; + + float maxValue = 1.0F; + + float value = 0F; + + boolean overReset = false; + boolean overSlide = false; + boolean overBar = false; + boolean setBar = false; + boolean dragging = false; + + int offset = 0; + + String minText = "Min"; + String maxText = "Max"; + + String labelText; + + public VoxelPropertySliderOld(IVoxelPropertyProvider propertyProvider, String binding, String displayText, + String minText, String maxText, int xPos, int yPos, float min, float max) { + this(propertyProvider, binding, displayText, minText, maxText, xPos, yPos); + this.minValue = min; + this.maxValue = max; + } + + public VoxelPropertySliderOld(IVoxelPropertyProvider propertyProvider, String binding, String displayText, int xPos, + int yPos, float min, float max) { + this(propertyProvider, binding, displayText, xPos, yPos); + } + + public VoxelPropertySliderOld(IVoxelPropertyProvider propertyProvider, String binding, String displayText, + String minText, String maxText, int xPos, int yPos) { + this(propertyProvider, binding, displayText, xPos, yPos); + + this.minText = minText; + this.maxText = maxText; + } + + public VoxelPropertySliderOld(IVoxelPropertyProvider propertyProvider, String binding, String displayText, int xPos, + int yPos) { + super(propertyProvider, binding, displayText, xPos, yPos); + } + + @Override + public void draw(IExtendedGui host, int mouseX, int mouseY) { + if (this.displayText != null) { + this.drawString(this.mc.fontRendererObj, this.displayText, this.xPosition + 18, this.yPosition, 0x99CCFF); + } + + this.drawString(this.mc.fontRendererObj, this.minText, this.xPosition + 30, this.yPosition + 15, 0xFFFFFF); + + if (this.maxText != null) { + this.drawString(this.mc.fontRendererObj, this.maxText, this.xPosition + 130, this.yPosition + 15, 0xFFFFFF); + } else { + float scale = (this.value + 1.0F) / 2.0F; + int displayValue = MathHelper + .ceiling_float_int((this.minValue + ((this.maxValue - this.minValue) * scale)) * 100F); + + this.drawString(this.mc.fontRendererObj, displayValue + "%", this.xPosition + 130, this.yPosition + 15, + 0xFFFFFF); + } + + this.overReset = this.mouseOverReset(mouseX, mouseY); + + int outset = this.overReset ? 1 : 0; + int v = this.overReset ? 16 : 0; + + drawRect(this.xPosition + 160 - outset, this.yPosition + 11 - outset, this.xPosition + 212 + outset, + this.yPosition + 26 + outset, 0xFF000000); + host.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, this.xPosition + 159 - outset, + this.yPosition + 10 - outset, this.xPosition + 213 + outset, this.yPosition + 27 + outset, 0, v, 16, + 16 + v, 4); + this.drawString(this.mc.fontRendererObj, "Default", this.xPosition + 169, this.yPosition + 15, + this.overReset ? 0xFFFFFF : 0x999999); + + int sliderLeft = this.xPosition + 48; + int sliderRight = this.xPosition + 124; + int sliderXPos = sliderLeft + 32; + int sliderXPos2 = sliderLeft + 45; + int sliderYPos = this.yPosition + 12; + int sliderYPos2 = this.yPosition + 25; + int sliderMinX = sliderLeft - ((sliderXPos + sliderXPos2) / 2) + 5; + int sliderMaxX = sliderRight - ((sliderXPos + sliderXPos2) / 2) - 5; + + this.drawHorizontalLine(sliderLeft, sliderRight, this.yPosition + 18, 0xFF999999); + this.drawVerticalLine(this.xPosition + 86, this.yPosition + 14, this.yPosition + 22, 0xFF999999); + this.drawVerticalLine(sliderLeft, this.yPosition + 14, this.yPosition + 22, 0xFF999999); + this.drawVerticalLine(sliderRight, this.yPosition + 14, this.yPosition + 22, 0xFF999999); + + this.overSlide = this.mouseIn(mouseX, mouseY, sliderXPos, sliderYPos, sliderXPos2, sliderYPos2); + this.overBar = this.mouseIn(mouseX, mouseY, sliderLeft, sliderYPos, sliderRight, sliderYPos2) + && !this.overSlide; + + if (this.dragging) { + if (Mouse.isButtonDown(0)) { + this.offset = Math.min(Math.max(mouseX - (sliderXPos + sliderXPos2) / 2, sliderMinX), sliderMaxX); + this.value = ((float) this.offset / (float) sliderMaxX); + } else { + this.value = ((float) this.offset / (float) sliderMaxX); + this.propertyProvider.setProperty(this.propertyBinding, this.value); + this.dragging = false; + } + } else { + this.offset = (int) ((this.propertyProvider.getFloatProperty(this.propertyBinding)) * sliderMaxX); + this.value = ((float) this.offset / (float) sliderMaxX); + } + + if (this.setBar) { + this.offset = mouseX - (sliderXPos + sliderXPos2) / 2; + this.value = ((float) this.offset / (float) sliderMaxX); + this.propertyProvider.setProperty(this.propertyBinding, this.value); + this.setBar = false; + this.dragging = true; + } + + if (this.offset > sliderMaxX) + this.offset = sliderMaxX; + if (this.offset < sliderMinX) + this.offset = sliderMinX; + + drawRect(sliderXPos2 - 1 + this.offset, sliderYPos2 - 1, sliderXPos + 1 + this.offset, sliderYPos + 1, + 0xFF000000); + host.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, (sliderXPos + this.offset), sliderYPos, + (sliderXPos2 + this.offset), sliderYPos2, 0, (this.overSlide || this.dragging) ? 16 : 0, 16, + (this.overSlide || this.dragging) ? 32 : 16, 4); + } + + /** + * @param mouseX + * @param mouseY + * @param x1 + * @param y1 + * @param x2 + * @param y2 + */ + protected boolean mouseIn(int mouseX, int mouseY, int x1, int y1, int x2, int y2) { + return mouseX > x1 + this.offset && mouseX < x2 + this.offset && mouseY > y1 && mouseY < y2; + } + + /** + * @param mouseX + * @param mouseY + * @return + */ + protected boolean mouseOverReset(int mouseX, int mouseY) { + return mouseX > this.xPosition + 159 && mouseX < this.xPosition + 213 && mouseY > this.yPosition + 10 + && mouseY < this.yPosition + 27; + } + + @Override + public void mouseClicked(int mouseX, int mouseY) { + if (this.overSlide) { + this.dragging = true; + this.playClickSound(this.mc.getSoundHandler()); + return; + } + + if (this.overBar) { + this.setBar = true; + this.playClickSound(this.mc.getSoundHandler()); + return; + } + + if (this.overReset) { + this.propertyProvider.setProperty(this.propertyBinding, 0.0F); + this.playClickSound(this.mc.getSoundHandler()); + } + } + + @Override + public void keyTyped(char keyChar, int keyCode) {} +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyToggleButton.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyToggleButton.java new file mode 100644 index 00000000..92861a57 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/VoxelPropertyToggleButton.java @@ -0,0 +1,104 @@ +package com.voxelmodpack.common.properties; + +import com.voxelmodpack.common.LiteModVoxelCommon; +import com.voxelmodpack.common.gui.interfaces.IExtendedGui; +import com.voxelmodpack.common.properties.interfaces.IVoxelPropertyProviderBoolean; + +/** + * Adapted from xTiming's button code + * + * @author Adam Mummery-Smith + */ +public class VoxelPropertyToggleButton extends VoxelProperty { + private int buttonOffset = 60; + private int buttonWidth = 70; + private int buttonHeight = 16; + + private String status; + + /** + * @param propertyProvider + * @param binding + * @param displayText + * @param xPos + * @param yPos + */ + public VoxelPropertyToggleButton(IVoxelPropertyProviderBoolean propertyProvider, String binding, String displayText, + int xPos, int yPos) { + this(propertyProvider, binding, displayText, xPos, yPos, 60, 70, 16); + } + + /** + * @param propertyProvider + * @param binding + * @param displayText + * @param xPos + * @param yPos + * @param buttonOffset + * @param buttonWidth + * @param buttonHeight + */ + public VoxelPropertyToggleButton(IVoxelPropertyProviderBoolean propertyProvider, String binding, String displayText, + int xPos, int yPos, int buttonOffset, int buttonWidth, int buttonHeight) { + super(propertyProvider, binding, displayText, xPos, yPos); + this.buttonOffset = buttonOffset; + this.buttonWidth = buttonWidth; + this.buttonHeight = buttonHeight; + this.status = this.propertyProvider.getOptionDisplayString(this.propertyBinding); + } + + /* + * (non-Javadoc) + * @see + * com.voxelmodpack.common.properties.VoxelProperty#draw(com.voxelmodpack. + * common.gui.IExtendedGui, int, int) + */ + @Override + public void draw(IExtendedGui host, int mouseX, int mouseY) { + boolean overButton = this.mouseOver(mouseX, mouseY); + int outset = overButton ? 1 : 0; + int v = overButton ? 16 : 0; + int colour = overButton ? 0xFFFFFF : 0x999999; + + this.drawString(this.fontRenderer, this.displayText, this.xPosition, this.yPosition + 4, 0xFFFFFF); + drawRect(this.xPosition + this.buttonOffset + this.buttonWidth - 1, this.yPosition + this.buttonHeight, + this.xPosition + this.buttonOffset + 1, this.yPosition, 0xFF000000); + host.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, + this.xPosition + this.buttonOffset - outset, this.yPosition - outset, + this.xPosition + this.buttonOffset + this.buttonWidth + outset, + this.yPosition + this.buttonHeight + outset, 0, v, 16, v + 16, 4); + this.drawString(this.fontRenderer, this.status, (this.xPosition + this.buttonOffset + (this.buttonWidth / 2)) + - (this.fontRenderer.getStringWidth(this.status) / 2), this.yPosition + 4, colour); + } + + /* + * (non-Javadoc) + * @see com.voxelmodpack.common.properties.VoxelProperty#mouseClicked(int, + * int) + */ + @Override + public void mouseClicked(int mouseX, int mouseY) { + if (this.mouseOver(mouseX, mouseY)) { + this.propertyProvider.toggleOption(this.propertyBinding); + this.status = this.propertyProvider.getOptionDisplayString(this.propertyBinding); + } + } + + /** + * @param mouseX + * @param mouseY + * @return + */ + public boolean mouseOver(int mouseX, int mouseY) { + return mouseX > this.xPosition + this.buttonOffset + && mouseX < this.xPosition + this.buttonOffset + this.buttonWidth && mouseY >= this.yPosition + && mouseY <= this.yPosition + this.buttonHeight; + } + + /* + * (non-Javadoc) + * @see com.voxelmodpack.common.properties.VoxelProperty#keyTyped(char, int) + */ + @Override + public void keyTyped(char keyChar, int keyCode) {} +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/gui/GuiVoxelBoxSettingsPanel.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/gui/GuiVoxelBoxSettingsPanel.java new file mode 100644 index 00000000..fffd6fd5 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/gui/GuiVoxelBoxSettingsPanel.java @@ -0,0 +1,303 @@ +package com.voxelmodpack.common.properties.gui; + +import static com.mumfrey.liteloader.gl.GL.*; + +import java.io.IOException; +import java.util.ArrayList; + +import net.minecraft.client.Minecraft; + +import org.lwjgl.input.Keyboard; + +import com.mumfrey.liteloader.modconfig.ConfigPanel; +import com.mumfrey.liteloader.modconfig.ConfigPanelHost; +import com.voxelmodpack.common.LiteModVoxelCommon; +import com.voxelmodpack.common.gui.GuiScreenEx; +import com.voxelmodpack.common.properties.ModConfig; +import com.voxelmodpack.common.properties.VoxelProperty; + +/** + * Base class for voxelmod gui config screens + * + * @author Adam Mummery-Smith + */ +public abstract class GuiVoxelBoxSettingsPanel extends GuiScreenEx implements ConfigPanel { + /** + * Mod config + */ + protected ModConfig config; + + /** + * Property widgets to display + */ + protected ArrayList> properties = new ArrayList>(); + + /** + * Shared panel width, calculated from the width of the tabs + */ + protected static int PANEL_WIDTH = 330; + + /** + * Panel left edge position + */ + protected static int PANEL_LEFT = 97; + + /** + * Panel top edge position + */ + protected static int PANEL_TOP = 0; + + /** + * + */ + protected static int PANEL_HEIGHT = 220; + + /** + * Pixel spacing between tabs + */ + protected static int TAB_SPACING = 2; + + protected boolean overCloseButton = false; + + protected SettingsPanelManager panelManager = SettingsPanelManager.getInstance(); + + protected boolean isPanel = false; + + protected int contentHeight = 240; + + public ModConfig getConfig() { + return this.config; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + super.drawScreen(mouseX, mouseY, partialTicks); + + this.setTexMapSize(256); + + glColor4f(1.0F, 1.0F, 1.0F, 0.5F); + glEnableBlend(); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + int right = PANEL_LEFT + PANEL_WIDTH; + int bottom = PANEL_TOP + PANEL_HEIGHT; + + this.zLevel = -50; + this.drawTabs(mouseX, mouseY, partialTicks, true); + this.drawPanel(right, bottom); + this.drawTabs(mouseX, mouseY, partialTicks, false); + this.zLevel = 0; + + this.drawCloseButton(mouseX, mouseY, right - 4, PANEL_TOP + 20); + for (VoxelProperty property : this.properties) { + if (property.isVisible()) { + property.draw(this, mouseX, mouseY); + } + } + } + + /** + * @param right + * @param bottom + */ + protected void drawPanel(int right, int bottom) { + PANEL_HEIGHT = Math.max(220, this.height - PANEL_TOP - 2); + + this.zLevel = -100; + glEnableDepthTest(); + + this.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, PANEL_LEFT, PANEL_TOP, right, bottom, 0, + 16, 16, 32, 4); + + this.zDrop(); + this.drawDepthRect(PANEL_LEFT + 1, PANEL_TOP + 1, right - 1, bottom - 1, 0x80000000); + + glDisableDepthTest(); + } + + /** + * @param mouseX + * @param mouseY + * @param partialTicks + */ + protected void drawTabs(int mouseX, int mouseY, float partialTicks, boolean mask) { + this.zDrop(); + + this.panelManager.renderTabs(this, mouseX, mouseY, partialTicks, PANEL_LEFT, PANEL_TOP, TAB_SPACING, mask); + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int button) throws IOException { + if (this.overCloseButton) // mouseIn(mouseX, mouseY, 315, 5, 330, 20)) + { + this.onClosed(); + this.mc.displayGuiScreen(null); + return; + } + + if (!this.panelManager.mouseClicked(this, mouseX, mouseY, button, PANEL_LEFT, PANEL_TOP, TAB_SPACING)) { + super.mouseClicked(mouseX, mouseY, button); + + for (VoxelProperty property : this.properties) { + if (property.isVisible()) { + property.mouseClicked(mouseX, mouseY); + } + } + } + } + + protected void onClosed() { + for (VoxelProperty property : this.properties) { + property.onClosed(); + } + } + + @Override + protected void keyTyped(char keyChar, int keyCode) throws IOException { + super.keyTyped(keyChar, keyCode); + + this.keyPressed(null, keyChar, keyCode); + } + + @Override + public void updateScreen() { + super.updateScreen(); + + for (VoxelProperty property : this.properties) { + property.updateCursorCounter(); + } + } + + /** + * @return + */ + public void zDrop() { + this.zLevel--; + } + + protected boolean mouseIn(int mouseX, int mouseY, int x, int y, int x2, int y2) { + return (mouseX > x && mouseX < x2 && mouseY > y && mouseY < y2); + } + + /** + * @param mouseX + * @param mouseY + * @param right + * @param top + */ + protected void drawCloseButton(int mouseX, int mouseY, int right, int top) { + this.overCloseButton = this.mouseIn(mouseX, mouseY, right - 15, top - 16, right, top - 1); + int v = this.overCloseButton ? 32 : 0; + + this.drawDepthRect(right - 1, top - 2, right - 14, top - 15, 0x80000000); + this.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, + this.overCloseButton ? right - 16 : right - 15, this.overCloseButton ? top - 17 : top - 16, + this.overCloseButton ? right + 1 : right, this.overCloseButton ? top : top - 1, 0, v, 16, 16 + v, 4); + this.drawString(this.mc.fontRendererObj, "x", right - 10, top - 13, this.overCloseButton ? 0x55FFFF : 0xAAAAAA); + } + + @Override + public int getContentHeight() { + return this.contentHeight; + } + + @Override + public void onPanelShown(ConfigPanelHost host) { + this.mc = Minecraft.getMinecraft(); + this.isPanel = true; + this.initGui(); + } + + @Override + public void onPanelResize(ConfigPanelHost host) { + this.initGui(); + } + + @Override + public void onPanelHidden() {} + + @Override + public void onTick(ConfigPanelHost host) { + this.updateScreen(); + } + + @Override + public void drawPanel(ConfigPanelHost host, int mouseX, int mouseY, float partialTicks) { + glTranslatef(-PANEL_LEFT, 0.0F, 0.0F); + + for (VoxelProperty property : this.properties) { + if (property.isVisible()) { + property.draw(this, mouseX + PANEL_LEFT, mouseY); + } + } + } + + @Override + public void mousePressed(ConfigPanelHost host, int mouseX, int mouseY, int mouseButton) { + try { + super.mouseClicked(mouseX + PANEL_LEFT, mouseY, mouseButton); + } catch (IOException ex) {} + + for (VoxelProperty property : this.properties) { + if (property.isVisible()) { + property.mouseClicked(mouseX + PANEL_LEFT, mouseY); + } + } + } + + @Override + public void mouseReleased(ConfigPanelHost host, int mouseX, int mouseY, int mouseButton) { + super.mouseClickMove(mouseX + PANEL_LEFT, mouseY, mouseButton, 0L); + } + + @Override + public void mouseMoved(ConfigPanelHost host, int mouseX, int mouseY) { + super.mouseClickMove(mouseX + PANEL_LEFT, mouseY, -1, 0L); + } + + @Override + public void keyPressed(ConfigPanelHost host, char keyChar, int keyCode) { + if (keyCode == Keyboard.KEY_ESCAPE && host != null) { + host.close(); + return; + } + + if (keyCode == Keyboard.KEY_TAB) { + VoxelProperty focused = null; // focused property + VoxelProperty next = null; // next focusable property AFTER the + // focused property + VoxelProperty before = null; // first focusable property BEFORE + // the focused property + + // Search through properties to find focus chain + for (VoxelProperty property : this.properties) { + if (property.isFocusable() && next == null) + next = property; + if (property.isFocused() && focused == null) { + focused = property; + before = next; + next = null; + } + } + + // If didn't find a focusable property after focused in the chain, + // use the one nearest the start + if (next == null) + next = before; + + // If we ARE focused and have a focusable property to switch to, + // then switch + if (focused != null && next != null && next != focused) { + focused.setFocused(false); + next.setFocused(true); + return; + } + } + + for (VoxelProperty property : this.properties) { + if (property.isVisible()) { + property.keyTyped(keyChar, keyCode); + } + } + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/gui/SettingsPanelManager.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/gui/SettingsPanelManager.java new file mode 100644 index 00000000..e03ccbe9 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/gui/SettingsPanelManager.java @@ -0,0 +1,317 @@ +package com.voxelmodpack.common.properties.gui; + +import static com.mumfrey.liteloader.gl.GL.*; + +import java.io.File; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; +import java.util.TreeSet; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.settings.KeyBinding; + +import org.lwjgl.input.Keyboard; + +import com.mumfrey.liteloader.Tickable; +import com.mumfrey.liteloader.core.LiteLoader; + +/** + * Manager object that keeps track of the settings panels and manages the tab + * display and switching between panels + * + * @author Adam Mummery-Smith + */ +public class SettingsPanelManager implements Tickable { + // Consts + private static int TAB_WIDTH = 72; + private static final int TAB_HEIGHT = 16; + + /** + * Singleton + */ + private static SettingsPanelManager instance; + + /** + * Minecraft game instance + */ + private Minecraft mc; + + /** + * Settings panels + */ + private Map> panels = new TreeMap>(); + + /** + * Sorted tabs + */ + private TreeSet tabs = new TreeSet(); + + /** + * Scroll bar to display when there are too many tabs + */ + private SettingsPanelScrollBar scrollbar = new SettingsPanelScrollBar(6, 4, 10, 220, 0); + + /** + * First panel which was added, this becomes the default panel + */ + private Class firstPanel = null; + + /** + * Key binding used to display the GUI + */ + public static KeyBinding guiKeyBinding = new KeyBinding("VoxelMods Config", Keyboard.KEY_NONE, "VoxelLib"); + + /** + * Get the singleton instance of the tab manager + * + * @return + */ + public static SettingsPanelManager getInstance() { + if (instance == null) { + instance = new SettingsPanelManager(); + LiteLoader.getInterfaceManager().registerListener(instance); + LiteLoader.getInput().registerKeyBinding(guiKeyBinding); + } + + return instance; + } + + /** + * Private ctor + */ + private SettingsPanelManager() { + this.mc = Minecraft.getMinecraft(); + } + + /** + * Add a settings panel to the tab list + * + * @param panelName + * @param panel + */ + public static void addSettingsPanel(String panelName, Class panel) { + SettingsPanelManager.getInstance().addPanel(panelName, panel); + } + + /** + * Remove a settings panel from the tab list + * + * @param panelName + */ + public static void removeSettingsPanel(String panelName) { + SettingsPanelManager.getInstance().removePanel(panelName); + } + + public static void displaySettings() { + SettingsPanelManager.getInstance().displaySettings(Minecraft.getMinecraft()); + } + + public static boolean hasOptions() { + return SettingsPanelManager.getInstance().panels.size() > 0; + } + + /** + * Add a settings panel to the panel pool + * + * @param panelName + * @param panel + */ + public void addPanel(String panelName, Class panel) { + // Add the panel to the pool + if (panel != null) { + this.panels.put(panelName, panel); + this.tabs.add(new SettingsPanelMenuTab(panelName, GuiVoxelBoxSettingsPanel.PANEL_LEFT, 0)); + } + + this.updateTabs(); + } + + public void addPanel(String panelName, Class panel, int priority) { + // Add the panel to the pool + if (panel != null) { + this.panels.put(panelName, panel); + this.tabs.add(new SettingsPanelMenuTab(panelName, 62, priority)); + } + + this.updateTabs(); + } + + /** + * Remove a settings panel from the tabs set + * + * @param panelName + */ + public void removePanel(String panelName) { + this.panels.remove(panelName); + this.updateTabs(); + } + + /** + * + */ + protected void updateTabs() { + + Iterator iter = this.panels.keySet().iterator(); + if (iter.hasNext()) + this.firstPanel = this.panels.get(iter.next()); + + int largest = 0; + + for (SettingsPanelMenuTab tab : this.tabs) + if (this.mc.fontRendererObj.getStringWidth(tab.getLabel()) > largest) + largest = this.mc.fontRendererObj.getStringWidth(tab.getLabel()); + + if (SettingsPanelManager.TAB_HEIGHT * this.tabs.size() < GuiVoxelBoxSettingsPanel.PANEL_HEIGHT) + SettingsPanelManager.TAB_WIDTH = largest + 6; + else + SettingsPanelManager.TAB_WIDTH = largest + 18 + this.scrollbar.getWidth(); + + for (SettingsPanelMenuTab tab : this.tabs) + tab.setXPos(SettingsPanelManager.TAB_WIDTH); + + GuiVoxelBoxSettingsPanel.PANEL_LEFT = SettingsPanelManager.TAB_WIDTH; + } + + /* + * (non-Javadoc) + * @see com.mumfrey.liteloader.Tickable#onTick(net.minecraft.src.Minecraft, + * float, boolean, boolean) + */ + @Override + public void onTick(Minecraft minecraft, float partialTicks, boolean inGame, boolean clock) { + // Handle GUI key being pressed + if (minecraft.currentScreen == null && guiKeyBinding.isKeyDown() && this.firstPanel != null) { + this.displaySettings(minecraft); + } + } + + /** + * @param minecraft + */ + public void displaySettings(Minecraft minecraft) { + try { + // If it was pressed display the default panel + GuiVoxelBoxSettingsPanel panel = this.firstPanel.newInstance(); + minecraft.displayGuiScreen(panel); + } catch (InstantiationException ex) {} catch (IllegalAccessException ex) {} + } + + /** + * Callback from the panel, checks whether a tab was clicked, returns true + * if a tab click was handled + * + * @param panel Source panel + * @param mouseX + * @param mouseY + * @param button + * @param xPos tab x pos + * @param yPos tab y pos + * @param spacing tab spacing + * @return + */ + public boolean mouseClicked(GuiVoxelBoxSettingsPanel panel, int mouseX, int mouseY, int button, int xPos, int yPos, + int spacing) { + if (button == 0) { + + int newWidth = SettingsPanelManager.TAB_WIDTH; + + if (SettingsPanelManager.TAB_HEIGHT * this.tabs.size() > GuiVoxelBoxSettingsPanel.PANEL_HEIGHT) + newWidth -= 18 + this.scrollbar.getWidth(); + + for (SettingsPanelMenuTab tab : this.tabs) + if (tab.isMouseOver(newWidth, mouseX, mouseY)) { + try { + GuiVoxelBoxSettingsPanel newPanel = this.panels.get(tab.getLabel()).newInstance(); + this.mc.displayGuiScreen(newPanel); + return true; + + } catch (InstantiationException e) {} catch (IllegalAccessException e) {} + } + + boolean intersects = this.scrollbar.mouseIn(mouseX, mouseY); + + if (intersects) { + this.scrollbar.mouseHeld = true; + return true; + } + + this.scrollbar.mouseHeld = false; + return false; + } + return false; + } + + /** + * Callback from the panel, renders the tabs + * + * @param panel + * @param mouseX + * @param mouseY + * @param partialTicks + * @param xPos + * @param tabYPosition + * @param spacing + */ + public void renderTabs(GuiVoxelBoxSettingsPanel panel, int mouseX, int mouseY, float partialTicks, int xPos, + int yPos, int spacing, boolean mask) { + int tabYPosition = yPos; + + glEnableDepthTest(); + + this.updateTabs(); + + int newWidth = SettingsPanelManager.TAB_WIDTH; + int newY = 0; + + if (TAB_HEIGHT * this.tabs.size() > GuiVoxelBoxSettingsPanel.PANEL_HEIGHT) { + newWidth -= 12 + this.scrollbar.getWidth(); + newY = (int) (TAB_HEIGHT * this.tabs.size() * this.scrollbar.getValue()); + } + + tabYPosition += 8; + tabYPosition -= newY; + + for (SettingsPanelMenuTab tab : this.tabs) { + tab.setActive(panel.getClass().equals(this.panels.get(tab.getLabel()))); + tab.renderTab(panel, newWidth, mouseX, mouseY, tabYPosition, mask); + + tabYPosition += TAB_HEIGHT; + } + + if (TAB_HEIGHT * this.tabs.size() > GuiVoxelBoxSettingsPanel.PANEL_HEIGHT) { + this.scrollbar.setHeight(GuiVoxelBoxSettingsPanel.PANEL_HEIGHT - 8); + this.scrollbar.render(panel, mouseY); + } + + glDisableDepthTest(); + } + + /* + * (non-Javadoc) + * @see com.mumfrey.liteloader.LiteMod#init() + */ + @Override + public void init(File f) {} + + /* + * (non-Javadoc) + * @see com.mumfrey.liteloader.LiteMod#getName() + */ + @Override + public String getName() { + return null; + } + + /* + * (non-Javadoc) + * @see com.mumfrey.liteloader.LiteMod#getVersion() + */ + @Override + public String getVersion() { + return null; + } + + @Override + public void upgradeSettings(String version, File configPath, File oldConfigPath) {} +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/gui/SettingsPanelMenuTab.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/gui/SettingsPanelMenuTab.java new file mode 100644 index 00000000..da48dba3 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/gui/SettingsPanelMenuTab.java @@ -0,0 +1,94 @@ +package com.voxelmodpack.common.properties.gui; + +import net.minecraft.client.Minecraft; + +import com.voxelmodpack.common.LiteModVoxelCommon; + +/** + * @author anangrybeaver + */ +public class SettingsPanelMenuTab implements Comparable { + private Minecraft mc; + + private final int priority; + private final int width; + + private int xPos; + private int yPos; + + private final String label; + + private boolean active = false; + + public SettingsPanelMenuTab(String label, int xPosition, int priority) { + this.mc = Minecraft.getMinecraft(); + + this.label = label; + this.priority = priority; + this.width = this.mc.fontRendererObj.getStringWidth(label); + this.xPos = xPosition - this.width - 2; + } + + public boolean isActive() { + return this.active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public void setXPos(int xPos) { + this.xPos = xPos - this.width - 3; + } + + public boolean isMouseOver(int tabMenuWidth, int mouseX, int mouseY) { + int newX = GuiVoxelBoxSettingsPanel.PANEL_LEFT - tabMenuWidth; + + return mouseX > newX && mouseX < newX + tabMenuWidth && mouseY > this.yPos - 4 && mouseY < this.yPos + 12; + } + + public String getLabel() { + return this.label; + } + + public void renderTab(GuiVoxelBoxSettingsPanel panel, int tabMenuWidth, int mouseX, int mouseY, int y, + boolean mask) { + this.yPos = y; + + int tabX = GuiVoxelBoxSettingsPanel.PANEL_LEFT - tabMenuWidth; + int tabY = this.yPos - 4; + int tabRight = GuiVoxelBoxSettingsPanel.PANEL_LEFT + 4; + int tabBottom = this.yPos + 12; + + if (mask) { + // Draw the tab mask over the window border so it looks like this + // tab "flows" into the window + if (this.active) { + this.renderTabMask(panel, tabY, tabRight, tabBottom); + } + } else { + // Draw the actual tab + boolean mouseOver = this.isMouseOver(tabMenuWidth, mouseX, mouseY); + int v = mouseOver ? 32 : (this.active ? 16 : 0); + panel.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, tabX, tabY, tabRight, tabBottom, 0, + 0 + v, 16, 16 + v, 4); + panel.zDrop(); + panel.drawDepthRect(tabX + 1, tabY + 1, tabRight - 1, tabBottom - 1, 0x80000000); + + this.mc.fontRendererObj.drawString(this.label, this.xPos, y, + this.isMouseOver(tabMenuWidth, mouseX, mouseY) ? 0x55FFFF : (this.active ? 0xFFFF55 : 0xAAAAAA)); + } + } + + private void renderTabMask(GuiVoxelBoxSettingsPanel panel, int tabY, int tabRight, int tabBottom) { + panel.drawDepthRect(tabRight - 4, tabY + 1, tabRight - 3, tabBottom - 1, 0x80000000); + panel.drawDepthRect(tabRight - 3, tabY, tabRight - 2, tabBottom, 0x80000000); + } + + @Override + public int compareTo(SettingsPanelMenuTab other) { + if (other == null) + return 0; + return (this.priority == other.priority) ? -1 : this.priority - other.priority; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/gui/SettingsPanelScrollBar.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/gui/SettingsPanelScrollBar.java new file mode 100644 index 00000000..e368e26b --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/gui/SettingsPanelScrollBar.java @@ -0,0 +1,89 @@ +package com.voxelmodpack.common.properties.gui; + +import static com.mumfrey.liteloader.gl.GL.*; + +import org.lwjgl.input.Mouse; + +import com.voxelmodpack.common.LiteModVoxelCommon; + +/** + * @author anangrybeaver + */ +public class SettingsPanelScrollBar { + public boolean mouseHeld = false; + + private final int xPos, yPos; + private final int width; + private int height; + + private int handleY; + + public SettingsPanelScrollBar(int x, int y, int width, int height, int startingValue) { + this.xPos = x; + this.yPos = y; + + this.width = width; + this.height = height; + + this.moveHandle(startingValue); + } + + @SuppressWarnings("cast") + public double getValue() { + return ((double) this.handleY - (double) this.yPos - 3) / (double) this.height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return this.width; + } + + public void moveHandle(int mouseY) { + this.handleY = mouseY - this.width / 2; + + if (this.handleY < this.yPos + 3) + this.handleY = this.yPos + 3; + + if (this.handleY > this.yPos + this.height - this.width - 3) + this.handleY = this.yPos + this.height - this.width - 3; + } + + public boolean mouseIn(int mouseX, int mouseY) { + return mouseX > this.xPos && mouseX < this.xPos + this.width && mouseY > this.yPos + && mouseY < this.yPos + this.height; + } + + private void renderHandle(GuiVoxelBoxSettingsPanel panel) { + panel.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, this.xPos - 2, this.handleY - 1, + this.xPos + this.width + 2, this.handleY + this.width + 1, 17, 33, 31, 47, 3); + panel.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, this.xPos - 2, this.handleY, + this.xPos + this.width + 2, this.handleY + this.width, 0, 121, 128, 128, 3); + } + + private void renderBar(GuiVoxelBoxSettingsPanel panel) { + glEnableDepthTest(); + + panel.drawTessellatedModalBorderRect(LiteModVoxelCommon.GUIPARTS, 256, this.xPos, this.yPos, + this.xPos + this.width, this.yPos + this.height, 0, 16, 16, 32, 4); + panel.zDrop(); + panel.drawDepthRect(this.xPos + 1, this.yPos + 1, this.xPos + this.width - 1, this.yPos + this.height - 1, + 0x80000000); + + glDisableDepthTest(); + + } + + public void render(GuiVoxelBoxSettingsPanel panel, int mouseY) { + if (Mouse.isButtonDown(0)) { + if (this.mouseHeld) + this.moveHandle(mouseY); + } else + this.mouseHeld = false; + + this.renderBar(panel); + this.renderHandle(panel); + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/interfaces/IVoxelPropertyProvider.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/interfaces/IVoxelPropertyProvider.java new file mode 100644 index 00000000..1ae8fee0 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/interfaces/IVoxelPropertyProvider.java @@ -0,0 +1,39 @@ +package com.voxelmodpack.common.properties.interfaces; + +/** + * Base interface for property providers + * + * @author Adam Mummery-Smith + */ +public interface IVoxelPropertyProvider { + /** + * Get the value of a property as a string + * + * @param propertyName + * @return + */ + public abstract String getStringProperty(String propertyName); + + /** + * Get the name of this property for display + * + * @param propertyName + * @return + */ + public abstract String getOptionDisplayString(String propertyName); + + /** + * Toggle the value of this option + * + * @param propertyName + */ + public abstract void toggleOption(String propertyName); + + /** + * Get the default value of the property as a string + * + * @param propertyName + * @return + */ + public abstract String getDefaultPropertyValue(String propertyName); +} \ No newline at end of file diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/interfaces/IVoxelPropertyProviderBoolean.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/interfaces/IVoxelPropertyProviderBoolean.java new file mode 100644 index 00000000..fcb9da13 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/interfaces/IVoxelPropertyProviderBoolean.java @@ -0,0 +1,25 @@ +package com.voxelmodpack.common.properties.interfaces; + +/** + * Interface for property providers that can provide boolean values + * + * @author Adam Mummery-Smith + */ +public interface IVoxelPropertyProviderBoolean extends IVoxelPropertyProvider { + /** + * Set the specified property to the boolean value specified + * + * @param propertyName + * @param value + */ + public abstract void setProperty(String propertyName, boolean value); + + /** + * Attempts to parse the value of the property specified by calling + * Boolean.parseBoolean on the underlying string value + * + * @param propertyName + * @return + */ + public abstract boolean getBoolProperty(String propertyName); +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/interfaces/IVoxelPropertyProviderFloat.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/interfaces/IVoxelPropertyProviderFloat.java new file mode 100644 index 00000000..27976465 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/interfaces/IVoxelPropertyProviderFloat.java @@ -0,0 +1,25 @@ +package com.voxelmodpack.common.properties.interfaces; + +/** + * Interface for property providers that can provide storage for float values + * + * @author Adam Mummery-Smith + */ +public interface IVoxelPropertyProviderFloat extends IVoxelPropertyProvider { + /** + * Set the specified property to the value specified + * + * @param propertyName + * @param value + */ + public abstract void setProperty(String propertyName, float value); + + /** + * Attempts to retrieve the specified value as a float by calling + * Float.parseFloat on the underlying string value + * + * @param propertyName + * @return + */ + public abstract float getFloatProperty(String propertyName); +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/properties/interfaces/IVoxelPropertyProviderInteger.java b/voxellib/src/main/java/com/voxelmodpack/common/properties/interfaces/IVoxelPropertyProviderInteger.java new file mode 100644 index 00000000..db7f50d3 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/properties/interfaces/IVoxelPropertyProviderInteger.java @@ -0,0 +1,25 @@ +package com.voxelmodpack.common.properties.interfaces; + +/** + * Interface for property providers that can provide storage for integer values + * + * @author Adam Mummery-Smith + */ +public interface IVoxelPropertyProviderInteger extends IVoxelPropertyProvider { + /** + * Set the specified property to the integer value specified + * + * @param propertyName + * @param value + */ + public abstract void setProperty(String propertyName, int value); + + /** + * Attempts to return the specified property as an integer by calling + * Integer.parseInt on the underlying string value + * + * @param propertyName + * @return + */ + public abstract int getIntProperty(String propertyName); +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/runtime/ObfMap.java b/voxellib/src/main/java/com/voxelmodpack/common/runtime/ObfMap.java new file mode 100644 index 00000000..67429da6 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/runtime/ObfMap.java @@ -0,0 +1,59 @@ +package com.voxelmodpack.common.runtime; + +import com.mumfrey.liteloader.core.runtime.Obf; + +/** + * Central list of obfuscation mappings used throughout macros, coalesced here + * instead of being spread throughout the different reflection mechanisms + * + * @author Adam Mummery-Smith TODO Obfuscation - updated 1.8 + */ +public class ObfMap extends Obf { + public static final ObfMap currentLocale = new ObfMap("field_135054_a", "a", "i18nLocale"); + public static final ObfMap downloadedImage = new ObfMap("field_110560_d", "l", "bufferedImage"); + public static final ObfMap renderZoom = new ObfMap("field_78503_V", "X", "cameraZoom"); + public static final ObfMap renderOfsetX = new ObfMap("field_78502_W", "Y", "cameraYaw"); + public static final ObfMap renderOfsetY = new ObfMap("field_78509_X", "Z", "cameraPitch"); + public static final ObfMap guiScreenSelectedButton = new ObfMap("field_146290_a", "h", "selectedButton"); + public static final ObfMap worldType = new ObfMap("field_76098_b", "c", "terrainType"); + public static final ObfMap soundSystemThread = new ObfMap("field_148620_e", "e", "sndSystem"); + public static final ObfMap lastClicked = new ObfMap("field_148167_s", "p", "lastClicked"); + public static final ObfMap imageUrl = new ObfMap("field_110562_b", "j", "imageUrl"); + public static final ObfMap imageThread = new ObfMap("field_110561_e", "m", "imageThread"); + public static final ObfMap imageBuffer = new ObfMap("field_110563_c", "k", "imageBuffer"); + public static final ObfMap imageFile = new ObfMap("field_152434_e", "i"); + public static final ObfMap resourceToTextureMap = new ObfMap("field_110585_a", "b", "mapTextureObjects"); + public static final ObfMap optionsBackground = new ObfMap("field_110325_k", "b", "optionsBackground"); + public static final ObfMap rainingStrength = new ObfMap("field_73004_o", "p", "rainingStrength"); + public static final ObfMap thunderingStrength = new ObfMap("field_73017_q", "r", "thunderingStrength"); + public static final ObfMap internetServerList = new ObfMap("field_146804_i", "i", "savedServerList"); + public static final ObfMap serverSelectionList = new ObfMap("field_146803_h", "h", "serverListSelector"); + public static final ObfMap guiResourcePacksParentScreen = new ObfMap("field_146965_f", "f"); + public static final ObfMap abstractResourcePackFile = new ObfMap("field_110597_b", "a", "resourcePackFile"); + public static final ObfMap mcFramebuffer = new ObfMap("field_147124_at", "aB", "framebufferMc"); + public static final ObfMap eventSounds = new ObfMap("field_148736_a", "a", "soundPool"); + + public static final ObfMap getSlotAtPosition = new ObfMap("func_146975_c", "c", "getSlotAtPosition"); + public static final ObfMap handleMouseClick = new ObfMap("func_146984_a", "a", "handleMouseClick"); + public static final ObfMap selectTab = new ObfMap("func_147050_b", "b", "setCurrentCreativeTab"); + public static final ObfMap scrollTo = new ObfMap("func_148329_a", "a", "scrollTo"); + public static final ObfMap renderSkyBox = new ObfMap("func_73971_c", "c", "renderSkybox"); + public static final ObfMap guiScreenMouseClicked = new ObfMap("func_73864_a", "a", "mouseClicked"); + public static final ObfMap guiScreenMouseMovedOrUp = new ObfMap("func_146286_b", "b", "mouseReleased"); + public static final ObfMap guiScreenKeyTyped = new ObfMap("func_73869_a", "a", "keyTyped"); + public static final ObfMap createPlayer = new ObfMap("func_178892_a", "a"); + + public static final ObfMap ContainerCreative = new ObfMap("net.minecraft.client.gui.inventory.GuiContainerCreative$ContainerCreative", "bza"); + public static final ObfMap SlotCreativeInventory = new ObfMap("net.minecraft.client.gui.inventory.GuiContainerCreative$CreativeSlot", "bzb"); + public static final ObfMap PlayerControllerMP = new ObfMap("net.minecraft.client.multiplayer.PlayerControllerMP", "cem"); + public static final ObfMap StatFileWriter = new ObfMap("net.minecraft.stats.StatFileWriter", "tz"); + public static final ObfMap World = new ObfMap("net.minecraft.world.World", "aqu"); + + private ObfMap(String seargeName, String obfuscatedName, String mcpName) { + super(seargeName, obfuscatedName, mcpName); + } + + private ObfMap(String seargeName, String obfuscatedName) { + super(seargeName, obfuscatedName, seargeName); + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/runtime/PrivateClasses.java b/voxellib/src/main/java/com/voxelmodpack/common/runtime/PrivateClasses.java new file mode 100644 index 00000000..af555dae --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/runtime/PrivateClasses.java @@ -0,0 +1,47 @@ +package com.voxelmodpack.common.runtime; + +import com.mumfrey.liteloader.core.runtime.Obf; +import com.mumfrey.liteloader.util.ModUtilities; + +import net.minecraft.inventory.Container; +import net.minecraft.inventory.Slot; + +/** + * Wrapper for obf/mcp reflection-accessed private (or default) classes, added + * to centralise the locations I have to update the obfuscated names and also + * make referencing the hidden classes more straightforward + * + * @author Adam Mummery-Smith + * @param Parent class type + */ +public class PrivateClasses { + /** + * Class to which this field belongs + */ + public final Class Class; + + /** + * Name used to access the field, determined at init + */ + private final String className; + + @SuppressWarnings({ "unchecked", "deprecation" }) + private PrivateClasses(Obf mapping) { + this.className = ModUtilities.getObfuscatedFieldName(mapping); + + Class reflectedClass = null; + + try { + reflectedClass = (Class) java.lang.Class.forName(this.className); + } catch (Exception ex) { + ex.printStackTrace(); + } + + this.Class = reflectedClass; + } + + public static final PrivateClasses SlotCreativeInventory = new PrivateClasses( + ObfMap.SlotCreativeInventory); + public static final PrivateClasses ContainerCreative = new PrivateClasses( + ObfMap.ContainerCreative); +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/runtime/PrivateFields.java b/voxellib/src/main/java/com/voxelmodpack/common/runtime/PrivateFields.java new file mode 100644 index 00000000..765815e3 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/runtime/PrivateFields.java @@ -0,0 +1,186 @@ +package com.voxelmodpack.common.runtime; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.util.List; +import java.util.Map; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.ISoundEventAccessor; +import net.minecraft.client.audio.SoundEventAccessorComposite; +import net.minecraft.client.audio.SoundManager; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiMultiplayer; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.GuiScreenResourcePacks; +import net.minecraft.client.gui.GuiSlot; +import net.minecraft.client.gui.ServerSelectionList; +import net.minecraft.client.multiplayer.ServerList; +import net.minecraft.client.renderer.EntityRenderer; +import net.minecraft.client.renderer.IImageBuffer; +import net.minecraft.client.renderer.ThreadDownloadImageData; +import net.minecraft.client.renderer.texture.ITextureObject; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.resources.AbstractResourcePack; +import net.minecraft.client.resources.I18n; +import net.minecraft.client.resources.Locale; +import net.minecraft.client.shader.Framebuffer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraft.world.WorldType; +import net.minecraft.world.storage.WorldInfo; +import paulscode.sound.SoundSystem; + +import com.mumfrey.liteloader.core.runtime.Obf; +import com.mumfrey.liteloader.util.ModUtilities; + +/** + * Wrapper for obf/mcp reflection-accessed private fields, mainly added to + * centralise the locations I have to update the obfuscated field names + * + * @author Adam Mummery-Smith + * @param + *

+ * Parent class type, the type of the class that owns the field + * @param Field type, the type of the field value + */ +public class PrivateFields { + /** + * Class to which this field belongs + */ + public final Class

parentClass; + + /** + * Name used to access the field, determined at init + */ + private final String fieldName; + + private boolean errorReported; + + /** + * Creates a new private field entry + * + * @param owner + * @param mcpName + * @param name + */ + @SuppressWarnings("deprecation") + private PrivateFields(Class

owner, Obf mapping) { + this.parentClass = owner; + this.fieldName = ModUtilities.getObfuscatedFieldName(mapping); + } + + /** + * Get the current value of this field on the instance class supplied + * + * @param instance Class to get the value of + * @return field value or null if errors occur + */ + @SuppressWarnings("unchecked") + public T get(P instance) { + try { + return (T) Reflection.getPrivateValue(this.parentClass, instance, this.fieldName); + } catch (Exception ex) { + if (!this.errorReported) { + this.errorReported = true; + ex.printStackTrace(); + } + return null; + } + } + + /** + * Set the value of this field on the instance class supplied + * + * @param instance Object to set the value of the field on + * @param value value to set + * @return value + */ + public T set(P instance, T value) { + try { + Reflection.setPrivateValue(this.parentClass, instance, this.fieldName, value); + } catch (Exception ex) { + if (!this.errorReported) { + this.errorReported = true; + ex.printStackTrace(); + } + } + + return value; + } + + /** + * Static private fields + * + * @param + *

+ * Parent class type, the type of the class that owns the field + * @param Field type, the type of the field value + */ + public static final class StaticFields extends PrivateFields { + @SuppressWarnings("synthetic-access") + public StaticFields(Class

owner, ObfMap mapping) { + super(owner, mapping); + } + + public T get() { + return this.get(null); + } + + public void set(T value) { + this.set(null, value); + } + + public static final StaticFields locale = new StaticFields(I18n.class, + ObfMap.currentLocale); + public static final StaticFields optionsBackground = new StaticFields( + Gui.class, ObfMap.optionsBackground); + } + + // If anyone screws up the formatting of this table again I will have them + // fed to a shark + public static final PrivateFields guiScreenSelectedButton = new PrivateFields( + GuiScreen.class, ObfMap.guiScreenSelectedButton); + public static final PrivateFields worldType = new PrivateFields( + WorldInfo.class, ObfMap.worldType); + public static final PrivateFields soundSystem = new PrivateFields( + SoundManager.class, ObfMap.soundSystemThread); + public static final PrivateFields lastClicked = new PrivateFields(GuiSlot.class, + ObfMap.lastClicked); + public static final PrivateFields renderZoom = new PrivateFields( + EntityRenderer.class, ObfMap.renderZoom); + public static final PrivateFields renderOfsetX = new PrivateFields( + EntityRenderer.class, ObfMap.renderOfsetX); + public static final PrivateFields renderOfsetY = new PrivateFields( + EntityRenderer.class, ObfMap.renderOfsetY); + public static final PrivateFields rainingStrength = new PrivateFields(World.class, + ObfMap.rainingStrength); + public static final PrivateFields thunderingStrength = new PrivateFields(World.class, + ObfMap.thunderingStrength); + public static final PrivateFields downloadedImage = new PrivateFields( + ThreadDownloadImageData.class, ObfMap.downloadedImage); + public static final PrivateFields internetServerList = new PrivateFields( + GuiMultiplayer.class, ObfMap.internetServerList); + public static final PrivateFields serverSelectionList = new PrivateFields( + GuiMultiplayer.class, ObfMap.serverSelectionList); + public static final PrivateFields guiResourcePacksParentScreen = new PrivateFields( + GuiScreenResourcePacks.class, ObfMap.guiResourcePacksParentScreen); + public static final PrivateFields abstractResourcePackFile = new PrivateFields( + AbstractResourcePack.class, ObfMap.abstractResourcePackFile); + public static final PrivateFields mcFramebuffer = new PrivateFields( + Minecraft.class, ObfMap.mcFramebuffer); + public static final PrivateFields imageUrl = new PrivateFields( + ThreadDownloadImageData.class, ObfMap.imageUrl); + public static final PrivateFields imageThread = new PrivateFields( + ThreadDownloadImageData.class, ObfMap.imageThread); + public static final PrivateFields imageBuffer = new PrivateFields( + ThreadDownloadImageData.class, ObfMap.imageBuffer); + public static final PrivateFields imageFile = new PrivateFields( + ThreadDownloadImageData.class, ObfMap.imageFile); + + public static final PrivateFields> eventSounds = new PrivateFields>( + SoundEventAccessorComposite.class, ObfMap.eventSounds); + public static final PrivateFields> resourceToTextureMap = new PrivateFields>( + TextureManager.class, ObfMap.resourceToTextureMap); +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/runtime/PrivateMethods.java b/voxellib/src/main/java/com/voxelmodpack/common/runtime/PrivateMethods.java new file mode 100644 index 00000000..fbaf841f --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/runtime/PrivateMethods.java @@ -0,0 +1,145 @@ +package com.voxelmodpack.common.runtime; + +import java.lang.reflect.Method; + +import net.minecraft.client.gui.GuiMainMenu; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.gui.inventory.GuiContainerCreative; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.Slot; + +import com.mumfrey.liteloader.core.runtime.Obf; +import com.mumfrey.liteloader.util.ModUtilities; + +/** + * Wrapper for obf/mcp reflection-accessed private methods, added to centralise + * the locations I have to update the obfuscated method names + * + * @author Adam Mummery-Smith + * @param + *

+ * Parent class type + * @param Method return type + */ +public class PrivateMethods { + public static class Void {} + + /** + * Class to which this field belongs + */ + public final Class parentClass; + + /** + * Name used to access the field, determined at init + */ + private final String methodName; + + /** + * Method + */ + private final Method method; + + /** + * Creates a new private field entry + * + * @param owner + * @param mcpName + * @param name + */ + @SuppressWarnings("deprecation") + private PrivateMethods(Class owner, Obf mapping, Class... parameterTypes) { + this.parentClass = owner; + this.methodName = ModUtilities.getObfuscatedFieldName(mapping); + + Method method = null; + + try { + method = this.parentClass.getDeclaredMethod(this.methodName, parameterTypes); + method.setAccessible(true); + } catch (SecurityException ex) { + ex.printStackTrace(); + } catch (NoSuchMethodException ex) { + ex.printStackTrace(); + } + + this.method = method; + } + + /** + * Invoke the method and return a value + * + * @param instance + * @param args + * @return + */ + @SuppressWarnings("unchecked") + public R invoke(P instance, Object... args) { + try { + return (R) this.method.invoke(instance, args); + } catch (Exception ex) { + return null; + } + } + + /** + * Invoke a static method that returns a value + * + * @param args + * @return + */ + @SuppressWarnings("unchecked") + public R invokeStatic(Object... args) { + try { + return (R) this.method.invoke(null, args); + } catch (Exception ex) { + return null; + } + } + + /** + * Invoke a method that returns void + * + * @param instance + * @param args + */ + public void invokeVoid(P instance, Object... args) { + try { + this.method.invoke(instance, args); + } catch (Exception ex) {} + } + + /** + * Invoke a static method that returns void + * + * @param args + */ + public void invokeStaticVoid(Object... args) { + try { + this.method.invoke(null, args); + } catch (Exception ex) {} + } + + // Methods on public classes + public static final PrivateMethods containerGetSlotAtPosition = new PrivateMethods( + GuiContainer.class, ObfMap.getSlotAtPosition, int.class, int.class); + public static final PrivateMethods containerHandleMouseClick = new PrivateMethods( + GuiContainer.class, ObfMap.handleMouseClick, Slot.class, int.class, int.class, int.class); + public static final PrivateMethods selectTab = new PrivateMethods( + GuiContainerCreative.class, ObfMap.selectTab, CreativeTabs.class); + public static final PrivateMethods mainMenuRenderSkyBox = new PrivateMethods( + GuiMainMenu.class, ObfMap.renderSkyBox, int.class, int.class, float.class); + + public static final PrivateMethods guiScreenMouseClicked = new PrivateMethods( + GuiScreen.class, ObfMap.guiScreenMouseClicked, int.class, int.class, int.class); + public static final PrivateMethods guiScreenMouseMovedOrUp = new PrivateMethods( + GuiScreen.class, ObfMap.guiScreenMouseMovedOrUp, int.class, int.class, int.class); + public static final PrivateMethods guiScreenKeyTyped = new PrivateMethods( + GuiScreen.class, ObfMap.guiScreenKeyTyped, char.class, int.class); + + // Methods on dynamic classes below here + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static final PrivateMethods scrollTo = new PrivateMethods( + PrivateClasses.ContainerCreative.Class, ObfMap.scrollTo, float.class); +} \ No newline at end of file diff --git a/voxellib/src/main/java/com/voxelmodpack/common/runtime/Reflection.java b/voxellib/src/main/java/com/voxelmodpack/common/runtime/Reflection.java new file mode 100644 index 00000000..6dc0eaf0 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/runtime/Reflection.java @@ -0,0 +1,108 @@ +package com.voxelmodpack.common.runtime; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +import com.mumfrey.liteloader.util.ModUtilities; + +public class Reflection { + private static Field MODIFIERS = null; + + static { + try { + Reflection.MODIFIERS = (java.lang.reflect.Field.class).getDeclaredField("modifiers"); + Reflection.MODIFIERS.setAccessible(true); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + /** + * ModLoader function, set a private value on the specified object + * + * @param instanceClass Class which the member belongs to (may be a + * superclass of the actual instance object's class) + * @param instance Object instance to set the value in + * @param fieldName Name of the field to set + * @param value Value to set for the field + */ + @SuppressWarnings("deprecation") + public static void setPrivateValue(Class instanceClass, Object instance, String fieldName, + String obfuscatedFieldName, String seargeName, Object value) + throws IllegalArgumentException, SecurityException, NoSuchFieldException { + Reflection.setPrivateValueRaw(instanceClass, instance, + ModUtilities.getObfuscatedFieldName(fieldName, obfuscatedFieldName, seargeName), value); + } + + /** + * ModLoader function, set a private value on the specified object + * + * @param instanceClass Class which the member belongs to (may be a + * superclass of the actual instance object's class) + * @param instance Object instance to set the value in + * @param fieldName Name of the field to set + * @param value Value to set for the field + */ + public static void setPrivateValue(Class instanceClass, Object instance, String fieldName, Object value) + throws IllegalArgumentException, SecurityException, NoSuchFieldException { + Reflection.setPrivateValueRaw(instanceClass, instance, fieldName, value); + } + + /** + * ModLoader function, get a private value from the specified object + * + * @param instanceClass Class which the member belongs to (may be a + * superclass of the actual instance object's class) + * @param instance Object instance to get the value from + * @param fieldName Name of the field to get the value of + * @return Value of the field + */ + @SuppressWarnings({ "unchecked", "deprecation" }) + public static T getPrivateValue(Class instanceClass, Object instance, String fieldName, + String obfuscatedFieldName, String seargeName) + throws IllegalArgumentException, SecurityException, NoSuchFieldException { + return (T) Reflection.getPrivateValueRaw(instanceClass, instance, + ModUtilities.getObfuscatedFieldName(fieldName, obfuscatedFieldName, seargeName)); + } + + /** + * ModLoader function, get a private value from the specified object + * + * @param instanceClass Class which the member belongs to (may be a + * superclass of the actual instance object's class) + * @param instance Object instance to get the value from + * @param fieldName Name of the field to get the value of + * @return Value of the field + */ + @SuppressWarnings("unchecked") + public static T getPrivateValue(Class instanceClass, Object instance, String fieldName) + throws IllegalArgumentException, SecurityException, NoSuchFieldException { + return (T) Reflection.getPrivateValueRaw(instanceClass, instance, fieldName); + } + + private static void setPrivateValueRaw(Class instanceClass, Object instance, String fieldName, Object value) + throws IllegalArgumentException, SecurityException, NoSuchFieldException { + try { + Field field = instanceClass.getDeclaredField(fieldName); + int modifiers = Reflection.MODIFIERS.getInt(field); + + if ((modifiers & Modifier.FINAL) != 0) { + Reflection.MODIFIERS.setInt(field, modifiers & 0xffffffef); + } + + field.setAccessible(true); + field.set(instance, value); + } catch (IllegalAccessException illegalaccessexception) {} + } + + public static Object getPrivateValueRaw(Class instanceClass, Object instance, String fieldName) + throws IllegalArgumentException, SecurityException, NoSuchFieldException { + try { + Field field = instanceClass.getDeclaredField(fieldName); + field.setAccessible(true); + return field.get(instance); + } catch (IllegalAccessException illegalaccessexception) { + return null; + } + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/sound/SoundEffect.java b/voxellib/src/main/java/com/voxelmodpack/common/sound/SoundEffect.java new file mode 100644 index 00000000..0b20d7ca --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/sound/SoundEffect.java @@ -0,0 +1,19 @@ +package com.voxelmodpack.common.sound; + +import net.minecraft.client.audio.ISound; +import net.minecraft.client.audio.PositionedSound; +import net.minecraft.util.ResourceLocation; + +public class SoundEffect extends PositionedSound { + public SoundEffect(ResourceLocation soundLocation, float volume, float pitch) { + super(soundLocation); + this.volume = volume; + this.pitch = pitch; + this.xPosF = 0.0F; + this.yPosF = 0.0F; + this.zPosF = 0.0F; + this.repeat = false; + this.repeatDelay = 0; + this.attenuationType = ISound.AttenuationType.NONE; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/status/StatusMessage.java b/voxellib/src/main/java/com/voxelmodpack/common/status/StatusMessage.java new file mode 100644 index 00000000..1064dbc6 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/status/StatusMessage.java @@ -0,0 +1,157 @@ +package com.voxelmodpack.common.status; + +import java.util.Random; + +import net.minecraft.client.gui.FontRenderer; + +/** + * A status message instance, this is returned from the manager to a mod to + * allow the mod to control its own status message display + * + * @author anangrybeaver + */ +public class StatusMessage implements Comparable { + /** + * Message format + */ + private static final String MESSAGE_FORMAT = "\247%s%s\247f: \247%s%s\247r"; + + private static final int MESSAGE_HEIGHT = 10; + + /** + * Colour for the title text + */ + private char titleColour = 'f'; + + /** + * Colour for the status text + */ + private char textColour = 'a'; + + /** + * The label for this particular status message, not displayed + */ + private final String label; + + /** + * Status message title + */ + private String title = ""; + + /** + * Status message text + */ + private String text = ""; + + /** + * Priority, for choosing display order + */ + private int priority = 0; + + /** + * Order the message was added, this is used to order messages which have + * the same priority + */ + private int order = 0; + + /** + * Show this message + */ + private boolean visible = false; + + public StatusMessage(String label) { + this.label = label; + this.order = new Random().nextInt(Integer.MAX_VALUE); + } + + public StatusMessage(String label, int priority, int order) { + this(label); + + this.priority = priority; + this.order = order; + } + + public StatusMessage setTitleAndText(String title, String text) { + this.title = title; + this.text = text; + return this; + } + + public StatusMessage setTitle(String title) { + this.title = title; + return this; + } + + public StatusMessage setText(String text) { + this.text = text; + return this; + } + + public StatusMessage setPriority(int priority) { + this.priority = priority; + return this; + } + + public StatusMessage setVisible(boolean visible) { + this.visible = visible; + return this; + } + + public StatusMessage setTextColour(char textColour) { + this.textColour = textColour; + return this; + } + + public StatusMessage setTitleColour(char titleColour) { + this.titleColour = titleColour; + return this; + } + + public StatusMessage setColours(char textColour, char titleColour) { + this.textColour = textColour; + this.titleColour = titleColour; + return this; + } + + public String getTitle() { + return this.title; + } + + public String getText() { + return this.text; + } + + public String getLabel() { + return this.label; + } + + public int getPriority() { + return this.priority; + } + + public boolean isVisible() { + return this.visible; + } + + public int drawStatus(FontRenderer fontRenderer, int xPos, int yPos) { + if (this.isVisible()) { + fontRenderer.drawStringWithShadow( + String.format(MESSAGE_FORMAT, this.titleColour, this.title, this.textColour, this.text), xPos, yPos, + 0xffffff); + return MESSAGE_HEIGHT; + } + + return 0; + } + + @Override + public int compareTo(StatusMessage other) { + if (other == null) + return 0; + + if (this.priority == other.priority) + return this.order - other.order; + + return this.priority - other.priority; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/status/StatusMessageConfig.java b/voxellib/src/main/java/com/voxelmodpack/common/status/StatusMessageConfig.java new file mode 100644 index 00000000..e67b5370 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/status/StatusMessageConfig.java @@ -0,0 +1,40 @@ +package com.voxelmodpack.common.status; + +import java.io.FileWriter; + +import com.mumfrey.liteloader.util.log.LiteLoaderLogger; +import com.voxelmodpack.common.properties.ModConfig; + +/** + * @author anangrybeaver + */ +public class StatusMessageConfig extends ModConfig { + public StatusMessageConfig() { + super("StatusMessage", "statusmessage.properties"); + } + + @Override + protected void createConfig() { + try { + this.config.setProperty("showStatuses", "true"); + this.config.store(new FileWriter(this.propertiesFile), null); + } catch (Exception e) { + LiteLoaderLogger.warning("%s> ERROR: %s", this.modName, e.toString()); + } + } + + @Override + public String getOptionDisplayString(String optionName) { + return null; + } + + @Override + public void toggleOption(String optionName) { + StatusMessageManager.getInstance().toggleOption(optionName); + } + + @Override + protected void setDefaults() { + this.defaults.setProperty("showStatuses", "true"); + } +} \ No newline at end of file diff --git a/voxellib/src/main/java/com/voxelmodpack/common/status/StatusMessageGUI.java b/voxellib/src/main/java/com/voxelmodpack/common/status/StatusMessageGUI.java new file mode 100644 index 00000000..e07029d4 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/status/StatusMessageGUI.java @@ -0,0 +1,27 @@ +package com.voxelmodpack.common.status; + +import com.voxelmodpack.common.properties.VoxelPropertyCheckBox; +import com.voxelmodpack.common.properties.VoxelPropertyLabel; +import com.voxelmodpack.common.properties.gui.GuiVoxelBoxSettingsPanel; + +/** + * @author anangrybeaver + */ +public class StatusMessageGUI extends GuiVoxelBoxSettingsPanel { + public StatusMessageGUI() { + this.config = StatusMessageManager.getInstance().getConfig(); + + this.properties.add(new VoxelPropertyLabel("Status Settings", PANEL_LEFT + 15, PANEL_TOP + 10)); + this.properties.add(new VoxelPropertyCheckBox(this.config, "showStatuses", "Show Statuses", PANEL_LEFT + 20, + this.getRowYPos(0))); + } + + public int getRowYPos(int row) { + return 26 + (row * 20); + } + + @Override + public String getPanelTitle() { + return "Voxel Status Message"; + } +} \ No newline at end of file diff --git a/voxellib/src/main/java/com/voxelmodpack/common/status/StatusMessageManager.java b/voxellib/src/main/java/com/voxelmodpack/common/status/StatusMessageManager.java new file mode 100644 index 00000000..c8b6e133 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/status/StatusMessageManager.java @@ -0,0 +1,101 @@ +package com.voxelmodpack.common.status; + +import static com.mumfrey.liteloader.gl.GL.*; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeSet; + +import net.minecraft.client.Minecraft; + +import com.mumfrey.liteloader.Tickable; +import com.mumfrey.liteloader.core.LiteLoader; +import com.voxelmodpack.common.properties.ModConfig; +import com.voxelmodpack.common.properties.gui.SettingsPanelManager; + +/** + * @author anangrybeaver + */ +public class StatusMessageManager implements Tickable { + private static StatusMessageManager instance; + + private static int order = 0; + + private Map statusMessages = new HashMap(); + private TreeSet sortedMessage = new TreeSet(); + private StatusMessageConfig config = new StatusMessageConfig(); + + private boolean showStatuses = true; + + @Override + public void init(File configPath) { + this.showStatuses = this.config.getBoolProperty("showStatuses"); + } + + public static StatusMessageManager getInstance() { + if (StatusMessageManager.instance == null) { + StatusMessageManager.instance = new StatusMessageManager(); + LiteLoader.getInterfaceManager().registerListener(StatusMessageManager.instance); + SettingsPanelManager.addSettingsPanel("Status MSG", StatusMessageGUI.class); + } + + return StatusMessageManager.instance; + } + + @Override + public void onTick(Minecraft minecraft, float partialTicks, boolean inGame, boolean clock) { + this.showStatuses = this.config.getBoolProperty("showStatuses"); + + if (minecraft.inGameHasFocus && !minecraft.gameSettings.hideGUI && !minecraft.gameSettings.showDebugInfo + && this.showStatuses) { + int xPos = 2; + int yPos = xPos; + + glDisableBlend(); + glEnableAlphaTest(); + glAlphaFunc(GL_GREATER, 0.1F); + + for (StatusMessage msg : this.sortedMessage) { + yPos += msg.drawStatus(minecraft.fontRendererObj, xPos, yPos); + } + } + } + + public StatusMessage getStatusMessage(String label, int priority) { + if (this.statusMessages.containsKey(label)) + return this.statusMessages.get(label); + + StatusMessage newMessage = new StatusMessage(label, priority, order++); + this.statusMessages.put(label, newMessage); + this.sortedMessage.add(newMessage); + + return newMessage; + } + + public void releaseStatusMessage(StatusMessage message) { + this.sortedMessage.remove(message); + this.statusMessages.remove(message); + } + + public ModConfig getConfig() { + return this.config; + } + + public void toggleOption(String optionName) { + this.config.setProperty(optionName, !this.config.getBoolProperty(optionName)); + } + + @Override + public String getName() { + return null; + } + + @Override + public String getVersion() { + return null; + } + + @Override + public void upgradeSettings(String version, File configPath, File oldConfigPath) {} +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/util/BrowserOpener.java b/voxellib/src/main/java/com/voxelmodpack/common/util/BrowserOpener.java new file mode 100644 index 00000000..0915a4f3 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/util/BrowserOpener.java @@ -0,0 +1,53 @@ +package com.voxelmodpack.common.util; + +import java.awt.Desktop; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + +/** + * Utility for opening the users default file/internet browser + * + * @author thatapplefreak + */ +public abstract class BrowserOpener { + /** + * Open via url + */ + public static void openURLinBrowser(URL url) { + try { + URI uri = url.toURI(); + Desktop.getDesktop().browse(uri); + } catch (URISyntaxException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Open via uri + */ + public static void openURIinBrowser(URI uri) { + try { + Desktop.getDesktop().browse(uri); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Open via string + */ + public static void openURLstringInBrowser(String url) { + try { + URI uri = new URI(url); + Desktop.getDesktop().browse(uri); + } catch (URISyntaxException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/util/ChatMessageBuilder.java b/voxellib/src/main/java/com/voxelmodpack/common/util/ChatMessageBuilder.java new file mode 100644 index 00000000..e289a733 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/util/ChatMessageBuilder.java @@ -0,0 +1,180 @@ +package com.voxelmodpack.common.util; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.event.ClickEvent; +import net.minecraft.event.ClickEvent.Action; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; + +/** + * Utility Class for building a chat message based on StringBuilder + * + * @author thatapplefreak + * @author Gabizou + * @author Mumfrey + */ +public class ChatMessageBuilder { + /** + * The message being built + */ + private final IChatComponent queuedMessage; + + public ChatMessageBuilder() { + this.queuedMessage = new ChatComponentText(""); + } + + /** + * Just add some plain text into the message + * + * @param text Text to add + */ + public ChatMessageBuilder append(String text) { + this.queuedMessage.appendSibling(new ChatComponentText(text)); + return this; + } + + /** + * Append some formatted text to this message + * + * @param format + * @param args + * @return fluent interface + */ + public ChatMessageBuilder append(String format, Object... args) { + this.queuedMessage.appendSibling(new ChatComponentText(String.format(format, args))); + return this; + } + + /** + * Add some coloured text into the message + * + * @param text The text in the message + * @param color The color in the message + */ + public ChatMessageBuilder append(String text, EnumChatFormatting color) { + IChatComponent addmsg = new ChatComponentText(text); + addmsg.getChatStyle().setColor(color); + this.queuedMessage.appendSibling(addmsg); + return this; + } + + /** + * Add some formatted text into the message + * + * @param text The text in the message + * @param color The color in the message + * @param underline Underline the text? + */ + public ChatMessageBuilder append(String text, EnumChatFormatting color, boolean underline) { + IChatComponent addmsg = new ChatComponentText(text); + addmsg.getChatStyle().setColor(color); + addmsg.getChatStyle().setUnderlined(underline); + this.queuedMessage.appendSibling(addmsg); + return this; + } + + /** + * @param comp + * @return + */ + public ChatMessageBuilder append(IChatComponent comp) { + this.queuedMessage.appendSibling(this.queuedMessage); + return this; + } + + /** + * Add a URL link into the message + * + * @param text The Link Text + * @param path The URL + */ + public ChatMessageBuilder append(String text, String path, boolean onAWebsite) { + this.append(text, EnumChatFormatting.WHITE, path, onAWebsite); + return this; + } + + /** + * Add a URL link into the message with color + * + * @param text The Link Text + * @param color Color of the link + * @param path The URL + */ + public ChatMessageBuilder append(String text, EnumChatFormatting color, String path, boolean onAWebsite) { + IChatComponent addmsg = new ChatComponentText(text); + addmsg.getChatStyle().setColor(color); + addmsg.getChatStyle().setUnderlined(true); + addmsg.getChatStyle().setChatClickEvent(new ClickEvent(onAWebsite ? Action.OPEN_URL : Action.OPEN_FILE, path)); + this.queuedMessage.appendSibling(addmsg); + return this; + } + + /** + * Put the message into chat + */ + public void showChatMessageIngame() { + Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(this.queuedMessage); + } + + /** + * Dispatch this message as as a chat packet to the server + * + * @param recipient + */ + public void dispatch(EntityPlayerSP recipient) { + recipient.sendChatMessage(this.getUnformattedText()); + } + + /** + * Dispatch this message to the specified client recipients + * + * @param recipient + */ + public void dispatch(EntityPlayerMP... recipients) { + for (EntityPlayerMP recipient : recipients) { + if (recipient != null) { + recipient.addChatMessage(this.queuedMessage); + } + } + } + + /** + * Get the chat message being built by this builder + */ + public IChatComponent getMessage() { + return this.queuedMessage; + } + + /** + * Get the current unformatted text string represented by this builder + */ + public String getFormattedText() { + return this.queuedMessage.getFormattedText(); + } + + /** + * Get the current unformatted text string represented by this builder + */ + public String getUnformattedText() { + return this.queuedMessage.getUnformattedText(); + } + + /* + * (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return this.getUnformattedText(); + } + + /** + * Get the current chat component as JSON + */ + public String toJson() { + return IChatComponent.Serializer.componentToJson(this.queuedMessage); + } +} \ No newline at end of file diff --git a/voxellib/src/main/java/com/voxelmodpack/common/util/ItemStackInfo.java b/voxellib/src/main/java/com/voxelmodpack/common/util/ItemStackInfo.java new file mode 100644 index 00000000..4aa9ab86 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/util/ItemStackInfo.java @@ -0,0 +1,283 @@ +package com.voxelmodpack.common.util; + +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.item.Item; +import net.minecraft.item.ItemFood; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; + +import com.mumfrey.liteloader.util.render.Icon; +import com.voxelmodpack.common.gui.interfaces.IListObject; + +/** + * Information about an enumerated item, for display in the item list + * + * @author Adam Mummery-Smith + */ +public class ItemStackInfo implements IListObject { + private int index; + + private Icon icon; + + /** + * Item name + */ + private String name, nameWithID; + + private Item item; + + private String itemId; + + private int damageValue; + + private ItemStack stack; + + /** + * Create a new item info + * + * @param id Item ID + * @param texture Item texture + * @param icon Item's icon index + */ + public ItemStackInfo(int index, Icon icon, int damage, ItemStack stack) { + this.index = index; + this.name = stack.getDisplayName(); + this.icon = icon; + this.damageValue = damage; + this.stack = stack; + } + + /** + * + */ + public void updateName() { + this.name = this.stack.getDisplayName(); + this.item = this.stack.getItem(); + this.itemId = ItemStackInfo.getItemIdentifier(this.item); + this.nameWithID = this.name + " " + EnumChatFormatting.LIGHT_PURPLE + this.itemId; + + if (this.damageValue > 0) + this.nameWithID += ":" + this.damageValue; + } + + /** + * True if the item has an icon that can be displayed in list boxes + */ + @Override + public boolean hasIcon() { + return true; + } + + @Override + public Icon getIcon() { + return this.icon; + } + + public String getName(boolean withID) { + return withID ? this.nameWithID : this.name; + } + + public int getDamage() { + return this.damageValue; + } + + public Item getItem() { + return this.item; + } + + public String getItemId() { + return this.itemId; + } + + public ItemStack getItemStack() { + return this.stack; + } + + public boolean compareTo(ItemStackInfo other) { + return (other.name.equalsIgnoreCase(this.name) && other.icon == this.icon); + } + + /** + * Get the display text to show in listboxes + * + * @return display text + */ + @Override + public String getText() { + return this.name; + } + + /** + * Get the display text to show in listboxes + * + * @return display text + */ + public String getSortText() { + String sortText = this.name; + + if (this.stack.getItem() instanceof ItemFood) + sortText += " food"; + if (this.name.toLowerCase().contains("wood")) + sortText += " wood"; + + return sortText; + } + + /** + * Get the item's ID + */ + @Override + public int getID() { + return this.index; + } + + /** + * Get the data associated with the item + */ + @Override + public Object getData() { + return null; + } + + /** + * Return the custom draw behaviour for the item + */ + @Override + public CustomDrawBehaviour getCustomDrawBehaviour() { + return CustomDrawBehaviour.NoCustomDraw; + } + + /** + * Handles custom drawing, this object does not support custom draw + * behaviour + */ + @Override + public void drawCustom(boolean iconEnabled, Minecraft minecraft, int mouseX, int mouseY, int xPosition, + int yPosition, int width, int height, int updateCounter) {} + + /** + * Handle mouse pressed, this object does not support this event + */ + @Override + public boolean mousePressed(boolean iconEnabled, Minecraft minecraft, int mouseX, int mouseY, int xPosition, + int yPosition, int width, int height) { + return false; + } + + /** + * Handle mouse released. + */ + @Override + public void mouseReleased(int mouseX, int mouseY) {} + + /** + * Get custom action. Not supported by this object, always returns an empty + * string. + */ + @Override + public String getCustomAction(boolean bClear) { + return ""; + } + + /** + * Get whether this object is draggable or not + */ + @Override + public boolean getDraggable() { + return false; + } + + @Override + public void setIconTexture(String newTexture) {} + + @Override + public void setIconID(int newIconId) {} + + @Override + public void setText(String newText) { + this.name = newText; + + } + + @Override + public void setID(int newId) {} + + @Override + public void setData(Object newData) {} + + @Override + public boolean getCanEditInPlace() { + return false; + } + + @Override + public boolean getEditingInPlace() { + return false; + } + + @Override + public void beginEditInPlace() {} + + @Override + public void endEditInPlace() {} + + @Override + public boolean editInPlaceKeyTyped(char keyChar, int keyCode) { + return false; + } + + @Override + public void editInPlaceDraw(boolean iconEnabled, Minecraft minecraft, int mouseX, int mouseY, int xPosition, + int yPosition, int width, int height, int updateCounter) {} + + @Override + public boolean editInPlaceMousePressed(boolean iconEnabled, Minecraft minecraft, int mouseX, int mouseY, + int xPosition, int yPosition, int width, int height) { + return false; + } + + @Override + public String serialise() { + return null; + } + + @Override + public void bindIconTexture() {} + + @Override + public int getIconSize() { + return 16; + } + + @Override + public int getIconTexmapSize() { + return 256; + } + + @Override + public String getDisplayName() { + return this.name.toLowerCase(); + } + + @Override + public void setDisplayName(String newDisplayName) {} + + public static String getItemIdentifier(Item item) { + String itemName = (String) Item.itemRegistry.getNameForObject(item); + return itemName == null ? "air" : ItemStackInfo.stripNamespace(itemName); + } + + public static String getBlockIdentifier(Block block) { + String blockName = (String) Block.blockRegistry.getNameForObject(block); + return blockName == null ? "air" : ItemStackInfo.stripNamespace(blockName); + } + + /** + * @param itemName + * @return + */ + private static String stripNamespace(String itemName) { + return itemName.startsWith("minecraft:") ? itemName.substring(10) : itemName; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/util/RenderItemEx.java b/voxellib/src/main/java/com/voxelmodpack/common/util/RenderItemEx.java new file mode 100644 index 00000000..616b0726 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/util/RenderItemEx.java @@ -0,0 +1,51 @@ +package com.voxelmodpack.common.util; + +import static com.mumfrey.liteloader.gl.GL.*; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.item.ItemStack; + +public class RenderItemEx extends RenderItem { + public RenderItemEx() { + super(Minecraft.getMinecraft().getTextureManager(), + Minecraft.getMinecraft().getRenderItem().getItemModelMesher().getModelManager()); + } + + /** + * Render the item's icon or block into the GUI, including the glint effect. + */ + @Override + public void renderItemOverlays(FontRenderer fontRenderer, ItemStack stack, int xPos, int yPos) { + if (stack != null) { + this.drawRect(xPos, yPos, 16, 16, 1, 0, 0, 1); + this.drawRect(xPos + 1, yPos + 1, 14, 14, 0.6F, 0, 0, 1); + super.renderItemOverlays(fontRenderer, stack, xPos, yPos); + } + } + + @SuppressWarnings("cast") + private void drawRect(int x, int y, int width, int height, float r, float g, float b, float a) { + glPushAttrib(GL_ALL_ATTRIB_BITS); + glDisableDepthTest(); + glDepthFunc(GL_GREATER); + glDisableLighting(); + glDepthMask(false); + glEnableBlend(); + glDisableTexture2D(); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(r, g, b, a); + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldRender = tessellator.getWorldRenderer(); + worldRender.startDrawingQuads(); + worldRender.addVertex((double) (x + 0), (double) (y + 0), 0.0D); + worldRender.addVertex((double) (x + 0), (double) (y + height), 0.0D); + worldRender.addVertex((double) (x + width), (double) (y + height), 0.0D); + worldRender.addVertex((double) (x + width), (double) (y + 0), 0.0D); + tessellator.draw(); + glDepthMask(true); + glPopAttrib(); + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/util/Util.java b/voxellib/src/main/java/com/voxelmodpack/common/util/Util.java new file mode 100644 index 00000000..3a725036 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/util/Util.java @@ -0,0 +1,21 @@ +package com.voxelmodpack.common.util; + +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.server.integrated.IntegratedServer; + +/** + * Utility functions + */ +public final class Util { + public static EntityPlayer getPlayerMP() { + Minecraft mc = Minecraft.getMinecraft(); + IntegratedServer server = mc.getIntegratedServer(); + + if (server != null) { + return server.getConfigurationManager().getPlayerByUsername(server.getServerOwner()); + } + + return Minecraft.getMinecraft().thePlayer; + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/xml/XmlHelper.java b/voxellib/src/main/java/com/voxelmodpack/common/xml/XmlHelper.java new file mode 100644 index 00000000..d2f23ed2 --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/xml/XmlHelper.java @@ -0,0 +1,344 @@ +package com.voxelmodpack.common.xml; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.util.ArrayList; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * XML helper functions to make working with XML less of a nuisance + * + * @author Adam Mummery-Smith + */ +public class XmlHelper { + /** + * xpath evaluator + */ + private static XPath xpath; + + /** + * Namespace context helper for resolving namespaces + */ + private static XmlNamespaceContext staticNamespaceContext; + + /** + * Factory for document builders + */ + private static DocumentBuilderFactory documentBuilderFactory; + + /** + * Document builder + */ + private static DocumentBuilder documentBuilder; + + /** + * Factory for transformers (not the big robotic kind, the small boring + * kind) + */ + private static TransformerFactory transformerFactory; + + /** + * Robots in disguise! (Wait, no...) + */ + private static Transformer transformer; + + static { + // XML namespace manager which is used if a context is not specified + XmlHelper.staticNamespaceContext = new XmlNamespaceContext(); + + // Create the xpath evaluator + XmlHelper.xpath = XPathFactory.newInstance().newXPath(); + XmlHelper.xpath.setNamespaceContext(XmlHelper.staticNamespaceContext); + + // Create the document builder factory and enable namespaces + XmlHelper.documentBuilderFactory = DocumentBuilderFactory.newInstance(); + XmlHelper.documentBuilderFactory.setNamespaceAware(true); + XmlHelper.createDocumentBuilder(XmlHelper.documentBuilderFactory); + + // Create the transformer factory + XmlHelper.transformerFactory = TransformerFactory.newInstance(); + XmlHelper.createTransformer(XmlHelper.transformerFactory); + } + + /** + * Attempts to create the document builder if one is not initialised + * already. This may fail in which case the function will return FALSE + * + * @param factory + * @return + */ + protected static boolean createDocumentBuilder(DocumentBuilderFactory factory) { + if (XmlHelper.documentBuilder == null) { + try { + // Create the document builder + XmlHelper.documentBuilder = XmlHelper.documentBuilderFactory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + return false; + } + } + + return true; + } + + /** + * Attempts to create the dom transformer if one is not initialised already. + * This may fail in which case the function will return FALSE + * + * @param factory + * @return + */ + protected static boolean createTransformer(TransformerFactory factory) { + if (XmlHelper.transformer == null) { + try { + XmlHelper.transformer = XmlHelper.transformerFactory.newTransformer(); + } catch (TransformerConfigurationException e) { + return false; + } + + // Set transformer properties for the desired output layout that we + // need for transformation + XmlHelper.transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); + XmlHelper.transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + XmlHelper.transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); + } + + return true; + } + + /** + * Create and return a new, empty document. Returns null if the document + * builder cannot be initialised + * + * @return new document + */ + public static Document newDocument() { + return (XmlHelper.createDocumentBuilder(XmlHelper.documentBuilderFactory)) + ? XmlHelper.documentBuilder.newDocument() : null; + } + + /** + * Loads a document from the specified URI. Returns null if the document + * builder cannot be initialised + * + * @param uri URI to load the xml from + * @return new document + */ + public static Document getDocument(String uri) throws SAXException, IOException { + return (XmlHelper.createDocumentBuilder(XmlHelper.documentBuilderFactory)) + ? XmlHelper.documentBuilder.parse(uri) : null; + } + + /** + * Loads a document from the specified URI. Returns null if the document + * builder cannot be initialised + * + * @param is InputStream to load the xml from + * @return new document + */ + public static Document getDocument(InputStream is) throws SAXException, IOException { + return (XmlHelper.createDocumentBuilder(XmlHelper.documentBuilderFactory)) ? XmlHelper.documentBuilder.parse(is) + : null; + } + + /** + * Loads a document from the specified file. Returns null if the document + * builder cannot be initialised + * + * @param file File to load from + * @return new document + */ + public static Document getDocument(File file) throws SAXException, IOException { + return (XmlHelper.createDocumentBuilder(XmlHelper.documentBuilderFactory)) + ? XmlHelper.documentBuilder.parse(file) : null; + } + + /** + * Attempts to save the specified document to the specified file + * + * @param file File to save to + * @param document DOM Document to save + * @return True if the file was saved successfully, false if saving the file + * failed + */ + public static boolean saveDocument(File file, Document document) { + if (XmlHelper.createTransformer(XmlHelper.transformerFactory)) { + try { + XmlHelper.transformer.transform(new DOMSource(document), new StreamResult(file)); + return true; + } catch (TransformerException e) {} + } + + return false; + } + + /** + * @param document + * @return + */ + public static String getDocumentContent(Document document) { + if (XmlHelper.createTransformer(XmlHelper.transformerFactory)) { + try { + StringWriter writer = new StringWriter(); + XmlHelper.transformer.transform(new DOMSource(document), new StreamResult(writer)); + writer.flush(); + return writer.getBuffer().toString(); + } catch (TransformerException e) {} + } + + return null; + } + + /** + * Add a namespace prefix to the current static namespace manager + * + * @param prefix + * @param namespaceURI + */ + public static void addNamespacePrefix(String prefix, String namespaceURI) { + XmlHelper.staticNamespaceContext.addPrefix(prefix, namespaceURI); + } + + /** + * Clear namespace prefixes in the current static namespace context + */ + public static void clearNamespacePrefixList() { + XmlHelper.staticNamespaceContext.clear(); + } + + /** + * Replace the current static namespace context with the supplied namespace + * context + * + * @param namespaceContext + */ + public static void setNamespaceContext(XmlNamespaceContext namespaceContext) { + if (namespaceContext != null) { + XmlHelper.staticNamespaceContext = namespaceContext; + } + } + + /** + * @param xml + * @param xPath + * @return + */ + public static NodeList query(Node xml, String xPath) { + return XmlHelper.query(xml, xPath, XmlHelper.staticNamespaceContext); + } + + public static NodeList query(Node xml, String xPath, NamespaceContext namespaceContext) { + try { + XmlHelper.xpath.setNamespaceContext(namespaceContext); + + // System.out.println("Result is: " + xpath.evaluate(xPath, xml)); + return (NodeList) XmlHelper.xpath.evaluate(xPath, xml, XPathConstants.NODESET); + } catch (XPathExpressionException e) { + e.printStackTrace(); + return null; + } + } + + public static ArrayList queryAsArray(Node xml, String xPath) { + return XmlHelper.queryAsArray(xml, xPath, XmlHelper.staticNamespaceContext); + } + + public static ArrayList queryAsArray(Node xml, String xPath, NamespaceContext namespaceContext) { + ArrayList nodes = new ArrayList(); + NodeList result = XmlHelper.query(xml, xPath, namespaceContext); + + if (result != null) { + for (int nodeIndex = 0; nodeIndex < result.getLength(); nodeIndex++) + nodes.add(result.item(nodeIndex)); + } + + return nodes; + } + + public static Node getNode(Node node, String nodeName) { + return XmlHelper.getNode(node, nodeName, XmlHelper.staticNamespaceContext); + } + + public static Node getNode(Node node, String nodeName, NamespaceContext namespaceContext) { + try { + XmlHelper.xpath.setNamespaceContext(namespaceContext); + return (Node) XmlHelper.xpath.evaluate(nodeName, node, XPathConstants.NODE); + } catch (XPathExpressionException e) {} + + return null; + } + + public static String getNodeValue(Node node, String nodeName, String defaultValue) { + return XmlHelper.getNodeValue(node, nodeName, defaultValue, XmlHelper.staticNamespaceContext); + } + + public static String getNodeValue(Node node, String nodeName, String defaultValue, + NamespaceContext namespaceContext) { + try { + XmlHelper.xpath.setNamespaceContext(namespaceContext); + NodeList nodes = (NodeList) XmlHelper.xpath.evaluate(nodeName, node, XPathConstants.NODESET); + + if (nodes.getLength() > 0) + return nodes.item(0).getTextContent(); + } catch (XPathExpressionException e) { + e.printStackTrace(); + } + + return defaultValue; + } + + public static int getNodeValue(Node node, String nodeName, int defaultValue) { + return XmlHelper.getNodeValue(node, nodeName, defaultValue, XmlHelper.staticNamespaceContext); + } + + public static int getNodeValue(Node node, String nodeName, int defaultValue, NamespaceContext namespaceContext) { + String nodeValue = XmlHelper.getNodeValue(node, nodeName, "" + defaultValue, namespaceContext); + + try { + return Integer.parseInt(nodeValue); + } catch (NumberFormatException ex) { + return defaultValue; + } + } + + public static String getAttributeValue(Node node, String attributeName, String defaultValue) { + Node attribute = node.getAttributes().getNamedItem(attributeName); + + if (attribute != null) { + return attribute.getTextContent(); + } + + return defaultValue; + } + + public static int getAttributeValue(Node node, String attributeName, int defaultValue) { + String attributeValue = XmlHelper.getAttributeValue(node, attributeName, "" + defaultValue); + + try { + return Integer.parseInt(attributeValue); + } catch (NumberFormatException ex) { + return defaultValue; + } + } +} diff --git a/voxellib/src/main/java/com/voxelmodpack/common/xml/XmlNamespaceContext.java b/voxellib/src/main/java/com/voxelmodpack/common/xml/XmlNamespaceContext.java new file mode 100644 index 00000000..39c7b6ef --- /dev/null +++ b/voxellib/src/main/java/com/voxelmodpack/common/xml/XmlNamespaceContext.java @@ -0,0 +1,44 @@ +package com.voxelmodpack.common.xml; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; + +import javax.xml.namespace.NamespaceContext; + +/** + * Xmlns for Xml Helper + * + * @author Adam Mummery-Smith + */ +public class XmlNamespaceContext implements NamespaceContext { + private HashMap prefixes = new HashMap(); + + public void addPrefix(String prefix, String namespaceURI) { + this.prefixes.put(prefix, namespaceURI); + } + + public void clear() { + this.prefixes.clear(); + } + + @Override + public Iterator getPrefixes(String namespaceURI) { + return this.prefixes.keySet().iterator(); + } + + @Override + public String getPrefix(String namespaceURI) { + for (Entry prefix : this.prefixes.entrySet()) { + if (prefix.getValue().equals(namespaceURI)) + return prefix.getKey(); + } + + return null; + } + + @Override + public String getNamespaceURI(String prefix) { + return this.prefixes.get(prefix); + } +} diff --git a/voxellib/src/main/resources/assets/voxelcommon/textures/gui/guiparts.png b/voxellib/src/main/resources/assets/voxelcommon/textures/gui/guiparts.png new file mode 100644 index 00000000..9f93565f Binary files /dev/null and b/voxellib/src/main/resources/assets/voxelcommon/textures/gui/guiparts.png differ diff --git a/voxellib/src/main/resources/litemod.json b/voxellib/src/main/resources/litemod.json new file mode 100644 index 00000000..96cd31b6 --- /dev/null +++ b/voxellib/src/main/resources/litemod.json @@ -0,0 +1,8 @@ +{ + "name": "voxellib", + "mcversion": "1.7.10", + "version": "2.3.1", + "revision": "234", + "author": "The VoxelModPack Team", + "description": "VoxelLib contains all of the shared functionality for the VoxelModPack mods" +}