Initial migration to V2 Energy API (#2474)

* Initial Energy API refactor

* Allow charging in energy storage BEs

* Remove maven for experimental fabric

Co-authored-by: modmuss50 <modmuss50@gmail.com>
This commit is contained in:
Technici4n 2021-09-01 22:14:15 +02:00 committed by GitHub
parent 2bc4886cc0
commit 3e2b0e11ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
75 changed files with 764 additions and 694 deletions

View file

@ -46,11 +46,12 @@ import reborncore.common.misc.ModSounds;
import reborncore.common.misc.RebornCoreTags;
import reborncore.common.multiblock.MultiblockRegistry;
import reborncore.common.network.ServerBoundPackets;
import reborncore.common.powerSystem.PowerAcceptorBlockEntity;
import reborncore.common.powerSystem.PowerSystem;
import reborncore.common.recipes.PaddedShapedRecipe;
import reborncore.common.util.CalenderUtils;
import reborncore.common.util.GenericWrenchHelper;
import reborncore.common.util.Tank;
import team.reborn.energy.api.EnergyStorage;
import java.io.File;
import java.util.function.Supplier;
@ -124,6 +125,12 @@ public class RebornCore implements ModInitializer {
}
return null;
});
EnergyStorage.SIDED.registerFallback((world, pos, state, be, direction) -> {
if (be instanceof PowerAcceptorBlockEntity powerAcceptor) {
return powerAcceptor.getSideEnergyStorage(direction);
}
return null;
});
LOGGER.info("Reborn core is done for now, now to let other mods have their turn...");
LOADED = true;

View file

@ -43,10 +43,8 @@ import reborncore.RebornCore;
import reborncore.api.IListInfoProvider;
import reborncore.common.BaseBlockEntityProvider;
import reborncore.common.powerSystem.PowerSystem;
import reborncore.common.powerSystem.RcEnergyItem;
import reborncore.common.util.StringUtils;
import team.reborn.energy.Energy;
import team.reborn.energy.EnergyHolder;
import team.reborn.energy.EnergySide;
import java.util.List;
@ -60,24 +58,24 @@ public class StackToolTipHandler implements ItemTooltipCallback {
if (item instanceof IListInfoProvider) {
((IListInfoProvider) item).addInfo(tooltipLines, false, false);
}
else if (item instanceof EnergyHolder) {
LiteralText line1 = new LiteralText(PowerSystem.getLocalizedPowerNoSuffix(Energy.of(itemStack).getEnergy()));
else if (item instanceof RcEnergyItem energyItem) {
LiteralText line1 = new LiteralText(PowerSystem.getLocalizedPowerNoSuffix(energyItem.getStoredEnergy(itemStack)));
line1.append("/");
line1.append(PowerSystem.getLocalizedPower(Energy.of(itemStack).getMaxStored()));
line1.append(PowerSystem.getLocalizedPower(energyItem.getEnergyCapacity()));
line1.formatted(Formatting.GOLD);
tooltipLines.add(1, line1);
if (Screen.hasShiftDown()) {
int percentage = percentage(Energy.of(itemStack).getEnergy(), Energy.of(itemStack).getMaxStored());
int percentage = percentage(energyItem.getStoredEnergy(itemStack), energyItem.getEnergyCapacity());
MutableText line2 = StringUtils.getPercentageText(percentage);
line2.append(" ");
line2.formatted(Formatting.GRAY);
line2.append(I18n.translate("reborncore.gui.tooltip.power_charged"));
tooltipLines.add(2, line2);
double inputRate = ((EnergyHolder) item).getMaxInput(EnergySide.UNKNOWN);
double outputRate = ((EnergyHolder) item).getMaxOutput(EnergySide.UNKNOWN);
double inputRate = energyItem.getEnergyMaxInput();
double outputRate = energyItem.getEnergyMaxOutput();
LiteralText line3 = new LiteralText("");
if (inputRate != 0 && inputRate == outputRate){
line3.append(I18n.translate("techreborn.tooltip.transferRate"));

View file

@ -1,48 +0,0 @@
/*
* This file is part of RebornCore, licensed under the MIT License (MIT).
*
* Copyright (c) 2021 TeamReborn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package reborncore.client.gui.slots;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import team.reborn.energy.Energy;
/**
* Created by Rushmead
*/
public class SlotCharge extends BaseSlot {
public SlotCharge(Inventory inventoryIn, int index, int xPosition, int yPosition) {
super(inventoryIn, index, xPosition, yPosition);
}
@Override
public boolean canInsert(ItemStack stack) {
return Energy.valid(stack);
}
@Override
public boolean canWorldBlockRemove() {
return false;
}
}

View file

@ -26,6 +26,9 @@ package reborncore.client.screen.builder;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import net.fabricmc.fabric.api.transfer.v1.context.ContainerItemContext;
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant;
import net.fabricmc.fabric.api.transfer.v1.item.base.SingleStackStorage;
import net.minecraft.block.entity.AbstractFurnaceBlockEntity;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.inventory.CraftingInventory;
@ -48,7 +51,7 @@ import reborncore.client.screen.builder.slot.UpgradeSlot;
import reborncore.common.blockentity.MachineBaseBlockEntity;
import reborncore.common.fluid.container.ItemFluidInfo;
import reborncore.common.powerSystem.PowerAcceptorBlockEntity;
import team.reborn.energy.Energy;
import team.reborn.energy.api.EnergyStorageUtil;
import java.util.function.Consumer;
import java.util.function.Predicate;
@ -106,7 +109,7 @@ public class BlockEntityScreenHandlerBuilder {
public BlockEntityScreenHandlerBuilder energySlot(final int index, final int x, final int y) {
this.parent.slots.add(new FilteredSlot(this.inventory, index, x, y)
.setFilter(Energy::valid));
.setFilter(EnergyStorageUtil::isEnergyStorage));
return this;
}

View file

@ -28,6 +28,7 @@ import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import reborncore.client.gui.slots.BaseSlot;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
public class FilteredSlot extends BaseSlot {

View file

@ -327,8 +327,8 @@ public class MachineBaseBlockEntity extends BlockEntity implements BlockEntityTi
}
@Override
public double getEuPerTick(double baseEu) {
return baseEu * powerMultiplier;
public long getEuPerTick(long baseEu) {
return (long) (baseEu * powerMultiplier);
}
@Override

View file

@ -24,9 +24,14 @@
package reborncore.common.powerSystem;
import net.fabricmc.fabric.api.transfer.v1.context.ContainerItemContext;
import net.fabricmc.fabric.api.transfer.v1.item.InventoryStorage;
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant;
import net.fabricmc.fabric.api.transfer.v1.storage.base.SingleSlotStorage;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.Text;
@ -41,23 +46,37 @@ import reborncore.api.IListInfoProvider;
import reborncore.common.blockentity.MachineBaseBlockEntity;
import reborncore.common.blockentity.RedstoneConfiguration;
import reborncore.common.util.StringUtils;
import team.reborn.energy.Energy;
import team.reborn.energy.EnergySide;
import team.reborn.energy.EnergyStorage;
import team.reborn.energy.EnergyTier;
import team.reborn.energy.api.EnergyStorage;
import team.reborn.energy.api.EnergyStorageUtil;
import team.reborn.energy.api.base.SimpleSidedEnergyContainer;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity implements EnergyStorage, IListInfoProvider // TechReborn
{
private EnergyTier blockEntityPowerTier;
private double energy;
public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity implements IListInfoProvider {
public final SimpleSidedEnergyContainer energyContainer = new SimpleSidedEnergyContainer() {
@Override
public long getCapacity() {
return PowerAcceptorBlockEntity.this.getMaxStoredPower();
}
public double extraPowerStorage;
public double extraPowerInput;
@Override
public long getMaxInsert(@Nullable Direction side) {
return PowerAcceptorBlockEntity.this.getMaxInput(side);
}
@Override
public long getMaxExtract(@Nullable Direction side) {
return PowerAcceptorBlockEntity.this.getMaxOutput(side);
}
};
private RcEnergyTier blockEntityPowerTier;
public long extraPowerStorage;
public long extraPowerInput;
public int extraTier;
public double powerChange;
public double powerLastTick;
public long powerChange;
public long powerLastTick;
public boolean checkOverfill = true; // Set to false to disable the overfill check.
public PowerAcceptorBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
@ -65,22 +84,16 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
checkTier();
}
public void checkTier() {
if (this.getMaxInput(EnergySide.UNKNOWN) == 0) {
blockEntityPowerTier = getTier((int) this.getBaseMaxOutput());
} else {
blockEntityPowerTier = getTier((int) this.getBaseMaxInput());
}
public EnergyStorage getSideEnergyStorage(@Nullable Direction side) {
return energyContainer.getSideStorage(side);
}
// TO-DO: Move to Energy API probably. Cables use this method.
public static EnergyTier getTier(int power) {
for (EnergyTier tier : EnergyTier.values()) {
if (tier.getMaxInput() >= power) {
return tier;
}
public void checkTier() {
if (this.getMaxInput(null) == 0) {
blockEntityPowerTier = RcEnergyTier.getTier(this.getBaseMaxOutput());
} else {
blockEntityPowerTier = RcEnergyTier.getTier(this.getBaseMaxInput());
}
return EnergyTier.INFINITE;
}
/**
@ -88,8 +101,8 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
*
* @return double Free space for energy in internal buffer
*/
public double getFreeSpace() {
return getMaxStoredPower() - getStored(EnergySide.UNKNOWN);
public long getFreeSpace() {
return getMaxStoredPower() - getStored();
}
/**
@ -97,8 +110,18 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
*
* @param amount double Amount to add
*/
public void addEnergy(double amount){
setStored(energy + amount);
public void addEnergy(long amount){
setStored(getEnergy() + amount);
}
public void addEnergyProbabilistic(double amount) {
long integerPart = (long) Math.floor(amount);
addEnergy(integerPart);
double fractionalPart = amount - integerPart;
if (ThreadLocalRandom.current().nextDouble() <= fractionalPart) {
addEnergy(1);
}
}
/**
@ -106,9 +129,9 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
*
* @param amount double Amount of energy to use
*/
public void useEnergy(double amount){
if (energy > amount) {
setStored(energy - amount);
public void useEnergy(long amount){
if (getEnergy() > amount) {
setStored(getEnergy() - amount);
} else {
setStored(0);
}
@ -127,21 +150,21 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
return;
}
double chargeEnergy = Math.min(getFreeSpace(), getMaxInput(EnergySide.UNKNOWN));
if (chargeEnergy <= 0.0) {
long chargeEnergy = Math.min(getFreeSpace(), getMaxInput(null));
if (chargeEnergy <= 0) {
return;
}
if (!getOptionalInventory().isPresent()) {
return;
}
ItemStack batteryStack = getOptionalInventory().get().getStack(slot);
if (batteryStack.isEmpty()) {
if (getOptionalInventory().isEmpty()) {
return;
}
Inventory inventory = getOptionalInventory().get();
if (Energy.valid(batteryStack)) {
Energy.of(batteryStack).into(Energy.of(this)).move();
}
EnergyStorageUtil.move(
ContainerItemContext.ofSingleSlot(InventoryStorage.of(inventory, null).getSlots().get(slot)).find(EnergyStorage.ITEM),
energyContainer.getSideStorage(null),
Long.MAX_VALUE,
null
);
}
/**
@ -158,30 +181,30 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
return;
}
if (!getOptionalInventory().isPresent()){
if (getOptionalInventory().isEmpty()){
return;
}
ItemStack batteryStack = getOptionalInventory().get().getStack(slot);
if (batteryStack.isEmpty()) {
return;
}
Inventory inventory = getOptionalInventory().get();
if (Energy.valid(batteryStack)) {
Energy.of(this).into(Energy.of(batteryStack)).move(getTier().getMaxOutput());
}
EnergyStorageUtil.move(
energyContainer.getSideStorage(null),
ContainerItemContext.ofSingleSlot(InventoryStorage.of(inventory, null).getSlots().get(slot)).find(EnergyStorage.ITEM),
Long.MAX_VALUE,
null
);
}
/**
* Calculates the comparator output of a powered BE with the formula
* {@code ceil(blockEntity.getStored(EnergySide.UNKNOWN) * 15.0 / storage.getMaxPower())}.
* {@code ceil(blockEntity.getStored() * 15.0 / storage.getMaxPower())}.
*
* @param blockEntity the powered BE
* @return the calculated comparator output or 0 if {@code blockEntity} is not a {@code PowerAcceptorBlockEntity}
*/
public static int calculateComparatorOutputFromEnergy(@Nullable BlockEntity blockEntity) {
if (blockEntity instanceof PowerAcceptorBlockEntity storage) {
return MathHelper.ceil(storage.getStored(EnergySide.UNKNOWN) * 15.0 / storage.getMaxStoredPower());
return MathHelper.ceil(storage.getStored() * 15.0 / storage.getMaxStoredPower());
} else {
return 0;
}
@ -202,7 +225,7 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
* @param side EnergySide Machine side
* @return boolean Returns true if machine can accept energy from side provided
*/
protected boolean canAcceptEnergy(EnergySide side){
protected boolean canAcceptEnergy(@Nullable Direction side){
return true;
}
@ -212,17 +235,7 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
* @param side EnergySide Machine side
* @return boolean Returns true if machine can provide energy via particular side
*/
protected boolean canProvideEnergy(EnergySide side){
return true;
}
@Deprecated
public boolean canAcceptEnergy(Direction direction) {
return true;
}
@Deprecated
public boolean canProvideEnergy(Direction direction) {
protected boolean canProvideEnergy(@Nullable Direction side){
return true;
}
@ -231,7 +244,7 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
*
* @return double Size of additional energy buffer
*/
public double getExtraPowerStorage(){
public long getExtraPowerStorage(){
return extraPowerStorage;
}
@ -240,7 +253,7 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
*
* @param extraPowerStorage double Size of additional energy buffer
*/
public void setExtraPowerStorage(double extraPowerStorage) {
public void setExtraPowerStorage(long extraPowerStorage) {
this.extraPowerStorage = extraPowerStorage;
}
@ -249,7 +262,7 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
*
* @return double Energy change per tick
*/
public double getPowerChange() {
public long getPowerChange() {
return powerChange;
}
@ -258,7 +271,7 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
*
* @param powerChange double Energy change per tick
*/
public void setPowerChange(double powerChange) {
public void setPowerChange(long powerChange) {
this.powerChange = powerChange;
}
@ -268,15 +281,15 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
* @return double Energy stored in block entity
*/
public double getEnergy() {
return getStored(EnergySide.UNKNOWN);
public long getEnergy() {
return getStored();
}
/**
* Wrapper method used to sync energy values with client via BlockEntityScreenHandlerBuilder
* @param energy double Energy stored in block entity
*/
public void setEnergy(double energy) {
public void setEnergy(long energy) {
setStored(energy);
}
@ -285,21 +298,21 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
*
* @return double Size of internal Energy buffer
*/
public abstract double getBaseMaxPower();
public abstract long getBaseMaxPower();
/**
* Returns base output rate or zero if machine doesn't output energy
*
* @return double Output rate, E\t
*/
public abstract double getBaseMaxOutput();
public abstract long getBaseMaxOutput();
/**
* Returns base input rate or zero if machine doesn't accept energy
*
* @return double Input rate, E\t
*/
public abstract double getBaseMaxInput();
public abstract long getBaseMaxInput();
// MachineBaseBlockEntity
@Override
@ -308,7 +321,7 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
if (world == null || world.isClient) {
return;
}
if (getStored(EnergySide.UNKNOWN) <= 0) {
if (getStored() <= 0) {
return;
}
if (!isActive(RedstoneConfiguration.POWER_IO)) {
@ -316,18 +329,16 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
}
for (Direction side : Direction.values()) {
BlockEntity blockEntity = world.getBlockEntity(getPos().offset(side));
if (blockEntity == null || !Energy.valid(blockEntity)) {
continue;
}
Energy.of(this)
.side(side)
.into(Energy.of(blockEntity).side(side.getOpposite()))
.move();
EnergyStorageUtil.move(
energyContainer.getSideStorage(side),
EnergyStorage.SIDED.find(world, pos.offset(side), side.getOpposite()),
Long.MAX_VALUE,
null
);
}
powerChange = getStored(EnergySide.UNKNOWN) - powerLastTick;
powerLastTick = getStored(EnergySide.UNKNOWN);
powerChange = getStored() - powerLastTick;
powerLastTick = getStored();
}
@Override
@ -335,7 +346,7 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
super.readNbt(tag);
NbtCompound data = tag.getCompound("PowerAcceptor");
if (shouldHandleEnergyNBT()) {
this.setStored(data.getDouble("energy"));
this.setStored(data.getLong("energy"));
}
}
@ -343,7 +354,7 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
public NbtCompound writeNbt(NbtCompound tag) {
super.writeNbt(tag);
NbtCompound data = new NbtCompound();
data.putDouble("energy", getStored(EnergySide.UNKNOWN));
data.putLong("energy", getStored());
tag.put("PowerAcceptor", data);
return tag;
}
@ -356,28 +367,23 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
extraPowerInput = 0;
}
// EnergyStorage
@Override
public double getStored(EnergySide face) {
return energy;
public long getStored() {
return energyContainer.amount;
}
@Override
public void setStored(double amount) {
this.energy = amount;
public void setStored(long amount) {
energyContainer.amount = amount;
if(checkOverfill){
this.energy = Math.max(Math.min(energy, getMaxStoredPower()), 0);
energyContainer.amount = Math.max(Math.min(energyContainer.amount, getMaxStoredPower()), 0);
}
markDirty();
}
@Override
public double getMaxStoredPower() {
public long getMaxStoredPower() {
return getBaseMaxPower() + extraPowerStorage;
}
@Override
public double getMaxOutput(EnergySide face) {
public long getMaxOutput(@Nullable Direction face) {
if (!isActive(RedstoneConfiguration.POWER_IO)) {
return 0;
}
@ -390,8 +396,7 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
return getBaseMaxOutput();
}
@Override
public double getMaxInput(EnergySide face) {
public long getMaxInput(@Nullable Direction face) {
if (!isActive(RedstoneConfiguration.POWER_IO)) {
return 0;
}
@ -404,23 +409,31 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
return getBaseMaxInput() + extraPowerInput;
}
@Override
public EnergyTier getTier() {
public RcEnergyTier getTier() {
if (blockEntityPowerTier == null) {
checkTier();
}
if (extraTier > 0) {
for (EnergyTier enumTier : EnergyTier.values()) {
for (RcEnergyTier enumTier : RcEnergyTier.values()) {
if (enumTier.ordinal() == blockEntityPowerTier.ordinal() + extraTier) {
return enumTier;
}
}
return EnergyTier.INFINITE;
return RcEnergyTier.INFINITE;
}
return blockEntityPowerTier;
}
public boolean tryUseExact(long energy) {
if (getStored() >= energy) {
addEnergy(-energy);
return true;
} else {
return false;
}
}
// IListInfoProvider
@Override
public void addInfo(List<Text> info, boolean isReal, boolean hasData) {
@ -429,7 +442,7 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
new TranslatableText("reborncore.tooltip.energy")
.formatted(Formatting.GRAY)
.append(": ")
.append(PowerSystem.getLocalizedPower(energy))
.append(PowerSystem.getLocalizedPower(getStored()))
.formatted(Formatting.GOLD)
);
}
@ -442,21 +455,21 @@ public abstract class PowerAcceptorBlockEntity extends MachineBaseBlockEntity im
.formatted(Formatting.GOLD)
);
if (getMaxInput(EnergySide.UNKNOWN) != 0) {
if (getMaxInput(null) != 0) {
info.add(
new TranslatableText("reborncore.tooltip.energy.inputRate")
.formatted(Formatting.GRAY)
.append(": ")
.append(PowerSystem.getLocalizedPower(getMaxInput(EnergySide.UNKNOWN)))
.append(PowerSystem.getLocalizedPower(getMaxInput(null)))
.formatted(Formatting.GOLD)
);
}
if (getMaxOutput(EnergySide.UNKNOWN) > 0) {
if (getMaxOutput(null) > 0) {
info.add(
new TranslatableText("reborncore.tooltip.energy.outputRate")
.formatted(Formatting.GRAY)
.append(": ")
.append(PowerSystem.getLocalizedPower(getMaxOutput(EnergySide.UNKNOWN)))
.append(PowerSystem.getLocalizedPower(getMaxOutput(null)))
.formatted(Formatting.GOLD)
);
}

View file

@ -0,0 +1,28 @@
package reborncore.common.powerSystem;
import team.reborn.energy.api.base.SimpleBatteryItem;
/**
* Implement on simple energy-containing items and (on top of what SimpleBatteryItem does):
* <ul>
* <li>A tooltip will be added for the item, indicating the stored power, the max power and the extraction rates.</li>
* <li>Any RcEnergyItem input in a crafting recipe input will automatically give its energy to the output if the output implements RcEnergyItem.</li>
* </ul>
* TODO: consider moving this functionality to the energy API?
*/
public interface RcEnergyItem extends SimpleBatteryItem {
long getEnergyCapacity();
/**
* @return the tier of this EnergyStorage, used to have standard I/O rates.
*/
RcEnergyTier getTier();
default long getEnergyMaxInput() {
return getTier().getMaxInput();
}
default long getEnergyMaxOutput() {
return getTier().getMaxOutput();
}
}

View file

@ -0,0 +1,39 @@
package reborncore.common.powerSystem;
/**
* Standard input / output limits for RC-based machines.
*/
public enum RcEnergyTier {
MICRO(8, 8),
LOW(32, 32),
MEDIUM(128, 128),
HIGH(512, 512),
EXTREME(2048, 2048),
INSANE(8192, 8192),
INFINITE(Integer.MAX_VALUE, Integer.MAX_VALUE);
private final int maxInput;
private final int maxOutput;
RcEnergyTier(int maxInput, int maxOutput) {
this.maxInput = maxInput;
this.maxOutput = maxOutput;
}
public int getMaxInput() {
return maxInput;
}
public int getMaxOutput() {
return maxOutput;
}
public static RcEnergyTier getTier(long power) {
for (RcEnergyTier tier : RcEnergyTier.values()) {
if (tier.getMaxInput() >= power) {
return tier;
}
}
return RcEnergyTier.INFINITE;
}
}

View file

@ -39,7 +39,7 @@ public interface IUpgradeHandler {
double getPowerMultiplier();
double getEuPerTick(double baseEu);
long getEuPerTick(long baseEu);
void addSpeedMulti(double amount);

View file

@ -36,11 +36,9 @@ import reborncore.common.blocks.BlockMachineBase;
import reborncore.common.crafting.RebornRecipe;
import reborncore.common.crafting.RebornRecipeType;
import reborncore.common.crafting.ingredient.RebornIngredient;
import reborncore.common.powerSystem.PowerAcceptorBlockEntity;
import reborncore.common.util.ItemUtils;
import reborncore.common.util.RebornInventory;
import team.reborn.energy.Energy;
import team.reborn.energy.EnergySide;
import team.reborn.energy.EnergyStorage;
import java.util.ArrayList;
import java.util.Optional;
@ -63,7 +61,7 @@ public class RecipeCrafter implements IUpgradeHandler {
/**
* This is the place to use the power from
*/
public EnergyStorage energy;
public PowerAcceptorBlockEntity energy;
public Optional<IUpgradeHandler> parentUpgradeHandler = Optional.empty();
@ -107,8 +105,8 @@ public class RecipeCrafter implements IUpgradeHandler {
int[] inputSlots, int[] outputSlots) {
this.recipeType = recipeType;
this.blockEntity = blockEntity;
if (blockEntity instanceof EnergyStorage) {
energy = (EnergyStorage) blockEntity;
if (blockEntity instanceof PowerAcceptorBlockEntity powerAcceptor) {
energy = powerAcceptor;
}
if (blockEntity instanceof IUpgradeHandler) {
parentUpgradeHandler = Optional.of((IUpgradeHandler) blockEntity);
@ -180,8 +178,8 @@ public class RecipeCrafter implements IUpgradeHandler {
}
}
} else if (currentRecipe != null && currentTickTime < currentNeededTicks) {
double useRequirement = getEuPerTick(currentRecipe.getPower());
if (Energy.of(energy).use(useRequirement)) {
long useRequirement = getEuPerTick(currentRecipe.getPower());
if (energy.tryUseExact(useRequirement)) {
currentTickTime++;
if ((currentTickTime == 1 || currentTickTime % 20 == 0) && soundHanlder != null) {
soundHanlder.playSound(false, blockEntity);
@ -315,7 +313,7 @@ public class RecipeCrafter implements IUpgradeHandler {
}
private boolean isActive() {
return currentRecipe != null && energy.getStored(EnergySide.UNKNOWN) >= currentRecipe.getPower();
return currentRecipe != null && energy.getEnergy() >= currentRecipe.getPower();
}
public boolean canCraftAgain() {
@ -326,7 +324,7 @@ public class RecipeCrafter implements IUpgradeHandler {
return false;
}
}
return !(energy.getStored(EnergySide.UNKNOWN) < recipe.getPower());
return !(energy.getEnergy() < recipe.getPower());
}
}
return false;
@ -404,8 +402,8 @@ public class RecipeCrafter implements IUpgradeHandler {
}
@Override
public double getEuPerTick(double baseEu) {
double power = parentUpgradeHandler.map(iUpgradeHandler -> iUpgradeHandler.getEuPerTick(baseEu)).orElse(1D);
public long getEuPerTick(long baseEu) {
long power = parentUpgradeHandler.map(iUpgradeHandler -> iUpgradeHandler.getEuPerTick(baseEu)).orElse(1L);
return Math.min(power, energy.getMaxStoredPower());
}

View file

@ -24,14 +24,20 @@
package reborncore.common.util;
import net.fabricmc.fabric.api.transfer.v1.context.ContainerItemContext;
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant;
import net.fabricmc.fabric.api.transfer.v1.item.PlayerInventoryStorage;
import net.fabricmc.fabric.api.transfer.v1.storage.base.SingleSlotStorage;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Formatting;
import reborncore.common.powerSystem.RcEnergyItem;
import reborncore.common.recipes.IRecipeInput;
import team.reborn.energy.Energy;
import team.reborn.energy.api.EnergyStorage;
import team.reborn.energy.api.EnergyStorageUtil;
import java.util.List;
import java.util.function.Predicate;
@ -103,15 +109,11 @@ public class ItemUtils {
}
public static double getPowerForDurabilityBar(ItemStack stack) {
if (stack.isEmpty()) {
if (!(stack.getItem() instanceof RcEnergyItem energyItem)) {
return 0.0;
}
if (!Energy.valid(stack)) {
return 0.0;
}
return Energy.of(stack).getEnergy() / Energy.of(stack).getMaxStored();
return (double) energyItem.getStoredEnergy(stack) / energyItem.getEnergyCapacity();
}
/**
@ -136,7 +138,7 @@ public class ItemUtils {
if (!ItemUtils.isActive(stack)) {
return;
}
if (Energy.of(stack).getEnergy() >= cost) {
if (((RcEnergyItem) stack.getItem()).getStoredEnergy(stack) >= cost) {
return;
}
if (isClient) {
@ -213,12 +215,29 @@ public class ItemUtils {
* @param itemStack ItemStack Powered item
* @param maxOutput int Maximum output rate of powered item
*/
public static void distributePowerToInventory(PlayerEntity player, ItemStack itemStack, int maxOutput) {
public static void distributePowerToInventory(PlayerEntity player, ItemStack itemStack, long maxOutput) {
distributePowerToInventory(player, itemStack, maxOutput, (stack) -> true);
}
public static void distributePowerToInventory(PlayerEntity player, ItemStack itemStack, int maxOutput, Predicate<ItemStack> filter) {
if (!Energy.valid(itemStack)) {
public static void distributePowerToInventory(PlayerEntity player, ItemStack itemStack, long maxOutput, Predicate<ItemStack> filter) {
// Locate the current stack in the player inventory.
PlayerInventoryStorage playerInv = PlayerInventoryStorage.of(player);
SingleSlotStorage<ItemVariant> sourceSlot = null;
for (int i = 0; i < player.getInventory().size(); i++) {
if (player.getInventory().getStack(i) == itemStack) {
sourceSlot = playerInv.getSlots().get(i);
break;
}
}
if (sourceSlot == null) {
throw new IllegalArgumentException("Failed to locate current stack in the player inventory.");
}
EnergyStorage sourceStorage = ContainerItemContext.ofPlayerSlot(player, sourceSlot).find(EnergyStorage.ITEM);
if (sourceStorage == null) {
return;
}
@ -229,11 +248,12 @@ public class ItemUtils {
continue;
}
if (Energy.valid(invStack)) {
Energy.of(itemStack)
.into(Energy.of(invStack))
.move(maxOutput);
}
EnergyStorageUtil.move(
sourceStorage,
ContainerItemContext.ofPlayerSlot(player, playerInv.getSlots().get(i)).find(EnergyStorage.ITEM),
maxOutput,
null
);
}
}
}