package com.supaham.commons.bukkit;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.base.Supplier;
import com.supaham.commons.bukkit.area.Region;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.Collection;
import java.util.Map;
import java.util.WeakHashMap;
import javax.annotation.Nonnull;
/**
* Represents a {@link LocationChecker} extension that kills players (set their health to 0) when
* they are outside of the given region for too long. To override such behaviour, override {@link
* #reachedMaxWarnings(T)}.
* <p />
* <b>This task runs every 20 minecraft ticks (every second).</b>
*
* @since 0.3.1
*/
public abstract class WarnableLocationChecker<T extends Entity> extends LocationChecker<T> {
private final int maxWarnings;
protected final Map<T, Integer> warnings = new WeakHashMap<>();
/**
* Constructs a new warnable location checker.
*
* @param plugin plugin to own this task
* @param interval interval (in minecraft ticks) to run this task at
* @param region region to check for entities in
* @param supplier supplier of entities to call for each iteration
* @param maxWarnings maximum amount of warnings (seconds) a player gets before their judgement.
*/
public WarnableLocationChecker(@Nonnull Plugin plugin, int interval, @Nonnull Region region,
@Nonnull Supplier<Collection<T>> supplier, int maxWarnings) {
super(plugin, interval, region, supplier);
checkArgument(maxWarnings > 0, "max warnings cannot be smaller than 1.");
this.maxWarnings = maxWarnings;
}
@Override protected boolean preRun(@Nonnull T entity) {
if (entity.isDead() || (entity instanceof Player && !((Player) entity).isOnline())) {
this.warnings.remove(entity);
return false;
}
return true;
}
@Override protected void onOutOfBounds(@Nonnull T entity) {
Integer warnings = this.warnings.get(entity);
if (warnings == null) {
warnings = 0;
}
if (warnings == this.maxWarnings) {
reachedMaxWarnings(entity);
} else {
if (!warn(entity, warnings)) {
return;
}
warnings++;
this.warnings.put(entity, warnings);
}
}
@Override protected void onInBounds(@Nonnull T entity) {
this.warnings.remove(entity);
}
protected void reachedMaxWarnings(@Nonnull T entity) {
this.warnings.remove(entity);
}
protected abstract boolean warn(@Nonnull T entity, int warnings);
public Map<T, Integer> getWarnings() {
return warnings;
}
public int getMaxWarnings() {
return maxWarnings;
}
}