batteries and fluid tanks now block propagation if not set to buffer mode (which the player can circumvent by cabling/piping around them, which gives them the choice of behaviour, and is more intuitive)

This commit is contained in:
George Paton 2025-03-24 16:09:56 +11:00
parent 62485c6854
commit 141e80bfcb
5 changed files with 139 additions and 99 deletions

View File

@ -1,5 +0,0 @@
package api.hbm.fluidmk2;
public interface IFluidBufferTransceiverMK2 extends IFluidStandardTransceiverMK2 {
}

View File

@ -46,7 +46,7 @@ public interface IFluidStandardSenderMK2 extends IFluidProviderMK2 {
} }
} }
if(te != this && te instanceof IFluidReceiverMK2 && !(te instanceof IFluidBufferTransceiverMK2)) { if(te != this && te instanceof IFluidReceiverMK2) {
IFluidReceiverMK2 rec = (IFluidReceiverMK2) te; IFluidReceiverMK2 rec = (IFluidReceiverMK2) te;
if(rec.canConnect(type, dir.getOpposite())) { if(rec.canConnect(type, dir.getOpposite())) {
long provides = Math.min(this.getFluidAvailable(type, pressure), this.getProviderSpeed(type, pressure)); long provides = Math.min(this.getFluidAvailable(type, pressure), this.getProviderSpeed(type, pressure));

View File

@ -2,7 +2,7 @@ package com.hbm.tileentity.machine.storage;
import api.hbm.energymk2.IEnergyReceiverMK2.ConnectionPriority; import api.hbm.energymk2.IEnergyReceiverMK2.ConnectionPriority;
import api.hbm.fluidmk2.FluidNode; import api.hbm.fluidmk2.FluidNode;
import api.hbm.fluidmk2.IFluidBufferTransceiverMK2; import api.hbm.fluidmk2.IFluidStandardTransceiverMK2;
import java.util.HashSet; import java.util.HashSet;
@ -45,10 +45,9 @@ import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.common.util.ForgeDirection;
@Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "opencomputers")}) @Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "opencomputers")})
public class TileEntityBarrel extends TileEntityMachineBase implements SimpleComponent, IFluidBufferTransceiverMK2, IPersistentNBT, IGUIProvider, CompatHandler.OCComponent, IFluidCopiable { public class TileEntityBarrel extends TileEntityMachineBase implements SimpleComponent, IFluidStandardTransceiverMK2, IPersistentNBT, IGUIProvider, CompatHandler.OCComponent, IFluidCopiable {
protected FluidNode node; protected FluidNode node;
protected FluidType lastType;
public FluidTank tank; public FluidTank tank;
public short mode = 0; public short mode = 0;
@ -100,27 +99,42 @@ public class TileEntityBarrel extends TileEntityMachineBase implements SimpleCom
tank.loadTank(2, 3, slots); tank.loadTank(2, 3, slots);
tank.unloadTank(4, 5, slots); tank.unloadTank(4, 5, slots);
if(this.node == null || this.node.expired || tank.getTankType() != lastType) { // In buffer mode, acts like a pipe block, providing fluid to its own node
// otherwise, it is a regular providing/receiving machine, blocking further propagation
if(mode == 1) {
if(this.node == null || this.node.expired) {
this.node = (FluidNode) UniNodespace.getNode(worldObj, xCoord, yCoord, zCoord, tank.getTankType().getNetworkProvider()); this.node = (FluidNode) UniNodespace.getNode(worldObj, xCoord, yCoord, zCoord, tank.getTankType().getNetworkProvider());
if(this.node == null || this.node.expired || tank.getTankType() != lastType) { if(this.node == null || this.node.expired) {
this.node = this.createNode(tank.getTankType()); this.node = this.createNode(tank.getTankType());
UniNodespace.createNode(worldObj, this.node); UniNodespace.createNode(worldObj, this.node);
lastType = tank.getTankType(); }
} }
}
if(mode == 2 || mode == 1) {
this.tryProvide(tank, worldObj, xCoord, yCoord, zCoord, ForgeDirection.UNKNOWN); this.tryProvide(tank, worldObj, xCoord, yCoord, zCoord, ForgeDirection.UNKNOWN);
} else {
if(node != null && node.hasValidNet()) node.net.removeProvider(this);
}
if(mode == 0 || mode == 1) {
if(node != null && node.hasValidNet()) node.net.addReceiver(this); if(node != null && node.hasValidNet()) node.net.addReceiver(this);
} else { } else {
if(node != null && node.hasValidNet()) node.net.removeReceiver(this); if(this.node != null) {
UniNodespace.destroyNode(worldObj, xCoord, yCoord, zCoord, tank.getTankType().getNetworkProvider());
this.node = null;
}
for(DirPos pos : getConPos()) {
FluidNode dirNode = (FluidNode) UniNodespace.getNode(worldObj, pos.getX(), pos.getY(), pos.getZ(), tank.getTankType().getNetworkProvider());
if(mode == 2) {
tryProvide(tank, worldObj, pos.getX(), pos.getY(), pos.getZ(), pos.getDir());
} else {
if(dirNode != null && dirNode.hasValidNet()) dirNode.net.removeProvider(this);
}
if(mode == 0) {
if(dirNode != null && dirNode.hasValidNet()) dirNode.net.addReceiver(this);
} else {
if(dirNode != null && dirNode.hasValidNet()) dirNode.net.removeReceiver(this);
}
}
} }
if(tank.getFill() > 0) { if(tank.getFill() > 0) {

View File

@ -16,6 +16,7 @@ import com.hbm.lib.Library;
import com.hbm.tileentity.IGUIProvider; import com.hbm.tileentity.IGUIProvider;
import com.hbm.tileentity.IPersistentNBT; import com.hbm.tileentity.IPersistentNBT;
import com.hbm.tileentity.TileEntityMachineBase; import com.hbm.tileentity.TileEntityMachineBase;
import com.hbm.uninos.UniNodespace;
import com.hbm.util.CompatEnergyControl; import com.hbm.util.CompatEnergyControl;
import cpw.mods.fml.common.Optional; import cpw.mods.fml.common.Optional;
@ -36,14 +37,14 @@ import net.minecraftforge.common.util.ForgeDirection;
@Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "opencomputers")}) @Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "opencomputers")})
public class TileEntityMachineBattery extends TileEntityMachineBase implements IEnergyConductorMK2, IEnergyProviderMK2, IEnergyReceiverMK2, IPersistentNBT, SimpleComponent, IGUIProvider, IInfoProviderEC, CompatHandler.OCComponent { public class TileEntityMachineBattery extends TileEntityMachineBase implements IEnergyConductorMK2, IEnergyProviderMK2, IEnergyReceiverMK2, IPersistentNBT, SimpleComponent, IGUIProvider, IInfoProviderEC, CompatHandler.OCComponent {
public long[] log = new long[20]; public long[] log = new long[20];
public long delta = 0; public long delta = 0;
public long power = 0; public long power = 0;
public long prevPowerState = 0; public long prevPowerState = 0;
protected PowerNode node; protected PowerNode node;
//0: input only //0: input only
//1: buffer //1: buffer
//2: output only //2: output only
@ -55,16 +56,16 @@ public class TileEntityMachineBattery extends TileEntityMachineBase implements I
public short redLow = 0; public short redLow = 0;
public short redHigh = 2; public short redHigh = 2;
public ConnectionPriority priority = ConnectionPriority.LOW; public ConnectionPriority priority = ConnectionPriority.LOW;
//public boolean conducts = false; //public boolean conducts = false;
public byte lastRedstone = 0; public byte lastRedstone = 0;
private static final int[] slots_top = new int[] {0}; private static final int[] slots_top = new int[] {0};
private static final int[] slots_bottom = new int[] {0, 1}; private static final int[] slots_bottom = new int[] {0, 1};
private static final int[] slots_side = new int[] {1}; private static final int[] slots_side = new int[] {1};
private String customName; private String customName;
public TileEntityMachineBattery() { public TileEntityMachineBattery() {
super(2); super(2);
slots = new ItemStack[2]; slots = new ItemStack[2];
@ -84,24 +85,24 @@ public class TileEntityMachineBattery extends TileEntityMachineBase implements I
public boolean hasCustomInventoryName() { public boolean hasCustomInventoryName() {
return this.customName != null && this.customName.length() > 0; return this.customName != null && this.customName.length() > 0;
} }
public void setCustomName(String name) { public void setCustomName(String name) {
this.customName = name; this.customName = name;
} }
@Override @Override
public boolean isItemValidForSlot(int i, ItemStack stack) { public boolean isItemValidForSlot(int i, ItemStack stack) {
switch(i) { switch(i) {
case 0: case 0:
case 1: case 1:
if(stack.getItem() instanceof IBatteryItem) return true; if(stack.getItem() instanceof IBatteryItem) return true;
break; break;
} }
return true; return true;
} }
@Override @Override
public void readFromNBT(NBTTagCompound nbt) { public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt); super.readFromNBT(nbt);
@ -112,18 +113,18 @@ public class TileEntityMachineBattery extends TileEntityMachineBase implements I
this.lastRedstone = nbt.getByte("lastRedstone"); this.lastRedstone = nbt.getByte("lastRedstone");
this.priority = ConnectionPriority.values()[nbt.getByte("priority")]; this.priority = ConnectionPriority.values()[nbt.getByte("priority")];
} }
@Override @Override
public void writeToNBT(NBTTagCompound nbt) { public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt); super.writeToNBT(nbt);
nbt.setLong("power", power); nbt.setLong("power", power);
nbt.setShort("redLow", redLow); nbt.setShort("redLow", redLow);
nbt.setShort("redHigh", redHigh); nbt.setShort("redHigh", redHigh);
nbt.setByte("lastRedstone", lastRedstone); nbt.setByte("lastRedstone", lastRedstone);
nbt.setByte("priority", (byte)this.priority.ordinal()); nbt.setByte("priority", (byte)this.priority.ordinal());
} }
@Override @Override
public int[] getAccessibleSlotsFromSide(int p_94128_1_) { public int[] getAccessibleSlotsFromSide(int p_94128_1_) {
return p_94128_1_ == 0 ? slots_bottom : (p_94128_1_ == 1 ? slots_top : slots_side); return p_94128_1_ == 0 ? slots_bottom : (p_94128_1_ == 1 ? slots_top : slots_side);
@ -136,7 +137,7 @@ public class TileEntityMachineBattery extends TileEntityMachineBase implements I
@Override @Override
public boolean canExtractItem(int i, ItemStack itemStack, int j) { public boolean canExtractItem(int i, ItemStack itemStack, int j) {
if(itemStack.getItem() instanceof IBatteryItem) { if(itemStack.getItem() instanceof IBatteryItem) {
if(i == 0 && ((IBatteryItem)itemStack.getItem()).getCharge(itemStack) == 0) { if(i == 0 && ((IBatteryItem)itemStack.getItem()).getCharge(itemStack) == 0) {
return true; return true;
@ -145,79 +146,95 @@ public class TileEntityMachineBattery extends TileEntityMachineBase implements I
return true; return true;
} }
} }
return false; return false;
} }
public long getPowerRemainingScaled(long i) { public long getPowerRemainingScaled(long i) {
return (power * i) / this.getMaxPower(); return (power * i) / this.getMaxPower();
} }
public byte getComparatorPower() { public byte getComparatorPower() {
if(power == 0) return 0; if(power == 0) return 0;
double frac = (double) this.power / (double) this.getMaxPower() * 15D; double frac = (double) this.power / (double) this.getMaxPower() * 15D;
return (byte) (MathHelper.clamp_int((int) frac + 1, 0, 15)); //to combat eventual rounding errors with the FEnSU's stupid maxPower return (byte) (MathHelper.clamp_int((int) frac + 1, 0, 15)); //to combat eventual rounding errors with the FEnSU's stupid maxPower
} }
@Override @Override
public void updateEntity() { public void updateEntity() {
if(!worldObj.isRemote && worldObj.getBlock(xCoord, yCoord, zCoord) instanceof MachineBattery) { if(!worldObj.isRemote && worldObj.getBlock(xCoord, yCoord, zCoord) instanceof MachineBattery) {
if(priority == null || priority.ordinal() == 0 || priority.ordinal() == 4) { if(priority == null || priority.ordinal() == 0 || priority.ordinal() == 4) {
priority = ConnectionPriority.LOW; priority = ConnectionPriority.LOW;
} }
int mode = this.getRelevantMode(false); int mode = this.getRelevantMode(false);
if(this.node == null || this.node.expired) { long prevPower = this.power;
this.node = Nodespace.getNode(worldObj, xCoord, yCoord, zCoord); power = Library.chargeItemsFromTE(slots, 1, power, getMaxPower());
// In buffer mode, becomes a cable block and provides power to itself
// otherwise, acts like a regular power providing/accepting machine
if(mode == mode_buffer) {
if(this.node == null || this.node.expired) { if(this.node == null || this.node.expired) {
this.node = this.createNode();
Nodespace.createNode(worldObj, this.node); this.node = (PowerNode) UniNodespace.getNode(worldObj, xCoord, yCoord, zCoord, Nodespace.THE_POWER_PROVIDER);
if(this.node == null || this.node.expired) {
this.node = this.createNode();
UniNodespace.createNode(worldObj, this.node);
}
}
this.tryProvide(worldObj, xCoord, yCoord, zCoord, ForgeDirection.UNKNOWN);
if(node != null && node.hasValidNet()) node.net.addReceiver(this);
} else {
if(this.node != null) {
UniNodespace.destroyNode(worldObj, xCoord, yCoord, zCoord, Nodespace.THE_POWER_PROVIDER);
this.node = null;
}
for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
PowerNode dirNode = (PowerNode) UniNodespace.getNode(worldObj, xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ, Nodespace.THE_POWER_PROVIDER);
if(mode == mode_output) {
tryProvide(worldObj, xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ, dir);
} else {
if(dirNode != null && dirNode.hasValidNet()) dirNode.net.removeProvider(this);
}
if(mode == mode_input) {
if(dirNode != null && dirNode.hasValidNet()) dirNode.net.addReceiver(this);
} else {
if(dirNode != null && dirNode.hasValidNet()) dirNode.net.removeReceiver(this);
}
} }
} }
long prevPower = this.power;
power = Library.chargeItemsFromTE(slots, 1, power, getMaxPower());
if(mode == mode_output || mode == mode_buffer) {
this.tryProvide(worldObj, xCoord, yCoord, zCoord, ForgeDirection.UNKNOWN);
} else {
if(node != null && node.hasValidNet()) node.net.removeProvider(this);
}
byte comp = this.getComparatorPower(); byte comp = this.getComparatorPower();
if(comp != this.lastRedstone) if(comp != this.lastRedstone)
this.markDirty(); this.markDirty();
this.lastRedstone = comp; this.lastRedstone = comp;
if(mode == mode_input || mode == mode_buffer) {
if(node != null && node.hasValidNet()) node.net.addReceiver(this);
} else {
if(node != null && node.hasValidNet()) node.net.removeReceiver(this);
}
power = Library.chargeTEFromItems(slots, 0, power, getMaxPower()); power = Library.chargeTEFromItems(slots, 0, power, getMaxPower());
long avg = (power + prevPower) / 2; long avg = (power + prevPower) / 2;
this.delta = avg - this.log[0]; this.delta = avg - this.log[0];
for(int i = 1; i < this.log.length; i++) { for(int i = 1; i < this.log.length; i++) {
this.log[i - 1] = this.log[i]; this.log[i - 1] = this.log[i];
} }
this.log[19] = avg; this.log[19] = avg;
prevPowerState = power; prevPowerState = power;
this.networkPackNT(20); this.networkPackNT(20);
} }
} }
public void onNodeDestroyedCallback() { public void onNodeDestroyedCallback() {
this.node = null; this.node = null;
} }
@ -225,10 +242,10 @@ public class TileEntityMachineBattery extends TileEntityMachineBase implements I
@Override @Override
public void invalidate() { public void invalidate() {
super.invalidate(); super.invalidate();
if(!worldObj.isRemote) { if(!worldObj.isRemote) {
if(this.node != null) { if(this.node != null) {
Nodespace.destroyNode(worldObj, xCoord, yCoord, zCoord); UniNodespace.destroyNode(worldObj, xCoord, yCoord, zCoord, Nodespace.THE_POWER_PROVIDER);
} }
} }
} }
@ -237,7 +254,7 @@ public class TileEntityMachineBattery extends TileEntityMachineBase implements I
int mode = this.getRelevantMode(true); int mode = this.getRelevantMode(true);
return mode == mode_output || mode == mode_buffer ? this.getMaxPower() / 600 : 0; return mode == mode_output || mode == mode_buffer ? this.getMaxPower() / 600 : 0;
} }
@Override public long getReceiverSpeed() { @Override public long getReceiverSpeed() {
int mode = this.getRelevantMode(true); int mode = this.getRelevantMode(true);
return mode == mode_input || mode == mode_buffer ? this.getMaxPower() / 200 : 0; return mode == mode_input || mode == mode_buffer ? this.getMaxPower() / 200 : 0;
@ -269,30 +286,30 @@ public class TileEntityMachineBattery extends TileEntityMachineBase implements I
public long getPower() { public long getPower() {
return power; return power;
} }
private short modeCache = 0; private short modeCache = 0;
public short getRelevantMode(boolean useCache) { public short getRelevantMode(boolean useCache) {
if(useCache) return this.modeCache; if(useCache) return this.modeCache;
this.modeCache = worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord) ? this.redHigh : this.redLow; this.modeCache = worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord) ? this.redHigh : this.redLow;
return this.modeCache; return this.modeCache;
} }
private long bufferedMax; private long bufferedMax;
@Override @Override
public long getMaxPower() { public long getMaxPower() {
if(bufferedMax == 0) { if(bufferedMax == 0) {
bufferedMax = ((MachineBattery)worldObj.getBlock(xCoord, yCoord, zCoord)).maxPower; bufferedMax = ((MachineBattery)worldObj.getBlock(xCoord, yCoord, zCoord)).maxPower;
} }
return bufferedMax; return bufferedMax;
} }
@Override public boolean canConnect(ForgeDirection dir) { return true; } @Override public boolean canConnect(ForgeDirection dir) { return true; }
@Override public void setPower(long power) { this.power = power; } @Override public void setPower(long power) { this.power = power; }
@Override public ConnectionPriority getPriority() { return this.priority; } @Override public ConnectionPriority getPriority() { return this.priority; }
// do some opencomputer stuff // do some opencomputer stuff
@Override @Override
@Optional.Method(modid = "OpenComputers") @Optional.Method(modid = "OpenComputers")

View File

@ -2,7 +2,7 @@ package com.hbm.tileentity.machine.storage;
import api.hbm.energymk2.IEnergyReceiverMK2.ConnectionPriority; import api.hbm.energymk2.IEnergyReceiverMK2.ConnectionPriority;
import api.hbm.fluidmk2.FluidNode; import api.hbm.fluidmk2.FluidNode;
import api.hbm.fluidmk2.IFluidBufferTransceiverMK2; import api.hbm.fluidmk2.IFluidStandardTransceiverMK2;
import com.hbm.blocks.BlockDummyable; import com.hbm.blocks.BlockDummyable;
import com.hbm.blocks.ModBlocks; import com.hbm.blocks.ModBlocks;
@ -54,10 +54,9 @@ import java.util.List;
import java.util.Random; import java.util.Random;
@Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "opencomputers")}) @Optional.InterfaceList({@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "opencomputers")})
public class TileEntityMachineFluidTank extends TileEntityMachineBase implements SimpleComponent, OCComponent, IFluidBufferTransceiverMK2, IPersistentNBT, IOverpressurable, IGUIProvider, IRepairable, IFluidCopiable { public class TileEntityMachineFluidTank extends TileEntityMachineBase implements SimpleComponent, OCComponent, IFluidStandardTransceiverMK2, IPersistentNBT, IOverpressurable, IGUIProvider, IRepairable, IFluidCopiable {
protected FluidNode node; protected FluidNode node;
protected FluidType lastType;
public FluidTank tank; public FluidTank tank;
public short mode = 0; public short mode = 0;
@ -114,27 +113,42 @@ public class TileEntityMachineFluidTank extends TileEntityMachineBase implements
this.markChanged(); this.markChanged();
} }
if(this.node == null || this.node.expired || tank.getTankType() != lastType) { // In buffer mode, acts like a pipe block, providing fluid to its own node
// otherwise, it is a regular providing/receiving machine, blocking further propagation
if(mode == 1) {
if(this.node == null || this.node.expired) {
this.node = (FluidNode) UniNodespace.getNode(worldObj, xCoord, yCoord, zCoord, tank.getTankType().getNetworkProvider()); this.node = (FluidNode) UniNodespace.getNode(worldObj, xCoord, yCoord, zCoord, tank.getTankType().getNetworkProvider());
if(this.node == null || this.node.expired || tank.getTankType() != lastType) { if(this.node == null || this.node.expired) {
this.node = this.createNode(tank.getTankType()); this.node = this.createNode(tank.getTankType());
UniNodespace.createNode(worldObj, this.node); UniNodespace.createNode(worldObj, this.node);
lastType = tank.getTankType(); }
} }
}
if(mode == 2 || mode == 1) {
this.tryProvide(tank, worldObj, xCoord, yCoord, zCoord, ForgeDirection.UNKNOWN); this.tryProvide(tank, worldObj, xCoord, yCoord, zCoord, ForgeDirection.UNKNOWN);
} else {
if(node != null && node.hasValidNet()) node.net.removeProvider(this);
}
if(mode == 0 || mode == 1) {
if(node != null && node.hasValidNet()) node.net.addReceiver(this); if(node != null && node.hasValidNet()) node.net.addReceiver(this);
} else { } else {
if(node != null && node.hasValidNet()) node.net.removeReceiver(this); if(this.node != null) {
UniNodespace.destroyNode(worldObj, xCoord, yCoord, zCoord, tank.getTankType().getNetworkProvider());
this.node = null;
}
for(DirPos pos : getConPos()) {
FluidNode dirNode = (FluidNode) UniNodespace.getNode(worldObj, pos.getX(), pos.getY(), pos.getZ(), tank.getTankType().getNetworkProvider());
if(mode == 2) {
tryProvide(tank, worldObj, pos.getX(), pos.getY(), pos.getZ(), pos.getDir());
} else {
if(dirNode != null && dirNode.hasValidNet()) dirNode.net.removeProvider(this);
}
if(mode == 0) {
if(dirNode != null && dirNode.hasValidNet()) dirNode.net.addReceiver(this);
} else {
if(dirNode != null && dirNode.hasValidNet()) dirNode.net.removeReceiver(this);
}
}
} }
tank.loadTank(2, 3, slots); tank.loadTank(2, 3, slots);