ProjectAres/PGM/src/main/java/tc/oc/pgm/doublejump/DoubleJumpMatchModule.java

149 lines
4.7 KiB
Java

package tc.oc.pgm.doublejump;
import java.util.Iterator;
import java.util.Map;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.bukkit.GameMode;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerToggleFlightEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.Vector;
import tc.oc.commons.bukkit.util.OnlinePlayerMapAdapter;
import tc.oc.pgm.events.ListenerScope;
import tc.oc.pgm.events.PlayerResetEvent;
import tc.oc.pgm.match.MatchModule;
import tc.oc.pgm.match.MatchPlayer;
import tc.oc.pgm.match.MatchScope;
@ListenerScope(MatchScope.RUNNING)
public class DoubleJumpMatchModule extends MatchModule implements Listener {
private class Jumper {
final Player player;
final DoubleJumpKit kit;
float charge;
private Jumper(Player player, DoubleJumpKit kit) {
this.player = player;
this.kit = kit;
}
}
private final OnlinePlayerMapAdapter<Jumper> jumpers;
@Inject DoubleJumpMatchModule(Plugin plugin) {
this.jumpers = new OnlinePlayerMapAdapter<>(plugin);
this.jumpers.enable();
}
@Override
public void enable() {
super.enable();
getMatch().getScheduler(MatchScope.LOADED).createRepeatingTask(1, new Runnable() {
public void run() {
for(Map.Entry<Player, Jumper> entry : jumpers.entrySetCopy()) {
Player player = entry.getKey();
Jumper jumper = entry.getValue();
if(player.isOnGround() || jumper.kit.rechargeInAir || jumper.charge > 0f) {
setCharge(jumper, jumper.charge + jumper.kit.chargePerTick());
refreshJump(player);
}
}
}
});
}
@Override
public void disable() {
this.disableAll();
super.disable();
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerReset(PlayerResetEvent event) {
this.setKit(event.getPlayer().getBukkit(), null);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerDeath(PlayerDeathEvent event) {
this.setKit(event.getEntity(), null);
}
public void setKit(Player player, @Nullable DoubleJumpKit kit) {
if(kit != null && kit.enabled) {
Jumper jumper = new Jumper(player, kit);
this.jumpers.put(player, jumper);
this.setCharge(jumper, 1f);
} else {
this.jumpers.remove(player);
this.refreshJump(player);
}
}
public void disableAll() {
for(Iterator<Player> iterator = this.jumpers.keySet().iterator(); iterator.hasNext(); ) {
Player player = iterator.next();
iterator.remove();
this.refreshJump(player);
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerToggleFlight(final PlayerToggleFlightEvent event) {
Player player = event.getPlayer();
Jumper jumper = this.jumpers.get(player);
if(jumper == null) return;
if(event.isFlying()) {
event.setCancelled(true);
this.setCharge(jumper, 0f);
this.refreshJump(player);
// calculate jump
Vector impulse = player.getLocation().getDirection();
impulse.setY(0.75 + Math.abs(impulse.getY()) * 0.5);
impulse.multiply(jumper.kit.power / 3f);
// HACK: Shiny broke the impulse API
// event.getPlayer().applyImpulse(impulse, true);
event.getPlayer().setVelocity(player.getVelocity().plus(impulse));
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ZOMBIE_INFECT, 0.5f, 1.8f);
}
}
private void setCharge(Jumper jumper, float charge) {
if(jumper.kit.needsRecharge()) {
charge = Math.min(charge, 1.0f);
if(charge != jumper.charge) {
jumper.charge = charge;
jumper.player.setExp(jumper.charge);
}
}
}
private void refreshJump(Player player) {
if(player.getGameMode() != GameMode.CREATIVE) {
player.setAllowFlight(this.canJump(player));
}
}
private boolean canJump(Player player) {
Jumper jumper = this.jumpers.get(player);
return jumper != null && (!jumper.kit.needsRecharge() || jumper.charge >= 1f);
}
public boolean hasKit(MatchPlayer player) {
return jumpers.containsKey(player.getBukkit());
}
}