From 42044ff74a2d6a72e0648be46f9b63027f35fad3 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Mon, 9 Aug 2021 15:07:15 +0700 Subject: [PATCH] Android station interaction test --- .../entity/BlockEntityAndroidStation.java | 3 +- .../mc/otm/capability/AndroidCapability.java | 81 ++++++++++++++++ .../mc/otm/capability/IAndroidCapability.java | 8 ++ .../otm/capability/IMatteryEnergyStorage.java | 12 +-- .../mc/otm/menu/AndroidStationMenu.java | 93 +++++++++++++++++-- .../mc/otm/screen/AndroidStationScreen.java | 10 ++ 6 files changed, 190 insertions(+), 17 deletions(-) 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 8514a8605..7c09d1522 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 @@ -37,8 +37,7 @@ public class BlockEntityAndroidStation extends BlockEntity implements MenuProvid @Nullable @Override public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) { - new Exception().printStackTrace(); - return new AndroidStationMenu(containerID, this); + return new AndroidStationMenu(containerID, inventory, new AndroidStationMenu.AndroidStationContainer(ply), this); } private final MatteryMachineEnergyStorage energy = new MatteryMachineEnergyStorage(MatteryMachineEnergyStorage.MachineType.WORKER); diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java index d1738f192..969874517 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/AndroidCapability.java @@ -5,10 +5,13 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.food.FoodData; +import net.minecraft.world.item.ItemStack; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.energy.CapabilityEnergy; +import net.minecraftforge.energy.IEnergyStorage; import ru.dbotthepony.mc.otm.OverdriveThatMatters; import javax.annotation.Nonnull; @@ -19,6 +22,7 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit private final LivingEntity ent; private BigDecimal energy_stored = new BigDecimal(0); private BigDecimal energy_stored_max = new BigDecimal(32000); + private ItemStack battery = ItemStack.EMPTY; public static final BigDecimal ENERGY_FOR_HUNGER_POINT = new BigDecimal(200); @@ -32,6 +36,7 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit CompoundTag tag = new CompoundTag(); tag.putString("energy_stored", energy_stored.toString()); tag.putString("energy_stored_max", energy_stored_max.toString()); + tag.put("battery", battery.serializeNBT()); return tag; } @@ -42,6 +47,9 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit if (compound.contains("energy_stored_max")) energy_stored_max = new BigDecimal(compound.getString("energy_stored_max")); + + if (compound.contains("battery")) + battery = ItemStack.of(compound.getCompound("battery")); } @Override @@ -97,6 +105,23 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit @Nonnull @Override public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) { + if (battery != ItemStack.EMPTY) { + LazyOptional get_mattery = battery.getCapability(MatteryCapability.ENERGY); + + if (get_mattery.isPresent()) { + return get_mattery.resolve().get().extractEnergyInner(howMuch, simulate); + } + + if (howMuch.compareTo(BigDecimal.ONE) >= 0) { + LazyOptional get_energy = battery.getCapability(CapabilityEnergy.ENERGY); + + if (get_energy.isPresent()) { + int converted = howMuch.compareTo(MatteryCapability.INT_MAX_VALUE) <= 0 ? howMuch.intValue() : Integer.MAX_VALUE; + return new BigDecimal(get_energy.resolve().get().extractEnergy(converted, simulate)); + } + } + } + BigDecimal new_energy = energy_stored.subtract(howMuch, MatteryCapability.ROUND_RULES).max(BigDecimal.ZERO); BigDecimal diff = energy_stored.subtract(new_energy); @@ -110,6 +135,23 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit @Nonnull @Override public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) { + if (battery != ItemStack.EMPTY) { + LazyOptional get_mattery = battery.getCapability(MatteryCapability.ENERGY); + + if (get_mattery.isPresent()) { + return get_mattery.resolve().get().receiveEnergyOuter(howMuch, simulate); + } + + if (howMuch.compareTo(BigDecimal.ONE) >= 0) { + LazyOptional get_energy = battery.getCapability(CapabilityEnergy.ENERGY); + + if (get_energy.isPresent()) { + int converted = howMuch.compareTo(MatteryCapability.INT_MAX_VALUE) <= 0 ? howMuch.intValue() : Integer.MAX_VALUE; + return new BigDecimal(get_energy.resolve().get().receiveEnergy(converted, simulate)); + } + } + } + BigDecimal new_energy = energy_stored.add(howMuch, MatteryCapability.ROUND_RULES).min(energy_stored_max); BigDecimal diff = new_energy.subtract(energy_stored); @@ -131,15 +173,54 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit return this.ent; } + @Nonnull + @Override + public ItemStack getBatteryItemStack() { + return battery; + } + + @Override + public void setBatteryItemStack(@Nonnull ItemStack stack) { + battery = stack; + } + @Override @Nonnull public BigDecimal getBatteryLevel() { + if (battery != ItemStack.EMPTY) { + LazyOptional get_mattery = battery.getCapability(MatteryCapability.ENERGY); + + if (get_mattery.isPresent()) { + return get_mattery.resolve().get().getBatteryLevel(); + } + + LazyOptional get_energy = battery.getCapability(CapabilityEnergy.ENERGY); + + if (get_energy.isPresent()) { + return new BigDecimal(get_energy.resolve().get().getEnergyStored()); + } + } + return energy_stored; } @Override @Nonnull public BigDecimal getMaxBatteryLevel() { + if (battery != ItemStack.EMPTY) { + LazyOptional get_mattery = battery.getCapability(MatteryCapability.ENERGY); + + if (get_mattery.isPresent()) { + return get_mattery.resolve().get().getMaxBatteryLevel(); + } + + LazyOptional get_energy = battery.getCapability(CapabilityEnergy.ENERGY); + + if (get_energy.isPresent()) { + return new BigDecimal(get_energy.resolve().get().getMaxEnergyStored()); + } + } + return energy_stored_max; } diff --git a/src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java b/src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java index 67b8468f7..ad83e2798 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/IAndroidCapability.java @@ -1,9 +1,17 @@ package ru.dbotthepony.mc.otm.capability; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; import net.minecraftforge.common.capabilities.ICapabilityProvider; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + public interface IAndroidCapability extends IMatteryEnergyStorage { void tick(); LivingEntity getEntity(); + + @Nonnull + ItemStack getBatteryItemStack(); + void setBatteryItemStack(@Nonnull ItemStack stack); } 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 46c2ddddf..e43fd80d8 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java +++ b/src/main/java/ru/dbotthepony/mc/otm/capability/IMatteryEnergyStorage.java @@ -78,27 +78,27 @@ public interface IMatteryEnergyStorage extends IEnergyStorage { @Override default int receiveEnergy(int maxReceive, boolean simulate) { BigDecimal toReceive = new BigDecimal(maxReceive); - BigDecimal received = receiveEnergyOuter(toReceive, true); + int received = receiveEnergyOuter(toReceive, true).intValue(); - if (received.compareTo(BigDecimal.ZERO) == 1 && received.compareTo(BigDecimal.ONE) == -1) { + if (received == 0) { // Receiving only a fraction return 0; } - return receiveEnergyOuter(received.round(MatteryCapability.ROUND_RULES), simulate).intValue(); + return receiveEnergyOuter(new BigDecimal(received), simulate).intValue(); } @Override default int extractEnergy(int maxReceive, boolean simulate) { BigDecimal toReceive = new BigDecimal(maxReceive); - BigDecimal extracted = extractEnergyOuter(toReceive, true); + int extracted = extractEnergyOuter(toReceive, true).intValue(); - if (extracted.compareTo(BigDecimal.ZERO) == 1 && extracted.compareTo(BigDecimal.ONE) == -1) { + if (extracted == 0) { // Extracting only a fraction return 0; } - return extractEnergyOuter(extracted.round(MatteryCapability.ROUND_RULES), simulate).intValue(); + return extractEnergyOuter(new BigDecimal(extracted), simulate).intValue(); } @Override 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 7df5e0aab..5cb2132e7 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java +++ b/src/main/java/ru/dbotthepony/mc/otm/menu/AndroidStationMenu.java @@ -1,28 +1,103 @@ package ru.dbotthepony.mc.otm.menu; +import net.minecraft.core.BlockPos; +import net.minecraft.world.Container; +import net.minecraft.world.SimpleContainer; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +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.block.entity.BlockEntityAndroidStation; +import ru.dbotthepony.mc.otm.capability.IAndroidCapability; +import ru.dbotthepony.mc.otm.capability.MatteryCapability; + +import javax.annotation.Nullable; public class AndroidStationMenu extends AbstractContainerMenu { - private BlockEntityAndroidStation tile; - private Inventory inventory; + public static class AndroidStationContainer extends SimpleContainer { + public final Player player; + private final IAndroidCapability android; - public AndroidStationMenu(int containerID, Inventory inventory) { - super(OverdriveThatMatters.ANDROID_STATION_MENU_TYPE, containerID); - new Exception().printStackTrace(); - this.inventory = inventory; + public AndroidStationContainer(Player ply) { + super(1); + player = ply; + + LazyOptional capability = ply.getCapability(MatteryCapability.ANDROID); + android = capability.isPresent() ? capability.resolve().get() : null; + + if (android != null) { + setItem(0, android.getBatteryItemStack()); + } + } } - public AndroidStationMenu(int containerID, BlockEntityAndroidStation tile) { + public static class AndroidBatterySlot extends Slot { + private final IAndroidCapability android; + + public AndroidBatterySlot(AndroidStationContainer container, int index, int x, int y) { + super(container, index, x, y); + android = container.android; + } + + @Override + public boolean mayPlace(ItemStack stack) { + LazyOptional capability = stack.getCapability(CapabilityEnergy.ENERGY); + return capability.isPresent() && capability.resolve().get().canExtract(); + } + + @Override + public void set(ItemStack stack) { + super.set(stack); + android.setBatteryItemStack(stack); + } + } + + private BlockEntityAndroidStation tile; + private Inventory inventory; + private Player ply; + private AndroidStationContainer container; + + // Clientside + public AndroidStationMenu(int containerID, Inventory inventory) { + this(containerID, inventory, new AndroidStationContainer(inventory.player), null); + } + + // Serverside + public AndroidStationMenu(int containerID, Inventory inventory, AndroidStationContainer container, @Nullable BlockEntityAndroidStation tile) { super(OverdriveThatMatters.ANDROID_STATION_MENU_TYPE, containerID); + this.inventory = inventory; + this.container = container; this.tile = tile; + this.ply = inventory.player; + + this.addSlot(new AndroidBatterySlot(this.container, 0, 0, 0)); + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + this.addSlot(new Slot(inventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + } + } + + for (int k = 0; k < 9; ++k) { + this.addSlot(new Slot(inventory, k, 8 + k * 18, 142)); + } } @Override - public boolean stillValid(Player p_38874_) { - return !tile.isRemoved(); + public boolean stillValid(Player player) { + if (tile == null) + return true; + + if (player.level.getBlockEntity(tile.getBlockPos()) != tile) { + return false; + } + + BlockPos pos = tile.getBlockPos(); + return player.distanceToSqr((double)pos.getX() + 0.5D, (double)pos.getY() + 0.5D, (double)pos.getZ() + 0.5D) <= 64.0D; } } diff --git a/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java b/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java index cc3551397..9c57f7e59 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java +++ b/src/main/java/ru/dbotthepony/mc/otm/screen/AndroidStationScreen.java @@ -1,8 +1,11 @@ package ru.dbotthepony.mc.otm.screen; +import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.renderer.GameRenderer; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; import ru.dbotthepony.mc.otm.menu.AndroidStationMenu; @@ -11,6 +14,13 @@ public class AndroidStationScreen extends AbstractContainerScreen