Skip to content

Commit 4020305

Browse files
progress
1 parent 7105b70 commit 4020305

File tree

10 files changed

+292
-252
lines changed

10 files changed

+292
-252
lines changed

neoforge-main/build.gradle.kts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ neoForge {
6262
logLevel.set(org.slf4j.event.Level.DEBUG)
6363
sourceSet = project.sourceSets.main
6464

65-
// JetBrains Runtime Hotswap
66-
if (!System.getenv().containsKey("CI")) {
67-
jvmArgument("-XX:+AllowEnhancedClassRedefinition")
68-
}
65+
// // JetBrains Runtime Hotswap
66+
// if (!System.getenv().containsKey("CI")) {
67+
// jvmArgument("-XX:+AllowEnhancedClassRedefinition")
68+
// }
6969
}
7070

7171
create("client") {
@@ -121,6 +121,9 @@ repositories {
121121
password = project.findProperty("gpr.token") as String? ?: System.getenv("GITHUB_TOKEN")
122122
}
123123
}
124+
maven("https://cursemaven.com"){
125+
name = "CurseMaven"
126+
}
124127
}
125128

126129
dependencies {
@@ -135,6 +138,8 @@ dependencies {
135138
testImplementation("org.junit.jupiter:junit-jupiter:5.7.1")
136139
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
137140

141+
implementation("curse.maven:jei-238222:7024953")
142+
138143
jarJar(libs.rxjava)
139144
jarJar(libs.reactivestreams)
140145
}

neoforge-main/src/main/java/dev/compactmods/crafting/client/ClientPacketHandler.java

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ public static void handleFieldActivation(IMiniaturizationField<MiniaturizationRe
2525
if (cw == null)
2626
return;
2727

28-
// FIXME field.loadClientData(fieldClientData);
29-
28+
// Field data is already loaded in the field creation
3029
mc.level.getData(CCAttachments.ACTIVE_FIELDS).registerField(field);
3130
});
3231
}
@@ -47,33 +46,14 @@ public static void handleFieldDeactivation(BlockPos center) {
4746
});
4847
}
4948

50-
// public static void handleFieldData(CompoundTag fieldData) {
51-
// Minecraft mc = Minecraft.getInstance();
52-
// if (mc.level == null)
53-
// return;
54-
//
55-
// MiniaturizationField field = new MiniaturizationField();
56-
// field.setLevel(mc.level);
57-
// // FIXME field.loadClientData(fieldData);
58-
//
59-
//// mc.level.getCapability(CCCapabilities.FIELDS)
60-
//// .ifPresent(fields -> {
61-
//// fields.setLevel(mc.level);
62-
//// CompactCrafting.LOGGER.debug("Registering field on client");
63-
//// final IMiniaturizationField fieldRegistered = fields.registerField(field);
64-
////
65-
//// CompactCrafting.LOGGER.debug("Setting field references");
66-
////
67-
//// field.getProjectorPositions()
68-
//// .map(mc.level::getBlockEntity)
69-
//// .map(tile -> (FieldProjectorEntity) tile)
70-
//// .filter(Objects::nonNull)
71-
//// .forEach(tile -> {
72-
//// final BlockState state = tile.getBlockState();
73-
//// tile.setFieldRef(fieldRegistered.getRef());
74-
//// });
75-
//// });
76-
// }
49+
public static void handleFieldData(CompoundTag fieldData) {
50+
Minecraft mc = Minecraft.getInstance();
51+
if (mc.level == null)
52+
return;
53+
54+
MiniaturizationField field = MiniaturizationField.fromNBT(mc.level, fieldData);
55+
mc.level.getData(CCAttachments.ACTIVE_FIELDS).registerField(field);
56+
}
7757

7858
public static void removeField(BlockPos fieldCenter) {
7959
Minecraft mc = Minecraft.getInstance();
@@ -112,7 +92,8 @@ public static void changeFieldRecipe(BlockPos center, RecipeHolder<Miniaturizati
11292
}
11393

11494
public static FieldActivatedPacket createFieldActivationPacket(MiniaturizationFieldSize fieldSize, BlockPos center, CompoundTag clientData) {
115-
var field = new MiniaturizationField(Minecraft.getInstance().level, fieldSize, center);
95+
// Reconstruct the field from the NBT data on the client side
96+
var field = MiniaturizationField.fromNBT(Minecraft.getInstance().level, clientData);
11697
return new FieldActivatedPacket(field, clientData);
11798
}
11899
}
Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package dev.compactmods.crafting.data;
22

3-
import com.mojang.serialization.Codec;
43
import dev.compactmods.crafting.CompactCrafting;
54
import dev.compactmods.crafting.field.ActiveWorldFields;
65
import net.minecraft.core.HolderLookup;
7-
import net.minecraft.nbt.NbtOps;
6+
import net.minecraft.nbt.ListTag;
87
import net.minecraft.nbt.Tag;
98
import net.minecraft.world.level.Level;
109
import net.neoforged.neoforge.attachment.AttachmentType;
@@ -15,42 +14,29 @@
1514
import net.neoforged.neoforge.registries.NeoForgeRegistries;
1615
import org.jetbrains.annotations.NotNull;
1716

18-
import java.util.function.BiConsumer;
19-
2017
public interface CCAttachments {
2118

2219
DeferredRegister<AttachmentType<?>> ATTACHMENT_TYPES = DeferredRegister.create(NeoForgeRegistries.ATTACHMENT_TYPES, CompactCrafting.MOD_ID);
2320

2421
DeferredHolder<AttachmentType<?>, AttachmentType<ActiveWorldFields>> ACTIVE_FIELDS = ATTACHMENT_TYPES
25-
.register("active_fields", () -> AttachmentType.builder((holder) -> ActiveWorldFields.create((Level) holder)).build());
26-
27-
static <T> IAttachmentSerializer<Tag, T> holderWith(Codec<T> codec, BiConsumer<T, IAttachmentHolder> setter) {
28-
return new IAttachmentSerializer<>() {
29-
@Override
30-
public @NotNull T read(@NotNull IAttachmentHolder holder, @NotNull Tag tag, HolderLookup.@NotNull Provider provider) {
31-
var parse = codec.parse(provider.createSerializationContext(NbtOps.INSTANCE), tag);
32-
if (parse.error().isPresent()) {
33-
throw new RuntimeException(parse.error().get().toString());
34-
}
35-
if (parse.result().isEmpty())
36-
throw new RuntimeException("Result not present");
37-
38-
var data = parse.result().get();
39-
setter.accept(data, holder);
40-
return data;
22+
.register("active_fields", () -> AttachmentType.builder((holder) -> ActiveWorldFields.create((Level) holder))
23+
.serialize(new ActiveWorldFieldsSerializer())
24+
.build());
25+
26+
class ActiveWorldFieldsSerializer implements IAttachmentSerializer<Tag, ActiveWorldFields> {
27+
@Override
28+
public @NotNull ActiveWorldFields read(@NotNull IAttachmentHolder holder, @NotNull Tag tag, HolderLookup.@NotNull Provider provider) {
29+
Level level = (Level) holder;
30+
ActiveWorldFields fields = ActiveWorldFields.create(level);
31+
if (tag instanceof ListTag listTag) {
32+
fields.deserializeNBT(listTag);
4133
}
34+
return fields;
35+
}
4236

43-
@Override
44-
public Tag write(@NotNull T attachment, HolderLookup.@NotNull Provider provider) {
45-
var encode = codec.encodeStart(provider.createSerializationContext(NbtOps.INSTANCE), attachment);
46-
if (encode.error().isPresent()) {
47-
throw new RuntimeException(encode.error().get().toString());
48-
}
49-
if (encode.result().isEmpty())
50-
throw new RuntimeException("Result not present");
51-
52-
return encode.result().get();
53-
}
54-
};
37+
@Override
38+
public Tag write(@NotNull ActiveWorldFields attachment, HolderLookup.@NotNull Provider provider) {
39+
return attachment.serializeNBT();
40+
}
5541
}
5642
}

neoforge-main/src/main/java/dev/compactmods/crafting/events/WorldEventHandler.java

Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,24 @@
33
import dev.compactmods.crafting.CompactCrafting;
44
import dev.compactmods.crafting.data.CCAttachments;
55
import dev.compactmods.crafting.field.ActiveWorldFields;
6+
import dev.compactmods.crafting.field.MiniaturizationField;
7+
import dev.compactmods.crafting.network.ClientFieldWatchPacket;
8+
import dev.compactmods.crafting.network.ClientFieldUnwatchPacket;
9+
import dev.compactmods.crafting.network.FieldActivatedPacket;
10+
import dev.compactmods.crafting.network.NetworkHandler;
611
import io.reactivex.rxjava3.subjects.PublishSubject;
712
import io.reactivex.rxjava3.subjects.Subject;
813
import net.minecraft.server.level.ServerLevel;
914
import net.minecraft.server.level.ServerPlayer;
1015
import net.minecraft.world.level.ChunkPos;
1116
import net.neoforged.bus.api.SubscribeEvent;
1217
import net.neoforged.fml.common.EventBusSubscriber;
18+
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
1319
import net.neoforged.neoforge.event.level.ChunkEvent;
1420
import net.neoforged.neoforge.event.level.ChunkWatchEvent;
1521
import net.neoforged.neoforge.event.server.ServerStartedEvent;
1622
import net.neoforged.neoforge.event.tick.LevelTickEvent;
23+
import net.neoforged.neoforge.network.PacketDistributor;
1724

1825
@SuppressWarnings("unused")
1926
@EventBusSubscriber(modid = CompactCrafting.MOD_ID)
@@ -28,18 +35,19 @@ public class WorldEventHandler {
2835
@SubscribeEvent
2936
public static void onServerStarted(final ServerStartedEvent evt) {
3037
CompactCrafting.LOGGER.trace("Server started; calling previously active fields to validate themselves.");
31-
// for (ServerLevel level : evt.getServer().getAllLevels()) {
32-
// // FIXME
33-
//// level.getCapability(CCCapabilities.FIELDS)
34-
//// .resolve()
35-
//// .ifPresent(fields -> {
36-
//// fields.setLevel(level);
37-
//// fields.getFields().forEach(f -> {
38-
//// f.setLevel(level);
39-
//// f.checkLoaded();
40-
//// });
41-
//// });
42-
// }
38+
for (ServerLevel level : evt.getServer().getAllLevels()) {
39+
level.getExistingData(CCAttachments.ACTIVE_FIELDS).ifPresent(fields -> {
40+
fields.getFields().forEach(f -> {
41+
if (f instanceof MiniaturizationField mf) {
42+
mf.checkLoaded();
43+
// Send field activation to all players tracking the chunk
44+
ChunkPos chunkPos = new ChunkPos(mf.getCenter());
45+
FieldActivatedPacket packet = new FieldActivatedPacket(mf, mf.serverData());
46+
PacketDistributor.sendToPlayersTrackingChunk(level, chunkPos, packet);
47+
}
48+
});
49+
});
50+
}
4351
}
4452

4553
@SubscribeEvent
@@ -53,19 +61,12 @@ public static void onStartChunkTracking(final ChunkWatchEvent.Watch event) {
5361
final ChunkPos pos = event.getPos();
5462
final ServerLevel level = event.getLevel();
5563

56-
// FIXME
57-
// level.getCapability(CCCapabilities.FIELDS)
58-
// .map(f -> f.getFields(pos))
59-
// .ifPresent(activeFields -> {
60-
// activeFields.forEach(field -> {
61-
// ClientFieldWatchPacket pkt = new ClientFieldWatchPacket(field);
62-
//
63-
// NetworkHandler.MAIN_CHANNEL.send(
64-
// PacketDistributor.PLAYER.with(() -> player),
65-
// pkt
66-
// );
67-
// });
68-
// });
64+
level.getExistingData(CCAttachments.ACTIVE_FIELDS).ifPresent(fields -> {
65+
fields.getFields(pos).forEach(field -> {
66+
ClientFieldWatchPacket pkt = new ClientFieldWatchPacket(field);
67+
PacketDistributor.sendToPlayer(player, pkt);
68+
});
69+
});
6970
}
7071

7172
@SubscribeEvent
@@ -74,19 +75,12 @@ public static void onStopChunkTracking(final ChunkWatchEvent.UnWatch event) {
7475
final ChunkPos pos = event.getPos();
7576
final ServerLevel level = event.getLevel();
7677

77-
// FIXME
78-
// level.getCapability(CCCapabilities.FIELDS)
79-
// .map(f -> f.getFields(pos))
80-
// .ifPresent(activeFields -> {
81-
// activeFields.forEach(field -> {
82-
// ClientFieldUnwatchPacket pkt = new ClientFieldUnwatchPacket(field.getCenter());
83-
//
84-
// NetworkHandler.MAIN_CHANNEL.send(
85-
// PacketDistributor.PLAYER.with(() -> player),
86-
// pkt
87-
// );
88-
// });
89-
// });
78+
level.getExistingData(CCAttachments.ACTIVE_FIELDS).ifPresent(fields -> {
79+
fields.getFields(pos).forEach(field -> {
80+
ClientFieldUnwatchPacket pkt = new ClientFieldUnwatchPacket(field.getCenter());
81+
PacketDistributor.sendToPlayer(player, pkt);
82+
});
83+
});
9084
}
9185

9286
@SubscribeEvent
@@ -98,4 +92,24 @@ public static void chunkLoaded(final ChunkEvent.Load cEvent) {
9892
public static void chunkUnloaded(final ChunkEvent.Unload cEvent) {
9993
CHUNK_CHANGES.onNext(cEvent);
10094
}
95+
96+
@SubscribeEvent
97+
public static void onPlayerLogin(final PlayerEvent.PlayerLoggedInEvent event) {
98+
if (event.getEntity() instanceof ServerPlayer player) {
99+
ServerLevel level = player.serverLevel();
100+
// Send all active fields in the player's view distance
101+
level.getExistingData(CCAttachments.ACTIVE_FIELDS).ifPresent(fields -> {
102+
fields.getFields().forEach(field -> {
103+
if (field instanceof MiniaturizationField mf) {
104+
// Check if player can see this field's chunk
105+
ChunkPos fieldChunk = new ChunkPos(mf.getCenter());
106+
if (player.getChunkTrackingView().contains(fieldChunk.x, fieldChunk.z)) {
107+
FieldActivatedPacket packet = new FieldActivatedPacket(mf, mf.serverData());
108+
PacketDistributor.sendToPlayer(player, packet);
109+
}
110+
}
111+
});
112+
});
113+
}
114+
}
101115
}

neoforge-main/src/main/java/dev/compactmods/crafting/field/ActiveWorldFields.java

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
import dev.compactmods.crafting.CompactCrafting;
44
import dev.compactmods.crafting.api.field.IMiniaturizationField;
55
import dev.compactmods.crafting.api.field.ITickingMiniaturizationField;
6+
import dev.compactmods.crafting.data.NbtListCollector;
67
import dev.compactmods.crafting.network.FieldDeactivatedPacket;
78
import dev.compactmods.crafting.projector.ProjectorHelper;
89
import dev.compactmods.crafting.recipes.MiniaturizationRecipe;
910
import net.minecraft.core.BlockPos;
11+
import net.minecraft.nbt.CompoundTag;
12+
import net.minecraft.nbt.ListTag;
1013
import net.minecraft.resources.ResourceKey;
1114
import net.minecraft.server.level.ServerLevel;
1215
import net.minecraft.world.level.ChunkPos;
@@ -60,15 +63,6 @@ public void tickFields() {
6063
public void addFieldInstance(IMiniaturizationField<MiniaturizationRecipe> field) {
6164
BlockPos center = field.getCenter();
6265
fields.put(center, field);
63-
64-
// TODO: Attachment for field invalidation
65-
// LazyOptional<IMiniaturizationField> lazy = LazyOptional.of(() -> field);
66-
// laziness.put(center, lazy);
67-
// field.setRef(lazy);
68-
//
69-
// lazy.addListener(lo -> {
70-
// lo.ifPresent(this::unregisterField);
71-
// });
7266
}
7367

7468
public IMiniaturizationField<MiniaturizationRecipe> registerField(IMiniaturizationField<MiniaturizationRecipe> field) {
@@ -83,19 +77,8 @@ public IMiniaturizationField<MiniaturizationRecipe> registerField(IMiniaturizati
8377

8478
addFieldInstance(field);
8579

86-
// FIXME - Set projector back-references to field
87-
// field.getProjectors().locations().forEach(pos -> {
88-
// BlockState stateAt = level.getBlockState(pos);
89-
// if (!(stateAt.getBlock() instanceof FieldProjectorBlock))
90-
// return;
91-
//
92-
// if (stateAt.hasBlockEntity()) {
93-
// BlockEntity tileAt = level.getBlockEntity(pos);
94-
// if (tileAt instanceof FieldProjectorEntity) {
95-
// // ((FieldProjectorEntity) tileAt).setFieldRef(field.getRef());
96-
// }
97-
// }
98-
// });
80+
// Projectors can find their field through the ActiveWorldFields attachment
81+
// using the field center position, so no need to store back-references
9982

10083
return field;
10184
}
@@ -138,22 +121,23 @@ public ResourceKey<Level> getLevel() {
138121
return level.dimension();
139122
}
140123

124+
public ListTag serializeNBT() {
125+
return getFields()
126+
.map(field -> {
127+
if (field instanceof MiniaturizationField mf) {
128+
return mf.serverData();
129+
}
130+
return new CompoundTag();
131+
})
132+
.collect(NbtListCollector.toNbtList());
133+
}
141134

142-
143-
// public ListTag serializeNBT() {
144-
// return getFields()
145-
// .map(IMiniaturizationField::serverData)
146-
// .collect(NbtListCollector.toNbtList());
147-
// }
148-
//
149-
150-
151-
// public void deserializeNBT(ListTag nbt) {
152-
// nbt.forEach(item -> {
153-
// if (item instanceof CompoundTag ct) {
154-
// MiniaturizationField field = new MiniaturizationField(ct);
155-
// addFieldInstance(field);
156-
// }
157-
// });
158-
// }
135+
public void deserializeNBT(ListTag nbt) {
136+
nbt.forEach(item -> {
137+
if (item instanceof CompoundTag ct) {
138+
MiniaturizationField field = MiniaturizationField.fromNBT(level, ct);
139+
addFieldInstance(field);
140+
}
141+
});
142+
}
159143
}

0 commit comments

Comments
 (0)