From a99a36496ac48e239f5591a342e13dbac45a90f5 Mon Sep 17 00:00:00 2001 From: Micle Date: Sun, 25 May 2025 00:24:13 +0100 Subject: [PATCH] Implemented logic for entity killing. --- .../OnLivingExperienceDropEventHandler.java | 116 +++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/micle/xptools/events/common/OnLivingExperienceDropEventHandler.java b/src/main/java/dev/micle/xptools/events/common/OnLivingExperienceDropEventHandler.java index 6cc7a23..f9d4a51 100644 --- a/src/main/java/dev/micle/xptools/events/common/OnLivingExperienceDropEventHandler.java +++ b/src/main/java/dev/micle/xptools/events/common/OnLivingExperienceDropEventHandler.java @@ -1,9 +1,123 @@ package dev.micle.xptools.events.common; +import dev.micle.xptools.XpTools; +import dev.micle.xptools.config.Config; +import dev.micle.xptools.operation.OperationCache; +import dev.micle.xptools.operation.OperationItem; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.entity.EntityType; import net.minecraftforge.event.entity.living.LivingExperienceDropEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.registries.ForgeRegistries; + +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; public class OnLivingExperienceDropEventHandler { @SubscribeEvent - public void onLivingExperienceDropEvent(LivingExperienceDropEvent event) {} + public void onLivingExperienceDropEvent(LivingExperienceDropEvent event) { + Instant start = Instant.now(); + float xpToDrop = event.getDroppedExperience(); + + // Get Entity id + ResourceLocation entity_rl = ForgeRegistries.ENTITY_TYPES.getKey(event.getEntity().getType()); + String entity_id = ""; + if (entity_rl != null) { + entity_id = entity_rl.toString(); + } + + // Collect operations + List operations = null; + if (Config.Server.optimizationUseCache.get()) { + operations = OperationCache.getEntityKillCacheEntry(entity_id); + } + + if (operations == null) { + operations = new ArrayList<>(); + + // Collect operations on relevant entity_id + if (!entity_id.isEmpty()) { + for (OperationItem operationItem : Config.Server.entityKillOperationItems) { + if (!operationItem.isTag() && operationItem.getId().equals(entity_id)) { + operations.add(operationItem); + } + } + } + + // Collect operations on relevant tag_id + for (TagKey> tagKey : event.getEntity().getType().getTags().toList()) { + String tag_id = tagKey.location().toString(); + for (OperationItem operationItem : Config.Server.entityKillOperationItems) { + if (operationItem.isTag() && operationItem.getId().equals(tag_id)) { + operations.add(operationItem); + } + } + } + + // Sort operations based on priority + operations.sort(Comparator.comparingInt(OperationItem::getPriority)); + + // Remove any operations after last operation + for (OperationItem operationItem : operations) { + if (operationItem.isLast()) { + operations = operations.subList(0, operations.indexOf(operationItem) + 1); + break; + } + } + + // Save operations to cache + OperationCache.addEntityKillCacheEntry(entity_id, operations); + } + + // Add global operations before all others + operations.addAll(0, Config.Server.entityKillGlobalOperationItems); + + // Apply operations to xp drops + for (OperationItem operation : operations) { + // Calculate operation value + float opValue = (operation.getMin() == operation.getMax()) ? + operation.getMin() : + ThreadLocalRandom.current().nextFloat(operation.getMin(), operation.getMax()); + + // Apply operation + switch (operation.getType()) { + case SET: + xpToDrop = opValue; + break; + case ADD: + xpToDrop += opValue; + break; + case SUBTRACT: + xpToDrop -= opValue; + break; + case MULTIPLY: + xpToDrop *= opValue; + break; + case DIVIDE: + xpToDrop /= opValue; + break; + } + + // Stop if this is the last operation + if (operation.isLast()) { + break; + } + } + + // Debug logging + if (Config.Server.debugExtra.get()) { + XpTools.LOGGER.debug("Completed entity kill event:"); + XpTools.LOGGER.debug("\tOperations: {}", operations); + XpTools.LOGGER.debug("\tTime taken (nano seconds): {}", Duration.between(start, Instant.now()).toNanos()); + XpTools.LOGGER.debug("\tXP: {} -> {}", event.getDroppedExperience(), xpToDrop); + } + + // Apply xp drop + event.setDroppedExperience((int)xpToDrop); + } }