Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-65029

Hopper minecart collects items far too quickly / ignores TransferCooldown

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Works As Intended
    • None
    • Minecraft 14w31a, Minecraft 1.8, Minecraft 15w40b, Minecraft 15w46a, Minecraft 16w33a, Minecraft 1.11, Minecraft 1.11.2, Minecraft 17w06a, Minecraft 1.12 Pre-Release 6, Minecraft 1.12.2, Minecraft 18w05a, Minecraft 1.13, Minecraft 18w31a, Minecraft 1.13.1, 1.15.2, 20w22a, 1.16.3, 1.17.1
    • None
    • Confirmed
    • Entities

      The bug

      MinecartHoppers completely ignore the TransferCooldown tag.

      The reason

      The variable field_174900_c (BlockPos) is only set in the constructor but after that never changed:

      EntityMinecartHopper.java (1.8)
          public EntityMinecartHopper(World worldIn, double p_i1721_2_, double p_i1721_4_, double p_i1721_6_) {
              super(worldIn, p_i1721_2_, p_i1721_4_, p_i1721_6_);
              this.field_174900_c = BlockPos.ORIGIN;
          }
      

      BlockPos.ORIGIN is new BlockPos(0, 0, 0). So when it later tests if the current BlockPos of the minecart is equal to the stored block pos it will fail (unless it is at 0, 0, 0).
      So is sets the TransferCooldown to 0 and after that tests if it can transfer, so the test will always (unless it is at 0, 0, 0) succeed, causing it to pick up items with a speed of 1 item per tick.
      The reason why the BlockPos is tested might be because the TransferCooldown is initialized with -1, but as the canTransfer() (rather cannotTransfer()) method would then return false it would work anyways.

      EntityMinecartHopper.java (1.8)
      /**
       * Returns whether the hopper cart can currently transfer an item.
       */
      public boolean canTransfer() {
      	// Probably wrong method name from MCP, it is rather cannotTransfer()
      	return this.transferTicker > 0;
      }
      
      /**
       * Called to update the entity's position/logic.
       */
      public void onUpdate() {
          super.onUpdate();
      
          if (!this.worldObj.isRemote && this.isEntityAlive() && this.getBlocked()) {
              BlockPos var1 = new BlockPos(this);
      
              if (var1.equals(this.field_174900_c)) {
                 // This tests if the stored block position (field_174900_c) equals the actual block position and this fails ALWAYS
                  --this.transferTicker;
              }
              else {
                  this.setTransferTicker(0);
              }
      
              if (!this.canTransfer()) {
                  this.setTransferTicker(0);
      
      	    // Tries to transfer the items
                  if (this.func_96112_aD()) {
                      this.setTransferTicker(4);
                      this.markDirty();
                  }
              }
          }
      }
      

      Note

      Testing for getBlocked() seems to be not needed as onUpdate() seems to be called only when the MinecartHopper is not blocked.

      Wrong names

      The wrong names can be caused by MCP as isRemote() is described as
      "This is set to true for client worlds, and false for server worlds."
      which would mean that hopper minecarts would not work in client worlds.
      The method getBlocked() is described like this:
      "Get whether this hopper minecart is being blocked by an activator rail."
      Which makes no sense as well as then a blocked MinecartHopper would collect items.

      I hope it is alright, that I added that much code from Minecraft here

            Unassigned Unassigned
            marcono1234 Marcono1234
            Votes:
            15 Vote for this issue
            Watchers:
            13 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: