Skip to content

Mekanisme Pengelompokan Mega-Stack (MC 26.1.2)

Dokumen ini menyajikan rincian teknis dan matematis tentang agregasi item di tanah, perhitungan radius pencarian, dan penggabungan entitas dalam Item Clumps untuk Minecraft 26.1.2.


📊 Kotak Info Fitur

PropertiSpesifikasi
Nama SistemAgregator Mega-Stack Item Tanah
Kelas Targetnet.minecraft.world.entity.item.ItemEntity
Batas Penggabungan Bawaan9.999 item (Dapat dikonfigurasi hingga $2.147.483.647$)
Radius Pencarian ($r$)Horisontal $1$ hingga $10$ blok (Bawaan: $1$ blok)
Injeksi Radius@ModifyArgs pada AABB.inflate(DDD)
GameRules Pengendaliitem_clumps:enable_clumping, item_clumps:max_clump_size, item_clumps:merge_radius

⚙️ Cara Kerja Agregasi Mega-Stack

Dalam vanilla Minecraft, item yang dijatuhkan memanggil mergeWithNeighbours() setiap tick, tetapi vanilla melarang penggabungan jika jumlah item melebihi itemStack.getMaxStackSize() (biasanya 64).

Item Clumps mencegat pemeriksaan ini melalui ItemEntityMixin.java untuk membuka batasan tersebut sembari mempertahankan keamanan komponen data.

                  ┌──────────────────────────────┐
                  │    ItemEntity A Ticks In     │
                  └──────────────┬───────────────┘


                  ┌──────────────────────────────┐
                  │     Feasibility Check        │
                  │  - Matching player target?   │
                  │  - Identical DataComponents? │
                  └──────────────┬───────────────┘
                                 │ (Pass)

                  ┌──────────────────────────────┐
                  │   Combine Stacks Math Check  │
                  └──────────────┬───────────────┘

                 ┌───────────────┴───────────────┐
                 │                               │
    thisCount + otherCount <= maxClump    thisCount + otherCount > maxClump
                 │                               │
                 ▼                               ▼
       ┌───────────────────┐           ┌───────────────────┐
       │   Complete Merge  │           │   Partial Merge   │
       │ Larger absorbs    │           │ Fill entity A to  │
       │ smaller entity;   │           │ maxClumpSize;     │
       │ Younger age kept. │           │ B keeps remainder.│
       └───────────────────┘           └───────────────────┘

📐 Rumus Matematika & Perhitungan Presisi

1. Pelebaran Kotak Batas Horisontal (@ModifyArgs)

$$\text{args.set}(0, r), \quad \text{args.set}(2, r)$$

Di mana:

  • $r = \text{DynamicGameRuleManager}.\text{getInt}(\text{level}, \text{MERGE_RADIUS}) \in [1, 10]$ blok.
  • Indeks ketinggian vertikal ($1$) tidak disentuh, menjaga pemisahan vertikal antar lantai yang berbeda.

2. Matematika Transfer Jumlah Item

  • Penyerapan Penuh ($S \le \text{maxClumpSize}$): $$\text{count}_{\text{merged}} = \text{thisCount} + \text{otherCount}$$
  • Penyerapan Sebagian ($S > \text{maxClumpSize}$): $$\Delta = \text{maxClumpSize} - \text{thisCount}$$ $$\text{thisCount}' = \text{maxClumpSize}, \quad \text{otherCount}' = \text{otherCount} - \Delta$$

💻 Implementasi Kode Sumber Java Asli

Dari ItemEntityMixin.java di Minecraft 26.1.2:

java
@ModifyArgs(method = "mergeWithNeighbours", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/phys/AABB;inflate(DDD)Lnet/minecraft/world/phys/AABB;"))
private void item_clumps$modifySearchRadius(Args args) {
    if (DynamicGameRuleManager.getBoolean(this.level(), ItemClumpsFabric.ENABLE_CLUMPING)) {
        double radius = DynamicGameRuleManager.getInt(this.level(), ItemClumpsFabric.MERGE_RADIUS);
        args.set(0, radius);
        args.set(2, radius);
    }
}

@Inject(method = "tryToMerge", at = @At("HEAD"), cancellable = true)
private void item_clumps$customMerge(ItemEntity other, CallbackInfo ci) {
    if (!DynamicGameRuleManager.getBoolean(this.level(), ItemClumpsFabric.ENABLE_CLUMPING)) return;

    ItemStack thisStack = this.getItem();
    ItemStack otherStack = other.getItem();

    if (!Objects.equals(this.target, ((ItemEntityMixin)(Object)other).target) || 
        !ItemStack.isSameItemSameComponents(thisStack, otherStack)) {
        return;
    }

    int thisCount = thisStack.getCount();
    int otherCount = otherStack.getCount();
    int maxClump = DynamicGameRuleManager.getInt(this.level(), ItemClumpsFabric.MAX_CLUMP_SIZE);

    if (thisCount + otherCount > maxClump) {
        int spaceLeft = maxClump - thisCount;
        if (spaceLeft > 0) {
            thisStack.setCount(maxClump);
            this.setItem(thisStack);
            otherStack.setCount(otherCount - spaceLeft);
            other.setItem(otherStack);
        }
        ci.cancel();
        return;
    }

    // Full Merge: larger stack absorbs the smaller stack
    if (otherCount < thisCount) {
        thisStack.setCount(thisCount + otherCount);
        this.setItem(thisStack);
        this.pickupDelay = Math.max(this.pickupDelay, ((ItemEntityMixin)(Object)other).pickupDelay);
        this.age = Math.min(this.age, ((ItemEntityMixin)(Object)other).age);
        other.discard();
    } else {
        otherStack.setCount(thisCount + otherCount);
        other.setItem(otherStack);
        ((ItemEntityMixin)(Object)other).pickupDelay = Math.max(((ItemEntityMixin)(Object)other).pickupDelay, this.pickupDelay);
        ((ItemEntityMixin)(Object)other).age = Math.min(((ItemEntityMixin)(Object)other).age, this.age);
        this.discard();
    }
    ci.cancel();
}

🔗 Dokumentasi Terkait (MC 26.1.2)

Official documentation & web portal for Dasik Igaijinn mods.