Posted September 4, 201510 yr i have an item that i want the reach distance extended on. any easy way to do this?
September 4, 201510 yr Euclidean distance? net.minecraft.util.Vec3.class // BSc CIS, hardcore gamer and a big fan of Minecraft. TmzOS ::..
September 4, 201510 yr Hi I used Reflection to do this, perhaps you can implement something similar - it's a bit of a hack but it worked ok. The code below might help you understand the key ideas behind it. public class ReplacePlayerControllerMPHandler { @SubscribeEvent public void worldLoadEvent(WorldEvent.Load event) { if (event.world instanceof WorldClient) { Minecraft mc = Minecraft.getMinecraft(); PlayerControllerMP playerControllerMP = mc.playerController; if (!(playerControllerMP instanceof PlayerControllerMPHijack)) { mc.playerController = PlayerControllerMPHijack.createFromVanilla(playerControllerMP); } } } } /** * Hijack various parts of PlayerControllerMP to extend the block reach distance */ @SideOnly(Side.CLIENT) public class PlayerControllerMPHijack extends PlayerControllerMP { private static Method syncCurrentPlayItemMethod; public static PlayerControllerMPHijack createFromVanilla(PlayerControllerMP playerControllerMP) { NetHandlerPlayClient netHandlerPlayClient = ReflectionHelper.getPrivateValue (PlayerControllerMP.class, playerControllerMP, "netClientHandler", "field_78774_b"); PlayerControllerMPHijack retObj = new PlayerControllerMPHijack(Minecraft.getMinecraft(), netHandlerPlayClient); WorldSettings.GameType gameType = ReflectionHelper.getPrivateValue(PlayerControllerMP.class, playerControllerMP, "currentGameType", "field_78779_k"); ReflectionHelper.setPrivateValue(PlayerControllerMP.class, retObj, gameType, "currentGameType", "field_78779_k"); syncCurrentPlayItemMethod = UsefulFunctions.findMethod(PlayerControllerMP.class, new String [] {"syncCurrentPlayItem", "func_78750_j"}, new Class [] {}); return retObj; } private PlayerControllerMPHijack(Minecraft mcIn, NetHandlerPlayClient netHandlerPlayClient) { super(mcIn, netHandlerPlayClient); } @Override public float getBlockReachDistance() { EntityPlayerSP player = Minecraft.getMinecraft().thePlayer; if (player == null) return super.getBlockReachDistance(); ItemStack heldItem = player.getHeldItem(); if (heldItem != null && heldItem.getItem() instanceof ItemStick) { ItemStick itemStick = (ItemStick)heldItem.getItem(); return itemStick.getReachDistance(heldItem, super.getBlockReachDistance()); } else { return super.getBlockReachDistance(); } } // copied from base class @Override public void attackEntity(EntityPlayer playerIn, Entity targetEntity) { try { syncCurrentPlayItemMethod.invoke(this); } catch (Exception e) { throw new RuntimeException("Could not invoke syncCurrentPlayItem()", e); } // this.syncCurrentPlayItem(); AttackMessageToServer attackMessageToServer = new AttackMessageToServer(targetEntity); StartupCommon.simpleNetworkWrapper.sendToServer(attackMessageToServer); if (getCurrentGameType() != WorldSettings.GameType.SPECTATOR) { playerIn.attackTargetEntityWithCurrentItem(targetEntity); } } } public class StartupClientOnly { public static void preInitClientOnly() { MinecraftForge.EVENT_BUS.register(new ReplacePlayerControllerMPHandler()); } public static void initClientOnly() { } public static void postInitClientOnly() { } } -TGG
September 4, 201510 yr Author cool thanks but is this the only way? or are there other easier ways to do this. im still getting some errors
September 4, 201510 yr Do you want to extend reach in matter of attacking, block-harvesting or totally in terms of reach in everything? There are ways of doing some stuff smooth and nice, but in case of "total-override" - yes, this (not counting ASM) is the only good way. 1.7.10 is no longer supported by forge, you are on your own.
September 4, 201510 yr Author i want is so that when i hold a certain item that my reach distance extends(the block highlight distance so i can destroy blocks from farther away or activate them)
September 4, 201510 yr Hi I think this is about the easiest way you're likely to find. If you find an easier one, please let me know and I'll implement it too -TGG
September 5, 201510 yr WorldEvent.Load is responsible for replacing, on client side (since it is client thread that "controls" player), player controller with hijacked one. PlayerControllerMPHijack extends PlayerControllerMP Is the hijacked version of normal controller that allows you to manipulate reach. It is possible by overriding methods: getBlockReachDistance() attackEntity(...) Inside those - you can see that everything is client sided, so you can use you own player from Minecraft.class to e.g get held item. As to reflection magic inside - google "java reflection" - LEARN IT - then, when you do - have look at class ObfuscationReflectionHelper. Logic behind - dev names are deobfuscated, when you release mod, you need SRGs - that is what those "func_78750_j" are. General questions get general answers - be more precise, or if you don't understand anything - learn more about Java (please). 1.7.10 is no longer supported by forge, you are on your own.
September 5, 201510 yr Author what does ItemStick, StartupCommon, AttackMessageToServer and UsefulFunctions refer to?
September 5, 201510 yr what does ItemStick, StartupCommon, AttackMessageToServer and UsefulFunctions refer to? Hi Most of those you don't need to worry about, they are just other parts of the mod I took the code from. I forgot to include the UsefulFunctions method, which you will need. public static Method findMethod(Class clazz, String[] methodNames, Class<?>... methodTypes) { Exception failed = null; for (String methodName : methodNames) { try { Method m = clazz.getDeclaredMethod(methodName, methodTypes); m.setAccessible(true); return m; } catch (Exception e) { failed = e; } } throw new ReflectionHelper.UnableToFindMethodException(methodNames, failed); } Unfortunately since the server side also checks the reach distance, you will need to do a similar trick on ItemInWorldManager as well. I don't have sample code for that because I used the extended reach client side only to send an AttackMessageToServer (to drop pigs from the sky onto the player's head) instead of using the vanilla block damaging code, which is in NetHandlerPlayServer.processPlayerDigging(). It will be tricky to get right without a fair bit of work to understand the vanilla code, plus trial and error. If there's an easier way, I don't know what it is. -TGG
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.