package nautilus.game.arcade.managers; import java.util.HashSet; import java.util.Iterator; import mineplex.core.common.util.UtilAction; import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilFirework; import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilParticle; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilParticle.ParticleType; import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilWorld; import mineplex.core.timing.TimingManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import nautilus.game.arcade.ArcadeManager; import nautilus.game.arcade.events.GameStateChangeEvent; import nautilus.game.arcade.game.Game; import nautilus.game.arcade.game.Game.GameState; import org.bukkit.Color; import org.bukkit.Effect; import org.bukkit.FireworkEffect; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.FireworkEffect.Type; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockDamageEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerPickupItemEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; public class HalloweenManager implements Listener { ArcadeManager Manager; public HashSet _active = new HashSet(); private HashSet _coins = new HashSet(); public long _lastSpawn = System.currentTimeMillis(); public HalloweenManager(ArcadeManager manager) { Manager = manager; Manager.GetPluginManager().registerEvents(this, Manager.GetPlugin()); } @EventHandler public void reset(GameStateChangeEvent event) { _active.clear(); _lastSpawn = System.currentTimeMillis(); } @EventHandler public void pumpkinEffect(UpdateEvent event) { if (event.getType() == UpdateType.TICK) return; Iterator pumpkinIterator = _active.iterator(); while (pumpkinIterator.hasNext()) { Block pumpkin = pumpkinIterator.next(); if (pumpkin.getType() != Material.PUMPKIN && pumpkin.getType() != Material.JACK_O_LANTERN) { pumpkinBreak(pumpkin); pumpkinIterator.remove(); continue; } UtilParticle.PlayParticle(ParticleType.FLAME, pumpkin.getLocation().add(0.5, 0.5, 0.5), 0, 0, 0, 0.06f, 4); if (Math.random() > 0.90) { if (pumpkin.getType() == Material.PUMPKIN) { pumpkin.setType(Material.JACK_O_LANTERN); } else { pumpkin.setType(Material.PUMPKIN); } } } } @EventHandler public void spawnPumpkinUpdate(UpdateEvent event) { if (event.getType() != UpdateType.SEC) return; if (Manager.GetGame() == null) return; Game game = Manager.GetGame(); int requirement = (int)((double)Manager.GetPlayerFull() * 0.75d); if (UtilServer.getPlayers().length < requirement) return; if (game.GetState() != GameState.Live) return; if (!UtilTime.elapsed(_lastSpawn, 120000)) return; if (Math.random() > 0.01) return; int toDrop = Math.max(1, game.GetPlayers(false).size()/6); for (int i=0 ; i< toDrop ; i++) { double interval = 1 / (double)(toDrop); if (Math.random() >= (i * interval)) // Diminishing per growth { spawnPumpkin(getPumpkinBlock(game)); } } _lastSpawn = System.currentTimeMillis(); } private void spawnPumpkin(Block block) { if (block == null) { System.out.println("Pumpkin: Could Not Find Suitable Block"); return; } block.setType(Material.PUMPKIN); block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.PUMPKIN); _active.add(block); System.out.println("Spawned Pumpkin: " + UtilWorld.locToStrClean(block.getLocation())); } private Block getPumpkinBlock(Game game) { Block block = null; int attempts = 2000; while (attempts > 0) { attempts--; int x = game.WorldData.MinX + UtilMath.r(Math.abs(game.WorldData.MaxX - game.WorldData.MinX)); int z = game.WorldData.MinZ + UtilMath.r(Math.abs(game.WorldData.MaxZ - game.WorldData.MinZ)); block = UtilBlock.getHighest(game.WorldData.World, x, z, null); if (block.getLocation().getY() <= 2 || block.getLocation().getY() < game.WorldData.MinY || block.getLocation().getY() > game.WorldData.MaxY) continue; if (block.getRelative(BlockFace.DOWN).isLiquid()) continue; if (!UtilBlock.airFoliage(block) || !UtilBlock.airFoliage(block.getRelative(BlockFace.UP))) continue; if (!UtilBlock.solid(block.getRelative(BlockFace.DOWN))) continue; return block; } return null; } @EventHandler public void pumpkinDamage(BlockDamageEvent event) { if (_active.contains(event.getBlock())) { Manager.GetGame().AddStat(event.getPlayer(), "Pumpkins Smashed", 1, false, true); pumpkinBreak(event.getBlock()); } } private void pumpkinBreak(Block block) { block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.PUMPKIN); block.setType(Material.AIR); //Coins for (int i=0 ; i < 4 + Math.random()*16 ; i++) { Item coin = block.getWorld().dropItem(block.getLocation().add(0.5, 1, 0.5), new ItemStack(Material.getMaterial(175))); Vector vel = new Vector( (Math.random() - 0.5) * 0.5, 0.1 + Math.random() * 0.3, (Math.random() - 0.5) * 0.5); coin.setVelocity(vel); coin.setPickupDelay(20); _coins.add(coin); } //Effect block.getWorld().playSound(block.getLocation(), Sound.ZOMBIE_REMEDY, 1f, 1f); } @EventHandler public void coinPickup(PlayerPickupItemEvent event) { if (_coins.contains(event.getItem())) { event.setCancelled(true); event.getItem().remove(); Manager.GetDonation().RewardCoins(null, "Halloween Pumpkin", event.getPlayer().getName(), event.getPlayer().getUniqueId(), 4 * event.getItem().getItemStack().getAmount()); event.getPlayer().getWorld().playSound(event.getPlayer().getLocation(), Sound.ORB_PICKUP, 1f, 2f); } } @EventHandler public void coinClean(UpdateEvent event) { if (event.getType() != UpdateType.FAST) return; Iterator coinIterator = _coins.iterator(); while (coinIterator.hasNext()) { Item coin = coinIterator.next(); if (!coin.isValid() || coin.getTicksLived() > 1200) { coin.remove(); coinIterator.remove(); } } } }