End Stone Smelter

This commit is contained in:
Aleksey 2020-09-29 15:26:15 +03:00
parent 257307d93d
commit a542aac45b
18 changed files with 551 additions and 77 deletions

View file

@ -1,7 +1,11 @@
package ru.betterend; package ru.betterend;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.minecraft.util.Identifier;
import ru.betterend.config.MainConfig; import ru.betterend.config.MainConfig;
import ru.betterend.recipe.AlloyingRecipes;
import ru.betterend.recipe.CraftingRecipes; import ru.betterend.recipe.CraftingRecipes;
import ru.betterend.registry.BiomeRegistry; import ru.betterend.registry.BiomeRegistry;
import ru.betterend.registry.BlockEntityRegistry; import ru.betterend.registry.BlockEntityRegistry;
@ -28,6 +32,11 @@ public class BetterEnd implements ModInitializer {
BiomeRegistry.register(); BiomeRegistry.register();
BetterEndBiomeSource.register(); BetterEndBiomeSource.register();
CraftingRecipes.register(); CraftingRecipes.register();
AlloyingRecipes.register();
BlockTagRegistry.register(); BlockTagRegistry.register();
} }
public static Identifier getResId(String path) {
return new Identifier(MOD_ID, path);
}
} }

View file

@ -94,6 +94,7 @@ public class EndStoneSmelter extends BaseBlockWithEntity {
@Override @Override
public int getComparatorOutput(BlockState state, World world, BlockPos pos) { public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
//TODO
return ScreenHandler.calculateComparatorOutput(world.getBlockEntity(pos)); return ScreenHandler.calculateComparatorOutput(world.getBlockEntity(pos));
} }

View file

@ -10,7 +10,9 @@ import com.google.common.collect.Maps;
import it.unimi.dsi.fastutil.objects.Object2IntMap.Entry; import it.unimi.dsi.fastutil.objects.Object2IntMap.Entry;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectIterator; import it.unimi.dsi.fastutil.objects.ObjectIterator;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.LockableContainerBlockEntity; import net.minecraft.block.entity.LockableContainerBlockEntity;
import net.minecraft.entity.ExperienceOrbEntity; import net.minecraft.entity.ExperienceOrbEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
@ -18,15 +20,19 @@ import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventories; import net.minecraft.inventory.Inventories;
import net.minecraft.inventory.SidedInventory; import net.minecraft.inventory.SidedInventory;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemConvertible;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.recipe.BlastingRecipe;
import net.minecraft.recipe.Recipe; import net.minecraft.recipe.Recipe;
import net.minecraft.recipe.RecipeFinder; import net.minecraft.recipe.RecipeFinder;
import net.minecraft.recipe.RecipeInputProvider; import net.minecraft.recipe.RecipeInputProvider;
import net.minecraft.recipe.RecipeType;
import net.minecraft.recipe.RecipeUnlocker; import net.minecraft.recipe.RecipeUnlocker;
import net.minecraft.screen.PropertyDelegate; import net.minecraft.screen.PropertyDelegate;
import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.ScreenHandler;
import net.minecraft.tag.Tag;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText; import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -36,6 +42,7 @@ import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import ru.betterend.BetterEnd; import ru.betterend.BetterEnd;
import ru.betterend.blocks.EndStoneSmelter; import ru.betterend.blocks.EndStoneSmelter;
import ru.betterend.client.gui.EndStoneSmelterScreenHandler; import ru.betterend.client.gui.EndStoneSmelterScreenHandler;
@ -52,51 +59,60 @@ public class EndStoneSmelterBlockEntity extends LockableContainerBlockEntity imp
private final Object2IntOpenHashMap<Identifier> recipesUsed; private final Object2IntOpenHashMap<Identifier> recipesUsed;
protected DefaultedList<ItemStack> inventory; protected DefaultedList<ItemStack> inventory;
protected final PropertyDelegate propertyDelegate; protected final PropertyDelegate propertyDelegate;
private Recipe<?> lastRecipe;
private int smeltTimeTotal;
private int smeltTime;
private int burnTime; private int burnTime;
private int fuelTime; private int fuelTime;
private int smeltTime;
private int smeltTimeTotal;
public EndStoneSmelterBlockEntity() { public EndStoneSmelterBlockEntity() {
super(BlockEntityRegistry.END_STONE_SMELTER); super(BlockEntityRegistry.END_STONE_SMELTER);
this.inventory = DefaultedList.ofSize(4, ItemStack.EMPTY); this.inventory = DefaultedList.ofSize(4, ItemStack.EMPTY);
this.recipesUsed = new Object2IntOpenHashMap<Identifier>(); this.recipesUsed = new Object2IntOpenHashMap<Identifier>();
this.propertyDelegate = new PropertyDelegate() { this.propertyDelegate = new PropertyDelegate() {
public int get(int index) { public int get(int index) {
switch(index) { switch(index) {
case 0: case 0:
return EndStoneSmelterBlockEntity.this.burnTime; return EndStoneSmelterBlockEntity.this.burnTime;
case 1: case 1:
return EndStoneSmelterBlockEntity.this.fuelTime; return EndStoneSmelterBlockEntity.this.fuelTime;
case 2: case 2:
return EndStoneSmelterBlockEntity.this.smeltTime; return EndStoneSmelterBlockEntity.this.smeltTime;
case 3: case 3:
return EndStoneSmelterBlockEntity.this.smeltTimeTotal; return EndStoneSmelterBlockEntity.this.smeltTimeTotal;
default: default:
return 0; return 0;
} }
} }
public void set(int index, int value) { public void set(int index, int value) {
switch(index) { switch(index) {
case 0: case 0:
EndStoneSmelterBlockEntity.this.burnTime = value; EndStoneSmelterBlockEntity.this.burnTime = value;
break; break;
case 1: case 1:
EndStoneSmelterBlockEntity.this.fuelTime = value; EndStoneSmelterBlockEntity.this.fuelTime = value;
break; break;
case 2: case 2:
EndStoneSmelterBlockEntity.this.smeltTime = value; EndStoneSmelterBlockEntity.this.smeltTime = value;
break; break;
case 3: case 3:
EndStoneSmelterBlockEntity.this.smeltTimeTotal = value; EndStoneSmelterBlockEntity.this.smeltTimeTotal = value;
} }
} }
public int size() { public int size() {
return 4; return 4;
} }
}; };
this.registerFuels();
}
private void registerFuels() {
registerFuel(Items.LAVA_BUCKET, 16000);
registerFuel(Blocks.COAL_BLOCK, 12000);
registerFuel(Items.BLAZE_ROD, 2000);
} }
private boolean isBurning() { private boolean isBurning() {
@ -139,14 +155,13 @@ public class EndStoneSmelterBlockEntity extends LockableContainerBlockEntity imp
@Override @Override
public void setStack(int slot, ItemStack stack) { public void setStack(int slot, ItemStack stack) {
//TODO
ItemStack itemStack = this.inventory.get(slot); ItemStack itemStack = this.inventory.get(slot);
boolean stackValid = !stack.isEmpty() && stack.isItemEqualIgnoreDamage(itemStack) && ItemStack.areTagsEqual(stack, itemStack); boolean stackValid = !stack.isEmpty() && stack.isItemEqualIgnoreDamage(itemStack) && ItemStack.areTagsEqual(stack, itemStack);
this.inventory.set(slot, stack); this.inventory.set(slot, stack);
if (stack.getCount() > this.getMaxCountPerStack()) { if (stack.getCount() > getMaxCountPerStack()) {
stack.setCount(this.getMaxCountPerStack()); stack.setCount(getMaxCountPerStack());
} }
if (slot == 0 && !stackValid) { if ((slot == 0 || slot == 1) && !stackValid) {
this.smeltTimeTotal = this.getSmeltTime(); this.smeltTimeTotal = this.getSmeltTime();
this.smeltTime = 0; this.smeltTime = 0;
this.markDirty(); this.markDirty();
@ -154,8 +169,14 @@ public class EndStoneSmelterBlockEntity extends LockableContainerBlockEntity imp
} }
protected int getSmeltTime() { protected int getSmeltTime() {
return this.world.getRecipeManager().getFirstMatch(AlloyingRecipe.TYPE, this, world) int smeltTime = this.world.getRecipeManager().getFirstMatch(AlloyingRecipe.TYPE, this, world)
.map(AlloyingRecipe::getSmeltTime).orElse(350); .map(AlloyingRecipe::getSmeltTime).orElse(0);
if (smeltTime == 0) {
smeltTime = this.world.getRecipeManager().getFirstMatch(RecipeType.BLASTING, this, world)
.map(BlastingRecipe::getCookTime).orElse(200);
smeltTime /= 1.5;
}
return smeltTime;
} }
public void dropExperience(PlayerEntity player) { public void dropExperience(PlayerEntity player) {
@ -165,8 +186,13 @@ public class EndStoneSmelterBlockEntity extends LockableContainerBlockEntity imp
Entry<Identifier> entry = usedRecipes.next(); Entry<Identifier> entry = usedRecipes.next();
world.getRecipeManager().get(entry.getKey()).ifPresent((recipe) -> { world.getRecipeManager().get(entry.getKey()).ifPresent((recipe) -> {
list.add(recipe); list.add(recipe);
AlloyingRecipe alloying = (AlloyingRecipe) recipe; if (recipe instanceof AlloyingRecipe) {
this.dropExperience(player.world, player.getPos(), entry.getIntValue(), alloying.getExperience()); AlloyingRecipe alloying = (AlloyingRecipe) recipe;
this.dropExperience(player.world, player.getPos(), entry.getIntValue(), alloying.getExperience());
} else {
BlastingRecipe blasting = (BlastingRecipe) recipe;
this.dropExperience(player.world, player.getPos(), entry.getIntValue(), blasting.getExperience());
}
}); });
} }
player.unlockRecipes(list); player.unlockRecipes(list);
@ -213,7 +239,123 @@ public class EndStoneSmelterBlockEntity extends LockableContainerBlockEntity imp
@Override @Override
public void tick() { public void tick() {
// TODO Auto-generated method stub boolean initialBurning = this.isBurning();
boolean smelting = false;
if (initialBurning) {
this.burnTime--;
}
boolean burning = this.isBurning();
if (!this.world.isClient) {
ItemStack fuel = this.inventory.get(2);
if (!burning && (fuel.isEmpty() || inventory.get(0).isEmpty() && inventory.get(1).isEmpty())) {
if (!burning && smeltTime > 0) {
this.smeltTime = MathHelper.clamp(smeltTime - 2, 0, smeltTimeTotal);
}
} else {
Recipe<?> recipe = this.world.getRecipeManager().getFirstMatch(AlloyingRecipe.TYPE, this, world).orElse(null);
if (recipe == null) {
recipe = this.world.getRecipeManager().getFirstMatch(RecipeType.BLASTING, this, world).orElse(null);
}
if (!burning && canAcceptRecipeOutput(recipe)) {
this.burnTime = this.getFuelTime(fuel);
this.fuelTime = this.burnTime;
burning = this.isBurning();
if (burning) {
smelting = true;
if (!fuel.isEmpty()) {
Item item = fuel.getItem();
fuel.decrement(1);
if (fuel.isEmpty()) {
Item remainFuel = item.getRecipeRemainder();
this.inventory.set(2, remainFuel == null ? ItemStack.EMPTY : new ItemStack(remainFuel));
}
}
}
}
if (burning && canAcceptRecipeOutput(recipe)) {
this.smeltTime++;
if (smeltTime == smeltTimeTotal) {
this.smeltTime = 0;
this.smeltTimeTotal = this.getSmeltTime();
this.craftRecipe(recipe);
smelting = true;
}
} else {
this.smeltTime = 0;
}
}
if (initialBurning != burning) {
smelting = true;
this.world.setBlockState(pos, world.getBlockState(pos).with(EndStoneSmelter.LIT, burning), 3);
}
}
if (smelting) {
this.markDirty();
}
}
protected boolean canAcceptRecipeOutput(Recipe<?> recipe) {
if (recipe == null) return false;
boolean validInput = false;
if (recipe instanceof AlloyingRecipe) {
validInput = !inventory.get(0).isEmpty() &&
!inventory.get(1).isEmpty();
} else {
validInput = !inventory.get(0).isEmpty() ||
!inventory.get(1).isEmpty();
}
if (validInput) {
ItemStack result = recipe.getOutput();
if (result.isEmpty()) {
return false;
} else {
ItemStack output = this.inventory.get(3);
int outCount = output.getCount();
int total = outCount + result.getCount();
if (output.isEmpty()) {
return true;
} else if (!output.isItemEqualIgnoreDamage(result)) {
return false;
} else if (outCount < this.getMaxCountPerStack() && outCount < output.getMaxCount()) {
return this.getMaxCountPerStack() >= total;
} else {
return output.getCount() < result.getMaxCount();
}
}
}
return false;
}
private void craftRecipe(Recipe<?> recipe) {
if (recipe == null || !canAcceptRecipeOutput(recipe)) return;
ItemStack result = recipe.getOutput();
ItemStack output = this.inventory.get(3);
if (output.isEmpty()) {
this.inventory.set(3, result.copy());
} else if (output.getItem() == result.getItem()) {
output.increment(result.getCount());
}
if (!this.world.isClient) {
this.setLastRecipe(recipe);
}
if (recipe instanceof AlloyingRecipe) {
this.inventory.get(0).decrement(1);
this.inventory.get(1).decrement(1);
} else {
if (!this.inventory.get(0).isEmpty()) {
this.inventory.get(0).decrement(1);
} else {
this.inventory.get(1).decrement(1);
}
}
} }
@Override @Override
@ -230,12 +372,13 @@ public class EndStoneSmelterBlockEntity extends LockableContainerBlockEntity imp
if (recipe != null) { if (recipe != null) {
Identifier recipeId = recipe.getId(); Identifier recipeId = recipe.getId();
this.recipesUsed.addTo(recipeId, 1); this.recipesUsed.addTo(recipeId, 1);
this.lastRecipe = recipe;
} }
} }
@Override @Override
public Recipe<?> getLastRecipe() { public Recipe<?> getLastRecipe() {
return null; return this.lastRecipe;
} }
@Override @Override
@ -318,4 +461,21 @@ public class EndStoneSmelterBlockEntity extends LockableContainerBlockEntity imp
public static boolean canUseAsFuel(ItemStack stack) { public static boolean canUseAsFuel(ItemStack stack) {
return availableFuels.containsKey(stack.getItem()); return availableFuels.containsKey(stack.getItem());
} }
public static void registerFuel(ItemConvertible fuel, int time) {
if (availableFuels.containsKey(fuel)) {
availableFuels.replace(fuel.asItem(), time);
} else {
availableFuels.put(fuel.asItem(), time);
}
}
public static void registerFuel(Tag<Item> tag, int time) {
Iterator<Item> tagItems = tag.values().iterator();
tagItems.forEachRemaining(item -> registerFuel(item, time));
}
public static Map<Item, Integer> availableFuels() {
return availableFuels;
}
} }

View file

@ -5,12 +5,14 @@ import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.RenderLayer;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import ru.betterend.registry.BlockEntityRenderRegistry; import ru.betterend.registry.BlockEntityRenderRegistry;
import ru.betterend.registry.ScreensRegistry;
public class BetterEndClient implements ClientModInitializer { public class BetterEndClient implements ClientModInitializer {
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
registerRenderLayers(); registerRenderLayers();
BlockEntityRenderRegistry.register(); BlockEntityRenderRegistry.register();
ScreensRegistry.register();
} }
private void registerRenderLayers() { private void registerRenderLayers() {

View file

@ -0,0 +1,22 @@
package ru.betterend.client.gui;
import java.util.Set;
import net.minecraft.client.gui.screen.recipebook.BlastFurnaceRecipeBookScreen;
import net.minecraft.item.Item;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import ru.betterend.blocks.entities.EndStoneSmelterBlockEntity;
public class EndStoneSmelterRecipeBookScreen extends BlastFurnaceRecipeBookScreen {
private static final Text TITLE = new TranslatableText("gui.recipebook.toggleRecipes.blastable");
protected Text getToggleCraftableButtonText() {
return TITLE;
}
protected Set<Item> getAllowedFuels() {
return EndStoneSmelterBlockEntity.availableFuels().keySet();
}
}

View file

@ -0,0 +1,128 @@
package ru.betterend.client.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider;
import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget;
import net.minecraft.client.gui.widget.TexturedButtonWidget;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.screen.slot.Slot;
import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.text.StringVisitable;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import ru.betterend.BetterEnd;
public class EndStoneSmelterScreen extends HandledScreen<EndStoneSmelterScreenHandler> implements RecipeBookProvider {
private final static Identifier RECIPE_BUTTON_TEXTURE = new Identifier("textures/gui/recipe_button.png");
private final static Identifier BACKGROUND_TEXTURE = BetterEnd.getResId("textures/gui/smelter_gui.png");
public final EndStoneSmelterRecipeBookScreen recipeBook;
private boolean narrow;
public EndStoneSmelterScreen(EndStoneSmelterScreenHandler handler, PlayerInventory inventory, Text title) {
super(handler, inventory, title);
this.recipeBook = new EndStoneSmelterRecipeBookScreen();
}
public void init() {
super.init();
this.narrow = this.width < 379;
this.recipeBook.initialize(width, height, client, narrow, handler);
this.x = this.recipeBook.findLeftEdge(narrow, width, backgroundWidth);
this.addButton(new TexturedButtonWidget(x + 20, height / 2 - 49, 20, 18, 0, 0, 19, RECIPE_BUTTON_TEXTURE, (buttonWidget) -> {
this.recipeBook.reset(narrow);
this.recipeBook.toggleOpen();
this.x = this.recipeBook.findLeftEdge(narrow, width, backgroundWidth);
((TexturedButtonWidget)buttonWidget).setPos(this.x + 20, height / 2 - 49);
}));
this.titleX = (this.backgroundWidth - this.textRenderer.getWidth((StringVisitable)this.title)) / 2;
}
@Override
public void tick() {
super.tick();
this.recipeBook.update();
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
this.renderBackground(matrices);
if (this.recipeBook.isOpen() && this.narrow) {
this.drawBackground(matrices, delta, mouseX, mouseY);
this.recipeBook.render(matrices, mouseX, mouseY, delta);
} else {
this.recipeBook.render(matrices, mouseX, mouseY, delta);
super.render(matrices, mouseX, mouseY, delta);
this.recipeBook.drawGhostSlots(matrices, x, y, true, delta);
}
this.drawMouseoverTooltip(matrices, mouseX, mouseY);
this.recipeBook.drawTooltip(matrices, x, y, mouseX, mouseY);
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (this.recipeBook.mouseClicked(mouseX, mouseY, button)) {
return true;
} else {
return this.narrow && this.recipeBook.isOpen() ? true : super.mouseClicked(mouseX, mouseY, button);
}
}
@Override
protected void onMouseClick(Slot slot, int invSlot, int clickData, SlotActionType actionType) {
super.onMouseClick(slot, invSlot, clickData, actionType);
this.recipeBook.slotClicked(slot);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
return this.recipeBook.keyPressed(keyCode, scanCode, modifiers) ? false : super.keyPressed(keyCode, scanCode, modifiers);
}
@Override
protected boolean isClickOutsideBounds(double mouseX, double mouseY, int left, int top, int button) {
boolean isMouseOut = mouseX < left || mouseY < top || mouseX >= (left + backgroundWidth) || mouseY >= (top + backgroundHeight);
return this.recipeBook.isClickOutsideBounds(mouseX, mouseY, x, y, backgroundWidth, backgroundHeight, button) && isMouseOut;
}
@Override
public boolean charTyped(char chr, int keyCode) {
return this.recipeBook.charTyped(chr, keyCode) ? true : super.charTyped(chr, keyCode);
}
@Override
public void refreshRecipeBook() {
this.recipeBook.refresh();
}
@Override
public RecipeBookWidget getRecipeBookWidget() {
return this.recipeBook;
}
@Override
protected void drawBackground(MatrixStack matrices, float delta, int mouseX, int mouseY) {
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
this.client.getTextureManager().bindTexture(BACKGROUND_TEXTURE);
this.drawTexture(matrices, x, y, 0, 0, backgroundWidth, backgroundHeight);
int p;
if (handler.isBurning()) {
p = handler.getFuelProgress();
this.drawTexture(matrices, x + 56, y + 36 + 12 - p, 176, 12 - p, 14, p + 1);
}
p = handler.getSmeltProgress();
this.drawTexture(matrices, x + 92, y + 34, 176, 14, p + 1, 16);
}
@Override
public void removed() {
this.recipeBook.close();
super.removed();
}
}

View file

@ -22,6 +22,8 @@ import net.minecraft.world.World;
import ru.betterend.BetterEnd; import ru.betterend.BetterEnd;
import ru.betterend.blocks.EndStoneSmelter; import ru.betterend.blocks.EndStoneSmelter;
import ru.betterend.blocks.entities.EndStoneSmelterBlockEntity; import ru.betterend.blocks.entities.EndStoneSmelterBlockEntity;
import ru.betterend.client.gui.slot.SmelterFuelSlot;
import ru.betterend.client.gui.slot.SmelterOutputSlot;
import ru.betterend.recipe.AlloyingRecipe; import ru.betterend.recipe.AlloyingRecipe;
public class EndStoneSmelterScreenHandler extends AbstractRecipeScreenHandler<Inventory> { public class EndStoneSmelterScreenHandler extends AbstractRecipeScreenHandler<Inventory> {
@ -44,10 +46,10 @@ public class EndStoneSmelterScreenHandler extends AbstractRecipeScreenHandler<In
this.world = playerInventory.player.world; this.world = playerInventory.player.world;
this.addProperties(propertyDelegate); this.addProperties(propertyDelegate);
this.addSlot(new Slot(inventory, 0, 52, 17)); this.addSlot(new Slot(inventory, 0, 45, 17));
this.addSlot(new Slot(inventory, 1, 77, 17)); this.addSlot(new Slot(inventory, 1, 67, 17));
this.addSlot(new SmelterFuelSlot(this, inventory, 2, 56, 53)); this.addSlot(new SmelterFuelSlot(this, inventory, 2, 56, 53));
this.addSlot(new SmelterOutputSlot(playerInventory.player, inventory, 3, 116, 35)); this.addSlot(new SmelterOutputSlot(playerInventory.player, inventory, 3, 129, 35));
for(int i = 0; i < 3; ++i) { for(int i = 0; i < 3; ++i) {
for(int j = 0; j < 9; ++j) { for(int j = 0; j < 9; ++j) {
@ -98,7 +100,7 @@ public class EndStoneSmelterScreenHandler extends AbstractRecipeScreenHandler<In
@Override @Override
public RecipeBookCategory getCategory() { public RecipeBookCategory getCategory() {
return RecipeBookCategory.FURNACE; return RecipeBookCategory.BLAST_FURNACE;
} }
@Override @Override
@ -110,7 +112,7 @@ public class EndStoneSmelterScreenHandler extends AbstractRecipeScreenHandler<In
return this.world.getRecipeManager().getFirstMatch(AlloyingRecipe.TYPE, new SimpleInventory(new ItemStack[]{itemStack}), this.world).isPresent(); return this.world.getRecipeManager().getFirstMatch(AlloyingRecipe.TYPE, new SimpleInventory(new ItemStack[]{itemStack}), this.world).isPresent();
} }
protected boolean isFuel(ItemStack itemStack) { public boolean isFuel(ItemStack itemStack) {
return EndStoneSmelterBlockEntity.canUseAsFuel(itemStack); return EndStoneSmelterBlockEntity.canUseAsFuel(itemStack);
} }

View file

@ -1,9 +1,10 @@
package ru.betterend.client.gui; package ru.betterend.client.gui.slot;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.screen.slot.FurnaceFuelSlot; import net.minecraft.screen.slot.FurnaceFuelSlot;
import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.Slot;
import ru.betterend.client.gui.EndStoneSmelterScreenHandler;
public class SmelterFuelSlot extends Slot { public class SmelterFuelSlot extends Slot {

View file

@ -1,4 +1,4 @@
package ru.betterend.client.gui; package ru.betterend.client.gui.slot;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;

View file

@ -3,14 +3,16 @@ package ru.betterend.recipe;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemConvertible;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.Recipe; import net.minecraft.recipe.Recipe;
import net.minecraft.recipe.RecipeSerializer; import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.RecipeType; import net.minecraft.recipe.RecipeType;
import net.minecraft.tag.Tag;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World; import net.minecraft.world.World;
import ru.betterend.BetterEnd; import ru.betterend.BetterEnd;
import ru.betterend.registry.BlockRegistry; import ru.betterend.registry.BlockRegistry;
@ -18,8 +20,8 @@ import ru.betterend.registry.BlockRegistry;
public class AlloyingRecipe implements Recipe<Inventory> { public class AlloyingRecipe implements Recipe<Inventory> {
public final static String GROUP = "alloying"; public final static String GROUP = "alloying";
public final static RecipeType<AlloyingRecipe> TYPE = registerType(GROUP); public final static RecipeType<AlloyingRecipe> TYPE = EndRecipeManager.registerType(GROUP);
public final static AlloyingRecipeSerializer SERIALIZER = registerSerializer(GROUP, new AlloyingRecipeSerializer()); public final static AlloyingRecipeSerializer SERIALIZER = EndRecipeManager.registerSerializer(GROUP, new AlloyingRecipeSerializer());
protected final RecipeType<?> type; protected final RecipeType<?> type;
protected final Identifier id; protected final Identifier id;
@ -104,15 +106,91 @@ public class AlloyingRecipe implements Recipe<Inventory> {
return new ItemStack(BlockRegistry.END_STONE_SMELTER); return new ItemStack(BlockRegistry.END_STONE_SMELTER);
} }
private static <S extends RecipeSerializer<T>, T extends Recipe<?>> S registerSerializer(String id, S serializer) { public static class Builder {
return Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(BetterEnd.MOD_ID, id), serializer); private final static Builder INSTANCE = new Builder();
}
private static <T extends Recipe<?>> RecipeType<T> registerType(String name) { public static Builder create(String id) {
return Registry.register(Registry.RECIPE_TYPE, new Identifier(BetterEnd.MOD_ID, name), new RecipeType<T>() { INSTANCE.id = BetterEnd.getResId(id);
public String toString() { INSTANCE.primaryInput = null;
return name; INSTANCE.secondaryInput = null;
INSTANCE.output = null;
INSTANCE.experience = 0.0F;
INSTANCE.smeltTime = 350;
return INSTANCE;
}
private Identifier id;
private Ingredient primaryInput;
private Ingredient secondaryInput;
private ItemStack output;
private float experience;
private int smeltTime;
private Builder() {}
public Builder setPrimaryInput(ItemConvertible... inputs) {
this.primaryInput = Ingredient.ofItems(inputs);
return this;
}
public Builder setSecondaryInput(ItemConvertible... inputs) {
this.secondaryInput = Ingredient.ofItems(inputs);
return this;
}
public Builder setPrimaryInput(Tag<Item> input) {
this.primaryInput = Ingredient.fromTag(input);
return this;
}
public Builder setSecondaryInput(Tag<Item> input) {
this.secondaryInput = Ingredient.fromTag(input);
return this;
}
public Builder setInput(ItemConvertible primaryInput, ItemConvertible secondaryInput) {
this.setPrimaryInput(primaryInput);
this.setSecondaryInput(secondaryInput);
return this;
}
public Builder setInput(Tag<Item> primaryInput, Tag<Item> secondaryInput) {
this.setPrimaryInput(primaryInput);
this.setSecondaryInput(secondaryInput);
return this;
}
public Builder setInput(Ingredient primaryInput, Ingredient secondaryInput) {
this.primaryInput = primaryInput;
this.secondaryInput = secondaryInput;
return this;
}
public Builder setOutput(ItemConvertible output, int amount) {
this.output = new ItemStack(output, amount);
return this;
}
public Builder setExpiriense(float amount) {
this.experience = amount;
return this;
}
public Builder setSmeltTime(int time) {
this.smeltTime = time;
return this;
}
public void build() {
if (primaryInput == null) {
throw new IllegalArgumentException("Primary input can't be null!");
} else if(secondaryInput == null) {
throw new IllegalArgumentException("Secondary input can't be null!");
} else if(output == null) {
throw new IllegalArgumentException("Output can't be null!");
} }
}); EndRecipeManager.addRecipe(AlloyingRecipe.TYPE, new AlloyingRecipe(id, primaryInput, secondaryInput, output, experience, smeltTime));
}
} }
} }

View file

@ -0,0 +1,38 @@
package ru.betterend.recipe;
import net.minecraft.block.Blocks;
import net.minecraft.item.Items;
import ru.betterend.registry.ItemRegistry;
public class AlloyingRecipes {
public static void register() {
AlloyingRecipe.Builder.create("additional_iron")
.setInput(Blocks.IRON_ORE, Blocks.IRON_ORE)
.setOutput(Items.IRON_INGOT, 3)
.setExpiriense(2.1F)
.build();
AlloyingRecipe.Builder.create("additional_gold")
.setInput(Blocks.GOLD_ORE, Blocks.GOLD_ORE)
.setOutput(Items.GOLD_INGOT, 3)
.setExpiriense(3F)
.build();
AlloyingRecipe.Builder.create("additional_netherite")
.setInput(Blocks.ANCIENT_DEBRIS, Blocks.ANCIENT_DEBRIS)
.setOutput(Items.NETHERITE_SCRAP, 3)
.setExpiriense(6F)
.setSmeltTime(500)
.build();
AlloyingRecipe.Builder.create("terminite_ingot")
.setInput(Items.IRON_INGOT, ItemRegistry.ENDER_DUST)
.setOutput(ItemRegistry.TERMINITE_INGOT, 1)
.setExpiriense(2.5F)
.setSmeltTime(450)
.build();
AlloyingRecipe.Builder.create("aeternium_ingot")
.setInput(ItemRegistry.TERMINITE_INGOT, Items.NETHERITE_INGOT)
.setOutput(ItemRegistry.AETERNIUM_INGOT, 1)
.setExpiriense(4.5F)
.setSmeltTime(600)
.build();
}
}

View file

@ -1,12 +1,16 @@
package ru.betterend.recipe; package ru.betterend.recipe;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import net.minecraft.recipe.Recipe; import net.minecraft.recipe.Recipe;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.RecipeType; import net.minecraft.recipe.RecipeType;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import ru.betterend.BetterEnd;
public class EndRecipeManager { public class EndRecipeManager {
private static final Map<RecipeType<?>, Map<Identifier, Recipe<?>>> RECIPES = Maps.newHashMap(); private static final Map<RecipeType<?>, Map<Identifier, Recipe<?>>> RECIPES = Maps.newHashMap();
@ -33,13 +37,30 @@ public class EndRecipeManager {
Map<Identifier, Recipe<?>> list = RECIPES.get(type); Map<Identifier, Recipe<?>> list = RECIPES.get(type);
if (list != null) { if (list != null) {
Map<Identifier, Recipe<?>> typeList = result.get(type); Map<Identifier, Recipe<?>> typeList = result.get(type);
list.forEach((id, recipe) -> { if (typeList == null) {
typeList = Maps.newHashMap();
result.put(type, typeList);
}
for (Entry<Identifier, Recipe<?>> entry : list.entrySet()) {
Identifier id = entry.getKey();
if (!typeList.containsKey(id)) if (!typeList.containsKey(id))
typeList.put(id, recipe); typeList.put(id, entry.getValue());
}); }
} }
} }
return result; return result;
} }
static <S extends RecipeSerializer<T>, T extends Recipe<?>> S registerSerializer(String id, S serializer) {
return Registry.register(Registry.RECIPE_SERIALIZER, BetterEnd.getResId(id), serializer);
}
static <T extends Recipe<?>> RecipeType<T> registerType(String name) {
return Registry.register(Registry.RECIPE_TYPE, BetterEnd.getResId(name), new RecipeType<T>() {
public String toString() {
return name;
}
});
}
} }

View file

@ -97,8 +97,8 @@ public class RecipeBuilder {
int height = shape.length; int height = shape.length;
int width = shape[0].length(); int width = shape[0].length();
ItemStack result = new ItemStack(output, count); ItemStack result = new ItemStack(output, count);
Identifier id = new Identifier(BetterEnd.MOD_ID, name); Identifier id = BetterEnd.getResId(name);
DefaultedList<Ingredient> materials = getMaterials(width, height); DefaultedList<Ingredient> materials = this.getMaterials(width, height);
CraftingRecipe recipe = shaped ? new ShapedRecipe(id, group, width, height, materials, result) : new ShapelessRecipe(id, group, result, materials); CraftingRecipe recipe = shaped ? new ShapedRecipe(id, group, width, height, materials, result) : new ShapelessRecipe(id, group, result, materials);
EndRecipeManager.addRecipe(type, recipe); EndRecipeManager.addRecipe(type, recipe);

View file

@ -31,7 +31,7 @@ public class BlockEntityRegistry {
BlockEntityType.Builder.create(ESignBlockEntity::new, getSigns())); BlockEntityType.Builder.create(ESignBlockEntity::new, getSigns()));
public static <T extends BlockEntity> BlockEntityType<T> registerBlockEntity(String id, BlockEntityType.Builder<T> builder) { public static <T extends BlockEntity> BlockEntityType<T> registerBlockEntity(String id, BlockEntityType.Builder<T> builder) {
return Registry.register(Registry.BLOCK_ENTITY_TYPE, new Identifier(BetterEnd.MOD_ID, id), builder.build(null)); return Registry.register(Registry.BLOCK_ENTITY_TYPE, BetterEnd.getResId(id), builder.build(null));
} }
public static void register() {} public static void register() {}

View file

@ -42,12 +42,12 @@ public class BlockRegistry {
public static void register() {} public static void register() {}
public static Block registerBlock(String name, Block block) { public static Block registerBlock(String name, Block block) {
Registry.register(Registry.BLOCK, new Identifier(BetterEnd.MOD_ID, name), block); Registry.register(Registry.BLOCK, BetterEnd.getResId(name), block);
ItemRegistry.registerItem(name, new BlockItem(block, new Item.Settings().group(CreativeTab.END_TAB))); ItemRegistry.registerItem(name, new BlockItem(block, new Item.Settings().group(CreativeTab.END_TAB)));
return block; return block;
} }
public static Block registerBlockNI(String name, Block block) { public static Block registerBlockNI(String name, Block block) {
return Registry.register(Registry.BLOCK, new Identifier(BetterEnd.MOD_ID, name), block); return Registry.register(Registry.BLOCK, BetterEnd.getResId(name), block);
} }
} }

View file

@ -1,10 +1,11 @@
package ru.betterend.registry; package ru.betterend.registry;
import net.fabricmc.fabric.api.tag.TagRegistry; import net.fabricmc.fabric.api.tag.TagRegistry;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.tag.Tag; import net.minecraft.tag.Tag;
import net.minecraft.tag.Tag.Identified; import net.minecraft.tag.Tag.Identified;
import net.minecraft.util.Identifier;
import ru.betterend.BetterEnd; import ru.betterend.BetterEnd;
import ru.betterend.util.TagHelper; import ru.betterend.util.TagHelper;
@ -12,7 +13,7 @@ public class BlockTagRegistry {
public static final Tag.Identified<Block> END_GROUND = makeTag("end_ground"); public static final Tag.Identified<Block> END_GROUND = makeTag("end_ground");
private static Tag.Identified<Block> makeTag(String name) { private static Tag.Identified<Block> makeTag(String name) {
return (Identified<Block>) TagRegistry.block(new Identifier(BetterEnd.MOD_ID, name)); return (Identified<Block>) TagRegistry.block(BetterEnd.getResId(name));
} }
public static void register() { public static void register() {

View file

@ -8,8 +8,8 @@ import net.minecraft.item.BlockItem;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import ru.betterend.BetterEnd; import ru.betterend.BetterEnd;
public class ItemRegistry { public class ItemRegistry {
@ -22,7 +22,7 @@ public class ItemRegistry {
protected static Item registerItem(String name, Item item) { protected static Item registerItem(String name, Item item) {
if (item != Items.AIR) { if (item != Items.AIR) {
Registry.register(Registry.ITEM, new Identifier(BetterEnd.MOD_ID, name), item); Registry.register(Registry.ITEM, BetterEnd.getResId(name), item);
if (item instanceof BlockItem) if (item instanceof BlockItem)
MOD_BLOCKS.add(item); MOD_BLOCKS.add(item);
else else

View file

@ -0,0 +1,11 @@
package ru.betterend.registry;
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry;
import ru.betterend.client.gui.EndStoneSmelterScreen;
import ru.betterend.client.gui.EndStoneSmelterScreenHandler;
public class ScreensRegistry {
public static void register() {
ScreenRegistry.register(EndStoneSmelterScreenHandler.HANDLER_TYPE, EndStoneSmelterScreen::new);
}
}