Skip to content

Commit b2e3bee

Browse files
committed
Kugelblitz energy generation
1 parent 876844c commit b2e3bee

File tree

15 files changed

+289
-126
lines changed

15 files changed

+289
-126
lines changed

src/generated/resources/assets/nuclearcraft/lang/en_us.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1973,6 +1973,11 @@
19731973
"itemGroup.nuclearcraft_items": "NuclearCraft Items",
19741974
"itemGroup.nuclearcraft_kugelblitz": "NuclearCraft Kugelblitz",
19751975
"itemGroup.nuclearcraft_turbine": "NuclearCraft Turbine",
1976+
"label.kugelblitz.blackhole_mass": "Blackhole Mass: %s",
1977+
"label.kugelblitz.energy_gen": "FE Gen",
1978+
"label.kugelblitz.evaporation": "Evaporation Rate: %s",
1979+
"label.kugelblitz.frequency": "Quantum Frequency: %s",
1980+
"label.kugelblitz.transformation": "Transformation",
19761981
"leacher.tooltip.invalid_pump": "Pump in the corner not found",
19771982
"leacher.tooltip.valid_pump": "Pump - Ok",
19781983
"message.heat_sink.invalid0": "Not sure if it's valid",

src/main/java/igentuman/nc/block/entity/MultiblockControllerBE.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import igentuman.nc.handler.sided.SidedContentHandler;
55
import igentuman.nc.handler.sided.capability.ItemCapabilityHandler;
66
import igentuman.nc.multiblock.AbstractNCMultiblock;
7+
import igentuman.nc.multiblock.MultiblockHandler;
78
import igentuman.nc.multiblock.ValidationResult;
89
import igentuman.nc.util.CustomEnergyStorage;
910
import igentuman.nc.util.annotation.NBTField;
@@ -123,6 +124,14 @@ public void load(CompoundTag tag) {
123124
}
124125
}
125126

127+
@Override
128+
public void setChanged() {
129+
super.setChanged();
130+
wasUpdated = true;
131+
changed = true;
132+
MultiblockHandler.addIgnoreToUpdate(getBlockPos());
133+
}
134+
126135
@Override
127136
public void saveAdditional(CompoundTag tag) {
128137
super.saveAdditional(tag);

src/main/java/igentuman/nc/block/entity/kugelblitz/BlackHoleBE.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66
import net.minecraft.core.BlockPos;
77
import net.minecraft.core.particles.ParticleTypes;
88
import net.minecraft.sounds.SoundSource;
9+
import net.minecraft.world.damagesource.DamageSource;
10+
import net.minecraft.world.damagesource.DamageSources;
911
import net.minecraft.world.entity.Entity;
1012
import net.minecraft.world.entity.LivingEntity;
1113
import net.minecraft.world.entity.item.ItemEntity;
14+
import net.minecraft.world.level.Level;
1215
import net.minecraft.world.level.block.Block;
1316
import net.minecraft.world.level.block.state.BlockState;
1417
import net.minecraft.world.phys.AABB;
@@ -18,12 +21,14 @@
1821
import static igentuman.nc.block.kugelblitz.BlackHoleBlock.ACTIVE;
1922
import static igentuman.nc.setup.registration.NCSounds.BLACKHOLE_IDLE;
2023
import static igentuman.nc.setup.registration.NCSounds.BLACKHOLE_SPAWN;
24+
import static net.minecraft.world.level.block.Blocks.AIR;
2125

2226
public class BlackHoleBE extends NuclearCraftBE {
2327

2428
public static String NAME = "black_hole";
2529
public float scale = 0.3f;
26-
30+
public static long MIN_MASS = 100_000_000L;
31+
public static long MAX_MASS = 100_000_000_000L;
2732
@NBTField
2833
public boolean isInitialized = false;
2934
@NBTField
@@ -144,4 +149,15 @@ private void handleClosestEntities() {
144149
public float getBlackholeScale() {
145150
return scale;
146151
}
152+
153+
public void meltdown() {
154+
getLevel().explode(null, getBlockPos().getX(), getBlockPos().getY(), getBlockPos().getZ(), 10, Level.ExplosionInteraction.TNT);
155+
setRemoved();
156+
getLevel().setBlockAndUpdate(getBlockPos(), AIR.defaultBlockState());
157+
}
158+
159+
public void evaporate() {
160+
setRemoved();
161+
getLevel().setBlockAndUpdate(getBlockPos(), AIR.defaultBlockState());
162+
}
147163
}

src/main/java/igentuman/nc/block/entity/kugelblitz/ChamberTerminalBE.java

Lines changed: 104 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,23 @@
22

33
import igentuman.nc.NuclearCraft;
44
import igentuman.nc.block.entity.MultiblockControllerBE;
5-
import igentuman.nc.block.entity.fusion.FusionCoreBE;
6-
import igentuman.nc.client.sound.SoundHandler;
75
import igentuman.nc.compat.cc.KugelblitzPeripheral;
86
import igentuman.nc.handler.sided.SidedContentHandler;
97
import igentuman.nc.handler.sided.SlotModePair;
108
import igentuman.nc.handler.sided.capability.ItemCapabilityHandler;
9+
import igentuman.nc.multiblock.MultiblockHandler;
1110
import igentuman.nc.multiblock.ValidationResult;
1211
import igentuman.nc.multiblock.kugelblitz.KugelblitzMultiblock;
1312
import igentuman.nc.multiblock.kugelblitz.KugelblitzRegistration;
14-
import igentuman.nc.recipes.NcRecipeType;
15-
import igentuman.nc.recipes.RecipeInfo;
1613
import igentuman.nc.recipes.ingredient.FluidStackIngredient;
1714
import igentuman.nc.recipes.ingredient.ItemStackIngredient;
15+
import igentuman.nc.recipes.ingredient.creator.IngredientCreatorAccess;
1816
import igentuman.nc.recipes.type.NcRecipe;
1917
import igentuman.nc.util.CustomEnergyStorage;
2018
import igentuman.nc.util.annotation.NBTField;
21-
import net.minecraft.client.Minecraft;
2219
import net.minecraft.core.BlockPos;
2320
import net.minecraft.core.Direction;
24-
import net.minecraft.nbt.CompoundTag;
25-
import net.minecraft.network.Connection;
26-
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
2721
import net.minecraft.resources.ResourceLocation;
28-
import net.minecraft.sounds.SoundSource;
2922
import net.minecraft.world.item.ItemStack;
3023
import net.minecraft.world.level.block.Block;
3124
import net.minecraft.world.level.block.state.BlockState;
@@ -45,10 +38,14 @@
4538
import java.util.List;
4639
import java.util.Objects;
4740

41+
import static igentuman.nc.block.entity.kugelblitz.BlackHoleBE.MAX_MASS;
42+
import static igentuman.nc.block.entity.kugelblitz.BlackHoleBE.MIN_MASS;
4843
import static igentuman.nc.block.fission.FissionControllerBlock.POWERED;
4944
import static igentuman.nc.compat.GlobalVars.CATALYSTS;
50-
import static igentuman.nc.multiblock.turbine.TurbineRegistration.TURBINE_BLOCKS;
51-
import static igentuman.nc.setup.registration.NCSounds.FISSION_REACTOR;
45+
import static igentuman.nc.content.materials.Materials.subliquid_matter;
46+
import static igentuman.nc.handler.config.CommonConfig.ENERGY_GENERATION;
47+
import static igentuman.nc.handler.config.KugelblitzConfig.KUGELBLITZ_CONFIG;
48+
import static igentuman.nc.multiblock.kugelblitz.KugelblitzRegistration.KUGELBLITZ_BE;
5249
import static igentuman.nc.util.ModUtil.isCcLoaded;
5350

5451
public class ChamberTerminalBE extends MultiblockControllerBE {
@@ -58,30 +55,39 @@ public class ChamberTerminalBE extends MultiblockControllerBE {
5855
public final CustomEnergyStorage energyStorage;
5956
private LazyOptional<KugelblitzPeripheral> peripheralCap;
6057
protected final LazyOptional<IEnergyStorage> energy;
58+
59+
@NBTField
60+
public long feeding = 0;
6161
@NBTField
6262
public int energyPerTick = 0;
6363
@NBTField
64-
public boolean powered = false;
64+
public double efficiency = 0;
65+
@NBTField
66+
public long mass = 0;
6567
@NBTField
66-
protected boolean forceShutdown = false;
68+
public int evaporation = 0;
6769
@NBTField
68-
public double efficiency = 0;
70+
public byte frequency = 0;
71+
@NBTField
72+
public int energyConvertionRate = 50;
73+
@NBTField
74+
public boolean controllerEnabled = false;
75+
76+
6977
protected Direction facing;
7078
public Recipe recipe;
7179
public HashMap<String, Recipe> cachedRecipes = new HashMap<>();
7280
private List<FluidStack> allowedInputs;
7381

74-
7582
public ChamberTerminalBE(BlockPos pPos, BlockState pBlockState) {
76-
super(KugelblitzRegistration.KUGELBLITZ_BE.get(NAME).get(), pPos, pBlockState);
83+
super(KUGELBLITZ_BE.get(NAME).get(), pPos, pBlockState);
7784
energyStorage = createEnergy();
7885
energy = LazyOptional.of(() -> energyStorage);
7986
multiblock = new KugelblitzMultiblock(this);
8087
contentHandler = new SidedContentHandler(
81-
0, 0,
82-
1, 1, 1000, 10000);
88+
1, 1,
89+
1, 0, 1000);
8390
contentHandler.fluidCapability.setGlobalMode(0, SlotModePair.SlotMode.INPUT);
84-
contentHandler.fluidCapability.setGlobalMode(1, SlotModePair.SlotMode.OUTPUT);
8591
contentHandler.setBlockEntity(this);
8692
contentHandler.setAllowedInputFluids(0, this::getAllowedInputFluids);
8793
}
@@ -107,7 +113,7 @@ protected void onEnergyChanged() {
107113

108114
@Override
109115
public Recipe getRecipe() {
110-
if(contentHandler().fluidCapability.tanks.get(0).isEmpty()) return null;
116+
if(contentHandler().itemHandler.getStackInSlot(0).isEmpty()) return null;
111117
//TODO implement
112118
return null;
113119
}
@@ -126,7 +132,7 @@ public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable D
126132
return contentHandler().getFluidCapability(null);
127133
}
128134
if (cap == ForgeCapabilities.ENERGY) {
129-
return energy.cast();
135+
return getEnergy().cast();
130136
}
131137
if(isCcLoaded()) {
132138
if(cap == dan200.computercraft.shared.Capabilities.CAPABILITY_PERIPHERAL) {
@@ -136,19 +142,17 @@ public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable D
136142
return super.getCapability(cap, side);
137143
}
138144

139-
protected void playRunningSound() {
140-
if(isRemoved() || (currentSound != null && !currentSound.getLocation().equals(FISSION_REACTOR.get().getLocation()))) {
141-
SoundHandler.stopTileSound(getBlockPos());
142-
currentSound = null;
143-
}
144-
if((currentSound == null || !Minecraft.getInstance().getSoundManager().isActive(currentSound))) {
145-
if(currentSound != null && currentSound.getLocation().equals(FISSION_REACTOR.get().getLocation())) {
146-
return;
145+
@Override
146+
public void handleSliderUpdate(int buttonId, int ratio) {
147+
switch(buttonId) {
148+
case 0 -> {
149+
energyConvertionRate = ratio;
150+
}
151+
case 1 -> {
152+
frequency = (byte) ratio;
147153
}
148-
149-
playSoundCooldown = 20;
150-
currentSound = SoundHandler.startTileSound(FISSION_REACTOR.get(), SoundSource.BLOCKS, 0.2f, level.getRandom(), getBlockPos());
151154
}
155+
setChanged();
152156
}
153157

154158
public void tickClient() {
@@ -158,7 +162,6 @@ public void tickClient() {
158162
}
159163
if(energyPerTick > 0) {
160164
//spawnSteamParticles();
161-
playRunningSound();
162165
}
163166
}
164167
protected int reValidateCounter = 0;
@@ -169,45 +172,86 @@ public void tickServer() {
169172
}
170173
changed = false;
171174
super.tickServer();
172-
boolean wasPowered = powered;
175+
boolean wasEnabled = controllerEnabled;
173176
handleValidation();
174-
trackChanges(wasPowered, powered);
175-
controllerEnabled = (hasRedstoneSignal() || controllerEnabled) && this.getMultiblock().isFormed();
176-
controllerEnabled = !forceShutdown && controllerEnabled;
177+
controllerEnabled = getMultiblock().isFormed() && hasBlackhole();
177178

178-
if (this.getMultiblock().isFormed()) {
179+
if (controllerEnabled) {
179180
trackChanges(contentHandler.tick());
180-
if(controllerEnabled) {
181-
powered = true;
182-
//powered = processRecipe();
183-
trackChanges(powered);
184-
} else {
185-
powered = false;
186-
}
181+
long wasMass = mass;
182+
updateBlackholeMass();
183+
trackChanges(false, wasMass != mass);
187184
handleMeltdown();
188185
}
189-
refreshCacheFlag = !this.getMultiblock().isFormed();
190-
if(wasPowered != powered) {
191-
level.setBlockAndUpdate(worldPosition, getBlockState().setValue(POWERED, powered));
186+
refreshCacheFlag = !getMultiblock().isFormed();
187+
if(wasEnabled != controllerEnabled) {
188+
setChanged();
192189
}
193190
if(refreshCacheFlag || changed) {
194191
try {
195-
level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState().setValue(POWERED, powered), Block.UPDATE_ALL);
192+
MultiblockHandler.addIgnoreToUpdate(getBlockPos());
193+
level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState().setValue(POWERED, controllerEnabled), Block.UPDATE_ALL);
194+
level.setBlockAndUpdate(worldPosition, getBlockState().setValue(POWERED, controllerEnabled));
196195
} catch (NullPointerException ignored) {}
197196
}
197+
}
198198

199-
controllerEnabled = false;
199+
public boolean hasBlackhole() {
200+
return getMultiblock().getBlackHole() instanceof BlackHoleBE;
201+
}
202+
203+
private void updateBlackholeMass()
204+
{
205+
if (!hasBlackhole()) {
206+
mass = 0;
207+
evaporation = 0;
208+
energyPerTick = 0;
209+
return;
210+
}
211+
feeding = contentHandler().fluidCapability.getFluidInSlot(0).getAmount() * 10L;
212+
mass += feeding;
213+
contentHandler.fluidCapability.voidSlot(0);
214+
updateEnergyGeneration();
215+
updateEvaporation();
216+
mass -= evaporation;
217+
if (mass < MIN_MASS) {
218+
doEvaporation();
219+
}
220+
}
221+
222+
private void updateEnergyGeneration() {
223+
int wasEnergy = energyPerTick;
224+
energyPerTick = (int) (mass * 0.00005D * Math.log(energyConvertionRate+1));
225+
energyPerTick *= ENERGY_GENERATION.GENERATION_MULTIPLIER.get();
226+
energyPerTick *= KUGELBLITZ_CONFIG.GENERATION_MULTIPLIER.get();
227+
energyStorage().addEnergy(energyPerTick);
228+
if (wasEnergy != energyPerTick) {
229+
setChanged();
230+
}
231+
}
232+
233+
private void updateEvaporation() {
234+
int wasEvaporation = evaporation;
235+
int rate = Math.max(1, energyConvertionRate);
236+
if (recipeInfo().recipe() != null && !recipeInfo().isCompleted()) {
237+
rate = 100;
238+
}
239+
rate = (int) Math.pow(rate, 1.2);
240+
evaporation = (int) (rate * KUGELBLITZ_CONFIG.EVAPORATION_MULTIPLIER.get() * (mass * 0.0000001D));
241+
if (wasEvaporation != evaporation) {
242+
setChanged();
243+
}
244+
}
245+
246+
private void doEvaporation() {
247+
200248
}
201249

202250
public List<FluidStack> getAllowedInputFluids()
203251
{
204252
if(allowedInputs == null) {
205253
allowedInputs = new ArrayList<>();
206-
for(NcRecipe recipe: NcRecipeType.ALL_RECIPES.get(getName()).getRecipeType().getRecipes(getLevel())) {
207-
for(FluidStackIngredient ingredient: recipe.getInputFluids()) {
208-
allowedInputs.addAll(ingredient.getRepresentations());
209-
}
210-
}
254+
allowedInputs.addAll(IngredientCreatorAccess.fluid().from(subliquid_matter, 1).getRepresentations());
211255
}
212256
return allowedInputs;
213257
}
@@ -235,7 +279,6 @@ private void handleValidation() {
235279
if(isCasingValid) {
236280
isInternalValid = this.getMultiblock().isInnerValid();
237281
}
238-
powered = false;
239282
changed = true;
240283
}
241284
validationResult = this.getMultiblock().validationResult;
@@ -255,7 +298,11 @@ public boolean canInvalidateCache() {
255298
}
256299

257300
private void handleMeltdown() {
258-
301+
if(mass > MAX_MASS) {
302+
if (getMultiblock().isFormed() && getMultiblock().getBlackHole() != null) {
303+
getMultiblock().getBlackHole().meltdown();
304+
}
305+
}
259306
}
260307

261308
private boolean processRecipe() {
@@ -351,14 +398,6 @@ public boolean hasRedstoneSignal() {
351398
return Objects.requireNonNull(getLevel()).hasNeighborSignal(worldPosition);
352399
}
353400

354-
public void forceShutdown() {
355-
forceShutdown = true;
356-
}
357-
358-
public void disableForceShutdown() {
359-
forceShutdown = false;
360-
}
361-
362401
public boolean isProcessing() {
363402
return hasRecipe() && recipeInfo().ticksProcessed > 0 && !recipeInfo.isCompleted();
364403
}

src/main/java/igentuman/nc/block/kugelblitz/ChamberTerminalBlock.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, @NotN
105105
return (lvl, pos, blockState, t) -> {
106106
if (t instanceof ChamberTerminalBE tile) {
107107
tile.tickClient();
108-
level.setBlock(pos, blockState.setValue(POWERED, tile.powered), 3);
108+
level.setBlock(pos, blockState.setValue(POWERED, tile.controllerEnabled), 3);
109109
}
110110
};
111111
}

0 commit comments

Comments
 (0)