diff --git a/.gitignore b/.gitignore index c27ff58..b9fc517 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,14 @@ +*.blend1 +*.blend2 + +.settings +build/ +eclipse/ +bin/ + +.classpath +.project + /* !/.gitignore !/gradle/ @@ -7,4 +18,5 @@ !/src/* !/*.gradle !/*.md -.gradle + +.gradle/ \ No newline at end of file diff --git a/README.md b/README.md index 2896b2b..69f8918 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,5 @@ MLCore A 'Library' of commonly used functions and class for my mods. ##License## -* You may use my code to learn. -* You may distribute MLCore in any mod packs without my permission; however, I would like to be notified.. -* You may also create derivatives for _private_ (includes server modpacks) use. -* You may not publish derivatives of MLCore without my permission. PRs are preferred. -* You may use MLCore in your mod as long as you notify me and give me credit. -* You may link _directly_ to the download of MLCore if your mod requires it. +Released under the Creative Commons `BY-NC-SA` License. +Available at http://creativecommons.org/licenses/by-nc-sa/4.0/ diff --git a/build.gradle b/build.gradle index 6b00b98..9b85f37 100644 --- a/build.gradle +++ b/build.gradle @@ -15,49 +15,44 @@ buildscript { } } +repositories { + ivy { + name 'Forge FS legacy' + artifactPattern "http://files.minecraftforge.net/[module]/[module]-dev-[revision].[ext]" + } + maven { + name 'CB Repo' + url "http://chickenbones.net/maven/" + } + maven { + name 'ForgeFS' + url 'http://files.minecraftforge.net/maven' + } +} + apply plugin: 'forge' -version = "1.0" -group= "ml" // http://maven.apache.org/guides/mini/guide-naming-conventions.html +file "build.properties" withReader { + def prop = new Properties() + prop.load(it) + ext.config = new ConfigSlurper().parse prop +} + +version = "${config.mlcore.version}" +group = "ml" archivesBaseName = "MLCore" -minecraft { - version = "1.7.2-10.12.2.1147" - assetDir = "run/assets" -} +if (System.getenv("BUILD_NUMBER") != null) + version += ".${System.getenv("BUILD_NUMBER")}" -dependencies { - // you may put jars on which you depend on in ./libs - // or you may define them like so.. - //compile "some.group:artifact:version:classifier" - //compile "some.group:artifact:version" - - // real examples - //compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env - //compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env - - // for more info... - // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html - // http://www.gradle.org/docs/current/userguide/dependency_management.html +ext.simpleVersion = version +version = "MC${config.minecraft.version}-${project.version}" +dependencies { + compile "codechicken:NotEnoughItems:${config.minecraft.version}-${config.NEI.version}:dev" } -processResources -{ - // this will ensure that this task is redone when the versions change. - inputs.property "version", project.version - inputs.property "mcversion", project.minecraft.version - - // replace stuff in mcmod.info, nothing else - from(sourceSets.main.resources.srcDirs) { - include 'mcmod.info' - - // replace version and mcversion - expand 'version':project.version, 'mcversion':project.minecraft.version - } - - // copy everything else, thats not the mcmod.info - from(sourceSets.main.resources.srcDirs) { - exclude 'mcmod.info' - } -} +apply from: 'gradle/forge.gradle' +apply from: 'gradle/artifact.gradle' +apply from: 'gradle/release.gradle' + diff --git a/build.properties b/build.properties index 86b3e6d..c00638f 100644 --- a/build.properties +++ b/build.properties @@ -1,2 +1,6 @@ -MLCore.version=0.8.1 -minecraft.version = 1.6.4 \ No newline at end of file +minecraft.version=1.7.2 +forge.version=10.12.2.1121 +CCLIB.version=1.0.1.7 +NEI.version=1.0.2.14 +mlcore.version=0.8.2 +maven.url=file:///media/storage/Minecraft/web/maven diff --git a/build.xml b/build.xml deleted file mode 100644 index ced00b8..0000000 --- a/build.xml +++ /dev/null @@ -1,145 +0,0 @@ - - - - MLCore - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/getversion.py b/getversion.py deleted file mode 100644 index 4fec84a..0000000 --- a/getversion.py +++ /dev/null @@ -1,63 +0,0 @@ -import sys -import os -import commands -import fnmatch -import re -import subprocess, shlex - -mcp_home = sys.argv[1] -mcp_dir = os.path.abspath(mcp_home) - -print(mcp_dir) -sys.path.append(mcp_dir) - -from runtime.commands import Commands -Commands._version_config = os.path.join(mcp_dir,Commands._version_config) - -def cmdsplit(args): - if os.sep == '\\': - args = args.replace('\\', '\\\\') - return shlex.split(args) - -def cleanDirs(path): - if not os.path.isdir(path): - return - - files = os.listdir(path) - if len(files): - for f in files: - fullpath = os.path.join(path, f) - if os.path.isdir(fullpath): - cleanDirs(fullpath) - - files = os.listdir(path) - if len(files) == 0: - os.rmdir(path) - -def main(): - print("Obtaining version information from git") - cmd = "git describe --long --match='[^(jenkins)]*'" - try: - process = subprocess.Popen(cmdsplit(cmd), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=-1) - vers, _ = process.communicate() - except OSError: - print("Git not found") - vers="v1.0-0-deadbeef" - (major,minor,info,rev,githash)=re.match("v(\d+).(\d+)(-.*)?-(\d+)-(.*)",vers).groups() - if not info: info="" - - (mcpversion,mcversion,mcserverversion) = re.match("[.\w]+ \(data: ([.\w]+), client: ([.\w.]+), server: ([.\w.]+)\)",Commands.fullversion()).groups() - - with open("version.properties","w") as f: - f.write("%s=%s\n" %("MLCore.build.major.number",major)) - f.write("%s=%s\n" %("MLCore.build.minor.number",minor)) - f.write("%s=%s\n" %("MLCore.build.info",info)) - f.write("%s=%s\n" %("MLCore.build.revision.number",rev)) - f.write("%s=%s\n" %("MLCore.build.githash",githash)) - f.write("%s=%s\n" %("MLCore.build.mcpversion",mcpversion)) - f.write("%s=%s\n" %("MLCore.build.mcversion",mcversion)) - - print("Version information: MLCore %s.%s.%s%s using MCP %s for %s" % (major, minor, rev, info, mcpversion, mcversion)) - -if __name__ == '__main__': - main() diff --git a/gradle/artifact.gradle b/gradle/artifact.gradle new file mode 100644 index 0000000..eff4a21 --- /dev/null +++ b/gradle/artifact.gradle @@ -0,0 +1,39 @@ +jar { + classifier = 'universal' + manifest { + attributes FMLCorePlugin: "ml.core.MLCore" + attributes FMLCorePluginContainsFMLMod: "true" + } +} + +javadoc { + include 'ml/core/api/**' +} + +// because the normal default jar task has been modified to be obfuscated +task deobfJar(type: Jar) { + from sourceSets.main.output + classifier = 'deobf' + manifest { + attributes FMLCorePlugin: "ml.core.MLCore" + attributes FMLCorePluginContainsFMLMod: "true" + } +} + +task apiJar(type: Jar) { + from sourceSets.main.output + from sourceSets.main.java + classifier = 'api' + include 'li/cil/oc/api/**' +} + +task javadocJar(type: Jar, dependsOn: javadoc) { + from 'build/docs/javadoc' + classifier 'javadoc' +} + +artifacts { + archives deobfJar + //archives apiJar + //archives javadocJar +} diff --git a/gradle/forge.gradle b/gradle/forge.gradle new file mode 100644 index 0000000..5a34bed --- /dev/null +++ b/gradle/forge.gradle @@ -0,0 +1,14 @@ + +minecraft { + version = "${config.minecraft.version}-${config.forge.version}" +} + +processResources { + from(sourceSets.main.resources.srcDirs) { + include 'mcmod.info' + expand 'version': project.simpleVersion, 'mcversion': config.minecraft.version + } + from(sourceSets.main.resources.srcDirs) { + exclude 'mcmod.info' + } +} diff --git a/gradle/release.gradle b/gradle/release.gradle new file mode 100644 index 0000000..ebf1741 --- /dev/null +++ b/gradle/release.gradle @@ -0,0 +1,17 @@ +apply plugin: 'maven-publish' + +publishing { + publications { + mavenJava(MavenPublication) { + artifact jar + //artifact apiJar + //artifact javadocJar + artifact deobfJar { classifier '' } + } + } + repositories { + maven { + url "${config.maven.url}" + } + } +} diff --git a/gradlew b/gradlew old mode 100755 new mode 100644 diff --git a/gradlew.bat b/gradlew.bat index aec9973..8a0b282 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,90 +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 +@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/make_at.py b/make_at.py deleted file mode 100644 index b5ae5a7..0000000 --- a/make_at.py +++ /dev/null @@ -1,24 +0,0 @@ -import re -import os, os.path -import sys - -mcp_home = sys.argv[1] -mcp_dir = os.path.abspath(mcp_home) -cfg_dir = os.path.join(mcp_dir, 'conf') - -joined_srg = os.path.join(cfg_dir, 'joined.srg') - -for f in os.listdir('./'): - n = re.match(r'(.*_at)\.man', f) - if n: - with open(n.group(1)+'.cfg', 'w+') as oat: - for instr in open(f, 'r+'): - instr = re.sub(r'\s*#.*', '', instr) - instr=instr.strip() - nat = re.match(r'(.*) (.*)$', instr) - if nat: - with open(joined_srg, 'r+') as jnd: - for ln in jnd: - if ln.find(nat.group(2))>-1: - at = re.match(r'(..): (\w+/\w+) ?(.*) net/.*', ln) - oat.write('%s %s%s'%(nat.group(1), at.group(2).replace('/', '.'), at.group(3))) \ No newline at end of file diff --git a/mlcore_at.man b/mlcore_at.man deleted file mode 100644 index e7d8928..0000000 --- a/mlcore_at.man +++ /dev/null @@ -1,2 +0,0 @@ - -public func_74187_b #GuiContainer.getSlotAtPosition(int, int) \ No newline at end of file diff --git a/src/main/java/ml/core/MLCore.java b/src/main/java/ml/core/MLCore.java index a3c8bdd..2adfdb0 100644 --- a/src/main/java/ml/core/MLCore.java +++ b/src/main/java/ml/core/MLCore.java @@ -3,7 +3,6 @@ import java.util.Map; import ml.core.internal.CommonProxy; -import ml.core.internal.PacketHandler; import ml.core.world.WorldGenHandler; import net.minecraftforge.common.MinecraftForge; import cpw.mods.fml.common.Mod; @@ -12,15 +11,12 @@ import cpw.mods.fml.common.SidedProxy; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; -import cpw.mods.fml.common.network.NetworkMod; import cpw.mods.fml.common.registry.GameRegistry; -import cpw.mods.fml.common.registry.TickRegistry; import cpw.mods.fml.relauncher.IFMLLoadingPlugin; import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions; -import cpw.mods.fml.relauncher.Side; @Mod(modid="MLCore", name="MLCore") -@NetworkMod(clientSideRequired=false, serverSideRequired=false, channels={PacketHandler.defChan}, packetHandler=PacketHandler.class) +//@NetworkMod(clientSideRequired=false, serverSideRequired=false, channels={PacketHandler.defChan}, packetHandler=PacketHandler.class) @TransformerExclusions({"ml"}) public class MLCore implements IFMLLoadingPlugin { @@ -35,25 +31,20 @@ public class MLCore implements IFMLLoadingPlugin { @EventHandler public void preInit(FMLPreInitializationEvent evt) { proxy.prInit(); + //NetworkRegistry. MinecraftForge.EVENT_BUS.register(WorldGenHandler.instance); - TickRegistry.registerTickHandler(WorldGenHandler.instance, Side.SERVER); - GameRegistry.registerWorldGenerator(WorldGenHandler.instance); + GameRegistry.registerWorldGenerator(WorldGenHandler.instance, 0); } @EventHandler public void init(FMLInitializationEvent evt) { proxy.load(); } - - @Override - public String[] getLibraryRequestClass() { - return null; - } @Override public String[] getASMTransformerClass() { - return new String[]{"ml.core.asm.MLCAccesTransformer"}; + return new String[]{}; } @Override @@ -70,4 +61,9 @@ public String getSetupClass() { public void injectData(Map data) { } + + @Override + public String getAccessTransformerClass() { + return "ml.core.asm.MLCAccesTransformer"; + } } diff --git a/src/main/java/ml/core/block/BlockDelegator.java b/src/main/java/ml/core/block/BlockDelegator.java index d94aa13..961d312 100644 --- a/src/main/java/ml/core/block/BlockDelegator.java +++ b/src/main/java/ml/core/block/BlockDelegator.java @@ -2,67 +2,75 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map.Entry; import java.util.Random; +import java.util.TreeMap; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.particle.EffectRenderer; -import net.minecraft.client.renderer.texture.IconRegister; +import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.Icon; +import net.minecraft.util.IIcon; import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.Vec3; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.common.IPlantable; - -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; +import net.minecraftforge.common.util.ForgeDirection; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; /** * Partially inspired by OpenComputers. * * @author Matchlighter */ -public class BlockDelegator extends Block { +public class BlockDelegator extends Block { + + private TreeMap subBlocks = new TreeMap(); - private BiMap subBlocks = HashBiMap.create(); + //private BiMap subBlocks = HashBiMap.create(); protected DCls nullDelegate; - public BlockDelegator(int blockId, Material xMaterial, DCls nullDelegate) { - super(blockId, xMaterial); + public BlockDelegator(Material xMaterial, DCls nullDelegate) { + super(xMaterial); this.nullDelegate = nullDelegate; this.nullDelegate.parent = this; } /* ---------------------------- SubBlocks ---------------------------- */ - public boolean addSubBlock(int metaData, DCls sub) { - if (subBlocks.containsKey(metaData) || subBlocks.containsValue(sub)) return false; - subBlocks.put(metaData, sub); + public boolean addSubBlock(int meta, DCls sub) { + if (subBlock(meta) != nullDelegate || subBlocks.containsValue(sub)) return false; + subBlocks.put(meta, sub); sub.parent = this; - sub.metaId = metaData; + sub.metaId = meta; return true; } - public DCls subBlock(int metaData) { - if (subBlocks.containsKey(metaData)) return subBlocks.get(metaData); + public DCls subBlock(int meta) { + if (subBlocks.containsKey(meta)) return subBlocks.get(meta); + Entry ent = subBlocks.floorEntry(meta); + if (ent != null && (ent.getValue().getMetaId() == meta || meta < ent.getValue().getMetaId()+ent.getValue().getMetaLength())) { + return ent.getValue(); + } return nullDelegate; } public DCls subBlock(ItemStack is) { if (is != null && is.getItem() instanceof ItemBlock) { ItemBlock ib = (ItemBlock)is.getItem(); - Block blk = Block.blocksList[ib.getBlockID()]; + Block blk = ib.field_150939_a; if (blk == this) { return subBlock(is.getItemDamage()); } @@ -71,17 +79,17 @@ public DCls subBlock(ItemStack is) { } public DCls subBlock(IBlockAccess world, int x, int y, int z) { - Block blk = Block.blocksList[world.getBlockId(x, y, z)]; + Block blk = world.getBlock(x, y, z); if (blk == this) { return subBlock(world.getBlockMetadata(x, y, z)); } return nullDelegate; } - public static Delegate findSubBlock(ItemStack is) { + public static DelegateBlock findSubBlock(ItemStack is) { if (is != null && is.getItem() instanceof ItemBlock) { ItemBlock ib = (ItemBlock)is.getItem(); - Block blk = Block.blocksList[ib.getBlockID()]; + Block blk = ib.field_150939_a; if (blk instanceof BlockDelegator) { return ((BlockDelegator)blk).subBlock(is.getItemDamage()); } @@ -89,8 +97,8 @@ public static Delegate findSubBlock(ItemStack is) { return null; } - public static Delegate findSubBlock(IBlockAccess world, int x, int y, int z) { - Block blk = Block.blocksList[world.getBlockId(x, y, z)]; + public static DelegateBlock findSubBlock(IBlockAccess world, int x, int y, int z) { + Block blk = world.getBlock(x, y, z); if (blk instanceof BlockDelegator) { return ((BlockDelegator)blk).subBlock(world.getBlockMetadata(x, y, z)); } @@ -108,16 +116,19 @@ public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlaye } @Override - public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List) { + public void getSubBlocks(Item par1, CreativeTabs par2CreativeTabs, List par3List) { for (Integer i : subBlocks.keySet()) { - par3List.add(new ItemStack(this, 1, i)); + DCls sub = subBlocks.get(i); + for (int a=0; a getBlockDropped(World world, int x, int y, int z, int metadata, int fortune) { - return subBlock(world, x, y, z).getBlockDropped(world, x, y, z, metadata, fortune); + public ArrayList getBlockDropped(World world, int x, int y, int z, int meta, int fortune) { + return subBlock(meta).getBlockDropped(world, x, y, z, meta, fortune); } @Override @@ -346,8 +364,8 @@ public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, i } @Override - public int getExpDrop(World world, int data, int enchantmentLevel) { - return subBlock(data).getExpDrop(world, data, enchantmentLevel); + public int getExpDrop(World world, int meta, int enchantmentLevel) { + return subBlock(meta).getExpDrop(world, meta, enchantmentLevel); } @Override @@ -358,52 +376,65 @@ public float getBlockHardness(World world, int x, int y, int z) { /* ---------------------------- ClientSide ---------------------------- */ @Override + @SideOnly(Side.CLIENT) public float getBlockBrightness(IBlockAccess world, int x, int y, int z) { return subBlock(world, x, y, z).getBlockBrightness(world, x, y, z); } @Override + @SideOnly(Side.CLIENT) public int getMixedBrightnessForBlock(IBlockAccess world, int x, int y, int z) { return subBlock(world, x, y, z).getMixedBrightnessForBlock(world, x, y, z); } @Override - public boolean shouldSideBeRendered(IBlockAccess world, int x, int y, int z, int par5) { - Boolean renderSide = subBlock(world, x, y, z).shouldSideBeRendered(world, x, y, z, par5); - return renderSide != null ? renderSide : super.shouldSideBeRendered(world, x, y, z, par5); + @SideOnly(Side.CLIENT) + public boolean shouldSideBeRendered(IBlockAccess world, int x, int y, int z, int side) { + Boolean renderSide = subBlock(world, x, y, z).shouldSideBeRendered(world, x, y, z, side); + return renderSide != null ? renderSide : super.shouldSideBeRendered(world, x, y, z, side); } @Override - public Icon getIcon(int side, int meta) { - return subBlock(meta).getIcon(side, meta); + @SideOnly(Side.CLIENT) + public IIcon getIcon(int side, int meta) { + DCls sub = subBlock(meta); + return sub.getIcon(side, meta - sub.metaId); } @Override - public Icon getBlockTexture(IBlockAccess world, int x, int y, int z, int par5) { - return subBlock(world, x, y, z).getBlockTexture(world, x, y, z, par5); + @SideOnly(Side.CLIENT) + public IIcon getBlockTexture(IBlockAccess world, int x, int y, int z, int side) { + return subBlock(world, x, y, z).getBlockTexture(world, x, y, z, side); } @Override + @SideOnly(Side.CLIENT) public int getRenderColor(int meta) { - return subBlock(meta).getRenderColor(meta); + DCls sub = subBlock(meta); + return sub.getRenderColor(meta - sub.metaId); } @Override - public void registerIcons(IconRegister par1IconRegister) { + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister par1IconRegister) { for (DCls sub : subBlocks.values()) sub.registerIcons(par1IconRegister); } @Override + @SideOnly(Side.CLIENT) public boolean addBlockDestroyEffects(World world, int x, int y, int z, int meta, EffectRenderer effectRenderer) { - return subBlock(world, x, y, z).addBlockDestroyEffects(world, x, y, z, meta, effectRenderer); + DCls sub = subBlock(meta); + return sub.addBlockDestroyEffects(world, x, y, z, meta - sub.metaId, effectRenderer); } @Override + @SideOnly(Side.CLIENT) public boolean addBlockHitEffects(World world, MovingObjectPosition target, EffectRenderer effectRenderer) { return subBlock(world, target.blockX, target.blockY, target.blockZ).addBlockHitEffects(world, target, effectRenderer); } @Override + @SideOnly(Side.CLIENT) public void randomDisplayTick(World world, int x, int y, int z, Random par5Random) { for (DCls sub : subBlocks.values()) sub.randomDisplayTick(world, x, y, z, par5Random); } diff --git a/src/main/java/ml/core/block/BlockUtils.java b/src/main/java/ml/core/block/BlockUtils.java index 6b6c971..a975a74 100644 --- a/src/main/java/ml/core/block/BlockUtils.java +++ b/src/main/java/ml/core/block/BlockUtils.java @@ -3,7 +3,7 @@ import ml.core.vec.Vector3d; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.entity.Entity; -import net.minecraftforge.common.ForgeDirection; +import net.minecraftforge.common.util.ForgeDirection; import org.lwjgl.opengl.GL11; diff --git a/src/main/java/ml/core/block/Delegate.java b/src/main/java/ml/core/block/DelegateBlock.java similarity index 61% rename from src/main/java/ml/core/block/Delegate.java rename to src/main/java/ml/core/block/DelegateBlock.java index 346196e..c4e95c9 100644 --- a/src/main/java/ml/core/block/Delegate.java +++ b/src/main/java/ml/core/block/DelegateBlock.java @@ -6,47 +6,92 @@ import net.minecraft.block.ITileEntityProvider; import net.minecraft.client.particle.EffectRenderer; -import net.minecraft.client.renderer.texture.IconRegister; +import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.Icon; +import net.minecraft.util.IIcon; import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.Vec3; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.IPlantable; +import net.minecraftforge.common.util.ForgeDirection; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; -public abstract class Delegate { +public class DelegateBlock { protected int metaId; - protected BlockDelegator parent; - - public Delegate() {} + protected BlockDelegator parent; + protected String unlocalizedName; + + @SideOnly(Side.CLIENT) + protected IIcon itemIcon; + protected String iconLocation; + + public DelegateBlock() {} - public BlockDelegator parent() { + public BlockDelegator parent() { return parent; } + + public DelegateBlock setIconString(String str) { + this.iconLocation = str; + return this; + } + + public DelegateBlock setUnlocalizedName(String str) { + this.unlocalizedName = str; + return this; + } + + public final int getMetaId() { + return metaId; + } + public int getMetaLength() { + return 1; + } + + public int getSubMeta(IBlockAccess w, int x, int y, int z) { + return getSubMeta(w.getBlockMetadata(x, y, z)); + } + + public int getSubMeta(int gmeta) { + return gmeta - metaId; + } + public void setBlockAt(World world, int wx, int wy, int wz, int flags) { - world.setBlock(wx, wy, wz, parent.blockID, metaId, flags); + this.setBlockAt(world, wx, wy, wz, 0, flags); + } + + public void setBlockAt(World world, int wx, int wy, int wz, int subMeta, int flags) { + if (subMeta < getMetaLength()) { + world.setBlock(wx, wy, wz, parent, metaId+subMeta, flags); + } else { + world.setBlock(wx, wy, wz, parent, metaId, flags); + } } /* ---------------------------- ItemMethods ---------------------------- */ public String getUnlocalizedName(ItemStack stack) { - return ""; + return unlocalizedName; } public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { } + public boolean isLogicalBlock(int subMeta) { + return false; + } + /* ---------------------------- BlockMethods ---------------------------- */ public float getExplosionResistance(Entity par1Entity, World world, int x, int y, int z, double explosionX, double explosionY, double explosionZ) { @@ -65,7 +110,7 @@ public int getLightValue(IBlockAccess world, int x, int y, int z) { return 0; } - public int getLightOpacity(World world, int x, int y, int z) { + public int getLightOpacity(IBlockAccess world, int x, int y, int z) { return isOpaqueCube() ? 255 : 0; } @@ -73,29 +118,29 @@ public boolean isOpaqueCube() { return true; } - public boolean canBeReplacedByLeaves(World world, int x, int y, int z) { + public boolean canBeReplacedByLeaves(IBlockAccess world, int x, int y, int z) { return false; } - public boolean canCreatureSpawn(EnumCreatureType type, World world, int x, int y, int z) { - return isBlockSolidOnSide(world, x, y, z, ForgeDirection.UP); + public boolean canCreatureSpawn(EnumCreatureType type, IBlockAccess world, int x, int y, int z) { + return isSideSolid(world, x, y, z, ForgeDirection.UP); } - public boolean canSilkHarvest(World world, EntityPlayer player, int x, int y, int z, int metadata) { + public boolean canSilkHarvest(World world, EntityPlayer player, int x, int y, int z, int subMeta) { return false; } - public boolean canSustainLeaves(World world, int x, int y, int z) { + public boolean canSustainLeaves(IBlockAccess world, int x, int y, int z) { return false; } - public boolean canSustainPlant(World world, int x, int y, int z, ForgeDirection direction, IPlantable plant) { + public boolean canSustainPlant(IBlockAccess world, int x, int y, int z, ForgeDirection direction, IPlantable plant) { return false; } public void velocityToAddToEntity(World par1World, int x, int y, int z, Entity par5Entity, Vec3 par6Vec3) {} - public boolean isLadder(World world, int x, int y, int z, EntityLivingBase entity) { + public boolean isLadder(IBlockAccess world, int x, int y, int z, EntityLivingBase entity) { return false; } @@ -103,19 +148,19 @@ public boolean isFertile(World world, int x, int y, int z) { return false; } - public boolean isAirBlock(World world, int x, int y, int z) { + public boolean isAir(IBlockAccess world, int x, int y, int z) { return false; } - public boolean isFlammable(IBlockAccess world, int x, int y, int z, int metadata, ForgeDirection face) { + public boolean isFlammable(IBlockAccess world, int x, int y, int z, ForgeDirection face) { return false; } - public boolean isBlockBurning(World world, int x, int y, int z) { + public boolean isBurning(IBlockAccess world, int x, int y, int z) { return false; } - public boolean isBlockSolidOnSide(World world, int x, int y, int z, ForgeDirection side) { + public boolean isSideSolid(IBlockAccess world, int x, int y, int z, ForgeDirection side) { return isOpaqueCube(); } @@ -126,7 +171,7 @@ public boolean canBlockStay(World par1World, int x, int y, int z) { public void fillWithRain(World par1World, int x, int y, int z) {} public boolean canPlaceTorchOnTop(World world, int x, int y, int z) { - return isBlockSolidOnSide(world, x, y, z, ForgeDirection.UP); + return isSideSolid(world, x, y, z, ForgeDirection.UP); } /* ---------------------------- Events ---------------------------- */ @@ -137,21 +182,21 @@ public void onBlockAdded(World par1World, int x, int y, int z) {} public void onBlockPlacedBy(World par1World, int x, int y, int z, EntityLivingBase par5EntityLivingBase, ItemStack par6ItemStack) {} - public void onBlockPreDestroy(World par1World, int x, int y, int z, int meta) {} + public void onBlockPreDestroy(World par1World, int x, int y, int z, int subMeta) {} - public void breakBlock(World par1World, int x, int y, int z, int id, int meta) { - if (hasTileEntity(meta)) par1World.removeBlockTileEntity(x, y, z); + public void breakBlock(World par1World, int x, int y, int z, int id, int subMeta) { + if (hasTileEntity(subMeta)) par1World.removeTileEntity(x, y, z); } public boolean removeBlockByPlayer(World world, EntityPlayer player, int x, int y, int z) { return world.setBlockToAir(x, y, z); } - public void onNeighborBlockChange(World par1World, int x, int y, int z, int par5) {} + public void onNeighborBlockChange(World par1World, int x, int y, int z, int id) {} public void onBlockClicked(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer) {} - public boolean onBlockActivated(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { + public boolean onBlockActivated(World par1World, int x, int y, int z, EntityPlayer par5EntityPlayer, int side, float hitx, float hity, float hitz) { return false; } @@ -175,13 +220,13 @@ public int isProvidingWeakPower(IBlockAccess world, int x, int y, int z, int par /* ---------------------------- TileEntities ---------------------------- */ - public boolean hasTileEntity(int metadata) { + public boolean hasTileEntity(int subMeta) { return this instanceof ITileEntityProvider; } - public TileEntity createTileEntity(World world, int metadata) { - if (hasTileEntity(metadata)) - return ((ITileEntityProvider)this).createNewTileEntity(world); + public TileEntity createTileEntity(World world, int subMeta) { + if (hasTileEntity(subMeta)) + return ((ITileEntityProvider)this).createNewTileEntity(world, subMeta); return null; } @@ -191,17 +236,20 @@ public boolean canEntityDestroy(World world, int x, int y, int z, Entity entity) return true; } - public boolean canHarvestBlock(EntityPlayer player, int meta) { - return ForgeHooks.canHarvestBlock(this.parent(), player, meta); + public boolean canHarvestBlock(EntityPlayer player, int subMeta) { + return ForgeHooks.canHarvestBlock(this.parent(), player, subMeta); } - public boolean canPlaceBlockOnSide(World par1World, int x, int y, int z, int par5, ItemStack par6ItemStack) { + public boolean canPlaceBlockOnSide(World par1World, int x, int y, int z, int side, ItemStack par6ItemStack) { return parent().canPlaceBlockAt(par1World, x, y, z); } - public ArrayList getBlockDropped(World world, int x, int y, int z, int metadata, int fortune) { + /** + * Note that meta is not subMeta in this case. + */ + public ArrayList getBlockDropped(World world, int x, int y, int z, int meta, int fortune) { ArrayList ret = new ArrayList(); - ret.add(new ItemStack(parent(), 1, metadata)); + ret.add(new ItemStack(parent(), 1, meta)); return ret; } @@ -219,38 +267,52 @@ public float getBlockHardness(World par1World, int x, int y, int z) { /* ---------------------------- ClientSide ---------------------------- */ + @SideOnly(Side.CLIENT) public float getBlockBrightness(IBlockAccess world, int x, int y, int z) { return world.getBrightness(x, y, z, getLightValue(world, x, y, z)); } + @SideOnly(Side.CLIENT) public int getMixedBrightnessForBlock(IBlockAccess world, int x, int y, int z) { return world.getLightBrightnessForSkyBlocks(x, y, z, getLightValue(world, x, y, z)); } + @SideOnly(Side.CLIENT) public Boolean shouldSideBeRendered(IBlockAccess world, int x, int y, int z, int side) { return null; } - public Icon getIcon(int side, int meta) {return null;} + @SideOnly(Side.CLIENT) + public IIcon getIcon(int side, int subMeta) { + return itemIcon; + } - public Icon getBlockTexture(IBlockAccess world, int x, int y, int z, int side) { - return this.getIcon(side, world.getBlockMetadata(x, y, z)); + @SideOnly(Side.CLIENT) + public IIcon getBlockTexture(IBlockAccess world, int x, int y, int z, int side) { + return this.getIcon(side, getSubMeta(world, x, y, z)); } - public int getRenderColor(int meta) { + @SideOnly(Side.CLIENT) + public int getRenderColor(int subMeta) { return 16777215; } - public void registerIcons(IconRegister par1IconRegister) {}; + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister ireg) { + this.itemIcon = ireg.registerIcon(iconLocation); + } - public boolean addBlockDestroyEffects(World world, int x, int y, int z, int meta, EffectRenderer effectRenderer) { + @SideOnly(Side.CLIENT) + public boolean addBlockDestroyEffects(World world, int x, int y, int z, int subMeta, EffectRenderer effectRenderer) { return false; } + @SideOnly(Side.CLIENT) public boolean addBlockHitEffects(World worldObj, MovingObjectPosition target, EffectRenderer effectRenderer) { return false; } + @SideOnly(Side.CLIENT) public void randomDisplayTick(World par1World, int x, int y, int z, Random par5Random) {} } diff --git a/src/main/java/ml/core/block/ItemBlockDelegate.java b/src/main/java/ml/core/block/ItemBlockDelegate.java index 7fbf415..39cecf5 100644 --- a/src/main/java/ml/core/block/ItemBlockDelegate.java +++ b/src/main/java/ml/core/block/ItemBlockDelegate.java @@ -2,13 +2,14 @@ import java.util.List; +import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; public class ItemBlockDelegate extends ItemBlock { - public ItemBlockDelegate(int par1) { + public ItemBlockDelegate(Block par1) { super(par1); setHasSubtypes(true); } diff --git a/src/main/java/ml/core/book/BlankPage.java b/src/main/java/ml/core/book/BlankPage.java new file mode 100644 index 0000000..55e5278 --- /dev/null +++ b/src/main/java/ml/core/book/BlankPage.java @@ -0,0 +1,14 @@ +package ml.core.book; + +import net.minecraft.client.Minecraft; + +public class BlankPage extends Page { + + public BlankPage(WindowBook window) { + super(window); + } + + @Override + public void drawPage(Minecraft mc, int x, int y, int w, int h, float partialTick) {} + +} diff --git a/src/main/java/ml/core/book/ChapterHeaderPage.java b/src/main/java/ml/core/book/ChapterHeaderPage.java new file mode 100644 index 0000000..e3f07b1 --- /dev/null +++ b/src/main/java/ml/core/book/ChapterHeaderPage.java @@ -0,0 +1,42 @@ +package ml.core.book; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.client.Minecraft; + +public class ChapterHeaderPage extends Page { + + public List title; + public List text = new ArrayList(); + + public ChapterHeaderPage(WindowBook window, String title, List text) { + super(window); + + this.title = getFontRenderer().listFormattedStringToWidth(title, window.getPageWidth()); + + int h = (int)(window.pageHeight * 0.25F) + (this.title.size()*getFontRenderer().FONT_HEIGHT)/2 + getFontRenderer().FONT_HEIGHT; + + while ((h+=getFontRenderer().FONT_HEIGHT) < window.getPageHeight() && text.size()>0) { + this.text.add(text.remove(0)); + } + } + + @Override + public void drawPage(Minecraft mc, int x, int y, int w, int h, float partialTick) { + + y = y + (int)(h*0.25F) - (title.size()*mc.fontRenderer.FONT_HEIGHT)/2; + + for (String ln : title) { + mc.fontRenderer.drawString(ln, x+(w-mc.fontRenderer.getStringWidth(ln))/2, y, 0x000000); + y += mc.fontRenderer.FONT_HEIGHT; + } + + y += mc.fontRenderer.FONT_HEIGHT; + for (String ln : text) { + mc.fontRenderer.drawString(ln, x, y, 0x000000); + y += mc.fontRenderer.FONT_HEIGHT; + } + } + +} diff --git a/src/main/java/ml/core/book/Page.java b/src/main/java/ml/core/book/Page.java new file mode 100644 index 0000000..62d2c19 --- /dev/null +++ b/src/main/java/ml/core/book/Page.java @@ -0,0 +1,24 @@ +package ml.core.book; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import cpw.mods.fml.client.FMLClientHandler; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +public abstract class Page { + + public final WindowBook window; + + public Page(WindowBook window) { + this.window = window; + } + + @SideOnly(Side.CLIENT) + public abstract void drawPage(Minecraft mc, int x, int y, int w, int h, float partialTick); + + @SideOnly(Side.CLIENT) + public FontRenderer getFontRenderer() { + return FMLClientHandler.instance().getClient().fontRenderer; + } +} diff --git a/src/main/java/ml/core/book/TextPage.java b/src/main/java/ml/core/book/TextPage.java new file mode 100644 index 0000000..fa03e2a --- /dev/null +++ b/src/main/java/ml/core/book/TextPage.java @@ -0,0 +1,29 @@ +package ml.core.book; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.client.Minecraft; + +public class TextPage extends Page { + + protected List text = new ArrayList(); + + public TextPage(WindowBook window, List text) { + super(window); + + int h = 0; + while ((h+=getFontRenderer().FONT_HEIGHT) < window.getPageHeight() && text.size()>0) { + this.text.add(text.remove(0)); + } + } + + @Override + public void drawPage(Minecraft mc, int x, int y, int w, int h, float partialTick) { + for (String ln : text) { + mc.fontRenderer.drawString(ln, x, y, 0x000000); + y+=mc.fontRenderer.FONT_HEIGHT; + } + } + +} diff --git a/src/main/java/ml/core/book/TitlePage.java b/src/main/java/ml/core/book/TitlePage.java new file mode 100644 index 0000000..ae0f57c --- /dev/null +++ b/src/main/java/ml/core/book/TitlePage.java @@ -0,0 +1,36 @@ +package ml.core.book; + +import java.util.List; + +import net.minecraft.client.Minecraft; + +import org.lwjgl.opengl.GL11; + +public class TitlePage extends Page { + + protected String title; + protected String subtitle; + + public TitlePage(WindowBook window, String title, String subtitle) { + super(window); + this.title = title; + this.subtitle = subtitle; + } + + @Override + public void drawPage(Minecraft mc, int x, int y, int w, int h, float partialTick) { + List lines = mc.fontRenderer.listFormattedStringToWidth(title, w); + y = y + (h-lines.size()*mc.fontRenderer.FONT_HEIGHT)/2; + for (String ln : lines) { + mc.fontRenderer.drawString(ln, x+(w-mc.fontRenderer.getStringWidth(ln))/2, y, 0x000000); + y += mc.fontRenderer.FONT_HEIGHT; + } + + GL11.glPushMatrix(); + GL11.glTranslatef(x + w/2, y , 0); + GL11.glScalef(0.5F, 0.5F, 1); + mc.fontRenderer.drawString(subtitle, -mc.fontRenderer.getStringWidth(subtitle)/2, 0, 0x000000); + GL11.glPopMatrix(); + } + +} diff --git a/src/main/java/ml/core/book/WindowBook.java b/src/main/java/ml/core/book/WindowBook.java new file mode 100644 index 0000000..d723546 --- /dev/null +++ b/src/main/java/ml/core/book/WindowBook.java @@ -0,0 +1,246 @@ +package ml.core.book; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import ml.core.enums.NaturalSide; +import ml.core.gui.GuiRenderUtils; +import ml.core.gui.controls.button.ControlButton; +import ml.core.gui.controls.tabs.ControlTabManager; +import ml.core.gui.controls.tabs.ControlTabManager.GuiTab; +import ml.core.gui.core.Window; +import ml.core.gui.event.EventGuiClosing; +import ml.core.gui.event.GuiEvent; +import ml.core.gui.event.mouse.EventMouseClicked; +import ml.core.vec.Vector2i; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import cpw.mods.fml.client.FMLClientHandler; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +public abstract class WindowBook extends Window { + + public List pages = new ArrayList(); + public Map bookmarks = new LinkedHashMap(); + protected int currentPage; + + public int pageWidth=127, pageHeight=163, pagePadding = 6; + + protected ControlButton btnPrevious, btnNext; + + public WindowBook(EntityPlayer epl, Side side) { + super(epl, side); + setSize(278, 175); + + if (side == Side.CLIENT) { + initBookContents(); + } + } + + @Override + public void constructClient() { + setCustomResource("window", "SGworlds:textures/gui/book_double"); + super.constructClient(); + } + + public int getPageWidth() { + return pageWidth - 2*pagePadding; + } + + public int getPageHeight() { + return pageHeight - 2*pagePadding; + } + + @Override + public ItemStack transferStackFromSlot(EntityPlayer epl, Slot slot) { + return null; + } + + @Override + public void drawBackground(float partialTick) { + bindStyleTexture("window"); + GuiRenderUtils.drawTexturedModalRect(this.getLocalPosition().x, this.getLocalPosition().y, 0, 0, this.getSize().x, this.getSize().y, 512,256); + } + + @Override + public void drawForeground(float partialTick) { + getLocalPosition().glTranslate(); + int awidth = pageWidth - 2*pagePadding, aheight = pageHeight - 2*pagePadding; + + pages.get(currentPage).drawPage(getMC(), 12 + pagePadding, 6 + pagePadding, awidth, aheight, partialTick); + + if (pages.size() > currentPage+1) { + pages.get(currentPage+1).drawPage(getMC(), 12 + 129 + pagePadding, 6 + pagePadding, awidth, aheight, partialTick); + } + } + + @Override + public void initControls() { + ControlTabManager ctm = new ControlTabManager(this, NaturalSide.Right); + for (Bookmark bm : bookmarks.keySet()) { + new TabBookmark(ctm, bm); + } + btnPrevious = new ControlButton(this, new Vector2i(0, 178), new Vector2i(20,20), "<"); + btnNext = new ControlButton(this, new Vector2i(258, 178), new Vector2i(20,20), ">"); + } + + @Override + public void handleEvent(GuiEvent evt) { + if (evt instanceof EventMouseClicked) { + if (evt.origin == btnPrevious) { + changePage(-2); + } else if (evt.origin == btnNext) { + changePage(2); + } + } else if (evt instanceof EventGuiClosing) { + } + } + + @Override + public boolean canInteractWith(EntityPlayer epl) { + return true; + } + + @Override + public boolean shouldShowNEI() { + return false; + } + + public class TabBookmark extends GuiTab { + + protected Bookmark mark; + + public TabBookmark(ControlTabManager ctm, Bookmark mark) { + super(ctm); + + this.mark = mark; + this.tabColor = mark.getColor(); + } + + @Override + public void constructClient() { + setCustomResource("ledger", "SGWorlds:textures/gui/tab_bookmark"); + super.constructClient(); + } + + @Override + public Vector2i getTargetSize() { + return new Vector2i(treeHasHover() ? 24 + getMC().fontRenderer.getStringWidth(mark.getName()) : 18, 24); + } + + @Override + public void drawForeground(float partialTick) { + getLocalPosition().glTranslate(); + FontRenderer fr = getMC().fontRenderer; + if (treeHasHover() && getSize().equals(getTargetSize())) { + fr.drawString(this.mark.getName(), 6, (24-getGui().getMinecraft().fontRenderer.FONT_HEIGHT)/2+1, 0xFFFFFF, true); + } + } + + @Override + public void handleEvent(GuiEvent evt) { + if (evt instanceof EventMouseClicked && evt.origin == this) { + jumpToBookmark(mark); + } + super.handleEvent(evt); + } + } + + // Book Stuff + + public abstract void initBookContents(); + + public Page addPage(Page page) { + pages.add(page); + return page; + } + + public Bookmark addBookmark(Page page, Bookmark mark) { + this.bookmarks.put(mark, page); + return mark; + } + + public void changePage(int delta) { + int oPage = currentPage; + oPage += delta; + if (oPage >=0 && oPage < pages.size()) { + currentPage = oPage; + } + } + + public void jumpToPage(Page page) { + if (pages.contains(page)) { + int i = pages.indexOf(page); + if (i%2 == 1) i--; + currentPage = i; + } + } + + public void jumpToBookmark(Bookmark mark) { + if (bookmarks.containsKey(mark)) + jumpToPage(bookmarks.get(mark)); + } + + @SideOnly(Side.CLIENT) + public List addTextPages(String text) { + List lines = splitStringWidth(text); + List pages = new ArrayList(); + + while (lines.size() > 0) { + pages.add(new TextPage(this, lines)); + } + this.pages.addAll(pages); + return pages; + } + + @SideOnly(Side.CLIENT) + public List addChapter(String title, String text) { + FontRenderer fr = FMLClientHandler.instance().getClient().fontRenderer; + + List lines = splitStringWidth(text); + List pages = new ArrayList(); + + pages.add(new ChapterHeaderPage(this, title, lines)); + while (lines.size() > 0) { + pages.add(new TextPage(this, lines)); + } + this.pages.addAll(pages); + return pages; + } + + @SideOnly(Side.CLIENT) + public List addChapter(String title, String text, int tabColor) { + List pages = addChapter(title, text); + addBookmark(pages.get(0), new Bookmark(title, tabColor)); + return pages; + } + + @SideOnly(Side.CLIENT) + public List splitStringWidth(String str) { + FontRenderer fr = FMLClientHandler.instance().getClient().fontRenderer; + return new ArrayList(fr.listFormattedStringToWidth(str, getPageWidth())); + } + + public class Bookmark { + protected String name; + protected int color; + + public Bookmark(String name, int color) { + this.name = name; + this.color = color; + } + + public String getName() { + return name; + } + + public int getColor() { + return color; + } + } +} diff --git a/src/main/java/ml/core/data/Config.java b/src/main/java/ml/core/data/Config.java index 3392404..f9b4f45 100644 --- a/src/main/java/ml/core/data/Config.java +++ b/src/main/java/ml/core/data/Config.java @@ -14,9 +14,9 @@ import ml.core.data.Config.Prop.Renamed; import ml.core.internal.CoreLogger; import ml.core.util.StringUtils; -import net.minecraftforge.common.ConfigCategory; -import net.minecraftforge.common.Configuration; -import net.minecraftforge.common.Property; +import net.minecraftforge.common.config.ConfigCategory; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.common.config.Property; public abstract class Config { @@ -73,7 +73,7 @@ public Config(Configuration cfg) { fcfg = cfg; } - public static Property.Type getForgeType(Class cls) { + public static Property.Type getForgeType(Class cls) { if (cls.isArray()) cls = cls.getComponentType(); if (cls == int.class || cls == Integer.class) return Property.Type.INTEGER; @@ -120,8 +120,8 @@ private String testGetCategory(Field fld, String last) { return last; } - protected void loadModule(Object modInst, Class modCls) throws IllegalAccessException { - String lastCategory = fcfg.CATEGORY_GENERAL; + protected void loadModule(Object modInst, Class modCls) throws IllegalAccessException { + String lastCategory = Configuration.CATEGORY_GENERAL; for (Field fld : modCls.getFields()){ if (modInst != null || Modifier.isStatic(fld.getModifiers())) { @@ -153,7 +153,7 @@ protected void loadModule(Object modInst, Class modCls) throws IllegalAccessExce } } - Class type = fld.getType(); + Class type = fld.getType(); Property.Type forgeTyp = getForgeType(type); Object fldValue = null; if (type.isArray()) { @@ -225,7 +225,7 @@ public Config load() { loadModule(this, this.getClass()); for (Object mod : mods) if (mod instanceof Class) - loadModule(null, (Class)mod); + loadModule(null, (Class)mod); else loadModule(mod, mod.getClass()); } catch(Exception e) { CoreLogger.log(Level.SEVERE, "Failed to load the configuration properly", e); @@ -235,8 +235,8 @@ public Config load() { return this; } - protected void saveModule(Object modInst, Class modCls) throws IllegalAccessException { - String lastCategory = fcfg.CATEGORY_GENERAL; + protected void saveModule(Object modInst, Class modCls) throws IllegalAccessException { + String lastCategory = Configuration.CATEGORY_GENERAL; for (Field fld : modCls.getFields()){ if (modInst != null || Modifier.isStatic(fld.getModifiers())) { @@ -250,7 +250,7 @@ protected void saveModule(Object modInst, Class modCls) throws IllegalAccessExce Property cProp = null; - Class type = fld.getType(); + Class type = fld.getType(); Property.Type forgeTyp = getForgeType(type); if (type.isArray()) { cProp = fcfg.get(propCategory, propName, (String[])fld.get(modInst), null, forgeTyp); @@ -275,7 +275,7 @@ public void save() { saveModule(this, this.getClass()); for (Object mod : mods) if (mod instanceof Class) - saveModule(null, (Class)mod); + saveModule(null, (Class)mod); else saveModule(mod, mod.getClass()); } catch(Exception e) { diff --git a/src/main/java/ml/core/data/IDataSerializer.java b/src/main/java/ml/core/data/IDataSerializer.java index bb73315..20d1c6f 100644 --- a/src/main/java/ml/core/data/IDataSerializer.java +++ b/src/main/java/ml/core/data/IDataSerializer.java @@ -7,9 +7,9 @@ public interface IDataSerializer { - public boolean handles(Class clazz); + public boolean handles(Class clazz); - public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOException; + public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOException; public void serialize(Object obj, DataOutputStream dOut) throws IOException; diff --git a/src/main/java/ml/core/data/NBTUtils.java b/src/main/java/ml/core/data/NBTUtils.java index 5357f9b..76eb2e8 100644 --- a/src/main/java/ml/core/data/NBTUtils.java +++ b/src/main/java/ml/core/data/NBTUtils.java @@ -23,6 +23,7 @@ */ public class NBTUtils { + @SuppressWarnings("unchecked") public static T getTagValue(NBTBase tag) { if (tag instanceof NBTTagFloat) {return (T)(Object)((NBTTagFloat)tag).data;} else if @@ -41,15 +42,15 @@ public static T getTagValue(NBTBase tag) { public static NBTBase createTag(String name, Object value) { if - (value instanceof Float) {return new NBTTagFloat(name, (Float)value);} else if - (value instanceof Integer) {return new NBTTagInt(name, (Integer)value);} else if - (value instanceof Short) {return new NBTTagShort(name, (Short)value);} else if - (value instanceof Long) {return new NBTTagLong(name, (Long)value);} else if - (value instanceof Double) {return new NBTTagDouble(name, (Double)value);} else if - (value instanceof Byte) {return new NBTTagByte(name, (Byte)value);} else if - (value instanceof String) {return new NBTTagString(name, (String)value);} else if - (value instanceof int[]) {return new NBTTagIntArray(name, (int[])value);} else if - (value instanceof byte[]) {return new NBTTagByteArray(name, (byte[])value);} else if + (value instanceof Float) {return new NBTTagFloat( (Float)value);} else if + (value instanceof Integer) {return new NBTTagInt( (Integer)value);} else if + (value instanceof Short) {return new NBTTagShort( (Short)value);} else if + (value instanceof Long) {return new NBTTagLong( (Long)value);} else if + (value instanceof Double) {return new NBTTagDouble( (Double)value);} else if + (value instanceof Byte) {return new NBTTagByte( (Byte)value);} else if + (value instanceof String) {return new NBTTagString( (String)value);} else if + (value instanceof int[]) {return new NBTTagIntArray( (int[])value);} else if + (value instanceof byte[]) {return new NBTTagByteArray((byte[])value);} else if (value instanceof NBTBase) {return (NBTBase)value;} return null; } @@ -65,6 +66,7 @@ private static String[] splitPath(String... path) { /** * You CAN get a string from any NBTTag type with this method - if the defaultVal is a String, toString() will be called on the returning Object. */ + @SuppressWarnings("unchecked") public static T getTagValue(NBTTagCompound parent, T defaultVal, String...tagPath) { try { tagPath = splitPath(tagPath); @@ -78,6 +80,8 @@ public static T getTagValue(NBTTagCompound parent, T defaultVal, String...ta Object value = NBTUtils.getTagValue(parent.getTag(tagName)); if (defaultVal instanceof String) return (T)value.toString(); + if (defaultVal instanceof Boolean) + return (T)(Boolean)((Byte)value!=0); return (T)value; } catch (Exception ex) { @@ -92,7 +96,7 @@ public static void setTag(NBTTagCompound parent, Object value, String...tagPath) tagName = tagPath[i]; if (i == tagPath.length-1) break; if (!parent.hasKey(tagName)) - parent.setCompoundTag(tagName, new NBTTagCompound(tagName)); + parent.setTag(tagName, new NBTTagCompound()); parent = parent.getCompoundTag(tagName); } NBTBase ntag = createTag(tagName, value); diff --git a/src/main/java/ml/core/data/Serialization.java b/src/main/java/ml/core/data/Serialization.java index 39f7a1b..6ac6ef3 100644 --- a/src/main/java/ml/core/data/Serialization.java +++ b/src/main/java/ml/core/data/Serialization.java @@ -30,7 +30,7 @@ public static void addSerializer(IDataSerializer serializer) { serializers.add(serializer); } - public static IDataSerializer getSerializer(Class clazz) { + public static IDataSerializer getSerializer(Class clazz) { IDataSerializer slzr = null; for (IDataSerializer IDS : serializers) { if (IDS.handles(clazz) && (slzr == null || slzr.getPriority() clazz, Object obj, DataOutputStream dataOut) throws IOException { if (clazz == int.class || clazz == Integer.class) dataOut.writeInt((Integer)obj); else if (clazz == boolean.class || clazz == Boolean.class) @@ -66,7 +66,7 @@ public static void serialize(Object obj, DataOutputStream dataOut) throws IOExce serialize(obj.getClass(), obj, dataOut); } - public static Object deserialize(Class clazz, ByteArrayDataInput dataIn) throws IOException { + public static Object deserialize(Class clazz, ByteArrayDataInput dataIn) throws IOException { if (clazz == int.class || clazz == Integer.class) return dataIn.readInt(); diff --git a/src/main/java/ml/core/data/serializers/SArray.java b/src/main/java/ml/core/data/serializers/SArray.java index d896465..375fc7c 100644 --- a/src/main/java/ml/core/data/serializers/SArray.java +++ b/src/main/java/ml/core/data/serializers/SArray.java @@ -12,13 +12,13 @@ public class SArray implements IDataSerializer { @Override - public boolean handles(Class clazz) { + public boolean handles(Class clazz) { return clazz.isArray(); } @Override - public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOException { - Class cls = clazz.getComponentType(); + public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOException { + Class cls = clazz.getComponentType(); int len = dIn.readInt(); Object arr = Array.newInstance(cls, len); @@ -30,8 +30,6 @@ public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOExceptio @Override public void serialize(Object array, DataOutputStream dataOut) throws IOException { - Class cls = array.getClass().getComponentType(); - int len = Array.getLength(array); dataOut.writeInt(len); for (int i=0; i clazz) { return clazz == BlockCoord.class; } @Override - public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOException { + public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOException { return new BlockCoord(dIn.readInt(), dIn.readInt(), dIn.readInt()); } diff --git a/src/main/java/ml/core/data/serializers/SForgeDirection.java b/src/main/java/ml/core/data/serializers/SForgeDirection.java index 4f99497..1f2cff2 100644 --- a/src/main/java/ml/core/data/serializers/SForgeDirection.java +++ b/src/main/java/ml/core/data/serializers/SForgeDirection.java @@ -4,19 +4,19 @@ import java.io.IOException; import ml.core.data.IDataSerializer; -import net.minecraftforge.common.ForgeDirection; +import net.minecraftforge.common.util.ForgeDirection; import com.google.common.io.ByteArrayDataInput; public class SForgeDirection implements IDataSerializer { @Override - public boolean handles(Class clazz) { + public boolean handles(Class clazz) { return clazz == ForgeDirection.class; } @Override - public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOException { + public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOException { return ForgeDirection.values()[dIn.readInt()]; } diff --git a/src/main/java/ml/core/data/serializers/SItemsStack.java b/src/main/java/ml/core/data/serializers/SItemsStack.java index 8ab4d46..ca20769 100644 --- a/src/main/java/ml/core/data/serializers/SItemsStack.java +++ b/src/main/java/ml/core/data/serializers/SItemsStack.java @@ -4,6 +4,7 @@ import java.io.IOException; import ml.core.data.IDataSerializer; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -12,12 +13,12 @@ public class SItemsStack implements IDataSerializer { @Override - public boolean handles(Class clazz) { + public boolean handles(Class clazz) { return clazz==ItemStack.class || ItemStack.class.isAssignableFrom(clazz); } @Override - public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOException { + public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOException { ItemStack var1 = null; short var2 = dIn.readShort(); @@ -25,7 +26,7 @@ public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOExceptio { byte var3 = dIn.readByte(); short var4 = dIn.readShort(); - var1 = new ItemStack(var2, var3, var4); + var1 = new ItemStack(Item.getItemById(var2), var3, var4); var1.stackTagCompound = SNBTTagCompound.readNBTTagCompound(dIn); } @@ -38,7 +39,7 @@ public void serialize(Object obj, DataOutputStream dOut) throws IOException { if (is == null) { dOut.writeShort(-1); } else { - dOut.writeShort(is.itemID); + dOut.writeShort(Item.getIdFromItem(is.getItem())); dOut.writeByte(is.stackSize); dOut.writeShort(is.getItemDamage()); NBTTagCompound var2 = null; diff --git a/src/main/java/ml/core/data/serializers/SNBTTagCompound.java b/src/main/java/ml/core/data/serializers/SNBTTagCompound.java index 1029950..d96b150 100644 --- a/src/main/java/ml/core/data/serializers/SNBTTagCompound.java +++ b/src/main/java/ml/core/data/serializers/SNBTTagCompound.java @@ -12,12 +12,12 @@ public class SNBTTagCompound implements IDataSerializer { @Override - public boolean handles(Class clazz) { + public boolean handles(Class clazz) { return clazz == NBTTagCompound.class; } @Override - public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOException { + public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOException { return readNBTTagCompound(dIn); } diff --git a/src/main/java/ml/core/data/serializers/SString.java b/src/main/java/ml/core/data/serializers/SString.java index caaf9cd..e259d17 100644 --- a/src/main/java/ml/core/data/serializers/SString.java +++ b/src/main/java/ml/core/data/serializers/SString.java @@ -10,12 +10,12 @@ public class SString implements IDataSerializer { @Override - public boolean handles(Class clazz) { + public boolean handles(Class clazz) { return clazz==String.class; } @Override - public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOException { + public Object deserialize(Class clazz, ByteArrayDataInput dIn) throws IOException { return readString(dIn, 256); } diff --git a/src/main/java/ml/core/gui/GuiRenderUtils.java b/src/main/java/ml/core/gui/GuiRenderUtils.java index 6f6bb6a..3dd1600 100644 --- a/src/main/java/ml/core/gui/GuiRenderUtils.java +++ b/src/main/java/ml/core/gui/GuiRenderUtils.java @@ -4,7 +4,7 @@ import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.entity.RenderItem; import net.minecraft.item.ItemStack; -import net.minecraft.util.Icon; +import net.minecraft.util.IIcon; import org.lwjgl.opengl.GL11; @@ -13,7 +13,6 @@ @SideOnly(Side.CLIENT) public class GuiRenderUtils { - public static RenderItem renderItem = new RenderItem(); public static int zLevel = 0; @@ -107,11 +106,11 @@ public static void drawSlicedRect(int x, int y, int w, int h, int uBase, int vBa drawSlicedRect(x, y, w, h, uBase, vBase, uW, uH, bord, bord, bord, bord); } - public static void drawTexturedModelRectFromIcon(int par1, int par2, Icon par3Icon, int par4, int par5) { + public static void drawTexturedModelRectFromIcon(int par1, int par2, IIcon par3Icon, int par4, int par5) { drawTexturedModelRect(par1, par2, par3Icon.getMinU(), par3Icon.getMinV(), par3Icon.getMaxU(), par3Icon.getMaxV(), par4, par5); } - public static void drawSlicedRectFromIcon(int x, int y, int w, int h, Icon i, int tBord, int rBord, int bBord, int lBord) { + public static void drawSlicedRectFromIcon(int x, int y, int w, int h, IIcon i, int tBord, int rBord, int bBord, int lBord) { double dtBord = (double)tBord / (double)i.getIconHeight(); double dbBord = (double)bBord / (double)i.getIconHeight(); double drBord = (double)tBord / (double)i.getIconWidth(); diff --git a/src/main/java/ml/core/gui/MLGuiHandler.java b/src/main/java/ml/core/gui/MLGuiHandler.java index 0f60071..07c3f20 100644 --- a/src/main/java/ml/core/gui/MLGuiHandler.java +++ b/src/main/java/ml/core/gui/MLGuiHandler.java @@ -19,6 +19,8 @@ public Object getServerGuiElement(int ID, EntityPlayer player, World world, int return null; tel.initControls(); + tel.getContainer().initMissingHotbarSlots(); + tel.getContainer().checkPacketQueue(); return tel.getContainer(); } @@ -34,6 +36,9 @@ public Object getClientGuiElement(int ID, EntityPlayer player, World world, int return null; tel.initControls(); + tel.constructClient(); + tel.getContainer().initMissingHotbarSlots(); + tel.getContainer().checkPacketQueue(); tel.guiTick(); return tel.getGui(); diff --git a/src/main/java/ml/core/gui/controls/ControlTextInput.java b/src/main/java/ml/core/gui/controls/ControlTextInput.java index c5304e7..9566615 100644 --- a/src/main/java/ml/core/gui/controls/ControlTextInput.java +++ b/src/main/java/ml/core/gui/controls/ControlTextInput.java @@ -29,7 +29,7 @@ public ControlTextInput(GuiElement parent, Vector2i pos, Vector2i size) { } @Override - public void drawBackground() { + public void drawBackground(float partialTick) { //GL11.glTranslatef(getPosition().x, getPosition().y, 0); //TODO Render TB background textBox.drawTextBox(); diff --git a/src/main/java/ml/core/gui/controls/GuiControl.java b/src/main/java/ml/core/gui/controls/GuiControl.java index b4ef21f..a46f9c2 100644 --- a/src/main/java/ml/core/gui/controls/GuiControl.java +++ b/src/main/java/ml/core/gui/controls/GuiControl.java @@ -22,13 +22,13 @@ public GuiControl(GuiElement parent, Vector2i position, Vector2i size) { * When inheriting through GuiControl, the matrix will already be localized to your control's position */ @SideOnly(Side.CLIENT) - public void drawBackground() {} + public void drawBackground(float partialTick) {} /** * When inheriting through GuiControl, the matrix will already be localized to your control's position */ @SideOnly(Side.CLIENT) - public void drawOverlay() {} + public void drawOverlay(float partialTick) {} /** * Always make a super call or a call to drawChilds() as your last call. It will render children.
@@ -36,21 +36,22 @@ public void drawOverlay() {} * You can also just override draw[Background|Overlay]() instead */ @SideOnly(Side.CLIENT) - public void drawElement(RenderStage stage) { - GL11.glPushMatrix(); + public void drawElement(RenderStage stage, float partialTick) { GL11.glTranslatef(getLocalPosition().x, getLocalPosition().y, 0); + GL11.glPushMatrix(); switch (stage) { case Background: - drawBackground(); + drawBackground(partialTick); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + drawForeground(partialTick); break; - //case Foreground: - //drawForeground(); - //break; case Overlay: - drawOverlay(); + drawOverlay(partialTick); break; } GL11.glPopMatrix(); - drawChilds(stage); + GL11.glTranslatef(-getLocalPosition().x, -getLocalPosition().y, 0); + drawChilds(stage, partialTick); } } diff --git a/src/main/java/ml/core/gui/controls/box/ControlAutoSizedBox.java b/src/main/java/ml/core/gui/controls/box/ControlAutoSizedBox.java new file mode 100644 index 0000000..4bce7df --- /dev/null +++ b/src/main/java/ml/core/gui/controls/box/ControlAutoSizedBox.java @@ -0,0 +1,20 @@ +package ml.core.gui.controls.box; + +import ml.core.gui.core.GuiElement; +import ml.core.vec.Rectangle; +import ml.core.vec.Vector2i; + +public class ControlAutoSizedBox extends ControlCenteredBox { + + public ControlAutoSizedBox(GuiElement parent, Vector2i position, boolean centerHorizontal, boolean centerVertical) { + super(parent, position, new Vector2i(), centerHorizontal, centerVertical); + } + + @Override + public Vector2i getSize() { + Rectangle controlRect = calculateControlBox(); + return new Vector2i(controlRect.width + controlRect.xCoord*2, + controlRect.height + controlRect.yCoord*2); + } + +} diff --git a/src/main/java/ml/core/gui/controls/box/ControlBox.java b/src/main/java/ml/core/gui/controls/box/ControlBox.java new file mode 100644 index 0000000..b555e04 --- /dev/null +++ b/src/main/java/ml/core/gui/controls/box/ControlBox.java @@ -0,0 +1,20 @@ +package ml.core.gui.controls.box; + +import ml.core.gui.GuiRenderUtils; +import ml.core.gui.controls.GuiControl; +import ml.core.gui.core.GuiElement; +import ml.core.vec.Vector2i; + +public class ControlBox extends GuiControl { + + public int backgroundColor = 0x44000000; + + public ControlBox(GuiElement parent, Vector2i position, Vector2i size) { + super(parent, position, size); + } + + @Override + public void drawBackground(float partialTick) { + GuiRenderUtils.drawGradientRect(0, 0, getSize().x, getSize().y, backgroundColor, backgroundColor); + } +} diff --git a/src/main/java/ml/core/gui/controls/box/ControlCenteredBox.java b/src/main/java/ml/core/gui/controls/box/ControlCenteredBox.java new file mode 100644 index 0000000..387fe71 --- /dev/null +++ b/src/main/java/ml/core/gui/controls/box/ControlCenteredBox.java @@ -0,0 +1,25 @@ +package ml.core.gui.controls.box; + +import ml.core.gui.core.GuiElement; +import ml.core.vec.Vector2i; + +public class ControlCenteredBox extends ControlBox { + + public boolean centerHorizontal, centerVertical; + + public ControlCenteredBox(GuiElement parent, Vector2i position, Vector2i size, boolean centerHorizontal, boolean centerVertical) { + super(parent, position, size); + this.centerHorizontal = centerHorizontal; + this.centerVertical = centerVertical; + } + + public ControlCenteredBox(GuiElement parent, Vector2i position, Vector2i size) { + this(parent, position, size, true, true); + } + + @Override + public Vector2i getLocalPosition() { + return new Vector2i(centerHorizontal ? (getParent().getSize().x - getSize().x) / 2 : super.getLocalPosition().x, centerVertical ? (getParent().getSize().y - getSize().y) / 2 : super.getLocalPosition().y); + } + +} diff --git a/src/main/java/ml/core/gui/controls/button/ControlButton.java b/src/main/java/ml/core/gui/controls/button/ControlButton.java index 802e2d0..af6521b 100644 --- a/src/main/java/ml/core/gui/controls/button/ControlButton.java +++ b/src/main/java/ml/core/gui/controls/button/ControlButton.java @@ -19,7 +19,7 @@ public ControlButton(GuiElement par, Vector2i pos, Vector2i size, String t) { } @Override - public void drawBackground() { + public void drawBackground(float partialTick) { bindStyleTexture("button"); int p = enabled ? (hasHover() ? 40 : 20) : 0; GuiRenderUtils.drawSlicedRect(0, 0, getSize().x, getSize().y, 0, p, 200, 20, 2, 2, 2, 2, 200, 80); diff --git a/src/main/java/ml/core/gui/controls/inventory/ControlMultiSlotBase.java b/src/main/java/ml/core/gui/controls/inventory/ControlMultiSlotBase.java index d533108..0dfa6b6 100644 --- a/src/main/java/ml/core/gui/controls/inventory/ControlMultiSlotBase.java +++ b/src/main/java/ml/core/gui/controls/inventory/ControlMultiSlotBase.java @@ -28,7 +28,7 @@ public void addSlot(Slot slot) { * Override this to create non-standard ControlSlots. */ protected ControlSlot makeControlSlot(Slot slot) { - return new ControlSlot(this, slot, new Vector2i(slot.xDisplayPosition, slot.yDisplayPosition), new Vector2i(18,18)); + return new ControlSlot(this, slot); } public List getMergeTargets(ItemStack is) { diff --git a/src/main/java/ml/core/gui/controls/inventory/ControlSlot.java b/src/main/java/ml/core/gui/controls/inventory/ControlSlot.java index 592fdf1..17e1a6c 100644 --- a/src/main/java/ml/core/gui/controls/inventory/ControlSlot.java +++ b/src/main/java/ml/core/gui/controls/inventory/ControlSlot.java @@ -30,9 +30,17 @@ public ControlSlot(GuiElement par, Slot slt, Vector2i pos, Vector2i size) { ((MLSlot)slot).controlSlot = this; getTopParent().getContainer().addSlotToContainer(slt); } + + public ControlSlot(GuiElement par, Slot slt, Vector2i size) { + this(par, slt, new Vector2i(slt.xDisplayPosition, slt.yDisplayPosition), size); + } + public ControlSlot(GuiElement par, Slot slt) { + this(par, slt, new Vector2i(slt.xDisplayPosition, slt.yDisplayPosition), new Vector2i(18, 18)); + } + @Override - public void drawBackground() { + public void drawBackground(float partialTick) { GL11.glScalef((float)getSize().x/18F, (float)getSize().y/18F, 1F); if (renderBackground) { @@ -53,9 +61,14 @@ public void drawBackground() { GuiRenderUtils.drawGradientRect(1, 1, 1 + 16, 1 + 16, hoverColor, hoverColor); } - super.drawBackground(); + super.drawBackground(partialTick); } + @Override + public void drawTooltip(int mX, int mY, float partialTick) { // Leaving this native so we don't conflict with NEI + //getGui().drawSpecialItemStackTooltip(slot.getStack(), mX, mY); + } + @Override public void guiTick() { Vector2i abPos = getGlobalPosition().minus(getTopParent().getLocalPosition()); diff --git a/src/main/java/ml/core/gui/controls/inventory/ControlSlotGrid.java b/src/main/java/ml/core/gui/controls/inventory/ControlSlotGrid.java index cdc7089..96740d4 100644 --- a/src/main/java/ml/core/gui/controls/inventory/ControlSlotGrid.java +++ b/src/main/java/ml/core/gui/controls/inventory/ControlSlotGrid.java @@ -49,6 +49,7 @@ protected Vector2i positionSlot(int idx) { return new Vector2i((idx%rowLength)*18, idx/rowLength*18); } + @Override protected ControlSlot makeControlSlot(Slot slot) { return new ControlSlot(this, slot, positionSlot(slots.size()), new Vector2i(18,18)); } diff --git a/src/main/java/ml/core/gui/controls/tabs/ControlTabManager.java b/src/main/java/ml/core/gui/controls/tabs/ControlTabManager.java index 6de26b0..a611554 100644 --- a/src/main/java/ml/core/gui/controls/tabs/ControlTabManager.java +++ b/src/main/java/ml/core/gui/controls/tabs/ControlTabManager.java @@ -27,7 +27,7 @@ public abstract static class GuiTab extends GuiElement { public ControlTabManager TabManager; public static final int defaultSize = 24; - public int sizingSpeed = 8; + public int sizingSpeed = 32; public GuiTab(ControlTabManager ctm) { super(ctm); @@ -35,6 +35,12 @@ public GuiTab(ControlTabManager ctm) { setSize(new Vector2i(defaultSize, defaultSize)); } + @Override + public void constructClient() { + setSize(getTargetSize()); + super.constructClient(); + } + public int tabColor = 0x3590FF; @Override @@ -42,6 +48,7 @@ public void guiTick() { super.guiTick(); Vector2i trg = getTargetSize(); + lastSize = new Vector2i(getSize()); getSize().x = Math.abs(getSize().x-trg.x) < sizingSpeed ? trg.x : getSize().x + (getSize().x > trg.x ? -sizingSpeed : sizingSpeed); getSize().y = Math.abs(getSize().y-trg.y) < sizingSpeed ? trg.y : getSize().y + (getSize().y > trg.y ? -sizingSpeed : sizingSpeed); } @@ -56,8 +63,9 @@ public Vector2i getLocalPosition() { return new Vector2i(tb.xCoord, tb.yCoord); } + private Vector2i lastSize = new Vector2i(); @Override - public void drawBackground() { + public void drawBackground(float partialTick) { getLocalPosition().glTranslate(); float red = ((tabColor >> 16) & 0xFF) /255F; float green = ((tabColor >> 8) & 0xFF) /255F; @@ -65,23 +73,26 @@ public void drawBackground() { GL11.glColor4f(red, green, blue, 1.0F); bindTexture(getStyle().getResource("ledger")); - + + int sizeX = lastSize.x + (int)((getSize().x - lastSize.x) * partialTick); + int sizeY = lastSize.y + (int)((getSize().y - lastSize.y) * partialTick); + switch (TabManager.side){ case Left: - GuiRenderUtils.drawTexturedModalRect(0, 0, 0, 0, this.getSize().x, this.getSize().y-4); - GuiRenderUtils.drawTexturedModalRect(0, 4, 0, 256-this.getSize().y+4, this.getSize().x, this.getSize().y-4); + GuiRenderUtils.drawTexturedModalRect(0, 0, 0, 0, sizeX, sizeY-4); + GuiRenderUtils.drawTexturedModalRect(0, 4, 0, 256-sizeY+4, sizeX, sizeY-4); break; case Right: - GuiRenderUtils.drawTexturedModalRect(0, 0, 256-this.getSize().x, 0, this.getSize().x, this.getSize().y-4); - GuiRenderUtils.drawTexturedModalRect(0, 4, 256-this.getSize().x, 256-this.getSize().y+4, this.getSize().x, this.getSize().y-4); + GuiRenderUtils.drawTexturedModalRect(0, 0, 256-sizeX, 0, sizeX, sizeY-4); + GuiRenderUtils.drawTexturedModalRect(0, 4, 256-sizeX, 256-sizeY+4, sizeX, sizeY-4); break; case Top: - GuiRenderUtils.drawTexturedModalRect(0, 0, 0, 0, this.getSize().x-4, this.getSize().y); - GuiRenderUtils.drawTexturedModalRect(4, 0, 256-this.getSize().x+4, 0, this.getSize().x-4, this.getSize().y); + GuiRenderUtils.drawTexturedModalRect(0, 0, 0, 0, sizeX-4, sizeY); + GuiRenderUtils.drawTexturedModalRect(4, 0, 256-sizeX+4, 0, sizeX-4, sizeY); break; case Bottom: - GuiRenderUtils.drawTexturedModalRect(0, 0, 0, 256-this.getSize().y, this.getSize().x-4, this.getSize().y); - GuiRenderUtils.drawTexturedModalRect(4, 0, 256-this.getSize().x+4, 256-this.getSize().y, this.getSize().x-4, this.getSize().y); + GuiRenderUtils.drawTexturedModalRect(0, 0, 0, 256-sizeY, sizeX-4, sizeY); + GuiRenderUtils.drawTexturedModalRect(4, 0, 256-sizeX+4, 256-sizeY, sizeX-4, sizeY); break; } GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); diff --git a/src/main/java/ml/core/gui/controls/tabs/TabDynamicLedger.java b/src/main/java/ml/core/gui/controls/tabs/TabDynamicLedger.java new file mode 100644 index 0000000..6883439 --- /dev/null +++ b/src/main/java/ml/core/gui/controls/tabs/TabDynamicLedger.java @@ -0,0 +1,20 @@ +package ml.core.gui.controls.tabs; + +import net.minecraft.client.gui.FontRenderer; +import ml.core.vec.Rectangle; +import ml.core.vec.Vector2i; + +public abstract class TabDynamicLedger extends TabLedger { + + public TabDynamicLedger(ControlTabManager ctm) { + super(ctm, new Vector2i()); + } + + @Override + public Vector2i getOpenSize() { + Rectangle controlRect = calculateControlBox(); + FontRenderer fr = getMC().fontRenderer; + return new Vector2i(Math.max(controlRect.width + controlRect.xCoord*2, 24 + fr.getStringWidth(getTitle())+8), + controlRect.yCoord + controlRect.height + (controlRect.yCoord - defaultSize + 8)); + } +} diff --git a/src/main/java/ml/core/gui/controls/tabs/TabLedger.java b/src/main/java/ml/core/gui/controls/tabs/TabLedger.java index e427b7b..9e6cbe8 100644 --- a/src/main/java/ml/core/gui/controls/tabs/TabLedger.java +++ b/src/main/java/ml/core/gui/controls/tabs/TabLedger.java @@ -1,33 +1,46 @@ package ml.core.gui.controls.tabs; +import java.util.ArrayList; +import java.util.List; + import ml.core.enums.MouseButton; import ml.core.gui.controls.tabs.ControlTabManager.GuiTab; +import ml.core.gui.core.GuiElement; import ml.core.gui.event.GuiEvent; import ml.core.gui.event.mouse.EventMouseDown; import ml.core.vec.Vector2i; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.gui.FontRenderer; -@SideOnly(Side.CLIENT) public abstract class TabLedger extends GuiTab { protected boolean openState = false; + public String title = ""; public Vector2i openSize; public Vector2i closeSize; - public int sizingSpeed = 8; - public TabLedger(ControlTabManager ctm, Vector2i oSize) { super(ctm); - closeSize = new Vector2i(defaultSize, defaultSize); + this.closeSize = new Vector2i(defaultSize, defaultSize); setSize(closeSize.copy()); openSize = oSize.copy(); } + public String getTitle() { + return title; + } + + public Vector2i getOpenSize() { + return openSize; + } + + public Vector2i getCloseSize() { + return closeSize; + } + @Override public Vector2i getTargetSize() { - return openState ? openSize : closeSize; + return (openState ? getOpenSize() : getCloseSize()).copy(); } public void openLedger() { @@ -42,6 +55,33 @@ public void openLedger() { public void closeLedger() { openState = false; } + + @Override + public void drawForeground(float partialTick) { + super.drawForeground(partialTick); + getLocalPosition().glTranslate(); + if (isFullyOpen()) { + FontRenderer fr = getMC().fontRenderer; + fr.drawString(getTitle(), 24, (24-fr.FONT_HEIGHT)/2+1, 0xFFFFFF, true); + } + } + + @Override + public void drawTooltip(int mX, int mY, float partialTick) { + if (openState) return; + List lines = new ArrayList(); + lines.add(getTitle()); + getGui().drawHoveringText(lines, mX, mY, getMC().fontRenderer); + } + + @Override + public boolean isChildVisible(GuiElement elm) { + return isFullyOpen() && super.isChildVisible(elm); + } + + public boolean isFullyOpen() { + return openState && getSize().equals(getTargetSize()); + } @Override public void handleEvent(GuiEvent evt) { diff --git a/src/main/java/ml/core/gui/core/DummyInventory.java b/src/main/java/ml/core/gui/core/DummyInventory.java new file mode 100644 index 0000000..8caf109 --- /dev/null +++ b/src/main/java/ml/core/gui/core/DummyInventory.java @@ -0,0 +1,115 @@ +package ml.core.gui.core; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +public class DummyInventory implements IInventory { + + protected ItemStack[] stacks; + private int nextId = 0; + + public DummyInventory(int size) { + stacks = new ItemStack[size]; + } + + /** + * DO NOT call this dynamically with variables. The server and client must be in sync. + * @return The next slot that hasn't been reserved in this inventory. + */ + public int getNextSlot() { + return nextId++; + } + + @Override + public int getSizeInventory() { + return stacks.length; + } + + @Override + public ItemStack getStackInSlot(int i) { + return stacks[i]; + } + + @Override + public ItemStack decrStackSize(int i, int j) { + if (this.stacks[i] != null) { + ItemStack itemstack; + + if (this.stacks[i].stackSize <= j) { + itemstack = this.stacks[i]; + this.stacks[i] = null; + return itemstack; + } else { + itemstack = this.stacks[i].splitStack(j); + + if (this.stacks[i].stackSize == 0) { + this.stacks[i] = null; + } + + return itemstack; + } + } else { + return null; + } + } + + @Override + public ItemStack getStackInSlotOnClosing(int i) { + if (this.stacks[i] != null) { + ItemStack itemstack = this.stacks[i]; + this.stacks[i] = null; + return itemstack; + } else { + return null; + } + } + + public void dumpItems(EntityPlayer epl) { + for (ItemStack is : stacks) { + if (is != null) { + epl.dropPlayerItemWithRandomChoice(is, true); + } + } + } + + @Override + public void setInventorySlotContents(int i, ItemStack itemstack) { + stacks[i] = itemstack; + } + + @Override + public int getInventoryStackLimit() { + return 64; + } + + @Override + public boolean isUseableByPlayer(EntityPlayer entityplayer) { + return true; + } + + @Override + public boolean isItemValidForSlot(int i, ItemStack itemstack) { + return true; + } + + @Override + public String getInventoryName() { + return "Gui"; + } + + @Override + public boolean hasCustomInventoryName() { + return false; + } + + @Override + public void markDirty() {} + + @Override + public void openInventory() {} + + @Override + public void closeInventory() {} + +} diff --git a/src/main/java/ml/core/gui/core/GuiElement.java b/src/main/java/ml/core/gui/core/GuiElement.java index b32f2bd..27c35e0 100644 --- a/src/main/java/ml/core/gui/core/GuiElement.java +++ b/src/main/java/ml/core/gui/core/GuiElement.java @@ -9,6 +9,7 @@ import ml.core.gui.event.GuiEvent; import ml.core.vec.Rectangle; import ml.core.vec.Vector2i; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraft.util.ResourceLocation; @@ -23,6 +24,7 @@ public abstract class GuiElement { protected List childObjects = new ArrayList(); private Vector2i position; private Vector2i size; + private boolean visible = true; /** * Use {@link GuiElement#getStyle()} for getting. It checks for null and defaults to the parent. @@ -37,6 +39,12 @@ public GuiElement(GuiElement parent) { setSize(new Vector2i()); } + @SideOnly(Side.CLIENT) + public void constructClient() { + for (GuiElement elm : childObjects) { + elm.constructClient(); + } + } // ------------------------ Tree Model ------------------------ // public void clearChildren() { @@ -105,6 +113,20 @@ public boolean isDescendant(GuiElement des) { public Side getSide() { return getTopParent().getSide(); } + + // ------------------------ Visibility Stuff ------------------------ // + + public void setVisibility(boolean visible) { + this.visible = visible; + } + + public boolean isVisible() { + return this.visible; + } + + public boolean isChildVisible(GuiElement elm) { + return elm.isVisible() && ((getParent() != null && getParent().isChildVisible(this)) || isTopParentElem()); + } // ------------------------ Size Stuff ------------------------ // public Vector2i getSize() { return size; } @@ -117,6 +139,19 @@ public void setSize(int w, int h) { setSize(new Vector2i(w, h)); } + public Rectangle calculateControlBox() { + int minx=Integer.MAX_VALUE, miny=Integer.MAX_VALUE, maxw=0, maxh=0; + + for (GuiElement elm : childObjects) { + minx = Math.min(minx, elm.getLocalPosition().x); + miny = Math.min(miny, elm.getLocalPosition().y); + maxw = Math.max(maxw, elm.getSize().x); + maxh = Math.max(maxh, elm.getSize().y); + } + + return new Rectangle(minx, miny, maxw, maxh); + } + // ------------------------ Position Stuff ------------------------ // public Vector2i getLocalPosition() { return position; @@ -190,7 +225,7 @@ public void onReceiveEvent(GuiEvent evt) { public GuiElement findElementAtLocal(Vector2i pos) { for (GuiElement el : childObjects) { - if (el.pointInElement(pos)) { + if (isChildVisible(el) && el.pointInElement(pos)) { GuiElement sel = el.findElementAtLocal(pos.copy().minus(el.getLocalPosition())); if (sel != null) return sel; @@ -273,60 +308,69 @@ protected void bindTexture(ResourceLocation res) { /** * Your matrix will be localized to the parent element, so you need to shift by your local position. + * @param partialTick TODO */ @SideOnly(Side.CLIENT) - public void drawBackground() {} + public void drawBackground(float partialTick) {} /** * Your matrix will be localized to the parent element, so you need to shift by your local position. + * @param partialTick TODO */ - //@SideOnly(Side.CLIENT) - //public void drawForeground() {} + @SideOnly(Side.CLIENT) + public void drawForeground(float partialTick) {} /** * Your matrix will be localized to the parent element, so you need to shift by your local position. + * @param partialTick TODO */ @SideOnly(Side.CLIENT) - public void drawOverlay() {} + public void drawOverlay(float partialTick) {} + + @SideOnly(Side.CLIENT) + public void drawTooltip(int mX, int mY, float partialTick) {} /** * Always make a super call or a call to drawChilds() as your last call. It will render children.
* Your matrix will be localized to the parent element, so you need to shift by your local position.
* You can also just override draw[Background|Overlay]() instead + * @param partialTick TODO */ @SideOnly(Side.CLIENT) - public void drawElement(RenderStage stage) { + public void drawElement(RenderStage stage, float partialTick) { GL11.glPushMatrix(); switch (stage) { case Background: - drawBackground(); + drawBackground(partialTick); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + drawForeground(partialTick); break; - //case Foreground: - //drawForeground(); - //break; case Overlay: - drawOverlay(); + drawOverlay(partialTick); break; } GL11.glPopMatrix(); - drawChilds(stage); + drawChilds(stage, partialTick); } /** * Called to draw children of the element. Automatically called if you don't - * override {@link #drawElement(RenderStage)} or if you include a super call in your overriding method + * override {@link #drawElement(RenderStage, float)} or if you include a super call in your overriding method * @param stage */ @SideOnly(Side.CLIENT) - protected void drawChilds(RenderStage stage) { + protected void drawChilds(RenderStage stage, float partialTick) { Vector2i pos = getLocalPosition(); GL11.glPushMatrix(); GL11.glTranslatef(pos.x, pos.y, 0.0F); for (GuiElement el : childObjects) { - GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - GL11.glDisable(GL11.GL_LIGHTING); - - el.drawElement(stage); + if (isChildVisible(el)) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(GL11.GL_LIGHTING); + + el.drawElement(stage, partialTick); + } } GL11.glPopMatrix(); } @@ -360,7 +404,8 @@ public void setStyle(GuiStyle stl) { @SideOnly(Side.CLIENT) public void setCustomResource(String feat, String npath) { if (!(this.style instanceof GuiStyleManip)) - this.style = new GuiStyleManip(style); + this.style = new GuiStyleManip(getStyle()); + ((GuiStyleManip)style).addResourceOverride(feat, npath); } @@ -381,10 +426,14 @@ public MLGuiClient getGui() { return getParent().getGui(); } + @SideOnly(Side.CLIENT) + public Minecraft getMC() { + return getGui().getMinecraft(); + } + @SideOnly(Side.CLIENT) public static enum RenderStage { Background, - //Foreground, Overlay, SlotInventory; } diff --git a/src/main/java/ml/core/gui/core/MLContainer.java b/src/main/java/ml/core/gui/core/MLContainer.java index 1b5022a..cc74420 100644 --- a/src/main/java/ml/core/gui/core/MLContainer.java +++ b/src/main/java/ml/core/gui/core/MLContainer.java @@ -1,9 +1,12 @@ package ml.core.gui.core; +import java.util.Iterator; + import ml.core.gui.event.EventDataPacketReceived; import ml.core.gui.event.EventGuiClosing; import ml.core.internal.PacketContainerData; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; @@ -43,6 +46,22 @@ public void handleDataPacket(NBTTagCompound pload, Side side) { priElemement.injectEvent(new EventDataPacketReceived(priElemement, pload, side)); // TODO Test this stuff } + /** + * If a data packet is sent right when a container is opened, it may be received early on the other side. + * In this case, it is queued and waits for construction to finish. This method checks the queue and processes and queued packets. + * There is no need to call this yourself. + */ + public final void checkPacketQueue() { + Iterator i = PacketContainerData.packetQ.get(priElemement.player).iterator(); + while (i.hasNext()) { + PacketContainerData pcd = i.next(); + if (pcd.winId == this.windowId) { + i.remove(); + handleDataPacket(pcd.payload, priElemement.side); + } + } + } + public void sendPacket(NBTTagCompound payload, Side sendTo) { Packet250CustomPayload pkt = new PacketContainerData(windowId, payload).convertToPkt250(); if (sendTo == Side.SERVER) { @@ -65,4 +84,13 @@ public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) { public Slot addSlotToContainer(Slot par1Slot) { return super.addSlotToContainer(par1Slot); } + + public void initMissingHotbarSlots() { + InventoryPlayer pli = priElemement.player.inventory; + for (int i=0; i<9; i++) { + if (getSlotFromInventory(pli, i) == null) { + addSlotToContainer(new Slot(pli, i, 0, 0)); + } + } + } } diff --git a/src/main/java/ml/core/gui/core/MLGuiClient.java b/src/main/java/ml/core/gui/core/MLGuiClient.java index d3e6a7c..9794d05 100644 --- a/src/main/java/ml/core/gui/core/MLGuiClient.java +++ b/src/main/java/ml/core/gui/core/MLGuiClient.java @@ -16,13 +16,19 @@ import ml.core.gui.event.mouse.EventMouseUp; import ml.core.vec.Vector2i; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.inventory.Slot; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; +import cpw.mods.fml.client.FMLClientHandler; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + // All this could be a lot cleaner, but that is the cost of trying to maintain universal compatibility with things such as NEI +@SideOnly(Side.CLIENT) public class MLGuiClient extends GuiContainer { protected TopParentGuiElement priElemement; @@ -38,7 +44,7 @@ public TopParentGuiElement getPrimaryElement() { private List eSlots = new ArrayList(); @Override - public void drawScreen(int mX, int mY, float par3) { + public void drawScreen(int mX, int mY, float partialTick) { if (mX != priElemement.gmousePos.x || mY != priElemement.gmousePos.y) { priElemement.injectEvent(new EventMouseMove(priElemement, new Vector2i(mX, mY).minus(priElemement.gmousePos))); priElemement.gmousePos.set(mX, mY); @@ -51,8 +57,12 @@ public void drawScreen(int mX, int mY, float par3) { priElemement.injectEvent(new EventMouseEntered(priElemement.hoverElement)); } } - super.drawScreen(mX, mY, par3); - matrixAndDraw(RenderStage.Overlay); + super.drawScreen(mX, mY, partialTick); + matrixAndDraw(RenderStage.Overlay, partialTick); + + if (priElemement.hoverElement != null) { + priElemement.hoverElement.drawTooltip(mX, mY, partialTick); + } } public void refreshSize() { @@ -78,21 +88,21 @@ public Slot getSlotAtPosition(int par1, int par2) { } /** - * Calls {@link TopParentGuiElement#drawElement(RenderStage)} wrapped in a new GL Matrix
+ * Calls {@link TopParentGuiElement#drawElement(RenderStage, float)} wrapped in a new GL Matrix
* Mostly just for DRY code * @param stage */ - private void matrixAndDraw(RenderStage stage) { + private void matrixAndDraw(RenderStage stage, float partialTick) { //GL11.glPushMatrix(); GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); GL11.glDisable(GL11.GL_LIGHTING); - priElemement.drawElement(stage); + priElemement.drawElement(stage, partialTick); //GL11.glPopMatrix(); } @Override protected void drawGuiContainerBackgroundLayer(float f, int i, int j) { - matrixAndDraw(RenderStage.Background); + matrixAndDraw(RenderStage.Background, f); } @Override @@ -110,7 +120,12 @@ public void drawSpecialSlotInventory(ControlSlot slt) { super.drawSlotInventory(slt.getSlot()); GL11.glPopMatrix(); } - + + @Override + public void drawHoveringText(List lines, int mX, int mY, FontRenderer font) { + super.drawHoveringText(lines, mX, mY, font); + } + private GuiElement mouseDownEl; private long mouseDownTime; @@ -166,6 +181,6 @@ public Vector2i getPosition() { } public Minecraft getMinecraft() { - return this.mc; + return this.mc != null ? this.mc : FMLClientHandler.instance().getClient(); } } diff --git a/src/main/java/ml/core/gui/core/SlotCycler.java b/src/main/java/ml/core/gui/core/SlotCycler.java index 0767b68..90dd02b 100644 --- a/src/main/java/ml/core/gui/core/SlotCycler.java +++ b/src/main/java/ml/core/gui/core/SlotCycler.java @@ -58,7 +58,7 @@ public boolean cycleSlot(ControlSlot cslot) { return cycleSlot(cslot.getSlot(), cslot); } - public boolean tryCycleSlot(Slot slot) { + public boolean cycleSlot(Slot slot) { if (slot instanceof MLSlot && ((MLSlot)slot).controlSlot != null) { ControlSlot cslot = ((MLSlot)slot).controlSlot; return cycleSlot(slot, cslot); diff --git a/src/main/java/ml/core/gui/core/TopParentGuiElement.java b/src/main/java/ml/core/gui/core/TopParentGuiElement.java index 2f5168a..2f193ba 100644 --- a/src/main/java/ml/core/gui/core/TopParentGuiElement.java +++ b/src/main/java/ml/core/gui/core/TopParentGuiElement.java @@ -1,6 +1,8 @@ package ml.core.gui.core; import ml.core.gui.core.style.GuiStyle; +import ml.core.gui.event.EventGuiClosing; +import ml.core.gui.event.GuiEvent; import ml.core.vec.Vector2i; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Slot; @@ -10,7 +12,7 @@ import cpw.mods.fml.relauncher.SideOnly; /** - * TopParentGuiObjects house all other GuiObjects in a Gui + * TopParentGuiObjects house all other GuiObjects in a Gui.
* May also be a child element * @author Matchlighter */ @@ -29,6 +31,11 @@ public abstract class TopParentGuiElement extends GuiElement { public GuiElement hoverElement; public GuiElement focusedElement; + + /** + * This inventory belongs to the gui. Any items will be dropped when it is closed. By default it can store 64 stacks. + */ + public DummyInventory guiInventory = new DummyInventory(64); public TopParentGuiElement(EntityPlayer epl, Side side) { super(null); @@ -93,6 +100,19 @@ public void sendPacket(NBTTagCompound payload) { } } + @Override + public void handleEvent(GuiEvent evt) { + if (evt instanceof EventGuiClosing && side == Side.SERVER) { + guiInventory.dumpItems(player); + } + + super.handleEvent(evt); + } + + public boolean shouldShowNEI() { + return true; + } + public abstract ItemStack transferStackFromSlot(EntityPlayer epl, Slot slot); public abstract void initControls(); diff --git a/src/main/java/ml/core/gui/core/Window.java b/src/main/java/ml/core/gui/core/Window.java index 4bd4011..5d59904 100644 --- a/src/main/java/ml/core/gui/core/Window.java +++ b/src/main/java/ml/core/gui/core/Window.java @@ -12,10 +12,10 @@ public Window(EntityPlayer epl, Side side) { } @Override - public void drawBackground() { + public void drawBackground(float partialTick) { bindStyleTexture("window"); GuiRenderUtils.drawSlicedRect(this.getLocalPosition().x, this.getLocalPosition().y, this.getSize().x, this.getSize().y, 0, 0, 256, 256, 6); - super.drawBackground(); + super.drawBackground(partialTick); } @Override @@ -27,10 +27,4 @@ public void close() { this.player.closeScreen(); } - public static enum WindowSide { - Top, - Right, - Bottom, - Left; - } } diff --git a/src/main/java/ml/core/gui/core/style/GuiStyle.java b/src/main/java/ml/core/gui/core/style/GuiStyle.java index aa3abba..76c28bd 100644 --- a/src/main/java/ml/core/gui/core/style/GuiStyle.java +++ b/src/main/java/ml/core/gui/core/style/GuiStyle.java @@ -6,10 +6,10 @@ import java.util.Map; import java.util.Properties; -import net.minecraft.client.resources.ReloadableResourceManager; -import net.minecraft.client.resources.Resource; -import net.minecraft.client.resources.ResourceManager; -import net.minecraft.client.resources.ResourceManagerReloadListener; +import net.minecraft.client.resources.IReloadableResourceManager; +import net.minecraft.client.resources.IResource; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.client.resources.IResourceManagerReloadListener; import net.minecraft.util.ResourceLocation; import cpw.mods.fml.client.FMLClientHandler; import cpw.mods.fml.relauncher.Side; @@ -29,7 +29,7 @@ * @author Matchlighter */ @SideOnly(Side.CLIENT) -public class GuiStyle implements ResourceManagerReloadListener { +public class GuiStyle implements IResourceManagerReloadListener { public static final String defaultDomain = "mlcontrols"; public static final String defaultBasePath = "default"; @@ -134,15 +134,15 @@ public void clearCache() { } @Override - public void onResourceManagerReload(ResourceManager resourcemanager) { + public void onResourceManagerReload(IResourceManager resourcemanager) { clearCache(); //Load Properties and Colors - ResourceManager rm = FMLClientHandler.instance().getClient().getResourceManager(); + IResourceManager rm = FMLClientHandler.instance().getClient().getResourceManager(); props.clear(); try { - List robjs = rm.getAllResources(getResourceManual("properties.txt")); //TODO 1.7.2: Make sure these load in the correct order - for (Resource res : robjs) { + List robjs = rm.getAllResources(getResourceManual("properties.txt")); //TODO 1.7.2: Make sure these load in the correct order + for (IResource res : robjs) { props.load(res.getInputStream()); } } catch (IOException e) { @@ -151,7 +151,7 @@ public void onResourceManagerReload(ResourceManager resourcemanager) { } public void registerAsReloadListener() { - ((ReloadableResourceManager)FMLClientHandler.instance().getClient().getResourceManager()).registerReloadListener(this); + ((IReloadableResourceManager)FMLClientHandler.instance().getClient().getResourceManager()).registerReloadListener(this); } } diff --git a/src/main/java/ml/core/gui/core/style/GuiStyleManip.java b/src/main/java/ml/core/gui/core/style/GuiStyleManip.java index b43232f..8da2ad5 100644 --- a/src/main/java/ml/core/gui/core/style/GuiStyleManip.java +++ b/src/main/java/ml/core/gui/core/style/GuiStyleManip.java @@ -42,7 +42,7 @@ public void addColorOverride(String ident, String color) { @Override protected ResourceLocation findResource(String feat) { if (resOverrides.containsKey(feat)) - return new ResourceLocation(resOverrides.get(feat)); + return new ResourceLocation(resOverrides.get(feat)+".png"); return parentStyle.findResource(feat); } diff --git a/src/main/java/ml/core/internal/PacketContainerData.java b/src/main/java/ml/core/internal/PacketContainerData.java index f5319b0..5b67910 100644 --- a/src/main/java/ml/core/internal/PacketContainerData.java +++ b/src/main/java/ml/core/internal/PacketContainerData.java @@ -1,23 +1,27 @@ package ml.core.internal; import java.io.IOException; +import java.util.Iterator; import ml.core.gui.core.MLContainer; import ml.core.network.MLPacket; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; +import com.google.common.collect.LinkedListMultimap; import com.google.common.io.ByteArrayDataInput; import cpw.mods.fml.relauncher.Side; public class PacketContainerData extends MLPacket { + public static final LinkedListMultimap packetQ = LinkedListMultimap.create(); + public @data int winId; public @data NBTTagCompound payload; public PacketContainerData(EntityPlayer pl, ByteArrayDataInput dataIn) { - super(pl, dataIn); + super(dataIn); } public PacketContainerData(int windowId, NBTTagCompound payload) { @@ -27,9 +31,26 @@ public PacketContainerData(int windowId, NBTTagCompound payload) { } @Override + public void handleClientSide(EntityPlayer epl) throws IOException { + handle(epl, Side.CLIENT); + } + + @Override + public void handleServerSide(EntityPlayer epl) throws IOException { + handle(epl, Side.SERVER); + } + public void handle(EntityPlayer epl, Side side) throws IOException { if (epl.openContainer instanceof MLContainer && epl.openContainer.windowId == winId) { ((MLContainer)epl.openContainer).handleDataPacket(payload, side); + } else { + packetQ.put(epl, this); + Iterator i = packetQ.values().iterator(); + while (i.hasNext()) { + if (i.next().winId != this.winId) { + i.remove(); + } + } } } } diff --git a/src/main/java/ml/core/internal/PacketHandler.java b/src/main/java/ml/core/internal/PacketHandler.java index ff3e5e2..f43c8d0 100644 --- a/src/main/java/ml/core/internal/PacketHandler.java +++ b/src/main/java/ml/core/internal/PacketHandler.java @@ -6,6 +6,7 @@ public final class PacketHandler extends ml.core.network.PacketHandler { public static final String defChan = "MLCore"; public PacketHandler() { + super(defChan); addHandler(PacketContainerData.class); } diff --git a/src/main/java/ml/core/inventory/CustomSlotClick.java b/src/main/java/ml/core/inventory/CustomSlotClick.java index 0b6b034..11dc19b 100644 --- a/src/main/java/ml/core/inventory/CustomSlotClick.java +++ b/src/main/java/ml/core/inventory/CustomSlotClick.java @@ -123,12 +123,12 @@ public ItemStack slotClick(int slotNum, int arg, int action, EntityPlayer par4En if (slotNum == -999) { if (inventoryplayer.getItemStack() != null && slotNum == -999) { if (arg == 0) { - par4EntityPlayer.dropPlayerItem(inventoryplayer.getItemStack()); + par4EntityPlayer.dropPlayerItemWithRandomChoice(inventoryplayer.getItemStack(), true); inventoryplayer.setItemStack((ItemStack)null); } if (arg == 1) { - par4EntityPlayer.dropPlayerItem(inventoryplayer.getItemStack().splitStack(1)); + par4EntityPlayer.dropPlayerItemWithRandomChoice(inventoryplayer.getItemStack().splitStack(1), true); if (inventoryplayer.getItemStack().stackSize == 0) { inventoryplayer.setItemStack((ItemStack)null); @@ -284,7 +284,7 @@ public ItemStack slotClick(int slotNum, int arg, int action, EntityPlayer par4En if (slot2 != null && slot2.getHasStack()) { itemstack1 = slot2.decrStackSize(arg == 0 ? 1 : slot2.getStack().stackSize); slot2.onPickupFromSlot(par4EntityPlayer, itemstack1); - par4EntityPlayer.dropPlayerItem(itemstack1); + par4EntityPlayer.dropPlayerItemWithRandomChoice(itemstack1, true); } } else if (action == 6 && slotNum >= 0) { slot2 = this.inventorySlots.get(slotNum); diff --git a/src/main/java/ml/core/item/DelegateItem.java b/src/main/java/ml/core/item/DelegateItem.java new file mode 100644 index 0000000..051cec1 --- /dev/null +++ b/src/main/java/ml/core/item/DelegateItem.java @@ -0,0 +1,138 @@ +package ml.core.item; + +import java.util.List; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + + + +public class DelegateItem { + + protected int metaId; + protected ItemDelegator parent; + protected String unlocalizedName; + + @SideOnly(Side.CLIENT) + protected IIcon itemIcon; + protected String iconLocation; + + public DelegateItem() {} + + public DelegateItem setIconString(String str) { + this.iconLocation = str; + return this; + } + + public DelegateItem setUnlocalizedName(String str) { + this.unlocalizedName = str; + return this; + } + + public ItemDelegator parent() { + return parent; + } + + public int getMetaId() { + return metaId; + } + + public ItemStack createStack(int size) { + return new ItemStack(parent(), size, getMetaId()); + } + + /* ---------------------------- ItemMethods ---------------------------- */ + + @SideOnly(Side.CLIENT) + public void addCreativeStacks(CreativeTabs ctab, List stackList) { + stackList.add(new ItemStack(parent(), 1, getMetaId())); + } + + public String getUnlocalizedName(ItemStack stack) { + return unlocalizedName; + } + + /** + * Return null for default implementation + */ + public String getItemDisplayName(ItemStack stack) { + return null; + } + + public EnumRarity getRarity(ItemStack stack) { + return EnumRarity.common; + } + + public ItemStack getContainerItemStack(ItemStack itemStack) { + return null; + } + + public int getDamage(ItemStack stack) { + return 0; + } + + public int getMaxDamage(ItemStack stack) { + return 0; + } + + public boolean isDamageable(ItemStack stack) { + return false; + } + + public void onUpdate(ItemStack stack, World par2World, Entity par3Entity, int par4, boolean par5) {} + + /* ---------------------------- Events ---------------------------- */ + + public boolean onItemUseFirst(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) { + return false; + } + + public boolean onItemUse(ItemStack stack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + return false; + } + + public ItemStack onItemRightClick(ItemStack stack, World par2World, EntityPlayer par3EntityPlayer) { + return stack; + } + + /* ---------------------------- ClientSide ---------------------------- */ + + public int getColorFromItemStack(ItemStack stack, int par2) { + return 16777215; + } + + @SideOnly(Side.CLIENT) + public IIcon getIcon(int meta) { + return itemIcon; + } + + @SideOnly(Side.CLIENT) + public IIcon getIcon(ItemStack stack, int pass) { + return getIcon(stack.getItemDamage()); + } + + @SideOnly(Side.CLIENT) + public IIcon getIconInHand(ItemStack stack, int renderPass, EntityPlayer player, ItemStack usingItem, int useRemaining) { + return getIcon(stack, renderPass); + } + + @SideOnly(Side.CLIENT) + public boolean hasEffect(ItemStack stack, int pass) { + return false; + } + + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister ireg) { + this.itemIcon = ireg.registerIcon(iconLocation); + } + + public void addInformation(ItemStack stack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) {} +} diff --git a/src/main/java/ml/core/item/ItemDelegator.java b/src/main/java/ml/core/item/ItemDelegator.java new file mode 100644 index 0000000..f12f7d4 --- /dev/null +++ b/src/main/java/ml/core/item/ItemDelegator.java @@ -0,0 +1,181 @@ +package ml.core.item; + +import java.util.List; + +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +public class ItemDelegator extends Item { + + private BiMap subItems = HashBiMap.create(); + + protected DCls nullDelegate; + + public ItemDelegator(DCls nullDelegate) { + setHasSubtypes(true); + this.nullDelegate = nullDelegate; + this.nullDelegate.parent = this; + } + + public ItemStack createStack(DCls subItem, int size) { + return new ItemStack(this, size, subItem.getMetaId()); + } + + /* ---------------------------- SubItems ---------------------------- */ + + public boolean addSubItem(int metaData, DCls sub) { + if (subItems.containsKey(metaData) || subItems.containsValue(sub)) return false; + subItems.put(metaData, sub); + sub.parent = this; + sub.metaId = metaData; + return true; + } + + public DCls subItem(int metaData) { + if (subItems.containsKey(metaData)) return subItems.get(metaData); + return nullDelegate; + } + + public DCls subItem(ItemStack is) { + if (is != null && is.getItem() == this) { + return subItem(is.getItemDamage()); + } + return nullDelegate; + } + + public static DelegateItem findSubItem(ItemStack is) { + if (is != null && is.getItem() instanceof ItemDelegator) { + ItemDelegator idg = (ItemDelegator) is.getItem(); + return idg.subItem(is.getItemDamage()); + } + return null; + } + + /* ---------------------------- ItemMethods ---------------------------- */ + + @Override + @SideOnly(Side.CLIENT) + public void getSubItems(Item par1, CreativeTabs par2CreativeTabs, List par3List) { + for (DCls sub : subItems.values()) { + sub.addCreativeStacks(par2CreativeTabs, par3List); + } + } + + @Override + public String getUnlocalizedName(ItemStack par1ItemStack) { + return "item."+subItem(par1ItemStack).getUnlocalizedName(par1ItemStack); + } + + @Override + public String getItemDisplayName(ItemStack par1ItemStack) { + String name = subItem(par1ItemStack).getItemDisplayName(par1ItemStack); + return name != null ? name : super.getItemDisplayName(par1ItemStack); + } + + @Override + public EnumRarity getRarity(ItemStack par1ItemStack) { + return subItem(par1ItemStack).getRarity(par1ItemStack); + } + + @Override + public ItemStack getContainerItemStack(ItemStack itemStack) { + return subItem(itemStack).getContainerItemStack(itemStack); + } + + @Override + public int getDisplayDamage(ItemStack stack) { + DCls sub = subItem(stack); + return sub.isDamageable(stack) ? sub.getDamage(stack) : 0; + } + + @Override + public int getMaxDamage(ItemStack stack) { + DCls sub = subItem(stack); + return sub.isDamageable(stack) ? sub.getMaxDamage(stack) : 0; + } + + @Override + public boolean isDamaged(ItemStack stack) { + DCls sub = subItem(stack); + return sub.isDamageable(stack) ? sub.getDamage(stack) > 0 : false; + } + + @Override + public void onUpdate(ItemStack par1ItemStack, World par2World, Entity par3Entity, int par4, boolean par5) { + subItem(par1ItemStack).onUpdate(par1ItemStack, par2World, par3Entity, par4, par5); + } + + /* ---------------------------- Events ---------------------------- */ + + @Override + public boolean onItemUseFirst(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) { + return subItem(stack).onItemUseFirst(stack, player, world, x, y, z, side, hitX, hitY, hitZ); + } + + @Override + public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { + return subItem(par1ItemStack).onItemUse(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7, par8, par9, par10); + } + + @Override + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) { + return subItem(par1ItemStack).onItemRightClick(par1ItemStack, par2World, par3EntityPlayer); + } + + /* ---------------------------- ClientSide ---------------------------- */ + + @Override + @SideOnly(Side.CLIENT) + public int getColorFromItemStack(ItemStack par1ItemStack, int par2) { + return subItem(par1ItemStack).getColorFromItemStack(par1ItemStack, par2); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIconFromDamage(int par1) { + return subItem(par1).getIcon(par1); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(ItemStack stack, int pass) { + return subItem(stack).getIcon(stack, pass); + } + + @Override + @SideOnly(Side.CLIENT) + public IIcon getIcon(ItemStack stack, int renderPass, EntityPlayer player, ItemStack usingItem, int useRemaining) { + return subItem(stack).getIconInHand(stack, renderPass, player, usingItem, useRemaining); + } + + @SideOnly(Side.CLIENT) + public boolean hasEffect(ItemStack stack, int pass) { + return subItem(stack).hasEffect(stack, pass); + } + + @Override + @SideOnly(Side.CLIENT) + public void registerIcons(IIconRegister par1IconRegister) { + for (DCls sub : subItems.values()) sub.registerIcons(par1IconRegister); + } + + @Override + @SideOnly(Side.CLIENT) + public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) { + subItem(par1ItemStack).addInformation(par1ItemStack, par2EntityPlayer, par3List, par4); + } + +} diff --git a/src/main/java/ml/core/item/StackUtils.java b/src/main/java/ml/core/item/StackUtils.java index 0a46cbf..b1fb2c9 100644 --- a/src/main/java/ml/core/item/StackUtils.java +++ b/src/main/java/ml/core/item/StackUtils.java @@ -19,18 +19,16 @@ public class StackUtils { - public static ItemStack create(int itemID, int count, int meta, NBTTagCompound nbt) { - ItemStack stack = new ItemStack(itemID, count, meta); + public static ItemStack create(Item item, int count, int meta, NBTTagCompound nbt) { + ItemStack stack = new ItemStack(item, count, meta); stack.setTagCompound(nbt); return stack; } - public static ItemStack create(Item item, int count, int meta, NBTTagCompound nbt) { - return create(item.itemID, count, meta, nbt); - } - public static ItemStack create(Block block, int count, int meta, NBTTagCompound nbt) { - return create(block.blockID, count, meta, nbt); + ItemStack stack = new ItemStack(block, count, meta); + stack.setTagCompound(nbt); + return stack; } /** @@ -176,7 +174,7 @@ public static boolean checkItemEquals(Object target, ItemStack input) { ItemStack trgIS = (ItemStack)target; return (trgIS.getItem() == input.getItem() && (trgIS.getItemDamage() == OreDictionary.WILDCARD_VALUE || trgIS.getItemDamage() == input.getItemDamage())); } else if (target instanceof Item) { - return (((Item)target).itemID == input.itemID); + return (((Item)target) == input.getItem()); } return false; } diff --git a/src/main/java/ml/core/nei/MLShapedRecipeHandler.java b/src/main/java/ml/core/nei/MLShapedRecipeHandler.java index a3fa4f2..44f3bbf 100644 --- a/src/main/java/ml/core/nei/MLShapedRecipeHandler.java +++ b/src/main/java/ml/core/nei/MLShapedRecipeHandler.java @@ -80,7 +80,7 @@ public void loadUsageRecipes(ItemStack ingredient) { CRecipeShapedBase crsb = (CRecipeShapedBase)irecipe; CachedMLShapedRecipe recipe = new CachedMLShapedRecipe(crsb); - if(recipe == null || !recipe.contains(recipe.ingredients, ingredient.itemID)) + if(recipe == null || !recipe.contains(recipe.ingredients, ingredient)) continue; recipe.computeVisuals(); diff --git a/src/main/java/ml/core/nei/NEI_MLCore_Config.java b/src/main/java/ml/core/nei/NEI_MLCore_Config.java index 4b98f76..3c3e8a3 100644 --- a/src/main/java/ml/core/nei/NEI_MLCore_Config.java +++ b/src/main/java/ml/core/nei/NEI_MLCore_Config.java @@ -2,8 +2,10 @@ import ml.core.gui.core.GuiElement; import ml.core.gui.core.MLGuiClient; +import ml.core.gui.core.TopParentGuiElement; import ml.core.vec.Rectangle; import net.minecraft.client.gui.inventory.GuiContainer; +import codechicken.nei.VisiblityData; import codechicken.nei.api.API; import codechicken.nei.api.IConfigureNEI; import codechicken.nei.api.INEIGuiAdapter; @@ -41,12 +43,22 @@ public boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h) { MLGuiClient mlg = (MLGuiClient)gui; GuiElement elm = mlg.getPrimaryElement(); for (GuiElement ge : elm.getDescendants()) { - if (ge.getGlobalBounds().intersects(new Rectangle(x, y, w, h))) { + if (ge.getParent().isChildVisible(ge) && ge.getGlobalBounds().intersects(new Rectangle(x, y, w, h))) { return true; } } } return false; } + + @Override + public VisiblityData modifyVisiblity(GuiContainer gui, VisiblityData currentVisibility) { + if (gui instanceof MLGuiClient) { + MLGuiClient mlg = (MLGuiClient)gui; + TopParentGuiElement elm = mlg.getPrimaryElement(); + currentVisibility.showNEI = elm.shouldShowNEI(); + } + return super.modifyVisiblity(gui, currentVisibility); + } } } diff --git a/src/main/java/ml/core/network/MLPacket.java b/src/main/java/ml/core/network/MLPacket.java index fc496b0..f23adf1 100644 --- a/src/main/java/ml/core/network/MLPacket.java +++ b/src/main/java/ml/core/network/MLPacket.java @@ -1,5 +1,8 @@ package ml.core.network; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -12,13 +15,10 @@ import ml.core.data.IDataSerializer; import ml.core.data.Serialization; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.network.packet.Packet250CustomPayload; import com.google.common.io.ByteArrayDataInput; -import cpw.mods.fml.common.network.PacketDispatcher; -import cpw.mods.fml.common.network.Player; -import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.common.network.internal.FMLProxyPacket; public abstract class MLPacket { @@ -33,14 +33,14 @@ public abstract class MLPacket { // Incoming - public MLPacket(EntityPlayer pl, ByteArrayDataInput dataIn) { + public MLPacket(ByteArrayDataInput dataIn) { try { Field[] flds = this.getClass().getFields(); Arrays.sort(flds, fldComparator); for (Field fld : flds) { data ann = fld.getAnnotation(data.class); if (ann != null) { - Class cls = fld.getType(); + Class cls = fld.getType(); Object v = Serialization.deserialize(cls, dataIn); fld.set(this, v); } @@ -50,14 +50,6 @@ public MLPacket(EntityPlayer pl, ByteArrayDataInput dataIn) { } } - public void handle(EntityPlayer epl, Side side) throws IOException { - if (side == Side.CLIENT) { - handleClientSide(epl); - } else { - handleServerSide(epl); - } - } - public void handleClientSide(EntityPlayer epl) throws IOException {}; public void handleServerSide(EntityPlayer epl) throws IOException {}; @@ -71,9 +63,10 @@ public MLPacket(String ch) { channel = ch; } - public Packet250CustomPayload convertToPkt250() { - ByteArrayOutputStream dataOutRaw = new ByteArrayOutputStream(); - DataOutputStream dataOut = new DataOutputStream(dataOutRaw); + public FMLProxyPacket convertToFMLPacket() { + ByteBuf buf = Unpooled.buffer(); +// ByteArrayOutputStream dataOutRaw = new ByteArrayOutputStream(); +// DataOutputStream dataOut = new DataOutputStream(dataOutRaw); try { dataOut.writeInt(packetID); @@ -83,7 +76,7 @@ public Packet250CustomPayload convertToPkt250() { for (Field fld : flds) { data ann = fld.getAnnotation(data.class); if (ann != null) { - Class cls = fld.getType(); + Class cls = fld.getType(); Serialization.serialize(cls, fld.get(this), dataOut); } } @@ -91,29 +84,7 @@ public Packet250CustomPayload convertToPkt250() { e.printStackTrace(); } - Packet250CustomPayload mcPkt = new Packet250CustomPayload(channel, dataOutRaw.toByteArray()); - mcPkt.isChunkDataPacket = chunkDataPacket; - return mcPkt; - } - - public void dispatchToServer() { - PacketDispatcher.sendPacketToServer(convertToPkt250()); - } - - public void dispatchToPlayer(EntityPlayer epl) { - PacketDispatcher.sendPacketToPlayer(convertToPkt250(), (Player)epl); - } - - public void dispatchToDimension(int dimId) { - PacketDispatcher.sendPacketToAllInDimension(convertToPkt250(), dimId); - } - - public void dispatchToAllNear(double X, double Y, double Z, double range, int dimensionId) { - PacketDispatcher.sendPacketToAllAround(X, Y, Z, range, dimensionId, convertToPkt250()); - } - - public void dispatchToAll() { - PacketDispatcher.sendPacketToAllPlayers(convertToPkt250()); + return new FMLProxyPacket(buf, channel); } private Comparator fldComparator = new Comparator() { diff --git a/src/main/java/ml/core/network/PacketHandler.java b/src/main/java/ml/core/network/PacketHandler.java index 84becc9..1b845bb 100644 --- a/src/main/java/ml/core/network/PacketHandler.java +++ b/src/main/java/ml/core/network/PacketHandler.java @@ -1,31 +1,44 @@ package ml.core.network; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageCodec; + import java.lang.reflect.Constructor; +import java.util.EnumMap; import java.util.List; import java.util.logging.Level; import ml.core.internal.CoreLogger; +import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.network.INetworkManager; -import net.minecraft.network.packet.Packet250CustomPayload; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.INetHandler; +import net.minecraft.network.NetHandlerPlayServer; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; -import com.google.common.io.ByteArrayDataInput; -import com.google.common.io.ByteStreams; -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.network.IPacketHandler; -import cpw.mods.fml.common.network.Player; +import cpw.mods.fml.common.network.FMLEmbeddedChannel; +import cpw.mods.fml.common.network.FMLOutboundHandler; +import cpw.mods.fml.common.network.NetworkRegistry; +import cpw.mods.fml.common.network.internal.FMLProxyPacket; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; /** * Thanks to MachineMuse for the idea on how to implement this * @author Matchlighter */ -public class PacketHandler implements IPacketHandler { +public class PacketHandler extends MessageToMessageCodec { + private EnumMap channels; protected static BiMap> PacketTypes = HashBiMap.create(); + public PacketHandler(String channel) { + this.channels = NetworkRegistry.INSTANCE.newChannel(channel, this); + } + public static void addHandler(Class pktClass){ PacketTypes.put(PacketTypes.size(), pktClass); } @@ -36,45 +49,73 @@ public static void addHandlers(List> pktClss) { } } - @Override - public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player) { - EntityPlayer entPl = (EntityPlayer)player; - - MLPacket mlPkt = tryCastPacket(packet, entPl); - if (mlPkt != null){ - try { - mlPkt.handle(entPl, FMLCommonHandler.instance().getEffectiveSide()); - } catch (Exception e) { - onError(e, mlPkt); - e.printStackTrace(); - } - } else { - CoreLogger.severe("("+this.getClass().toString()+") received unknown packet"); - } - } - protected void onError(Throwable e, MLPacket mlPkt) { CoreLogger.log(Level.SEVERE, "Error handling packet in channel ("+mlPkt.channel+")", e); } - private static MLPacket tryCastPacket(Packet250CustomPayload pkt, EntityPlayer pl){ - ByteArrayDataInput dat = ByteStreams.newDataInput(pkt.data); - int pkId = dat.readInt(); + public static int findPacketId(Class pktClass){ + return PacketTypes.inverse().get(pktClass); + } + + @Override + protected void encode(ChannelHandlerContext ctx, MLPacket msg, List out) throws Exception { + out.add(msg.convertToFMLPacket()); + } + + @Override + protected void decode(ChannelHandlerContext ctx, FMLProxyPacket msg, List out) throws Exception { + ByteBuf buf = msg.payload(); + int pkId = buf.readInt(); if (PacketTypes.get(pkId) != null){ try { - Constructor contructor = PacketTypes.get(pkId).getConstructor(EntityPlayer.class, ByteArrayDataInput.class); - MLPacket nPkt = contructor.newInstance(pl, dat); - nPkt.channel = pkt.channel; - return nPkt; + Constructor contructor = PacketTypes.get(pkId).getConstructor(ByteBuf.class); + MLPacket nPkt = contructor.newInstance(buf); + nPkt.channel = msg.channel(); + + Side side = msg.getTarget(); + if (side == Side.CLIENT) { + nPkt.handleClientSide(getClientPlayer()); + } else { + INetHandler netHandler = ctx.channel().attr(NetworkRegistry.NET_HANDLER).get(); + nPkt.handleServerSide(((NetHandlerPlayServer) netHandler).playerEntity); + } + } catch (Exception e) { e.printStackTrace(); } - } - return null; } - public static int findPacketId(Class pktClass){ - return PacketTypes.inverse().get(pktClass); + @SideOnly(Side.CLIENT) + private EntityPlayer getClientPlayer() { + return Minecraft.getMinecraft().thePlayer; + } + + public void sendToAll(MLPacket message) { + this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALL); + this.channels.get(Side.SERVER).writeAndFlush(message); + } + + public void sendTo(MLPacket message, EntityPlayerMP player) { + this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER); + this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(player); + this.channels.get(Side.SERVER).writeAndFlush(message); + } + + public void sendToAllAround(MLPacket message, NetworkRegistry.TargetPoint point) { + this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALLAROUNDPOINT); + this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point); + this.channels.get(Side.SERVER).writeAndFlush(message); + } + + public void sendToDimension(MLPacket message, int dimensionId) { + this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.DIMENSION); + this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(dimensionId); + this.channels.get(Side.SERVER).writeAndFlush(message); + } + + public void sendToServer(MLPacket message) { + this.channels.get(Side.CLIENT).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TOSERVER); + this.channels.get(Side.CLIENT).writeAndFlush(message); } } diff --git a/src/main/java/ml/core/texture/ConnectedTexture.java b/src/main/java/ml/core/texture/ConnectedTexture.java index 64301aa..34843cc 100644 --- a/src/main/java/ml/core/texture/ConnectedTexture.java +++ b/src/main/java/ml/core/texture/ConnectedTexture.java @@ -4,7 +4,7 @@ import ml.core.block.BlockUtils.SpatialRelation; import ml.core.vec.BlockCoord; import net.minecraft.world.IBlockAccess; -import net.minecraftforge.common.ForgeDirection; +import net.minecraftforge.common.util.ForgeDirection; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; diff --git a/src/main/java/ml/core/texture/CustomTextureMapManager.java b/src/main/java/ml/core/texture/CustomTextureMapManager.java index da03dc3..7823353 100644 --- a/src/main/java/ml/core/texture/CustomTextureMapManager.java +++ b/src/main/java/ml/core/texture/CustomTextureMapManager.java @@ -5,7 +5,7 @@ import net.minecraft.client.Minecraft; import net.minecraftforge.client.event.TextureStitchEvent; -import net.minecraftforge.event.ForgeSubscribe; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -19,7 +19,7 @@ public class CustomTextureMapManager { public void registerMap(CustomTextureMap map) { if (maps.contains(map)) - throw new RuntimeException("TextureMap type " + map.textureType + " is already registered."); + throw new RuntimeException("TextureMap type " + map.getTextureType() + " is already registered."); maps.add(map); Minecraft mc = Minecraft.getMinecraft(); @@ -30,10 +30,10 @@ public void registerMap(CustomTextureMap map) { } catch (IOException e) {} } - @ForgeSubscribe + @SubscribeEvent public void reregisterIcons(TextureStitchEvent.Pre evt) { Minecraft mc = Minecraft.getMinecraft(); - if (evt.map.textureType==0) { + if (evt.map.getTextureType()==0) { for (CustomTextureMap map : maps) { try { map.loadTexture(mc.getResourceManager()); diff --git a/src/main/java/ml/core/texture/IIconProvider.java b/src/main/java/ml/core/texture/IIconProvider.java index 12430ce..fcec516 100644 --- a/src/main/java/ml/core/texture/IIconProvider.java +++ b/src/main/java/ml/core/texture/IIconProvider.java @@ -1,7 +1,7 @@ package ml.core.texture; -import net.minecraft.client.renderer.texture.IconRegister; +import net.minecraft.client.renderer.texture.IIconRegister; public interface IIconProvider { - public void registerIcons(IconRegister ireg); + public void registerIcons(IIconRegister ireg); } \ No newline at end of file diff --git a/src/main/java/ml/core/texture/TextureSheet.java b/src/main/java/ml/core/texture/TextureSheet.java index 86dc175..ec4bad6 100644 --- a/src/main/java/ml/core/texture/TextureSheet.java +++ b/src/main/java/ml/core/texture/TextureSheet.java @@ -10,12 +10,12 @@ import javax.imageio.ImageIO; import net.minecraft.block.Block; -import net.minecraft.client.renderer.texture.IconRegister; +import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.client.resources.ResourceManager; +import net.minecraft.client.resources.IResourceManager; import net.minecraft.client.resources.SimpleResource; -import net.minecraft.util.Icon; +import net.minecraft.util.IIcon; import net.minecraft.util.ResourceLocation; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -38,8 +38,7 @@ protected TextureSprite(String par1, int tindex) { } @Override - public boolean load(ResourceManager manager, ResourceLocation location) - throws IOException { + public boolean load(IResourceManager manager, ResourceLocation location) { int offX = index%tilesX * swidth; int offY = index/tilesY * sheight; @@ -52,6 +51,11 @@ public boolean load(ResourceManager manager, ResourceLocation location) return true; } + @Override + public boolean hasCustomLoader(IResourceManager manager, ResourceLocation location) { + return true; + } + } protected TextureSprite[] sprites; @@ -75,7 +79,7 @@ public TextureSheet(String fl, int tilesX, int tilesY) { /** * Call in your code (e.g. on {@link Block#registerIcons(IconRegister)}) */ - public void registerIcons(IconRegister reg) { + public void registerIcons(IIconRegister reg) { TextureMap tmap = (TextureMap)reg; if (TextureUtils.shouldReloadTexture(tmap, texFile)) { loadMasterImg(); @@ -109,7 +113,7 @@ public void initSpriteList(int[] indices) { } } - public Icon getSprite(int i) { + public IIcon getSprite(int i) { return sprites[i]; } } diff --git a/src/main/java/ml/core/texture/TextureUtils.java b/src/main/java/ml/core/texture/TextureUtils.java index 61e1073..32134de 100644 --- a/src/main/java/ml/core/texture/TextureUtils.java +++ b/src/main/java/ml/core/texture/TextureUtils.java @@ -9,7 +9,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.client.resources.ResourceManager; +import net.minecraft.client.resources.IResourceManager; import net.minecraft.util.ResourceLocation; public class TextureUtils { @@ -53,8 +53,7 @@ public static BufferedImage loadBufferedImage(InputStream is) throws IOException public static boolean shouldReloadTexture(TextureMap mp, String texFile) { return mp.setTextureEntry(texFile, new TextureAtlasSprite(texFile) { @Override - public boolean load(ResourceManager manager, - ResourceLocation location) throws IOException { + public boolean load(IResourceManager manager, ResourceLocation location) { return false; } }); diff --git a/src/main/java/ml/core/tile/IRotatableTE.java b/src/main/java/ml/core/tile/IRotatableTE.java index d3c651a..ce3c92c 100644 --- a/src/main/java/ml/core/tile/IRotatableTE.java +++ b/src/main/java/ml/core/tile/IRotatableTE.java @@ -1,6 +1,6 @@ package ml.core.tile; -import net.minecraftforge.common.ForgeDirection; +import net.minecraftforge.common.util.ForgeDirection; public interface IRotatableTE { diff --git a/src/main/java/ml/core/tile/TileEntityConnectable.java b/src/main/java/ml/core/tile/TileEntityConnectable.java index 813d1d4..f5a5f1a 100644 --- a/src/main/java/ml/core/tile/TileEntityConnectable.java +++ b/src/main/java/ml/core/tile/TileEntityConnectable.java @@ -3,7 +3,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.packet.Packet; import net.minecraft.tileentity.TileEntity; -import net.minecraftforge.common.ForgeDirection; +import net.minecraftforge.common.util.ForgeDirection; import cpw.mods.fml.common.network.PacketDispatcher; public abstract class TileEntityConnectable extends TileEntity { @@ -40,7 +40,7 @@ public boolean isMaster() { } public TileEntityConnectable getConnected() { - TileEntity te = worldObj.getBlockTileEntity(xCoord+linkedDir.offsetX, yCoord+linkedDir.offsetY, zCoord+linkedDir.offsetZ); + TileEntity te = worldObj.getTileEntity(xCoord+linkedDir.offsetX, yCoord+linkedDir.offsetY, zCoord+linkedDir.offsetZ); if (linkedDir != ForgeDirection.UNKNOWN && te instanceof TileEntityConnectable && te.getClass()==this.getClass()) { return (TileEntityConnectable)te; } @@ -66,7 +66,7 @@ public boolean canConnectWith(TileEntityConnectable rtec) { } private boolean tryConnection(ForgeDirection fd){ - TileEntity rte = worldObj.getBlockTileEntity(xCoord+fd.offsetX, yCoord+fd.offsetY, zCoord+fd.offsetZ); + TileEntity rte = worldObj.getTileEntity(xCoord+fd.offsetX, yCoord+fd.offsetY, zCoord+fd.offsetZ); if (rte instanceof TileEntityConnectable){ TileEntityConnectable rtec = (TileEntityConnectable)rte; if (rtec.facing == this.facing && @@ -92,7 +92,7 @@ public void tryConnection(){ public void refreshConnection(){ if (linkedDir != ForgeDirection.UNKNOWN) { - TileEntity te = worldObj.getBlockTileEntity(xCoord+linkedDir.offsetX, yCoord+linkedDir.offsetY, zCoord+linkedDir.offsetZ); + TileEntity te = worldObj.getTileEntity(xCoord+linkedDir.offsetX, yCoord+linkedDir.offsetY, zCoord+linkedDir.offsetZ); if (!(te instanceof TileEntityConnectable) || !canConnectWith((TileEntityConnectable)te) || ((TileEntityConnectable)te).linkedDir != linkedDir.getOpposite()){ linkedDir = ForgeDirection.UNKNOWN; diff --git a/src/main/java/ml/core/util/DyeUtils.java b/src/main/java/ml/core/util/DyeUtils.java index 40639e7..af6b423 100644 --- a/src/main/java/ml/core/util/DyeUtils.java +++ b/src/main/java/ml/core/util/DyeUtils.java @@ -4,7 +4,7 @@ import java.util.Collection; import java.util.List; -import net.minecraft.item.Item; +import net.minecraft.init.Items; import net.minecraft.item.ItemDye; import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.OreDictionary; @@ -18,7 +18,7 @@ public static int getVanillaColorId(ItemStack mOre) { if (mOre == null) return -1; for (int i=0; i<16; i++){ - if (OreDictionary.getOreID(new ItemStack(Item.dyePowder, 1, i)) == OreDictionary.getOreID(mOre)){ + if (OreDictionary.itemMatches(new ItemStack(Items.dye, 1, i), mOre, true)){ return i; } } @@ -28,7 +28,7 @@ public static int getVanillaColorId(ItemStack mOre) { public static int getDyeColor(ItemStack dyeStack) { int dyeId = getVanillaColorId(dyeStack); if (dyeId > -1) { - return ItemDye.dyeColors[dyeId]; + return ItemDye.field_150922_c[dyeId]; } return -1; } @@ -64,10 +64,29 @@ public static int mixDyeColors(Collection dyes) { return mixDyeColors(-1, dyes); } + private static final String[] dyes = + { + "Black", + "Red", + "Green", + "Brown", + "Blue", + "Purple", + "Cyan", + "LightGray", + "Gray", + "Pink", + "Lime", + "Yellow", + "LightBlue", + "Magenta", + "Orange", + "White" + }; public static List getAllDyeStacks() { List stacks = new ArrayList(); - for (int i=0; i genFeatures = HashMultimap.create(); @@ -37,7 +38,7 @@ public void registerGenerator(String modId, IFeatureGenerator gen) { genFeatures.put(modId, gen); } - @ForgeSubscribe + @SubscribeEvent public void handleChunkLoad(ChunkEvent.Load evt) { World w = evt.world; Chunk c = evt.getChunk(); @@ -53,13 +54,52 @@ public void handleChunkLoad(ChunkEvent.Load evt) { for (IFeatureGenerator feat : genFeatures.get(modId)) { if (feat.allowRetroGen(w, x, z) && feat.canGenerateInWorld(w) && rdb.shouldPerformRetroJob(x, z, feat.getGenIdentifier(), feat.getFeatureVersion())) { RetroQueueItem rqi = new RetroQueueItem(x, z, w, feat, rdb.getLastFeatureVesrion(x, z, feat.getGenIdentifier()), rdb); - CoreLogger.info("Chunk @ ("+x+","+z+",DIM"+w.provider.dimensionId+") has been marked for retroactive feature generation for ("+modId+":"+feat.getGenIdentifier()+")"); - genQueue.put(dimid, rqi); + synchronized(this) { + CoreLogger.info("Chunk @ ("+x+","+z+",DIM"+w.provider.dimensionId+") has been marked for retroactive feature generation for ("+modId+":"+feat.getGenIdentifier()+")"); + genQueue.put(dimid, rqi); + } } } } } + public void tickWorld(TickEvent.WorldTickEvent evt) { + if (evt.phase == Phase.END) { + World world = evt.world; + int dimid = world.provider.dimensionId; + + synchronized (this) { + if (genQueue.get(dimid).size() > 0) { + List subQ = new ArrayList(genQueue.removeAll(dimid)); + Iterator iter = subQ.iterator(); + + int count=0; + while (iter.hasNext()) { + RetroQueueItem rqi = iter.next(); + iter.remove(); + + long worldSeed = world.getSeed(); + Random rand = new Random(worldSeed); + long xSeed = rand.nextLong() >> 2 + 1L; + long zSeed = rand.nextLong() >> 2 + 1L; + long chunkSeed = (xSeed * rqi.chunkX + zSeed * rqi.chunkZ) ^ worldSeed; + rand.setSeed(chunkSeed); + + rqi.feature.doPopulate(rand, rqi.chunkX, rqi.chunkZ, world, true, rqi.lastVer); + rqi.rdb.markRetroJobDone(rqi.chunkX, rqi.chunkZ, rqi.feature.getGenIdentifier(), rqi.feature.getFeatureVersion()); + + count++; + if (count > 32) + break; + } + + genQueue.putAll(dimid, subQ); + CoreLogger.info(count+" chunks have been retro-generated. "+genQueue.get(dimid).size()+" more left."); + } + } + } + } + /** * Standard, first-time chunk generation. */ @@ -71,7 +111,7 @@ public void generate(Random rand, int chunkX, int chunkZ, World world, IChunkPro for (IFeatureGenerator feature : features) { if (feature.canGenerateInWorld(world)) { - feature.doGeneration(rand, chunkX, chunkZ, world, false, -1); + feature.doPopulate(rand, chunkX, chunkZ, world, false, -1); rdb.markRetroJobDone(chunkX, chunkZ, feature.getGenIdentifier(), feature.getFeatureVersion()); } } @@ -88,51 +128,6 @@ private RetroDataBase getRetroDataBase(World w, String modId) { return rdb; } - @Override - public void tickStart(EnumSet type, Object... tickData) {} - - @Override - public void tickEnd(EnumSet type, Object... tickData) { - World world = (World)tickData[0]; - int dimid = world.provider.dimensionId; - - if (genQueue.get(dimid).size() > 0) { - Iterator iter = genQueue.get(dimid).iterator(); - - int count=0; - while (iter.hasNext()) { - RetroQueueItem rqi = iter.next(); - iter.remove(); - - long worldSeed = world.getSeed(); - Random rand = new Random(worldSeed); - long xSeed = rand.nextLong() >> 2 + 1L; - long zSeed = rand.nextLong() >> 2 + 1L; - long chunkSeed = (xSeed * rqi.chunkX + zSeed * rqi.chunkZ) ^ worldSeed; - rand.setSeed(chunkSeed); - - rqi.feature.doGeneration(rand, rqi.chunkX, rqi.chunkZ, world, true, rqi.lastVer); - rqi.rdb.markRetroJobDone(rqi.chunkX, rqi.chunkZ, rqi.feature.getGenIdentifier(), rqi.feature.getFeatureVersion()); - - count++; - if (count > 32) - break; - } - - CoreLogger.info(count+" chunks have been retro-generated. "+genQueue.get(dimid).size()+" more left."); - } - } - - @Override - public EnumSet ticks() { - return EnumSet.of(TickType.WORLD); - } - - @Override - public String getLabel() { - return "MLCore:WorldGen"; - } - private static class RetroQueueItem { final World w; final int chunkX; @@ -162,7 +157,7 @@ public boolean equals(Object obj) { } //Credit to ProjectRed for most of this bit. - private static class RetroDataBase extends WorldSavedData { + public static class RetroDataBase extends WorldSavedData { private HashMap chunks = new HashMap(); @@ -191,9 +186,9 @@ public void markRetroJobDone(int chunkX, int chunkZ, String jobId, int jlevel) { @Override public void readFromNBT(NBTTagCompound nbt) { - NBTTagList lst = (NBTTagList)nbt.getTagList("chunks"); + NBTTagList lst = (NBTTagList)nbt.getTagList("chunks", 10); for (int i=0; i unbuiltComponents = new ArrayList(); + protected int componentCounter; + protected int range = 7 * 16; // Corresponds with MapGenBase.range + + public InitialStructureComponent() {} + + public InitialStructureComponent(ChunkCoordinates position, int rotation, int componentCount) { + super(position, rotation); + this.componentCounter = componentCount; + } + + public MLStructureComponent getNextStructureComponent(MLStructureComponent prev, int oRotation, List componentWeights, List existingComponents, ChunkCoordinates entrancePosition, Random rnd) { + int totalWeight = getTotalWeight(componentWeights); + + if (componentCounter < 1 || totalWeight < 1) { + return null; + } else if (Math.abs(entrancePosition.posX - position.posX) <= range && Math.abs(entrancePosition.posZ - position.posZ) <= range) { + int rn = rnd.nextInt(totalWeight); + for (WeightedComponent wc : componentWeights) { + rn -= wc.componentWeight; + + if (rn < 0) { + MLStructureComponent nComponent = createComponent(wc, prev, (rotation + oRotation) % 4, existingComponents, entrancePosition, rnd); + + if (nComponent != null) { + componentCounter--; + wc.instancesCreated++; + + if (wc.maxComponentInstances > 0 && wc.instancesCreated >= wc.maxComponentInstances) componentWeights.remove(wc); + + unbuiltComponents.add(nComponent); + existingComponents.add(nComponent); + + return nComponent; + } + } + } + } + return null; + } + + protected MLStructureComponent createComponent(WeightedComponent wComponent, MLStructureComponent prev, int nRotation, List existingComponents, ChunkCoordinates entrancePosition, Random rnd) { + + try { + MLStructureComponent nComponent = ConstructorUtils.invokeConstructor(wComponent.cls); + nComponent.constructComponent(prev, nRotation, entrancePosition, rnd); + StructureComponent intersect = StructureComponent.findIntersecting(existingComponents, nComponent.boundingBox); + if (intersect != null && intersect != prev) return null; + return nComponent; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + private static int getTotalWeight(List par0List) { + int tweight = 0; + + for (WeightedComponent wc : par0List) { + tweight += wc.componentWeight; + } + + return tweight; + } + } +} diff --git a/src/main/java/ml/core/world/structure/MLStructureStart.java b/src/main/java/ml/core/world/structure/MLStructureStart.java new file mode 100644 index 0000000..7fb4d2f --- /dev/null +++ b/src/main/java/ml/core/world/structure/MLStructureStart.java @@ -0,0 +1,30 @@ +package ml.core.world.structure; + +import java.util.Random; + +import ml.core.world.structure.MLStructureComponent.InitialStructureComponent; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureStart; + +public abstract class MLStructureStart extends StructureStart { + + public MLStructureStart() {} + + public MLStructureStart(InitialStructureComponent initialComponent, World world, Random rnd, int chunkX, int chunkZ) { + super(chunkX, chunkZ); + + this.components.add(initialComponent); + initialComponent.buildComponent(initialComponent, this.components, rnd); + + while (!initialComponent.unbuiltComponents.isEmpty()) { + //int i = rnd.nextInt(initialComponent.unbuiltComponents.size()); + MLStructureComponent nextComponent = initialComponent.unbuiltComponents.remove(0); + nextComponent.buildComponent(initialComponent, this.components, rnd); + + if (this.components.contains(nextComponent)) this.components.add(nextComponent); + } + + updateBoundingBox(); + } + +} diff --git a/src/main/java/ml/core/world/structure/StructureBuilder.java b/src/main/java/ml/core/world/structure/StructureBuilder.java new file mode 100644 index 0000000..05508aa --- /dev/null +++ b/src/main/java/ml/core/world/structure/StructureBuilder.java @@ -0,0 +1,337 @@ +package ml.core.world.structure; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockButton; +import net.minecraft.block.BlockDoor; +import net.minecraft.block.BlockLever; +import net.minecraft.block.BlockPistonBase; +import net.minecraft.block.BlockRailBase; +import net.minecraft.block.BlockRedstoneRepeater; +import net.minecraft.block.BlockStairs; +import net.minecraft.block.BlockTorch; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemDoor; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.world.ChunkPosition; +import net.minecraft.world.World; +import net.minecraft.world.gen.structure.StructureBoundingBox; +import net.minecraftforge.common.util.ForgeDirection; + +/** + * Helper class for making the creation of rotatable structures easier.
+ * Imposes a custom coordinate system: + * + *
+ *              Z-
+ *              ^
+ *              |
+ *              N
+ *  X- <------W + E------> X+
+ *              S
+ *              |
+ *              v
+ *              Z+
+ * 
+ * + * N,E,S,W are default minecraft directions, in global space. Z-, X+, Z+, X- are in local space and are rotated depending on the passed rotation. + * Rotation works in 90-degree increments, rotating the axes in the above illustration clockwise. e.g. Z- becomes East, X+ becomes South, etc.
+ * + * @author Matchlighter + */ +public class StructureBuilder { + + public final World world; + public final int rotation; + public final ChunkPosition center; + public ChunkCoordinates ioffset = new ChunkCoordinates(); + public ChunkCoordinates absMinimum, absMaximum; + + public boolean flipXZ = false; + + public boolean symmetryX = false; + public boolean symmetryZ = false; + + public boolean invertX = false; + public boolean invertY = false; + public boolean invertZ = false; + + public int rotationOffset = 0; + + /** + * See {@link StructureBuilder} for details. + * @param world + * @param pos The point to rotate the structure around. + * @param rot The number of clockwise, 90-degree increments to rotate the structure. + */ + public StructureBuilder(World world, ChunkPosition pos, int rot) { + this.world = world; + this.center = pos; + this.rotation = rot; + } + + public StructureBuilder(World world, ChunkCoordinates pos, int rot) { + this.world = world; + this.center = new ChunkPosition(pos.posX, pos.posY, pos.posZ); + this.rotation = rot; + } + + public StructureBuilder(World world, int x, int y, int z, int rot) { + this.world = world; + this.center = new ChunkPosition(x, y, z); + this.rotation = rot; + } + + /** + * Converts the local x passed to a global x-value. + */ + public int getAbsX(int x, int z) { + if (invertX) x = -x; if (invertZ) z = -z; + x += ioffset.posX; z += ioffset.posZ; + int mrot = (rotation + rotationOffset) % 4; + + switch (mrot) { + case 0: + return center.chunkPosX+x; + case 1: + return center.chunkPosX-z; + case 2: + return center.chunkPosX-x; + case 3: + return center.chunkPosX+z; + } + return center.chunkPosX; + } + + public int getAbsY(int oy) { + if (invertY) oy = -oy; + return center.chunkPosY + oy + ioffset.posY; + } + + /** + * Converts the local z passed to a global z-value. + */ + public int getAbsZ(int x, int z) { + if (invertX) x = -x; if (invertZ) z = -z; + x += ioffset.posX; z += ioffset.posZ; + int mrot = (rotation + rotationOffset) % 4; + + switch (mrot) { + case 0: + return center.chunkPosZ+z; + case 1: + return center.chunkPosZ+x; + case 2: + return center.chunkPosZ-z; + case 3: + return center.chunkPosZ-x; + } + return center.chunkPosZ; + } + + public TileEntity getTileEntityAt(int rx, int ry, int rz) { + ChunkCoordinates abs = getAbsCoords(rx, ry, rz); + return world.getTileEntity(abs.posX, abs.posY, abs.posZ); + } + + /** + * Converts the relative x,y,z into a global point. + */ + public ChunkCoordinates getAbsCoords(int rx, int ry, int rz) { + int bx = flipXZ ? rz : rx; + int bz = flipXZ ? rx : rz; + + return new ChunkCoordinates(getAbsX(bx, bz), getAbsY(ry), getAbsZ(bx, bz)); + } + + public boolean absCoordsInRange(int ax, int ay, int az) { + if (absMinimum == null || absMaximum == null) return true; + return (ax >= absMinimum.posX && ax <= absMaximum.posX) && + (ay >= absMinimum.posY && ay <= absMaximum.posY) & + (az >= absMinimum.posZ && az <= absMaximum.posZ); + } + + public boolean relCoordsInRange(int rx, int ry, int rz) { + if (absMinimum == null || absMaximum == null) return true; + ChunkCoordinates absPt = getAbsCoords(rx, ry, rz); + return (absPt.posX >= absMinimum.posX && absPt.posX <= absMaximum.posX) && + (absPt.posY >= absMinimum.posY && absPt.posY <= absMaximum.posY) & + (absPt.posZ >= absMinimum.posZ && absPt.posZ <= absMaximum.posZ); + } + + public void setMinMax(ChunkCoordinates min, ChunkCoordinates max) { + this.absMinimum = min; + this.absMaximum = max; + } + + public void setMinMax(StructureBoundingBox bb) { + if (bb != null) { + this.absMinimum = new ChunkCoordinates(bb.minX, bb.minY, bb.minZ); + this.absMaximum = new ChunkCoordinates(bb.maxX, bb.maxY, bb.maxZ); + } else { + this.absMinimum = null; + this.absMaximum = null; + } + } + + public Block getBlockAt(int rx, int ry, int rz) { + ChunkCoordinates p = getAbsCoords(rx, ry, rz); + return world.getBlock(p.posX, p.posY, p.posZ); + } + + private void setBlockAtAbs(int ax, int ay, int az, Block block, int blockMeta) { + if (!absCoordsInRange(ax, ay, az)) return; + + if (block instanceof BlockDoor) { + ItemDoor.placeDoorBlock(world, ax, ay, az, blockMeta, block); + } else { + world.setBlock(ax, ay, az, block != null ? block : Blocks.air, blockMeta, 3); + } + } + + /** + * Set the block at the local coordinates (rx, ry, rz) to the specified block and meta. + * Takes symmetry booleans into account, so up to 4 blocks may be placed. + */ + public void setBlockAt(int rx, int ry, int rz, Block block, int blockMeta) { + + int bx = flipXZ ? rz : rx; + int bz = flipXZ ? rx : rz; + + setBlockAtAbs(getAbsX(bx, bz), getAbsY(ry), getAbsZ(bx, bz), block, blockMeta); + + if (symmetryX && symmetryZ && bx != 0 && bz != 0) { + setBlockAtAbs(getAbsX(-bx, -bz), getAbsY(ry), getAbsZ(-bx, -bz), block, blockMeta); + } + if (symmetryX && bx != 0) { + setBlockAtAbs(getAbsX(-bx, bz), getAbsY(ry), getAbsZ(-bx, bz), block, blockMeta); + } + if (symmetryZ && bz != 0) { + setBlockAtAbs(getAbsX(bx, -bz), getAbsY(ry), getAbsZ(bx, -bz), block, blockMeta); + } + } + + /** + * Fills the specified area with blocks. start_ and end_ are both inclusive. + */ + public void fillArea(int startX, int startY, int startZ, int endX, int endY, int endZ, Block block, int blockMeta) { + for (int x=startX; x<=endX; x++) { + for (int z=startZ; z<=endZ; z++) { + for (int y=startY; y<=endY; y++) { + setBlockAt(x, y, z, block, blockMeta); + } + } + } + } + + /** + * Fills the edges of the specified area with blocks. start_ and end_ are both inclusive. + */ + public void borderArea(int startX, int startY, int startZ, int endX, int endY, int endZ, Block block, int blockMeta) { + for (int x=startX; x<=endX; x++) { + boolean xc = x==startX || x==endX; + + for (int z=startZ; z<=endZ; z++) { + boolean zc = z==startZ || z==endZ; + + for (int y=startY; y<=endY; y++) { + boolean yc = y==startY || y==endY; + + if ((yc && xc) || (yc && zc) || (xc && zc)) setBlockAt(x, y, z, block, blockMeta); + } + } + } + } + + /** + * Fills the faces of the specified area with blocks. start_ and end_ are both inclusive. + */ + public void wallArea(int startX, int startY, int startZ, int endX, int endY, int endZ, Block block, int blockMeta) { + wallArea(startX, startY, startZ, endX, endY, endZ, true, true, true, block, blockMeta); + } + + /** + * Fills the faces of the specified area with blocks, if the w_ is true for the axis. start_ and end_ are both inclusive. + */ + public void wallArea(int startX, int startY, int startZ, int endX, int endY, int endZ, boolean wx, boolean wy, boolean wz, Block block, int blockMeta) { + for (int x=startX; x<=endX; x++) { + boolean xc = (x==startX || x==endX) && wx; + + for (int z=startZ; z<=endZ; z++) { + boolean zc = (z==startZ || z==endZ) && wz; + + for (int y=startY; y<=endY; y++) { + boolean yc = (y==startY || y==endY) && wy; + + if (xc || yc || zc) setBlockAt(x, y, z, block, blockMeta); + } + } + } + } + + public void fillDown(int startX, int startY, int startZ, int endX, int endZ, Block block, int blockMeta) { + for (int x=startX; x<=endX; x++) { + for (int z=startZ; z<=endZ; z++) { + for (int y=startY; getAbsY(y)>0; y--) { + if (getBlockAt(x, y, z) != Blocks.air) { + break; + } + setBlockAt(x, y, z, block, blockMeta); + } + } + } + } + + /** + * Attempts to get the rotated metadata of a rotatable block. + */ + public int getRotatedMeta(Block block, int cRotation) { + int rot4 =(this.rotation + cRotation) % 4; + + if (block instanceof BlockRailBase) { + return (this.rotation + cRotation) % 2; + + } else if (block instanceof BlockDoor) { + return (this.rotation + cRotation + 1) % 4; + + } else if (block instanceof BlockStairs) { + int rot = rot4; + + if (rot4 == 0) rot = 2; + else if (rot4 == 2) rot = 3; + else if (rot4 == 3) rot = 0; + + return rot | (cRotation & 8); + + } else if (block == Blocks.ladder) { + if (rot4 == 0) return 2; + if (rot4 == 1) return 5; + else if (rot4 == 2) return 3; + else if (rot4 == 3) return 4; + + } else if (block instanceof BlockButton || block instanceof BlockLever || block instanceof BlockTorch) { + if (rot4 == 0) return 4; + if (rot4 == 1) return 1; + else if (rot4 == 2) return 3; + else if (rot4 == 3) return 2; + + } else if (block instanceof BlockPistonBase || block instanceof BlockLever || block == Blocks.dispenser) { + // TODO + } else if (block instanceof BlockRedstoneRepeater) { + return rot4; + } + + return rot4; + } + + private static final int[][] rotMatrix = { + {0,1, 2,3,4,5}, + {0,1, 5,4,2,3}, + {0,1, 3,2,5,4}, + {0,1, 4,5,3,2}, + }; + + public ForgeDirection rotateForgeDir(ForgeDirection fdir) { + return ForgeDirection.getOrientation(rotMatrix[rotation][fdir.ordinal()]); + } +} diff --git a/src/main/java/ml/core/world/structure/StructureHelper.java b/src/main/java/ml/core/world/structure/StructureHelper.java new file mode 100644 index 0000000..51f7d6d --- /dev/null +++ b/src/main/java/ml/core/world/structure/StructureHelper.java @@ -0,0 +1,68 @@ +package ml.core.world.structure; + +import java.util.Random; + +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.world.World; + +public class StructureHelper { + + public static boolean shouldGenerateAt(World world, int chunkX, int chunkZ, int minDist, int maxDist) { + int k = chunkX; + int l = chunkZ; + + if (chunkX < 0) { + chunkX -= maxDist - 1; + } + + if (chunkZ < 0) { + chunkZ -= maxDist - 1; + } + + int i1 = chunkX / maxDist; + int j1 = chunkZ / maxDist; + Random random = world.setRandomSeed(i1, j1, 14357617); + i1 *= maxDist; + j1 *= maxDist; + i1 += random.nextInt(maxDist - minDist); + j1 += random.nextInt(maxDist - minDist); + + return (k == i1 && l == j1); + } + + public static int getRotatedX(int x, int z, int rotation) { + switch (rotation) { + case 0: + return x; + case 1: + return -z; + case 2: + return -x; + case 3: + return z; + } + return x; + } + + public static int getRotatedZ(int x, int z, int rotation) { + switch (rotation) { + case 0: + return z; + case 1: + return x; + case 2: + return -z; + case 3: + return -x; + } + return z; + } + + public static ChunkCoordinates getRotatedCoords(ChunkCoordinates coord, int rotation) { + return new ChunkCoordinates(getRotatedX(coord.posX, coord.posZ, rotation), coord.posY, getRotatedZ(coord.posX, coord.posZ, rotation)); + } + + public static ChunkCoordinates addCoords(ChunkCoordinates a, ChunkCoordinates b) { + return new ChunkCoordinates(a.posX + b.posX, a.posY + b.posY, a.posZ + b.posZ); + } +} diff --git a/src/main/java/ml/core/world/structure/WeightedComponent.java b/src/main/java/ml/core/world/structure/WeightedComponent.java new file mode 100644 index 0000000..9bef15c --- /dev/null +++ b/src/main/java/ml/core/world/structure/WeightedComponent.java @@ -0,0 +1,17 @@ +package ml.core.world.structure; + + +public class WeightedComponent { + + public Class cls; + public final int componentWeight; + public int instancesCreated; + public int maxComponentInstances; + + public WeightedComponent(Class cls, int weight, int maxPieces) { + this.cls = cls; + this.componentWeight = weight; + this.maxComponentInstances = maxPieces; + } + +} diff --git a/src/main/resources/mlcore_at.cfg b/src/main/resources/mlcore_at.cfg new file mode 100644 index 0000000..1aa192c --- /dev/null +++ b/src/main/resources/mlcore_at.cfg @@ -0,0 +1,2 @@ +public net.minecraft.client.gui.inventory.GuiContainer func_146977_a () #drawSlotContents +public net.minecraft.client.gui.inventory.GuiContainer func_74187_b () #getSlotAtPosition \ No newline at end of file