package com.nisovin.magicspells.spells.buff; import java.util.HashMap; import java.util.HashSet; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerPortalEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerToggleSneakEvent; import com.nisovin.magicspells.MagicSpells; import com.nisovin.magicspells.materials.MagicMaterial; import com.nisovin.magicspells.spells.BuffSpell; import com.nisovin.magicspells.util.BlockPlatform; import com.nisovin.magicspells.util.MagicConfig; public class CarpetSpell extends BuffSpell { private Material platformBlock; private int size; private boolean cancelOnTeleport; private HashMap<String,BlockPlatform> windwalkers; private HashSet<Player> falling; private Listener listener; public CarpetSpell(MagicConfig config, String spellName) { super(config, spellName); MagicMaterial m = MagicSpells.getItemNameResolver().resolveBlock(getConfigString("platform-block", "glass")); if (m != null) { platformBlock = m.getMaterial(); } else { platformBlock = Material.GLASS; } size = getConfigInt("size", 2); cancelOnTeleport = getConfigBoolean("cancel-on-teleport", true); windwalkers = new HashMap<String,BlockPlatform>(); falling = new HashSet<Player>(); } @Override public void initialize() { super.initialize(); if (cancelOnLogout) { registerEvents(new QuitListener()); } if (cancelOnTeleport) { registerEvents(new TeleportListener()); } } @Override public boolean castBuff(Player player, float power, String[] args) { windwalkers.put(player.getName(), new BlockPlatform(platformBlock, Material.AIR, player.getLocation().getBlock().getRelative(0,-1,0), size, true, "square")); registerListener(); return true; } private void registerListener() { if (listener == null) { listener = new CarpetListener(); registerEvents(listener); } } private void unregisterListener() { if (listener != null && windwalkers.size() == 0) { unregisterEvents(listener); listener = null; } } public class CarpetListener implements Listener { @EventHandler(priority=EventPriority.MONITOR) public void onPlayerMove(PlayerMoveEvent event) { BlockPlatform platform = windwalkers.get(event.getPlayer().getName()); if (platform != null) { Player player = event.getPlayer(); if (isExpired(player)) { turnOff(player); } else { if (falling.contains(player)) { if (event.getTo().getY() < event.getFrom().getY()) { falling.remove(player); } else { return; } } if (!player.isSneaking()) { Block block = event.getTo().subtract(0,1,0).getBlock(); boolean moved = platform.isMoved(block, false); if (moved) { platform.movePlatform(block, true); addUse(player); chargeUseCost(player); } } } } } @EventHandler(priority=EventPriority.MONITOR) public void onPlayerToggleSneak(PlayerToggleSneakEvent event) { if (windwalkers.containsKey(event.getPlayer().getName()) && event.isSneaking()) { Player player = event.getPlayer(); if (isExpired(player)) { turnOff(player); } else { Block block = player.getLocation().subtract(0,2,0).getBlock(); boolean moved = windwalkers.get(player.getName()).movePlatform(block); if (moved) { falling.add(player); addUse(player); chargeUseCost(player); } } } } @EventHandler(priority=EventPriority.NORMAL, ignoreCancelled=true) public void onBlockBreak(BlockBreakEvent event) { if (windwalkers.size() > 0 && event.getBlock().getType() == platformBlock) { for (BlockPlatform platform : windwalkers.values()) { if (platform.blockInPlatform(event.getBlock())) { event.setCancelled(true); break; } } } } } public class TeleportListener implements Listener { @EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true) public void onPlayerTeleport(PlayerTeleportEvent event) { if (windwalkers.containsKey(event.getPlayer().getName())) { if (!event.getFrom().getWorld().getName().equals(event.getTo().getWorld().getName()) || event.getFrom().toVector().distanceSquared(event.getTo().toVector()) > 50*50) { turnOff(event.getPlayer()); } } } @EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true) public void onPlayerPortal(PlayerPortalEvent event) { if (windwalkers.containsKey(event.getPlayer().getName())) { turnOff(event.getPlayer()); } } } @Override public void turnOffBuff(Player player) { BlockPlatform platform = windwalkers.get(player.getName()); if (platform != null) { platform.destroyPlatform(); windwalkers.remove(player.getName()); unregisterListener(); } } @Override protected void turnOff() { for (BlockPlatform platform : windwalkers.values()) { platform.destroyPlatform(); } windwalkers.clear(); unregisterListener(); } @Override public boolean isActive(Player player) { return windwalkers.containsKey(player.getName()); } }