diff --git a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java index d812e4a5f..dc7eac171 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java +++ b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java @@ -1,7 +1,6 @@ package ru.dbotthepony.mc.otm; import net.minecraft.client.gui.screens.MenuScreens; -import net.minecraft.client.gui.screens.inventory.ContainerScreen; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; @@ -11,7 +10,6 @@ import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.LazyOptional; @@ -29,8 +27,11 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import ru.dbotthepony.mc.otm.block.BlockAndroidStation; +import ru.dbotthepony.mc.otm.block.entity.BlockEntityAndroidStation; import ru.dbotthepony.mc.otm.capability.AndroidCapability; import ru.dbotthepony.mc.otm.capability.IAndroidCapability; +import ru.dbotthepony.mc.otm.menu.AndroidStationMenu; +import ru.dbotthepony.mc.otm.screen.AndroidStationScreen; import java.util.stream.Collectors; @@ -42,10 +43,10 @@ public class OverdriveThatMatters { public static final Logger LOGGER = LogManager.getLogger(); public static Block ANDROID_STATION = new BlockAndroidStation(); - public static BlockEntityType.Builder ANDROID_STATION_BUILDER = BlockEntityType.Builder.of(BlockAndroidStation.BlockAndroidStationEntity::new, ANDROID_STATION); - public static BlockEntityType ANDROID_STATION_FACTORY = null; + public static BlockEntityType.Builder ANDROID_STATION_BUILDER = BlockEntityType.Builder.of(BlockEntityAndroidStation::new, ANDROID_STATION); + public static BlockEntityType ANDROID_STATION_FACTORY = null; public static Item ANDROID_STATION_ITEM = new BlockItem(ANDROID_STATION, new Item.Properties().stacksTo(64).tab(CreativeModeTab.TAB_MISC)).setRegistryName(BlockAndroidStation.REGISTRY_NAME); - public static MenuType ANDROID_STATION_MENU_TYPE = new MenuType<>(BlockAndroidStation.BlockAndroidStationEntity.AndroidStationMenu::new); + public static MenuType ANDROID_STATION_MENU_TYPE = new MenuType<>(AndroidStationMenu::new); static { ANDROID_STATION_MENU_TYPE.setRegistryName(BlockAndroidStation.REGISTRY_NAME); @@ -147,7 +148,7 @@ public class OverdriveThatMatters { // регистрация tile entity LOGGER.info("Register MenuType called"); blockRegistryEvent.getRegistry().register(ANDROID_STATION_MENU_TYPE); - MenuScreens.register(ANDROID_STATION_MENU_TYPE, BlockAndroidStation.BlockAndroidStationEntity.AndroidStationScreen::new); + MenuScreens.register(ANDROID_STATION_MENU_TYPE, AndroidStationScreen::new); } } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/BlockAndroidStation.java b/src/main/java/ru/dbotthepony/mc/otm/block/BlockAndroidStation.java index 0cf1f911b..6162b0ccb 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/BlockAndroidStation.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/BlockAndroidStation.java @@ -1,24 +1,10 @@ package ru.dbotthepony.mc.otm.block; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; -import net.minecraft.client.renderer.GameRenderer; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; -import net.minecraft.world.MenuProvider; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.inventory.MenuType; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; @@ -30,24 +16,14 @@ import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.Material; import net.minecraft.world.level.material.MaterialColor; -import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.energy.CapabilityEnergy; -import net.minecraftforge.energy.EnergyStorage; -import net.minecraftforge.energy.IEnergyStorage; -import org.apache.logging.log4j.core.jmx.Server; import ru.dbotthepony.mc.otm.OverdriveThatMatters; -import ru.dbotthepony.mc.otm.capability.AndroidCapability; -import ru.dbotthepony.mc.otm.capability.IAndroidCapability; +import ru.dbotthepony.mc.otm.block.entity.BlockEntityAndroidStation; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.List; public class BlockAndroidStation extends Block implements EntityBlock { public static final ResourceLocation REGISTRY_NAME = new ResourceLocation(OverdriveThatMatters.MOD_ID, "android_station"); @@ -66,147 +42,22 @@ public class BlockAndroidStation extends Block implements EntityBlock { @Nullable @Override public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { - return new BlockAndroidStationEntity(pos, state); + return new BlockEntityAndroidStation(pos, state); } @Nullable @Override public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType type) { - return level.isClientSide || type != OverdriveThatMatters.ANDROID_STATION_FACTORY ? null : BlockAndroidStationEntity::tick; + return level.isClientSide || type != OverdriveThatMatters.ANDROID_STATION_FACTORY ? null : BlockEntityAndroidStation::tick; } @Override public InteractionResult use(BlockState p_60503_, Level level, BlockPos pos, Player ply, InteractionHand p_60507_, BlockHitResult p_60508_) { - if (!level.isClientSide && level.getBlockEntity(pos) instanceof BlockAndroidStationEntity tile) { + if (!level.isClientSide && level.getBlockEntity(pos) instanceof BlockEntityAndroidStation tile) { ply.openMenu(tile); return InteractionResult.CONSUME; } return InteractionResult.SUCCESS; } - - public static class BlockAndroidStationEntity extends BlockEntity implements MenuProvider { - @Override - public Component getDisplayName() { - return new TranslatableComponent("container.android_station"); - } - - @Nullable - @Override - public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) { - new Exception().printStackTrace(); - return new AndroidStationMenu(containerID, this); - } - - public static class AndroidStationMenu extends AbstractContainerMenu { - private BlockAndroidStationEntity tile; - private Inventory inventory; - - public AndroidStationMenu(int containerID, Inventory inventory) { - super(OverdriveThatMatters.ANDROID_STATION_MENU_TYPE, containerID); - new Exception().printStackTrace(); - this.inventory = inventory; - } - - public AndroidStationMenu(int containerID, BlockAndroidStationEntity tile) { - super(OverdriveThatMatters.ANDROID_STATION_MENU_TYPE, containerID); - new Exception().printStackTrace(); - this.tile = tile; - } - - @Override - public boolean stillValid(Player p_38874_) { - return !tile.isRemoved(); - } - } - - public static class AndroidStationScreen extends AbstractContainerScreen { - public AndroidStationScreen(AndroidStationMenu p_97741_, Inventory p_97742_, Component p_97743_) { - super(p_97741_, p_97742_, p_97743_); - } - - @Override - protected void renderBg(PoseStack p_97787_, float p_97788_, int p_97789_, int p_97790_) { - - } - } - - private static class AndroidStationEnergyStorage extends EnergyStorage { - public AndroidStationEnergyStorage(int capacity, int maxReceive, int maxExtract) { - super(capacity, maxReceive, maxExtract); - } - - void setEnergy(int energy) { - this.energy = energy; - } - } - - private final AndroidStationEnergyStorage energy = new AndroidStationEnergyStorage(64000, 1024, 1024); - - public BlockAndroidStationEntity(BlockPos p_155229_, BlockState p_155230_) { - super(OverdriveThatMatters.ANDROID_STATION_FACTORY, p_155229_, p_155230_); - } - - @Nonnull - public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { - if (cap == CapabilityEnergy.ENERGY) { - return LazyOptional.of(() -> energy).cast(); - } - - return super.getCapability(cap, side); - } - - @Override - public CompoundTag save(CompoundTag nbt) { - nbt.putInt("energy_stored", energy.getEnergyStored()); - return super.save(nbt); - } - - public void load(CompoundTag nbt) { - super.load(nbt); - - if (nbt.contains("energy_stored")) - energy.setEnergy(nbt.getInt("energy_stored")); - } - - void tick() { - if (!hasLevel()) - return; - - if (energy.getEnergyStored() <= 0) - return; - - BlockPos pos = getBlockPos(); - List entities = getLevel().getEntitiesOfClass(LivingEntity.class, new AABB(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 2, pos.getZ() + 1)); - - for (LivingEntity ent : entities) { - LazyOptional resolver = ent.getCapability(AndroidCapability.CAPABILITY); - - if (resolver.isPresent()) { - IAndroidCapability capability = resolver.resolve().get(); - - int missing = capability.getMissingPowerInt(); - - if (missing > 0) { - int extract = energy.extractEnergy(missing, true); - - if (extract > 0) { - int received = (int) capability.receiveEnergy(extract, true); - - if (received > 0) { - energy.extractEnergy(extract, false); - capability.receiveEnergy(extract, false); - } - } - } - } - } - } - - public static void tick(Level level, BlockPos blockPos, BlockState blockState, T t) { - if (t instanceof BlockAndroidStationEntity tile) { - tile.tick(); - } - } - } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java new file mode 100644 index 000000000..e02b7c9dc --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java @@ -0,0 +1,112 @@ +package ru.dbotthepony.mc.otm.block.entity; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.energy.CapabilityEnergy; +import ru.dbotthepony.mc.otm.OverdriveThatMatters; +import ru.dbotthepony.mc.otm.capability.AndroidCapability; +import ru.dbotthepony.mc.otm.capability.IAndroidCapability; +import ru.dbotthepony.mc.otm.capability.MatteryEnergyCapability; +import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage; +import ru.dbotthepony.mc.otm.menu.AndroidStationMenu; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.math.BigDecimal; +import java.util.List; + +public class BlockEntityAndroidStation extends BlockEntity implements MenuProvider { + @Override + public Component getDisplayName() { + return new TranslatableComponent("container.android_station"); + } + + @Nullable + @Override + public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) { + new Exception().printStackTrace(); + return new AndroidStationMenu(containerID, this); + } + + private final MatteryMachineEnergyStorage energy = new MatteryMachineEnergyStorage(MatteryMachineEnergyStorage.MachineType.WORKER); + + public BlockEntityAndroidStation(BlockPos p_155229_, BlockState p_155230_) { + super(OverdriveThatMatters.ANDROID_STATION_FACTORY, p_155229_, p_155230_); + } + + @Nonnull + public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { + if (cap == MatteryEnergyCapability.CAPABILITY || cap == CapabilityEnergy.ENERGY) { + return LazyOptional.of(() -> energy).cast(); + } + + return super.getCapability(cap, side); + } + + @Override + public CompoundTag save(CompoundTag nbt) { + nbt.put("energy_cap", energy.serializeNBT()); + return super.save(nbt); + } + + public void load(CompoundTag nbt) { + super.load(nbt); + + if (nbt.contains("energy_cap") && nbt.get("energy_cap") instanceof CompoundTag tag) + energy.deserializeNBT(tag); + } + + void tick() { + if (!hasLevel()) + return; + + if (energy.getEnergyStored() <= 0) + return; + + BlockPos pos = getBlockPos(); + List entities = getLevel().getEntitiesOfClass(LivingEntity.class, new AABB(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 2, pos.getZ() + 1)); + + for (LivingEntity ent : entities) { + LazyOptional resolver = ent.getCapability(AndroidCapability.CAPABILITY); + + if (resolver.isPresent()) { + IAndroidCapability capability = resolver.resolve().get(); + + BigDecimal missing = capability.getMissingPower(); + + if (missing.compareTo(BigDecimal.ZERO) == -1) { + BigDecimal extract = energy.extractEnergyInner(missing, true); + + if (extract.compareTo(BigDecimal.ZERO) == -1) { + BigDecimal received = capability.receiveEnergyOuter(extract, true); + + if (received.compareTo(BigDecimal.ZERO) == -1) { + energy.extractEnergyInner(extract, false); + capability.receiveEnergyOuter(extract, false); + } + } + } + } + } + } + + public static void tick(Level level, BlockPos blockPos, BlockState blockState, T t) { + if (t instanceof BlockEntityAndroidStation tile) { + tile.tick(); + } + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java index 6c778fc90..142f8814b 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java @@ -19,12 +19,15 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.math.BigDecimal; import java.util.function.Function; -public class AndroidCapability implements ICapabilityProvider, IAndroidCapability, INBTSerializable { +public class AndroidCapability implements ICapabilityProvider, IAndroidCapability, INBTSerializable { private final LivingEntity ent; - public long energy_stored = 32000L; - public long energy_stored_max = 32000L; + private BigDecimal energy_stored = new BigDecimal(0); + private BigDecimal energy_stored_max = new BigDecimal(32000); + + public static final BigDecimal ENERGY_FOR_HUNGER_POINT = new BigDecimal(200); public AndroidCapability(LivingEntity ent) { this.ent = ent; @@ -34,27 +37,21 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit public static Capability CAPABILITY = null; @Override - public Tag serializeNBT() { + @Nonnull + public CompoundTag serializeNBT() { CompoundTag tag = new CompoundTag(); - tag.put("energy_stored", LongTag.valueOf(energy_stored)); - tag.put("energy_stored_max", LongTag.valueOf(energy_stored_max)); + tag.putString("energy_stored", energy_stored.toString()); + tag.putString("energy_stored_max", energy_stored_max.toString()); return tag; } @Override - public void deserializeNBT(Tag nbt) { - if (nbt instanceof CompoundTag compound) { - if (compound.contains("energy_stored")) - energy_stored = compound.getLong("energy_stored"); + public void deserializeNBT(CompoundTag compound) { + if (compound.contains("energy_stored")) + energy_stored = new BigDecimal(compound.getString("energy_stored")); - if (compound.contains("energy_stored_max")) - energy_stored_max = compound.getLong("energy_stored_max"); - } - } - - @Override - public long getMissingPower() { - return getMaxBatteryLevel() - getBatteryLevel(); + if (compound.contains("energy_stored_max")) + energy_stored_max = new BigDecimal(compound.getString("energy_stored_max")); } @Override @@ -69,8 +66,8 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit boolean saturation_changed = false; while (food_points_missing > 0) { - if (this.extractEnergy(200L, true) == 200L) { - this.extractEnergy(200L, false); + if (this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT, true).equals(ENERGY_FOR_HUNGER_POINT)) { + this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT, false); food_points_missing--; food_changed = true; } else { @@ -79,8 +76,8 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit } while (saturation_points_missing >= 1F) { - if (this.extractEnergy(200L, true) == 200L) { - this.extractEnergy(200L, false); + if (this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT, true).equals(ENERGY_FOR_HUNGER_POINT)) { + this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT, false); saturation_points_missing--; saturation_changed = true; } else { @@ -101,43 +98,61 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit } } + @Nonnull + @Override + public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) { + return BigDecimal.ZERO; + } + + @Nonnull + @Override + public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) { + BigDecimal new_energy = energy_stored.subtract(howMuch, MatteryEnergyCapability.ROUND_RULES).max(BigDecimal.ZERO); + BigDecimal diff = energy_stored.subtract(new_energy); + + if (!simulate) { + energy_stored = new_energy; + } + + return diff; + } + + @Nonnull + @Override + public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) { + BigDecimal new_energy = energy_stored.add(howMuch, MatteryEnergyCapability.ROUND_RULES).min(energy_stored_max); + BigDecimal diff = new_energy.subtract(energy_stored); + + if (!simulate) { + energy_stored = new_energy; + } + + return diff; + } + + @Nonnull + @Override + public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) { + return receiveEnergyOuter(howMuch, simulate); + } + @Override public LivingEntity getEntity() { return this.ent; } @Override - public long getBatteryLevel() { + @Nonnull + public BigDecimal getBatteryLevel() { return energy_stored; } @Override - public long getMaxBatteryLevel() { + @Nonnull + public BigDecimal getMaxBatteryLevel() { return energy_stored_max; } - @Override - public long receiveEnergy(long howMuch, boolean simulate) { - long final_value = Math.min(energy_stored_max, energy_stored + howMuch); - - if (!simulate) { - energy_stored = final_value; - } - - return final_value - energy_stored; - } - - @Override - public long extractEnergy(long howMuch, boolean simulate) { - long final_value = Math.max(0, energy_stored - howMuch); - - if (!simulate) { - energy_stored = final_value; - } - - return energy_stored - final_value; - } - @Nonnull @Override public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java index f8ff74ee3..67b8468f7 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java @@ -3,23 +3,7 @@ package ru.dbotthepony.mc.otm.capability; import net.minecraft.world.entity.LivingEntity; import net.minecraftforge.common.capabilities.ICapabilityProvider; -public interface IAndroidCapability { +public interface IAndroidCapability extends IMatteryEnergyStorage { void tick(); LivingEntity getEntity(); - - long getBatteryLevel(); - long getMaxBatteryLevel(); - long getMissingPower(); - long receiveEnergy(long howMuch, boolean simulate); - long extractEnergy(long howMuch, boolean simulate); - - default int getMissingPowerInt() { - long power = getMissingPower(); - - if (power > Integer.MAX_VALUE) { - return Integer.MAX_VALUE; - } - - return (int) power; - } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java b/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java new file mode 100644 index 000000000..32c6d905d --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java @@ -0,0 +1,156 @@ +package ru.dbotthepony.mc.otm.capability; + +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.energy.CapabilityEnergy; +import net.minecraftforge.energy.IEnergyStorage; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.math.BigDecimal; +import java.math.BigInteger; + +// IEnergyStorage for direct compat with Forge Energy +public interface IMatteryEnergyStorage extends IEnergyStorage { + // such as cables. This is something that would work only with energy storage + @Nonnull + BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate); + + // for internal needs, e.g. for work + // CAN also be used by something that does evil + // e.g. sucking out energy anomaly should use this + @Nonnull + BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate); + + // energy is received from outside, e.g. cables + @Nonnull + BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate); + + // energy is received from inside, e.g. generator generates power + @Nonnull + BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate); + + @Nonnull + default BigDecimal extractEnergyOuter(long howMuch, boolean simulate) { + return extractEnergyOuter(new BigDecimal(howMuch), simulate); + } + + @Nonnull + default BigDecimal extractEnergyOuter(int howMuch, boolean simulate) { + return extractEnergyOuter(new BigDecimal(howMuch), simulate); + } + + @Nonnull + default BigDecimal receiveEnergyOuter(long howMuch, boolean simulate) { + return receiveEnergyOuter(new BigDecimal(howMuch), simulate); + } + + @Nonnull + default BigDecimal receiveEnergyOuter(int howMuch, boolean simulate) { + return receiveEnergyOuter(new BigDecimal(howMuch), simulate); + } + + @Nonnull + default BigDecimal extractEnergyInner(long howMuch, boolean simulate) { + return receiveEnergyOuter(new BigDecimal(howMuch), simulate); + } + + @Nonnull + default BigDecimal extractEnergyInner(int howMuch, boolean simulate) { + return receiveEnergyOuter(new BigDecimal(howMuch), simulate); + } + + @Nonnull + default BigDecimal receiveEnergyInner(long howMuch, boolean simulate) { + return receiveEnergyOuter(new BigDecimal(howMuch), simulate); + } + + @Nonnull + default BigDecimal receiveEnergyInner(int howMuch, boolean simulate) { + return receiveEnergyOuter(new BigDecimal(howMuch), simulate); + } + + @Nonnull + BigDecimal getBatteryLevel(); + + @Nonnull + BigDecimal getMaxBatteryLevel(); + + default BigDecimal getMissingPower() { + return getMaxBatteryLevel().subtract(getBatteryLevel(), MatteryEnergyCapability.ROUND_RULES); + } + + @Override + default int receiveEnergy(int maxReceive, boolean simulate) { + BigDecimal toReceive = new BigDecimal(maxReceive); + BigDecimal received = receiveEnergyOuter(toReceive, true); + + if (received.compareTo(BigDecimal.ZERO) == 1 && received.compareTo(BigDecimal.ONE) == -1) { + // Receiving only a fraction + return 0; + } + + return receiveEnergyOuter(received.round(MatteryEnergyCapability.ROUND_RULES), simulate).intValue(); + } + + @Override + default int extractEnergy(int maxReceive, boolean simulate) { + BigDecimal toReceive = new BigDecimal(maxReceive); + BigDecimal extracted = extractEnergyOuter(toReceive, true); + + if (extracted.compareTo(BigDecimal.ZERO) == 1 && extracted.compareTo(BigDecimal.ONE) == -1) { + // Extracting only a fraction + return 0; + } + + return extractEnergyOuter(extracted.round(MatteryEnergyCapability.ROUND_RULES), simulate).intValue(); + } + + @Override + default int getEnergyStored() { + BigDecimal level = getBatteryLevel(); + + if (level.compareTo(MatteryEnergyCapability.INT_MAX_VALUE) == -1) { + return level.intValue(); + } + + return Integer.MAX_VALUE; + }; + + @Override + default int getMaxEnergyStored() { + BigDecimal level = getMaxBatteryLevel(); + + if (level.compareTo(MatteryEnergyCapability.INT_MAX_VALUE) == -1) { + return level.intValue(); + } + + return Integer.MAX_VALUE; + }; + + @Override + default boolean canExtract() { + return extractEnergyOuter(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0; + }; + + @Override + default boolean canReceive() { + return receiveEnergyOuter(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0; + }; + + default boolean canExtractOuter() { + return extractEnergyOuter(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0; + }; + + default boolean canReceiveOuter() { + return receiveEnergyOuter(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0; + }; + + default boolean canExtractInner() { + return extractEnergyInner(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0; + }; + + default boolean canReceiveInner() { + return receiveEnergyInner(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0; + }; +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryEnergyCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryEnergyCapability.java new file mode 100644 index 000000000..d5f6156f6 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryEnergyCapability.java @@ -0,0 +1,21 @@ +package ru.dbotthepony.mc.otm.capability; + +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.CapabilityInject; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.math.RoundingMode; + +public class MatteryEnergyCapability { + @CapabilityInject(IMatteryEnergyStorage.class) + public static Capability CAPABILITY = null; + + public static final MathContext ROUND_RULES = new MathContext(0, RoundingMode.HALF_UP); + + public static final BigDecimal INT_MAX_VALUE = new BigDecimal(Integer.MAX_VALUE); + public static final BigDecimal INT_MIN_VALUE = new BigDecimal(Integer.MIN_VALUE); + + public static final BigDecimal LONG_MAX_VALUE = new BigDecimal(Long.MAX_VALUE); + public static final BigDecimal LONG_MIN_VALUE = new BigDecimal(Long.MIN_VALUE); +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.java b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.java new file mode 100644 index 000000000..e982a4125 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryMachineEnergyStorage.java @@ -0,0 +1,135 @@ +package ru.dbotthepony.mc.otm.capability; + +import net.minecraft.nbt.CompoundTag; +import net.minecraftforge.common.util.INBTSerializable; +import ru.dbotthepony.mc.otm.OverdriveThatMatters; + +import javax.annotation.Nonnull; +import java.math.BigDecimal; + +public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTSerializable { + public enum MachineType { + WORKER, + GENERATOR, + CAPACITOR, + } + + public static final BigDecimal DEFAULT_MAX_RECEIVE = new BigDecimal(4000); + public static final BigDecimal DEFAULT_MAX_EXTRACT = new BigDecimal(4000); + public static final BigDecimal DEFAULT_MAX_CAPACITY = new BigDecimal(64000); + + protected BigDecimal energy_stored = BigDecimal.ZERO; + protected BigDecimal energy_stored_max; + protected BigDecimal max_input; + protected BigDecimal max_output; + protected final MachineType machine_type; + + public MatteryMachineEnergyStorage(BigDecimal capacity, MachineType type) { + this(capacity, type, DEFAULT_MAX_RECEIVE, DEFAULT_MAX_EXTRACT); + } + + public MatteryMachineEnergyStorage(MachineType type) { + this(DEFAULT_MAX_CAPACITY, type); + } + + public MatteryMachineEnergyStorage(BigDecimal capacity, MachineType type, BigDecimal maxReceive, BigDecimal maxExtract) { + energy_stored_max = capacity; + max_input = maxReceive; + max_output = maxExtract; + machine_type = type; + } + + @Nonnull + @Override + public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) { + if (machine_type == MachineType.WORKER) { + return BigDecimal.ZERO; + } + + return extractEnergyInner(howMuch, simulate); + } + + @Nonnull + @Override + public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) { + BigDecimal new_energy = energy_stored.subtract(howMuch.min(max_output), MatteryEnergyCapability.ROUND_RULES).max(BigDecimal.ZERO); + BigDecimal diff = energy_stored.subtract(new_energy); + + if (!simulate) { + energy_stored = new_energy; + } + + return diff; + } + + @Nonnull + @Override + public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) { + if (machine_type == MachineType.GENERATOR) { + return BigDecimal.ZERO; + } + + return receiveEnergyInner(howMuch, simulate); + } + + @Nonnull + @Override + public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) { + BigDecimal new_energy = energy_stored.add(howMuch.min(max_input), MatteryEnergyCapability.ROUND_RULES).min(energy_stored_max); + BigDecimal diff = new_energy.subtract(energy_stored); + + if (!simulate) { + energy_stored = new_energy; + } + + return diff; + } + + @Nonnull + @Override + public BigDecimal getBatteryLevel() { + return energy_stored; + } + + @Nonnull + @Override + public BigDecimal getMaxBatteryLevel() { + return energy_stored_max; + } + + @Override + public boolean canExtract() { + return machine_type != MachineType.WORKER; + } + + @Override + public boolean canReceive() { + return machine_type != MachineType.GENERATOR; + } + + @Override + @Nonnull + public CompoundTag serializeNBT() { + CompoundTag tag = new CompoundTag(); + tag.putString("energy_stored", energy_stored.toString()); + tag.putString("energy_stored_max", energy_stored_max.toString()); + tag.putString("max_input", max_input.toString()); + tag.putString("max_output", max_output.toString()); + return tag; + } + + @Override + public void deserializeNBT(CompoundTag nbt) { + if (nbt.contains("energy_stored")) + energy_stored = new BigDecimal(nbt.getString("energy_stored")); + + if (nbt.contains("energy_stored_max")) + energy_stored_max = new BigDecimal(nbt.getString("energy_stored_max")); + + if (nbt.contains("max_input")) + max_input = new BigDecimal(nbt.getString("max_input")); + + if (nbt.contains("max_output")) + max_output = new BigDecimal(nbt.getString("max_output")); + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java b/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java new file mode 100644 index 000000000..7df5e0aab --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java @@ -0,0 +1,28 @@ +package ru.dbotthepony.mc.otm.menu; + +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import ru.dbotthepony.mc.otm.OverdriveThatMatters; +import ru.dbotthepony.mc.otm.block.entity.BlockEntityAndroidStation; + +public class AndroidStationMenu extends AbstractContainerMenu { + private BlockEntityAndroidStation tile; + private Inventory inventory; + + public AndroidStationMenu(int containerID, Inventory inventory) { + super(OverdriveThatMatters.ANDROID_STATION_MENU_TYPE, containerID); + new Exception().printStackTrace(); + this.inventory = inventory; + } + + public AndroidStationMenu(int containerID, BlockEntityAndroidStation tile) { + super(OverdriveThatMatters.ANDROID_STATION_MENU_TYPE, containerID); + this.tile = tile; + } + + @Override + public boolean stillValid(Player p_38874_) { + return !tile.isRemoved(); + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java b/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java new file mode 100644 index 000000000..cc3551397 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java @@ -0,0 +1,18 @@ +package ru.dbotthepony.mc.otm.screen; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Inventory; +import ru.dbotthepony.mc.otm.menu.AndroidStationMenu; + +public class AndroidStationScreen extends AbstractContainerScreen { + public AndroidStationScreen(AndroidStationMenu p_97741_, Inventory p_97742_, Component p_97743_) { + super(p_97741_, p_97742_, p_97743_); + } + + @Override + protected void renderBg(PoseStack p_97787_, float p_97788_, int p_97789_, int p_97790_) { + + } +}