workee
This commit is contained in:
@@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.GTValues;
|
||||
import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity;
|
||||
import com.gregtechceu.gtceu.api.capability.ITurbineMachine;
|
||||
import com.gregtechceu.gtceu.api.capability.compat.FeCompat;
|
||||
import com.gregtechceu.gtceu.api.item.tool.GTToolType;
|
||||
import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity;
|
||||
import com.gregtechceu.gtceu.api.machine.MachineDefinition;
|
||||
import com.gregtechceu.gtceu.api.machine.MetaMachine;
|
||||
@@ -33,27 +34,31 @@ import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
import com.imbgt.kineticbridge.machine.KineticOutputHatchPartMachine;
|
||||
import com.simibubi.create.content.kinetics.KineticNetwork;
|
||||
import com.simibubi.create.content.kinetics.base.GeneratingKineticBlockEntity;
|
||||
import com.simibubi.create.content.kinetics.base.IRotate;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.imbgt.kineticbridge.KineticBridge;
|
||||
|
||||
/**
|
||||
* Block entity that bridges a GTCEu meta machine with Create's kinetic network.
|
||||
*/
|
||||
public class KineticOutputHatchBlockEntity extends GeneratingKineticBlockEntity
|
||||
implements IMachineBlockEntity, IManaged {
|
||||
implements IMachineBlockEntity, IManaged {
|
||||
|
||||
private static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(
|
||||
KineticOutputHatchBlockEntity.class);
|
||||
private static final float CREATE_MAX_RPM = KineticOutputHatchPartMachine.TARGET_RPM;
|
||||
private static final float TURBINE_REFERENCE_RPM = 7000.0f;
|
||||
private static final float MIN_GENERATED_RPM = 1.0f;
|
||||
// FE generated per stress unit per RPM tick, aligned with Create: New Age defaults
|
||||
private static final double SU_TO_FE_ENERGY = 15.0d / 512.0d;
|
||||
// FE generated per stress unit per RPM tick, aligned with Create: New Age
|
||||
// defaults
|
||||
private static final double SU_TO_FE = 15.0d / 512.0d;
|
||||
private static final float EPSILON = 1.0e-4f;
|
||||
private static final float TARGET_RPM = KineticOutputHatchPartMachine.TARGET_RPM;
|
||||
|
||||
private final MultiManagedStorage managedStorage = new MultiManagedStorage();
|
||||
private final FieldManagedStorage syncStorage = new FieldManagedStorage(this);
|
||||
@@ -61,9 +66,8 @@ public class KineticOutputHatchBlockEntity extends GeneratingKineticBlockEntity
|
||||
private MachineRenderState renderState;
|
||||
private final long offset = GTValues.RNG.nextInt(20);
|
||||
|
||||
private float advertisedCapacity = 0.0f;
|
||||
private float generatedSpeed = 0.0f;
|
||||
private long lastTickPower = 0L;
|
||||
private float lastGeneratedSpeed = 0.0f;
|
||||
private boolean metaUnloaded = false;
|
||||
|
||||
public KineticOutputHatchBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState blockState) {
|
||||
@@ -77,20 +81,19 @@ public class KineticOutputHatchBlockEntity extends GeneratingKineticBlockEntity
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (level == null) {
|
||||
if (level == null || level.isClientSide())
|
||||
return;
|
||||
|
||||
MetaMachine mm = getMetaMachine();
|
||||
if (!(mm instanceof KineticOutputHatchPartMachine hatch)) {
|
||||
this.generatedSpeed = 0;
|
||||
finalizeKinetics();
|
||||
return;
|
||||
}
|
||||
|
||||
if (level.isClientSide()) {
|
||||
metaMachine.clientTick();
|
||||
return;
|
||||
}
|
||||
|
||||
var machine = getMetaMachine();
|
||||
if (!(machine instanceof KineticOutputHatchPartMachine hatch)) {
|
||||
updateKinetics(0.0f, 0.0f, 0L);
|
||||
metaMachine.serverTick();
|
||||
return;
|
||||
var ec = getEc();
|
||||
if (ec != null) {
|
||||
ec.setEnergyStored(0);
|
||||
}
|
||||
|
||||
ITurbineMachine turbine = null;
|
||||
@@ -100,104 +103,74 @@ public class KineticOutputHatchBlockEntity extends GeneratingKineticBlockEntity
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int rotorSpeed = turbine != null ? Math.max(0, turbine.getRotorSpeed()) : hatch.getRotorSpeed();
|
||||
int maxRotorSpeed = turbine != null ? Math.max(1, turbine.getMaxRotorHolderSpeed()) : hatch.getMaxRotorSpeed();
|
||||
float rpmScale = 0.0f;
|
||||
if (rotorSpeed > 0) {
|
||||
rpmScale = Math.min(1.0f, Math.max(0.0f, rotorSpeed / TURBINE_REFERENCE_RPM));
|
||||
}
|
||||
hatch.updateRotorTelemetry(rotorSpeed, maxRotorSpeed);
|
||||
|
||||
NotifiableEnergyContainer container = hatch.getEnergyContainer();
|
||||
long voltage = container.getOutputVoltage();
|
||||
long amperage = container.getOutputAmperage();
|
||||
long theoreticalPower = Math.max(0L, voltage * amperage);
|
||||
|
||||
if (theoreticalPower <= 0 || rpmScale <= 0.0f) {
|
||||
updateKinetics(0.0f, 0.0f, 0L);
|
||||
metaMachine.serverTick();
|
||||
if (turbine == null) {
|
||||
this.generatedSpeed = 0;
|
||||
finalizeKinetics();
|
||||
return;
|
||||
}
|
||||
int rotorSpeed = turbine.getRotorSpeed();
|
||||
int maxRotorSpeed = turbine.getMaxRotorHolderSpeed();
|
||||
|
||||
float previousCapacity = advertisedCapacity;
|
||||
float previousSpeed = generatedSpeed;
|
||||
float nextSpeed = ((float) rotorSpeed / (float) maxRotorSpeed) * TARGET_RPM;
|
||||
this.generatedSpeed = (float) Math.ceil(nextSpeed);
|
||||
|
||||
float nextSpeed = CREATE_MAX_RPM * rpmScale;
|
||||
if (nextSpeed > 0.0f && nextSpeed < MIN_GENERATED_RPM) {
|
||||
nextSpeed = MIN_GENERATED_RPM;
|
||||
finalizeKinetics();
|
||||
}
|
||||
|
||||
private NotifiableEnergyContainer getEc() {
|
||||
MetaMachine mm = getMetaMachine();
|
||||
if (!(mm instanceof KineticOutputHatchPartMachine hatch)) {
|
||||
return null;
|
||||
}
|
||||
return hatch.getEnergyContainer();
|
||||
|
||||
}
|
||||
|
||||
private void finalizeKinetics() {
|
||||
|
||||
if (Math.abs(this.lastGeneratedSpeed - this.generatedSpeed) >= 1) {
|
||||
updateGeneratedRotation();
|
||||
this.lastGeneratedSpeed = this.generatedSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateGeneratedRotation() {
|
||||
if (level == null || level.isClientSide)
|
||||
return;
|
||||
|
||||
float speed = getGeneratedSpeed();
|
||||
float prev = this.lastGeneratedSpeed; // add a private field or reuse your cached prev if you keep one
|
||||
|
||||
if (prev != speed) {
|
||||
if (!hasSource()) {
|
||||
var before = IRotate.SpeedLevel.of(prev);
|
||||
var after = IRotate.SpeedLevel.of(speed);
|
||||
if (before != after)
|
||||
effects.queueRotationIndicators();
|
||||
}
|
||||
// this attaches/creates the network and propagates RPM
|
||||
applyNewSpeed(prev, speed);
|
||||
}
|
||||
|
||||
double speedFraction = Math.min(1.0d, nextSpeed / CREATE_MAX_RPM);
|
||||
int euToFeRatio = Math.max(1, FeCompat.ratio(false));
|
||||
double theoreticalEuAtSpeed = theoreticalPower * speedFraction;
|
||||
double theoreticalFeAtSpeed = theoreticalEuAtSpeed * euToFeRatio;
|
||||
double absSpeed = Math.max(MIN_GENERATED_RPM, Math.abs(nextSpeed));
|
||||
double theoreticalStressCapacity = absSpeed > 0.0d ?
|
||||
theoreticalFeAtSpeed / (absSpeed * SU_TO_FE_ENERGY) : 0.0d;
|
||||
double theoreticalStress = theoreticalStressCapacity * absSpeed;
|
||||
|
||||
double networkStress = Math.max(0.0d, this.stress);
|
||||
double networkCapacity = Math.max(0.0d, this.capacity);
|
||||
|
||||
double requestedStress = theoreticalStress;
|
||||
if (networkCapacity > 0.0d) {
|
||||
double shareRatio = theoreticalStress / networkCapacity;
|
||||
requestedStress = Math.min(theoreticalStress, networkStress * shareRatio);
|
||||
} else if (networkStress <= 0.0d) {
|
||||
requestedStress = 0.0d;
|
||||
}
|
||||
|
||||
double requestedFe = requestedStress * SU_TO_FE_ENERGY;
|
||||
double requestedEu = requestedFe / euToFeRatio;
|
||||
|
||||
double targetEu = Math.min(theoreticalEuAtSpeed, requestedEu);
|
||||
long stored = container.getEnergyStored();
|
||||
long maxAvailable = Math.min(stored, theoreticalPower);
|
||||
if (maxAvailable > 0) {
|
||||
targetEu = Math.min(targetEu, maxAvailable);
|
||||
}
|
||||
|
||||
long energyBudget = 0L;
|
||||
if (targetEu > 0.0d) {
|
||||
energyBudget = Math.max(1L, (long) Math.ceil(targetEu));
|
||||
if (maxAvailable > 0) {
|
||||
energyBudget = Math.min(energyBudget, maxAvailable);
|
||||
if (speed != 0 && hasNetwork()) {
|
||||
KineticNetwork net = getOrCreateNetwork();
|
||||
if (net != null) {
|
||||
// your advertisedCapacity is TOTAL SU at current speed
|
||||
net.updateCapacityFor(this, calculateAddedStressCapacity());
|
||||
// keep Create’s bookkeeping in sync
|
||||
notifyStressCapacityChange(calculateAddedStressCapacity());
|
||||
// generators apply 0 stress
|
||||
net.updateStressFor(this, 0f);
|
||||
net.updateStress();
|
||||
}
|
||||
}
|
||||
|
||||
long drained = energyBudget > 0 ? container.removeEnergy(energyBudget) : 0L;
|
||||
onSpeedChanged(prev);
|
||||
sendData();
|
||||
|
||||
double advertised = theoreticalStressCapacity;
|
||||
if (energyBudget > drained && requestedStress > 0.0d) {
|
||||
double drainedFe = FeCompat.toFeLong(drained, euToFeRatio);
|
||||
double actualCapacity = drainedFe / (absSpeed * absSpeed * SU_TO_FE_ENERGY);
|
||||
advertised = Math.min(theoreticalStressCapacity, actualCapacity);
|
||||
}
|
||||
|
||||
float nextCapacity = (float) Math.max(0.0d, advertised);
|
||||
|
||||
updateKinetics(nextSpeed, nextCapacity, drained);
|
||||
|
||||
boolean speedChanged = Math.abs(previousSpeed - generatedSpeed) > EPSILON;
|
||||
boolean capacityChanged = Math.abs(previousCapacity - advertisedCapacity) > EPSILON;
|
||||
|
||||
if (speedChanged) {
|
||||
updateGeneratedRotation();
|
||||
} else if (capacityChanged && hasNetwork()) {
|
||||
notifyStressCapacityChange(advertisedCapacity);
|
||||
getOrCreateNetwork().updateStressFor(this, calculateStressApplied());
|
||||
getOrCreateNetwork().updateStress();
|
||||
sendData();
|
||||
}
|
||||
|
||||
metaMachine.serverTick();
|
||||
}
|
||||
|
||||
private void updateKinetics(float speed, float capacityPerSpeed, long drainedPower) {
|
||||
this.generatedSpeed = speed;
|
||||
this.advertisedCapacity = capacityPerSpeed;
|
||||
this.lastTickPower = drainedPower;
|
||||
// remember last speed locally
|
||||
this.lastGeneratedSpeed = speed;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -207,7 +180,16 @@ public class KineticOutputHatchBlockEntity extends GeneratingKineticBlockEntity
|
||||
|
||||
@Override
|
||||
public float calculateAddedStressCapacity() {
|
||||
return advertisedCapacity;
|
||||
var ec = getEc();
|
||||
if (ec == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long euMax = Math.max(0L, ec.getOutputVoltage() * ec.getOutputAmperage());
|
||||
double feMax = FeCompat.toFeLong(euMax, FeCompat.ratio(false));
|
||||
double suMAx = feMax * SU_TO_FE;
|
||||
|
||||
return (float) suMAx;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -222,16 +204,12 @@ public class KineticOutputHatchBlockEntity extends GeneratingKineticBlockEntity
|
||||
}
|
||||
super.read(tag, clientPacket);
|
||||
this.generatedSpeed = tag.getFloat("GeneratedSpeed");
|
||||
this.advertisedCapacity = tag.getFloat("StressCapacity");
|
||||
this.lastTickPower = tag.getLong("LastPower");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void write(CompoundTag tag, boolean clientPacket) {
|
||||
super.write(tag, clientPacket);
|
||||
tag.putFloat("GeneratedSpeed", generatedSpeed);
|
||||
tag.putFloat("StressCapacity", advertisedCapacity);
|
||||
tag.putLong("LastPower", lastTickPower);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -245,12 +223,10 @@ public class KineticOutputHatchBlockEntity extends GeneratingKineticBlockEntity
|
||||
Component.literal(FormattingUtil.formatNumbers(maxPower))
|
||||
.withStyle(ChatFormatting.AQUA)));
|
||||
tooltip.add(Component.translatable("tooltip.kineticbridge.max_stress",
|
||||
Component.literal(FormattingUtil.formatNumbers(Math.max(0.0f, advertisedCapacity)))
|
||||
Component.literal(FormattingUtil.formatNumbers(Math.max(0.0f, calculateAddedStressCapacity())))
|
||||
.withStyle(ChatFormatting.AQUA),
|
||||
Component.literal(String.format("%.0f", (double) CREATE_MAX_RPM))
|
||||
Component.literal(String.format("%.0f", (double) speed))
|
||||
.withStyle(ChatFormatting.AQUA)));
|
||||
tooltip.add(Component.translatable("tooltip.kineticbridge.last_tick_power",
|
||||
Component.literal(FormattingUtil.formatNumbers(lastTickPower)).withStyle(ChatFormatting.AQUA)));
|
||||
return true;
|
||||
}
|
||||
return added;
|
||||
@@ -294,6 +270,8 @@ public class KineticOutputHatchBlockEntity extends GeneratingKineticBlockEntity
|
||||
@Override
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
if (!level.isClientSide)
|
||||
updateGeneratedRotation();
|
||||
metaMachine.onLoad();
|
||||
}
|
||||
|
||||
@@ -318,15 +296,15 @@ public class KineticOutputHatchBlockEntity extends GeneratingKineticBlockEntity
|
||||
|
||||
@Override
|
||||
public boolean shouldRenderGrid(Player player, BlockPos pos, BlockState state, ItemStack held,
|
||||
Set<com.gregtechceu.gtceu.api.item.tool.GTToolType> toolTypes) {
|
||||
Set<GTToolType> toolTypes) {
|
||||
return metaMachine.shouldRenderGrid(player, pos, state, held, toolTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable com.lowdragmc.lowdraglib.gui.texture.ResourceTexture sideTips(Player player, BlockPos pos,
|
||||
BlockState state,
|
||||
Set<com.gregtechceu.gtceu.api.item.tool.GTToolType> toolTypes,
|
||||
Direction side) {
|
||||
BlockState state,
|
||||
Set<GTToolType> toolTypes,
|
||||
Direction side) {
|
||||
return metaMachine.sideTips(player, pos, state, toolTypes, side);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ public final class KineticBridgeDatagen {
|
||||
KineticBridge.REGISTRATE.addDataGenerator(ProviderType.LANG, provider -> {
|
||||
provider.add("tooltip.kineticbridge.max_power", "Max Output: %s EU/t");
|
||||
provider.add("tooltip.kineticbridge.max_stress", "Active Capacity: %s SU @ %s RPM");
|
||||
provider.add("tooltip.kineticbridge.last_tick_power", "Last Tick Draw: %s EU");
|
||||
provider.add("kineticbridge.tooltip.rpm", "Outputs Create rotation at %s RPM");
|
||||
provider.add("kineticbridge.tooltip.capacity", "Provides up to %s SU (~%s EU/t)");
|
||||
});
|
||||
|
||||
@@ -25,27 +25,7 @@ public class KineticOutputHatchPartMachine extends EnergyHatchPartMachine {
|
||||
return energyContainer.getOutputVoltage() * energyContainer.getOutputAmperage();
|
||||
}
|
||||
|
||||
public float getTargetRpm() {
|
||||
return TARGET_RPM;
|
||||
}
|
||||
|
||||
public NotifiableEnergyContainer getEnergyContainer() {
|
||||
return energyContainer;
|
||||
}
|
||||
|
||||
private int reportedRotorSpeed;
|
||||
private int maxRotorSpeed = 1;
|
||||
|
||||
public void updateRotorTelemetry(int rotorSpeed, int maxSpeed) {
|
||||
this.reportedRotorSpeed = Math.max(0, rotorSpeed);
|
||||
this.maxRotorSpeed = Math.max(1, maxSpeed);
|
||||
}
|
||||
|
||||
public int getRotorSpeed() {
|
||||
return reportedRotorSpeed;
|
||||
}
|
||||
|
||||
public int getMaxRotorSpeed() {
|
||||
return Math.max(1, maxRotorSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user