@@ -209,10 +209,10 @@ index 55e0be135ec084ee7ebe6bc7bb9323519e0cd864..51fa57e8b9d5c9ee563ec3608a437c69
209
209
this.guardEntityTick(this::tickNonPassenger, entity);
210
210
gameprofilerfiller.pop();
211
211
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
212
- index e657b5f88195f1db2cb9a9a97f255ff23992cadd..a81dde7251255aa0966498c1c8449492dae537a9 100644
212
+ index e657b5f88195f1db2cb9a9a97f255ff23992cadd..5e155cdf66701f96dd0b831603c714b5a47d74c0 100644
213
213
--- a/src/main/java/net/minecraft/world/entity/Entity.java
214
214
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
215
- @@ -603,6 +603,117 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
215
+ @@ -603,6 +603,116 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
216
216
return to.entityState() != null && to.entityState().isCurrentState(this);
217
217
}
218
218
// Sakura end - store entity data/state
@@ -264,31 +264,30 @@ index e657b5f88195f1db2cb9a9a97f255ff23992cadd..a81dde7251255aa0966498c1c8449492
264
264
+ }
265
265
+
266
266
+ public final boolean tryMergeInto(@Nullable Entity entity) {
267
- + if (mergeLevel.atLeast(me.samsuik.sakura.entity.merge.MergeLevel.NON_STRICT ) && tickCount == 0) {
267
+ + if (mergeLevel.atLeast(me.samsuik.sakura.entity.merge.MergeLevel.LENIENT ) && tickCount == 0) {
268
268
+ originData = level.mergeHistory.retrievePositions(this);
269
269
+ }
270
270
+
271
271
+ Entity mergeEntity = null;
272
272
+
273
273
+ if (entity == null || entity.getType() != getType()) {
274
- + // first entity in the tick loop, we have to let it into this method so that we can retrieve the originData
275
- + return false;
274
+ + return false; // First entity
276
275
+ } else if (mergeLevel.atLeast(me.samsuik.sakura.entity.merge.MergeLevel.SPAWN) && entity.isSafeToSpawnMerge(this)) {
277
- + // On spawn merging, this merges entities immediately upon spawning after
278
- + // it is considered "safe". We try to make sure it is safe by only retaining
279
- + // positions that do not change when we're collecting information .
276
+ + // "SPAWN" merges entities one gametick after they have spawned. Merging is
277
+ + // only possible after it has been established that the entity is safe to
278
+ + // merge by collecting information on the entities that merge together over time .
280
279
+ mergeEntity = entity;
281
280
+ } else {
282
- + // Strict, simple merging
283
- + // This merges entities that are in the exact same state and sequential.
284
- + // Sane for most use cases but as it is merging entities plugins may misbehave.
281
+ + // "STRICT" merges entities with the same properties, position, momentum and OOE.
282
+ + // This is considered safe to use, and will not break cannon mechanics.
285
283
+ if (mergeLevel.atLeast(me.samsuik.sakura.entity.merge.MergeLevel.STRICT) && compareState(entity)) {
286
284
+ mergeEntity = entity;
287
285
+ }
288
286
+
289
- + // Non strict merging algorithm uses information collected after entities die
290
- + // to be able to perform more aggressive merging by already knowing the OOE.
291
- + if (mergeLevel.atLeast(me.samsuik.sakura.entity.merge.MergeLevel.NON_STRICT) && mergeEntity == null && originData != null) {
287
+ + // "LENIENT" merges entities aggressively by tracking the entities that have
288
+ + // previously merged. This is a hybrid of "SPAWN" and "STRICT" merging, with the
289
+ + // visuals of "STRICT" merging and better merging potential of "SPAWN" merging.
290
+ + if (mergeLevel.atLeast(me.samsuik.sakura.entity.merge.MergeLevel.LENIENT) && mergeEntity == null && originData != null) {
292
291
+ mergeEntity = originData.findFirstEntityInSamePosition(this);
293
292
+ }
294
293
+ }
@@ -330,15 +329,15 @@ index e657b5f88195f1db2cb9a9a97f255ff23992cadd..a81dde7251255aa0966498c1c8449492
330
329
331
330
public Entity(EntityType<?> type, Level world) {
332
331
this.id = Entity.ENTITY_COUNTER.incrementAndGet();
333
- @@ -651,6 +762 ,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
332
+ @@ -651,6 +761 ,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
334
333
this.getEntityData().registrationLocked = true; // Spigot
335
334
this.setPos(0.0D, 0.0D, 0.0D);
336
335
this.eyeHeight = this.getEyeHeight(net.minecraft.world.entity.Pose.STANDING, this.dimensions);
337
336
+ this.mergeLevel = level.sakuraConfig().cannons.mergeLevel; // Sakura
338
337
}
339
338
340
339
public boolean isColliding(BlockPos pos, BlockState state) {
341
- @@ -2533,6 +2645 ,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
340
+ @@ -2533,6 +2644 ,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
342
341
nbttagcompound.putBoolean("Paper.FreezeLock", true);
343
342
}
344
343
// Paper end
@@ -350,7 +349,7 @@ index e657b5f88195f1db2cb9a9a97f255ff23992cadd..a81dde7251255aa0966498c1c8449492
350
349
return nbttagcompound;
351
350
} catch (Throwable throwable) {
352
351
CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT");
353
- @@ -2680,6 +2797 ,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
352
+ @@ -2680,6 +2796 ,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
354
353
freezeLocked = nbt.getBoolean("Paper.FreezeLock");
355
354
}
356
355
// Paper end
@@ -362,7 +361,7 @@ index e657b5f88195f1db2cb9a9a97f255ff23992cadd..a81dde7251255aa0966498c1c8449492
362
361
363
362
} catch (Throwable throwable) {
364
363
CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT");
365
- @@ -4889,6 +5011 ,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
364
+ @@ -4889,6 +5010 ,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
366
365
// Paper end - rewrite chunk system
367
366
CraftEventFactory.callEntityRemoveEvent(this, cause);
368
367
// CraftBukkit end
0 commit comments