-
-
Notifications
You must be signed in to change notification settings - Fork 216
/
Copy pathLevel.java.patch
262 lines (244 loc) · 11.6 KB
/
Level.java.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
--- a/net/minecraft/world/level/Level.java
+++ b/net/minecraft/world/level/Level.java
@@ -79,7 +_,7 @@
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.scores.Scoreboard;
-public abstract class Level implements LevelAccessor, AutoCloseable, net.neoforged.neoforge.common.extensions.ILevelExtension {
+public abstract class Level extends net.neoforged.neoforge.attachment.AttachmentHolder implements LevelAccessor, AutoCloseable, net.neoforged.neoforge.common.extensions.ILevelExtension {
public static final Codec<ResourceKey<Level>> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION);
public static final ResourceKey<Level> OVERWORLD = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld"));
public static final ResourceKey<Level> NETHER = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("the_nether"));
@@ -116,6 +_,11 @@
private final RegistryAccess registryAccess;
private final DamageSources damageSources;
private long subTickCount;
+ public boolean restoringBlockSnapshots = false;
+ public boolean captureBlockSnapshots = false;
+ public java.util.ArrayList<net.neoforged.neoforge.common.util.BlockSnapshot> capturedBlockSnapshots = new java.util.ArrayList<>();
+ private final java.util.ArrayList<BlockEntity> freshBlockEntities = new java.util.ArrayList<>();
+ private final java.util.ArrayList<BlockEntity> pendingFreshBlockEntities = new java.util.ArrayList<>();
protected Level(
WritableLevelData p_270739_,
@@ -216,11 +_,36 @@
} else {
LevelChunk levelchunk = this.getChunkAt(p_46605_);
Block block = p_46606_.getBlock();
+
+ p_46605_ = p_46605_.immutable(); // Forge - prevent mutable BlockPos leaks
+ net.neoforged.neoforge.common.util.BlockSnapshot blockSnapshot = null;
+ if (this.captureBlockSnapshots && !this.isClientSide) {
+ blockSnapshot = net.neoforged.neoforge.common.util.BlockSnapshot.create(this.dimension, this, p_46605_, p_46607_);
+ this.capturedBlockSnapshots.add(blockSnapshot);
+ }
+
BlockState blockstate = levelchunk.setBlockState(p_46605_, p_46606_, (p_46607_ & 64) != 0);
if (blockstate == null) {
+ if (blockSnapshot != null) this.capturedBlockSnapshots.remove(blockSnapshot);
return false;
} else {
BlockState blockstate1 = this.getBlockState(p_46605_);
+
+ if (blockSnapshot == null) { // Don't notify clients or update physics while capturing blockstates
+ this.markAndNotifyBlock(p_46605_, levelchunk, blockstate, p_46606_, p_46607_, p_46608_);
+ }
+
+ return true;
+ }
+ }
+ }
+
+ // Split off from original setBlockState(BlockPos, BlockState, int, int) method in order to directly send client and physic updates
+ public void markAndNotifyBlock(BlockPos p_46605_, @Nullable LevelChunk levelchunk, BlockState blockstate, BlockState p_46606_, int p_46607_, int p_46608_) {
+ Block block = p_46606_.getBlock();
+ BlockState blockstate1 = getBlockState(p_46605_);
+ {
+ {
if (blockstate1 == p_46606_) {
if (blockstate != blockstate1) {
this.setBlocksDirty(p_46605_, blockstate, blockstate1);
@@ -247,9 +_,8 @@
}
this.onBlockStateChange(p_46605_, blockstate, blockstate1);
+ p_46606_.onBlockStateChange(this, p_46605_, blockstate);
}
-
- return true;
}
}
}
@@ -301,6 +_,7 @@
}
public void updateNeighborsAt(BlockPos p_46673_, Block p_46674_) {
+ net.neoforged.neoforge.event.EventHooks.onNeighborNotify(this, p_46673_, this.getBlockState(p_46673_), java.util.EnumSet.allOf(Direction.class), false).isCanceled();
}
public void updateNeighborsAt(BlockPos p_365514_, Block p_364886_, @Nullable Orientation p_363337_) {
@@ -500,10 +_,26 @@
(this.tickingBlockEntities ? this.pendingBlockEntityTickers : this.blockEntityTickers).add(p_151526_);
}
+ public void addFreshBlockEntities(java.util.Collection<BlockEntity> beList) {
+ if (this.tickingBlockEntities) {
+ this.pendingFreshBlockEntities.addAll(beList);
+ } else {
+ this.freshBlockEntities.addAll(beList);
+ }
+ }
+
protected void tickBlockEntities() {
ProfilerFiller profilerfiller = Profiler.get();
profilerfiller.push("blockEntities");
+ if (!this.pendingFreshBlockEntities.isEmpty()) {
+ this.freshBlockEntities.addAll(this.pendingFreshBlockEntities);
+ this.pendingFreshBlockEntities.clear();
+ }
this.tickingBlockEntities = true;
+ if (!this.freshBlockEntities.isEmpty()) {
+ this.freshBlockEntities.forEach(BlockEntity::onLoad);
+ this.freshBlockEntities.clear();
+ }
if (!this.pendingBlockEntityTickers.isEmpty()) {
this.blockEntityTickers.addAll(this.pendingBlockEntityTickers);
this.pendingBlockEntityTickers.clear();
@@ -527,12 +_,19 @@
public <T extends Entity> void guardEntityTick(Consumer<T> p_46654_, T p_46655_) {
try {
+ net.neoforged.neoforge.server.timings.TimeTracker.ENTITY_UPDATE.trackStart(p_46655_);
p_46654_.accept(p_46655_);
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking entity");
CrashReportCategory crashreportcategory = crashreport.addCategory("Entity being ticked");
p_46655_.fillCrashReportCategory(crashreportcategory);
+ if (net.neoforged.neoforge.common.NeoForgeConfig.SERVER.removeErroringEntities.get()) {
+ com.mojang.logging.LogUtils.getLogger().error("{}", crashreport.getFriendlyReport(net.minecraft.ReportType.CRASH));
+ p_46655_.discard();
+ } else
throw new ReportedException(crashreport);
+ } finally {
+ net.neoforged.neoforge.server.timings.TimeTracker.ENTITY_UPDATE.trackEnd(p_46655_);
}
}
@@ -682,6 +_,7 @@
if (!this.isOutsideBuildHeight(p_46748_)) {
this.getChunkAt(p_46748_).removeBlockEntity(p_46748_);
}
+ this.updateNeighbourForOutputSignal(p_46748_, getBlockState(p_46748_).getBlock()); //Notify neighbors of changes
}
public boolean isLoaded(BlockPos p_46750_) {
@@ -761,9 +_,9 @@
}
});
- for (EnderDragonPart enderdragonpart : this.dragonParts()) {
+ for (net.neoforged.neoforge.entity.PartEntity<?> enderdragonpart : this.dragonParts()) {
if (enderdragonpart != p_46536_
- && enderdragonpart.parentMob != p_46536_
+ && enderdragonpart.getParent() != p_46536_
&& p_46538_.test(enderdragonpart)
&& p_46537_.intersects(enderdragonpart.getBoundingBox())) {
list.add(enderdragonpart);
@@ -796,6 +_,8 @@
}
}
+
+ if (false)
if (p_261454_ instanceof EnderDragon enderdragon) {
for (EnderDragonPart enderdragonpart : enderdragon.getSubEntities()) {
T t = p_261885_.tryCast(enderdragonpart);
@@ -810,12 +_,21 @@
return AbortableIterationConsumer.Continuation.CONTINUE;
});
+ for (net.neoforged.neoforge.entity.PartEntity<?> p : this.dragonParts()) {
+ T t = p_261885_.tryCast(p);
+ if (t != null && t.getBoundingBox().intersects(p_262086_) && p_261688_.test(t)) {
+ p_262071_.add(t);
+ if (p_262071_.size() >= p_261858_) {
+ break;
+ }
+ }
+ }
}
@Nullable
public abstract Entity getEntity(int p_46492_);
- public abstract Collection<EnderDragonPart> dragonParts();
+ public abstract Collection<net.neoforged.neoforge.entity.PartEntity<?>> dragonParts();
public void blockEntityChanged(BlockPos p_151544_) {
if (this.hasChunkAt(p_151544_)) {
@@ -934,17 +_,20 @@
public abstract Scoreboard getScoreboard();
+ private static final Direction[] NEIGHBOR_UPDATE_LIST = java.util.stream.Stream.concat(Direction.Plane.HORIZONTAL.stream(), Direction.Plane.VERTICAL.stream()).toArray(Direction[]::new);
+
public void updateNeighbourForOutputSignal(BlockPos p_46718_, Block p_46719_) {
- for (Direction direction : Direction.Plane.HORIZONTAL) {
+ // Neo: Also send update to vertical directions
+ for (Direction direction : NEIGHBOR_UPDATE_LIST) {
BlockPos blockpos = p_46718_.relative(direction);
if (this.hasChunkAt(blockpos)) {
BlockState blockstate = this.getBlockState(blockpos);
- if (blockstate.is(Blocks.COMPARATOR)) {
- this.neighborChanged(blockstate, blockpos, p_46719_, null, false);
- } else if (blockstate.isRedstoneConductor(this, blockpos)) {
+ blockstate.onNeighborChange(this, blockpos, p_46718_);
+ if (blockstate.isRedstoneConductor(this, blockpos)) {
blockpos = blockpos.relative(direction);
blockstate = this.getBlockState(blockpos);
- if (blockstate.is(Blocks.COMPARATOR)) {
+ // Neo: send to any blockstate that wants weak changes, but exclude vanilla comparators from vertical updates
+ if (blockstate.getWeakChanges(this, blockpos) && (direction.getAxis().isHorizontal() || !blockstate.is(Blocks.COMPARATOR))) {
this.neighborChanged(blockstate, blockpos, p_46719_, null, false);
}
}
@@ -1026,6 +_,18 @@
return this.biomeManager;
}
+ private double maxEntityRadius = 2.0D;
+ @Override
+ public double getMaxEntityRadius() {
+ return maxEntityRadius;
+ }
+ @Override
+ public double increaseMaxEntityRadius(double value) {
+ if (value > maxEntityRadius)
+ maxEntityRadius = value;
+ return maxEntityRadius;
+ }
+
public final boolean isDebug() {
return this.isDebug;
}
@@ -1068,5 +_,38 @@
public String getSerializedName() {
return this.id;
}
+ }
+
+ // Neo: Variable day time code
+
+ @org.jetbrains.annotations.ApiStatus.Internal
+ public abstract void setDayTimeFraction(float dayTimeFraction);
+
+ @org.jetbrains.annotations.ApiStatus.Internal
+ public abstract float getDayTimeFraction();
+
+ /**
+ * Returns the current ratio between game ticks and clock ticks. If this value is negative, no
+ * speed has been set and those two are coupled 1:1 (i.e. vanilla mode).
+ */
+ public abstract float getDayTimePerTick();
+
+ /**
+ * DO NOT CALL.
+ * <p>
+ * Use {@link net.minecraft.server.level.ServerLevel#setDayTimePerTick(float)} instead.
+ */
+ public abstract void setDayTimePerTick(float dayTimePerTick);
+
+ // advances the fractional daytime, returns the integer part of it
+ @org.jetbrains.annotations.ApiStatus.Internal
+ protected long advanceDaytime() {
+ if (getDayTimePerTick() < 0) {
+ return 1L; // avoid doing math (and rounding errors) if no speed has been set
+ }
+ float dayTimeStep = getDayTimeFraction() + getDayTimePerTick();
+ long result = (long)dayTimeStep;
+ setDayTimeFraction(dayTimeStep - result);
+ return result;
}
}