깔때기 및 자동화 시스템 연동 (MC 26.1.2)
이 문서는 Minecraft 26.1.2 버전의 Item Clumps에 대한 깔때기 추출 메커니즘, 전송 속도 동등성, 레드스톤 분류기 안정성 및 보관함 연동에 대해 다룹니다.
📊 기능 정보 상자
| 속성 | 세부 정보 |
|---|---|
| 시스템 이름 | 깔때기 드립 추출 엔진 |
| 대상 클래스 | net.minecraft.world.level.block.entity.HopperBlockEntity |
| 추출 메서드 | HopperBlockEntity.addItem(Container, ItemEntity) |
| 추출 속도 | 8틱당 $1$개 ($2.5$개/초) |
| 아이템 분할 방식 | baseItem.setCount(1) |
| 자동화 호환성 | 바닐라 레드스톤 아이템 분류기 및 필터와 100% 호환 |
⚙️ 자동화 드립 아키텍처
바닐라 Minecraft에서 깔때기는 수량이 $\le 64$이고 공간이 충분하면 ItemEntity 전체를 흡수합니다. 만약 5,000개가 들어있는 대형 뭉치를 한꺼번에 흡수하게 두면 깔때기가 넘치거나 수천 개의 아이템이 증발할 수 있습니다.
Item Clumps는 HopperBlockEntity.addItem을 가로채어 **드립 추출(1개씩 순차 흡수)**을 강제합니다:
┌────────────────────────────┐
│ Hopper Tick Cycle │
│ (Every 8 Game Ticks) │
└─────────────┬──────────────┘
│
▼
┌────────────────────────────┐
│ Is Item Entity Count > 1? │
└─────────────┬──────────────┘
│
┌────────────────┴────────────────┐
│ (Yes) │ (No)
▼ ▼
┌───────────────────────────┐ ┌───────────────────────────┐
│ Clone Single Item Slice │ │ Native Vanilla Extraction │
│ baseItem = stack.copy() │ │ (Standard 1-item / stack) │
│ baseItem.setCount(1) │ └───────────────────────────┘
└─────────────┬─────────────┘
│
▼
┌───────────────────────────┐
│ Try Insert Into Hopper │
│ HopperBlockEntity.addItem │
└─────────────┬─────────────┘
│
┌────────┴────────┐
│ │
(Success) (Failed / Full)
│ │
▼ ▼
┌───────────────────┐ ┌───────────────┐
│ Shrink Ground │ │ Abort Transfer│
│ Clump by 1; │ │ Entity Retains│
│ Refresh Name Tag. │ │ Full Count. │
└───────────────────┘ └───────────────┘💻 실제 Java 소스 코드 구현
Minecraft 26.1.2의 HopperBlockEntityMixin.java 출처:
java
@Inject(method = "addItem(Lnet/minecraft/world/Container;Lnet/minecraft/world/entity/item/ItemEntity;)Z", at = @At("HEAD"), cancellable = true)
private static void item_clumps$customHopperExtract(Container container, ItemEntity entity, CallbackInfoReturnable<Boolean> cir) {
ItemStack itemStack = entity.getItem();
int count = itemStack.getCount();
if (count > 1) {
// Entity is a clump. Extract exactly 1 item.
ItemStack baseItem = itemStack.copy();
baseItem.setCount(1);
ItemStack result = HopperBlockEntity.addItem(null, container, baseItem, null);
if (result.isEmpty()) {
// Hopper successfully absorbed the 1 item. Shrink entity stack.
ItemStack originalStack = entity.getItem();
originalStack.shrink(1);
entity.setItem(originalStack); // Updates standard item tracker and custom name
cir.setReturnValue(true);
} else {
// Hopper was full or couldn't take it
cir.setReturnValue(false);
}
}
}