SOLVED Changer la boite de collision du joueur


  • Bonjour,

    je cherche à modifier la boite de collision du joueur, ayant recherché un peu partout, j'ai trouvé la fonction setSize, cette fonction modifie bein la boite de collision mais pas la position de la caméra (en fait, je veux faire en sorte que le joueur fasse 1x1x1 bloc), avec un peu de refléxion (l'api mais aussi le mot en lui même x) ), j'ai réussi à appeler cette méthode de la classe player. Voilà, ma boîte de collision est changée, comme ma caméra n'a pas changé, je peux poser des blocs sur moi, mais je ne peux pas les traverser, en gros, si j'ai un bloc d'air en dessous et un bloc normal, je peux passer à travers mais ça me renvoie à l'endroit où j'étais (comme si le bloc était de la mousse). En réfléchissant un peu j'en suis venu au fait qu'il faut changer la position Y de la caméra mais voilà la question : Comment faire ?
    J'ai recherché et j'ai trouvé une entité qui est un copie conforme du joueur à son spawn : renderViewEntity disponible dans la classe Minecraft. Ensuite, j'ai trouvé la variable yOffset. Lorsque je modifie cette variable (dans le tickhandler), ça me modifier le point x pù je sélectionne les blocs, en gros, il faut que mon curseur soit plus haut pour que je puisse sélectionner le bloc. Comme si mas caméra était plus bas sauf qu'elle n'y est pas. En regardant un peu dans la classe EntityPlayer j'ai trouvé la fonction wakeUpPlayer qui modifie le yOffset et change la caméra car lorsque le joueur dort, la caméra est plus basse. La fonction est appeller dans la fonction onUpdate du joueur, l'event PlayerTick est un event qui est appelé dans cette même fonction sachant que j'ai modifié le yOffset dans cet event et que ça ne modifie pas la caméra je suis complètement perdu. J'ai aussi trouvé la variable eyeHeight d'EntityPlayer, mais cette variable n'a l'air de ne rien modifier.

    Merci d'avoir lu 😄


  • Yop

    Fait un tour au niveau de morph mod (https://github.com/iChun/Morph), je pence que tu pourrait trouvé se qui t’intéresse 🙂


  • J'ai déjà cherché et c'est très le bordel, c'est incompréhensible ><


  • Heuu bas alors la je ne sais pas trop,il faudrait que tu regard se qu'il se passe quand tu saute,il doit bien y avoir un truc qui change la camera de pose.

    Après quelque recherche j ai vu des truc intersent dans net.minecraft.client.renderer.entity 🙂


  • Nan lorsque je saute c'est la position du joueur qui change et quand je m'accroupis c'est la boite de collision du bloc en dessous.


  • Up ! 🙂

  • Moddeurs confirmés

    Je peux voir les codes pour appeler la méthode setSize(…) ?
    Et pour la hauteur de vue c'est Minecraft.getMinecraft().thePlayer.eyeHeight


  • Voici le code pour le setSize (Tiré de l'API d'iChun) :

    
    public static void forceSetSize(Class clz, Entity ent, float width, float height)
    {
    try
    {
    Method m = clz.getDeclaredMethod("setSize", float.class, float.class);
    m.setAccessible(true);
    m.invoke(ent, width, height);
    }
    catch(IllegalAccessException e)
    {
    e.printStackTrace();
    }
    catch (InvocationTargetException e)
    {
    e.printStackTrace();
    }
    catch (NoSuchMethodException e)
    {
    e.printStackTrace();
    }
    catch (SecurityException e)
    {
    e.printStackTrace();
    }
    }
    
    

    C'est juste un peu de réflexion, après il faut bien sûr adapter pour l'obfuscation 😉

    Pour le eyeHeight, il modifie comme le yOffset la hauteur de séléction, c'est assez zarb O.o


    J'ai trouvé un topic qui traite de ce sujet avec la solution http://www.minecraftforge.net/forum/index.php?topic=17968.0
    Cette dernière change la position de la caméra et fonctionne parfaitement, mais maintenant, la boite de collision est buggée :

    Pour ce qui est de mon code les voici :
    TickHandler :

    
    @SubscribeEvent
    public void tick(TickEvent.RenderTickEvent event) {
    if(event.phase == TickEvent.Phase.START && minecraft.theWorld != null){
    if(!Util.b){
    if (renderer == null) {
    renderer = new EntityRendererCustom(minecraft);
    }
    if (minecraft.entityRenderer != renderer) {
    // be sure to store the previous renderer
    prevRenderer = minecraft.entityRenderer;
    minecraft.entityRenderer = renderer;
    }
    forceSetSize(Entity.class, minecraft.thePlayer, 0.6F, 0.6F);
    } else if (prevRenderer != null && minecraft.entityRenderer != prevRenderer) {
    // reset the renderer
    minecraft.entityRenderer = prevRenderer;
    }
    }
    }
    
    

    EntityRendererCustom :

    
    public class EntityRendererCustom extends EntityRenderer
    {
    private final Minecraft mc;
    private float offsetY = -1F; // just for testing, should be based on actual render size
    
    public EntityRendererCustom(Minecraft mc) {
    super(mc, mc.getResourceManager());
    this.mc = mc;
    }
    
    @Override
    public void updateCameraAndRender(float partialTick) {
    if (mc.thePlayer == null || mc.thePlayer.isPlayerSleeping()){
    super.updateCameraAndRender(partialTick);
    return;
    }
    // this is what changes the actual camera height
    // but also seems to affect the player model render position
    mc.thePlayer.yOffset -= offsetY;
    super.updateCameraAndRender(partialTick);
    mc.thePlayer.yOffset = 1.62F;
    }
    
    @Override
    public void getMouseOver(float partialTick) {
    if (mc.thePlayer == null || mc.thePlayer.isPlayerSleeping()){
    super.getMouseOver(partialTick);
    return;
    }
    // adjust the y position to get a mouseover at eye-level
    // not perfect, as the server posY does not match, meaning
    // that some block clicks do not process correctly
    // (distance check or something like that)
    mc.thePlayer.posY += offsetY;
    mc.thePlayer.prevPosY += offsetY;
    mc.thePlayer.lastTickPosY += offsetY;
    super.getMouseOver(partialTick);
    mc.thePlayer.posY -= offsetY;
    mc.thePlayer.prevPosY -= offsetY;
    mc.thePlayer.lastTickPosY -= offsetY;
    }
    }
    
    

    Y'a pas de RenderPlayerEvent car j'en ai pas besoin.
    Le boolean b ne sert pas à grand chose pour l'instant, c'est juste pour le test.
    Pour rendu du joueur, c'est pas grave, je vais le changer de toute façon.


    PS : La boîte de collision est aux pieds de l'entité et moi je veux qu'elle soit à la tête.

  • Moddeurs confirmés

    (Tiré de l'API d'iChun)

    Dans morph il utilise plutôt l'AT (Access trandformer)
    Sinon la boite de collision du joueur en f5 à toujours été mal affiché donc il faut pas trop s'y fier pour voir où elle est vraiment sur l'axe y.

    PS : La boîte de collision est aux pieds de l'entité et moi je veux qu'elle soit à la tête.

    ça c'est une question de rendu pas de positionnement de la boite de collision, car le rendu est justement positionné à partir de cette boite


  • Y'a pas une technique pour afficher vraiment la boite de collision ? Parce que là je n'ai aucun idée d'où elle est en fait. Lorsque j'essaie de passer en-dessous d'un bloc ça me met comme si j'étais dans un bloc et ça me renvoie.


  • F3+B 🙂


  • Nan mais pour voir la vraie collision du joueur, le f3 + B affiche la boite de collision buggée du joueur. Par contre je ne comprends pas pourquoi le joueur ne peut pas aller en dessous d'un bloc 😕

  • Moddeurs confirmés Rédacteurs Administrateurs

    Il y a smart moving qui change la collision du joueur, tu devrais jeter un coup d’œil à player API : http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/1277996-1-7-10-api-player-api


  • Je veux bien utiliser la PlayerAPI mais bon, si c'est juste pour modifier la caméra… 😕


  • J'ai trouvé l'utilité du eyeHeight, il sert juste à savoir si ta tête est dans un bloc ou pas, je ne peux toujours pas passer en dessous du bloc 😕


  • Donc j'ai trouvé ce qui ne va pas, en fait je ne peux pas passer en dessous d'un bloc à cause d'une condition dans NetHandlerPlayServer méthode processPlayer :

    
    if (flag && (flag1 || !flag2) && !this.playerEntity.isPlayerSleeping() && !this.playerEntity.noClip)
    {
    this.setPlayerLocation(this.lastPosX, this.lastPosY, this.lastPosZ, f1, f2);
    return;
    }
    
    

    ligne 394.
    Il faut donc que je patche la méthode avec de l'ASM.

    
    private static int returns = 0;
    
    private static void patchMethod(MethodNode mn) {
    
    System.out.println("\tPatching method processPlayer in NetHandlerPlayServer");
    InsnList newList = new InsnList();
    
    Iterator <abstractinsnnode>it = mn.instructions.iterator();
    while (it.hasNext()) {
    AbstractInsnNode insn = it.next();
    newList.add(insn);
    if (insn.getOpcode() == Opcodes.RETURN) {
    returns++;
    }
    if(returns == 10){
    newList.remove(insn.getPrevious());
    newList.remove(insn);
    newList.add(new VarInsnNode(Opcodes.ALOAD, 0));
    newList.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "fr/zak/cubesedge/coremod/Patch", "processPlayerPatch"
    , "(L" + className + ";)V"));
    }
    }
    newList.add(new InsnNode(Opcodes.RETURN));
    mn.instructions = newList;
    }
    
    

    et puis ça me fait un crash :

    
    java.lang.VerifyError: Expecting a stackmap frame at branch target 1374
    Exception Details:
    Location:
    net/minecraft/network/NetHandlerPlayServer.processPlayer(Lnet/minecraft/network/play/client/C03PacketPlayer;)V @1321: ifeq
    Reason:
    Expected stackmap frame at this location.
    Bytecode:
    0000000: 2ab4 0054 2ab4 005e b400 d4b6 00d8 4d2a
    0000010: 04b5 006b 2ab4 005e b400 db9a 061d 2ab4
    0000020: 0052 9a00 342b b600 e12a b400 e367 4a2b
    0000030: b600 e62a b400 e897 9a00 1e29 296b 1400
    0000040: e998 9c00 142b b600 ed2a b400 ef97 9a00
    0000050: 082a 04b5 0052 2ab4 0052 9905 b62a b400
    0000060: 5eb4 00f5 c600 d32a b400 5eb4 00f9 380b
    0000070: 2ab4 005e b400 fc38 0c2a b400 5eb4 00f5
    0000080: b601 012a b400 5eb4 0104 3905 2ab4 005e
    0000090: b401 0739 072a b400 5eb4 010a 3909 2bb6
    00000a0: 010d 9900 0f2b b601 1038 0b2b b601 1338
    00000b0: 0c2a b400 5e2b b601 16b5 0119 2ab4 005e
    00000c0: b601 1c2a b400 5e0b b501 1f2a b400 5e18
    00000d0: 0518 0718 0917 0b17 0cb6 0123 2ab4 005e
    00000e0: b400 f5c6 000d 2ab4 005e b400 f5b6 0101
    00000f0: 2ab4 0052 9a00 04b1 2ab4 0054 b601 272a
    0000100: b400 5eb6 012d 2ab4 0052 9900 242a 2ab4
    0000110: 005e b401 04b5 00e8 2a2a b400 5eb4 0107
    0000120: b500 e32a 2ab4 005e b401 0ab5 00ef 2c2a
    0000130: b400 5eb6 0131 b12a b400 5eb6 0134 9900
    0000140: 342a b400 5eb6 011c 2ab4 005e 2ab4 00e8
    0000150: 2ab4 00e3 2ab4 00ef 2ab4 005e b400 f92a
    0000160: b400 5eb4 00fc b601 232c 2ab4 005e b601
    0000170: 31b1 2ab4 005e b401 074a 2a2a b400 5eb4
    0000180: 0104 b500 e82a 2ab4 005e b401 07b5 00e3
    0000190: 2a2a b400 5eb4 010a b500 ef2a b400 5eb4
    00001a0: 0104 3905 2ab4 005e b401 0739 072a b400
    00001b0: 5eb4 010a 3909 2ab4 005e b400 f938 0b2a
    00001c0: b400 5eb4 00fc 380c 2bb6 0137 9900 1e2b
    00001d0: b600 e114 0138 979a 0013 2bb6 013c 1401
    00001e0: 3897 9a00 082b 03b6 0140 2bb6 0137 9900
    00001f0: 8f2b b600 e639 052b b600 e139 072b b600
    0000200: ed39 092b b601 3c2b b600 e167 390d 2ab4
    0000210: 005e b601 349a 0044 180d 1401 4197 9d00
    0000220: 0c18 0d14 0143 989c 0032 2a13 0146 b601
    0000230: 48b2 014a bb01 4c59 b701 4d2a b400 5eb6
    0000240: 0151 b601 5513 0157 b601 5518 0db6 015a
    0000250: b601 5db9 0162 0200 b12b b600 e6b8 0168
    0000260: 1401 6997 9d00 112b b600 edb8 0168 1401
    0000270: 6997 9e00 0b2a 1301 6cb6 0148 b12b b601
    0000280: 0d99 000f 2bb6 0110 380b 2bb6 0113 380c
    0000290: 2ab4 005e b601 1c2a b400 5e0b b501 1f2a
    00002a0: b400 5e2a b400 e82a b400 e32a b400 ef17
    00002b0: 0b17 0cb6 0123 2ab4 0052 9a00 04b1 1805
    00002c0: 2ab4 005e b401 0467 390d 1807 2ab4 005e
    00002d0: b401 0767 390f 1809 2ab4 005e b401 0a67
    00002e0: 3911 180d b801 682a b400 5eb4 016f b801
    00002f0: 68b8 0173 3913 180f b801 682a b400 5eb4
    0000300: 0176 b801 68b8 0173 3915 1811 b801 682a
    0000310: b400 5eb4 0179 b801 68b8 0173 3917 1813
    0000320: 1813 6b18 1518 156b 6318 1718 176b 6339
    0000330: 1918 1914 017a 979e 00a4 2ab4 0054 b601
    0000340: 7e99 0017 2ab4 0054 b601 812a b400 5eb6
    0000350: 0151 b601 879a 0086 b201 4abb 014c 59b7
    0000360: 014d 2ab4 005e b601 51b6 0155 1301 89b6
    0000370: 0155 180d b601 5a13 018b b601 5518 0fb6
    0000380: 015a 1301 8bb6 0155 1811 b601 5a13 018d
    0000390: b601 5518 13b6 015a 1301 8fb6 0155 1815
    00003a0: b601 5a13 018f b601 5518 17b6 015a 1301
    00003b0: 91b6 0155 b601 5db9 0162 0200 2a2a b400
    00003c0: e82a b400 e32a b400 ef2a b400 5eb4 00f9
    00003d0: 2ab4 005e b400 fcb6 0194 b113 0195 381b
    00003e0: 2c2a b400 5e2a b400 5eb4 0199 b601 9f17
    00003f0: 1b8d 171b 8d17 1b8d b601 a3b6 01a7 b901
    0000400: ac01 0036 1c2a b400 5eb4 0119 9900 182b
    0000410: b601 169a 0011 180f 0e97 9e00 0a2a b400
    0000420: 5eb6 01af 2ab4 0052 9a00 04b1 2ab4 005e
    0000430: 180d 180f 1811 b601 b32a b400 5e2b b601
    0000440: 16b5 0119 2ab4 005e 180d 180f 1811 b601
    0000450: b618 0f39 1d18 052a b400 5eb4 0104 6739
    0000460: 0d18 072a b400 5eb4 0107 6739 0f18 0f14
    0000470: 01b7 979d 000c 180f 1401 b998 9c00 060e
    0000480: 390f 1809 2ab4 005e b401 0a67 3911 180d
    0000490: 180d 6b18 0f18 0f6b 6318 1118 116b 6339
    00004a0: 1903 361f 1819 1401 bb97 9e00 3f2a b400
    00004b0: 5eb6 0134 9a00 352a b400 5eb4 01c0 b601
    00004c0: c59a 0028 0436 1fb2 014a bb01 4c59 b701
    00004d0: 4d2a b400 5eb6 0151 b601 5513 01c7 b601
    00004e0: 55b6 015d b901 6202 002a b400 529a 0004
    00004f0: b12a b400 5e18 0518 0718 0917 0b17 0cb6
    0000500: 0123 2c2a b400 5e2a b400 5eb4 0199 b601
    0000510: 9f17 1b8d 171b 8d17 1b8d b601 a3b6 01a7
    0000520: b901 ac01 0036 2015 1c99 0035 151f 9a00
    0000530: 0815 209a 002b 2ab4 005e b601 349a 0021
    0000540: 2ab4 005e b401 ca9a 0017 2a2a b400 e82a
    0000550: b400 e32a b400 ef17 0b17 0cb6 0194 2a2a
    0000560: b400 5e2a b601 9f2a 8d2a 8d2a 8d2a 0e2a
    0000570: 0e2a 3a21 2a2a b400 542a 9a00 592a b400
    0000580: 5e2a b601 c52a 2c2a b601 ce2a 2a2a b401
    0000590: d22a 9a00 412a 2a14 01d3 2a9b 003d 2a2a
    00005a0: 592a 042a b501 d62a 2ab4 01d6 2aa4 002b
    00005b0: 2a2a bb01 4c2a b701 4d2a b400 5e2a b601
    00005c0: 552a b601 552a b901 6202 002a 2a13 01d8
    00005d0: 2a2a b12a 03b5 01d6 2ab4 0052 9a00 04b1
    00005e0: 2ab4 005e 2bb6 0116 b501 192a b400 54b6
    00005f0: 0127 2ab4 005e b601 2d2a b400 5e2a b400
    0000600: 5eb4 0107 2967 2bb6 0116 b601 dca7 002b
    0000610: 2ab4 006d 1014 709a 0021 2a2a b400 e82a
    0000620: b400 e32a b400 ef2a b400 5eb4 00f9 2ab4
    0000630: 005e b400 fcb6 0194 b1b1
    Stackmap Table:
    append_frame(@86,Object[#241])
    full_frame(@177,{Object[#2],Object[#221],Object[#241],Top,Top,Double,Double,Double,Float,Float},{})
    same_frame(@240)
    same_frame(@248)
    same_frame(@302)
    full_frame(@311,{Object[#2],Object[#221],Object[#241]},{})
    same_frame(@370)
    full_frame(@490,{Object[#2],Object[#221],Object[#241],Double,Double,Double,Double,Float,Float},{})
    append_frame(@554,Double)
    same_frame(@601)
    same_frame(@629)
    chop_frame(@637,1)
    same_frame(@656)
    same_frame(@702)
    full_frame(@856,{Object[#2],Object[#221],Object[#241],Double,Double,Double,Double,Float,Float,Double,Double,Double,Double,Double,Double,Double},{})
    same_frame_extended(@987)
    append_frame(@1060,Float,Integer)
    same_frame(@1068)
    append_frame(@1151,Double)
    same_frame(@1154)
    append_frame(@1257,Integer)
    same_frame(@1265)
    append_frame(@1334,Integer)
    same_frame(@1375)
    append_frame(@1491,Object[#411])
    same_frame(@1496)
    same_frame(@1504)
    full_frame(@1552,{Object[#2],Object[#221],Object[#241]},{})
    same_frame(@1592)
    
    at cpw.mods.fml.common.network.handshake.NetworkDispatcher.serverInitiateHandshake(NetworkDispatcher.java:143) ~[NetworkDispatcher.class:?]
    at cpw.mods.fml.common.network.handshake.FMLHandshakeServerState$1.accept(FMLHandshakeServerState.java:21) ~[FMLHandshakeServerState$1.class:?]
    at cpw.mods.fml.common.network.handshake.FMLHandshakeServerState$1.accept(FMLHandshakeServerState.java:15) ~[FMLHandshakeServerState$1.class:?]
    at cpw.mods.fml.common.network.handshake.HandshakeMessageHandler.userEventTriggered(HandshakeMessageHandler.java:40) ~[HandshakeMessageHandler.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.invokeUserEventTriggered(DefaultChannelHandlerContext.java:308) [DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.fireUserEventTriggered(DefaultChannelHandlerContext.java:294) [DefaultChannelHandlerContext.class:?]
    at io.netty.channel.ChannelInboundHandlerAdapter.userEventTriggered(ChannelInboundHandlerAdapter.java:108) [ChannelInboundHandlerAdapter.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.invokeUserEventTriggered(DefaultChannelHandlerContext.java:308) [DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.fireUserEventTriggered(DefaultChannelHandlerContext.java:294) [DefaultChannelHandlerContext.class:?]
    at io.netty.channel.ChannelInboundHandlerAdapter.userEventTriggered(ChannelInboundHandlerAdapter.java:108) [ChannelInboundHandlerAdapter.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.invokeUserEventTriggered(DefaultChannelHandlerContext.java:308) [DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelHandlerContext.fireUserEventTriggered(DefaultChannelHandlerContext.java:294) [DefaultChannelHandlerContext.class:?]
    at io.netty.channel.DefaultChannelPipeline.fireUserEventTriggered(DefaultChannelPipeline.java:779) [DefaultChannelPipeline.class:?]
    at cpw.mods.fml.common.network.handshake.NetworkDispatcher.handlerAdded(NetworkDispatcher.java:132) [NetworkDispatcher.class:?]
    at io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:484) [DefaultChannelPipeline.class:?]
    at io.netty.channel.DefaultChannelPipeline.access$100(DefaultChannelPipeline.java:44) [DefaultChannelPipeline.class:?]
    at io.netty.channel.DefaultChannelPipeline$3.run(DefaultChannelPipeline.java:474) [DefaultChannelPipeline$3.class:?]
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:354) [SingleThreadEventExecutor.class:?]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:348) [NioEventLoop.class:?]
    at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101) [SingleThreadEventExecutor$2.class:?]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_05]
    
    

    C'est sans doute car j'ai pas supprimé les "fload" (opcode) de lastTickPosX, etc.
    Lorsque je fais newList.remove(insn.getPrevious().getPrevious()); ça me fait une nullpointerexception : insn.getPrevious().getPrevious() est null.
    Il est impossible d'obtenir l'AbstractInsnNode précédent du précédent.
    Je ne peux pas supprimer pas le numéro d'index, je ne vois pas du tout comment faire D:</abstractinsnnode>

  • Modérateurs


  • Je préfère utiliser l'ASM, patcher la classe entière pète la compabilité, désolé, sinon je peux patcher la méthode, mais lorsque je supprime tout et que j'appelle ma fonction ça me met Duplicate local variable 'd4' ou je ne sais plus trop quoi.

  • Modérateurs

    Tu peux t'inspirer de Morph sinon.

  • Moddeurs confirmés Rédacteurs Administrateurs

    @'Zak':

    Je préfère utiliser l'ASM, patcher la classe entière pète la compabilité, désolé, sinon je peux patcher la méthode, mais lorsque je supprime tout et que j'appelle ma fonction ça me met Duplicate local variable 'd4' ou je ne sais plus trop quoi.

    Dans les deux cas l'ASM détruit la compatibilité avec n'importe quel mod qui modifie la même classe.