9
0
mirror of https://github.com/Samsuik/Sakura.git synced 2025-12-27 18:59:06 +00:00

Fix lenient and spawn merging and use game time

This commit is contained in:
Samsuik
2025-02-20 13:38:24 +00:00
parent cbca3dfa1d
commit 948b3a17ba
2 changed files with 47 additions and 32 deletions

View File

@@ -87,7 +87,7 @@ public interface MergeStrategy {
}
Entity nextEntity = this.entityTable.getAndWrite(entity);
if (nextEntity == null || !nextEntity.level().equals(entity.level())) {
if (nextEntity == null || entity == nextEntity || !nextEntity.level().equals(entity.level())) {
return null;
}

View File

@@ -5,7 +5,6 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import me.samsuik.sakura.configuration.WorldConfiguration.Cannons.Mechanics.TNTSpread;
import me.samsuik.sakura.utils.TickExpiry;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.item.FallingBlockEntity;
import org.jetbrains.annotations.NotNull;
@@ -14,48 +13,64 @@ public final class TrackedMergeHistory {
private final Long2ObjectMap<PositionHistory> historyMap = new Long2ObjectOpenHashMap<>();
public boolean hasPreviousMerged(@NotNull Entity entity, @NotNull Entity into) {
PositionHistory positions = this.getHistory(into);
return positions != null && positions.has(entity.getPackedOriginPosition());
}
public void trackHistory(@NotNull Entity entity, @NotNull MergeEntityData mergeEntityData) {
long originPosition = entity.getPackedOriginPosition();
PositionHistory positions = this.historyMap.computeIfAbsent(originPosition, p -> new PositionHistory());
LongOpenHashSet originPositions = mergeEntityData.getOriginPositions();
boolean createHistory = positions.hasTimePassed(160);
if (createHistory && (entity instanceof FallingBlockEntity || entity.level().sakuraConfig().cannons.mechanics.tntSpread == TNTSpread.ALL)) {
originPositions.forEach(pos -> this.historyMap.put(pos, positions));
}
positions.trackPositions(originPositions, !createHistory);
PositionHistory positions = this.getHistory(into, false);
return positions != null && positions.hasPosition(entity);
}
public boolean hasMetCondition(@NotNull Entity entity, MergeCondition condition) {
PositionHistory positions = this.getHistory(entity);
PositionHistory positions = this.getHistory(entity, false);
return positions != null && positions.hasMetConditions(entity, condition);
}
private PositionHistory getHistory(Entity entity) {
long originPosition = entity.getPackedOriginPosition();
return this.historyMap.get(originPosition);
private boolean shouldTrackAllPositions(Entity entity, MergeEntityData mergeEntityData) {
return entity instanceof FallingBlockEntity
|| mergeEntityData.getMergeLevel() == MergeLevel.LENIENT
|| entity.level().sakuraConfig().cannons.mechanics.tntSpread == TNTSpread.ALL;
}
public void expire(long tick) {
this.historyMap.values().removeIf(p -> p.expiry().isExpired(tick));
public void trackHistory(@NotNull Entity entity, @NotNull MergeEntityData mergeEntityData) {
PositionHistory positions = this.getHistory(entity, true);
LongOpenHashSet originPositions = mergeEntityData.getOriginPositions();
long gameTime = entity.level().getGameTime();
boolean retainHistory = positions.hasTicksPassed(gameTime, 160);
if (!retainHistory && this.shouldTrackAllPositions(entity, mergeEntityData)) {
originPositions.forEach(pos -> this.historyMap.put(pos, positions));
}
positions.trackPositions(originPositions, retainHistory);
}
public void expire(long gameTime) {
this.historyMap.values().removeIf(p -> p.expiry().isExpired(gameTime));
}
private PositionHistory getHistory(Entity entity, boolean create) {
long originPosition = entity.getPackedOriginPosition();
PositionHistory history = this.historyMap.get(originPosition);
if (create && history == null) {
history = new PositionHistory(entity.level().getGameTime());
this.historyMap.put(originPosition, history);
}
return history;
}
private static final class PositionHistory {
private final LongOpenHashSet positions = new LongOpenHashSet();
private final TickExpiry expiry = new TickExpiry(MinecraftServer.currentTick, 200);
private final long created = MinecraftServer.currentTick;
private final TickExpiry expiry;
private final long created;
private int cycles = 0;
public PositionHistory(long gameTime) {
this.expiry = new TickExpiry(gameTime, 200);
this.created = gameTime;
}
public TickExpiry expiry() {
return this.expiry;
}
public boolean has(long position) {
this.expiry.refresh(MinecraftServer.currentTick);
return this.positions.contains(position);
public boolean hasPosition(Entity entity) {
this.expiry.refresh(entity.level().getGameTime());
return this.positions.contains(entity.getPackedOriginPosition());
}
public void trackPositions(LongOpenHashSet positions, boolean retain) {
@@ -68,16 +83,16 @@ public final class TrackedMergeHistory {
}
public boolean hasMetConditions(@NotNull Entity entity, @NotNull MergeCondition condition) {
this.expiry.refresh(MinecraftServer.currentTick);
return condition.accept(entity, this.cycles, this.timeSinceCreation());
long gameTime = entity.level().getGameTime();
return condition.accept(entity, this.cycles, this.timeSinceCreation(gameTime));
}
public boolean hasTimePassed(int ticks) {
return this.timeSinceCreation() > ticks;
public boolean hasTicksPassed(long gameTime, int ticks) {
return this.timeSinceCreation(gameTime) > ticks;
}
private long timeSinceCreation() {
return MinecraftServer.currentTick - this.created;
private long timeSinceCreation(long gameTime) {
return gameTime - this.created;
}
}
}