|
@@ -5,7 +5,6 @@ import com.gmail.nossr50.skills.taming.TrackedTamingEntity;
|
|
|
import com.gmail.nossr50.util.player.NotificationManager;
|
|
|
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
|
|
import com.gmail.nossr50.util.text.StringUtils;
|
|
|
-import org.bukkit.Chunk;
|
|
|
import org.bukkit.Location;
|
|
|
import org.bukkit.Sound;
|
|
|
import org.bukkit.entity.LivingEntity;
|
|
@@ -19,10 +18,13 @@ import java.util.concurrent.ConcurrentHashMap;
|
|
|
import static java.util.stream.Collectors.toSet;
|
|
|
|
|
|
public class TransientEntityTracker {
|
|
|
- private final @NotNull Map<UUID, Set<TrackedTamingEntity>> playerSummonedEntityTracker;
|
|
|
+ final @NotNull Map<UUID, Set<TrackedTamingEntity>> playerSummonedEntityTracker;
|
|
|
+ // used for fast lookups during chunk unload events
|
|
|
+ final @NotNull Set<LivingEntity> entityLookupCache;
|
|
|
|
|
|
public TransientEntityTracker() {
|
|
|
- playerSummonedEntityTracker = new ConcurrentHashMap<>();
|
|
|
+ this.playerSummonedEntityTracker = new ConcurrentHashMap<>();
|
|
|
+ this.entityLookupCache = ConcurrentHashMap.newKeySet();
|
|
|
}
|
|
|
|
|
|
public void initPlayer(@NotNull Player player) {
|
|
@@ -33,14 +35,6 @@ public class TransientEntityTracker {
|
|
|
cleanPlayer(player, player.getUniqueId());
|
|
|
}
|
|
|
|
|
|
- public @NotNull List<LivingEntity> getAllTransientEntitiesInChunk(@NotNull Chunk chunk) {
|
|
|
- return playerSummonedEntityTracker.values().stream()
|
|
|
- .flatMap(Collection::stream)
|
|
|
- .map(TrackedTamingEntity::getLivingEntity)
|
|
|
- .filter(livingEntity -> livingEntity.getLocation().getChunk() == chunk)
|
|
|
- .toList();
|
|
|
- }
|
|
|
-
|
|
|
public int summonCountForPlayerOfType(@NotNull UUID playerUUID, @NotNull CallOfTheWildType callOfTheWildType) {
|
|
|
return getTrackedEntities(playerUUID, callOfTheWildType).size();
|
|
|
}
|
|
@@ -48,6 +42,7 @@ public class TransientEntityTracker {
|
|
|
public void addSummon(@NotNull UUID playerUUID, @NotNull TrackedTamingEntity trackedTamingEntity) {
|
|
|
playerSummonedEntityTracker.computeIfAbsent(playerUUID, __ -> ConcurrentHashMap.newKeySet())
|
|
|
.add(trackedTamingEntity);
|
|
|
+ entityLookupCache.add(trackedTamingEntity.getLivingEntity());
|
|
|
}
|
|
|
|
|
|
public void killSummonAndCleanMobFlags(@NotNull LivingEntity livingEntity, @Nullable Player player,
|
|
@@ -77,9 +72,7 @@ public class TransientEntityTracker {
|
|
|
}
|
|
|
|
|
|
public boolean isTransient(@NotNull LivingEntity livingEntity) {
|
|
|
- return playerSummonedEntityTracker.values().stream().anyMatch(
|
|
|
- trackedEntities -> trackedEntities.stream()
|
|
|
- .anyMatch(trackedTamingEntity -> trackedTamingEntity.getLivingEntity().equals(livingEntity)));
|
|
|
+ return entityLookupCache.contains(livingEntity);
|
|
|
}
|
|
|
|
|
|
private @NotNull Set<TrackedTamingEntity> getTrackedEntities(@NotNull UUID playerUUID,
|
|
@@ -117,7 +110,29 @@ public class TransientEntityTracker {
|
|
|
}
|
|
|
|
|
|
public void removeSummonFromTracker(@NotNull UUID playerUUID, @NotNull TrackedTamingEntity trackedTamingEntity) {
|
|
|
- playerSummonedEntityTracker.computeIfAbsent(playerUUID, __ -> ConcurrentHashMap.newKeySet())
|
|
|
- .remove(trackedTamingEntity);
|
|
|
+ if (playerSummonedEntityTracker.containsKey(playerUUID)) {
|
|
|
+ playerSummonedEntityTracker.get(playerUUID).remove(trackedTamingEntity);
|
|
|
+ entityLookupCache.remove(trackedTamingEntity.getLivingEntity());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void removeTrackedEntity(@NotNull LivingEntity livingEntity) {
|
|
|
+ // Fail fast if the entity isn't being tracked
|
|
|
+ if (!entityLookupCache.contains(livingEntity)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ final List<TrackedTamingEntity> matchingEntities = new ArrayList<>();
|
|
|
+
|
|
|
+ // Collect matching entities without copying each set
|
|
|
+ playerSummonedEntityTracker.values().forEach(trackedEntitiesPerPlayer ->
|
|
|
+ trackedEntitiesPerPlayer.stream()
|
|
|
+ .filter(trackedTamingEntity -> trackedTamingEntity.getLivingEntity() == livingEntity)
|
|
|
+ .forEach(matchingEntities::add)
|
|
|
+ );
|
|
|
+
|
|
|
+ // Iterate over the collected list to handle removal and cleanup
|
|
|
+ matchingEntities.forEach(TrackedTamingEntity::run);
|
|
|
}
|
|
|
+
|
|
|
}
|