136 lines
4.5 KiB
Java
136 lines
4.5 KiB
Java
package tc.oc.pgm.mutation.types;
|
|
|
|
import org.bukkit.Material;
|
|
import org.bukkit.entity.Item;
|
|
import org.bukkit.event.EventHandler;
|
|
import org.bukkit.event.EventPriority;
|
|
import org.bukkit.event.entity.ItemSpawnEvent;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import tc.oc.commons.bukkit.inventory.Slot;
|
|
import tc.oc.commons.core.util.Optionals;
|
|
import tc.oc.pgm.killreward.KillReward;
|
|
import tc.oc.pgm.killreward.KillRewardMatchModule;
|
|
import tc.oc.pgm.kits.ItemKit;
|
|
import tc.oc.pgm.kits.Kit;
|
|
import tc.oc.pgm.kits.KitPlayerFacet;
|
|
import tc.oc.pgm.match.Match;
|
|
import tc.oc.pgm.match.MatchPlayer;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.WeakHashMap;
|
|
import java.util.stream.Stream;
|
|
|
|
/**
|
|
* A mutation module that injects special kits on spawn and/or kill.
|
|
*/
|
|
public class KitMutation extends MutationModule.Impl {
|
|
|
|
protected final List<Kit> kits;
|
|
protected final Map<MatchPlayer, List<Kit>> playerKits;
|
|
protected final Map<MatchPlayer, Map<Slot, ItemStack>> savedSlots;
|
|
protected final Set<Material> itemRemove;
|
|
protected final List<KillReward> rewards;
|
|
protected final boolean force;
|
|
|
|
public KitMutation(Match match, boolean force) {
|
|
super(match);
|
|
this.kits = new ArrayList<>();
|
|
this.playerKits = new WeakHashMap<>();
|
|
this.savedSlots = new WeakHashMap<>();
|
|
this.itemRemove = new HashSet<>();
|
|
this.rewards = new ArrayList<>();
|
|
this.force = force;
|
|
}
|
|
|
|
public KitMutation(Match match, boolean force, Kit... kits) {
|
|
this(match, force);
|
|
Stream.of(kits).forEachOrdered(this.kits::add);
|
|
}
|
|
|
|
/**
|
|
* Generates a list of kits to apply for the player.
|
|
* Called inside {@link #apply(MatchPlayer)}.
|
|
* @param player the player that will receive the kits
|
|
* @param kits a mutable list of kits.
|
|
*/
|
|
public void kits(MatchPlayer player, List<Kit> kits) {
|
|
kits.addAll(this.kits);
|
|
}
|
|
|
|
/**
|
|
* Apply the kits to the player.
|
|
* @param player the player.
|
|
*/
|
|
public void apply(MatchPlayer player) {
|
|
List<Kit> kits = new ArrayList<>();
|
|
kits(player, kits);
|
|
playerKits.put(player, kits);
|
|
kits.forEach(kit -> Optionals.cast(kit, ItemKit.class).ifPresent(items -> itemRemove.add(items.item().getType())));
|
|
saved().forEach(slot -> {
|
|
slot.item(player.getInventory()).ifPresent(item -> {
|
|
Map<Slot, ItemStack> slots = savedSlots.getOrDefault(player, new HashMap<>());
|
|
slots.put(slot, (ItemStack) item);
|
|
savedSlots.put(player, slots);
|
|
slot.putItem(player.getInventory(), null);
|
|
});
|
|
});
|
|
kits.forEach(kit -> player.facet(KitPlayerFacet.class).applyKit(kit, force));
|
|
}
|
|
|
|
/**
|
|
* Forcefuly remove kits from the player.
|
|
* @param player the player.
|
|
*/
|
|
public void remove(MatchPlayer player) {
|
|
playerKits.getOrDefault(player, new ArrayList<>()).stream().filter(Kit::isRemovable).forEach(kit -> kit.remove(player));
|
|
savedSlots.getOrDefault(player, new HashMap<>()).forEach((Slot slot, ItemStack item) -> slot.putItem(player.getInventory(), item));
|
|
}
|
|
|
|
/**
|
|
* Any slots in the player's inventory that should be saved
|
|
* before {@link #apply(MatchPlayer)} and restored after {@link #remove(MatchPlayer)}.
|
|
* @return the saved slots.
|
|
*/
|
|
public Stream<? extends Slot> saved() {
|
|
return Stream.empty();
|
|
}
|
|
|
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
|
public void onItemDrop(ItemSpawnEvent event) {
|
|
Item entity = event.getEntity();
|
|
if(entity != null) {
|
|
ItemStack item = entity.getItemStack();
|
|
if(item != null && itemRemove.contains(item.getType())) {
|
|
entity.remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void enable() {
|
|
super.enable();
|
|
match().module(KillRewardMatchModule.class).get().rewards().addAll(rewards);
|
|
if(match().hasStarted()) {
|
|
match().participants().forEach(this::apply);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void disable() {
|
|
match().module(KillRewardMatchModule.class).get().rewards().removeAll(rewards);
|
|
match().participants().forEach(this::remove);
|
|
kits.clear();
|
|
playerKits.clear();
|
|
savedSlots.clear();
|
|
itemRemove.clear();
|
|
rewards.clear();
|
|
super.disable();
|
|
}
|
|
|
|
}
|