Skip to content

Commit 219257d

Browse files
扩散器初步代码
1 parent 43a009b commit 219257d

10 files changed

Lines changed: 291 additions & 19 deletions

File tree

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ repositories {
113113
}
114114

115115
dependencies {
116+
116117
implementation "software.bernie.geckolib:geckolib-neoforge-${minecraft_version}:${geckolib_version}"
117118
compileOnly "curse.maven:jade-api-${jade_version}"
118119
implementation "curse.maven:jade-${jade_version}"

src/main/java/top/ctnstudio/futurefood/capability/RegisterCapability.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,6 @@ public static void register(final RegisterCapabilitiesEvent event) {
3535
(be, side) -> !getOppositeDirection(be, side) ? null : be.getEnergyStorage());
3636
event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, ModTileEntity.QER.get(),
3737
(be, side) -> !getOppositeDirection(be, side) ? null : be.getEnergyStorage());
38-
// for (BlockEntityType<? extends BlockEntity> blockEntityType : BuiltInRegistries.BLOCK_ENTITY_TYPE) {
39-
// Set<Block> validBlocks = blockEntityType.getValidBlocks();
40-
// if (validBlocks.isEmpty()) {
41-
// continue;
42-
// }
43-
// validBlocks.forEach(block -> {
44-
// if (block instanceof ModEnergyStorageBlock) event.registerBlockEntity(Capabilities.EnergyStorage.BLOCK, blockEntityType,
45-
// (be, side) -> !getOppositeDirection(be, side) ?
46-
// null : ((BasicEnergyStorageBlockEntity<?>) be).getEnergyStorage());
47-
// });
48-
// }
4938
}
5039

5140
/**
@@ -58,8 +47,7 @@ private static boolean getOppositeDirection(BlockEntity be, Direction side) {
5847
if (side == null) {
5948
return false;
6049
}
61-
BlockState bs = be.getBlockState();
62-
Optional<Direction> optionalValue = bs.getOptionalValue(QedEntityBlock.FACING);
50+
Optional<Direction> optionalValue = be.getBlockState().getOptionalValue(QedEntityBlock.FACING);
6351
if (optionalValue.isEmpty()) {
6452
return false;
6553
}

src/main/java/top/ctnstudio/futurefood/common/block/QedEntityBlock.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,31 @@
22

33
import com.mojang.serialization.MapCodec;
44
import net.minecraft.core.BlockPos;
5+
import net.minecraft.world.entity.LivingEntity;
6+
import net.minecraft.world.item.ItemStack;
57
import net.minecraft.world.item.context.BlockPlaceContext;
8+
import net.minecraft.world.level.Level;
69
import net.minecraft.world.level.block.BaseEntityBlock;
710
import net.minecraft.world.level.block.RenderShape;
11+
import net.minecraft.world.level.block.entity.BlockEntity;
12+
import net.minecraft.world.level.block.entity.BlockEntityTicker;
13+
import net.minecraft.world.level.block.entity.BlockEntityType;
814
import net.minecraft.world.level.block.state.BlockState;
15+
import net.minecraft.world.level.levelgen.structure.BoundingBox;
16+
import net.minecraft.world.phys.AABB;
17+
import org.jetbrains.annotations.NotNull;
918
import top.ctnstudio.futurefood.common.block.tile.QedBlockEntity;
1019
import top.ctnstudio.futurefood.core.init.ModBlock;
20+
import top.ctnstudio.futurefood.core.init.ModTileEntity;
21+
import top.ctnstudio.futurefood.datagen.tag.FfBlockTags;
1122

1223
import javax.annotation.Nullable;
24+
import java.util.HashMap;
25+
import java.util.Map;
26+
import java.util.Optional;
27+
import java.util.stream.Stream;
28+
29+
import static top.ctnstudio.futurefood.util.BlockEntyUtil.getBlockEntityFromLevel;
1330

1431
public class QedEntityBlock extends DirectionalEntityBlock<QedBlockEntity> implements ModEnergyStorageBlock {
1532
private static final MapCodec<QedEntityBlock> CODEC = simpleCodec(QedEntityBlock::new);
@@ -23,6 +40,33 @@ public QedEntityBlock() {
2340
.isViewBlocking(ModBlock.never()));
2441
}
2542

43+
@Override
44+
public void setPlacedBy(Level level, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
45+
buildUnlimitedLinks(level, pos, state);
46+
}
47+
48+
/**
49+
* 建立无限链接
50+
*/
51+
public void buildUnlimitedLinks(Level level, BlockPos pos, BlockState state) {
52+
AABB aabb = AABB.of(BoundingBox.fromCorners(pos.offset(5,5,5), pos.offset(-5,-5,-5)));
53+
Map<BlockPos, BlockState> blockStateMap = new HashMap<>();
54+
BlockPos.betweenClosedStream(aabb)
55+
.forEach(pos1 -> blockStateMap.put(pos1, level.getBlockState(pos1)));
56+
QedBlockEntity blockEntity = getBlockEntity(level, pos);
57+
blockStateMap.entrySet().stream()
58+
.filter(entry -> entry.getValue().is(FfBlockTags.UNLIMITED_RECEPTION))
59+
.forEach(entry -> blockEntity.linkBlock(entry.getKey()));
60+
}
61+
62+
public @NotNull QedBlockEntity getBlockEntity(Level level, BlockPos pos) {
63+
Optional<QedBlockEntity> blockEntity = getBlockEntityFromLevel(level, pos, ModTileEntity.QED.get());
64+
if (blockEntity.isEmpty()) {
65+
throw new IllegalStateException("QedBlockEntity not found at " + pos);
66+
}
67+
return blockEntity.get();
68+
}
69+
2670
private QedEntityBlock(Properties properties) {
2771
super(properties);
2872
}
@@ -47,4 +91,10 @@ public QedBlockEntity newBlockEntity(BlockPos pos, BlockState state) {
4791
public BlockState getStateForPlacement(BlockPlaceContext context) {
4892
return this.defaultBlockState().setValue(FACING, context.getClickedFace());
4993
}
94+
95+
@Override
96+
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) {
97+
return type == ModTileEntity.QED.get() ? QedBlockEntity::tick : null;
98+
}
99+
50100
}

src/main/java/top/ctnstudio/futurefood/common/block/tile/BasicEnergyStorageBlockEntity.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
import net.minecraft.core.BlockPos;
44
import net.minecraft.core.HolderLookup;
55
import net.minecraft.nbt.CompoundTag;
6+
import net.minecraft.network.Connection;
7+
import net.minecraft.network.protocol.Packet;
8+
import net.minecraft.network.protocol.game.ClientGamePacketListener;
9+
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
610
import net.minecraft.world.level.block.entity.BlockEntity;
711
import net.minecraft.world.level.block.entity.BlockEntityType;
812
import net.minecraft.world.level.block.state.BlockState;
9-
import net.neoforged.neoforge.energy.EnergyStorage;
1013
import top.ctnstudio.futurefood.capability.ModEnergyStorage;
1114

12-
public class BasicEnergyStorageBlockEntity<T extends BlockEntity> extends BlockEntity {
15+
public abstract class BasicEnergyStorageBlockEntity<T extends BlockEntity> extends BlockEntity {
1316
protected final ModEnergyStorage energyStorage;
1417

1518
public BasicEnergyStorageBlockEntity(BlockEntityType<? extends T> type,BlockPos pos, BlockState blockState) {
@@ -33,6 +36,28 @@ protected void saveAdditional(CompoundTag nbt, HolderLookup.Provider registries)
3336
ModEnergyStorage.deserializeNBT(registries, nbt, energyStorage);
3437
}
3538

39+
@Override
40+
public CompoundTag getUpdateTag(HolderLookup.Provider registries) {
41+
CompoundTag tag = new CompoundTag();
42+
saveAdditional(tag, registries);
43+
return tag;
44+
}
45+
46+
@Override
47+
public void handleUpdateTag(CompoundTag tag, HolderLookup.Provider registries) {
48+
super.handleUpdateTag(tag, registries);
49+
}
50+
51+
@Override
52+
public Packet<ClientGamePacketListener> getUpdatePacket() {
53+
return ClientboundBlockEntityDataPacket.create(this);
54+
}
55+
56+
@Override
57+
public void onDataPacket(Connection connection, ClientboundBlockEntityDataPacket packet, HolderLookup.Provider registries) {
58+
super.onDataPacket(connection, packet, registries);
59+
}
60+
3661
public ModEnergyStorage getEnergyStorage() {
3762
return energyStorage;
3863
}
Lines changed: 166 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,177 @@
11
package top.ctnstudio.futurefood.common.block.tile;
22

33
import net.minecraft.core.BlockPos;
4+
import net.minecraft.core.Direction;
5+
import net.minecraft.core.HolderLookup;
6+
import net.minecraft.nbt.CompoundTag;
7+
import net.minecraft.nbt.ListTag;
8+
import net.minecraft.world.level.Level;
9+
import net.minecraft.world.level.block.entity.BlockEntity;
410
import net.minecraft.world.level.block.state.BlockState;
11+
import net.neoforged.neoforge.capabilities.Capabilities;
12+
import net.neoforged.neoforge.energy.IEnergyStorage;
513
import top.ctnstudio.futurefood.capability.ModEnergyStorage;
614
import top.ctnstudio.futurefood.core.init.ModTileEntity;
715

8-
public class QedBlockEntity extends BasicEnergyStorageBlockEntity<QedBlockEntity> {
16+
import javax.annotation.Nullable;
17+
import java.util.LinkedHashMap;
18+
19+
public class QedBlockEntity extends BasicEnergyStorageBlockEntity<QedBlockEntity> implements UnlimitedLink {
20+
private final LinkedHashMap<BlockPos, IEnergyStorage> linkList; // 链接列表
21+
922
public QedBlockEntity(BlockPos pos, BlockState blockState) {
1023
super(ModTileEntity.QED.get(), pos, blockState, new ModEnergyStorage(20480, 4096, 4096));
24+
linkList = new LinkedHashMap<>();
25+
}
26+
27+
public static <T extends BlockEntity> void tick(Level level, BlockPos blockPos, BlockState blockState, T blockEntity) {
28+
if (level == null) {
29+
return;
30+
}
31+
QedBlockEntity be = (QedBlockEntity) blockEntity;
32+
// 移除无效的链接
33+
be.linkList.entrySet().removeIf(entry -> {
34+
BlockState bs = be.getLinkedBlock(entry.getKey());
35+
if (bs == null || bs.isEmpty()) {
36+
return true;
37+
}
38+
BlockPos bp = entry.getKey();
39+
return bp == null;
40+
});
41+
be.linkList.forEach((bp, bs) -> {
42+
43+
});
44+
}
45+
46+
@Override
47+
protected void loadAdditional(CompoundTag nbt, HolderLookup.Provider registries) {
48+
super.loadAdditional(nbt, registries);
49+
serializeLinkedListNBT(registries, nbt);
50+
}
51+
52+
@Override
53+
protected void saveAdditional(CompoundTag nbt, HolderLookup.Provider registries) {
54+
super.saveAdditional(nbt, registries);
55+
deserializeLinkedListNBT(registries, nbt);
56+
}
57+
58+
@Override
59+
public boolean linkBlock(BlockPos pos) {
60+
if (pos == null || level == null) {
61+
linkFailure(pos);
62+
return false;
63+
}
64+
BlockState state = getLinkedBlock(pos);
65+
if (state == null) {
66+
linkFailure(pos);
67+
return false;
68+
}
69+
IEnergyStorage capability = getEnergyStorage(level, pos);
70+
if (capability == null) {
71+
linkFailure(pos);
72+
return false;
73+
}
74+
linkList.put(pos, capability);
75+
return true;
76+
}
77+
78+
@Override
79+
public void linkFailure(BlockPos pos) {
80+
81+
}
82+
83+
@Override
84+
public void removeLink(BlockPos pos) {
85+
if (pos == null) {
86+
return;
87+
}
88+
linkList.remove(pos);
89+
}
90+
91+
@Nullable
92+
@Override
93+
public BlockState getLinkedBlock(BlockPos pos) {
94+
if (level == null || pos == null) {
95+
return null;
96+
}
97+
BlockState blockState = level.getBlockState(pos);
98+
if (blockState == null || blockState.isEmpty()) {
99+
return null;
100+
}
101+
return blockState;
102+
}
103+
104+
@Override
105+
public void serializeLinkedListNBT(HolderLookup.Provider provider, CompoundTag nbt) {
106+
if (nbt == null || level != null) {
107+
return;
108+
}
109+
ListTag tags = new ListTag();
110+
linkList.forEach(
111+
(pos, es) -> {
112+
if (pos == null || es == null) {
113+
return;
114+
}
115+
BlockState state = getLinkedBlock(pos);
116+
if (state == null) {
117+
return;
118+
}
119+
CompoundTag tag = new CompoundTag();
120+
tag.putIntArray("pos", new int[]{pos.getX(), pos.getY(), pos.getZ()});
121+
}
122+
);
123+
nbt.put("linkList", tags);
124+
}
125+
126+
@Override
127+
public void deserializeLinkedListNBT(HolderLookup.Provider provider, CompoundTag nbt) {
128+
if (level == null || nbt.isEmpty()) {
129+
return;
130+
}
131+
ListTag tags = nbt.getList("linkList", 10);
132+
if (tags.isEmpty()) {
133+
return;
134+
}
135+
tags.forEach(tag -> {
136+
if (!(tag instanceof CompoundTag compoundTag)) {
137+
return;
138+
}
139+
int[] pos = compoundTag.getIntArray("pos");
140+
BlockPos blockPos = new BlockPos(pos[0], pos[1], pos[2]);
141+
BlockState state = getLinkedBlock(blockPos);
142+
if (state == null) {
143+
return;
144+
}
145+
IEnergyStorage capability = getEnergyStorage(level, blockPos);
146+
if (capability == null) {
147+
return;
148+
}
149+
linkList.put(blockPos, capability);
150+
});
151+
}
152+
153+
/**
154+
* 验证方块是否包含能获取能量的 capability
155+
* @return 是否包含能获取能量的 capability
156+
*/
157+
public static boolean verifyEnergyStorage(Level level, BlockPos pos) {
158+
if (level == null || pos == null) {
159+
return false;
160+
}
161+
return getEnergyStorage(level, pos) != null;
162+
}
163+
164+
public static IEnergyStorage getEnergyStorage(Level level, BlockPos pos) {
165+
IEnergyStorage capability = level.getCapability(Capabilities.EnergyStorage.BLOCK, pos, null);
166+
if (capability != null) {
167+
return capability;
168+
}
169+
for (Direction direction : Direction.values()) {
170+
IEnergyStorage capability1 = level.getCapability(Capabilities.EnergyStorage.BLOCK, pos, direction);
171+
if (capability1 != null) {
172+
return capability1;
173+
}
174+
}
175+
return null;
11176
}
12177
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package top.ctnstudio.futurefood.common.block.tile;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.core.HolderLookup;
5+
import net.minecraft.nbt.CompoundTag;
6+
import net.minecraft.world.level.block.state.BlockState;
7+
8+
public interface UnlimitedLink {
9+
boolean linkBlock(BlockPos pos);
10+
11+
void linkFailure(BlockPos pos);
12+
13+
void removeLink(BlockPos pos);
14+
15+
BlockState getLinkedBlock(BlockPos pos);
16+
17+
void serializeLinkedListNBT(HolderLookup.Provider provider, CompoundTag nbt);
18+
19+
void deserializeLinkedListNBT(HolderLookup.Provider provider, CompoundTag nbt);
20+
}

src/main/java/top/ctnstudio/futurefood/datagen/tag/FfBlockTags.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@
88
import net.neoforged.neoforge.common.data.BlockTagsProvider;
99
import net.neoforged.neoforge.common.data.ExistingFileHelper;
1010
import top.ctnstudio.futurefood.core.FutureFood;
11+
import top.ctnstudio.futurefood.core.init.ModBlock;
1112

1213
import javax.annotation.CheckForNull;
1314
import java.util.concurrent.CompletableFuture;
1415

1516
public class FfBlockTags extends BlockTagsProvider {
1617

18+
public static final TagKey<Block> UNLIMITED_RECEPTION = createTag("unlimited_reception");
19+
1720
public FfBlockTags(PackOutput output, CompletableFuture<HolderLookup.Provider> lookupProvider,
1821
@CheckForNull ExistingFileHelper existingFileHelper) {
1922
super(output, lookupProvider, FutureFood.ID, existingFileHelper);
@@ -25,5 +28,6 @@ protected static TagKey<Block> createTag(String name) {
2528

2629
@Override
2730
protected void addTags(HolderLookup.Provider capability) {
31+
tag(UNLIMITED_RECEPTION).add(ModBlock.PARTICLE_COLLIDER.value(), ModBlock.QER.value());
2832
}
2933
}

src/main/java/top/ctnstudio/futurefood/linkage/jade/ModEnergyStorageComponentProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public void appendTooltip(ITooltip tooltip, T accessor, IPluginConfig config) {
7070
ClientViewGroup<EnergyView> clientViewGroup = new ClientViewGroup<>(energyViews);
7171
groups.add(clientViewGroup);
7272

73-
boolean renderGroup = groups.size() > 1 || groups.getFirst().shouldRenderGroup();
73+
boolean renderGroup = groups.size() > 1 || groups.getFirst().shouldRenderGroup();
7474
ClientViewGroup.tooltip(
7575
tooltip, groups, true, (theTooltip, group) -> {
7676
if (renderGroup) {

0 commit comments

Comments
 (0)