WIP: Anvil crafts

This commit is contained in:
Aleksey 2020-10-05 18:00:44 +03:00
parent e1496cd1ad
commit f44162d2e9
7 changed files with 232 additions and 1 deletions

View file

@ -19,6 +19,7 @@ import net.minecraft.item.Items;
import net.minecraft.loot.context.LootContext; import net.minecraft.loot.context.LootContext;
import net.minecraft.loot.context.LootContextParameters; import net.minecraft.loot.context.LootContextParameters;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import ru.betterend.item.EndHammer; import ru.betterend.item.EndHammer;
import ru.betterend.util.MHelper; import ru.betterend.util.MHelper;

View file

@ -0,0 +1,77 @@
package ru.betterend.mixin.common;
import java.util.List;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.RecipeManager;
import net.minecraft.screen.AnvilScreenHandler;
import net.minecraft.screen.ForgingScreenHandler;
import net.minecraft.screen.Property;
import net.minecraft.screen.ScreenHandlerContext;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.world.World;
import ru.betterend.recipe.AnvilSmithingRecipe;
@Mixin(AnvilScreenHandler.class)
public abstract class AnvilScreenHandlerMixin extends ForgingScreenHandler {
private final World world = this.player.world;
private final RecipeManager recipeManager = this.world.getRecipeManager();
private AnvilSmithingRecipe currentRecipe;
@Final
@Shadow
private Property levelCost;
public AnvilScreenHandlerMixin(ScreenHandlerType<?> type, int syncId, PlayerInventory playerInventory,
ScreenHandlerContext context) {
super(type, syncId, playerInventory, context);
}
@Inject(method = "canTakeOutput", at = @At("RETURN"))
protected void canTakeOutput(PlayerEntity player, boolean present, CallbackInfoReturnable<Boolean> info) {
if (!info.getReturnValue()) {
info.setReturnValue(currentRecipe != null && !currentRecipe.craft(input, player).isEmpty());
}
}
@Inject(method = "onTakeOutput", at = @At("HEAD"), cancellable = true)
protected void onTakeOutput(PlayerEntity player, ItemStack stack, CallbackInfoReturnable<ItemStack> info) {
if (currentRecipe != null) {
this.input.getStack(0).decrement(1);
if (!currentRecipe.matches(input)) {
this.currentRecipe = null;
}
info.cancel();
}
}
@Inject(method = "updateResult", at = @At("HEAD"), cancellable = true)
public void updateResult(CallbackInfo info) {
this.currentRecipe = null;
List<AnvilSmithingRecipe> recipes = this.recipeManager.listAllOfType(AnvilSmithingRecipe.TYPE);
for (AnvilSmithingRecipe entry : recipes) {
if (entry.matches(input)) {
this.currentRecipe = entry;
break;
}
}
if (currentRecipe != null) {
this.levelCost.set(0);
this.output.setStack(0, currentRecipe.getOutput());
this.sendContentUpdates();
info.cancel();
}
}
}

View file

@ -103,6 +103,7 @@ public class AlloyingRecipe implements Recipe<Inventory> {
return this.type; return this.type;
} }
@Override
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public String getGroup() { public String getGroup() {
return this.group; return this.group;

View file

@ -0,0 +1,145 @@
package ru.betterend.recipe;
import com.google.gson.JsonObject;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ToolItem;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.Recipe;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.RecipeType;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import ru.betterend.registry.ItemTagRegistry;
public class AnvilSmithingRecipe implements Recipe<Inventory> {
public final static RecipeType<AnvilSmithingRecipe> TYPE = EndRecipeManager.registerType("smithing");
public final static Serializer SERIALIZER = EndRecipeManager.registerSerializer("smithing", new Serializer());
private final Identifier id;
private final Ingredient input;
private final ItemStack output;
private final int damage;
private final int level;
public AnvilSmithingRecipe(Identifier identifier, Ingredient input, ItemStack output, int level, int damage) {
this.id = identifier;
this.input = input;
this.output = output;
this.level = level;
this.damage = damage;
}
@Override
public RecipeSerializer<?> getSerializer() {
return SERIALIZER;
}
@Override
public boolean isIgnoredInRecipeBook() {
return false;
}
@Override
public ItemStack getOutput() {
return ItemStack.EMPTY;
}
@Override
public boolean matches(Inventory craftingInventory, World world) {
return this.matches(craftingInventory);
}
@Override
public ItemStack craft(Inventory craftingInventory) {
if (!matches(craftingInventory)) return ItemStack.EMPTY;
ItemStack hammer = craftingInventory.getStack(1);
int damage = hammer.getDamage() + this.damage;
if (damage >= hammer.getMaxDamage()) return ItemStack.EMPTY;
hammer.setDamage(damage);
return this.output.copy();
}
public ItemStack craft(Inventory craftingInventory, PlayerEntity player) {
if (!matches(craftingInventory)) return ItemStack.EMPTY;
ItemStack hammer = craftingInventory.getStack(1);
int damage = hammer.getDamage() + this.damage;
if (damage >= hammer.getMaxDamage()) return ItemStack.EMPTY;
hammer.damage(this.damage, player, ((entity) -> {
entity.sendEquipmentBreakStatus(null);
}));
return this.output.copy();
}
public boolean matches(Inventory craftingInventory) {
ItemStack hammer = craftingInventory.getStack(1);
System.out.println(ItemTagRegistry.HAMMERS.values());
if (hammer.isEmpty() || !ItemTagRegistry.HAMMERS.contains(hammer.getItem())) {
return false;
}
int level = ((ToolItem) hammer.getItem()).getMaterial().getMiningLevel();
return level >= this.level && this.input.test(craftingInventory.getStack(0));
}
@Override
@Environment(EnvType.CLIENT)
public boolean fits(int width, int height) {
return true;
}
@Override
public Identifier getId() {
return this.id;
}
@Override
public RecipeType<?> getType() {
return TYPE;
}
public static class Serializer implements RecipeSerializer<AnvilSmithingRecipe> {
@Override
public AnvilSmithingRecipe read(Identifier id, JsonObject json) {
Ingredient input = Ingredient.fromJson(JsonHelper.getObject(json, "input"));
String resultStr = JsonHelper.getString(json, "result");
Identifier resultId = new Identifier(resultStr);
ItemStack output = new ItemStack(Registry.ITEM.getOrEmpty(resultId).orElseThrow(() -> {
return new IllegalStateException("Item: " + resultStr + " does not exists!");
}));
int level = JsonHelper.getInt(json, "level", 0);
int damage = JsonHelper.getInt(json, "damage", 1);
return new AnvilSmithingRecipe(id, input, output, level, damage);
}
@Override
public AnvilSmithingRecipe read(Identifier id, PacketByteBuf packetBuffer) {
Ingredient input = Ingredient.fromPacket(packetBuffer);
ItemStack output = packetBuffer.readItemStack();
int level = packetBuffer.readVarInt();
int damage = packetBuffer.readVarInt();
return new AnvilSmithingRecipe(id, input, output, level, damage);
}
@Override
public void write(PacketByteBuf packetBuffer, AnvilSmithingRecipe recipe) {
recipe.input.write(packetBuffer);
packetBuffer.writeItemStack(recipe.output);
packetBuffer.writeVarInt(recipe.level);
packetBuffer.writeVarInt(recipe.damage);
}
}
}

View file

@ -2,7 +2,11 @@ package ru.betterend.recipe;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.RecipeType;
import ru.betterend.BetterEnd;
import ru.betterend.registry.BlockRegistry; import ru.betterend.registry.BlockRegistry;
import ru.betterend.registry.ItemRegistry; import ru.betterend.registry.ItemRegistry;
@ -68,6 +72,8 @@ public class CraftingRecipes {
RecipeBuilder.make("creeping_moss_dye", Items.CYAN_DYE).setList("#").addMaterial('#', BlockRegistry.CREEPING_MOSS).build(); RecipeBuilder.make("creeping_moss_dye", Items.CYAN_DYE).setList("#").addMaterial('#', BlockRegistry.CREEPING_MOSS).build();
RecipeBuilder.make("umbrella_moss_dye", Items.YELLOW_DYE).setList("#").addMaterial('#', BlockRegistry.UMBRELLA_MOSS).build(); RecipeBuilder.make("umbrella_moss_dye", Items.YELLOW_DYE).setList("#").addMaterial('#', BlockRegistry.UMBRELLA_MOSS).build();
RecipeBuilder.make("umbrella_moss_tall_dye", Items.YELLOW_DYE).setList("#").addMaterial('#', BlockRegistry.UMBRELLA_MOSS_TALL).build(); RecipeBuilder.make("umbrella_moss_tall_dye", Items.YELLOW_DYE).setList("#").addMaterial('#', BlockRegistry.UMBRELLA_MOSS_TALL).build();
EndRecipeManager.addRecipe(AnvilSmithingRecipe.TYPE, new AnvilSmithingRecipe(BetterEnd.makeID("ender_pearl_to_dust"), Ingredient.ofItems(Items.ENDER_PEARL), new ItemStack(ItemRegistry.ENDER_DUST), 4, 1));
} }
private static void registerHelmet(String name, Item material, Item result) { private static void registerHelmet(String name, Item material, Item result) {

View file

@ -11,7 +11,7 @@ import net.minecraft.util.Identifier;
import ru.betterend.BetterEnd; import ru.betterend.BetterEnd;
public class ItemTagRegistry { public class ItemTagRegistry {
public final static Tag<Item> HAMMERS = registerFabricItemTag("hammer"); public final static Tag<Item> HAMMERS = registerFabricItemTag("hammers");
public static Tag<Item> registerItemTag(String name) { public static Tag<Item> registerItemTag(String name) {
return TagRegistry.item(BetterEnd.makeID(name)); return TagRegistry.item(BetterEnd.makeID(name));

View file

@ -10,6 +10,7 @@
"TagGroupLoaderMixin", "TagGroupLoaderMixin",
"CraftingScreenHandlerMixin", "CraftingScreenHandlerMixin",
"GenerationSettingsMixin", "GenerationSettingsMixin",
"AnvilScreenHandlerMixin",
"AbstractBlockMixin", "AbstractBlockMixin",
"LivingEntityMixin", "LivingEntityMixin",
"BiomeMixin" "BiomeMixin"