diff --git a/src/main/java/ru/dbotthepony/mc/otm/MatterRegistry.java b/src/main/java/ru/dbotthepony/mc/otm/MatterRegistry.java index a849ed3c2..d80966baa 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/MatterRegistry.java +++ b/src/main/java/ru/dbotthepony/mc/otm/MatterRegistry.java @@ -12,6 +12,7 @@ import net.minecraft.world.item.crafting.RecipeType; import net.minecraftforge.event.entity.player.ItemTooltipEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fmlserverevents.FMLServerStartedEvent; +import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.menu.FormattingHelper; import javax.annotation.Nullable; @@ -28,6 +29,15 @@ public class MatterRegistry { return ITEMS.getOrDefault(item, INITIAL_ITEMS.getOrDefault(item, BigDecimal.ZERO)); } + public static boolean hasMatterValue(Item item) { + return ITEMS.containsKey(item) || INITIAL_ITEMS.containsKey(item); + } + + public static boolean hasMatterValue(ItemStack item) { + return hasMatterValue(item.getItem()); + } + + public static BigDecimal getMatterValue(ItemStack stack) { Item item = stack.getItem(); @@ -280,7 +290,7 @@ public class MatterRegistry { private static final HashMap seen_items = new HashMap<>(); private static final HashMap seen_items_child = new HashMap<>(); - public static final MathContext ROUND_RULES = new MathContext(32, RoundingMode.DOWN); + public static final MathContext ROUND_RULES = MatteryCapability.ROUND_RULES; private static boolean solve_occured = false; private static Set defered_items = new HashSet<>(); @@ -468,6 +478,7 @@ public class MatterRegistry { // clean up garbage usages.clear(); results.clear(); + defered_items.clear(); ArrayList> required_resolve = new ArrayList<>(seen_items.entrySet()); required_resolve.sort((a, b) -> Integer.compare(0, a.getValue().compareTo(b.getValue()))); diff --git a/src/main/java/ru/dbotthepony/mc/otm/Registry.java b/src/main/java/ru/dbotthepony/mc/otm/Registry.java index 991e8ff00..374e47472 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/Registry.java +++ b/src/main/java/ru/dbotthepony/mc/otm/Registry.java @@ -17,14 +17,18 @@ import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import ru.dbotthepony.mc.otm.block.BlockAndroidStation; import ru.dbotthepony.mc.otm.block.BlockBatteryBank; +import ru.dbotthepony.mc.otm.block.BlockMatterDecomposer; import ru.dbotthepony.mc.otm.block.entity.BlockEntityAndroidStation; import ru.dbotthepony.mc.otm.block.entity.BlockEntityBatteryBank; +import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterDecomposer; import ru.dbotthepony.mc.otm.item.ItemBattery; import ru.dbotthepony.mc.otm.item.ItemPill; import ru.dbotthepony.mc.otm.menu.AndroidStationMenu; import ru.dbotthepony.mc.otm.menu.BatteryBankMenu; +import ru.dbotthepony.mc.otm.menu.MatterDecomposerMenu; import ru.dbotthepony.mc.otm.screen.AndroidStationScreen; import ru.dbotthepony.mc.otm.screen.BatteryBankScreen; +import ru.dbotthepony.mc.otm.screen.MatterDecomposerScreen; import java.math.BigDecimal; @@ -40,6 +44,8 @@ public class Registry { public static class Names { public static final ResourceLocation ANDROID_STATION = new ResourceLocation(OverdriveThatMatters.MOD_ID, "android_station"); public static final ResourceLocation BATTERY_BANK = new ResourceLocation(OverdriveThatMatters.MOD_ID, "battery_bank"); + public static final ResourceLocation MATTER_DECOMPOSER = new ResourceLocation(OverdriveThatMatters.MOD_ID, "matter_decomposer"); + public static final ResourceLocation ANDROID_CAPABILITY = new ResourceLocation(OverdriveThatMatters.MOD_ID, "android_capability"); public static final ResourceLocation PILL_ANDROID = new ResourceLocation(OverdriveThatMatters.MOD_ID, "pill_android"); @@ -56,15 +62,18 @@ public class Registry { public static class Blocks { public static final Block ANDROID_STATION = new BlockAndroidStation(); public static final Block BATTERY_BANK = new BlockBatteryBank(); + public static final Block MATTER_DECOMPOSER = new BlockMatterDecomposer(); static { ANDROID_STATION.setRegistryName(Names.ANDROID_STATION); BATTERY_BANK.setRegistryName(Names.BATTERY_BANK); + MATTER_DECOMPOSER.setRegistryName(Names.MATTER_DECOMPOSER); } public static void register(final RegistryEvent.Register event) { event.getRegistry().register(ANDROID_STATION); event.getRegistry().register(BATTERY_BANK); + event.getRegistry().register(MATTER_DECOMPOSER); // OverdriveThatMatters.LOGGER.info("Registered blocks"); } @@ -73,6 +82,7 @@ public class Registry { public static class Items { public static final Item ANDROID_STATION = new BlockItem(Blocks.ANDROID_STATION, new Item.Properties().stacksTo(64).tab(CreativeModeTab.TAB_MISC)); public static final Item BATTERY_BANK = new BlockItem(Blocks.BATTERY_BANK, new Item.Properties().stacksTo(64).tab(CreativeModeTab.TAB_MISC)); + public static final Item MATTER_DECOMPOSER = new BlockItem(Blocks.MATTER_DECOMPOSER, new Item.Properties().stacksTo(64).tab(CreativeModeTab.TAB_MISC)); public static final ItemPill PILL_ANDROID = new ItemPill(ItemPill.PillType.BECOME_ANDROID); public static final ItemPill PILL_HUMANE = new ItemPill(ItemPill.PillType.BECOME_HUMANE); @@ -86,6 +96,7 @@ public class Registry { static { ANDROID_STATION.setRegistryName(Names.ANDROID_STATION); BATTERY_BANK.setRegistryName(Names.BATTERY_BANK); + MATTER_DECOMPOSER.setRegistryName(Names.MATTER_DECOMPOSER); PILL_ANDROID.setRegistryName(Names.PILL_ANDROID); PILL_HUMANE.setRegistryName(Names.PILL_HUMANE); @@ -100,6 +111,7 @@ public class Registry { public static void register(final RegistryEvent.Register event) { event.getRegistry().register(ANDROID_STATION); event.getRegistry().register(BATTERY_BANK); + event.getRegistry().register(MATTER_DECOMPOSER); event.getRegistry().register(PILL_ANDROID); event.getRegistry().register(PILL_HUMANE); @@ -117,15 +129,18 @@ public class Registry { public static class BlockEntities { public static BlockEntityType ANDROID_STATION = BlockEntityType.Builder.of(BlockEntityAndroidStation::new, Blocks.ANDROID_STATION).build(null); public static BlockEntityType BATTERY_BANK = BlockEntityType.Builder.of(BlockEntityBatteryBank::new, Blocks.BATTERY_BANK).build(null); + public static BlockEntityType MATTER_DECOMPOSER = BlockEntityType.Builder.of(BlockEntityMatterDecomposer::new, Blocks.MATTER_DECOMPOSER).build(null); static { ANDROID_STATION.setRegistryName(Names.ANDROID_STATION); BATTERY_BANK.setRegistryName(Names.BATTERY_BANK); + MATTER_DECOMPOSER.setRegistryName(Names.MATTER_DECOMPOSER); } public static void register(final RegistryEvent.Register> event) { event.getRegistry().register(ANDROID_STATION); event.getRegistry().register(BATTERY_BANK); + event.getRegistry().register(MATTER_DECOMPOSER); // OverdriveThatMatters.LOGGER.info("Registered block entities"); } @@ -134,15 +149,18 @@ public class Registry { public static class Menus { public static final MenuType ANDROID_STATION = new MenuType<>(AndroidStationMenu::new); public static final MenuType BATTERY_BANK = new MenuType<>(BatteryBankMenu::new); + public static final MenuType MATTER_DECOMPOSER = new MenuType<>(MatterDecomposerMenu::new); static { ANDROID_STATION.setRegistryName(Names.ANDROID_STATION); BATTERY_BANK.setRegistryName(Names.BATTERY_BANK); + MATTER_DECOMPOSER.setRegistryName(Names.MATTER_DECOMPOSER); } public static void register(final RegistryEvent.Register> event) { event.getRegistry().register(ANDROID_STATION); event.getRegistry().register(BATTERY_BANK); + event.getRegistry().register(MATTER_DECOMPOSER); // OverdriveThatMatters.LOGGER.info("Registered menus"); } @@ -150,6 +168,7 @@ public class Registry { public static void registerScreens(final FMLClientSetupEvent event) { MenuScreens.register(ANDROID_STATION, AndroidStationScreen::new); MenuScreens.register(BATTERY_BANK, BatteryBankScreen::new); + MenuScreens.register(MATTER_DECOMPOSER, MatterDecomposerScreen::new); // OverdriveThatMatters.LOGGER.info("Registered screens"); } diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/BlockMatterDecomposer.java b/src/main/java/ru/dbotthepony/mc/otm/block/BlockMatterDecomposer.java new file mode 100644 index 000000000..d05bc29d6 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/block/BlockMatterDecomposer.java @@ -0,0 +1,27 @@ +package ru.dbotthepony.mc.otm.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import ru.dbotthepony.mc.otm.Registry; +import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterDecomposer; + +import javax.annotation.Nullable; + +public class BlockMatterDecomposer extends BlockMatteryRotatableMachineBase implements EntityBlock { + @Nullable + @Override + public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) { + return new BlockEntityMatterDecomposer(blockPos, blockState); + } + + @Nullable + @Override + public BlockEntityTicker getTicker(Level p_153212_, BlockState p_153213_, BlockEntityType p_153214_) { + return p_153212_.isClientSide || p_153214_ != Registry.BlockEntities.MATTER_DECOMPOSER ? null : BlockEntityMatterDecomposer::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 index efd62b3d5..21bc6509d 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityAndroidStation.java @@ -39,7 +39,6 @@ public class BlockEntityAndroidStation extends BlockEntityMatteryPoweredMachine public BlockEntityAndroidStation(BlockPos p_155229_, BlockState p_155230_) { super(Registry.BlockEntities.ANDROID_STATION, p_155229_, p_155230_); energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new BigDecimal(100_000), new BigDecimal(250), new BigDecimal(250)); - energy_resolver = LazyOptional.of(() -> energy); } public static void tick(Level level, BlockPos blockPos, BlockState blockState, T t) { 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 2f4f43422..37867959c 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 @@ -70,25 +70,15 @@ public class BlockEntityBatteryBank extends BlockEntityMatteryMachine { } @Override - public boolean canExtractOuter() { + public boolean canExtract() { return mode == BankMode.EXTRACT || mode == BankMode.BIDIRECTIONAL; } @Override - public boolean canReceiveOuter() { + public boolean canReceive() { return mode == BankMode.RECEIVE || mode == BankMode.BIDIRECTIONAL; } - @Override - public boolean canExtractInner() { - return true; - } - - @Override - public boolean canReceiveInner() { - return true; - } - @Nonnull @Override public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) { @@ -318,7 +308,7 @@ public class BlockEntityBatteryBank extends BlockEntityMatteryMachine { Optional cap = get_entity.getCapability(MatteryCapability.ENERGY).resolve(); if (cap.isPresent()) { - if (cap.get().canReceiveOuter()) { + if (cap.get().canReceive()) { BatteryBankDistribution distribution = tile.energy.getDistribution(false); BigDecimal diff = cap.get().receiveEnergyOuter(distribution.max_throughput, true); diff = tile.energy.extractEnergyOuter(diff, false); diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.java new file mode 100644 index 000000000..d59bf07a4 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.java @@ -0,0 +1,243 @@ +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.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; +import ru.dbotthepony.mc.otm.MatterRegistry; +import ru.dbotthepony.mc.otm.OverdriveThatMatters; +import ru.dbotthepony.mc.otm.Registry; +import ru.dbotthepony.mc.otm.capability.IMatterHandler; +import ru.dbotthepony.mc.otm.capability.MatterHandlerCapability; +import ru.dbotthepony.mc.otm.capability.MatteryCapability; +import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage; +import ru.dbotthepony.mc.otm.container.SimpleSerializableContainer; +import ru.dbotthepony.mc.otm.menu.MatterDecomposerMenu; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.math.BigDecimal; + +public class BlockEntityMatterDecomposer extends BlockEntityMatteryPoweredMachine implements IItemHandler { + private static final TranslatableComponent MACHINE_NAME = new TranslatableComponent("block.overdrive_that_matters.matter_decomposer"); + private boolean valid = true; + public final MatterHandlerCapability matter = new MatterHandlerCapability(this::setChanged, IMatterHandler.MatterDirection.EXTRACT, new BigDecimal("20")); + private final LazyOptional matter_resolver = LazyOptional.of(() -> matter); + private final LazyOptional handler_resolver = LazyOptional.of(() -> this); + + // вход, выход + public SimpleSerializableContainer item_container = new SimpleSerializableContainer(this::setChanged, 2); + + public BlockEntityMatterDecomposer(BlockPos p_155229_, BlockState p_155230_) { + super(Registry.BlockEntities.MATTER_DECOMPOSER, p_155229_, p_155230_); + energy = new MatteryMachineEnergyStorage(this, MatteryMachineEnergyStorage.MachineType.WORKER, new BigDecimal(400_000), new BigDecimal(2000), new BigDecimal(2000)); + } + + @Override + public int getSlots() { + return item_container.getContainerSize(); + } + + @Nonnull + @Override + public ItemStack getStackInSlot(int slot) { + return item_container.getItem(slot); + } + + @Nonnull + @Override + public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) { + if (slot != 0) + return stack; + + if (!MatterRegistry.hasMatterValue(stack)) + return stack; + + ItemStack self_stack = item_container.getItem(slot); + + if (self_stack.isEmpty()) { + if (!simulate) { + item_container.setItem(slot, stack.copy()); + } + + return ItemStack.EMPTY; + } else if (self_stack.isStackable() && self_stack.getMaxStackSize() > self_stack.getCount() && ItemStack.isSameItemSameTags(self_stack, stack)) { + int new_count = Math.min(self_stack.getMaxStackSize(), self_stack.getCount() + stack.getCount()); + int diff = new_count - self_stack.getCount(); + + if (diff != 0) { + if (!simulate) { + self_stack.grow(diff); + item_container.setChanged(); + } + + ItemStack copy = stack.copy(); + copy.shrink(diff); + return copy; + } + } + + return stack; + } + + @Nonnull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (slot != 1 || amount == 0) + return ItemStack.EMPTY.copy(); + + if (amount < 0) + throw new IllegalArgumentException("Can not extract negative amount of items"); + + ItemStack self_stack = item_container.getItem(slot); + + if (self_stack.isEmpty()) + return ItemStack.EMPTY.copy(); + + int minimal = Math.min(amount, self_stack.getCount()); + ItemStack copy = self_stack.copy(); + copy.setCount(minimal); + + if (!simulate) { + self_stack.shrink(minimal); + item_container.setChanged(); + } + + return copy; + } + + @Override + public int getSlotLimit(int slot) { + // return Items.AIR.getMaxStackSize(); + return item_container.getMaxStackSize(); + } + + @Override + public boolean isItemValid(int slot, @Nonnull ItemStack stack) { + return slot == 0 && MatterRegistry.hasMatterValue(stack); + } + + @Override + protected Component getDefaultDisplayName() { + return MACHINE_NAME; + } + + @Nullable + @Override + public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) { + return new MatterDecomposerMenu(containerID, inventory, this); + } + + @Override + public CompoundTag save(CompoundTag nbt) { + nbt.put("work_inventory", item_container.serializeNBT()); + nbt.putDouble("work_progress", work_progress); + nbt.put("work_item", work_item.serializeNBT()); + + nbt.put("matter_capability", matter.serializeNBT()); + + return super.save(nbt); + } + + @Override + public void load(CompoundTag nbt) { + super.load(nbt); + + if (nbt.contains("matter_capability") && nbt.get("matter_capability") instanceof CompoundTag tag) + matter.deserializeNBT(tag); + + if (nbt.contains("work_inventory") && nbt.get("work_inventory") instanceof CompoundTag tag) + item_container = SimpleSerializableContainer.of(this::setChanged, tag, item_container.getContainerSize()); + + work_progress = nbt.getDouble("work_progress"); + + if (nbt.contains("work_item") && nbt.get("work_item") instanceof CompoundTag tag) + work_item = ItemStack.of(tag); + } + + @Override + public void reviveCaps() { + valid = true; + super.reviveCaps(); + } + + @Override + public void invalidateCaps() { + valid = false; + super.invalidateCaps(); + } + + @Nonnull + @Override + public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { + if (valid) { + if (cap == MatteryCapability.MATTER) + return matter_resolver.cast(); + + if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) + return handler_resolver.cast(); + } + + return super.getCapability(cap, side); + } + + private static final BigDecimal ENERGY_CONSUMPTION_PER_TICK = new BigDecimal("240"); + + private double work_progress = 0; + private ItemStack work_item = ItemStack.EMPTY; + + public double getWorkProgress() { + return work_progress; + } + + public static void tick(Level level, BlockPos blockPos, BlockState blockState, T t) { + if (t instanceof BlockEntityMatterDecomposer tile) { + tile.tickBatteryCharge(); + + ItemStack stack = tile.item_container.getItem(0); + + if (!stack.isEmpty()) { + BigDecimal matter_value = MatterRegistry.getMatterValue(stack); + + if (!matter_value.equals(BigDecimal.ZERO) && tile.matter.canReceiveAll(matter_value)) { + if (!ItemStack.isSameItemSameTags(tile.work_item, stack)) { + tile.work_progress = 0; + tile.work_item = stack.copy(); + } + + tile.work_progress += + // work speed multiplier + tile.workSpeedMultiplier(ENERGY_CONSUMPTION_PER_TICK) * + // unit of full work for getting thing done (0.05 MtU is full unit of work, which is equal one real second) + // the more MtUs are in item, the lesser this value should be + (0.05 / matter_value.doubleValue()) * + // the tick time + 0.05; + + if (tile.work_progress >= 1) { + // work is done! + tile.matter.receiveMatterInner(matter_value, false); + stack.shrink(1); + tile.item_container.setChanged(); + tile.work_progress = 0; + } + } + } else if (tile.work_progress != 0) { + tile.work_progress = 0; + tile.work_item = ItemStack.EMPTY; + } + } + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPoweredMachine.java b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPoweredMachine.java index e262bb8d6..d1aaa01f7 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPoweredMachine.java +++ b/src/main/java/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatteryPoweredMachine.java @@ -5,6 +5,7 @@ import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.StringTag; import net.minecraft.network.chat.Component; +import net.minecraft.world.Container; import net.minecraft.world.SimpleContainer; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.entity.BlockEntityType; @@ -25,12 +26,24 @@ import java.util.Optional; abstract public class BlockEntityMatteryPoweredMachine extends BlockEntityMatteryMachine { protected MatteryMachineEnergyStorage energy = null; - protected LazyOptional energy_resolver = null; + protected final LazyOptional energy_resolver = LazyOptional.of(() -> energy);; private boolean valid = true; public SimpleSerializableContainer battery_container = new SimpleSerializableContainer(this::setChanged, 1); + protected double workSpeedMultiplier(BigDecimal energy_required, boolean simulate) { + BigDecimal extract_much = energy.extractEnergyInner(energy_required, simulate); + return extract_much.divide(energy_required, MatteryCapability.ROUND_RULES).doubleValue(); + } + + protected double workSpeedMultiplier(BigDecimal energy_required) { + return workSpeedMultiplier(energy_required, false); + } + protected void tickBatteryCharge() { + if (energy == null) + return; + if (energy.getMissingPower().compareTo(BigDecimal.ZERO) <= 0) return; @@ -96,7 +109,7 @@ abstract public class BlockEntityMatteryPoweredMachine extends BlockEntityMatter @Nonnull public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { - if (valid && (cap == MatteryCapability.ENERGY || cap == CapabilityEnergy.ENERGY) && energy_resolver != null) { + if (valid && (cap == MatteryCapability.ENERGY || cap == CapabilityEnergy.ENERGY) && energy != null) { return energy_resolver.cast(); } diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/IMatterHandler.java b/src/main/java/ru/dbotthepony/mc/otm/capability/IMatterHandler.java new file mode 100644 index 000000000..eb71a869b --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/IMatterHandler.java @@ -0,0 +1,30 @@ +package ru.dbotthepony.mc.otm.capability; + +import javax.annotation.Nonnull; +import java.math.BigDecimal; + +public interface IMatterHandler { + enum MatterDirection { + RECEIVE, // consumer + EXTRACT, // producer + BIDIRECTIONAL // storage + } + + @Nonnull + BigDecimal getStoredMatter(); + @Nonnull + BigDecimal getMaxStoredMatter(); + + @Nonnull + BigDecimal receiveMatterOuter(BigDecimal howMuch, boolean simulate); + @Nonnull + BigDecimal receiveMatterInner(BigDecimal howMuch, boolean simulate); + + @Nonnull + BigDecimal extractMatterOuter(BigDecimal howMuch, boolean simulate); + @Nonnull + BigDecimal extractMatterInner(BigDecimal howMuch, boolean simulate); + + @Nonnull + MatterDirection getDirection(); +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java b/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java index d8a61bb61..bbb79fa96 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java @@ -132,20 +132,4 @@ public interface IMatteryEnergyStorage extends IEnergyStorage { 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/MatterHandlerCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/MatterHandlerCapability.java new file mode 100644 index 000000000..ca5cc0f7a --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/MatterHandlerCapability.java @@ -0,0 +1,164 @@ +package ru.dbotthepony.mc.otm.capability; + +import net.minecraft.nbt.CompoundTag; +import net.minecraftforge.common.util.INBTSerializable; +import ru.dbotthepony.mc.otm.MatterRegistry; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.math.BigDecimal; + +public class MatterHandlerCapability implements IMatterHandler, INBTSerializable { + protected final Runnable listener; + protected BigDecimal stored = BigDecimal.ZERO; + protected MatterDirection direction; + protected BigDecimal max_storage; + + protected BigDecimal max_receive; + protected BigDecimal max_extract; + + public MatterHandlerCapability( + @Nullable Runnable listener, + MatterDirection direction, + BigDecimal max_storage + ) { + this.listener = listener; + this.direction = direction; + this.max_storage = max_storage; + } + + public MatterHandlerCapability( + @Nullable Runnable listener, + MatterDirection direction, + BigDecimal max_storage, + BigDecimal max_receive, + BigDecimal max_extract + ) { + this(listener, direction, max_storage); + + this.max_receive = max_receive; + this.max_extract = max_extract; + } + + @Nonnull + @Override + public BigDecimal getStoredMatter() { + return stored; + } + + @Nonnull + @Override + public BigDecimal getMaxStoredMatter() { + return max_storage; + } + + public boolean canReceiveAll(BigDecimal value) { + return max_storage.compareTo(value) >= 0 && stored.add(value).compareTo(max_storage) <= 0; + } + + @Nonnull + @Override + public BigDecimal receiveMatterOuter(BigDecimal howMuch, boolean simulate) { + if (direction == MatterDirection.EXTRACT) + return BigDecimal.ZERO; + + return receiveMatterInner(howMuch, simulate); + } + + @Nonnull + @Override + public BigDecimal receiveMatterInner(BigDecimal howMuch, boolean simulate) { + BigDecimal new_matter; + + if (max_receive == null) { + new_matter = stored.add(howMuch, MatterRegistry.ROUND_RULES).min(max_storage); + } else { + new_matter = stored.add(howMuch.min(max_receive), MatterRegistry.ROUND_RULES).min(max_storage); + } + + BigDecimal diff = new_matter.subtract(stored); + + if (!simulate && new_matter.compareTo(stored) != 0) { + stored = new_matter; + + if (listener != null) { + listener.run(); + } + } + + return diff; + } + + @Nonnull + @Override + public BigDecimal extractMatterOuter(BigDecimal howMuch, boolean simulate) { + if (direction == MatterDirection.RECEIVE) + return BigDecimal.ZERO; + + return extractMatterInner(howMuch, simulate); + } + + @Nonnull + @Override + public BigDecimal extractMatterInner(BigDecimal howMuch, boolean simulate) { + BigDecimal new_matter; + + if (max_receive == null) { + new_matter = stored.subtract(howMuch, MatterRegistry.ROUND_RULES).max(BigDecimal.ZERO); + } else { + new_matter = stored.subtract(howMuch.min(max_receive), MatterRegistry.ROUND_RULES).max(BigDecimal.ZERO); + } + + BigDecimal diff = stored.subtract(new_matter); + + if (!simulate && new_matter.compareTo(stored) != 0) { + stored = new_matter; + + if (listener != null) { + listener.run(); + } + } + + return diff; + } + + @Nonnull + @Override + public MatterDirection getDirection() { + return direction; + } + + @Override + public CompoundTag serializeNBT() { + CompoundTag tag = new CompoundTag(); + tag.putString("stored", stored.toString()); + tag.putString("max_storage", max_storage.toString()); + + if (max_receive != null) + tag.putString("max_receive", max_receive.toString()); + + if (max_extract != null) + tag.putString("max_extract", max_extract.toString()); + + return tag; + } + + @Override + public void deserializeNBT(CompoundTag tag) { + if (tag.contains("stored")) + stored = new BigDecimal(tag.getString("stored")); + + if (tag.contains("max_storage")) + max_storage = new BigDecimal(tag.getString("max_storage")); + + if (tag.contains("max_receive")) + max_receive = new BigDecimal(tag.getString("max_receive")); + else + max_receive = null; + + if (tag.contains("max_extract")) + max_extract = new BigDecimal(tag.getString("max_extract")); + else + max_extract = null; + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java index 47fbb295e..3e99dd865 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/MatteryCapability.java @@ -16,12 +16,17 @@ public class MatteryCapability { @CapabilityInject(IAndroidCapability.class) public static Capability ANDROID = null; + @CapabilityInject(IMatterHandler.class) + public static Capability MATTER = null; + public static void register() { CapabilityManager.INSTANCE.register(IAndroidCapability.class); CapabilityManager.INSTANCE.register(IMatteryEnergyStorage.class); + + CapabilityManager.INSTANCE.register(IMatterHandler.class); } - public static final MathContext ROUND_RULES = new MathContext(24, RoundingMode.HALF_UP); + public static final MathContext ROUND_RULES = new MathContext(32, RoundingMode.HALF_DOWN); public static final BigDecimal INT_MAX_VALUE = new BigDecimal(Integer.MAX_VALUE); public static final BigDecimal INT_MIN_VALUE = new BigDecimal(Integer.MIN_VALUE); diff --git a/src/main/java/ru/dbotthepony/mc/otm/item/ItemBattery.java b/src/main/java/ru/dbotthepony/mc/otm/item/ItemBattery.java index 2e0614de7..d6d00f342 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/item/ItemBattery.java +++ b/src/main/java/ru/dbotthepony/mc/otm/item/ItemBattery.java @@ -7,9 +7,12 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.world.item.*; import net.minecraft.world.level.Level; +import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.energy.CapabilityEnergy; +import net.minecraftforge.fml.loading.FMLEnvironment; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.menu.FormattingHelper; @@ -18,6 +21,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.math.BigDecimal; import java.util.List; +import java.util.Objects; public class ItemBattery extends Item { public class BatteryMatteryCapability implements IMatteryEnergyStorage, ICapabilityProvider { @@ -25,19 +29,32 @@ public class ItemBattery extends Item { private final BigDecimal max_input; private final BigDecimal max_output; private final boolean is_creative; + private BigDecimal energy; + private String _energy; private final ItemStack stack; private BigDecimal energy() { CompoundTag tag = stack.getOrCreateTag(); - if (tag.contains("otm_energy")) - return new BigDecimal(tag.getString("otm_energy")); + if (tag.contains("otm_energy")) { + String get_energy = tag.getString("otm_energy"); + + if (Objects.equals(_energy, get_energy)) { + return energy; + } + + energy = new BigDecimal(tag.getString("otm_energy")); + _energy = get_energy; + + return energy; + } return BigDecimal.ZERO; } private void energy(BigDecimal value) { + energy = value; stack.getOrCreateTag().putString("otm_energy", value.toString()); } @@ -132,7 +149,7 @@ public class ItemBattery extends Item { @Nonnull @Override public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { - if (cap == MatteryCapability.ENERGY) + if (cap == MatteryCapability.ENERGY || cap == CapabilityEnergy.ENERGY) return resolver.cast(); return LazyOptional.empty(); @@ -147,26 +164,6 @@ public class ItemBattery extends Item { public boolean canReceive() { return true; } - - @Override - public boolean canExtractOuter() { - return true; - } - - @Override - public boolean canReceiveOuter() { - return true; - } - - @Override - public boolean canExtractInner() { - return true; - } - - @Override - public boolean canReceiveInner() { - return true; - } } private final boolean is_creative; diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java b/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java index d3ef1033e..517d850b6 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java @@ -35,7 +35,7 @@ public class AndroidStationMenu extends PoweredMatteryMenu { private final IAndroidCapability android; public AndroidBatterySlot(AndroidStationContainer container, int index, int x, int y) { - super(container, index, x, y); + super(container, index, x, y, false); android = container.android; } diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/FormattingHelper.java b/src/main/java/ru/dbotthepony/mc/otm/menu/FormattingHelper.java index ebc23139f..2bbb81df1 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/FormattingHelper.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/FormattingHelper.java @@ -70,10 +70,18 @@ public class FormattingHelper { return new TranslatableComponent("otm.gui.level", formatSI(power, POWER_NAME), formatSI(max_power, POWER_NAME)); } + public static Component formatMatterLevel(BigDecimal power, BigDecimal max_power) { + return new TranslatableComponent("otm.gui.level", formatMatterValuePlain(power), formatMatterValuePlain(max_power)); + } + public static TranslatableComponent formatMatterValue(BigDecimal matter) { return new TranslatableComponent("otm.gui.matter.format", formatSI(matter, MATTER_NAME)); } + public static Component formatMatterValuePlain(BigDecimal matter) { + return formatSI(matter, MATTER_NAME); + } + public static Component formatPower(BigDecimal power) { return formatSI(power, POWER_NAME); } diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/MatterDecomposerMenu.java b/src/main/java/ru/dbotthepony/mc/otm/menu/MatterDecomposerMenu.java new file mode 100644 index 000000000..6dafeb658 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/MatterDecomposerMenu.java @@ -0,0 +1,105 @@ +package ru.dbotthepony.mc.otm.menu; + +import net.minecraft.world.Container; +import net.minecraft.world.SimpleContainer; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.ContainerData; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import ru.dbotthepony.mc.otm.MatterRegistry; +import ru.dbotthepony.mc.otm.Registry; +import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterDecomposer; +import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatteryPoweredMachine; +import ru.dbotthepony.mc.otm.menu.data.BigDecimalDataContainer; +import ru.dbotthepony.mc.otm.menu.slot.MachineInputSlot; +import ru.dbotthepony.mc.otm.menu.slot.MachineOutputSlot; + +import javax.annotation.Nullable; + +public class MatterDecomposerMenu extends PoweredMatteryMenu { + public MatterDecomposerMenu(int containerID, Inventory inventory) { + this(containerID, inventory, null); + } + + public BigDecimalDataContainer matter; + public BigDecimalDataContainer max_matter; + + public ContainerData progress; + + public MatterDecomposerMenu(int containerID, Inventory inventory, @Nullable BlockEntityMatterDecomposer tile) { + super(Registry.Menus.MATTER_DECOMPOSER, containerID, inventory, tile); + Container container = tile != null ? tile.item_container : new SimpleContainer(2); + + progress = new ContainerData() { + int get_value; + + @Override + public int get(int i) { + if (tile != null) + return (int) (tile.getWorkProgress() * 100); + + return get_value; + } + + @Override + public void set(int i, int i1) { + get_value = i1; + } + + @Override + public int getCount() { + return 1; + } + }; + + // Вход + addSlot(new MachineInputSlot(container, 0, 61, 36) { + @Override + public boolean mayPlace(ItemStack p_40231_) { + return MatterRegistry.hasMatterValue(p_40231_); + } + }); + + // Выход + addSlot(new MachineOutputSlot(container, 1, 61 + 18 + 10 + 3 + 22, 36, true, true)); + + if (tile == null) { + matter = new BigDecimalDataContainer(); + max_matter = new BigDecimalDataContainer(); + } else { + matter = new BigDecimalDataContainer() { + @Override + protected void updateValue() { + setDecimal(tile.matter.getStoredMatter()); + } + }; + + max_matter = new BigDecimalDataContainer() { + @Override + protected void updateValue() { + setDecimal(tile.matter.getMaxStoredMatter()); + } + }; + } + + addBatterySlot(14); + + addInventorySlots(); + + this.addDataSlots(matter); + this.addDataSlots(max_matter); + + this.addDataSlots(progress); + } + + @Override + protected int getWorkingSlotStart() { + return 0; + } + + @Override + protected int getWorkingSlotEnd() { + return 1; + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/PoweredMatteryMenu.java b/src/main/java/ru/dbotthepony/mc/otm/menu/PoweredMatteryMenu.java index dc067b296..8d4d76c0f 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/PoweredMatteryMenu.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/PoweredMatteryMenu.java @@ -4,7 +4,9 @@ import net.minecraft.world.Container; import net.minecraft.world.SimpleContainer; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; import net.minecraftforge.common.util.LazyOptional; +import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatteryPoweredMachine; import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage; import ru.dbotthepony.mc.otm.capability.MatteryCapability; @@ -26,6 +28,7 @@ abstract public class PoweredMatteryMenu extends MatteryMenu { @Nullable BlockEntityMatteryPoweredMachine tile ) { super(menuType, containerID, inventory, tile); + this.tile = tile; if (tile == null) { energy = new BigDecimalDataContainer(); @@ -60,8 +63,12 @@ abstract public class PoweredMatteryMenu extends MatteryMenu { addBatterySlot(8, 66); } + protected void addBatterySlot(int x) { + addBatterySlot(x, 66); + } + protected void addBatterySlot(int x, int y) { Container battery_container = tile != null ? tile.battery_container : new SimpleContainer(1); - this.addSlot(new BatterySlot(battery_container, 0, x, y)); + this.addSlot(new BatterySlot(battery_container, 0, x, y, true)); } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/slot/BatterySlot.java b/src/main/java/ru/dbotthepony/mc/otm/menu/slot/BatterySlot.java index b4e43a081..a01fb2b1d 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/slot/BatterySlot.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/slot/BatterySlot.java @@ -12,18 +12,19 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability; import java.util.Optional; public class BatterySlot extends Slot { - public BatterySlot(Container container, int index, int x, int y) { + public boolean auto_bg; + + public BatterySlot(Container container, int index, int x, int y, boolean auto_bg) { super(container, index, x, y); + this.auto_bg = auto_bg; + } + + public BatterySlot(Container container, int index, int x, int y) { + this(container, index, x, y, true); } @Override public boolean mayPlace(ItemStack stack) { - Optional storage = stack.getCapability(MatteryCapability.ENERGY).resolve(); - - if (storage.isPresent()) { - return storage.get().canExtractOuter(); - } - LazyOptional capability = stack.getCapability(CapabilityEnergy.ENERGY); return capability.resolve().isPresent() && capability.resolve().get().canExtract(); } diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/slot/MachineInputSlot.java b/src/main/java/ru/dbotthepony/mc/otm/menu/slot/MachineInputSlot.java new file mode 100644 index 000000000..8374489a2 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/slot/MachineInputSlot.java @@ -0,0 +1,19 @@ +package ru.dbotthepony.mc.otm.menu.slot; + +import net.minecraft.world.Container; +import net.minecraft.world.inventory.Slot; + +// Just a sign that this slot needs auto draw +public class MachineInputSlot extends Slot { + public boolean auto_bg; + + public MachineInputSlot(Container p_40223_, int index, int x, int y, boolean auto_bg) { + super(p_40223_, index, x, y); + this.auto_bg = auto_bg; + } + + public MachineInputSlot(Container p_40223_, int index, int x, int y) { + this(p_40223_, index, x, y, true); + } + +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/menu/slot/MachineOutputSlot.java b/src/main/java/ru/dbotthepony/mc/otm/menu/slot/MachineOutputSlot.java new file mode 100644 index 000000000..5e25b1d71 --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/slot/MachineOutputSlot.java @@ -0,0 +1,25 @@ +package ru.dbotthepony.mc.otm.menu.slot; + +import net.minecraft.world.Container; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; + +public class MachineOutputSlot extends Slot { + public boolean auto_bg; + public boolean is_main_output; + + public MachineOutputSlot(Container p_40223_, int index, int x, int y, boolean auto_bg, boolean is_main_output) { + super(p_40223_, index, x, y); + this.is_main_output = is_main_output; + this.auto_bg = auto_bg; + } + + public MachineOutputSlot(Container p_40223_, int index, int x, int y) { + this(p_40223_, index, x, y, true, false); + } + + @Override + public boolean mayPlace(ItemStack p_40231_) { + return false; + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/screen/BatteryBankScreen.java b/src/main/java/ru/dbotthepony/mc/otm/screen/BatteryBankScreen.java index b1d615a3c..7410d9a99 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/screen/BatteryBankScreen.java +++ b/src/main/java/ru/dbotthepony/mc/otm/screen/BatteryBankScreen.java @@ -19,20 +19,10 @@ public class BatteryBankScreen extends MatteryScreen { public BatteryBankScreen(BatteryBankMenu p_97741_, Inventory p_97742_, Component p_97743_) { super(p_97741_, p_97742_, p_97743_); - } + power_supplier = () -> menu.energy.getDecimal(); + max_matter_supplier = () -> menu.max_energy.getDecimal(); - @Override - protected void renderTooltip(PoseStack p_97791_, int mouseX, int mouseY) { - super.renderTooltip(p_97791_, mouseX, mouseY); - - if (this.hoveredSlot == null && menu.getCarried().isEmpty() && hovering_power_gauge) { - this.renderComponentToolTip(p_97791_, getFormattedPowerLevel(() -> menu.energy.getDecimal(), () -> menu.max_energy.getDecimal()), mouseX, mouseY, font); - } - } - - @Override - protected void renderBg(PoseStack pose, float p_97788_, int mouseX, int mouseY) { - super.renderBg(pose, p_97788_, mouseX, mouseY); - renderPowerGauge(pose, 15, 24, mouseX, mouseY, () -> menu.energy.getDecimal(), () -> menu.max_energy.getDecimal()); + power_gauge_x = 15; + power_gauge_y = 24; } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/screen/MatterDecomposerScreen.java b/src/main/java/ru/dbotthepony/mc/otm/screen/MatterDecomposerScreen.java new file mode 100644 index 000000000..70aac663e --- /dev/null +++ b/src/main/java/ru/dbotthepony/mc/otm/screen/MatterDecomposerScreen.java @@ -0,0 +1,16 @@ +package ru.dbotthepony.mc.otm.screen; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Inventory; +import ru.dbotthepony.mc.otm.menu.MatterDecomposerMenu; + +public class MatterDecomposerScreen extends PoweredMachineScreen { + public MatterDecomposerScreen(MatterDecomposerMenu p_97741_, Inventory p_97742_, Component p_97743_) { + super(p_97741_, p_97742_, p_97743_); + matter_supplier = () -> menu.matter.getDecimal(); + max_matter_supplier = () -> menu.max_matter.getDecimal(); + + progress_supplier = () -> p_97741_.progress.get(0) / 100f; + } +} diff --git a/src/main/java/ru/dbotthepony/mc/otm/screen/MatteryScreen.java b/src/main/java/ru/dbotthepony/mc/otm/screen/MatteryScreen.java index ea5a56ab1..b8a2d696e 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/screen/MatteryScreen.java +++ b/src/main/java/ru/dbotthepony/mc/otm/screen/MatteryScreen.java @@ -9,23 +9,50 @@ import net.minecraft.network.chat.FormattedText; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.Slot; import ru.dbotthepony.mc.otm.OverdriveThatMatters; import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.menu.FormattingHelper; import ru.dbotthepony.mc.otm.menu.MatteryMenu; -import ru.dbotthepony.mc.otm.menu.PoweredMatteryMenu; +import ru.dbotthepony.mc.otm.menu.slot.BatterySlot; +import ru.dbotthepony.mc.otm.menu.slot.MachineInputSlot; +import ru.dbotthepony.mc.otm.menu.slot.MachineOutputSlot; import java.math.BigDecimal; import java.util.List; import java.util.function.Supplier; public class MatteryScreen extends AbstractContainerScreen { - protected static final ResourceLocation CONTAINER_BASE = new ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/mattery_machine_base.png"); + protected static final ResourceLocation CONTAINER_BASE = new ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/generic_machine.png"); + public static final ResourceLocation WIDGETS = new ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/widgets.png"); + + public static final int PROGRESS_WIDGET_WIDTH = 21; + public static final int PROGRESS_WIDGET_HEIGHT = 16; protected ResourceLocation CONTAINER_BACKGROUND() { return CONTAINER_BASE; } + protected Supplier power_supplier; + protected Supplier max_power_supplier; + + protected int power_gauge_x = 13; + protected int power_gauge_y = 14; + + protected Supplier matter_supplier; + protected Supplier max_matter_supplier; + + protected Supplier progress_supplier; + + protected int matter_gauge_x = 22; + protected int matter_gauge_y = 14; + + protected boolean hovering_power_gauge = false; + protected boolean hovering_matter_gauge = false; + + protected int render_x; + protected int render_y; + public MatteryScreen(T p_97741_, Inventory p_97742_, Component p_97743_) { super(p_97741_, p_97742_, p_97743_); @@ -36,75 +63,212 @@ public class MatteryScreen extends AbstractContainerScree inventoryLabelY = imageHeight - 92; } - protected boolean hovering_power_gauge = false; + @Override + protected void renderTooltip(PoseStack p_97791_, int mouseX, int mouseY) { + super.renderTooltip(p_97791_, mouseX, mouseY); - protected List getFormattedPowerLevel(Supplier s_energy, Supplier s_max_energy) { - BigDecimal energy = s_energy.get(); - BigDecimal max_energy = s_max_energy.get(); + if (this.hoveredSlot == null && menu.getCarried().isEmpty()) { + if (hovering_power_gauge) { + List text = getFormattedPowerLevel(); - float level; + if (text.size() != 0) + this.renderComponentToolTip(p_97791_, text, mouseX, mouseY, font); + } else if (hovering_matter_gauge) { + List text = getFormattedMatterLevel(); - if (max_energy.compareTo(BigDecimal.ZERO) == 0) { - level = 0f; - } else { - level = energy.divide(max_energy, MatteryCapability.ROUND_RULES).floatValue(); + if (text.size() != 0) + this.renderComponentToolTip(p_97791_, text, mouseX, mouseY, font); + } } + } + + protected List getFormattedPowerLevel() { + if (power_supplier != null && max_power_supplier != null) + return getFormattedPowerLevel(power_supplier.get(), max_power_supplier.get()); + + return List.of(); + } + + protected List getFormattedMatterLevel() { + if (matter_supplier != null && max_matter_supplier != null) + return getFormattedMatterLevel(matter_supplier.get(), max_matter_supplier.get()); + + return List.of(); + } + + protected List getFormattedPowerLevel(BigDecimal current, BigDecimal max) { + if (current == null || max == null) + return List.of(); return List.of( - new TranslatableComponent("otm.gui.power.percentage_level", String.format("%.2f", level * 100d)), - FormattingHelper.formatPowerLevel(energy, max_energy) + new TranslatableComponent("otm.gui.power.percentage_level", String.format("%.2f", level(current, max) * 100d)), + FormattingHelper.formatPowerLevel(current, max) ); } - protected boolean renderPowerGauge(PoseStack pose, int x, int y, int mouseX, int mouseY, Supplier s_energy, Supplier s_max_energy) { - BigDecimal energy = s_energy.get(); - BigDecimal max_energy = s_max_energy.get(); + protected List getFormattedMatterLevel(BigDecimal current, BigDecimal max) { + if (current == null || max == null) + return List.of(); - int i = (width - imageWidth) / 2; - int j = (height - imageHeight) / 2; + return List.of( + new TranslatableComponent("otm.gui.matter.percentage_level", String.format("%.2f", level(current, max) * 100d)), + FormattingHelper.formatMatterLevel(current, max) + ); + } - float level; + protected void renderVerticalGauge(PoseStack pose, int x, int y, float level, int image_x, int image_y, int width, int max_height) { + RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + RenderSystem.setShaderTexture(0, WIDGETS); - if (max_energy.compareTo(BigDecimal.ZERO) == 0) { - level = 0f; - } else { - level = energy.divide(max_energy, MatteryCapability.ROUND_RULES).floatValue(); + this.blit(pose, render_x + x, render_y + y, image_x, image_y, width, max_height); - if (level >= 0.98) - level = 1f; + if (level > 0.01f) { + int intHeight = (int) Math.floor(level * (float) max_height + 0.5f); + this.blit(pose, render_x + x, render_y + y + max_height - intHeight, image_x + width, image_y + max_height - intHeight, width, intHeight); } + } - if (level > 0.01) { - RenderSystem.setShader(GameRenderer::getPositionTexShader); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.setShaderTexture(0, CONTAINER_BASE); - - int intHeight = (int) Math.floor(level * 46d + 0.5d); - - this.blit(pose, i + x, j + y + 46 - intHeight, 176, 0, 7, intHeight); - } + protected boolean renderVerticalGauge(PoseStack pose, int x, int y, int mouseX, int mouseY, float level, int image_x, int image_y, int width, int max_height) { + renderVerticalGauge(pose, x, y, level, image_x, image_y, width, max_height); x += leftPos; y += topPos; - hovering_power_gauge = x <= mouseX && x + 7 >= mouseX && y <= mouseY && y + 46 >= mouseY; - return hovering_power_gauge; + return x <= mouseX && x + 7 >= mouseX && y <= mouseY && y + 46 >= mouseY; + } + + protected void renderHorizontalGauge(PoseStack pose, int x, int y, float level, int image_x, int image_y, int max_width, int height) { + RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + RenderSystem.setShaderTexture(0, WIDGETS); + + this.blit(pose, render_x + x, render_y + y, image_x, image_y, max_width, height); + + if (level > 0.01f) { + int intWidth = (int) Math.floor(level * (float) max_width + 0.5f); + this.blit(pose, render_x + x, render_y + y, image_x + max_width, image_y, intWidth, height); + } + } + + protected boolean renderHorizontalGauge(PoseStack pose, int x, int y, int mouseX, int mouseY, float level, int image_x, int image_y, int width, int max_height) { + renderVerticalGauge(pose, x, y, level, image_x, image_y, width, max_height); + + x += leftPos; + y += topPos; + return x <= mouseX && x + 7 >= mouseX && y <= mouseY && y + 46 >= mouseY; + } + + public static float level(BigDecimal a, BigDecimal b, boolean exact) { + float level; + + if (b.compareTo(BigDecimal.ZERO) == 0) { + level = 0f; + } else { + level = a.divide(b, MatteryCapability.ROUND_RULES).floatValue(); + + if (!exact && level >= 0.98) + level = 1f; + } + + return level; + } + + public static float level(BigDecimal a, BigDecimal b) { + return level(a, b, true); + } + + protected boolean renderMatterGauge(PoseStack pose, int mouseX, int mouseY) { + if (matter_supplier != null && max_matter_supplier != null) + return renderMatterGauge(pose, mouseX, mouseY, matter_supplier.get(), max_matter_supplier.get()); + + return false; + } + + protected boolean renderPowerGauge(PoseStack pose, int mouseX, int mouseY) { + if (power_supplier != null && max_power_supplier != null) + return renderPowerGauge(pose, mouseX, mouseY, power_supplier.get(), max_power_supplier.get()); + + return false; + } + + protected boolean renderMatterGauge(PoseStack pose, int mouseX, int mouseY, BigDecimal current_value, BigDecimal max_value) { + return renderMatterGauge(pose, matter_gauge_x, matter_gauge_y, mouseX, mouseY, current_value, max_value); + } + + protected boolean renderPowerGauge(PoseStack pose, int mouseX, int mouseY, BigDecimal current_value, BigDecimal max_value) { + return renderPowerGauge(pose, power_gauge_x, power_gauge_y, mouseX, mouseY, current_value, max_value); + } + + protected boolean renderPowerGauge(PoseStack pose, int x, int y, int mouseX, int mouseY, BigDecimal current_value, BigDecimal max_value) { + return hovering_power_gauge = renderVerticalGauge(pose, x, y, mouseX, mouseY, level(current_value, max_value), 0, 48, 9, 48); + } + + protected boolean renderMatterGauge(PoseStack pose, int x, int y, int mouseX, int mouseY, BigDecimal current_value, BigDecimal max_value) { + return hovering_matter_gauge = renderVerticalGauge(pose, x, y, mouseX, mouseY, level(current_value, max_value), 0, 0, 9, 48); + } + + protected void renderProgressGauge(PoseStack pose, int x, int y, float level) { + renderHorizontalGauge(pose, x, y, level, 0, 132, 22, 16); + } + + protected void renderProgressGaugeLeft(PoseStack pose, int x, int y, float level) { + renderHorizontalGauge(pose, x - 22, y, level, 0, 132, 22, 16); } @Override public void render(PoseStack p_98418_, int mouseX, int mouseY, float p_98421_) { + render_x = (width - imageWidth) / 2; + render_y = (height - imageHeight) / 2; + this.renderBackground(p_98418_); super.render(p_98418_, mouseX, mouseY, p_98421_); this.renderTooltip(p_98418_, mouseX, mouseY); } + protected void renderRegularSlot(PoseStack pose, int x, int y) { + this.blit(pose, render_x + x - 1, render_y + y - 1, 0, 96, 18, 18); + } + + protected void renderOutputSlot(PoseStack pose, int x, int y) { + this.blit(pose, render_x + x - 5, render_y + y - 5, 18, 96, 26, 26); + } + + protected void renderBatterySlot(PoseStack pose, int x, int y) { + renderRegularSlot(pose, x, y); + this.blit(pose, render_x + x - 1, render_y + y - 1, 0, 114, 18, 18); + } + @Override protected void renderBg(PoseStack pose, float p_97788_, int mouseX, int mouseY) { RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.setShaderTexture(0, CONTAINER_BACKGROUND()); - int i = (width - imageWidth) / 2; - int j = (height - imageHeight) / 2; // PoseStack, x, y, image_start_x, image_start_y, rect_size_x, rect_size_y - this.blit(pose, i, j, 0, 0, this.imageWidth, this.imageHeight); + this.blit(pose, render_x, render_y, 0, 0, this.imageWidth, this.imageHeight); + + renderPowerGauge(pose, mouseX, mouseY); + renderMatterGauge(pose, mouseX, mouseY); + + RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + RenderSystem.setShaderTexture(0, WIDGETS); + + for (Slot slot : menu.slots) { + if (slot instanceof BatterySlot slot1 && slot1.auto_bg) { + renderBatterySlot(pose, slot1.x, slot1.y); + } else if (slot instanceof MachineOutputSlot slot1 && slot1.auto_bg) { + if (slot1.is_main_output) { + renderOutputSlot(pose, slot1.x, slot1.y); + + if (progress_supplier != null) { + renderProgressGaugeLeft(pose, slot1.x - 8, slot1.y, progress_supplier.get()); + } + } else { + renderRegularSlot(pose, slot1.x, slot1.y); + } + } else if (slot instanceof MachineInputSlot slot1 && slot1.auto_bg) { + renderRegularSlot(pose, slot1.x, slot1.y); + } + } } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/screen/PoweredMachineScreen.java b/src/main/java/ru/dbotthepony/mc/otm/screen/PoweredMachineScreen.java index 9816b1864..9db00f381 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/screen/PoweredMachineScreen.java +++ b/src/main/java/ru/dbotthepony/mc/otm/screen/PoweredMachineScreen.java @@ -9,36 +9,9 @@ import ru.dbotthepony.mc.otm.menu.PoweredMatteryMenu; import java.util.List; public class PoweredMachineScreen extends MatteryScreen { - protected boolean auto_draw_gauge = true; - protected int power_gauge_x = 13; - protected int power_gauge_y = 15; - public PoweredMachineScreen(T p_97741_, Inventory p_97742_, Component p_97743_) { super(p_97741_, p_97742_, p_97743_); - } - - @Override - protected void renderTooltip(PoseStack p_97791_, int mouseX, int mouseY) { - super.renderTooltip(p_97791_, mouseX, mouseY); - - if (this.hoveredSlot == null && menu.getCarried().isEmpty() && hovering_power_gauge) { - this.renderComponentToolTip(p_97791_, getFormattedPowerLevel(), mouseX, mouseY, font); - } - } - - protected List getFormattedPowerLevel() { - return getFormattedPowerLevel(() -> menu.energy.getDecimal(), () -> menu.max_energy.getDecimal()); - } - - protected void renderPowerGauge(PoseStack pose, int x, int y, int mouseX, int mouseY) { - renderPowerGauge(pose, x, y, mouseX, mouseY, () -> menu.energy.getDecimal(), () -> menu.max_energy.getDecimal()); - } - - @Override - protected void renderBg(PoseStack pose, float p_97788_, int mouseX, int mouseY) { - super.renderBg(pose, p_97788_, mouseX, mouseY); - - if (auto_draw_gauge) - renderPowerGauge(pose, power_gauge_x, power_gauge_y, mouseX, mouseY); + power_supplier = () -> menu.energy.getDecimal(); + max_power_supplier = () -> menu.max_energy.getDecimal(); } } 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 2c35e5649..fa659cd5a 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 @@ -1,11 +1,12 @@ { "otm.pill.warning": "WARNING: This will INSTANTLY kill you upon ingestion!", - "otm.pill.android": "Take this pill and lose what is holding your back.", + "otm.pill.android": "Take this pill and lose what is holding you back.", "otm.pill.humane": "Take this pill and wake up in bed none the wiser.", "otm.gui.power.percentage_level": "Energy level: %s%%", "otm.gui.level": "%s / %s", "otm.gui.power.name": "MtE", + "otm.gui.matter.percentage_level": "Matter level: %s%%", "otm.gui.matter.format": "Matter: %s", "otm.gui.matter.name": "MtU", @@ -42,6 +43,7 @@ "block.overdrive_that_matters.android_station": "Android station", "block.overdrive_that_matters.battery_bank": "Battery bank", + "block.overdrive_that_matters.matter_decomposer": "Matter decomposer", "item.overdrive_that_matters.pill_android": "Android pill", "item.overdrive_that_matters.pill_humane": "Humane pill", diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/android_station.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/android_station.png index 242cc9cf9..b920ebcc0 100644 Binary files a/src/main/resources/assets/overdrive_that_matters/textures/gui/android_station.png and b/src/main/resources/assets/overdrive_that_matters/textures/gui/android_station.png differ diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/android_station.xcf b/src/main/resources/assets/overdrive_that_matters/textures/gui/android_station.xcf index 0be23dfca..798fb9990 100644 Binary files a/src/main/resources/assets/overdrive_that_matters/textures/gui/android_station.xcf and b/src/main/resources/assets/overdrive_that_matters/textures/gui/android_station.xcf differ diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/battery_bank.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/battery_bank.png deleted file mode 100644 index 8339cb0f2..000000000 Binary files a/src/main/resources/assets/overdrive_that_matters/textures/gui/battery_bank.png and /dev/null differ diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/generic_machine.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/generic_machine.png new file mode 100644 index 000000000..3abf7adc2 Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/gui/generic_machine.png differ diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/battery_bank.xcf b/src/main/resources/assets/overdrive_that_matters/textures/gui/generic_machine.xcf similarity index 69% rename from src/main/resources/assets/overdrive_that_matters/textures/gui/battery_bank.xcf rename to src/main/resources/assets/overdrive_that_matters/textures/gui/generic_machine.xcf index 7321a9955..a71437516 100644 Binary files a/src/main/resources/assets/overdrive_that_matters/textures/gui/battery_bank.xcf and b/src/main/resources/assets/overdrive_that_matters/textures/gui/generic_machine.xcf differ diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/mattery_machine_base.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/mattery_machine_base.png deleted file mode 100644 index f6b3c452c..000000000 Binary files a/src/main/resources/assets/overdrive_that_matters/textures/gui/mattery_machine_base.png and /dev/null differ diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.png b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.png new file mode 100644 index 000000000..93c1bb19a Binary files /dev/null and b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.png differ diff --git a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.xcf b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.xcf index 20f1f2acc..ee92f6c9d 100644 Binary files a/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.xcf and b/src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.xcf differ