95 lines
3.6 KiB
Java
95 lines
3.6 KiB
Java
package tc.oc.pgm.killreward;
|
|
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
import java.util.stream.Collectors;
|
|
import javax.annotation.Nullable;
|
|
|
|
import com.google.common.collect.ArrayListMultimap;
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.collect.Multimap;
|
|
import org.bukkit.event.Event;
|
|
import org.bukkit.event.EventHandler;
|
|
import org.bukkit.event.EventPriority;
|
|
import org.bukkit.event.Listener;
|
|
import tc.oc.pgm.events.ListenerScope;
|
|
import tc.oc.pgm.events.MatchPlayerDeathEvent;
|
|
import tc.oc.pgm.events.PlayerPartyChangeEvent;
|
|
import tc.oc.pgm.filters.query.DamageQuery;
|
|
import tc.oc.pgm.kits.ItemKitApplicator;
|
|
import tc.oc.pgm.match.Match;
|
|
import tc.oc.pgm.match.MatchModule;
|
|
import tc.oc.pgm.match.MatchPlayer;
|
|
import tc.oc.pgm.match.MatchScope;
|
|
import tc.oc.pgm.match.ParticipantState;
|
|
import tc.oc.pgm.tracker.damage.DamageInfo;
|
|
|
|
@ListenerScope(MatchScope.RUNNING)
|
|
public class KillRewardMatchModule extends MatchModule implements Listener {
|
|
|
|
private final List<KillReward> killRewards;
|
|
private final Multimap<MatchPlayer, KillReward> deadPlayerRewards = ArrayListMultimap.create();
|
|
|
|
public KillRewardMatchModule(Match match, List<KillReward> killRewards) {
|
|
super(match);
|
|
this.killRewards = killRewards;
|
|
}
|
|
|
|
public List<KillReward> rewards() {
|
|
return killRewards;
|
|
}
|
|
|
|
public ImmutableList<KillReward> rewardsImmutable() {
|
|
return ImmutableList.copyOf(killRewards);
|
|
}
|
|
|
|
public List<KillReward> rewards(@Nullable Event event, ParticipantState victim, DamageInfo damageInfo) {
|
|
final DamageQuery query = DamageQuery.attackerDefault(event, victim, damageInfo);
|
|
return rewardsImmutable().stream().filter(reward -> reward.filter.query(query).isAllowed()).collect(Collectors.toList());
|
|
}
|
|
|
|
public List<KillReward> rewards(MatchPlayerDeathEvent event) {
|
|
return rewards(event, event.getVictim().getParticipantState(), event.getDamageInfo());
|
|
}
|
|
|
|
public void giveRewards(MatchPlayer killer, Collection<KillReward> rewards) {
|
|
rewards.forEach(reward -> {
|
|
// Apply kit first so it can not override reward items
|
|
reward.kit.apply(killer);
|
|
reward.items.forEach(stack -> ItemKitApplicator.fireEventAndTransfer(killer, stack));
|
|
});
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
|
public void onDeath(MatchPlayerDeathEvent event) {
|
|
if(!event.isChallengeKill()) return;
|
|
MatchPlayer killer = event.getOnlineKiller();
|
|
if(killer == null) return;
|
|
|
|
List<KillReward> rewards = rewards(event);
|
|
|
|
if(killer.isDead()) {
|
|
// If a player earns a KW while dead, give it to them when they respawn. Rationale: If they click respawn
|
|
// fast enough, they will get the reward anyway, and we can't prevent it in that case, so we might as well
|
|
// just give it to them always. Also, if the KW is in itemkeep, they should definitely get it while dead,
|
|
// and this is a relatively simple way to handle that case.
|
|
deadPlayerRewards.putAll(killer, rewards);
|
|
} else {
|
|
giveRewards(killer, rewards);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This is called from {@link tc.oc.pgm.spawns.SpawnMatchModule} so that rewards are given after kits
|
|
*/
|
|
public void giveDeadPlayerRewards(MatchPlayer attacker) {
|
|
giveRewards(attacker, deadPlayerRewards.removeAll(attacker));
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
|
public void onPartyChange(PlayerPartyChangeEvent event) {
|
|
deadPlayerRewards.removeAll(event.getPlayer());
|
|
}
|
|
|
|
}
|