Split, implement own energy capability

This commit is contained in:
DBotThePony 2021-08-09 12:09:18 +07:00
parent 8b435f1d91
commit 7e57fefcaa
Signed by: DBot
GPG Key ID: DCC23B5715498507
10 changed files with 543 additions and 222 deletions

View File

@ -1,7 +1,6 @@
package ru.dbotthepony.mc.otm;
import net.minecraft.client.gui.screens.MenuScreens;
import net.minecraft.client.gui.screens.inventory.ContainerScreen;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
@ -11,7 +10,6 @@ import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.LazyOptional;
@ -29,8 +27,11 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import ru.dbotthepony.mc.otm.block.BlockAndroidStation;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityAndroidStation;
import ru.dbotthepony.mc.otm.capability.AndroidCapability;
import ru.dbotthepony.mc.otm.capability.IAndroidCapability;
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu;
import ru.dbotthepony.mc.otm.screen.AndroidStationScreen;
import java.util.stream.Collectors;
@ -42,10 +43,10 @@ public class OverdriveThatMatters {
public static final Logger LOGGER = LogManager.getLogger();
public static Block ANDROID_STATION = new BlockAndroidStation();
public static BlockEntityType.Builder<BlockAndroidStation.BlockAndroidStationEntity> ANDROID_STATION_BUILDER = BlockEntityType.Builder.of(BlockAndroidStation.BlockAndroidStationEntity::new, ANDROID_STATION);
public static BlockEntityType<BlockAndroidStation.BlockAndroidStationEntity> ANDROID_STATION_FACTORY = null;
public static BlockEntityType.Builder<BlockEntityAndroidStation> ANDROID_STATION_BUILDER = BlockEntityType.Builder.of(BlockEntityAndroidStation::new, ANDROID_STATION);
public static BlockEntityType<BlockEntityAndroidStation> ANDROID_STATION_FACTORY = null;
public static Item ANDROID_STATION_ITEM = new BlockItem(ANDROID_STATION, new Item.Properties().stacksTo(64).tab(CreativeModeTab.TAB_MISC)).setRegistryName(BlockAndroidStation.REGISTRY_NAME);
public static MenuType<BlockAndroidStation.BlockAndroidStationEntity.AndroidStationMenu> ANDROID_STATION_MENU_TYPE = new MenuType<>(BlockAndroidStation.BlockAndroidStationEntity.AndroidStationMenu::new);
public static MenuType<AndroidStationMenu> ANDROID_STATION_MENU_TYPE = new MenuType<>(AndroidStationMenu::new);
static {
ANDROID_STATION_MENU_TYPE.setRegistryName(BlockAndroidStation.REGISTRY_NAME);
@ -147,7 +148,7 @@ public class OverdriveThatMatters {
// регистрация tile entity
LOGGER.info("Register MenuType called");
blockRegistryEvent.getRegistry().register(ANDROID_STATION_MENU_TYPE);
MenuScreens.register(ANDROID_STATION_MENU_TYPE, BlockAndroidStation.BlockAndroidStationEntity.AndroidStationScreen::new);
MenuScreens.register(ANDROID_STATION_MENU_TYPE, AndroidStationScreen::new);
}
}
}

View File

@ -1,24 +1,10 @@
package ru.dbotthepony.mc.otm.block;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
@ -30,24 +16,14 @@ import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.material.MaterialColor;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.EnergyStorage;
import net.minecraftforge.energy.IEnergyStorage;
import org.apache.logging.log4j.core.jmx.Server;
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.capability.AndroidCapability;
import ru.dbotthepony.mc.otm.capability.IAndroidCapability;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityAndroidStation;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
public class BlockAndroidStation extends Block implements EntityBlock {
public static final ResourceLocation REGISTRY_NAME = new ResourceLocation(OverdriveThatMatters.MOD_ID, "android_station");
@ -66,147 +42,22 @@ public class BlockAndroidStation extends Block implements EntityBlock {
@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
return new BlockAndroidStationEntity(pos, state);
return new BlockEntityAndroidStation(pos, state);
}
@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) {
return level.isClientSide || type != OverdriveThatMatters.ANDROID_STATION_FACTORY ? null : BlockAndroidStationEntity::tick;
return level.isClientSide || type != OverdriveThatMatters.ANDROID_STATION_FACTORY ? null : BlockEntityAndroidStation::tick;
}
@Override
public InteractionResult use(BlockState p_60503_, Level level, BlockPos pos, Player ply, InteractionHand p_60507_, BlockHitResult p_60508_) {
if (!level.isClientSide && level.getBlockEntity(pos) instanceof BlockAndroidStationEntity tile) {
if (!level.isClientSide && level.getBlockEntity(pos) instanceof BlockEntityAndroidStation tile) {
ply.openMenu(tile);
return InteractionResult.CONSUME;
}
return InteractionResult.SUCCESS;
}
public static class BlockAndroidStationEntity extends BlockEntity implements MenuProvider {
@Override
public Component getDisplayName() {
return new TranslatableComponent("container.android_station");
}
@Nullable
@Override
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
new Exception().printStackTrace();
return new AndroidStationMenu(containerID, this);
}
public static class AndroidStationMenu extends AbstractContainerMenu {
private BlockAndroidStationEntity tile;
private Inventory inventory;
public AndroidStationMenu(int containerID, Inventory inventory) {
super(OverdriveThatMatters.ANDROID_STATION_MENU_TYPE, containerID);
new Exception().printStackTrace();
this.inventory = inventory;
}
public AndroidStationMenu(int containerID, BlockAndroidStationEntity tile) {
super(OverdriveThatMatters.ANDROID_STATION_MENU_TYPE, containerID);
new Exception().printStackTrace();
this.tile = tile;
}
@Override
public boolean stillValid(Player p_38874_) {
return !tile.isRemoved();
}
}
public static class AndroidStationScreen extends AbstractContainerScreen<AndroidStationMenu> {
public AndroidStationScreen(AndroidStationMenu p_97741_, Inventory p_97742_, Component p_97743_) {
super(p_97741_, p_97742_, p_97743_);
}
@Override
protected void renderBg(PoseStack p_97787_, float p_97788_, int p_97789_, int p_97790_) {
}
}
private static class AndroidStationEnergyStorage extends EnergyStorage {
public AndroidStationEnergyStorage(int capacity, int maxReceive, int maxExtract) {
super(capacity, maxReceive, maxExtract);
}
void setEnergy(int energy) {
this.energy = energy;
}
}
private final AndroidStationEnergyStorage energy = new AndroidStationEnergyStorage(64000, 1024, 1024);
public BlockAndroidStationEntity(BlockPos p_155229_, BlockState p_155230_) {
super(OverdriveThatMatters.ANDROID_STATION_FACTORY, p_155229_, p_155230_);
}
@Nonnull
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
if (cap == CapabilityEnergy.ENERGY) {
return LazyOptional.of(() -> energy).cast();
}
return super.getCapability(cap, side);
}
@Override
public CompoundTag save(CompoundTag nbt) {
nbt.putInt("energy_stored", energy.getEnergyStored());
return super.save(nbt);
}
public void load(CompoundTag nbt) {
super.load(nbt);
if (nbt.contains("energy_stored"))
energy.setEnergy(nbt.getInt("energy_stored"));
}
void tick() {
if (!hasLevel())
return;
if (energy.getEnergyStored() <= 0)
return;
BlockPos pos = getBlockPos();
List<LivingEntity> entities = getLevel().getEntitiesOfClass(LivingEntity.class, new AABB(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 2, pos.getZ() + 1));
for (LivingEntity ent : entities) {
LazyOptional<IAndroidCapability> resolver = ent.getCapability(AndroidCapability.CAPABILITY);
if (resolver.isPresent()) {
IAndroidCapability capability = resolver.resolve().get();
int missing = capability.getMissingPowerInt();
if (missing > 0) {
int extract = energy.extractEnergy(missing, true);
if (extract > 0) {
int received = (int) capability.receiveEnergy(extract, true);
if (received > 0) {
energy.extractEnergy(extract, false);
capability.receiveEnergy(extract, false);
}
}
}
}
}
}
public static <T extends BlockEntity> void tick(Level level, BlockPos blockPos, BlockState blockState, T t) {
if (t instanceof BlockAndroidStationEntity tile) {
tile.tick();
}
}
}
}

View File

@ -0,0 +1,112 @@
package ru.dbotthepony.mc.otm.block.entity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.capability.AndroidCapability;
import ru.dbotthepony.mc.otm.capability.IAndroidCapability;
import ru.dbotthepony.mc.otm.capability.MatteryEnergyCapability;
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage;
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.util.List;
public class BlockEntityAndroidStation extends BlockEntity implements MenuProvider {
@Override
public Component getDisplayName() {
return new TranslatableComponent("container.android_station");
}
@Nullable
@Override
public AbstractContainerMenu createMenu(int containerID, Inventory inventory, Player ply) {
new Exception().printStackTrace();
return new AndroidStationMenu(containerID, this);
}
private final MatteryMachineEnergyStorage energy = new MatteryMachineEnergyStorage(MatteryMachineEnergyStorage.MachineType.WORKER);
public BlockEntityAndroidStation(BlockPos p_155229_, BlockState p_155230_) {
super(OverdriveThatMatters.ANDROID_STATION_FACTORY, p_155229_, p_155230_);
}
@Nonnull
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
if (cap == MatteryEnergyCapability.CAPABILITY || cap == CapabilityEnergy.ENERGY) {
return LazyOptional.of(() -> energy).cast();
}
return super.getCapability(cap, side);
}
@Override
public CompoundTag save(CompoundTag nbt) {
nbt.put("energy_cap", energy.serializeNBT());
return super.save(nbt);
}
public void load(CompoundTag nbt) {
super.load(nbt);
if (nbt.contains("energy_cap") && nbt.get("energy_cap") instanceof CompoundTag tag)
energy.deserializeNBT(tag);
}
void tick() {
if (!hasLevel())
return;
if (energy.getEnergyStored() <= 0)
return;
BlockPos pos = getBlockPos();
List<LivingEntity> entities = getLevel().getEntitiesOfClass(LivingEntity.class, new AABB(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 2, pos.getZ() + 1));
for (LivingEntity ent : entities) {
LazyOptional<IAndroidCapability> resolver = ent.getCapability(AndroidCapability.CAPABILITY);
if (resolver.isPresent()) {
IAndroidCapability capability = resolver.resolve().get();
BigDecimal missing = capability.getMissingPower();
if (missing.compareTo(BigDecimal.ZERO) == -1) {
BigDecimal extract = energy.extractEnergyInner(missing, true);
if (extract.compareTo(BigDecimal.ZERO) == -1) {
BigDecimal received = capability.receiveEnergyOuter(extract, true);
if (received.compareTo(BigDecimal.ZERO) == -1) {
energy.extractEnergyInner(extract, false);
capability.receiveEnergyOuter(extract, false);
}
}
}
}
}
}
public static <T extends BlockEntity> void tick(Level level, BlockPos blockPos, BlockState blockState, T t) {
if (t instanceof BlockEntityAndroidStation tile) {
tile.tick();
}
}
}

View File

@ -19,12 +19,15 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.util.function.Function;
public class AndroidCapability implements ICapabilityProvider, IAndroidCapability, INBTSerializable<Tag> {
public class AndroidCapability implements ICapabilityProvider, IAndroidCapability, INBTSerializable<CompoundTag> {
private final LivingEntity ent;
public long energy_stored = 32000L;
public long energy_stored_max = 32000L;
private BigDecimal energy_stored = new BigDecimal(0);
private BigDecimal energy_stored_max = new BigDecimal(32000);
public static final BigDecimal ENERGY_FOR_HUNGER_POINT = new BigDecimal(200);
public AndroidCapability(LivingEntity ent) {
this.ent = ent;
@ -34,27 +37,21 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit
public static Capability<IAndroidCapability> CAPABILITY = null;
@Override
public Tag serializeNBT() {
@Nonnull
public CompoundTag serializeNBT() {
CompoundTag tag = new CompoundTag();
tag.put("energy_stored", LongTag.valueOf(energy_stored));
tag.put("energy_stored_max", LongTag.valueOf(energy_stored_max));
tag.putString("energy_stored", energy_stored.toString());
tag.putString("energy_stored_max", energy_stored_max.toString());
return tag;
}
@Override
public void deserializeNBT(Tag nbt) {
if (nbt instanceof CompoundTag compound) {
if (compound.contains("energy_stored"))
energy_stored = compound.getLong("energy_stored");
public void deserializeNBT(CompoundTag compound) {
if (compound.contains("energy_stored"))
energy_stored = new BigDecimal(compound.getString("energy_stored"));
if (compound.contains("energy_stored_max"))
energy_stored_max = compound.getLong("energy_stored_max");
}
}
@Override
public long getMissingPower() {
return getMaxBatteryLevel() - getBatteryLevel();
if (compound.contains("energy_stored_max"))
energy_stored_max = new BigDecimal(compound.getString("energy_stored_max"));
}
@Override
@ -69,8 +66,8 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit
boolean saturation_changed = false;
while (food_points_missing > 0) {
if (this.extractEnergy(200L, true) == 200L) {
this.extractEnergy(200L, false);
if (this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT, true).equals(ENERGY_FOR_HUNGER_POINT)) {
this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT, false);
food_points_missing--;
food_changed = true;
} else {
@ -79,8 +76,8 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit
}
while (saturation_points_missing >= 1F) {
if (this.extractEnergy(200L, true) == 200L) {
this.extractEnergy(200L, false);
if (this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT, true).equals(ENERGY_FOR_HUNGER_POINT)) {
this.extractEnergyInner(ENERGY_FOR_HUNGER_POINT, false);
saturation_points_missing--;
saturation_changed = true;
} else {
@ -101,43 +98,61 @@ public class AndroidCapability implements ICapabilityProvider, IAndroidCapabilit
}
}
@Nonnull
@Override
public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) {
return BigDecimal.ZERO;
}
@Nonnull
@Override
public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) {
BigDecimal new_energy = energy_stored.subtract(howMuch, MatteryEnergyCapability.ROUND_RULES).max(BigDecimal.ZERO);
BigDecimal diff = energy_stored.subtract(new_energy);
if (!simulate) {
energy_stored = new_energy;
}
return diff;
}
@Nonnull
@Override
public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) {
BigDecimal new_energy = energy_stored.add(howMuch, MatteryEnergyCapability.ROUND_RULES).min(energy_stored_max);
BigDecimal diff = new_energy.subtract(energy_stored);
if (!simulate) {
energy_stored = new_energy;
}
return diff;
}
@Nonnull
@Override
public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) {
return receiveEnergyOuter(howMuch, simulate);
}
@Override
public LivingEntity getEntity() {
return this.ent;
}
@Override
public long getBatteryLevel() {
@Nonnull
public BigDecimal getBatteryLevel() {
return energy_stored;
}
@Override
public long getMaxBatteryLevel() {
@Nonnull
public BigDecimal getMaxBatteryLevel() {
return energy_stored_max;
}
@Override
public long receiveEnergy(long howMuch, boolean simulate) {
long final_value = Math.min(energy_stored_max, energy_stored + howMuch);
if (!simulate) {
energy_stored = final_value;
}
return final_value - energy_stored;
}
@Override
public long extractEnergy(long howMuch, boolean simulate) {
long final_value = Math.max(0, energy_stored - howMuch);
if (!simulate) {
energy_stored = final_value;
}
return energy_stored - final_value;
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {

View File

@ -3,23 +3,7 @@ package ru.dbotthepony.mc.otm.capability;
import net.minecraft.world.entity.LivingEntity;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
public interface IAndroidCapability {
public interface IAndroidCapability extends IMatteryEnergyStorage {
void tick();
LivingEntity getEntity();
long getBatteryLevel();
long getMaxBatteryLevel();
long getMissingPower();
long receiveEnergy(long howMuch, boolean simulate);
long extractEnergy(long howMuch, boolean simulate);
default int getMissingPowerInt() {
long power = getMissingPower();
if (power > Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
}
return (int) power;
}
}

View File

@ -0,0 +1,156 @@
package ru.dbotthepony.mc.otm.capability;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.math.BigInteger;
// IEnergyStorage for direct compat with Forge Energy
public interface IMatteryEnergyStorage extends IEnergyStorage {
// such as cables. This is something that would work only with energy storage
@Nonnull
BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate);
// for internal needs, e.g. for work
// CAN also be used by something that does evil
// e.g. sucking out energy anomaly should use this
@Nonnull
BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate);
// energy is received from outside, e.g. cables
@Nonnull
BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate);
// energy is received from inside, e.g. generator generates power
@Nonnull
BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate);
@Nonnull
default BigDecimal extractEnergyOuter(long howMuch, boolean simulate) {
return extractEnergyOuter(new BigDecimal(howMuch), simulate);
}
@Nonnull
default BigDecimal extractEnergyOuter(int howMuch, boolean simulate) {
return extractEnergyOuter(new BigDecimal(howMuch), simulate);
}
@Nonnull
default BigDecimal receiveEnergyOuter(long howMuch, boolean simulate) {
return receiveEnergyOuter(new BigDecimal(howMuch), simulate);
}
@Nonnull
default BigDecimal receiveEnergyOuter(int howMuch, boolean simulate) {
return receiveEnergyOuter(new BigDecimal(howMuch), simulate);
}
@Nonnull
default BigDecimal extractEnergyInner(long howMuch, boolean simulate) {
return receiveEnergyOuter(new BigDecimal(howMuch), simulate);
}
@Nonnull
default BigDecimal extractEnergyInner(int howMuch, boolean simulate) {
return receiveEnergyOuter(new BigDecimal(howMuch), simulate);
}
@Nonnull
default BigDecimal receiveEnergyInner(long howMuch, boolean simulate) {
return receiveEnergyOuter(new BigDecimal(howMuch), simulate);
}
@Nonnull
default BigDecimal receiveEnergyInner(int howMuch, boolean simulate) {
return receiveEnergyOuter(new BigDecimal(howMuch), simulate);
}
@Nonnull
BigDecimal getBatteryLevel();
@Nonnull
BigDecimal getMaxBatteryLevel();
default BigDecimal getMissingPower() {
return getMaxBatteryLevel().subtract(getBatteryLevel(), MatteryEnergyCapability.ROUND_RULES);
}
@Override
default int receiveEnergy(int maxReceive, boolean simulate) {
BigDecimal toReceive = new BigDecimal(maxReceive);
BigDecimal received = receiveEnergyOuter(toReceive, true);
if (received.compareTo(BigDecimal.ZERO) == 1 && received.compareTo(BigDecimal.ONE) == -1) {
// Receiving only a fraction
return 0;
}
return receiveEnergyOuter(received.round(MatteryEnergyCapability.ROUND_RULES), simulate).intValue();
}
@Override
default int extractEnergy(int maxReceive, boolean simulate) {
BigDecimal toReceive = new BigDecimal(maxReceive);
BigDecimal extracted = extractEnergyOuter(toReceive, true);
if (extracted.compareTo(BigDecimal.ZERO) == 1 && extracted.compareTo(BigDecimal.ONE) == -1) {
// Extracting only a fraction
return 0;
}
return extractEnergyOuter(extracted.round(MatteryEnergyCapability.ROUND_RULES), simulate).intValue();
}
@Override
default int getEnergyStored() {
BigDecimal level = getBatteryLevel();
if (level.compareTo(MatteryEnergyCapability.INT_MAX_VALUE) == -1) {
return level.intValue();
}
return Integer.MAX_VALUE;
};
@Override
default int getMaxEnergyStored() {
BigDecimal level = getMaxBatteryLevel();
if (level.compareTo(MatteryEnergyCapability.INT_MAX_VALUE) == -1) {
return level.intValue();
}
return Integer.MAX_VALUE;
};
@Override
default boolean canExtract() {
return extractEnergyOuter(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0;
};
@Override
default boolean canReceive() {
return receiveEnergyOuter(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0;
};
default boolean canExtractOuter() {
return extractEnergyOuter(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0;
};
default boolean canReceiveOuter() {
return receiveEnergyOuter(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0;
};
default boolean canExtractInner() {
return extractEnergyInner(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0;
};
default boolean canReceiveInner() {
return receiveEnergyInner(BigDecimal.ONE, true).compareTo(BigDecimal.ZERO) > 0;
};
}

View File

@ -0,0 +1,21 @@
package ru.dbotthepony.mc.otm.capability;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
public class MatteryEnergyCapability {
@CapabilityInject(IMatteryEnergyStorage.class)
public static Capability<IMatteryEnergyStorage> CAPABILITY = null;
public static final MathContext ROUND_RULES = new MathContext(0, RoundingMode.HALF_UP);
public static final BigDecimal INT_MAX_VALUE = new BigDecimal(Integer.MAX_VALUE);
public static final BigDecimal INT_MIN_VALUE = new BigDecimal(Integer.MIN_VALUE);
public static final BigDecimal LONG_MAX_VALUE = new BigDecimal(Long.MAX_VALUE);
public static final BigDecimal LONG_MIN_VALUE = new BigDecimal(Long.MIN_VALUE);
}

View File

@ -0,0 +1,135 @@
package ru.dbotthepony.mc.otm.capability;
import net.minecraft.nbt.CompoundTag;
import net.minecraftforge.common.util.INBTSerializable;
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import javax.annotation.Nonnull;
import java.math.BigDecimal;
public class MatteryMachineEnergyStorage implements IMatteryEnergyStorage, INBTSerializable<CompoundTag> {
public enum MachineType {
WORKER,
GENERATOR,
CAPACITOR,
}
public static final BigDecimal DEFAULT_MAX_RECEIVE = new BigDecimal(4000);
public static final BigDecimal DEFAULT_MAX_EXTRACT = new BigDecimal(4000);
public static final BigDecimal DEFAULT_MAX_CAPACITY = new BigDecimal(64000);
protected BigDecimal energy_stored = BigDecimal.ZERO;
protected BigDecimal energy_stored_max;
protected BigDecimal max_input;
protected BigDecimal max_output;
protected final MachineType machine_type;
public MatteryMachineEnergyStorage(BigDecimal capacity, MachineType type) {
this(capacity, type, DEFAULT_MAX_RECEIVE, DEFAULT_MAX_EXTRACT);
}
public MatteryMachineEnergyStorage(MachineType type) {
this(DEFAULT_MAX_CAPACITY, type);
}
public MatteryMachineEnergyStorage(BigDecimal capacity, MachineType type, BigDecimal maxReceive, BigDecimal maxExtract) {
energy_stored_max = capacity;
max_input = maxReceive;
max_output = maxExtract;
machine_type = type;
}
@Nonnull
@Override
public BigDecimal extractEnergyOuter(BigDecimal howMuch, boolean simulate) {
if (machine_type == MachineType.WORKER) {
return BigDecimal.ZERO;
}
return extractEnergyInner(howMuch, simulate);
}
@Nonnull
@Override
public BigDecimal extractEnergyInner(BigDecimal howMuch, boolean simulate) {
BigDecimal new_energy = energy_stored.subtract(howMuch.min(max_output), MatteryEnergyCapability.ROUND_RULES).max(BigDecimal.ZERO);
BigDecimal diff = energy_stored.subtract(new_energy);
if (!simulate) {
energy_stored = new_energy;
}
return diff;
}
@Nonnull
@Override
public BigDecimal receiveEnergyOuter(BigDecimal howMuch, boolean simulate) {
if (machine_type == MachineType.GENERATOR) {
return BigDecimal.ZERO;
}
return receiveEnergyInner(howMuch, simulate);
}
@Nonnull
@Override
public BigDecimal receiveEnergyInner(BigDecimal howMuch, boolean simulate) {
BigDecimal new_energy = energy_stored.add(howMuch.min(max_input), MatteryEnergyCapability.ROUND_RULES).min(energy_stored_max);
BigDecimal diff = new_energy.subtract(energy_stored);
if (!simulate) {
energy_stored = new_energy;
}
return diff;
}
@Nonnull
@Override
public BigDecimal getBatteryLevel() {
return energy_stored;
}
@Nonnull
@Override
public BigDecimal getMaxBatteryLevel() {
return energy_stored_max;
}
@Override
public boolean canExtract() {
return machine_type != MachineType.WORKER;
}
@Override
public boolean canReceive() {
return machine_type != MachineType.GENERATOR;
}
@Override
@Nonnull
public CompoundTag serializeNBT() {
CompoundTag tag = new CompoundTag();
tag.putString("energy_stored", energy_stored.toString());
tag.putString("energy_stored_max", energy_stored_max.toString());
tag.putString("max_input", max_input.toString());
tag.putString("max_output", max_output.toString());
return tag;
}
@Override
public void deserializeNBT(CompoundTag nbt) {
if (nbt.contains("energy_stored"))
energy_stored = new BigDecimal(nbt.getString("energy_stored"));
if (nbt.contains("energy_stored_max"))
energy_stored_max = new BigDecimal(nbt.getString("energy_stored_max"));
if (nbt.contains("max_input"))
max_input = new BigDecimal(nbt.getString("max_input"));
if (nbt.contains("max_output"))
max_output = new BigDecimal(nbt.getString("max_output"));
}
}

View File

@ -0,0 +1,28 @@
package ru.dbotthepony.mc.otm.menu;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityAndroidStation;
public class AndroidStationMenu extends AbstractContainerMenu {
private BlockEntityAndroidStation tile;
private Inventory inventory;
public AndroidStationMenu(int containerID, Inventory inventory) {
super(OverdriveThatMatters.ANDROID_STATION_MENU_TYPE, containerID);
new Exception().printStackTrace();
this.inventory = inventory;
}
public AndroidStationMenu(int containerID, BlockEntityAndroidStation tile) {
super(OverdriveThatMatters.ANDROID_STATION_MENU_TYPE, containerID);
this.tile = tile;
}
@Override
public boolean stillValid(Player p_38874_) {
return !tile.isRemoved();
}
}

View File

@ -0,0 +1,18 @@
package ru.dbotthepony.mc.otm.screen;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Inventory;
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu;
public class AndroidStationScreen extends AbstractContainerScreen<AndroidStationMenu> {
public AndroidStationScreen(AndroidStationMenu p_97741_, Inventory p_97742_, Component p_97743_) {
super(p_97741_, p_97742_, p_97743_);
}
@Override
protected void renderBg(PoseStack p_97787_, float p_97788_, int p_97789_, int p_97790_) {
}
}