Skip to content

スマート回収とインベントリ分配 (MC 26.2)

本書では、Minecraft 26.2 におけるインベントリへの一括取得、容量シミュレーション、バニラスタック生成、NBT汚染防止を解説します。


📊 機能情報ボックス

項目仕様
システム名スマート一括インベントリ分配エンジン
対象クラスnet.minecraft.world.entity.item.ItemEntity
インベントリ上限バニラ制限を厳守 (通常アイテム: $64$、パール/卵: $16$)
データ純度$100%\text{ 完全なバニラItemStack}$ (独自NBTやタグの付与ゼロ)
回収アニメーションバニラ標準の player.take(this, added) アニメーション&SE
統計追跡バニラの Stats.ITEM_PICKED_UP.get(item) を正常に実行
部分回収完全対応 (入り切らない分は地上に残存)

🎒 スマート回収のライフサイクル

Item Clumps の極めて重要な設計要件は 「インベントリ汚染ゼロ」 です。地上のエンティティが9,999個のアイテムを保持できたとしても、プレイヤーのインベントリのスタック上限が変更または拡張されることは絶対にありません

                ┌──────────────────────────────────────────────┐
                │ Player Collides with Ground Clump (e.g. 500x)│
                └──────────────────────┬───────────────────────┘


                ┌──────────────────────────────────────────────┐
                │        Pickup Validity & Target Check        │
                │     - pickupDelay == 0?                      │
                │     - target == null || target == player?    │
                └──────────────────────┬───────────────────────┘
                                       │ (Pass)

                ┌──────────────────────────────────────────────┐
                │  Single-Batch Native Inventory Dispatch      │
                │       player.getInventory().add(stack)       │
                └──────────────────────┬───────────────────────┘

                     ┌─────────────────┴─────────────────┐
                     │                                   │
              Inventory Has Space                Inventory Becomes Full
                     │                                   │
                     ▼                                   ▼
        ┌─────────────────────────┐         ┌─────────────────────────┐
        │  Entire Clump Absorbed  │         │     Partial Pickup      │
        │ - 500 items transferred │         │ - e.g. 192 items added  │
        │ - Clump entity removed  │         │ - 308 items remain in   │
        │ - Sound & particles play│         │   ground clump entity   │
        └─────────────────────────┘         └─────────────────────────┘

🛡️ NBT汚染ゼロの保証

地上のアイテムは数量を示すカスタムネームタグ (例: 丸石 x500) を表示しますが、プレイヤーのインベントリに入ると:

  1. ネームタグの消去: カスタム名は ItemEntity にのみ付与されており、内部の ItemStack には付与されません。
  2. バニラスタック: インベントリに入るアイテムには独自データが含まれないため、チェストやシュルカーボックス、作業台で既存のアイテムと完全にスタックできます。
  3. 不要データの非残留: 後からサーバーからMODを削除した場合でも、ワールドデータが破損したり異常データが残ることはありません。

💻 実際のJavaソースコード実装

Minecraft 26.2 の ItemEntityMixin.java より:

java
@Inject(method = "playerTouch", at = @At("HEAD"), cancellable = true)
private void item_clumps$smartPickup(Player player, CallbackInfo ci) {
    if (!DynamicGameRuleManager.getBoolean(this.level(), ItemClumpsFabric.ENABLE_CLUMPING) || 
        this.level().isClientSide()) return;

    int count = this.getItem().getCount();
    if (count <= 1) return; // Allow vanilla to handle normal 1-count items

    if (this.pickupDelay == 0 && (this.target == null || this.target.equals(player.getUUID()))) {
        ItemStack pickupStack = this.getItem().copy();
        int originalCount = count;

        // Native batch addition into player inventory
        player.getInventory().add(pickupStack);
        int added = originalCount - pickupStack.getCount();

        if (added > 0) {
            player.take(this, added);
            player.awardStat(net.minecraft.stats.Stats.ITEM_PICKED_UP.get(pickupStack.getItem()), added);

            ItemStack remainingStack = this.getItem().copyWithCount(pickupStack.getCount());
            this.setItem(remainingStack);

            if (pickupStack.getCount() <= 0) {
                player.onItemPickup((ItemEntity) (Object) this);
            }
        }
        ci.cancel(); // Prevent vanilla pickup interference
    }
}

🔗 関連ドキュメント (MC 26.2)

Official documentation & web portal for Dasik Igaijinn mods.