diff --git a/src/main/java/ru/betterend/BetterEnd.java b/src/main/java/ru/betterend/BetterEnd.java index bb2f54e9..a2ee36a3 100644 --- a/src/main/java/ru/betterend/BetterEnd.java +++ b/src/main/java/ru/betterend/BetterEnd.java @@ -10,6 +10,7 @@ import ru.betterend.effects.EndPotions; import ru.betterend.recipe.AlloyingRecipes; import ru.betterend.recipe.CraftingRecipes; import ru.betterend.recipe.FurnaceRecipes; +import ru.betterend.recipe.InfusionRecipes; import ru.betterend.recipe.SmithingRecipes; import ru.betterend.registry.EndBiomes; import ru.betterend.registry.EndBlockEntities; @@ -45,6 +46,7 @@ public class BetterEnd implements ModInitializer { FurnaceRecipes.register(); AlloyingRecipes.register(); SmithingRecipes.register(); + InfusionRecipes.register(); EndStructures.register(); FabricLoader.getInstance().getEntrypoints("betterend", BetterEndPlugin.class).forEach(BetterEndPlugin::register); diff --git a/src/main/java/ru/betterend/blocks/InfusionPedestal.java b/src/main/java/ru/betterend/blocks/InfusionPedestal.java index 53add7e6..5df746c3 100644 --- a/src/main/java/ru/betterend/blocks/InfusionPedestal.java +++ b/src/main/java/ru/betterend/blocks/InfusionPedestal.java @@ -16,6 +16,7 @@ import net.minecraft.world.BlockView; import net.minecraft.world.World; import ru.betterend.blocks.basis.BlockPedestal; import ru.betterend.blocks.entities.InfusionPedestalEntity; +import ru.betterend.rituals.InfusionRitual; public class InfusionPedestal extends BlockPedestal { private static final VoxelShape SHAPE_DEFAULT; @@ -28,7 +29,28 @@ public class InfusionPedestal extends BlockPedestal { @Override public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + BlockEntity blockEntity = world.getBlockEntity(pos); + InfusionPedestalEntity pedestal = null; + if (blockEntity instanceof InfusionPedestalEntity) { + pedestal = (InfusionPedestalEntity) blockEntity; + if (!pedestal.isEmpty() && pedestal.hasRitual()) { + if (pedestal.getRitual().checkRecipe()) { + return ActionResult.SUCCESS; + } + } + } ActionResult result = super.onUse(state, world, pos, player, hand, hit); + if (result == ActionResult.SUCCESS) { + if (pedestal != null) { + if (pedestal.hasRitual()) { + pedestal.getRitual().checkRecipe(); + } else { + InfusionRitual ritual = new InfusionRitual(world, pos); + pedestal.linkRitual(ritual); + ritual.checkRecipe(); + } + } + } return result; } diff --git a/src/main/java/ru/betterend/blocks/entities/InfusionPedestalEntity.java b/src/main/java/ru/betterend/blocks/entities/InfusionPedestalEntity.java index cb22b342..0c42dc75 100644 --- a/src/main/java/ru/betterend/blocks/entities/InfusionPedestalEntity.java +++ b/src/main/java/ru/betterend/blocks/entities/InfusionPedestalEntity.java @@ -2,23 +2,57 @@ package ru.betterend.blocks.entities; import net.minecraft.block.BlockState; import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + import ru.betterend.rituals.InfusionRitual; public class InfusionPedestalEntity extends PedestalBlockEntity { - private InfusionRitual activeRitual; + private InfusionRitual linkedRitual; + + @Override + public void setLocation(World world, BlockPos pos) { + super.setLocation(world, pos); + if (hasRitual()) { + this.linkedRitual.setLocation(world, pos); + } + } + + public void linkRitual(InfusionRitual ritual) { + this.linkedRitual = ritual; + } + + public InfusionRitual getRitual() { + return this.linkedRitual; + } public boolean hasRitual() { - return this.activeRitual != null; + return this.linkedRitual != null; + } + + @Override + public void tick() { + if (hasRitual()) { + this.linkedRitual.tick(); + } + super.tick(); } @Override public void fromTag(BlockState state, CompoundTag tag) { + if (tag.contains("ritual")) { + this.linkedRitual = new InfusionRitual(world, pos); + this.linkedRitual.fromTag(tag.getCompound("ritual")); + } super.fromTag(state, tag); } @Override public CompoundTag toTag(CompoundTag tag) { + if (hasRitual()) { + tag.put("ritual", linkedRitual.toTag(new CompoundTag())); + } return super.toTag(tag); } } diff --git a/src/main/java/ru/betterend/recipe/InfusionRecipes.java b/src/main/java/ru/betterend/recipe/InfusionRecipes.java new file mode 100644 index 00000000..328dd7b5 --- /dev/null +++ b/src/main/java/ru/betterend/recipe/InfusionRecipes.java @@ -0,0 +1,18 @@ +package ru.betterend.recipe; + +import ru.betterend.recipe.builders.InfusionRecipe; +import ru.betterend.registry.EndBlocks; +import ru.betterend.registry.EndItems; + +public class InfusionRecipes { + public static void register() { + InfusionRecipe.Builder.create("runed_flavolite") + .setInput(EndBlocks.FLAVOLITE.polished) + .setOutput(EndBlocks.FLAVOLITE_RUNED) + .addCatalyst(0, EndItems.CRYSTAL_SHARDS) + .addCatalyst(2, EndItems.CRYSTAL_SHARDS) + .addCatalyst(4, EndItems.CRYSTAL_SHARDS) + .addCatalyst(6, EndItems.CRYSTAL_SHARDS) + .build(); + } +} diff --git a/src/main/java/ru/betterend/recipe/builders/InfusionRecipe.java b/src/main/java/ru/betterend/recipe/builders/InfusionRecipe.java index 118bd966..0bccf0eb 100644 --- a/src/main/java/ru/betterend/recipe/builders/InfusionRecipe.java +++ b/src/main/java/ru/betterend/recipe/builders/InfusionRecipe.java @@ -55,8 +55,8 @@ public class InfusionRecipe implements Recipe { public boolean matches(InfusionRitual inv, World world) { boolean valid = this.input.test(inv.getStack(0)); if (!valid) return false; - for (int i = 1; i < 9; i++) { - valid &= this.catalysts[i].test(inv.getStack(i)); + for (int i = 0; i < 8; i++) { + valid &= this.catalysts[i].test(inv.getStack(i + 1)); } return valid; } @@ -91,7 +91,7 @@ public class InfusionRecipe implements Recipe { return TYPE; } - public InfusionRecipe fromTag(CompoundTag tag) { + public static InfusionRecipe fromTag(CompoundTag tag) { return SERIALIZER.fromTag(tag); } @@ -132,8 +132,8 @@ public class InfusionRecipe implements Recipe { return this; } - public Builder setOutput(ItemStack output) { - this.output = output; + public Builder setOutput(ItemConvertible output) { + this.output = new ItemStack(output); this.output.setCount(1); return this; } diff --git a/src/main/java/ru/betterend/rituals/InfusionRitual.java b/src/main/java/ru/betterend/rituals/InfusionRitual.java index af63af02..6a1eb157 100644 --- a/src/main/java/ru/betterend/rituals/InfusionRitual.java +++ b/src/main/java/ru/betterend/rituals/InfusionRitual.java @@ -1,42 +1,114 @@ package ru.betterend.rituals; -import net.minecraft.block.BlockState; +import java.awt.Point; + +import net.minecraft.block.entity.BlockEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.Inventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundTag; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.world.World; + +import ru.betterend.blocks.entities.InfusionPedestalEntity; +import ru.betterend.blocks.entities.PedestalBlockEntity; import ru.betterend.recipe.builders.InfusionRecipe; public class InfusionRitual implements Inventory { + private static Point[] pedestalsMap = new Point[] { + new Point(0, 3), new Point(2, 2), new Point(3, 0), new Point(2, -2), + new Point(0, -3), new Point(-2, -2), new Point(-3, 0), new Point(-2, 2) + }; - private final World world; - private final BlockPos worldPos; + private World world; + private BlockPos worldPos; private InfusionRecipe activeRecipe; private int progress = 0; private int time = 0; + private InfusionPedestalEntity input; + private PedestalBlockEntity[] catalysts = new PedestalBlockEntity[8]; + public InfusionRitual(World world, BlockPos pos) { this.world = world; this.worldPos = pos; + this.configure(); + } + + public void configure() { + if (world == null || world.isClient || worldPos == null) return; + BlockEntity inputEntity = world.getBlockEntity(worldPos); + if (inputEntity instanceof InfusionPedestalEntity) { + this.input = (InfusionPedestalEntity) inputEntity; + } + int i = 0; + for(Point point : pedestalsMap) { + BlockPos.Mutable checkPos = worldPos.mutableCopy().move(Direction.EAST, point.x).move(Direction.NORTH, point.y); + BlockEntity catalystEntity = world.getBlockEntity(checkPos); + if (catalystEntity instanceof PedestalBlockEntity) { + catalysts[i] = (PedestalBlockEntity) catalystEntity; + i++; + } else { + break; + } + } + } + + public boolean checkRecipe() { + if (!isValid()) return false; + this.activeRecipe = this.world.getRecipeManager().getFirstMatch(InfusionRecipe.TYPE, this, world).orElse(null); + if (activeRecipe != null) { + this.time = this.activeRecipe.getInfusionTime(); + return true; + } + return false; } public void tick() { - if (!hasRecipe()) return; + if (!isValid() || !hasRecipe()) return; this.progress++; if (progress == time) { - + this.input.setStack(0, activeRecipe.craft(this)); + for (PedestalBlockEntity catalyst : catalysts) { + catalyst.clear(); + } + this.activeRecipe = null; + this.progress = 0; + this.time = 0; } } + @Override + public boolean isValid(int slot, ItemStack stack) { + return this.isValid(); + } + + public boolean isValid() { + if (world == null || world.isClient || worldPos == null || input == null) return false; + for (PedestalBlockEntity catalyst : catalysts) { + if (catalyst == null) return false; + } + return true; + } + public boolean hasRecipe() { return this.activeRecipe != null; } + public void setLocation(World world, BlockPos pos) { + this.world = world; + this.worldPos = pos; + this.configure(); + } + @Override public void clear() { - // TODO + if (!isValid()) return; + this.input.clear(); + for (PedestalBlockEntity catalyst : catalysts) { + catalyst.clear(); + } } @Override @@ -51,28 +123,41 @@ public class InfusionRitual implements Inventory { @Override public ItemStack getStack(int slot) { - return null; + if (slot > 8) return ItemStack.EMPTY; + if (slot == 0) { + return this.input.getStack(0); + } else { + return this.catalysts[slot - 1].getStack(0); + } } @Override public ItemStack removeStack(int slot, int amount) { - return null; + return this.removeStack(slot); } @Override public ItemStack removeStack(int slot) { - return null; + if (slot > 8) return ItemStack.EMPTY; + if (slot == 0) { + return this.input.removeStack(0); + } else { + return this.catalysts[slot - 1].getStack(0); + } } @Override public void setStack(int slot, ItemStack stack) { - // TODO + if (slot > 8) return; + if (slot == 0) { + this.input.setStack(0, stack); + } else { + this.catalysts[slot - 1].setStack(0, stack); + } } @Override - public void markDirty() { - // TODO - } + public void markDirty() {} @Override public boolean canPlayerUse(PlayerEntity player) { @@ -80,9 +165,19 @@ public class InfusionRitual implements Inventory { } public void fromTag(CompoundTag tag) { + if (tag.contains("recipe")) { + this.activeRecipe = InfusionRecipe.fromTag(tag.getCompound("recipe")); + this.progress = tag.getInt("progress"); + this.time = tag.getInt("time"); + } } public CompoundTag toTag(CompoundTag tag) { + if (hasRecipe()) { + tag.put("recipe", activeRecipe.toTag(new CompoundTag())); + tag.putInt("progress", progress); + tag.putInt("time", time); + } return tag; } }