Skip to content

Commit 4d53a5b

Browse files
committed
Kugelblitz feature #147 WIP
1 parent b5ab107 commit 4d53a5b

File tree

25 files changed

+1752
-40
lines changed

25 files changed

+1752
-40
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package igentuman.nc.block.entity.kugelblitz;
2+
3+
import igentuman.nc.block.entity.NuclearCraftBE;
4+
import igentuman.nc.multiblock.AbstractNCMultiblock;
5+
import igentuman.nc.multiblock.IMultiblockAttachable;
6+
import igentuman.nc.multiblock.kugelblitz.KugelblitzMultiblock;
7+
import igentuman.nc.multiblock.kugelblitz.KugelblitzRegistration;
8+
import net.minecraft.core.BlockPos;
9+
import net.minecraft.world.level.block.state.BlockState;
10+
11+
public class ChamberBE extends NuclearCraftBE implements IMultiblockAttachable {
12+
13+
@Override
14+
public void setMultiblock(AbstractNCMultiblock multiblock) {
15+
this.multiblock = (KugelblitzMultiblock) multiblock;
16+
}
17+
18+
@Override
19+
public ChamberTerminalBE<?> controller() {
20+
try {
21+
return (ChamberTerminalBE<?>) multiblock().controller().controllerBE();
22+
} catch (NullPointerException ignore) {
23+
return null;
24+
}
25+
}
26+
27+
public KugelblitzMultiblock multiblock() {
28+
return multiblock;
29+
}
30+
31+
@Override
32+
public boolean canInvalidateCache() {
33+
return true;
34+
}
35+
36+
protected KugelblitzMultiblock multiblock;
37+
38+
public static String NAME;
39+
public boolean refreshCacheFlag = true;
40+
41+
public byte validationRuns = 0;
42+
43+
public ChamberTerminalBE<?> controller;
44+
45+
public ChamberBE(BlockPos pPos, BlockState pBlockState, String name) {
46+
super(KugelblitzRegistration.KUGELBLITZ_BE.get(name).get(), pPos, pBlockState);
47+
}
48+
49+
public void invalidateCache()
50+
{
51+
refreshCacheFlag = true;
52+
validationRuns = 0;
53+
}
54+
55+
public void tickClient() {
56+
}
57+
58+
public void tickServer() {
59+
60+
}
61+
62+
@Override
63+
public void setRemoved()
64+
{
65+
if(controller() != null) controller().invalidateCache();
66+
super.setRemoved();
67+
}
68+
69+
public boolean isValidating = false;
70+
71+
public void onNeighborChange(BlockState state, BlockPos pos, BlockPos neighbor) {
72+
if(multiblock() != null) {
73+
multiblock().onNeighborChange(state, pos, neighbor);
74+
}
75+
}
76+
}
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
package igentuman.nc.block.entity.kugelblitz;
2+
3+
import igentuman.nc.NuclearCraft;
4+
import igentuman.nc.handler.sided.capability.FluidCapabilityHandler;
5+
import igentuman.nc.util.annotation.NBTField;
6+
import net.minecraft.core.BlockPos;
7+
import net.minecraft.core.Direction;
8+
import net.minecraft.nbt.CompoundTag;
9+
import net.minecraft.world.level.block.Block;
10+
import net.minecraft.world.level.block.entity.BlockEntity;
11+
import net.minecraft.world.level.block.state.BlockState;
12+
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
13+
import net.minecraftforge.common.capabilities.Capability;
14+
import net.minecraftforge.common.capabilities.ForgeCapabilities;
15+
import net.minecraftforge.common.util.LazyOptional;
16+
import net.minecraftforge.fluids.capability.templates.FluidTank;
17+
18+
import javax.annotation.Nonnull;
19+
import javax.annotation.Nullable;
20+
import java.util.Objects;
21+
import java.util.concurrent.atomic.AtomicInteger;
22+
23+
import static igentuman.nc.util.ModUtil.isCcLoaded;
24+
25+
public class ChamberPortBE extends ChamberBE {
26+
public static String NAME = "chamber_port";
27+
@NBTField
28+
public byte analogSignal = 0;
29+
@NBTField
30+
public byte comparatorMode = SignalSource.OVERFLOW;
31+
32+
@NBTField
33+
public BlockPos controllerPos;
34+
35+
public ChamberPortBE(BlockPos pPos, BlockState pBlockState) {
36+
super(pPos, pBlockState, NAME);
37+
}
38+
public Direction getFacing() {
39+
return getBlockState().getValue(BlockStateProperties.HORIZONTAL_FACING);
40+
}
41+
42+
public boolean hasRedstoneSignal() {
43+
return Objects.requireNonNull(getLevel()).hasNeighborSignal(worldPosition);
44+
}
45+
46+
@Override
47+
public void tickServer() {
48+
if(NuclearCraft.instance.isNcBeStopped) return;
49+
super.tickServer();
50+
if(multiblock() == null || controller() == null) return;
51+
int wasSignal = analogSignal;
52+
boolean updated = sendOutPower();
53+
if(controllerPos == null) {
54+
controllerPos = controller().getBlockPos();
55+
updated = true;
56+
setChanged();
57+
}
58+
if(hasRedstoneSignal()) {
59+
controller().controllerEnabled = true;
60+
}
61+
62+
updateAnalogSignal();
63+
64+
updated = wasSignal != analogSignal || updated;
65+
66+
Direction dir = getFacing();
67+
68+
if(fluidHandler() != null) {
69+
updated = fluidHandler().pushFluids(dir, false, worldPosition) || updated;
70+
updated = fluidHandler().pullFluids(dir, false, worldPosition) || updated;
71+
}
72+
73+
if(updated) {
74+
setChanged();
75+
level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState(), Block.UPDATE_ALL);
76+
}
77+
}
78+
79+
private void updateAnalogSignal() {
80+
switch (comparatorMode) {
81+
case SignalSource.ENERGY:
82+
analogSignal = (byte) (controller().energyStorage.getEnergyStored() * 15 / controller().energyStorage.getMaxEnergyStored());
83+
break;
84+
85+
}
86+
}
87+
88+
protected FluidCapabilityHandler fluidHandler()
89+
{
90+
return controller().contentHandler.fluidCapability;
91+
}
92+
protected <T> LazyOptional<T> fluidHandler(@Nullable Direction side)
93+
{
94+
return controller().contentHandler.getFluidCapability(side);
95+
}
96+
@Nonnull
97+
@Override
98+
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
99+
if(controller() == null) return super.getCapability(cap, side);
100+
101+
if (cap == ForgeCapabilities.FLUID_HANDLER) {
102+
return fluidHandler(side).cast();
103+
}
104+
if (cap == ForgeCapabilities.ENERGY) {
105+
return controller().getEnergy().cast();
106+
}
107+
if(isCcLoaded()) {
108+
if(cap == dan200.computercraft.shared.Capabilities.CAPABILITY_PERIPHERAL) {
109+
return controller().getPeripheral(cap, side);
110+
}
111+
}
112+
return super.getCapability(cap, side);
113+
}
114+
115+
protected boolean sendOutPower() {
116+
if(multiblock() == null) return false;
117+
AtomicInteger capacity = new AtomicInteger(controller().energyStorage.getEnergyStored());
118+
if (capacity.get() > 0) {
119+
for (Direction direction : Direction.values()) {
120+
BlockEntity be = getLevel().getBlockEntity(worldPosition.relative(direction));
121+
if (be != null) {
122+
boolean doContinue = be.getCapability(ForgeCapabilities.ENERGY, direction.getOpposite()).map(handler -> {
123+
if (handler.canReceive()) {
124+
int received = handler.receiveEnergy(Math.min(capacity.get(), controller().energyStorage.getMaxEnergyStored()), false);
125+
capacity.addAndGet(-received);
126+
controller().energyStorage.consumeEnergy(received);
127+
setChanged();
128+
return capacity.get() > 0;
129+
} else {
130+
return true;
131+
}
132+
}
133+
).orElse(true);
134+
if (!doContinue) {
135+
return true;
136+
}
137+
}
138+
}
139+
return true;
140+
}
141+
return false;
142+
}
143+
144+
@Override
145+
public boolean canInvalidateCache() {
146+
return false;
147+
}
148+
149+
@Override
150+
public ChamberTerminalBE<?> controller() {
151+
if(NuclearCraft.instance.isNcBeStopped || (!getLevel().isClientSide() && getLevel().getServer() != null && !getLevel().getServer().isRunning())) return null;
152+
if(getLevel().isClientSide && controllerPos != null) {
153+
return (ChamberTerminalBE<?>) getLevel().getBlockEntity(controllerPos);
154+
}
155+
try {
156+
return (ChamberTerminalBE<?>) multiblock().controller().controllerBE();
157+
} catch (NullPointerException e) {
158+
if(controllerPos != null) {
159+
return (ChamberTerminalBE<?>) getLevel().getBlockEntity(controllerPos);
160+
}
161+
return null;
162+
}
163+
}
164+
165+
@Override
166+
public void load(CompoundTag tag) {
167+
if (tag.contains("Info")) {
168+
CompoundTag infoTag = tag.getCompound("Info");
169+
readTagData(infoTag);
170+
}
171+
super.load(tag);
172+
}
173+
174+
@Override
175+
public void saveAdditional(CompoundTag tag) {
176+
CompoundTag infoTag = new CompoundTag();
177+
saveTagData(infoTag);
178+
tag.put("Info", infoTag);
179+
}
180+
181+
@Override
182+
public void loadClientData(CompoundTag tag) {
183+
if (tag.contains("Info")) {
184+
CompoundTag infoTag = tag.getCompound("Info");
185+
readTagData(infoTag);
186+
}
187+
}
188+
189+
@Override
190+
protected void saveClientData(CompoundTag tag) {
191+
CompoundTag infoTag = new CompoundTag();
192+
tag.put("Info", infoTag);
193+
saveTagData(infoTag);
194+
}
195+
196+
public int getEnergyStored() {
197+
if(controller() == null) return 0;
198+
return controller().energyStorage.getEnergyStored();
199+
}
200+
201+
public int getMaxEnergyStored() {
202+
if(controller() == null) return 0;
203+
return controller().energyStorage.getMaxEnergyStored();
204+
}
205+
206+
public int energyPerTick() {
207+
if(controller() == null) return 0;
208+
return controller().energyPerTick;
209+
}
210+
211+
public void toggleComparatorMode() {
212+
comparatorMode++;
213+
if(comparatorMode > SignalSource.OVERFLOW) {
214+
comparatorMode = SignalSource.ENERGY;
215+
}
216+
setChanged();
217+
level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState(), Block.UPDATE_ALL);
218+
}
219+
220+
public FluidTank getFluidTank(int i) {
221+
if(controller() == null) return null;
222+
return controller().getFluidTank(i);
223+
}
224+
225+
public static class SignalSource {
226+
public static final byte ENERGY = 1;
227+
public static final byte OVERFLOW = 2;
228+
}
229+
}

0 commit comments

Comments
 (0)