package tc.oc.pgm.itemkeep; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.inject.Inject; import org.bukkit.entity.Player; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import tc.oc.commons.bukkit.event.targeted.TargetedEventHandler; import tc.oc.commons.bukkit.inventory.Slot; import tc.oc.pgm.events.PlayerPartyChangeEvent; import tc.oc.pgm.match.MatchPlayer; import tc.oc.pgm.match.MatchPlayerFacet; public class ItemKeepPlayerFacet implements MatchPlayerFacet, Listener { private final MatchPlayer player; private final Player bukkit; private final ItemKeepRules rules; private final Map<Slot, ItemStack> kept = new HashMap<>(); @Inject ItemKeepPlayerFacet(MatchPlayer player, Player bukkit, ItemKeepRules rules) { this.player = player; this.bukkit = bukkit; this.rules = rules; } /** * NOTE: Must be called before {@link tc.oc.pgm.tracker.trackers.DeathTracker#onPlayerDeath(PlayerDeathEvent)} */ @SuppressWarnings("deprecation") @TargetedEventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void processPlayerDeath(PlayerDeathEvent event) { if(!player.isParticipating()) return; if(!rules.canKeepAny()) return; final Map<Slot, ItemStack> carrying = new HashMap<>(); Slot.Player.player().forEach(slot -> slot.item(event.getEntity()) .ifPresent(item -> carrying.put(slot, item))); kept.clear(); carrying.forEach((slot, item) -> { if(rules.canKeep(slot, item)) { event.getDrops().remove(item); kept.put(slot, item); } }); } public void restoreKeptInventory() { final List<ItemStack> displaced = new ArrayList<>(); final PlayerInventory inv = bukkit.getInventory(); kept.forEach((slot, keptStack) -> { final ItemStack invStack = slot.getItem(bukkit); if(invStack == null || slot instanceof Slot.Armor) { slot.putItem(inv, keptStack); } else { if(invStack.isSimilar(keptStack)) { int n = Math.min(keptStack.getAmount(), invStack.getMaxStackSize() - invStack.getAmount()); invStack.setAmount(invStack.getAmount() + n); keptStack.setAmount(keptStack.getAmount() - n); } if(keptStack.getAmount() > 0) { displaced.add(keptStack); } } for(ItemStack stack : displaced) { inv.addItem(stack); } }); kept.clear(); } @TargetedEventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void partyChange(PlayerPartyChangeEvent event) { kept.clear(); } }