added Anti Player Loot despawn #16
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
|
|||||||
|
item.forEach(itemStack ->
|
||||||
|
itemStack.editPersistentDataContainer(persistentDataContainer ->
|
||||||
|
persistentDataContainer.set(cyclesKey, PersistentDataType.INTEGER, extraCycles)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
MineTec marked this conversation as resolved
MineTec
commented
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 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() {
|
||||||
|
MineTec marked this conversation as resolved
Outdated
MineTec
commented
methoden werden kleingeschrieben methoden werden kleingeschrieben
`isItemAboveMaxAge`
ich hatte nur das Max noch einfügen wollen, nicht das 'isItem' streichen.
Ich war halt am handy.
|
|||||||
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);
|
|
||||||
}
|
}
|
||||||
|
MineTec marked this conversation as resolved
Outdated
MineTec
commented
die klasse kann package-private sein, dann sieht nur die Appliance den Listener, und nicht das ganze Projekt. Dazu einfach das Public ersatzlos wegnehmen. die klasse kann package-private sein, dann sieht nur die Appliance den Listener, und nicht das ganze Projekt. Dazu einfach das Public ersatzlos wegnehmen.
|
|||||||
|
|
||||||
|
MineTec marked this conversation as resolved
Outdated
MineTec
commented
alle Konstanten zur appliance, nicht in den listener alle Konstanten zur appliance, nicht in den listener
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void onItemDespawn(ItemDespawnEvent event) {
|
public void onItemDespawn(ItemDespawnEvent event) {
|
||||||
PersistentDataContainer data = event.getEntity().getPersistentDataContainer();
|
Item item = event.getEntity();
|
||||||
|
MineTec marked this conversation as resolved
Outdated
MineTec
commented
dieses Vorgehen wird schwirig, oder sogar garnicht mehr funktionieren, sobald mehr als ein Spieler Pro Spiel-Tick sterben sollten... siehe unten für Lösung. dieses Vorgehen wird schwirig, oder sogar garnicht mehr funktionieren, sobald mehr als ein Spieler Pro Spiel-Tick sterben sollten...
siehe unten für Lösung.
|
|||||||
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)
|
||||||
|
);
|
||||||
|
MineTec marked this conversation as resolved
Outdated
MineTec
commented
dieser Weg ist sehr sehr Hacky... Und es gibt einen viel besseren Weg: es gibt PlayerDeathEvent#getDrops. Dort können direkt alle ItemStacks welche resultiertend aus dem Tod gedroppt werden. Kein Distance-Check, keine Race conditions, mit Items die zufällit normal in dem Bereich im selbigen Tick gedroppt werden. Sowas wie Die Variablen und der Listener fallen weg. dieser Weg ist sehr sehr Hacky... Und es gibt einen viel besseren Weg: es gibt PlayerDeathEvent#getDrops. Dort können direkt alle ItemStacks welche resultiertend aus dem Tod gedroppt werden. Kein Distance-Check, keine Race conditions, mit Items die zufällit normal in dem Bereich im selbigen Tick gedroppt werden.
Sowas wie `event.getDrops().forEach(item -> item.editPersistentDataContainer(persistentDataContainer -> persistentDataContainer.set(cyclesKey, PersistentDataType.INTEGER, extraCycles));`
Die Variablen und der Listener fallen weg.
|
|||||||
|
|
||||||
|
item.setItemStack(itemStack);
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getItemspasst nicht. VielleichtmarkItems