From e6b7308c3bfd6b4480abe9feb3fca56dfc1dea35 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sat, 11 Sep 2021 23:36:46 +0700 Subject: [PATCH] Energy counter test --- .../mc/otm/OverdriveThatMatters.java | 4 + .../java/ru/dbotthepony/mc/otm/Registry.java | 24 ++ .../mc/otm/block/BlockEnergyCounter.java | 64 ++++ .../block/entity/BlockEntityBatteryBank.java | 4 +- .../entity/BlockEntityEnergyCounter.java | 314 ++++++++++++++++++ .../mc/otm/client/render/RGBAColor.java | 22 +- .../client/screen/EnergyCounterScreen.java | 38 +++ .../client/screen/panels/EditablePanel.java | 6 + .../mc/otm/client/screen/panels/Label.java | 60 ++++ .../mc/otm/menu/EnergyCounterMenu.java | 43 +++ .../overdrive_that_matters/lang/en_us.json | 1 + 11 files changed, 571 insertions(+), 9 deletions(-) create mode 100644 src/main/java/ru/dbotthepony/mc/otm/block/BlockEnergyCounter.java create mode 100644 src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.java create mode 100644 src/main/java/ru/dbotthepony/mc/otm/client/screen/EnergyCounterScreen.java create mode 100644 src/main/java/ru/dbotthepony/mc/otm/client/screen/panels/Label.java create mode 100644 src/main/java/ru/dbotthepony/mc/otm/menu/EnergyCounterMenu.java diff --git a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java index c2d7304a4..6c7f39037 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java +++ b/src/main/java/ru/dbotthepony/mc/otm/OverdriveThatMatters.java @@ -110,6 +110,10 @@ public class OverdriveThatMatters { tick_once.computeIfAbsent(level, (k) -> new ArrayList<>()).add(ticker); } + public static void tickOnce(Level level, Runnable ticker) { + tick_once.computeIfAbsent(level, (k) -> new ArrayList<>()).add((l) -> ticker.run()); + } + public OverdriveThatMatters() { // Register the setup method for modloading FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); diff --git a/src/main/java/ru/dbotthepony/mc/otm/Registry.java b/src/main/java/ru/dbotthepony/mc/otm/Registry.java index ee92f248b..6d9170352 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/Registry.java +++ b/src/main/java/ru/dbotthepony/mc/otm/Registry.java @@ -77,6 +77,7 @@ public class Registry { public static void dummy() {} + @SuppressWarnings("unchecked") private static Class c(Class cls) { return (Class) cls; } record CrateProps(MaterialColor color, ResourceLocation name) { @@ -110,6 +111,7 @@ public class Registry { public static final ResourceLocation DRIVE_VIEWER = new ResourceLocation(OverdriveThatMatters.MOD_ID, "drive_viewer"); public static final ResourceLocation DRIVE_RACK = new ResourceLocation(OverdriveThatMatters.MOD_ID, "drive_rack"); public static final ResourceLocation ITEM_MONITOR = new ResourceLocation(OverdriveThatMatters.MOD_ID, "item_monitor"); + public static final ResourceLocation ENERGY_COUNTER = new ResourceLocation(OverdriveThatMatters.MOD_ID, "energy_counter"); public static final ResourceLocation BLACK_HOLE = new ResourceLocation(OverdriveThatMatters.MOD_ID, "black_hole"); public static final ResourceLocation CARGO_CRATE = new ResourceLocation(OverdriveThatMatters.MOD_ID, "cargo_crate"); @@ -245,6 +247,7 @@ public class Registry { public static final BlockCargoCrate CARGO_CRATE = new BlockCargoCrate(); public static final BlockDriveRack DRIVE_RACK = new BlockDriveRack(); public static final BlockItemMonitor ITEM_MONITOR = new BlockItemMonitor(); + public static final BlockEnergyCounter ENERGY_COUNTER = new BlockEnergyCounter(); public static final BlockBlackHole BLACK_HOLE = new BlockBlackHole(); @@ -322,6 +325,7 @@ public class Registry { CARGO_CRATE.setRegistryName(Names.CARGO_CRATE); DRIVE_RACK.setRegistryName(Names.DRIVE_RACK); ITEM_MONITOR.setRegistryName(Names.ITEM_MONITOR); + ENERGY_COUNTER.setRegistryName(Names.ENERGY_COUNTER); TRITANIUM_BLOCK.setRegistryName(Names.TRITANIUM_BLOCK); TRITANIUM_STRIPED_BLOCK.setRegistryName(Names.TRITANIUM_STRIPED_BLOCK); @@ -329,6 +333,7 @@ public class Registry { } @SubscribeEvent + @SuppressWarnings("unused") public static void register(final RegistryEvent.Register event) { event.getRegistry().register(ANDROID_STATION); event.getRegistry().register(BATTERY_BANK); @@ -351,6 +356,7 @@ public class Registry { event.getRegistry().register(TRITANIUM_RAW_BLOCK); event.getRegistry().register(DRIVE_RACK); event.getRegistry().register(ITEM_MONITOR); + event.getRegistry().register(ENERGY_COUNTER); for (var crate : CRATES) { event.getRegistry().register(crate); @@ -378,6 +384,7 @@ public class Registry { public static final Item TRITANIUM_RAW_BLOCK = new BlockItem(Blocks.TRITANIUM_RAW_BLOCK, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB)); public static final Item DRIVE_RACK = new BlockItem(Blocks.DRIVE_RACK, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB)); public static final Item ITEM_MONITOR = new BlockItem(Blocks.ITEM_MONITOR, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB)); + public static final Item ENERGY_COUNTER = new BlockItem(Blocks.ENERGY_COUNTER, new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB)); public static final Item TRITANIUM_ORE_CLUMP = new Item(new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB)); public static final Item TRITANIUM_INGOT = new Item(new Item.Properties().stacksTo(64).tab(OverdriveThatMatters.CREATIVE_TAB)); @@ -451,6 +458,7 @@ public class Registry { CARGO_CRATE.setRegistryName(Names.CARGO_CRATE); DRIVE_RACK.setRegistryName(Names.DRIVE_RACK); ITEM_MONITOR.setRegistryName(Names.ITEM_MONITOR); + ENERGY_COUNTER.setRegistryName(Names.ENERGY_COUNTER); TRITANIUM_ORE.setRegistryName(Names.TRITANIUM_ORE); DEEPSLATE_TRITANIUM_ORE.setRegistryName(Names.DEEPSLATE_TRITANIUM_ORE); @@ -501,6 +509,7 @@ public class Registry { } @SubscribeEvent + @SuppressWarnings("unused") public static void register(final RegistryEvent.Register event) { event.getRegistry().register(ANDROID_STATION); event.getRegistry().register(BATTERY_BANK); @@ -517,6 +526,7 @@ public class Registry { event.getRegistry().register(CARGO_CRATE); event.getRegistry().register(DRIVE_RACK); event.getRegistry().register(ITEM_MONITOR); + event.getRegistry().register(ENERGY_COUNTER); event.getRegistry().register(TRITANIUM_ORE); event.getRegistry().register(DEEPSLATE_TRITANIUM_ORE); @@ -590,6 +600,7 @@ public class Registry { public static final BlockEntityType CARGO_CRATE = BlockEntityType.Builder.of(BlockEntityCargoCrate::new, Blocks.CARGO_CRATE).build(null); public static final BlockEntityType DRIVE_RACK = BlockEntityType.Builder.of(BlockEntityDriveRack::new, Blocks.DRIVE_RACK).build(null); public static final BlockEntityType ITEM_MONITOR = BlockEntityType.Builder.of(BlockEntityItemMonitor::new, Blocks.ITEM_MONITOR).build(null); + public static final BlockEntityType ENERGY_COUNTER = BlockEntityType.Builder.of(BlockEntityEnergyCounter::new, Blocks.ENERGY_COUNTER).build(null); static { ANDROID_STATION.setRegistryName(Names.ANDROID_STATION); @@ -607,9 +618,11 @@ public class Registry { CARGO_CRATE.setRegistryName(Names.CARGO_CRATE); DRIVE_RACK.setRegistryName(Names.DRIVE_RACK); ITEM_MONITOR.setRegistryName(Names.ITEM_MONITOR); + ENERGY_COUNTER.setRegistryName(Names.ENERGY_COUNTER); } @SubscribeEvent + @SuppressWarnings("unused") public static void register(final RegistryEvent.Register> event) { event.getRegistry().register(ANDROID_STATION); event.getRegistry().register(BATTERY_BANK); @@ -626,12 +639,14 @@ public class Registry { event.getRegistry().register(CARGO_CRATE); event.getRegistry().register(DRIVE_RACK); event.getRegistry().register(ITEM_MONITOR); + event.getRegistry().register(ENERGY_COUNTER); // OverdriveThatMatters.LOGGER.info("Registered block entities"); } @SubscribeEvent + @SuppressWarnings("unused") public static void registerRenderers(final FMLClientSetupEvent event) { BlockEntityRenderers.register(BLACK_HOLE, BlackHoleRenderer::new); } @@ -653,6 +668,7 @@ public class Registry { } @SubscribeEvent + @SuppressWarnings("unused") public static void register(final RegistryEvent.Register> event) { event.getRegistry().register(AIR_BAGS); event.getRegistry().register(LIMB_OVERCLOCKING); @@ -852,6 +868,7 @@ public class Registry { } @SubscribeEvent + @SuppressWarnings("unused") public static void register(final RegistryEvent.Register> event) { event.getRegistry().register(AIR_BAGS); event.getRegistry().register(NANOBOTS); @@ -891,6 +908,7 @@ public class Registry { public static final MenuType CARGO_CRATE = new MenuType<>(CargoCrateMenu::new); public static final MenuType DRIVE_RACK = new MenuType<>(DriveRackMenu::new); public static final MenuType ITEM_MONITOR = new MenuType<>(ItemMonitorMenu::new); + public static final MenuType ENERGY_COUNTER = new MenuType<>(EnergyCounterMenu::new); static { ANDROID_STATION.setRegistryName(Names.ANDROID_STATION); @@ -906,9 +924,11 @@ public class Registry { CARGO_CRATE.setRegistryName(Names.CARGO_CRATE); DRIVE_RACK.setRegistryName(Names.DRIVE_RACK); ITEM_MONITOR.setRegistryName(Names.ITEM_MONITOR); + ENERGY_COUNTER.setRegistryName(Names.ENERGY_COUNTER); } @SubscribeEvent + @SuppressWarnings("unused") public static void register(final RegistryEvent.Register> event) { event.getRegistry().register(ANDROID_STATION); event.getRegistry().register(BATTERY_BANK); @@ -923,11 +943,13 @@ public class Registry { event.getRegistry().register(CARGO_CRATE); event.getRegistry().register(DRIVE_RACK); event.getRegistry().register(ITEM_MONITOR); + event.getRegistry().register(ENERGY_COUNTER); // OverdriveThatMatters.LOGGER.info("Registered menus"); } @SubscribeEvent + @SuppressWarnings("unused") public static void registerScreens(final FMLClientSetupEvent event) { MenuScreens.register(ANDROID_STATION, AndroidStationScreen::new); MenuScreens.register(BATTERY_BANK, BatteryBankScreen::new); @@ -942,6 +964,7 @@ public class Registry { MenuScreens.register(CARGO_CRATE, CargoCrateScreen::new); MenuScreens.register(DRIVE_RACK, DriveRackScreen::new); MenuScreens.register(ITEM_MONITOR, ItemMonitorScreen::new); + MenuScreens.register(ENERGY_COUNTER, EnergyCounterScreen::new); // OverdriveThatMatters.LOGGER.info("Registered screens"); } @@ -949,6 +972,7 @@ public class Registry { public static class Stats { @SubscribeEvent + @SuppressWarnings("unused") public static void registerVanilla(final FMLCommonSetupEvent event) { net.minecraft.core.Registry.register(net.minecraft.core.Registry.CUSTOM_STAT, Names.DAMAGE_ABSORBED, Names.DAMAGE_ABSORBED); net.minecraft.core.Registry.register(net.minecraft.core.Registry.CUSTOM_STAT, Names.HEALTH_REGENERATED, Names.HEALTH_REGENERATED); diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/BlockEnergyCounter.java b/src/main/java/ru/dbotthepony/mc/otm/block/BlockEnergyCounter.java new file mode 100644 index 000000000..e8504085b --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/block/BlockEnergyCounter.java @@ -0,0 +1,64 @@ +package ru.dbotthepony.mc.otm.block; + +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class BlockEnergyCounter extends BlockMattery implements EntityBlock { + public static final EnumProperty INPUT_DIRECTION = EnumProperty.create("input", Direction.class); + public static final EnumProperty IF_DIRECTION = EnumProperty.create("if", Direction.class); + + @Nullable + @Override + public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { + return new BlockEntityEnergyCounter(blockPos, blockState); + } + + @Nullable + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + final var input_direction = context.getPlayer() != null && context.getPlayer().isCrouching() ? context.getClickedFace().getOpposite() : context.getClickedFace(); + final var opposite = input_direction.getOpposite(); + + Direction dir = null; + + for (var _dir : context.getNearestLookingDirections()) { + if (_dir != input_direction && _dir != opposite) { + dir = _dir.getOpposite(); + break; + } + } + + assert dir != null; + return defaultBlockState().setValue(INPUT_DIRECTION, input_direction).setValue(IF_DIRECTION, dir); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder p_49915_) { + super.createBlockStateDefinition(p_49915_); + p_49915_.add(INPUT_DIRECTION, IF_DIRECTION); + } + + @Override + public void neighborChanged(BlockState state, Level level, BlockPos pos, Block sender, BlockPos sender_pos, boolean flag) { + super.neighborChanged(state, level, pos, sender, sender_pos, flag); + + if (!level.isClientSide && level.getBlockEntity(pos) instanceof BlockEntityEnergyCounter tile) { + tile.checkSurroundings(level); + } + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.java index 368487805..d49602d17 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityBatteryBank.java @@ -323,7 +323,7 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { BlockEntity get_entity = level.getBlockEntity(blockPos.offset(tile.getBlockState().getValue(BlockMatteryRotatable.FACING).getNormal())); if (get_entity != null) { - Optional cap = get_entity.getCapability(MatteryCapability.ENERGY).resolve(); + Optional cap = get_entity.getCapability(MatteryCapability.ENERGY, tile.getBlockState().getValue(BlockMatteryRotatable.FACING).getOpposite()).resolve(); if (cap.isPresent()) { if (cap.get().canReceive()) { @@ -333,7 +333,7 @@ public class BlockEntityBatteryBank extends BlockEntityMattery { cap.get().receiveEnergyOuter(diff, false); } } else { - Optional cap2 = get_entity.getCapability(CapabilityEnergy.ENERGY).resolve(); + Optional cap2 = get_entity.getCapability(CapabilityEnergy.ENERGY, tile.getBlockState().getValue(BlockMatteryRotatable.FACING).getOpposite()).resolve(); if (cap2.isPresent()) { if (cap2.get().canReceive()) { diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.java new file mode 100644 index 000000000..660c03d25 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityEnergyCounter.java @@ -0,0 +1,314 @@ +package ru.dbotthepony.mc.otm.block.entity; + +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.server.level.ServerLevel; +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.state.BlockState; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.energy.CapabilityEnergy; +import net.minecraftforge.energy.IEnergyStorage; +import ru.dbotthepony.mc.otm.OverdriveThatMatters; +import ru.dbotthepony.mc.otm.Registry; +import ru.dbotthepony.mc.otm.block.BlockEnergyCounter; +import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; +import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; +import java.lang.ref.WeakReference; +import java.math.BigDecimal; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class BlockEntityEnergyCounter extends BlockEntityMattery { + protected BigDecimal passed = BigDecimal.ZERO; + + public BigDecimal getPassed() { + return passed; + } + + public BlockEntityEnergyCounter(BlockPos p_155229_, BlockState p_155230_) { + super(Registry.BlockEntities.ENERGY_COUNTER, p_155229_, p_155230_); + } + + @Override + public CompoundTag save(CompoundTag nbt) { + nbt.putString("passed", passed.toString()); + return super.save(nbt); + } + + @Override + public void load(CompoundTag nbt) { + super.load(nbt); + + if (nbt.get("passed") instanceof StringTag tag) + passed = new BigDecimal(tag.getAsString()); + } + + private static final TranslatableComponent NAME = new TranslatableComponent("block.overdrive_that_matters.energy_counter"); + + @Override + protected Component getDefaultDisplayName() { + return NAME; + } + + @Nullable + @Override + public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) { + return new EnergyCounterMenu(containerID, inventory, this); + } + + public final EnergyCounterCap input = new EnergyCounterCap(true); + public final EnergyCounterCap output = new EnergyCounterCap(false); + + protected LazyOptional input_cap_mte = LazyOptional.empty(); + protected LazyOptional input_cap_fe = LazyOptional.empty(); + protected LazyOptional output_cap_mte = LazyOptional.empty(); + protected LazyOptional output_cap_fe = LazyOptional.empty(); + + @Override + public void setLevel(Level p_155231_) { + super.setLevel(p_155231_); + + if (p_155231_ instanceof ServerLevel level) { + OverdriveThatMatters.tickOnce(level, this::checkSurroundings); + } + } + + public class EnergyCounterCap implements IMatteryEnergyStorage { + public final boolean is_input; + + public EnergyCounterCap(boolean is_input) { + this.is_input = is_input; + } + + private EnergyCounterCap opposite() { + return is_input ? output : input; + } + + @Override + public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) { + return extractEnergyInner(howMuch, simulate); + } + + @Override + public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) { + if (is_input) + return BigDecimal.ZERO; + + if (input_cap_mte.isPresent()) { + final var value = input_cap_mte.resolve().get().extractEnergyOuter(howMuch, simulate); + + if (!simulate) { + passed = passed.add(value); + } + + return value; + } + + if (input_cap_fe.isPresent()) { + final var value = MatteryCapability.drainFE(input_cap_fe.resolve().get(), howMuch, simulate); + + if (!simulate) { + passed = passed.add(value); + } + + return value; + } + + return BigDecimal.ZERO; + } + + @Override + public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) { + return receiveEnergyInner(howMuch, simulate); + } + + @Override + public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) { + if (!is_input) + return BigDecimal.ZERO; + + if (output_cap_mte.isPresent()) { + final var value = output_cap_mte.resolve().get().receiveEnergyOuter(howMuch, simulate); + + if (!simulate) { + passed = passed.add(value); + } + + return value; + } + + if (output_cap_fe.isPresent()) { + final var value = MatteryCapability.floodFE(output_cap_fe.resolve().get(), howMuch, simulate); + + if (!simulate) { + passed = passed.add(value); + } + + return value; + } + + return BigDecimal.ZERO; + } + + @Override + public BigDecimal getBatteryLevel() { + if (is_input) { + if (output_cap_mte.isPresent()) { + return output_cap_mte.resolve().get().getBatteryLevel(); + } + + if (output_cap_fe.isPresent()) { + return new BigDecimal(output_cap_fe.resolve().get().getEnergyStored()); + } + } else { + if (input_cap_mte.isPresent()) { + return input_cap_mte.resolve().get().getBatteryLevel(); + } + + if (input_cap_fe.isPresent()) { + return new BigDecimal(input_cap_fe.resolve().get().getEnergyStored()); + } + } + + return BigDecimal.ZERO; + } + + @Override + public BigDecimal getMaxBatteryLevel() { + if (is_input) { + if (output_cap_mte.isPresent()) { + return output_cap_mte.resolve().get().getMaxBatteryLevel(); + } + + if (output_cap_fe.isPresent()) { + return new BigDecimal(output_cap_fe.resolve().get().getMaxEnergyStored()); + } + } else { + if (input_cap_mte.isPresent()) { + return input_cap_mte.resolve().get().getMaxBatteryLevel(); + } + + if (input_cap_fe.isPresent()) { + return new BigDecimal(input_cap_fe.resolve().get().getMaxEnergyStored()); + } + } + + return BigDecimal.ZERO; + } + + @Override + public boolean canExtract() { + return !is_input; + } + + @Override + public boolean canReceive() { + return is_input; + } + } + + protected LazyOptional input_resolver = LazyOptional.of(() -> input); + protected LazyOptional output_resolver = LazyOptional.of(() -> output); + + @Override + public void invalidateCaps() { + super.invalidateCaps(); + input_resolver.invalidate(); + output_resolver.invalidate(); + } + + @Override + public void reviveCaps() { + super.reviveCaps(); + input_resolver = LazyOptional.of(() -> input); + output_resolver = LazyOptional.of(() -> output); + } + + @Override + @SuppressWarnings("deprecation") + public void setBlockState(BlockState p_155251_) { + final var old = getBlockState(); + + super.setBlockState(p_155251_); + + if (p_155251_ != old && p_155251_.getValue(BlockEnergyCounter.INPUT_DIRECTION) != old.getValue(BlockEnergyCounter.INPUT_DIRECTION)) { + input_resolver.invalidate(); + output_resolver.invalidate(); + + input_resolver = LazyOptional.of(() -> input); + output_resolver = LazyOptional.of(() -> output); + + if (level != null) + checkSurroundings(level); + } + } + + private LazyOptional getAndBind(Level level, LazyOptional old, Capability cap, Direction side) { + final var ent = level.getBlockEntity(getBlockPos().offset(side.getNormal())); + + if (ent == null) + return LazyOptional.empty(); + + final var resolve = ent.getCapability(cap, side.getOpposite()); + + if (resolve != old) { + final var weak = new WeakReference<>(this); + + resolve.addListener((l) -> { + final var get = weak.get(); + + if (get != null && get.level != null) { + get.checkSurroundings(get.level); + } + }); + + return resolve; + } + + return old; + } + + public void checkSurroundings(Level level) { + if (isRemoved() || !(level instanceof ServerLevel)) + return; + + input_cap_mte = getAndBind(level, input_cap_mte, MatteryCapability.ENERGY, getBlockState().getValue(BlockEnergyCounter.INPUT_DIRECTION)); + input_cap_fe = getAndBind(level, input_cap_fe, CapabilityEnergy.ENERGY, getBlockState().getValue(BlockEnergyCounter.INPUT_DIRECTION)); + + output_cap_mte = getAndBind(level, output_cap_mte, MatteryCapability.ENERGY, getBlockState().getValue(BlockEnergyCounter.INPUT_DIRECTION).getOpposite()); + output_cap_fe = getAndBind(level, output_cap_fe, CapabilityEnergy.ENERGY, getBlockState().getValue(BlockEnergyCounter.INPUT_DIRECTION).getOpposite()); + } + + @Nonnull + @Override + public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { + if (side == null || isRemoved()) + return super.getCapability(cap, side); + + if (side == getBlockState().getValue(BlockEnergyCounter.INPUT_DIRECTION)) { + if (cap == MatteryCapability.ENERGY || cap == CapabilityEnergy.ENERGY) { + return input_resolver.cast(); + } + } else if (side == getBlockState().getValue(BlockEnergyCounter.INPUT_DIRECTION).getOpposite()) { + if (cap == MatteryCapability.ENERGY || cap == CapabilityEnergy.ENERGY) { + return output_resolver.cast(); + } + } + + return super.getCapability(cap, side); + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/client/render/RGBAColor.java b/src/main/java/ru/dbotthepony/mc/otm/client/render/RGBAColor.java index b909030b7..dc6fcccb2 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/client/render/RGBAColor.java +++ b/src/main/java/ru/dbotthepony/mc/otm/client/render/RGBAColor.java @@ -3,15 +3,23 @@ package ru.dbotthepony.mc.otm.client.render; import com.mojang.blaze3d.systems.RenderSystem; public record RGBAColor(float r, float g, float b, float a) { - public RGBAColor(float r, float g, float b, float a) { - this.r = r; - this.g = g; - this.b = b; - this.a = a; - } - public static final RGBAColor BLACK = new RGBAColor(0, 0, 0, 1f); public static final RGBAColor WHITE = new RGBAColor(1f, 1f, 1f, 1f); + public static final RGBAColor SLATE_GRAY = new RGBAColor(64, 64, 64); + + public int whole() { + return + Math.min(255, Math.max(0, Math.round(r * 255))) << 16 | + Math.min(255, Math.max(0, Math.round(g * 255))) << 8 | + Math.min(255, Math.max(0, Math.round(b * 255))); + } + + public int wholeinv() { + return + Math.min(255, Math.max(0, Math.round(b * 255))) << 16 | + Math.min(255, Math.max(0, Math.round(g * 255))) << 8 | + Math.min(255, Math.max(0, Math.round(r * 255))); + } public RGBAColor(int r, int g, int b) { this(r / 255F, g / 255F, b / 255F, 1F); diff --git a/src/main/java/ru/dbotthepony/mc/otm/client/screen/EnergyCounterScreen.java b/src/main/java/ru/dbotthepony/mc/otm/client/screen/EnergyCounterScreen.java new file mode 100644 index 000000000..0e17c1899 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/client/screen/EnergyCounterScreen.java @@ -0,0 +1,38 @@ +package ru.dbotthepony.mc.otm.client.screen; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.world.entity.player.Inventory; +import ru.dbotthepony.mc.otm.client.screen.panels.Dock; +import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel; +import ru.dbotthepony.mc.otm.client.screen.panels.Label; +import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu; +import ru.dbotthepony.mc.otm.menu.FormattingHelper; + +import javax.annotation.Nullable; + +public class EnergyCounterScreen extends MatteryScreen { + public EnergyCounterScreen(EnergyCounterMenu menu, Inventory inventory, Component title) { + super(menu, inventory, title); + } + + @Nullable + @Override + protected FramePanel makeMainFrame() { + var frame = super.makeMainFrame(); + + var label = new Label(this, frame) { + @Override + public void tick() { + super.tick(); + + setText(new TranslatableComponent("otm.item.power.passed", FormattingHelper.formatPower(menu.passed.getDecimal()))); + } + }; + + label.setDock(Dock.TOP); + + return frame; + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.java b/src/main/java/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.java index 77ba035a5..9046ee445 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.java +++ b/src/main/java/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.java @@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.client.screen.panels; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; import net.minecraft.client.gui.components.events.GuiEventListener; import ru.dbotthepony.mc.otm.client.screen.MatteryScreen; import ru.dbotthepony.mc.otm.client.render.RenderHelper; @@ -17,6 +18,7 @@ import java.util.List; * This panel represent part of GMod's Panels API * which allows much simpler GUI composition */ +@SuppressWarnings("unused") public class EditablePanel implements GuiEventListener { public record ScreenPos(float x, float y) {} @@ -149,6 +151,10 @@ public class EditablePanel implements GuiEventListener { } + protected Font font() { + return screen.getFont(); + } + /** * @param stack * @param mouse_x diff --git a/src/main/java/ru/dbotthepony/mc/otm/client/screen/panels/Label.java b/src/main/java/ru/dbotthepony/mc/otm/client/screen/panels/Label.java new file mode 100644 index 000000000..711131dc0 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/client/screen/panels/Label.java @@ -0,0 +1,60 @@ +package ru.dbotthepony.mc.otm.client.screen.panels; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextComponent; +import ru.dbotthepony.mc.otm.client.render.RGBAColor; +import ru.dbotthepony.mc.otm.client.screen.MatteryScreen; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class Label extends EditablePanel { + protected Component text = new TextComponent("Label"); + + public Label(@Nonnull MatteryScreen screen, @Nullable EditablePanel parent, float x, float y, float width, float height) { + super(screen, parent, x, y, width, height); + scissor = true; + } + + public Label(@Nonnull MatteryScreen screen, @Nullable EditablePanel parent) { + super(screen, parent); + scissor = true; + } + + public Label(@Nonnull MatteryScreen screen, @Nullable EditablePanel parent, float x, float y) { + super(screen, parent, x, y, 100, 12); + scissor = true; + } + + public Label(@Nonnull MatteryScreen screen, @Nullable EditablePanel parent, float x, float y, float width, float height, Component text) { + super(screen, parent, x, y, width, height); + scissor = true; + this.text = text; + } + + public Label(@Nonnull MatteryScreen screen, @Nullable EditablePanel parent, Component text) { + super(screen, parent); + scissor = true; + this.text = text; + } + + public Label(@Nonnull MatteryScreen screen, @Nullable EditablePanel parent, float x, float y, Component text) { + super(screen, parent, x, y, 100, 12); + scissor = true; + this.text = text; + } + + public Component getText() { + return text; + } + + public void setText(Component text) { + this.text = text; + } + + @Override + protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) { + font().draw(stack, text, 0, 0, RGBAColor.SLATE_GRAY.wholeinv()); + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/EnergyCounterMenu.java b/src/main/java/ru/dbotthepony/mc/otm/menu/EnergyCounterMenu.java new file mode 100644 index 000000000..32fbd7ac8 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/EnergyCounterMenu.java @@ -0,0 +1,43 @@ +package ru.dbotthepony.mc.otm.menu; + +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.level.block.entity.BlockEntity; +import ru.dbotthepony.mc.otm.Registry; +import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter; +import ru.dbotthepony.mc.otm.menu.data.BigDecimalDataContainer; + +import javax.annotation.Nullable; + +public class EnergyCounterMenu extends MatteryMenu { + public final BigDecimalDataContainer passed = new BigDecimalDataContainer(); + + public EnergyCounterMenu(int p_38852_, Inventory inventory) { + this(p_38852_, inventory, null); + } + + public EnergyCounterMenu(int p_38852_, Inventory inventory, BlockEntityEnergyCounter tile) { + super(Registry.Menus.ENERGY_COUNTER, p_38852_, inventory, tile); + + addDataSlots(passed); + } + + @Override + public void broadcastChanges() { + if (tile != null) { + passed.setDecimal(((BlockEntityEnergyCounter) tile).getPassed()); + } + + super.broadcastChanges(); + } + + @Override + protected int getWorkingSlotStart() { + return 0; + } + + @Override + protected int getWorkingSlotEnd() { + return 0; + } +} diff --git a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json index c6661cd6a..1270beabc 100644 --- a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json +++ b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json @@ -32,6 +32,7 @@ "otm.item.power.infinite.storage": "Stored energy: Infinity / Infinity", "otm.item.power.infinite.throughput": "Max I/O Infinite / Infinite", + "otm.item.power.passed": "Passed energy: %s", "otm.item.power.normal.storage": "Stored energy: %s / %s", "otm.item.power.normal.throughput": "Max I/O %s / %s",