mirror of
https://github.com/Samsuik/Sakura.git
synced 2025-12-28 11:19:08 +00:00
fix entity data becoming desynced after an explosion
This commit is contained in:
@@ -4,6 +4,7 @@ import ca.spottedleaf.moonrise.common.util.WorldUtil;
|
||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices;
|
||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.EntityLookup;
|
||||
import it.unimi.dsi.fastutil.objects.*;
|
||||
import me.samsuik.sakura.entity.EntityState;
|
||||
import me.samsuik.sakura.mechanics.MechanicVersion;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@@ -26,11 +27,13 @@ public abstract class SpecialisedExplosion<T extends Entity> extends ServerExplo
|
||||
private static final double ENTITY_DISPATCH_DISTANCE_SQR = 32.0 * 32.0;
|
||||
|
||||
protected final T cause; // preferred over source
|
||||
protected final Deque<Entity> sourceEntities = new ArrayDeque<>();
|
||||
private Vec3 dispatchPosition;
|
||||
private final List<Vec3> bufferedExplosions = new ObjectArrayList<>();
|
||||
private AABB bounds;
|
||||
private final Set<BlockPos> gameEvents = new ObjectOpenHashSet<>();
|
||||
private final Deque<ExplosionToSend> explosionsToSend = new ArrayDeque<>();
|
||||
private final Map<Entity, EntityState> entityStates = new Reference2ObjectOpenHashMap<>();
|
||||
|
||||
public SpecialisedExplosion(
|
||||
final ServerLevel level,
|
||||
@@ -46,6 +49,7 @@ public abstract class SpecialisedExplosion<T extends Entity> extends ServerExplo
|
||||
this.cause = entity;
|
||||
this.dispatchPosition = center;
|
||||
this.bounds = new AABB(center, center);
|
||||
this.sourceEntities.add(entity);
|
||||
}
|
||||
|
||||
public final Queue<ExplosionToSend> getExplosionsToSend() {
|
||||
@@ -61,7 +65,16 @@ public abstract class SpecialisedExplosion<T extends Entity> extends ServerExplo
|
||||
@Override
|
||||
public final int explode() {
|
||||
this.createBlockCache();
|
||||
|
||||
// Handle batching, entities, blocks and events
|
||||
final int blocksDestroyed = this.handleExplosion();
|
||||
|
||||
// Apply entity states (this is so plugins have up to date entity information)
|
||||
this.entityStates.forEach((entity, state) -> {
|
||||
state.apply(entity);
|
||||
entity.updateBukkitHandle(entity); // restore entity handle
|
||||
});
|
||||
|
||||
this.clearBlockCache();
|
||||
return blocksDestroyed;
|
||||
}
|
||||
@@ -77,6 +90,12 @@ public abstract class SpecialisedExplosion<T extends Entity> extends ServerExplo
|
||||
? this.calculateExplodedPositions()
|
||||
: List.of();
|
||||
|
||||
// Poll the sourceEntities queue and keep track of the entity state
|
||||
final Entity head = this.sourceEntities.poll();
|
||||
if (head != null) {
|
||||
this.entityStates.put(head, EntityState.of(this.cause));
|
||||
}
|
||||
|
||||
// Buffer explosions to reduce the amount of calculations and improve locality
|
||||
this.bounds = this.bounds.expand(center);
|
||||
this.bufferedExplosions.add(center);
|
||||
|
||||
@@ -70,6 +70,13 @@ public final class TntExplosion extends SpecialisedExplosion<PrimedTnt> {
|
||||
|
||||
// Merge the found entity into the explosion source
|
||||
this.level().mergeHandler.mergeEntity(mergeEntity, cause);
|
||||
|
||||
// To keep track of this for merged entities we'd need to sort the connected entity list.
|
||||
// Which I don't think is worth the cost. If you're running a cannon server and want people
|
||||
// to have access to accurate entity data consider turning off merging or make it accessible.
|
||||
|
||||
// Add the found entity to the source entities
|
||||
this.sourceEntities.add(foundEntity);
|
||||
}
|
||||
entities.finishRawIterator();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user