package de.anura.core; import de.anura.core.API.Core; import de.anura.core.API.Inventories; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.entity.Boat; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerToggleFlightEvent; import org.bukkit.event.vehicle.VehicleDestroyEvent; import org.bukkit.event.vehicle.VehicleExitEvent; import org.bukkit.util.Vector; public class Features implements Listener { public static ArrayList wantFlight = new ArrayList<>(); public enum Feature { DOUBLE_JUMP(1), BOAT(2); private Feature(int id) { this.featureId = id; } private final int featureId; private static final HashMap BY_ID = new HashMap<>(); public static Feature getById(Integer id) { return BY_ID.get(id); } static { for (Feature feature : values()) { BY_ID.put(feature.featureId, feature); } } } public Features() { Bukkit.getPluginManager().registerEvents(this, AnuraCore.getInstance()); } private final HashMap> playerFeatures = new HashMap<>(); private final HashMap canDoubleJump = new HashMap<>(); private final HashMap> featureEnabled = new HashMap<>(); public void updateFeatures(Player P) { if (!mainLobby()) { return; } try { ResultSet rs = Core.getMySql().querySelect("SELECT featureId FROM coreFeatures WHERE playerId = (SELECT id FROM players WHERE uuid = '" + P.getUniqueId().toString() + "')"); resetPlayerFeatures(P); playerFeatures.put(P, new ArrayList()); featureEnabled.put(P, new HashMap()); boolean added = false; while (rs.next()) { if (!added) { P.getInventory().setItem(2, Inventories.getItem("CHARGE", P)); added = true; } if (Feature.getById(rs.getInt("featureId")) != null) { this.addFeature(P, Feature.getById(rs.getInt("featureId"))); featureEnabled.get(P).put(Feature.DOUBLE_JUMP, true); } } } catch (SQLException ex) { System.err.println("Could not update player features because of a sql exception: " + ex.getLocalizedMessage()); } } public void updateFeaturesAll() { if (!mainLobby()) { return; } for (Player P : Bukkit.getOnlinePlayers()) { updateFeatures(P); } } public void reset() { for (Player P : Bukkit.getOnlinePlayers()) { this.resetPlayerFeatures(P); } } public void disableFeature(Player P, Feature f) { if (!mainLobby()) { return; } if (f == Feature.DOUBLE_JUMP) { if (!hasFeature(P, f)) { Core.statusMsg(P, "dont_have_dbl_jump", false); return; } featureEnabled.get(P).put(f, false); canDoubleJump.put(P, false); Core.statusMsg(P, "dbl_jump_off", true); P.setExp(0); if (P.getGameMode() != GameMode.CREATIVE) { P.setAllowFlight(false); } } } public void enableFeature(Player P, Feature f) { if (!mainLobby()) { return; } if (f == Feature.DOUBLE_JUMP) { if (!hasFeature(P, f)) { Core.statusMsg(P, "dont_have_dbl_jump", false); return; } featureEnabled.get(P).put(f, true); P.setAllowFlight(true); P.setExp(1); canDoubleJump.put(P, true); Core.statusMsg(P, "dbl_jump_on", true); } } public boolean hasFeature(Player P, Feature f) { if (!mainLobby()) { return false; } if (playerFeatures.containsKey(P)) { return playerFeatures.get(P).contains(f); } return false; } private void resetPlayerFeatures(Player P) { if (!playerFeatures.containsKey(P)) { return; } for (Feature f : (ArrayList) playerFeatures.get(P).clone()) { removeFeature(P, f); } } public void removeFeature(Player P, Feature f) { if (!mainLobby()) { return; } if (playerFeatures.containsKey(P)) { playerFeatures.get(P).remove(f); } if (f.equals(Feature.DOUBLE_JUMP)) { if (!P.getGameMode().equals(GameMode.CREATIVE)) { P.setAllowFlight(false); P.setExp(0); } this.canDoubleJump.put(P, false); } } public void addFeature(Player P, Feature f) { if (!mainLobby()) { return; } if (playerFeatures.containsKey(P) && !hasFeature(P, f)) { playerFeatures.get(P).add(f); } if (f.equals(Feature.DOUBLE_JUMP)) { P.setAllowFlight(true); P.setExp(1); this.canDoubleJump.put(P, true); } } private boolean mainLobby() { return AnuraCore.getInstance().getConfig().getBoolean("is-main-lobby"); } @EventHandler public void onPlayerMove(PlayerMoveEvent event) { if (!mainLobby()) { return; } Player P = event.getPlayer(); if (this.hasFeature(P, Feature.DOUBLE_JUMP)) { if (this.canDoubleJump.containsKey(P) && !this.canDoubleJump.get(P) && ((Entity) P).isOnGround() && this.featureEnabled.get(P).get(Feature.DOUBLE_JUMP)) { this.canDoubleJump.put(P, true); P.setExp(1); } } if (P.getLocation().getBlock().getType().equals(Material.STATIONARY_WATER) && P.getVehicle() == null) { Boat b = (Boat) P.getWorld().spawnEntity(event.getTo(), EntityType.BOAT); b.setPassenger(P); } } @EventHandler public void onToggleFlight(PlayerToggleFlightEvent event) { if (!mainLobby()) { return; } Player P = event.getPlayer(); if (this.hasFeature(P, Feature.DOUBLE_JUMP) && !P.getGameMode().equals(GameMode.CREATIVE)) { if (this.canDoubleJump.containsKey(P) && this.canDoubleJump.get(P)) { this.canDoubleJump.put(P, false); P.setExp(0); Vector v = P.getLocation().getDirection(); P.setVelocity(v.multiply(new Vector(1, 2, 1))); P.setVelocity(P.getVelocity().setY(1)); } else { Vector v = P.getVelocity(); P.setVelocity(v.setY(-0.4)); } event.setCancelled(true); } } @EventHandler public void onBoatDestory(VehicleDestroyEvent event) { if (event.getVehicle().getType().equals(EntityType.BOAT)) { event.setCancelled(true); } } @EventHandler public void onExit(VehicleExitEvent event) { if (event.getVehicle().getType().equals(EntityType.BOAT)) { event.getVehicle().remove(); Player p = (Player) event.getExited(); p.setVelocity(p.getVelocity().add(new Vector(0D, 1D, 0D))); if (p.getGameMode().equals(GameMode.CREATIVE) && wantFlight.contains(p.getUniqueId())) { p.setFlying(true); } } } }