diff --git a/src/com/projectkorra/ProjectKorra/Ability/StockAbilities.java b/src/com/projectkorra/ProjectKorra/Ability/StockAbilities.java index a6b8af8a..1a7fc725 100644 --- a/src/com/projectkorra/ProjectKorra/Ability/StockAbilities.java +++ b/src/com/projectkorra/ProjectKorra/Ability/StockAbilities.java @@ -18,7 +18,7 @@ public enum StockAbilities { AvatarState, // Project Korra - Extraction; + Extraction, Smokescreen; private enum AirbendingAbilities { AirBlast, AirBubble, AirShield, AirSuction, AirSwipe, Tornado, AirScooter, AirSpout, AirBurst; @@ -37,7 +37,7 @@ public enum StockAbilities { } private enum ChiblockingAbilities { - HighJump, RapidPunch, Paralyze; + HighJump, RapidPunch, Paralyze, Smokescreen; } public static boolean isAirbending(StockAbilities ability) { diff --git a/src/com/projectkorra/ProjectKorra/ConfigManager.java b/src/com/projectkorra/ProjectKorra/ConfigManager.java index 328d64b1..205d7504 100644 --- a/src/com/projectkorra/ProjectKorra/ConfigManager.java +++ b/src/com/projectkorra/ProjectKorra/ConfigManager.java @@ -474,6 +474,12 @@ public class ConfigManager { config.addDefault("Abilities.Chi.RapidPunch.Distance", 4); config.addDefault("Abilities.Chi.RapidPunch.Cooldown", 15000); config.addDefault("Abilities.Chi.RapidPunch.Punches", 4); + + config.addDefault("Abilities.Chi.Smokescreen.Enabled", true); + config.addDefault("Abilities.Chi.Smokescreen.Description", "Smokescren, if used correctly, can serve as a defensive and offensive ability for Chiblockers. To use, simply left click and you will toss out a Smoke Bomb. When the bomb hits the ground, it will explode and give all players within a small radius of the explosion temporary blindness, allowing you to either get away, or move in for the kill. This ability has a long cooldown."); + config.addDefault("Abilities.Chi.Smokescreen.Cooldown", 50000); + config.addDefault("Abilities.Chi.Smokescreen.Radius", 4); + config.addDefault("Abilities.Chi.Smokescreen.Duration", 15); config.addDefault("Storage.engine", "sqlite"); diff --git a/src/com/projectkorra/ProjectKorra/Methods.java b/src/com/projectkorra/ProjectKorra/Methods.java index 52c4d1cf..7107d915 100644 --- a/src/com/projectkorra/ProjectKorra/Methods.java +++ b/src/com/projectkorra/ProjectKorra/Methods.java @@ -219,7 +219,7 @@ public class Methods { if (bPlayer.hasElement(Element.Chi)) elements.append("c"); HashMap abilities = bPlayer.abilities; - + for (int i = 1; i <= 9; i++) { DBConnection.sql.modifyQuery("UPDATE pk_players SET slot" + i +" = '" + (abilities.get(i) == null ? null : abilities.get(i)) + "' WHERE uuid = '" + uuid + "'"); } @@ -1067,7 +1067,7 @@ public class Methods { if (isNight(world)) return plugin.getConfig().getDouble("Properties.Water.NightFactor"); return 1; } - + public static void playAirbendingParticles(Location loc) { for (int i = 0; i < 20; i++) { ParticleEffect.CLOUD.display(loc, (float) Math.random(), (float) Math.random(), (float) Math.random(), 0, 1); @@ -1699,11 +1699,33 @@ public class Methods { if (AbilityModuleManager.metalbendingabilities.contains(ability)) return true; return false; } - + public static boolean isImportEnabled() { return plugin.getConfig().getBoolean("Properties.ImportEnabled"); } - + + public static List getCircle(Location loc, int radius, int height, boolean hollow, boolean sphere, int plusY){ + List circleblocks = new ArrayList(); + int cx = loc.getBlockX(); + int cy = loc.getBlockY(); + int cz = loc.getBlockZ(); + + for(int x = cx - radius; x <= cx + radius; x++){ + for (int z = cz - radius; z <= cz + radius; z++){ + for(int y = (sphere ? cy - radius : cy); y < (sphere ? cy + radius : cy + height); y++){ + double dist = (cx - x) * (cx - x) + (cz - z) * (cz - z) + (sphere ? (cy - y) * (cy - y) : 0); + + if(dist < radius * radius && !(hollow && dist < (radius - 1) * (radius - 1))){ + Location l = new Location(loc.getWorld(), x, y + plusY, z); + circleblocks.add(l); + } + } + } + } + + return circleblocks; + } + public static void reloadPlugin() { for (Player player: Bukkit.getOnlinePlayers()) { Methods.saveBendingPlayer(player.getName()); diff --git a/src/com/projectkorra/ProjectKorra/PKListener.java b/src/com/projectkorra/ProjectKorra/PKListener.java index f2455ea7..07af543d 100644 --- a/src/com/projectkorra/ProjectKorra/PKListener.java +++ b/src/com/projectkorra/ProjectKorra/PKListener.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.Location; @@ -36,13 +37,13 @@ import org.bukkit.event.entity.EntityTargetEvent; import org.bukkit.event.entity.EntityTargetLivingEntityEvent; import org.bukkit.event.entity.EntityTeleportEvent; import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.event.entity.SlimeSplitEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryType.SlotType; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerAnimationEvent; -import org.bukkit.event.player.PlayerAnimationType; import org.bukkit.event.player.PlayerFishEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; @@ -70,6 +71,7 @@ import com.projectkorra.ProjectKorra.chiblocking.ChiPassive; import com.projectkorra.ProjectKorra.chiblocking.HighJump; import com.projectkorra.ProjectKorra.chiblocking.Paralyze; import com.projectkorra.ProjectKorra.chiblocking.RapidPunch; +import com.projectkorra.ProjectKorra.chiblocking.Smokescreen; import com.projectkorra.ProjectKorra.earthbending.Catapult; import com.projectkorra.ProjectKorra.earthbending.Collapse; import com.projectkorra.ProjectKorra.earthbending.CompactColumn; @@ -164,6 +166,19 @@ public class PKListener implements Listener { GrapplingHookAPI.addPlayerCooldown(player, 100); } } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onProjectileHit(ProjectileHitEvent event) { + Integer id = event.getEntity().getEntityId(); + if (Smokescreen.snowballs.contains(id)) { + Location loc = event.getEntity().getLocation(); + Smokescreen.playEffect(loc); + for (Entity en: Methods.getEntitiesAroundPoint(loc, Smokescreen.radius)) { + Smokescreen.applyBlindness(en); + } + Smokescreen.snowballs.remove(id); + } + } @EventHandler(priority = EventPriority.HIGHEST) public void fishEvent(PlayerFishEvent event) { @@ -714,6 +729,9 @@ public class PKListener implements Listener { if (abil.equalsIgnoreCase("Paralyze")) { // } + if (abil.equalsIgnoreCase("Smokescreen")) { + new Smokescreen(player); + } } if (abil.equalsIgnoreCase("AvatarState")) { diff --git a/src/com/projectkorra/ProjectKorra/chiblocking/Smokescreen.java b/src/com/projectkorra/ProjectKorra/chiblocking/Smokescreen.java new file mode 100644 index 00000000..61100f58 --- /dev/null +++ b/src/com/projectkorra/ProjectKorra/chiblocking/Smokescreen.java @@ -0,0 +1,74 @@ +package com.projectkorra.ProjectKorra.chiblocking; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Snowball; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import com.projectkorra.ProjectKorra.ProjectKorra; + +public class Smokescreen { + + public static HashMap cooldowns = new HashMap(); + public static List snowballs = new ArrayList(); + /* + * TODO: Make stuff configurable + */ + + private long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Chi.Smokescreen.Cooldown"); + public static int duration = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.Smokescreen.Duration"); + public static double radius = ProjectKorra.plugin.getConfig().getDouble("Abilities.Chi.Smokescreen.Radius"); + + public Smokescreen(Player player) { + if (cooldowns.containsKey(player.getName())) { + if (cooldowns.get(player.getName()) + cooldown >= System.currentTimeMillis()) { + return; + } else { + cooldowns.remove(player.getName()); + } + } + + snowballs.add(player.launchProjectile(Snowball.class).getEntityId()); + cooldowns.put(player.getName(), System.currentTimeMillis()); + } + + + public static void playEffect(Location loc) { + int z = -2; + int x = -2; + int y = 0; + for(int i = 0; i < 125;i++) + { + Location newLoc = new Location(loc.getWorld(), loc.getX() + x, loc.getY() + y, loc.getZ() + z); + for(int direction = 0; direction < 8; direction++) + { + loc.getWorld().playEffect(newLoc, Effect.SMOKE, direction); + } + if(z == 2) + { + z = -2; +// y++; + } + if(x == 2) + { + x = -2; + z++; + } + x++; + } + } + + public static void applyBlindness(Entity entity) { + if (entity instanceof Player) { + Player p = (Player) entity; + p.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, duration * 20, 2)); + } + } +} diff --git a/src/config.yml b/src/config.yml index dbcbd7bd..83872fdf 100644 --- a/src/config.yml +++ b/src/config.yml @@ -354,6 +354,12 @@ Abilities: Distance: 4 Cooldown: 15000 Punches: 4 + Smokescreen: + Enabled: true + Description: "Smokescren, if used correctly, can serve as a defensive and offensive ability for Chiblockers. To use, simply left click and you will toss out a Smoke Bomb. When the bomb hits the ground, it will explode and give all players within a small radius of the explosion temporary blindness, allowing you to either get away, or move in for the kill. This ability has a long cooldown." + Cooldown: 50000 + Radius: 4 + Duration: 15 Storage: engine: sqlite MySQL: diff --git a/src/plugin.yml b/src/plugin.yml index c284bee9..bf0dda04 100644 --- a/src/plugin.yml +++ b/src/plugin.yml @@ -109,6 +109,7 @@ permissions: bending.ability.HighJump: true bending.ability.Paralyze: true bending.ability.RapidPunch: true + bending.ability.Smokescreen: true bending.chi.passive: true bending.chi.grapplinghook: true bending.avatar: