added Anti Player Loot despawn #16

Merged
MineTec merged 6 commits from feature/AntiPlayerLootDespawn into master 2026-10-14 10:31:29 +00:00
2 changed files with 30 additions and 30 deletions
Showing only changes of commit 73fa6649af - Show all commits

No files matched your search

@@ -1,12 +1,28 @@
package eu.mhsl.craftattack.spawn.craftattack.appliances.metaGameplay.antiPlayerLootDespawn; package eu.mhsl.craftattack.spawn.craftattack.appliances.metaGameplay.antiPlayerLootDespawn;
import eu.mhsl.craftattack.spawn.core.appliance.Appliance; import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
import org.bukkit.NamespacedKey;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
import java.util.Locale;
public class AntiPlayerLootDespawn extends Appliance { public class AntiPlayerLootDespawn extends Appliance {
private static final int extraCycles = 5;
private static final String namespace = AntiPlayerLootDespawnListener.class.getSimpleName().toLowerCase(Locale.ROOT);
public static NamespacedKey cyclesKey = new NamespacedKey(namespace, "item_deaths_cycles".toLowerCase());
public void getItems(List<ItemStack> item) {
MineTec marked this conversation as resolved
Review

getItems passt nicht. Vielleicht markItems

`getItems` passt nicht. Vielleicht `markItems`
item.forEach(itemStack ->
itemStack.editPersistentDataContainer(persistentDataContainer ->
persistentDataContainer.set(cyclesKey, PersistentDataType.INTEGER, extraCycles)
)
);
}
MineTec marked this conversation as resolved
Review

Wenn das Markieren von Items hier als Logik in der Appliance liegt, sollte das testen auf markierte Items auch hier liegen. Dann ist die Logik "was ist ein markiertes Item?" hier zusammen und nicht geteilt.

Sowas wie boolean shouldDelete(ItemStack stack) {}
Dann wird hier auch der counter berechnet und das event bricht dann nur anhand des booleans ab.

Wenn das Markieren von Items hier als Logik in der Appliance liegt, sollte das testen auf markierte Items auch hier liegen. Dann ist die Logik "was ist ein markiertes Item?" hier zusammen und nicht geteilt. Sowas wie `boolean shouldDelete(ItemStack stack) {}` Dann wird hier auch der counter berechnet und das event bricht dann nur anhand des booleans ab.
@Override @Override
protected @NotNull List<Listener> listeners() { protected @NotNull List<Listener> listeners() {
return List.of(new AntiPlayerLootDespawnListener()); return List.of(new AntiPlayerLootDespawnListener());
@@ -1,51 +1,35 @@
package eu.mhsl.craftattack.spawn.craftattack.appliances.metaGameplay.antiPlayerLootDespawn; package eu.mhsl.craftattack.spawn.craftattack.appliances.metaGameplay.antiPlayerLootDespawn;
import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Item; import org.bukkit.entity.Item;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.ItemDespawnEvent; import org.bukkit.event.entity.ItemDespawnEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType; import org.bukkit.persistence.PersistentDataType;
import java.util.Locale; class AntiPlayerLootDespawnListener extends ApplianceListener<AntiPlayerLootDespawn> {
public class AntiPlayerLootDespawnListener extends ApplianceListener<AntiPlayerLootDespawn> {
private static final int extraCycles = 5;
private static final String namespace = AntiPlayerLootDespawnListener.class.getSimpleName().toLowerCase(Locale.ROOT);
public static NamespacedKey cyclesKey = new NamespacedKey(namespace, "item_deaths_cycles".toLowerCase());
private Location lastDeathLocation;
private long lastDeathTick = -1;
@EventHandler @EventHandler
public void onDeath(PlayerDeathEvent event) { public void onDeath(PlayerDeathEvent event) {
this.lastDeathLocation = event.getEntity().getLocation(); this.getAppliance().getItems(event.getDrops());
this.lastDeathTick = event.getPlayer().getWorld().getGameTime();
}
@EventHandler
public void onItemSpawn(ItemSpawnEvent event) {
Item item = event.getEntity();
if(this.lastDeathLocation == null) return;
if(!item.getWorld().equals(this.lastDeathLocation.getWorld())) return;
if (item.getWorld().getGameTime() != this.lastDeathTick) return;
if(item.getLocation().distanceSquared(this.lastDeathLocation) > 9) return;
item.getPersistentDataContainer().set(cyclesKey, PersistentDataType.INTEGER, extraCycles);
} }
@EventHandler @EventHandler
public void onItemDespawn(ItemDespawnEvent event) { public void onItemDespawn(ItemDespawnEvent event) {
PersistentDataContainer data = event.getEntity().getPersistentDataContainer(); Item item = event.getEntity();
Integer cycles = data.get(cyclesKey, PersistentDataType.INTEGER); ItemStack itemStack = item.getItemStack();
if(cycles == null || cycles <= 0) return; int cycles = itemStack.getPersistentDataContainer()
.getOrDefault(AntiPlayerLootDespawn.cyclesKey, PersistentDataType.INTEGER, 0);
data.set(cyclesKey, PersistentDataType.INTEGER, cycles - 1); if(cycles <= 0) return;
itemStack.editPersistentDataContainer(data ->
data.set(AntiPlayerLootDespawn.cyclesKey, PersistentDataType.INTEGER, cycles - 1)
);
item.setItemStack(itemStack);
event.setCancelled(true); event.setCancelled(true);
} }
} }