Add the insolator #17
Binary file not shown.
36
build.gradle
36
build.gradle
@ -133,6 +133,16 @@ repositories {
|
|||||||
includeGroup("org.squiddev")
|
includeGroup("org.squiddev")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maven {
|
||||||
|
// location of the maven that hosts JEI files since January 2023
|
||||||
|
name = "Jared's maven"
|
||||||
|
url = "https://maven.blamejared.com/"
|
||||||
|
}
|
||||||
|
|
||||||
|
maven {
|
||||||
|
url 'https://modmaven.dev/'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -141,25 +151,17 @@ dependencies {
|
|||||||
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
|
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
|
||||||
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
||||||
|
|
||||||
// Real mod deobf dependency examples - these get remapped to your current mappings
|
// compile against the JEI API but do not include it at runtime
|
||||||
// compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency
|
compileOnly(fg.deobf("mezz.jei:jei-${minecraft_version}-common-api:${jei_version}"))
|
||||||
// runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}") // Adds the full JEI mod as a runtime dependency
|
compileOnly(fg.deobf("mezz.jei:jei-${minecraft_version}-forge-api:${jei_version}"))
|
||||||
// implementation fg.deobf("com.tterrag.registrate:Registrate:MC${mc_version}-${registrate_version}") // Adds registrate as a dependency
|
// at runtime, use the full JEI jar for Forge
|
||||||
|
runtimeOnly(fg.deobf("mezz.jei:jei-${minecraft_version}-forge:${jei_version}"))
|
||||||
|
|
||||||
// Examples using mod jars from ./libs
|
// CC:Tweaked API
|
||||||
// implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}")
|
implementation(fg.deobf("org.squiddev:cc-tweaked-${minecraft_version}:${cct_version}"))
|
||||||
|
|
||||||
// For more info...
|
// Mekanism: useful for testing energy and so on.
|
||||||
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
|
runtimeOnly(fg.deobf("mekanism:Mekanism:${minecraft_version}-${mekanism_version}"))
|
||||||
// http://www.gradle.org/docs/current/userguide/dependency_management.html
|
|
||||||
|
|
||||||
// Vanilla (i.e. for multi-loader systems)
|
|
||||||
// compileOnly("cc.tweaked:cc-tweaked-${minecraft_version}-common-api:${cct_version}")
|
|
||||||
|
|
||||||
// Forge Gradle
|
|
||||||
// compileOnly("cc.tweaked:cc-tweaked-${minecraft_version}-core-api:${cct_version}")
|
|
||||||
// compileOnly(fg.deobf("cc.tweaked:cc-tweaked-${minecraft_version}-forge-api:${cct_version}"))
|
|
||||||
implementation fg.deobf("org.squiddev:cc-tweaked-${minecraft_version}:${cct_version}")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This task will expand all declared properties from Gradle (gradle.properties) in the specified resource targets.
|
// This task will expand all declared properties from Gradle (gradle.properties) in the specified resource targets.
|
||||||
|
@ -39,6 +39,10 @@ mapping_version=2022.11.27-1.19.2
|
|||||||
|
|
||||||
# The version of CC:Tweaked we're building against
|
# The version of CC:Tweaked we're building against
|
||||||
cct_version=1.101.3
|
cct_version=1.101.3
|
||||||
|
# The version of JEI that we're building against
|
||||||
|
jei_version=11.6.0.1015
|
||||||
|
# The version of Mekanism we use when testing
|
||||||
|
mekanism_version=10.3.8.477
|
||||||
|
|
||||||
## Mod Properties
|
## Mod Properties
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ import net.banutama.utamacraft.block.custom.ModBlocks;
|
|||||||
import net.banutama.utamacraft.block.entity.ModBlockEntities;
|
import net.banutama.utamacraft.block.entity.ModBlockEntities;
|
||||||
import net.banutama.utamacraft.item.ModItems;
|
import net.banutama.utamacraft.item.ModItems;
|
||||||
|
|
||||||
|
import net.banutama.utamacraft.networking.ModMessages;
|
||||||
|
import net.banutama.utamacraft.recipe.ModRecipes;
|
||||||
import net.banutama.utamacraft.screen.InsolatorScreen;
|
import net.banutama.utamacraft.screen.InsolatorScreen;
|
||||||
import net.banutama.utamacraft.screen.ModMenuTypes;
|
import net.banutama.utamacraft.screen.ModMenuTypes;
|
||||||
import net.banutama.utamacraft.sound.ModSounds;
|
import net.banutama.utamacraft.sound.ModSounds;
|
||||||
@ -38,12 +40,16 @@ public class Utamacraft {
|
|||||||
CCRegistration.register(bus);
|
CCRegistration.register(bus);
|
||||||
ModMenuTypes.register(bus);
|
ModMenuTypes.register(bus);
|
||||||
ModSounds.register(bus);
|
ModSounds.register(bus);
|
||||||
|
ModRecipes.register(bus);
|
||||||
|
|
||||||
bus.addListener(this::commonSetup);
|
bus.addListener(this::commonSetup);
|
||||||
MinecraftForge.EVENT_BUS.register(this);
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void commonSetup(final FMLCommonSetupEvent event) {
|
private void commonSetup(final FMLCommonSetupEvent event) {
|
||||||
|
event.enqueueWork(() -> {
|
||||||
|
ModMessages.register();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Mod.EventBusSubscriber(modid = MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
|
@Mod.EventBusSubscriber(modid = MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||||
|
@ -6,6 +6,7 @@ import net.banutama.utamacraft.networking.ModMessages;
|
|||||||
import net.banutama.utamacraft.networking.packet.EnergySyncPacket;
|
import net.banutama.utamacraft.networking.packet.EnergySyncPacket;
|
||||||
import net.banutama.utamacraft.networking.packet.FluidSyncPacket;
|
import net.banutama.utamacraft.networking.packet.FluidSyncPacket;
|
||||||
import net.banutama.utamacraft.networking.packet.ItemStackSyncPacket;
|
import net.banutama.utamacraft.networking.packet.ItemStackSyncPacket;
|
||||||
|
import net.banutama.utamacraft.recipe.InsolatorRecipe;
|
||||||
import net.banutama.utamacraft.screen.InsolatorMenu;
|
import net.banutama.utamacraft.screen.InsolatorMenu;
|
||||||
import net.banutama.utamacraft.util.ModEnergyStorage;
|
import net.banutama.utamacraft.util.ModEnergyStorage;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
@ -25,6 +26,7 @@ import net.minecraft.world.item.Items;
|
|||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.material.Fluids;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
import net.minecraftforge.common.capabilities.ForgeCapabilities;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
@ -33,11 +35,14 @@ import net.minecraftforge.fluids.FluidStack;
|
|||||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||||
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
import net.minecraftforge.fluids.capability.templates.FluidTank;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
import net.minecraftforge.items.ItemStackHandler;
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class InsolatorBlockEntity extends BlockEntity implements MenuProvider, EnergySyncPacket.EnergySyncReceiver, FluidSyncPacket.FluidSyncReceiver, ItemStackSyncPacket.ItemStackSyncReceiver {
|
public class InsolatorBlockEntity extends BlockEntity implements MenuProvider, EnergySyncPacket.EnergySyncReceiver, FluidSyncPacket.FluidSyncReceiver, ItemStackSyncPacket.ItemStackSyncReceiver {
|
||||||
private static final Logger LOGGER = LogUtils.getLogger();
|
private static final Logger LOGGER = LogUtils.getLogger();
|
||||||
|
|
||||||
@ -73,12 +78,16 @@ public class InsolatorBlockEntity extends BlockEntity implements MenuProvider, E
|
|||||||
@Override
|
@Override
|
||||||
public void onEnergyChanged() {
|
public void onEnergyChanged() {
|
||||||
setChanged();
|
setChanged();
|
||||||
ModMessages.sendToClients(new EnergySyncPacket(energy, getBlockPos()));
|
ModMessages.sendToClients(new EnergySyncPacket(energy, capacity, getBlockPos()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public IEnergyStorage getEnergyStorage() {
|
||||||
|
return this.energyStorage;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void receiveEnergySync(int energy) {
|
public void receiveEnergySync(int energy, int capacity) {
|
||||||
energyStorage.setEnergy(energy);
|
energyStorage.setEnergy(energy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,9 +96,14 @@ public class InsolatorBlockEntity extends BlockEntity implements MenuProvider, E
|
|||||||
protected void onContentsChanged() {
|
protected void onContentsChanged() {
|
||||||
setChanged();
|
setChanged();
|
||||||
if (level != null && !level.isClientSide()) {
|
if (level != null && !level.isClientSide()) {
|
||||||
ModMessages.sendToClients(new FluidSyncPacket(fluid, worldPosition));
|
ModMessages.sendToClients(new FluidSyncPacket(fluid, worldPosition));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFluidValid(FluidStack stack) {
|
||||||
|
return stack.getFluid() == Fluids.WATER;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public FluidStack getFluidStack() {
|
public FluidStack getFluidStack() {
|
||||||
@ -147,7 +161,7 @@ public class InsolatorBlockEntity extends BlockEntity implements MenuProvider, E
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public AbstractContainerMenu createMenu(int pContainerId, @NotNull Inventory pPlayerInventory, @NotNull Player pPlayer) {
|
public AbstractContainerMenu createMenu(int pContainerId, @NotNull Inventory pPlayerInventory, @NotNull Player pPlayer) {
|
||||||
ModMessages.sendToClients(new EnergySyncPacket(this.energyStorage.getEnergyStored(), getBlockPos()));
|
ModMessages.sendToClients(new EnergySyncPacket(this.energyStorage.getEnergyStored(), this.energyStorage.getMaxEnergyStored(), getBlockPos()));
|
||||||
ModMessages.sendToClients(new FluidSyncPacket(this.fluidTank.getFluid(), getBlockPos()));
|
ModMessages.sendToClients(new FluidSyncPacket(this.fluidTank.getFluid(), getBlockPos()));
|
||||||
return new InsolatorMenu(pContainerId, pPlayerInventory, this, this.data);
|
return new InsolatorMenu(pContainerId, pPlayerInventory, this, this.data);
|
||||||
}
|
}
|
||||||
@ -223,9 +237,10 @@ public class InsolatorBlockEntity extends BlockEntity implements MenuProvider, E
|
|||||||
|
|
||||||
boolean newActive;
|
boolean newActive;
|
||||||
|
|
||||||
if (entity.canCraft()) {
|
if (entity.canCraft().isPresent() && entity.hasEnoughEnergy()) {
|
||||||
++entity.progress;
|
++entity.progress;
|
||||||
newActive = true;
|
newActive = true;
|
||||||
|
entity.energyStorage.extractEnergy(ENERGY_REQUIRED, false);
|
||||||
setChanged(level, pos, state);
|
setChanged(level, pos, state);
|
||||||
|
|
||||||
if (entity.progress >= entity.maxProgress) {
|
if (entity.progress >= entity.maxProgress) {
|
||||||
@ -242,6 +257,28 @@ public class InsolatorBlockEntity extends BlockEntity implements MenuProvider, E
|
|||||||
state = state.setValue(InsolatorBlock.ACTIVE, newActive);
|
state = state.setValue(InsolatorBlock.ACTIVE, newActive);
|
||||||
level.setBlock(pos, state, 3);
|
level.setBlock(pos, state, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ItemStack fluid = entity.itemHandler.getStackInSlot(0);
|
||||||
|
if (fluid.getCount() > 0) {
|
||||||
|
fluid.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresent(handler -> {
|
||||||
|
// Remove as much as we need, but no more than a bucket
|
||||||
|
int amount = Math.min(entity.fluidTank.getSpace(), 1000);
|
||||||
|
|
||||||
|
// Simulate removal of that amount from the IFluidHandlerItem
|
||||||
|
FluidStack stack = handler.drain(amount, IFluidHandler.FluidAction.SIMULATE);
|
||||||
|
|
||||||
|
// Ensure that the fluid we would use is valid
|
||||||
|
if (entity.fluidTank.isFluidValid(stack)) {
|
||||||
|
// Remove the amount of fluid from the IFluidHandlerItem
|
||||||
|
stack = handler.drain(amount, IFluidHandler.FluidAction.EXECUTE);
|
||||||
|
// Fill our fluid tank with the fluid stack we drained from the IFluidHandlerItem
|
||||||
|
entity.fluidTank.fill(stack, IFluidHandler.FluidAction.EXECUTE);
|
||||||
|
// Extract the current item from the fluid slot? TODO: Should this be when empty?
|
||||||
|
entity.itemHandler.extractItem(0, 1, false);
|
||||||
|
entity.itemHandler.insertItem(0, handler.getContainer(), false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetProgress() {
|
private void resetProgress() {
|
||||||
@ -249,38 +286,80 @@ public class InsolatorBlockEntity extends BlockEntity implements MenuProvider, E
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void craftItem() {
|
private void craftItem() {
|
||||||
ItemStack stack = itemHandler.extractItem(1, 1, false);
|
Optional<InsolatorRecipe> recipe = canCraft();
|
||||||
stack.grow(1);
|
if (recipe.isEmpty()) {
|
||||||
itemHandler.insertItem(2, stack, false);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drain the amount of fluid specified in our recipe from the fluid tank
|
||||||
|
fluidTank.drain(recipe.get().getFluid().getAmount(), IFluidHandler.FluidAction.EXECUTE);
|
||||||
|
|
||||||
|
// Remove an item from the input slot.
|
||||||
|
itemHandler.extractItem(1, 1, false);
|
||||||
|
|
||||||
|
// Insert the recipe output in to the output slot.
|
||||||
|
ItemStack output = itemHandler.getStackInSlot(2);
|
||||||
|
if (output.isEmpty()) {
|
||||||
|
itemHandler.setStackInSlot(2, recipe.get().getResultItem().copy());
|
||||||
|
} else {
|
||||||
|
output.grow(recipe.get().getResultItem().getCount());
|
||||||
|
}
|
||||||
|
|
||||||
resetProgress();
|
resetProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean canCraft() {
|
private boolean hasEnoughEnergy() {
|
||||||
ItemStack input = itemHandler.getStackInSlot(1);
|
return energyStorage.getEnergyStored() >= ENERGY_REQUIRED * maxProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<InsolatorRecipe> canCraft() {
|
||||||
|
Optional<InsolatorRecipe> recipe = getRecipe();
|
||||||
|
if (recipe.isEmpty()) {
|
||||||
|
// LOGGER.info("Insolator cannot find recipe");
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure that the correct fluid is in the tank.
|
||||||
|
if (!fluidTank.getFluid().equals(recipe.get().getFluid())) {
|
||||||
|
// LOGGER.info("Insolator does not have correct fluid; contains {}, expected {}",
|
||||||
|
// fluidTank.getFluid().getFluid(), recipe.get().getFluid().getFluid());
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that we have enough fluid
|
||||||
|
if (fluidTank.getFluidAmount() < recipe.get().getFluid().getAmount()) {
|
||||||
|
// LOGGER.info("Insolator has {} of fluid; recipe requires {}", fluidTank.getFluidAmount(), recipe.get().getFluid().getAmount());
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
ItemStack output = itemHandler.getStackInSlot(2);
|
ItemStack output = itemHandler.getStackInSlot(2);
|
||||||
|
|
||||||
if (input.isEmpty()) {
|
// If the output isn't empty, and the item in the output is different to the output of the recipe, we cannot process.
|
||||||
return false;
|
if (!output.isEmpty() && output.getItem() != recipe.get().getResultItem().getItem()) {
|
||||||
}
|
// LOGGER.info("Cannot run insolator, as output item is not the same as the recipe output");
|
||||||
|
return Optional.empty();
|
||||||
// Make sure that the item in the input is a flower.
|
|
||||||
if (input.getItem() != Items.CORNFLOWER) {
|
|
||||||
LOGGER.info("Cannot run insolator, as item is not recognized");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the output isn't empty, and the item in the output is different to the input, we cannot process.
|
|
||||||
if (!output.isEmpty() && output.getItem() != input.getItem()) {
|
|
||||||
LOGGER.info("Cannot run insolator, as output item is not the same as the input item");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that the output is not saturated.
|
// Make sure that the output is not saturated.
|
||||||
if (output.getCount() >= output.getMaxStackSize()) {
|
if (output.getCount() + recipe.get().getResultItem().getCount() > output.getMaxStackSize()) {
|
||||||
LOGGER.info("Cannot run insolator, as output of {} items exceeds maximum of {}", output.getCount(), output.getMaxStackSize());
|
// LOGGER.info("Cannot run insolator, as output of {} items exceeds maximum of {}", output.getCount(), output.getMaxStackSize());
|
||||||
return false;
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return recipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<InsolatorRecipe> getRecipe() {
|
||||||
|
if (level == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleContainer inventory = new SimpleContainer(itemHandler.getSlots());
|
||||||
|
for (int slot = 0; slot < itemHandler.getSlots(); ++slot) {
|
||||||
|
inventory.setItem(slot, itemHandler.getStackInSlot(slot));
|
||||||
|
}
|
||||||
|
|
||||||
|
return level.getRecipeManager()
|
||||||
|
.getRecipeFor(InsolatorRecipe.Type.INSTANCE, inventory, level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,21 +13,25 @@ import java.util.function.Supplier;
|
|||||||
|
|
||||||
public class EnergySyncPacket extends BasePacket {
|
public class EnergySyncPacket extends BasePacket {
|
||||||
private final int energy;
|
private final int energy;
|
||||||
|
private final int capacity;
|
||||||
private final BlockPos pos;
|
private final BlockPos pos;
|
||||||
|
|
||||||
public EnergySyncPacket(int energy, BlockPos pos) {
|
public EnergySyncPacket(int energy, int capacity, BlockPos pos) {
|
||||||
this.energy = energy;
|
this.energy = energy;
|
||||||
|
this.capacity = capacity;
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EnergySyncPacket(@NotNull FriendlyByteBuf buf) {
|
public EnergySyncPacket(@NotNull FriendlyByteBuf buf) {
|
||||||
this.energy = buf.readInt();
|
this.energy = buf.readInt();
|
||||||
|
this.capacity = buf.readInt();
|
||||||
this.pos = buf.readBlockPos();
|
this.pos = buf.readBlockPos();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toBytes(@NotNull FriendlyByteBuf buf) {
|
public void toBytes(@NotNull FriendlyByteBuf buf) {
|
||||||
buf.writeInt(energy);
|
buf.writeInt(energy);
|
||||||
|
buf.writeInt(capacity);
|
||||||
buf.writeBlockPos(pos);
|
buf.writeBlockPos(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +46,7 @@ public class EnergySyncPacket extends BasePacket {
|
|||||||
|
|
||||||
BlockEntity blockEntity = level.getBlockEntity(pos);
|
BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||||
if (blockEntity instanceof EnergySyncReceiver energyReceiver) {
|
if (blockEntity instanceof EnergySyncReceiver energyReceiver) {
|
||||||
energyReceiver.receiveEnergySync(energy);
|
energyReceiver.receiveEnergySync(energy, capacity);
|
||||||
|
|
||||||
Player player = Minecraft.getInstance().player;
|
Player player = Minecraft.getInstance().player;
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
@ -51,7 +55,7 @@ public class EnergySyncPacket extends BasePacket {
|
|||||||
|
|
||||||
if (player.containerMenu instanceof EnergySyncReceiverMenu menu &&
|
if (player.containerMenu instanceof EnergySyncReceiverMenu menu &&
|
||||||
menu.getBlockEntity().getBlockPos().equals(pos)) {
|
menu.getBlockEntity().getBlockPos().equals(pos)) {
|
||||||
menu.receiveEnergySync(energy);
|
menu.receiveEnergySync(energy, capacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -60,7 +64,7 @@ public class EnergySyncPacket extends BasePacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface EnergySyncReceiver {
|
public interface EnergySyncReceiver {
|
||||||
void receiveEnergySync(int energy);
|
void receiveEnergySync(int energy, int capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface EnergySyncReceiverMenu extends EnergySyncReceiver {
|
public interface EnergySyncReceiverMenu extends EnergySyncReceiver {
|
||||||
|
@ -8,12 +8,10 @@ import net.minecraft.world.item.ItemStack;
|
|||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
import net.minecraftforge.items.ItemStackHandler;
|
|
||||||
import net.minecraftforge.network.NetworkEvent;
|
import net.minecraftforge.network.NetworkEvent;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@ -27,7 +25,7 @@ public class ItemStackSyncPacket extends BasePacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ItemStackSyncPacket(IItemHandler handler, BlockPos pos) {
|
public ItemStackSyncPacket(IItemHandler handler, BlockPos pos) {
|
||||||
this.stacks = NonNullList.withSize(handler.getSlots(), ItemStack.EMPTY);
|
this.stacks = NonNullList.create();
|
||||||
for (int slot = 0; slot < handler.getSlots(); ++slot) {
|
for (int slot = 0; slot < handler.getSlots(); ++slot) {
|
||||||
this.stacks.add(handler.getStackInSlot(slot));
|
this.stacks.add(handler.getStackInSlot(slot));
|
||||||
}
|
}
|
||||||
@ -36,7 +34,12 @@ public class ItemStackSyncPacket extends BasePacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ItemStackSyncPacket(@NotNull FriendlyByteBuf buf) {
|
public ItemStackSyncPacket(@NotNull FriendlyByteBuf buf) {
|
||||||
this.stacks = buf.readCollection((int size) -> NonNullList.withSize(size, ItemStack.EMPTY), FriendlyByteBuf::readItem);
|
List<ItemStack> stacks = buf.readCollection(ArrayList::new, FriendlyByteBuf::readItem);
|
||||||
|
this.stacks = NonNullList.withSize(stacks.size(), ItemStack.EMPTY);
|
||||||
|
for (int slot = 0; slot < stacks.size(); ++slot) {
|
||||||
|
this.stacks.set(slot, stacks.get(slot));
|
||||||
|
}
|
||||||
|
|
||||||
this.pos = buf.readBlockPos();
|
this.pos = buf.readBlockPos();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,108 @@
|
|||||||
|
package net.banutama.utamacraft.recipe;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.mojang.serialization.JsonOps;
|
||||||
|
import net.banutama.utamacraft.Utamacraft;
|
||||||
|
import net.minecraft.core.NonNullList;
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.GsonHelper;
|
||||||
|
import net.minecraft.world.SimpleContainer;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.crafting.*;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class InsolatorRecipe implements Recipe<SimpleContainer> {
|
||||||
|
private final ResourceLocation id;
|
||||||
|
private final ItemStack output;
|
||||||
|
private final Ingredient input;
|
||||||
|
private final FluidStack fluid;
|
||||||
|
|
||||||
|
public InsolatorRecipe(ResourceLocation id, ItemStack output, Ingredient input, FluidStack fluid) {
|
||||||
|
this.id = id;
|
||||||
|
this.output = output;
|
||||||
|
this.input = input;
|
||||||
|
this.fluid = fluid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(@NotNull SimpleContainer pContainer, @NotNull Level pLevel) {
|
||||||
|
if (pLevel.isClientSide()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return input.test(pContainer.getItem(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ItemStack assemble(@NotNull SimpleContainer pContainer) {
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCraftInDimensions(int pWidth, int pHeight) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FluidStack getFluid() {
|
||||||
|
return fluid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ItemStack getResultItem() {
|
||||||
|
return output.copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ResourceLocation getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull RecipeSerializer<?> getSerializer() {
|
||||||
|
return Serializer.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull RecipeType<?> getType() {
|
||||||
|
return Type.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Type implements RecipeType<InsolatorRecipe> {
|
||||||
|
public static final Type INSTANCE = new Type();
|
||||||
|
public static final String ID = "insolator";
|
||||||
|
private Type() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Serializer implements RecipeSerializer<InsolatorRecipe> {
|
||||||
|
public static final Serializer INSTANCE = new Serializer();
|
||||||
|
public static final ResourceLocation ID = new ResourceLocation(Utamacraft.MOD_ID, "insolator");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull InsolatorRecipe fromJson(@NotNull ResourceLocation pRecipeId, @NotNull JsonObject pSerializedRecipe) {
|
||||||
|
ItemStack output = ShapedRecipe.itemStackFromJson(GsonHelper.getAsJsonObject(pSerializedRecipe, "output"));
|
||||||
|
Ingredient input = Ingredient.fromJson(pSerializedRecipe.getAsJsonObject("input"));
|
||||||
|
FluidStack fluid = FluidStack.CODEC.decode(JsonOps.INSTANCE, pSerializedRecipe.get("fluid")).result().orElseThrow().getFirst();
|
||||||
|
return new InsolatorRecipe(pRecipeId, output, input, fluid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable InsolatorRecipe fromNetwork(@NotNull ResourceLocation pRecipeId, @NotNull FriendlyByteBuf pBuffer) {
|
||||||
|
ItemStack output = pBuffer.readItem();
|
||||||
|
Ingredient input = Ingredient.fromNetwork(pBuffer);
|
||||||
|
FluidStack fluid = pBuffer.readFluidStack();
|
||||||
|
return new InsolatorRecipe(pRecipeId, output, input, fluid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toNetwork(@NotNull FriendlyByteBuf pBuffer, @NotNull InsolatorRecipe pRecipe) {
|
||||||
|
pBuffer.writeItemStack(pRecipe.output, false);
|
||||||
|
pRecipe.input.toNetwork(pBuffer);
|
||||||
|
pBuffer.writeFluidStack(pRecipe.fluid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
src/main/java/net/banutama/utamacraft/recipe/ModRecipes.java
Normal file
20
src/main/java/net/banutama/utamacraft/recipe/ModRecipes.java
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package net.banutama.utamacraft.recipe;
|
||||||
|
|
||||||
|
import net.banutama.utamacraft.Utamacraft;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
|
import net.minecraftforge.registries.DeferredRegister;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
import net.minecraftforge.registries.RegistryObject;
|
||||||
|
|
||||||
|
public class ModRecipes {
|
||||||
|
public static final DeferredRegister<RecipeSerializer<?>> SERIALIZERS =
|
||||||
|
DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, Utamacraft.MOD_ID);
|
||||||
|
|
||||||
|
public static final RegistryObject<RecipeSerializer<InsolatorRecipe>> INSOLATOR_SERIALIZER =
|
||||||
|
SERIALIZERS.register("insolator", () -> InsolatorRecipe.Serializer.INSTANCE);
|
||||||
|
|
||||||
|
public static void register(IEventBus bus) {
|
||||||
|
SERIALIZERS.register(bus);
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ package net.banutama.utamacraft.screen;
|
|||||||
import com.mojang.logging.LogUtils;
|
import com.mojang.logging.LogUtils;
|
||||||
import net.banutama.utamacraft.block.custom.ModBlocks;
|
import net.banutama.utamacraft.block.custom.ModBlocks;
|
||||||
import net.banutama.utamacraft.block.entity.InsolatorBlockEntity;
|
import net.banutama.utamacraft.block.entity.InsolatorBlockEntity;
|
||||||
|
import net.banutama.utamacraft.networking.packet.EnergySyncPacket;
|
||||||
import net.banutama.utamacraft.networking.packet.FluidSyncPacket;
|
import net.banutama.utamacraft.networking.packet.FluidSyncPacket;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
@ -17,12 +18,14 @@ import net.minecraftforge.items.SlotItemHandler;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
public class InsolatorMenu extends AbstractContainerMenu implements FluidSyncPacket.FluidSyncReceiverMenu {
|
public class InsolatorMenu extends AbstractContainerMenu implements FluidSyncPacket.FluidSyncReceiverMenu, EnergySyncPacket.EnergySyncReceiverMenu {
|
||||||
private static final Logger LOGGER = LogUtils.getLogger();
|
private static final Logger LOGGER = LogUtils.getLogger();
|
||||||
public final InsolatorBlockEntity blockEntity;
|
public final InsolatorBlockEntity blockEntity;
|
||||||
private final Level level;
|
private final Level level;
|
||||||
private final ContainerData data;
|
private final ContainerData data;
|
||||||
private FluidStack fluid;
|
private FluidStack fluid;
|
||||||
|
private int energy = 0;
|
||||||
|
private int capacity = 0;
|
||||||
|
|
||||||
public InsolatorMenu(int id, Inventory inventory, FriendlyByteBuf extraData) {
|
public InsolatorMenu(int id, Inventory inventory, FriendlyByteBuf extraData) {
|
||||||
this(id, inventory, inventory.player.level.getBlockEntity(extraData.readBlockPos()), new SimpleContainerData(3));
|
this(id, inventory, inventory.player.level.getBlockEntity(extraData.readBlockPos()), new SimpleContainerData(3));
|
||||||
@ -37,6 +40,8 @@ public class InsolatorMenu extends AbstractContainerMenu implements FluidSyncPac
|
|||||||
this.data = data;
|
this.data = data;
|
||||||
this.blockEntity = insolator;
|
this.blockEntity = insolator;
|
||||||
this.fluid = insolator.getFluidStack();
|
this.fluid = insolator.getFluidStack();
|
||||||
|
this.energy = insolator.getEnergyStorage().getEnergyStored();
|
||||||
|
this.capacity = insolator.getEnergyStorage().getMaxEnergyStored();
|
||||||
|
|
||||||
addPlayerInventory(inventory);
|
addPlayerInventory(inventory);
|
||||||
addPlayerHotbar(inventory);
|
addPlayerHotbar(inventory);
|
||||||
@ -58,20 +63,38 @@ public class InsolatorMenu extends AbstractContainerMenu implements FluidSyncPac
|
|||||||
this.fluid = fluid;
|
this.fluid = fluid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receiveEnergySync(int energy, int capacity) {
|
||||||
|
this.energy = energy;
|
||||||
|
this.capacity = capacity;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockEntity getBlockEntity() {
|
public BlockEntity getBlockEntity() {
|
||||||
return blockEntity;
|
return blockEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCrafting() {
|
public FluidStack getFluid() {
|
||||||
return data.get(0) > 0;
|
return fluid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getScaledProgress(int scale) {
|
public int getEnergy() {
|
||||||
|
return energy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEnergyCapacity() {
|
||||||
|
return capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCrafting() {
|
||||||
|
return data.get(2) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getScaledProgress() {
|
||||||
int progress = this.data.get(0);
|
int progress = this.data.get(0);
|
||||||
int maxProgress = this.data.get(1);
|
int maxProgress = this.data.get(1);
|
||||||
|
|
||||||
return maxProgress != 0 && progress != 0 ? progress * scale / maxProgress : 0;
|
return maxProgress != 0 && progress != 0 ? (float)progress / (float)maxProgress : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -3,19 +3,30 @@ package net.banutama.utamacraft.screen;
|
|||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import net.banutama.utamacraft.Utamacraft;
|
import net.banutama.utamacraft.Utamacraft;
|
||||||
|
import net.banutama.utamacraft.screen.utils.FluidSprite;
|
||||||
|
import net.banutama.utamacraft.screen.utils.MouseUtils;
|
||||||
|
import net.banutama.utamacraft.screen.utils.TiledSprite;
|
||||||
|
import net.banutama.utamacraft.screen.utils.TooltipUtils;
|
||||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
import net.minecraft.client.renderer.GameRenderer;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.entity.player.Inventory;
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.level.material.Fluids;
|
||||||
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class InsolatorScreen extends AbstractContainerScreen<InsolatorMenu> {
|
public class InsolatorScreen extends AbstractContainerScreen<InsolatorMenu> {
|
||||||
private static final ResourceLocation TEXTURE =
|
private static final ResourceLocation TEXTURE =
|
||||||
new ResourceLocation(Utamacraft.MOD_ID, "textures/gui/insolator_gui.png");
|
new ResourceLocation(Utamacraft.MOD_ID, "textures/gui/insolator_gui.png");
|
||||||
|
|
||||||
public InsolatorScreen(InsolatorMenu menu, Inventory inventory, Component component) {
|
public InsolatorScreen(InsolatorMenu menu, Inventory inventory, Component component) {
|
||||||
super(menu, inventory, component);
|
super(menu, inventory, component);
|
||||||
|
inventoryLabelY += 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -27,12 +38,72 @@ public class InsolatorScreen extends AbstractContainerScreen<InsolatorMenu> {
|
|||||||
int x = (width - imageWidth) / 2;
|
int x = (width - imageWidth) / 2;
|
||||||
int y = (height - imageHeight) / 2;
|
int y = (height - imageHeight) / 2;
|
||||||
blit(stack, x, y, 0, 0, imageWidth, imageHeight);
|
blit(stack, x, y, 0, 0, imageWidth, imageHeight);
|
||||||
|
renderBulb(stack, x, y);
|
||||||
renderProgressArrow(stack, x, y);
|
renderProgressArrow(stack, x, y);
|
||||||
|
renderFluid(stack, x + 33, y + 16);
|
||||||
|
renderEnergy(stack, x + 46, y + 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderLabels(@NotNull PoseStack pPoseStack, int pMouseX, int pMouseY) {
|
||||||
|
int x = (width - imageWidth) / 2;
|
||||||
|
int y = (height - imageHeight) / 2;
|
||||||
|
|
||||||
|
if (MouseUtils.isMouseOver(pMouseX, pMouseY, x + 32, y + 15, 11, 61)) {
|
||||||
|
List<Component> components = TooltipUtils.getFluidTooltip(menu.getFluid(), 64000);
|
||||||
|
renderTooltip(pPoseStack, components, Optional.empty(),
|
||||||
|
pMouseX - x, pMouseY - y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MouseUtils.isMouseOver(pMouseX, pMouseY, x + 45, y + 15, 11, 61)) {
|
||||||
|
List<Component> components = TooltipUtils.getEnergyTooltip(getMenu().getEnergy(), getMenu().getEnergyCapacity());
|
||||||
|
renderTooltip(pPoseStack, components, Optional.empty(), pMouseX - x, pMouseY - y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderEnergy(@NotNull PoseStack stack, int x, int y) {
|
||||||
|
if (menu.getEnergy() <= 0 || menu.getEnergyCapacity() <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int ENERGY_HEIGHT = 60;
|
||||||
|
int stored = (int)(ENERGY_HEIGHT * ((float)menu.getEnergy() / (float)menu.getEnergyCapacity()));
|
||||||
|
fillGradient(stack, x, y + (ENERGY_HEIGHT - stored), x + 9, y + 60, 0xffb51500, 0xff600b00);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderFluid(@NotNull PoseStack stack, int x, int y) {
|
||||||
|
FluidStack fluid = menu.getFluid();
|
||||||
|
if (fluid.getFluid().isSame(Fluids.EMPTY)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int FLUID_HEIGHT = 60;
|
||||||
|
|
||||||
|
TextureAtlasSprite sprite = FluidSprite.getStillFluidSprite(fluid);
|
||||||
|
int tint = FluidSprite.getTint(fluid);
|
||||||
|
int amount = fluid.getAmount();
|
||||||
|
int scaled = Math.min(FLUID_HEIGHT, Math.max(amount > 0 ? 1 : 0, (amount * FLUID_HEIGHT) / 64000));
|
||||||
|
|
||||||
|
RenderSystem.enableBlend();
|
||||||
|
stack.pushPose();
|
||||||
|
stack.translate(x, y, 0);
|
||||||
|
|
||||||
|
TiledSprite.drawTiledSprite(stack, 9, FLUID_HEIGHT, tint, scaled, sprite, 16);
|
||||||
|
|
||||||
|
stack.popPose();
|
||||||
|
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
RenderSystem.disableBlend();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderProgressArrow(PoseStack stack, int x, int y) {
|
private void renderProgressArrow(PoseStack stack, int x, int y) {
|
||||||
if (menu.isCrafting()) {
|
if (menu.isCrafting()) {
|
||||||
blit(stack, x + 90, y + 33, 176, 0, 8, menu.getScaledProgress(25));
|
blit(stack, x + 90, y + 33, 176, 0, 8, (int)(25.0f * menu.getScaledProgress()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderBulb(PoseStack stack, int x, int y) {
|
||||||
|
if (menu.isCrafting()) {
|
||||||
|
blit(stack, x + 67, y + 38, 176, 25, 9, 14);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package net.banutama.utamacraft.screen.utils;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.inventory.InventoryMenu;
|
||||||
|
import net.minecraft.world.level.material.Fluid;
|
||||||
|
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
|
||||||
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
|
||||||
|
public class FluidSprite {
|
||||||
|
public static int getTint(FluidStack fluid) {
|
||||||
|
return IClientFluidTypeExtensions.of(fluid.getFluid()).getTintColor(fluid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setColorFromTint(int tint) {
|
||||||
|
float a = ((tint >> 24) & 0xff) / 255.0f;
|
||||||
|
float r = ((tint >> 16) & 0xff) / 255.0f;
|
||||||
|
float g = ((tint >> 8) & 0xff) / 255.0f;
|
||||||
|
float b = (tint & 0xff) / 255.0f;
|
||||||
|
RenderSystem.setShaderColor(r, g, b, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TextureAtlasSprite getStillFluidSprite(FluidStack fluid) {
|
||||||
|
ResourceLocation texture = IClientFluidTypeExtensions.of(fluid.getFluid()).getStillTexture(fluid);
|
||||||
|
return Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply(texture);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package net.banutama.utamacraft.screen.utils;
|
||||||
|
|
||||||
|
public class MouseUtils {
|
||||||
|
public static boolean isMouseOver(double mouseX, double mouseY, int x, int y, int w, int h) {
|
||||||
|
return mouseX >= x && mouseX <= x + w && mouseY >= y && mouseY <= y + h;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package net.banutama.utamacraft.screen.utils;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import com.mojang.blaze3d.vertex.*;
|
||||||
|
import com.mojang.math.Matrix4f;
|
||||||
|
import net.minecraft.client.renderer.GameRenderer;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
import net.minecraft.world.inventory.InventoryMenu;
|
||||||
|
|
||||||
|
public class TiledSprite {
|
||||||
|
public static void drawTiledSprite(PoseStack stack, int tiledWidth, int tiledHeight, int tint, int scaledAmount, TextureAtlasSprite sprite, int textureSize) {
|
||||||
|
RenderSystem.setShaderTexture(0, InventoryMenu.BLOCK_ATLAS);
|
||||||
|
Matrix4f m = stack.last().pose();
|
||||||
|
FluidSprite.setColorFromTint(tint);
|
||||||
|
|
||||||
|
int xTileCount = tiledWidth / textureSize;
|
||||||
|
int xRemainder = tiledWidth - (xTileCount * textureSize);
|
||||||
|
int yTileCount = scaledAmount / textureSize;
|
||||||
|
int yRemainder = scaledAmount - (yTileCount * textureSize);
|
||||||
|
|
||||||
|
for (int xTile = 0; xTile <= xTileCount; ++xTile) {
|
||||||
|
for (int yTile = 0; yTile <= yTileCount; ++yTile) {
|
||||||
|
int width = (xTile == xTileCount) ? xRemainder : textureSize;
|
||||||
|
if (width <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int height = (yTile == yTileCount) ? yRemainder : textureSize;
|
||||||
|
if (height <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x = xTile * textureSize;
|
||||||
|
int y = tiledHeight - ((yTile + 1) * textureSize);
|
||||||
|
drawTextureWithMasking(m, x, y, sprite, textureSize - height, textureSize - width, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void drawTextureWithMasking(Matrix4f m, float x, float y, TextureAtlasSprite sprite, int maskTop, int maskRight, float z) {
|
||||||
|
float u0 = sprite.getU0();
|
||||||
|
float u1 = sprite.getU1();
|
||||||
|
float v0 = sprite.getV0();
|
||||||
|
float v1 = sprite.getV1();
|
||||||
|
|
||||||
|
u1 = u1 - (maskRight / 16.0f * (u1 - u0));
|
||||||
|
v1 = v1 - (maskTop / 16.0f * (v1 - v0));
|
||||||
|
|
||||||
|
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||||
|
|
||||||
|
Tesselator tesselator = Tesselator.getInstance();
|
||||||
|
BufferBuilder builder = tesselator.getBuilder();
|
||||||
|
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX);
|
||||||
|
builder.vertex(m, x, y + 16, z).uv(u0, v1).endVertex();
|
||||||
|
builder.vertex(m, x + 16 - maskRight, y + 16, z).uv(u1, v1).endVertex();
|
||||||
|
builder.vertex(m, x + 16 - maskRight, y + maskTop, z).uv(u1, v0).endVertex();
|
||||||
|
builder.vertex(m, x, y + maskTop, z).uv(u0, v0).endVertex();
|
||||||
|
tesselator.end();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
package net.banutama.utamacraft.screen.utils;
|
||||||
|
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.world.level.material.Fluid;
|
||||||
|
import net.minecraft.world.level.material.Fluids;
|
||||||
|
import net.minecraftforge.energy.IEnergyStorage;
|
||||||
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
|
import net.minecraftforge.fluids.FluidType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class TooltipUtils {
|
||||||
|
private static final NumberFormat nf = NumberFormat.getIntegerInstance();
|
||||||
|
|
||||||
|
private static @NotNull List<Component> startFluidTooltip(@NotNull FluidStack stack) {
|
||||||
|
List<Component> tooltip = new ArrayList<>();
|
||||||
|
|
||||||
|
Fluid fluid = stack.getFluid();
|
||||||
|
if (fluid.isSame(Fluids.EMPTY)) {
|
||||||
|
tooltip.add(Component.translatable("tooltip.utamacraft.fluid.empty")
|
||||||
|
.withStyle(ChatFormatting.ITALIC)
|
||||||
|
.withStyle(ChatFormatting.GRAY));
|
||||||
|
return tooltip;
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltip.add(stack.getDisplayName());
|
||||||
|
return tooltip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull List<Component> getFluidTooltip(@NotNull FluidStack stack, int capacity) {
|
||||||
|
List<Component> tooltip = startFluidTooltip(stack);
|
||||||
|
|
||||||
|
int amount = stack.getAmount();
|
||||||
|
int mb = (amount * 1000) / FluidType.BUCKET_VOLUME;
|
||||||
|
|
||||||
|
tooltip.add(Component.translatable("tooltip.utamacraft.fluid.amount.with_capacity",
|
||||||
|
nf.format(mb), nf.format(capacity))
|
||||||
|
.withStyle(ChatFormatting.GRAY));
|
||||||
|
|
||||||
|
return tooltip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull List<Component> getFluidTooltip(@NotNull FluidStack stack) {
|
||||||
|
List<Component> tooltip = startFluidTooltip(stack);
|
||||||
|
|
||||||
|
int amount = stack.getAmount();
|
||||||
|
int mb = (amount * 1000) / FluidType.BUCKET_VOLUME;
|
||||||
|
|
||||||
|
tooltip.add(Component.translatable("tooltip.utamacraft.fluid.amount", nf.format(mb))
|
||||||
|
.withStyle(ChatFormatting.GRAY));
|
||||||
|
|
||||||
|
return tooltip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull List<Component> getEnergyTooltip(int energy) {
|
||||||
|
return List.of(Component.translatable("tooltip.utamacraft.energy.amount",
|
||||||
|
nf.format(energy)).withStyle(ChatFormatting.GRAY));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull List<Component> getEnergyTooltip(int energy, int capacity) {
|
||||||
|
return List.of(
|
||||||
|
Component.translatable(("tooltip.utamacraft.energy")),
|
||||||
|
Component.translatable("tooltip.utamacraft.energy.amount.with_capacity",
|
||||||
|
nf.format(energy), nf.format(capacity)).withStyle(ChatFormatting.GRAY));
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,13 @@
|
|||||||
"item.utamacraft.tungsten_ingot": "Tungsten Ingot",
|
"item.utamacraft.tungsten_ingot": "Tungsten Ingot",
|
||||||
"item.utamacraft.utamacraft_logo": "Utamacraft",
|
"item.utamacraft.utamacraft_logo": "Utamacraft",
|
||||||
"itemGroup.utamacraft_tab": "Utamacraft",
|
"itemGroup.utamacraft_tab": "Utamacraft",
|
||||||
|
"tooltip.utamacraft.energy": "Energy",
|
||||||
|
"tooltip.utamacraft.energy.amount": "%s FE",
|
||||||
|
"tooltip.utamacraft.energy.amount.with_capacity": "%s / %s FE",
|
||||||
"tooltip.utamacraft.ethereal_glass": "Glass that is not solid to players",
|
"tooltip.utamacraft.ethereal_glass": "Glass that is not solid to players",
|
||||||
|
"tooltip.utamacraft.fluid.empty": "Empty",
|
||||||
|
"tooltip.utamacraft.fluid.amount": "%s mB",
|
||||||
|
"tooltip.utamacraft.fluid.amount.with_capacity": "%s / %s mB",
|
||||||
"tooltip.utamacraft.tinted_ethereal_glass": "Glass that is not solid to players and blocks light",
|
"tooltip.utamacraft.tinted_ethereal_glass": "Glass that is not solid to players and blocks light",
|
||||||
"turtle.utamacraft.player_turtle": "Player"
|
"turtle.utamacraft.player_turtle": "Player"
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"type": "utamacraft:insolator",
|
||||||
|
"input": { "item": "minecraft:cornflower" },
|
||||||
|
"fluid": {
|
||||||
|
"FluidName": "minecraft:water",
|
||||||
|
"Amount": 500
|
||||||
|
},
|
||||||
|
"output": { "item": "minecraft:cornflower", "count": 2 }
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user