/AltarBlockEntitySource.java Secret
Created
April 10, 2023 20:11
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.techtastic.tat.sources; | |
import net.minecraft.core.BlockPos; | |
import net.minecraft.world.level.Level; | |
import net.techtastic.tat.api.altar.source.IAltarSource; | |
import net.techtastic.tat.block.entity.AltarBlockEntity; | |
public class AltarBlockEntitySource implements IAltarSource { | |
private final AltarBlockEntity altar; | |
public AltarBlockEntitySource(AltarBlockEntity altar) { | |
this.altar = altar; | |
} | |
@Override | |
public double getMaxPower() { | |
return this.altar.getMaxPower(); | |
} | |
@Override | |
public double getCurrentPower() { | |
return this.altar.getCurrentPower(); | |
} | |
@Override | |
public double getRange() { | |
return this.altar.getRange(); | |
} | |
@Override | |
public double getRate() { | |
return this.altar.getRate(); | |
} | |
@Override | |
public void setMaxPower(double newMaxPower) { | |
this.altar.setMaxPower(newMaxPower); | |
} | |
@Override | |
public void setCurrentPower(double newPower) { | |
this.altar.setCurrentPower(newPower); | |
} | |
@Override | |
public void setRange(double newRange) { | |
this.altar.setRange(newRange); | |
} | |
@Override | |
public void setRate(double newRate) { | |
this.altar.setRate(newRate); | |
} | |
@Override | |
public boolean drawPowerFromAltar(Level level, BlockPos sink, BlockPos source, double amount) { | |
return this.altar.drawPowerFromAltar(level, sink, source, amount); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.techtastic.tat.api.altar.source; | |
import net.minecraft.core.BlockPos; | |
import net.minecraft.world.level.Level; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Optional; | |
import java.util.concurrent.atomic.AtomicReference; | |
public class AltarSources { | |
private static final List<IAltarSourceProvider> providers = new ArrayList<>(); | |
public static void registerAltarSourceProvider(IAltarSourceProvider provider) { | |
providers.add(provider); | |
} | |
public static IAltarSource testForAltarSource(Level level, BlockPos pos) { | |
if (pos == null) return null; | |
List<IAltarSourceProvider> currentProviders = new ArrayList<>(providers); | |
for (IAltarSourceProvider provider : currentProviders) { | |
Optional<IAltarSource> source = provider.getAltarSource(level, pos); | |
if (source.isPresent()) | |
return source.get(); | |
} | |
return null; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.techtastic.tat.block.entity; | |
import dev.architectury.registry.menu.ExtendedMenuProvider; | |
import net.minecraft.core.BlockPos; | |
import net.minecraft.core.Direction; | |
import net.minecraft.core.NonNullList; | |
import net.minecraft.nbt.CompoundTag; | |
import net.minecraft.network.FriendlyByteBuf; | |
import net.minecraft.network.chat.Component; | |
import net.minecraft.network.chat.TranslatableComponent; | |
import net.minecraft.world.ContainerHelper; | |
import net.minecraft.world.Containers; | |
import net.minecraft.world.SimpleContainer; | |
import net.minecraft.world.WorldlyContainer; | |
import net.minecraft.world.entity.player.Inventory; | |
import net.minecraft.world.entity.player.Player; | |
import net.minecraft.world.entity.player.StackedContents; | |
import net.minecraft.world.inventory.AbstractContainerMenu; | |
import net.minecraft.world.inventory.ContainerData; | |
import net.minecraft.world.inventory.StackedContentsCompatible; | |
import net.minecraft.world.item.ItemStack; | |
import net.minecraft.world.level.Level; | |
import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; | |
import net.minecraft.world.level.block.state.BlockState; | |
import net.minecraft.world.level.levelgen.structure.BoundingBox; | |
import net.techtastic.tat.api.altar.source.AltarSources; | |
import net.techtastic.tat.api.altar.source.IAltarSource; | |
import net.techtastic.tat.block.TATBlockEntities; | |
import net.techtastic.tat.block.custom.DistilleryBlock; | |
import net.techtastic.tat.item.TATItems; | |
import net.techtastic.tat.recipe.DistilleryRecipe; | |
import net.techtastic.tat.screen.DistilleryMenu; | |
import org.jetbrains.annotations.NotNull; | |
import org.jetbrains.annotations.Nullable; | |
import java.util.*; | |
import java.util.concurrent.atomic.AtomicReference; | |
import java.util.function.Predicate; | |
import java.util.stream.Stream; | |
public class DistilleryBlockEntity extends BaseContainerBlockEntity implements StackedContentsCompatible, WorldlyContainer, ExtendedMenuProvider { | |
public NonNullList<ItemStack> inventory; | |
protected final ContainerData data; | |
private int craftProgress = 0; | |
private int maxCraftProgress = 38; | |
private int powerProgress = 0; | |
private int maxPowerProgress = 4; | |
private boolean hasAltar = false; | |
private int ticks = 1; | |
private BlockPos altarPos = null; | |
public DistilleryBlockEntity(BlockPos blockPos, BlockState blockState) { | |
super(TATBlockEntities.DISTILLERY_BLOCK_ENTITY.get(), blockPos, blockState); | |
this.inventory = NonNullList.withSize(7, ItemStack.EMPTY); | |
this.data = new ContainerData() { | |
@Override | |
public int get(int i) { | |
return switch (i) { | |
case 0 -> DistilleryBlockEntity.this.craftProgress; | |
case 1 -> DistilleryBlockEntity.this.maxCraftProgress; | |
case 2 -> DistilleryBlockEntity.this.powerProgress; | |
case 3 -> DistilleryBlockEntity.this.maxPowerProgress; | |
case 4 -> DistilleryBlockEntity.this.hasAltar ? 1 : 0; | |
default -> 0; | |
}; | |
} | |
@Override | |
public void set(int i, int j) { | |
switch (i) { | |
case 0 -> DistilleryBlockEntity.this.craftProgress = j; | |
case 1 -> DistilleryBlockEntity.this.maxCraftProgress = j; | |
case 2 -> DistilleryBlockEntity.this.powerProgress = j; | |
case 3 -> DistilleryBlockEntity.this.maxPowerProgress = j; | |
case 4 -> DistilleryBlockEntity.this.hasAltar = j == 1; | |
} | |
} | |
@Override | |
public int getCount() { | |
return 5; | |
} | |
}; | |
} | |
@Override | |
public Component getDisplayName() { | |
return new TranslatableComponent("block.tat.distillery"); | |
} | |
@Override | |
protected Component getDefaultName() { | |
return new TranslatableComponent("block.tat.distillery"); | |
} | |
@Override | |
protected AbstractContainerMenu createMenu(int i, @NotNull Inventory inventory) { | |
return new DistilleryMenu(i, inventory, this, this.data); | |
} | |
@Override | |
protected void saveAdditional(CompoundTag compoundTag) { | |
ContainerHelper.saveAllItems(compoundTag, this.inventory); | |
compoundTag.putInt("ToilAndTrouble$craftProgress", this.craftProgress); | |
compoundTag.putInt("ToilAndTrouble$powerProgress", this.powerProgress); | |
compoundTag.putBoolean("ToilAndTrouble$hasAltar", this.hasAltar); | |
super.saveAdditional(compoundTag); | |
} | |
@Override | |
public void load(@NotNull CompoundTag compoundTag) { | |
super.load(compoundTag); | |
this.inventory = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); | |
ContainerHelper.loadAllItems(compoundTag, this.inventory); | |
this.craftProgress = compoundTag.getInt("ToilAndTrouble$craftProgress"); | |
this.powerProgress = compoundTag.getInt("ToilAndTrouble$powerProgress"); | |
this.hasAltar = compoundTag.getBoolean("ToilAndTrouble$hasAltar"); | |
} | |
public void drops() { | |
assert this.level != null; | |
Containers.dropContents(this.level, this.worldPosition, this); | |
} | |
public SimpleContainer getContainer() { | |
SimpleContainer container = new SimpleContainer(7); | |
this.inventory.forEach(stack -> | |
container.setItem(this.inventory.indexOf(stack), stack) | |
); | |
return container; | |
} | |
public static void tick(Level pLevel, BlockPos pPos, BlockState pState, DistilleryBlockEntity entity) { | |
if (pLevel.isClientSide) return; | |
System.err.println("This is Ticking!"); | |
int ticks = entity.getTicks(); | |
if (ticks % 5 == 0 || AltarSources.testForAltarSource(pLevel, entity.altarPos) == null) { | |
System.err.println("Uh Oh Spaghetti-o! " + ticks + ", " + entity.altarPos + ", " + entity.hasAltar); | |
entity.altarPos = findNearestAltar(pLevel, pPos); | |
entity.hasAltar = AltarSources.testForAltarSource(pLevel, entity.altarPos) != null; | |
System.err.println("Uh Oh Spaghetti-o 2! " + ticks + ", " + entity.altarPos + ", " + entity.hasAltar); | |
entity.resetTicks(); | |
entity.setChanged(); | |
} | |
int jars = getJarCount(entity); | |
if (pState.getValue(DistilleryBlock.JARS) != jars) { | |
pState.setValue(DistilleryBlock.JARS, switch (jars) { | |
case 0, 1, 2, 3, 4 -> jars; | |
default -> 4; | |
}); | |
entity.setChanged(); | |
} | |
if (!hasRecipe(entity) || !entity.hasAltar) { | |
System.err.println("Has No Recipe or No Altar? " + hasRecipe(entity) + " : " + entity.hasAltar); | |
if (pState.getValue(DistilleryBlock.POWERED)) | |
pLevel.setBlockAndUpdate(pPos, pState.setValue(DistilleryBlock.POWERED, false)); | |
entity.resetCraftProgress(); | |
entity.resetPowerProgress(); | |
entity.setChanged(); | |
return; | |
} | |
IAltarSource altar = AltarSources.testForAltarSource(pLevel, entity.altarPos); | |
System.err.println("Altar? " + altar); | |
if (altar == null) return; | |
System.err.println("Altar Source is not null!"); | |
boolean pullPower = altar.drawPowerFromAltar(pLevel, pPos, entity.altarPos, 2); | |
System.err.println("Can we pull power? " + pullPower); | |
if (!pullPower) { | |
if (pState.getValue(DistilleryBlock.POWERED)) | |
pLevel.setBlockAndUpdate(pPos, pState.setValue(DistilleryBlock.POWERED, false)); | |
return; | |
} | |
if (!pState.getValue(DistilleryBlock.POWERED)) | |
pLevel.setBlockAndUpdate(pPos, pState.setValue(DistilleryBlock.POWERED, true)); | |
entity.powerProgress++; | |
if (entity.powerProgress > entity.maxPowerProgress) { | |
entity.craftProgress++; | |
entity.resetPowerProgress(); | |
} | |
if (entity.craftProgress > entity.maxCraftProgress) { | |
craftItem(entity); | |
entity.resetPowerProgress(); | |
} | |
entity.incrementTicks(); | |
entity.setChanged(); | |
} | |
public int getTicks() { | |
return this.ticks; | |
} | |
public void incrementTicks() { | |
this.ticks += 1; | |
} | |
public void resetTicks() { | |
this.ticks = 1; | |
} | |
public static BlockPos findNearestAltar(Level level, BlockPos center) { | |
Stream<BlockPos> allPositions = | |
BlockPos.betweenClosedStream( | |
BoundingBox.fromCorners( | |
center.offset(-15, -15, -15), | |
center.offset(15, 15, 15))); | |
BlockPos closest = null; | |
for (BlockPos pos : allPositions.toList()) { | |
if (AltarSources.testForAltarSource(level, pos) == null) | |
continue; | |
System.err.println("This block is an Altar! " + pos); | |
if (closest == null || center.distSqr(closest) > center.distSqr(pos)) | |
closest = pos; | |
} | |
return closest; | |
} | |
private static boolean hasRecipe(DistilleryBlockEntity entity) { | |
Level level = entity.level; | |
assert level != null; | |
Optional<DistilleryRecipe> match = level.getRecipeManager() | |
.getRecipeFor(DistilleryRecipe.Type.INSTANCE, entity.getContainer(), level); | |
return match.isPresent() && | |
canInsertItemsIntoOutputSlots(entity, match.get().getOutputs()) && | |
hasJarInSlot(entity, match.get().getJarCount()); | |
} | |
private static boolean hasJarInSlot(DistilleryBlockEntity entity, int required) { | |
return entity.getItem(2).is(TATItems.CLAY_JAR.get()) && entity.getItem(2).getCount() >= required; | |
} | |
private static int getJarCount(DistilleryBlockEntity entity) { | |
return entity.getItem(2).getCount(); | |
} | |
private static void craftItem(DistilleryBlockEntity entity) { | |
Level level = entity.level; | |
assert level != null; | |
Optional<DistilleryRecipe> match = level.getRecipeManager() | |
.getRecipeFor(DistilleryRecipe.Type.INSTANCE, entity.getContainer(), level); | |
if (match.isEmpty()) return; | |
DistilleryRecipe recipe = match.get(); | |
NonNullList<ItemStack> outputs = recipe.getOutputs(); | |
entity.removeItem(0, 1); | |
entity.removeItem(1, 1); | |
entity.removeItem(2, recipe.getJarCount()); | |
addOutput(entity, outputs.get(0), 3); | |
addOutput(entity, outputs.get(1), 4); | |
addOutput(entity, outputs.get(2), 5); | |
addOutput(entity, outputs.get(3), 6); | |
} | |
private static void addOutput(DistilleryBlockEntity entity, ItemStack recipeOutput, int slot) { | |
entity.setItem(slot, new ItemStack(recipeOutput.getItem(), entity.getItem(slot).getCount() + recipeOutput.getCount())); | |
} | |
private void resetCraftProgress() { | |
this.craftProgress = 0; | |
} | |
private void resetPowerProgress() { | |
this.powerProgress = 0; | |
} | |
private static boolean canInsertItemIntoOutputSlot(DistilleryBlockEntity inventory, ItemStack output, int slot) { | |
return inventory.getItem(slot).getItem() == output.getItem() || inventory.getItem(slot).isEmpty(); | |
} | |
private static boolean canInsertItemsIntoOutputSlots(DistilleryBlockEntity inventory, List<ItemStack> results) { | |
return canInsertItemIntoOutputSlot(inventory, results.get(0), 3) && canInsertAmountIntoOutputSlot(inventory, 3) && | |
canInsertItemIntoOutputSlot(inventory, results.get(1), 4) && canInsertAmountIntoOutputSlot(inventory, 4) && | |
canInsertItemIntoOutputSlot(inventory, results.get(2), 5) && canInsertAmountIntoOutputSlot(inventory, 5) && | |
canInsertItemIntoOutputSlot(inventory, results.get(3), 6) && canInsertAmountIntoOutputSlot(inventory, 6); | |
} | |
private static boolean canInsertAmountIntoOutputSlot(DistilleryBlockEntity inventory, int slot) { | |
return inventory.getItem(slot).getMaxStackSize() > inventory.getItem(slot).getCount(); | |
} | |
@Override | |
public int getContainerSize() { | |
return 7; | |
} | |
@Override | |
public boolean isEmpty() { | |
for (ItemStack stack : this.inventory) { | |
if (!stack.isEmpty()) | |
return false; | |
} | |
return true; | |
} | |
@Override | |
public ItemStack getItem(int i) { | |
return this.inventory.get(i); | |
} | |
@Override | |
public ItemStack removeItem(int i, int j) { | |
ItemStack itemStack = ContainerHelper.removeItem(this.inventory, i, j); | |
if (!itemStack.isEmpty()) | |
this.setChanged(); | |
return itemStack; | |
} | |
@Override | |
public ItemStack removeItemNoUpdate(int i) { | |
ItemStack itemStack = this.inventory.get(i); | |
if (itemStack.isEmpty()) | |
return ItemStack.EMPTY; | |
this.inventory.set(i, ItemStack.EMPTY); | |
return itemStack; | |
} | |
@Override | |
public void setItem(int i, @NotNull ItemStack itemStack) { | |
this.inventory.set(i, itemStack); | |
if (!itemStack.isEmpty() && itemStack.getCount() > this.getMaxStackSize()) | |
itemStack.setCount(this.getMaxStackSize()); | |
this.setChanged(); | |
} | |
@Override | |
public boolean stillValid(@NotNull Player player) { | |
return true; | |
} | |
@Override | |
public void clearContent() { | |
this.inventory.clear(); | |
this.setChanged(); | |
} | |
@Override | |
public int[] getSlotsForFace(Direction direction) { | |
return switch (direction) { | |
case UP, NORTH, SOUTH, WEST, EAST -> new int[] {0, 1, 2}; | |
case DOWN -> new int[] {3, 4, 5, 6}; | |
}; | |
} | |
@Override | |
public boolean canPlaceItemThroughFace(int i, @NotNull ItemStack itemStack, @Nullable Direction direction) { | |
return switch (i) { | |
case 0, 1 -> true; | |
case 2 -> itemStack.is(TATItems.CLAY_JAR.get()); | |
default -> false; | |
}; | |
} | |
@Override | |
public boolean canTakeItemThroughFace(int i, @NotNull ItemStack itemStack, @NotNull Direction direction) { | |
return switch (i) { | |
case 0, 1, 2 -> false; | |
default -> true; | |
}; | |
} | |
@Override | |
public void fillStackedContents(StackedContents stackedContents) { | |
this.inventory.forEach(stackedContents::accountStack); | |
} | |
@Override | |
public void saveExtraData(FriendlyByteBuf buf) { | |
buf.writeBlockPos(worldPosition); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.techtastic.tat.api.altar.source; | |
import net.minecraft.core.BlockPos; | |
import net.minecraft.world.level.Level; | |
public interface IAltarSource { | |
default double getRange() { | |
return 0.0; | |
} | |
default void setRange(double newRange) { | |
} | |
default double getCurrentPower() { | |
return 0.0; | |
} | |
default void setCurrentPower(double newPower) { | |
} | |
default double getMaxPower() { | |
return 0.0; | |
} | |
default void setMaxPower(double newMaxPower) { | |
} | |
default double getRate() { | |
return 0.0; | |
} | |
default void setRate(double newRate) { | |
} | |
boolean drawPowerFromAltar(Level level, BlockPos sink, BlockPos source, double amount); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.techtastic.tat.api.altar.source; | |
import net.minecraft.core.BlockPos; | |
import net.minecraft.world.level.Level; | |
import java.util.Optional; | |
public interface IAltarSourceProvider { | |
default Optional<IAltarSource> getAltarSource(Level level, BlockPos pos) { | |
return Optional.empty(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.techtastic.tat.sources; | |
import net.minecraft.core.BlockPos; | |
import net.minecraft.world.level.Level; | |
import net.minecraft.world.level.block.entity.BlockEntity; | |
import net.minecraft.world.level.block.state.BlockState; | |
import net.techtastic.tat.api.altar.source.IAltarSource; | |
import net.techtastic.tat.api.altar.source.IAltarSourceProvider; | |
import net.techtastic.tat.block.custom.AltarBlock; | |
import net.techtastic.tat.block.entity.AltarBlockEntity; | |
import java.util.Optional; | |
public class TATAltarSourceProvider implements IAltarSourceProvider { | |
@Override | |
public Optional<IAltarSource> getAltarSource(Level level, BlockPos pos) { | |
BlockEntity be = level.getBlockEntity(pos); | |
BlockState state = level.getBlockState(pos); | |
System.err.println("Testing " + pos + "and it has " + state + " and " + be); | |
if (be instanceof AltarBlockEntity altar && altar.isMaster()) { | |
System.err.println("This is an Altar and is th Master Altar!"); | |
return Optional.of(new AltarBlockEntitySource(altar)); | |
} | |
else | |
return Optional.empty(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.techtastic.tat; | |
import dev.architectury.registry.ReloadListenerRegistry; | |
import net.minecraft.server.packs.PackType; | |
import net.techtastic.tat.api.altar.augment.AltarAugments; | |
import net.techtastic.tat.api.altar.source.AltarSources; | |
import net.techtastic.tat.augments.TATAugmentProvider; | |
import net.techtastic.tat.dataloader.altar.nature.NatureBlocksDataResolver; | |
import net.techtastic.tat.sources.TATAltarSourceProvider; | |
public class TATExtras { | |
public static void registerResourceListeners() { | |
ReloadListenerRegistry.register(PackType.SERVER_DATA, NatureBlocksDataResolver.loader); | |
} | |
public static void registerAltarAugments() { | |
AltarAugments.registerAltarAugmentProvider(new TATAugmentProvider()); | |
} | |
public static void registerAltarSources() { | |
AltarSources.registerAltarSourceProvider(new TATAltarSourceProvider()); | |
} | |
public static void register() { | |
registerResourceListeners(); | |
registerAltarAugments(); | |
registerAltarSources(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment