private final ItemStackHandler itemHandler = new ItemStackHandler(4) {
@Override
protected void onContentsChanged(int slot) {
setChanged();
}
};
private LazyOptional<IItemHandler> lazyItemHandler = LazyOptional.empty();
//我们的方块有当前反应进度和总反应进度两个数据
protected IIntArray data = new IIntArray() {
public int get(int index) {
switch (index) {
case 0: return VirusGeneratorBlockEntity.this.progress;
case 1: return VirusGeneratorBlockEntity.this.maxProgress;
default: return 0;
}
}
public void set(int index, int value) {
switch(index) {
case 0: VirusGeneratorBlockEntity.this.progress = value; break;
case 1: VirusGeneratorBlockEntity.this.maxProgress = value; break;
}
}
public int getCount() {
return 2;
}
};
private int progress = 0;
private int maxProgress = 72;
public VirusGeneratorBlockEntity() {
super(BlockEntityInit.VIRUS_GENERATOR_BLOCK_ENTITY.get());
this.data=new IIntArray() {
public int get(int index) {
switch (index) {
case 0: return VirusGeneratorBlockEntity.this.progress;
case 1: return VirusGeneratorBlockEntity.this.maxProgress;
default: return 0;
}
}
public void set(int index, int value) {
switch(index) {
case 0: VirusGeneratorBlockEntity.this.progress = value; break;
case 1: VirusGeneratorBlockEntity.this.maxProgress = value; break;
}
}
public int getCount() {
return 2;
}
};
}
@Override
public int getContainerSize() {
return this.items.size();
}
//你机器的名称
@Override
public ITextComponent getDisplayName() {
return new TranslationTextComponent("container.virus_generator");
}
@Override
protected ITextComponent getDefaultName() {
return new TranslationTextComponent("container.virus_generator");
}
public class BlockEntityInit {
public static final DeferredRegister<TileEntityType<?>> BLOCK_ENTITIES =
DeferredRegister.create(ForgeRegistries.TILE_ENTITIES, Utils.MOD_ID);
public class VirusGeneratorRecipe implements IRecipe<Inventory> {
private final ResourceLocation id;
private final ItemStack output;
private final NonNullList<Ingredient> recipeItems;
@Override
public NonNullList<Ingredient> getIngredients() {
return recipeItems;
}
// @Override
// public ItemStack assemble(ItemStackHandler pContainer) {
// return output;
// }
//判断我们两个原料是否和配方中对应的上
@Override
public boolean matches(Inventory pContainer, World p_77569_2_) {
return recipeItems.get(0).test(pContainer.getItem(1))
&& recipeItems.get(1).test(pContainer.getItem(0));
}
@Override
public ItemStack assemble(Inventory p_77572_1_) {
return output;
}
@Override
public boolean canCraftInDimensions(int pWidth, int pHeight) {
return true;
}
@Override
public ItemStack getResultItem() {
return output.copy();
}
@Override
public ResourceLocation getId() {
return id;
}
@Override
public IRecipeSerializer<?> getSerializer() {
return Serializer.INSTANCE;
}
@Override
public IRecipeType<?> getType() {
return Type.INSTANCE;
}
public static class Type implements IRecipeType<VirusGeneratorRecipe> {
private Type() { }
public static final Type INSTANCE = new Type();
public static final String ID = "virus_generator";
}
//我们配方是将.json文件进行转换后在游戏进行判断
public static class Serializer implements IRecipeSerializer<VirusGeneratorRecipe> {
public static final Serializer INSTANCE = new Serializer();
//这个名称很重要,因为我们把这个配方类型定义为了virus_generator
public static final ResourceLocation ID = new ResourceLocation(Utils.MOD_ID,"virus_generator");
public class RecipeInit
{
public static final DeferredRegister<IRecipeSerializer<?>> SERIALIZERS =
DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, Utils.MOD_ID);
//注册我们的配方类
public static final RegistryObject<IRecipeSerializer<?>> VIRUS_GENERATOR_SERIALIZER =
SERIALIZERS.register("virus_generator", () -> VirusGeneratorRecipe.Serializer.INSTANCE);
public static void register(IEventBus eventBus) {
SERIALIZERS.register(eventBus);
}
}
```
#### 在我们的项目主类中的Main函数中将`BlockEntityInit`类进行注册:
```
public Main(){
IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
public class VirusGeneratorScreen extends ContainerScreen<VirusGeneratorMenu> {
//我们的gui图片
private static final ResourceLocation TEXTURE =
new ResourceLocation(Utils.MOD_ID, "textures/gui/virus_generator.png");
public class VirusGeneratorMenu extends Container {
private final VirusGeneratorBlockEntity blockEntity;
private final World level;
private final IIntArray data;
public VirusGeneratorMenu(int pContainerId, PlayerInventory inv, PacketBuffer extraData) {
this(pContainerId, inv, inv.player.level.getBlockEntity(extraData.readBlockPos()), new IntArray(2));
}
public boolean isCrafting() {
return data.get(0) > 0;
}
public int getScaledProgress() {
int progress = this.data.get(0);
int maxProgress = this.data.get(1); // Max Progress
//int progressArrowSize = 26; // This is the height in pixels of your arrow
int progressArrowSize = 13;
return maxProgress != 0 && progress != 0 ? progress * progressArrowSize / maxProgress : 0;
}
// must assign a slot number to each of the slots used by the GUI.
// For this container, we can see both the tile inventory's slots as well as the player inventory slots and the hotbar.
// Each time we add a Slot to the container, it automatically increases the slotIndex, which means
// 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - 8)
// 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35)
// 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - 8)
private static final int HOTBAR_SLOT_COUNT = 9;
private static final int PLAYER_INVENTORY_ROW_COUNT = 3;
private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
private static final int VANILLA_FIRST_SLOT_INDEX = 0;
private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
// 这个和我们上面的槽位对应一致都是4
private static final int TE_INVENTORY_SLOT_COUNT = 4; // must be the number of slots you have!
@Override
public ItemStack quickMoveStack(PlayerEntity playerIn, int index) {
Slot sourceSlot = slots.get(index);
if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; //EMPTY_ITEM
ItemStack sourceStack = sourceSlot.getItem();
ItemStack copyOfSourceStack = sourceStack.copy();
// Check if the slot clicked is one of the vanilla container slots
if (index < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
// This is a vanilla container slot so merge the stack into the tile inventory
if (!moveItemStackTo(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX
+ TE_INVENTORY_SLOT_COUNT, false)) {
return ItemStack.EMPTY; // EMPTY_ITEM
}
} else if (index < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
// This is a TE slot so merge the stack into the players inventory
if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
return ItemStack.EMPTY;
}
} else {
//System.out.println("Invalid slotIndex:" + index);
return ItemStack.EMPTY;
}
// If stack size == 0 (the entire stack was moved) set slot contents to null
if (sourceStack.getCount() == 0) {
sourceSlot.set(ItemStack.EMPTY);
} else {
sourceSlot.setChanged();
}
sourceSlot.onTake(playerIn, sourceStack);
return copyOfSourceStack;
}
public class ModResultSlot extends SlotItemHandler {
public ModResultSlot(IItemHandler itemHandler, int index, int x, int y) {
super(itemHandler, index, x, y);
}
public class MenuInit {
public static final DeferredRegister<ContainerType<?>> MENUS =
DeferredRegister.create(ForgeRegistries.CONTAINERS, Utils.MOD_ID);
//将我们的屏幕信息进行注册
public static final RegistryObject<ContainerType<VirusGeneratorMenu>> VIRUS_GENERATOR_MENU =
registerMenuType(VirusGeneratorMenu::new, "virus_generator_menu");