From d2bd9878955dd59b0d65790f7e653fb0ccc38e5f Mon Sep 17 00:00:00 2001 From: Nathan Braun Date: Wed, 13 Jan 2016 13:14:34 -0800 Subject: [PATCH] Rebase master and refactor --- .../projectkorra/BendingManager.java | 99 +- .../projectkorra/BendingPlayer.java | 518 +++++--- .../projectkorra/projectkorra/Element.java | 138 +- .../projectkorra/GeneralMethods.java | 985 ++++---------- .../projectkorra/projectkorra/PKListener.java | 1165 +++++++++-------- .../projectkorra/ProjectKorra.java | 21 +- .../projectkorra/projectkorra/SubElement.java | 65 - .../projectkorra/ability/Ability.java | 42 + .../projectkorra/ability/AbilityModule.java | 123 -- .../ability/AbilityModuleManager.java | 427 ------ .../projectkorra/ability/AddonAbility.java | 25 + .../projectkorra/ability/AirAbility.java | 147 +++ .../projectkorra/ability/AvatarAbility.java | 34 + .../projectkorra/ability/AvatarState.java | 139 -- .../projectkorra/ability/BlockAbility.java | 11 + .../projectkorra/ability/BloodAbility.java | 27 + .../projectkorra/ability/ChiAbility.java | 28 + .../projectkorra/ability/ComboAbility.java | 35 + .../ability/{api => }/CombustionAbility.java | 20 +- .../projectkorra/ability/CoreAbility.java | 386 ++++++ .../projectkorra/ability/EarthAbility.java | 595 +++++++++ .../ability/ElementalAbility.java | 205 +++ .../FireAbility.java} | 466 ++++--- .../ability/{api => }/FlightAbility.java | 18 +- .../ability/{api => }/HealingAbility.java | 20 +- .../projectkorra/ability/IceAbility.java | 27 + .../ability/{api => }/LavaAbility.java | 20 +- .../ability/{api => }/LightningAbility.java | 18 +- .../ability/{api => }/MetalAbility.java | 20 +- .../projectkorra/ability/MultiAbility.java | 17 + .../projectkorra/ability/PlantAbility.java | 27 + .../ability/{api => }/SandAbility.java | 22 +- .../ability/SpiritualAbility.java | 27 + .../projectkorra/ability/StockAbility.java | 240 ---- .../projectkorra/ability/SubAbility.java | 10 + .../projectkorra/ability/WaterAbility.java | 298 +++++ .../projectkorra/ability/api/Ability.java | 12 - .../projectkorra/ability/api/AirAbility.java | 32 - .../projectkorra/ability/api/CoreAbility.java | 155 --- .../ability/api/EarthAbility.java | 46 - .../projectkorra/ability/api/FireAbility.java | 81 -- .../ability/api/SourceAbility.java | 14 - .../projectkorra/ability/api/SubAbility.java | 6 - .../ability/api/WaterAbility.java | 47 - .../ability/combo/ComboAbilityModule.java | 116 -- .../ability/combo/ComboModuleManager.java | 35 - .../multiability/MultiAbilityModule.java | 130 -- .../MultiAbilityModuleManager.java | 96 -- .../ability/util/AbilityLoader.java | 129 ++ .../ability/{combo => util}/ComboManager.java | 831 ++++++------ .../MultiAbilityManager.java | 601 ++++----- .../projectkorra/airbending/AirBlast.java | 568 ++++---- .../projectkorra/airbending/AirBubble.java | 306 +++-- .../projectkorra/airbending/AirBurst.java | 349 ++--- .../projectkorra/airbending/AirCombo.java | 676 ++++++---- .../projectkorra/airbending/AirFlight.java | 142 ++ .../projectkorra/airbending/AirMethods.java | 268 ---- .../projectkorra/airbending/AirPassive.java | 64 +- .../projectkorra/airbending/AirScooter.java | 241 ++-- .../projectkorra/airbending/AirShield.java | 285 ++-- .../projectkorra/airbending/AirSpout.java | 217 ++- .../projectkorra/airbending/AirSuction.java | 386 +++--- .../projectkorra/airbending/AirSwipe.java | 432 +++--- .../airbending/AirbendingManager.java | 19 +- .../airbending/FlightAbility.java | 127 -- .../projectkorra/airbending/Suffocate.java | 857 ++++++------ .../projectkorra/airbending/Tornado.java | 366 +++--- .../projectkorra/avatar/AvatarState.java | 232 ++++ .../chiblocking/AcrobatStance.java | 129 +- .../projectkorra/chiblocking/ChiCombo.java | 185 ++- .../projectkorra/chiblocking/ChiMethods.java | 56 - .../projectkorra/chiblocking/ChiPassive.java | 99 +- .../chiblocking/ChiblockingManager.java | 3 - .../projectkorra/chiblocking/HighJump.java | 88 +- .../projectkorra/chiblocking/Paralyze.java | 114 +- .../projectkorra/chiblocking/QuickStrike.java | 103 +- .../projectkorra/chiblocking/RapidPunch.java | 169 ++- .../projectkorra/chiblocking/Smokescreen.java | 121 +- .../projectkorra/chiblocking/SwiftKick.java | 118 +- .../chiblocking/WarriorStance.java | 88 +- .../projectkorra/command/AddCommand.java | 9 +- .../command/BendingTabComplete.java | 95 +- .../projectkorra/command/BindCommand.java | 28 +- .../projectkorra/command/ChooseCommand.java | 46 +- .../projectkorra/command/ClearCommand.java | 6 +- .../projectkorra/command/Commands.java | 1 - .../projectkorra/command/CopyCommand.java | 101 -- .../projectkorra/command/DisplayCommand.java | 149 +-- .../projectkorra/command/HelpCommand.java | 87 +- .../projectkorra/command/ImportCommand.java | 39 +- .../projectkorra/command/PKCommand.java | 90 +- .../command/PermaremoveCommand.java | 4 +- .../projectkorra/command/PresetCommand.java | 112 +- .../projectkorra/command/RemoveCommand.java | 37 +- .../projectkorra/command/ToggleCommand.java | 57 +- .../projectkorra/command/WhoCommand.java | 168 +-- .../configuration/ConfigLoadable.java | 18 - .../configuration/ConfigManager.java | 131 +- .../configuration/ConfigType.java | 6 +- .../projectkorra/earthbending/Catapult.java | 266 ++-- .../projectkorra/earthbending/Collapse.java | 275 +++- .../earthbending/CollapseWall.java | 152 +++ .../earthbending/CompactColumn.java | 177 --- .../projectkorra/earthbending/EarthArmor.java | 520 +++++--- .../projectkorra/earthbending/EarthBlast.java | 924 +++++++------ .../earthbending/EarthColumn.java | 210 --- .../projectkorra/earthbending/EarthGrab.java | 236 +++- .../earthbending/EarthMethods.java | 752 ----------- .../earthbending/EarthPassive.java | 132 +- .../projectkorra/earthbending/EarthSmash.java | 812 +++++++----- .../earthbending/EarthTunnel.java | 251 ++-- .../projectkorra/earthbending/EarthWall.java | 95 -- .../earthbending/EarthbendingManager.java | 12 - .../projectkorra/earthbending/Extraction.java | 130 +- .../projectkorra/earthbending/LavaFlow.java | 680 +++++----- .../projectkorra/earthbending/LavaSurge.java | 520 +++++--- .../earthbending/LavaSurgeWall.java | 461 +++++++ .../earthbending/LavaSurgeWave.java | 443 +++++++ .../projectkorra/earthbending/LavaWall.java | 335 ----- .../projectkorra/earthbending/LavaWave.java | 313 ----- .../projectkorra/earthbending/MetalClips.java | 686 ++++++---- .../projectkorra/earthbending/RaiseEarth.java | 259 ++++ .../earthbending/RaiseEarthWall.java | 154 +++ .../projectkorra/earthbending/Ripple.java | 350 +++-- .../projectkorra/earthbending/SandSpout.java | 268 ++-- .../projectkorra/earthbending/Shockwave.java | 196 +-- .../earthbending/Tremorsense.java | 220 ++-- .../event/HorizontalVelocityChangeEvent.java | 9 +- .../event/PlayerBendingDeathEvent.java | 27 +- .../event/PlayerCooldownChangeEvent.java | 12 +- .../projectkorra/firebending/ArcOfFire.java | 71 - .../projectkorra/firebending/Blaze.java | 87 ++ .../projectkorra/firebending/BlazeArc.java | 274 ++++ .../projectkorra/firebending/BlazeRing.java | 106 ++ .../projectkorra/firebending/Combustion.java | 335 +++-- .../projectkorra/firebending/Cook.java | 165 --- .../projectkorra/firebending/Enflamed.java | 67 - .../projectkorra/firebending/Extinguish.java | 99 -- .../projectkorra/firebending/FireBlast.java | 650 ++++----- .../firebending/FireBlastCharged.java | 312 +++++ .../projectkorra/firebending/FireBurst.java | 277 ++-- .../projectkorra/firebending/FireCombo.java | 750 +++++++---- .../firebending/FireDamageTimer.java | 67 + .../projectkorra/firebending/FireJet.java | 226 ++-- .../projectkorra/firebending/FirePassive.java | 6 +- .../projectkorra/firebending/FireShield.java | 319 ++--- .../projectkorra/firebending/FireStream.java | 234 ---- .../projectkorra/firebending/Fireball.java | 405 ------ .../firebending/FirebendingManager.java | 22 +- .../projectkorra/firebending/HeatControl.java | 215 --- .../firebending/HeatControlCook.java | 139 ++ .../firebending/HeatControlExtinguish.java | 99 ++ .../firebending/HeatControlMelt.java | 98 ++ .../firebending/HeatControlSolidify.java | 239 ++++ .../projectkorra/firebending/HeatMelt.java | 49 - .../firebending/Illumination.java | 241 ++-- .../projectkorra/firebending/Lightning.java | 902 +++++++------ .../projectkorra/firebending/RingOfFire.java | 59 - .../projectkorra/firebending/WallOfFire.java | 419 +++--- .../object/HorizontalVelocityTracker.java | 15 +- .../projectkorra/object/Preset.java | 136 +- .../projectkorra/util/AbilityLoadable.java | 63 - .../projectkorra/util/AbilityLoader.java | 161 --- .../projectkorra/util/ActionBar.java | 61 - .../projectkorra/util/BlockCacheElement.java | 61 + .../projectkorra/util/BlockSource.java | 264 ++-- .../projectkorra/util/Flight.java | 31 +- .../projectkorra/util/RevertChecker.java | 12 +- .../projectkorra/util/Updater.java | 6 +- .../waterbending/Bloodbending.java | 407 +++--- .../projectkorra/waterbending/FreezeMelt.java | 142 -- .../waterbending/HealingWaters.java | 138 +- .../projectkorra/waterbending/IceBlast.java | 459 ++++--- .../projectkorra/waterbending/IceSpike.java | 320 ----- .../projectkorra/waterbending/IceSpike2.java | 458 ------- .../waterbending/IceSpikeBlast.java | 564 ++++++++ .../waterbending/IceSpikePillar.java | 431 ++++++ .../waterbending/IceSpikePillarField.java | 164 +++ .../projectkorra/waterbending/Melt.java | 91 -- .../waterbending/OctopusForm.java | 665 ++++++---- .../waterbending/PhaseChangeFreeze.java | 261 ++++ .../waterbending/PhaseChangeMelt.java | 168 +++ .../projectkorra/waterbending/PlantArmor.java | 371 +++--- .../waterbending/PlantRegrowth.java | 122 ++ .../waterbending/Plantbending.java | 65 - .../projectkorra/waterbending/SpikeField.java | 90 -- .../projectkorra/waterbending/SurgeWall.java | 600 +++++++++ .../projectkorra/waterbending/SurgeWave.java | 584 +++++++++ .../projectkorra/waterbending/Torrent.java | 814 +++++++----- .../waterbending/TorrentBurst.java | 232 ---- .../waterbending/TorrentWave.java | 294 +++++ .../projectkorra/waterbending/WaterArms.java | 470 ++++--- .../waterbending/WaterArmsFreeze.java | 199 ++- .../waterbending/WaterArmsSpear.java | 388 ++++-- .../waterbending/WaterArmsWhip.java | 494 ++++--- .../waterbending/WaterBubble.java | 46 + .../projectkorra/waterbending/WaterCombo.java | 872 ++++++------ .../waterbending/WaterManipulation.java | 1066 ++++++++------- .../waterbending/WaterMethods.java | 460 ------- .../waterbending/WaterPassive.java | 54 +- .../waterbending/WaterReturn.java | 200 +-- .../waterbending/WaterSourceGrabber.java | 109 +- .../projectkorra/waterbending/WaterSpout.java | 623 +++++---- .../waterbending/WaterSpoutWave.java | 626 +++++++++ .../projectkorra/waterbending/WaterWall.java | 564 -------- .../projectkorra/waterbending/WaterWave.java | 478 ------- .../waterbending/WaterbendingManager.java | 26 +- .../projectkorra/waterbending/Wave.java | 534 -------- src/plugin.yml | 7 +- 209 files changed, 25922 insertions(+), 23141 deletions(-) delete mode 100644 src/com/projectkorra/projectkorra/SubElement.java create mode 100644 src/com/projectkorra/projectkorra/ability/Ability.java delete mode 100644 src/com/projectkorra/projectkorra/ability/AbilityModule.java delete mode 100644 src/com/projectkorra/projectkorra/ability/AbilityModuleManager.java create mode 100644 src/com/projectkorra/projectkorra/ability/AddonAbility.java create mode 100644 src/com/projectkorra/projectkorra/ability/AirAbility.java create mode 100644 src/com/projectkorra/projectkorra/ability/AvatarAbility.java delete mode 100644 src/com/projectkorra/projectkorra/ability/AvatarState.java create mode 100644 src/com/projectkorra/projectkorra/ability/BlockAbility.java create mode 100644 src/com/projectkorra/projectkorra/ability/BloodAbility.java create mode 100644 src/com/projectkorra/projectkorra/ability/ChiAbility.java create mode 100644 src/com/projectkorra/projectkorra/ability/ComboAbility.java rename src/com/projectkorra/projectkorra/ability/{api => }/CombustionAbility.java (52%) create mode 100644 src/com/projectkorra/projectkorra/ability/CoreAbility.java create mode 100644 src/com/projectkorra/projectkorra/ability/EarthAbility.java create mode 100644 src/com/projectkorra/projectkorra/ability/ElementalAbility.java rename src/com/projectkorra/projectkorra/{firebending/FireMethods.java => ability/FireAbility.java} (53%) rename src/com/projectkorra/projectkorra/ability/{api => }/FlightAbility.java (53%) rename src/com/projectkorra/projectkorra/ability/{api => }/HealingAbility.java (53%) create mode 100644 src/com/projectkorra/projectkorra/ability/IceAbility.java rename src/com/projectkorra/projectkorra/ability/{api => }/LavaAbility.java (53%) rename src/com/projectkorra/projectkorra/ability/{api => }/LightningAbility.java (54%) rename src/com/projectkorra/projectkorra/ability/{api => }/MetalAbility.java (50%) create mode 100644 src/com/projectkorra/projectkorra/ability/MultiAbility.java create mode 100644 src/com/projectkorra/projectkorra/ability/PlantAbility.java rename src/com/projectkorra/projectkorra/ability/{api => }/SandAbility.java (50%) create mode 100644 src/com/projectkorra/projectkorra/ability/SpiritualAbility.java delete mode 100644 src/com/projectkorra/projectkorra/ability/StockAbility.java create mode 100644 src/com/projectkorra/projectkorra/ability/SubAbility.java create mode 100644 src/com/projectkorra/projectkorra/ability/WaterAbility.java delete mode 100644 src/com/projectkorra/projectkorra/ability/api/Ability.java delete mode 100644 src/com/projectkorra/projectkorra/ability/api/AirAbility.java delete mode 100644 src/com/projectkorra/projectkorra/ability/api/CoreAbility.java delete mode 100644 src/com/projectkorra/projectkorra/ability/api/EarthAbility.java delete mode 100644 src/com/projectkorra/projectkorra/ability/api/FireAbility.java delete mode 100644 src/com/projectkorra/projectkorra/ability/api/SourceAbility.java delete mode 100644 src/com/projectkorra/projectkorra/ability/api/SubAbility.java delete mode 100644 src/com/projectkorra/projectkorra/ability/api/WaterAbility.java delete mode 100644 src/com/projectkorra/projectkorra/ability/combo/ComboAbilityModule.java delete mode 100644 src/com/projectkorra/projectkorra/ability/combo/ComboModuleManager.java delete mode 100644 src/com/projectkorra/projectkorra/ability/multiability/MultiAbilityModule.java delete mode 100644 src/com/projectkorra/projectkorra/ability/multiability/MultiAbilityModuleManager.java create mode 100644 src/com/projectkorra/projectkorra/ability/util/AbilityLoader.java rename src/com/projectkorra/projectkorra/ability/{combo => util}/ComboManager.java (61%) rename src/com/projectkorra/projectkorra/ability/{multiability => util}/MultiAbilityManager.java (65%) create mode 100644 src/com/projectkorra/projectkorra/airbending/AirFlight.java delete mode 100644 src/com/projectkorra/projectkorra/airbending/AirMethods.java delete mode 100644 src/com/projectkorra/projectkorra/airbending/FlightAbility.java create mode 100644 src/com/projectkorra/projectkorra/avatar/AvatarState.java delete mode 100644 src/com/projectkorra/projectkorra/chiblocking/ChiMethods.java delete mode 100644 src/com/projectkorra/projectkorra/command/CopyCommand.java delete mode 100644 src/com/projectkorra/projectkorra/configuration/ConfigLoadable.java create mode 100644 src/com/projectkorra/projectkorra/earthbending/CollapseWall.java delete mode 100644 src/com/projectkorra/projectkorra/earthbending/CompactColumn.java delete mode 100644 src/com/projectkorra/projectkorra/earthbending/EarthColumn.java delete mode 100644 src/com/projectkorra/projectkorra/earthbending/EarthMethods.java delete mode 100644 src/com/projectkorra/projectkorra/earthbending/EarthWall.java create mode 100644 src/com/projectkorra/projectkorra/earthbending/LavaSurgeWall.java create mode 100644 src/com/projectkorra/projectkorra/earthbending/LavaSurgeWave.java delete mode 100644 src/com/projectkorra/projectkorra/earthbending/LavaWall.java delete mode 100644 src/com/projectkorra/projectkorra/earthbending/LavaWave.java create mode 100644 src/com/projectkorra/projectkorra/earthbending/RaiseEarth.java create mode 100644 src/com/projectkorra/projectkorra/earthbending/RaiseEarthWall.java delete mode 100644 src/com/projectkorra/projectkorra/firebending/ArcOfFire.java create mode 100644 src/com/projectkorra/projectkorra/firebending/Blaze.java create mode 100644 src/com/projectkorra/projectkorra/firebending/BlazeArc.java create mode 100644 src/com/projectkorra/projectkorra/firebending/BlazeRing.java delete mode 100644 src/com/projectkorra/projectkorra/firebending/Cook.java delete mode 100644 src/com/projectkorra/projectkorra/firebending/Enflamed.java delete mode 100644 src/com/projectkorra/projectkorra/firebending/Extinguish.java create mode 100644 src/com/projectkorra/projectkorra/firebending/FireBlastCharged.java create mode 100644 src/com/projectkorra/projectkorra/firebending/FireDamageTimer.java delete mode 100644 src/com/projectkorra/projectkorra/firebending/FireStream.java delete mode 100644 src/com/projectkorra/projectkorra/firebending/Fireball.java delete mode 100644 src/com/projectkorra/projectkorra/firebending/HeatControl.java create mode 100644 src/com/projectkorra/projectkorra/firebending/HeatControlCook.java create mode 100644 src/com/projectkorra/projectkorra/firebending/HeatControlExtinguish.java create mode 100644 src/com/projectkorra/projectkorra/firebending/HeatControlMelt.java create mode 100644 src/com/projectkorra/projectkorra/firebending/HeatControlSolidify.java delete mode 100644 src/com/projectkorra/projectkorra/firebending/HeatMelt.java delete mode 100644 src/com/projectkorra/projectkorra/firebending/RingOfFire.java delete mode 100644 src/com/projectkorra/projectkorra/util/AbilityLoadable.java delete mode 100644 src/com/projectkorra/projectkorra/util/AbilityLoader.java delete mode 100644 src/com/projectkorra/projectkorra/util/ActionBar.java create mode 100644 src/com/projectkorra/projectkorra/util/BlockCacheElement.java delete mode 100644 src/com/projectkorra/projectkorra/waterbending/FreezeMelt.java delete mode 100644 src/com/projectkorra/projectkorra/waterbending/IceSpike.java delete mode 100644 src/com/projectkorra/projectkorra/waterbending/IceSpike2.java create mode 100644 src/com/projectkorra/projectkorra/waterbending/IceSpikeBlast.java create mode 100644 src/com/projectkorra/projectkorra/waterbending/IceSpikePillar.java create mode 100644 src/com/projectkorra/projectkorra/waterbending/IceSpikePillarField.java delete mode 100644 src/com/projectkorra/projectkorra/waterbending/Melt.java create mode 100644 src/com/projectkorra/projectkorra/waterbending/PhaseChangeFreeze.java create mode 100644 src/com/projectkorra/projectkorra/waterbending/PhaseChangeMelt.java create mode 100644 src/com/projectkorra/projectkorra/waterbending/PlantRegrowth.java delete mode 100644 src/com/projectkorra/projectkorra/waterbending/Plantbending.java delete mode 100644 src/com/projectkorra/projectkorra/waterbending/SpikeField.java create mode 100644 src/com/projectkorra/projectkorra/waterbending/SurgeWall.java create mode 100644 src/com/projectkorra/projectkorra/waterbending/SurgeWave.java delete mode 100644 src/com/projectkorra/projectkorra/waterbending/TorrentBurst.java create mode 100644 src/com/projectkorra/projectkorra/waterbending/TorrentWave.java create mode 100644 src/com/projectkorra/projectkorra/waterbending/WaterBubble.java delete mode 100644 src/com/projectkorra/projectkorra/waterbending/WaterMethods.java create mode 100644 src/com/projectkorra/projectkorra/waterbending/WaterSpoutWave.java delete mode 100644 src/com/projectkorra/projectkorra/waterbending/WaterWall.java delete mode 100644 src/com/projectkorra/projectkorra/waterbending/WaterWave.java delete mode 100644 src/com/projectkorra/projectkorra/waterbending/Wave.java diff --git a/src/com/projectkorra/projectkorra/BendingManager.java b/src/com/projectkorra/projectkorra/BendingManager.java index 04cc8727..b93a15a8 100644 --- a/src/com/projectkorra/projectkorra/BendingManager.java +++ b/src/com/projectkorra/projectkorra/BendingManager.java @@ -1,32 +1,26 @@ package com.projectkorra.projectkorra; -import com.projectkorra.projectkorra.ability.AvatarState; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.FireAbility; import com.projectkorra.projectkorra.chiblocking.ChiCombo; -import com.projectkorra.projectkorra.chiblocking.RapidPunch; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.firebending.FireMethods; +import com.projectkorra.projectkorra.configuration.ConfigManager; import com.projectkorra.projectkorra.object.HorizontalVelocityTracker; import com.projectkorra.projectkorra.util.Flight; import com.projectkorra.projectkorra.util.RevertChecker; import com.projectkorra.projectkorra.util.TempPotionEffect; -import com.projectkorra.projectkorra.waterbending.WaterMethods; import org.bukkit.Bukkit; import org.bukkit.World; +import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import java.util.HashMap; import java.util.UUID; -public class BendingManager implements Runnable, ConfigLoadable { +public class BendingManager implements Runnable { private static BendingManager instance; - - private static String sunriseMessage = config.get().getString("Properties.Fire.DayMessage"); - private static String sunsetMessage = config.get().getString("Properties.Fire.NightMessage"); - - private static String moonriseMessage = config.get().getString("Properties.Water.NightMessage"); - private static String moonsetMessage = config.get().getString("Properties.Water.DayMessage"); + public static HashMap events = new HashMap(); // holds any current event. long time; long interval; @@ -55,34 +49,44 @@ public class BendingManager implements Runnable, ConfigLoadable { public void handleDayNight() { for (World world : Bukkit.getServer().getWorlds()) { if (!times.containsKey(world)) { - if (FireMethods.isDay(world)) { + if (FireAbility.isDay(world)) { times.put(world, true); } else { times.put(world, false); } } else { - if (times.get(world) && !FireMethods.isDay(world)) { + if (times.get(world) && !FireAbility.isDay(world)) { // The hashmap says it is day, but it is not. times.put(world, false); // Sets time to night. for (Player player : world.getPlayers()) { - if (GeneralMethods.isBender(player.getName(), Element.Water) && player.hasPermission("bending.message.daymessage")) { - player.sendMessage(WaterMethods.getWaterColor() + moonriseMessage); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + continue; } - if (GeneralMethods.isBender(player.getName(), Element.Fire) && player.hasPermission("bending.message.nightmessage")) { - player.sendMessage(FireMethods.getFireColor() + sunsetMessage); + + if (bPlayer.hasElement(Element.WATER) && player.hasPermission("bending.message.daymessage")) { + player.sendMessage(Element.WATER.getColor() + getMoonriseMessage()); + } + if (bPlayer.hasElement(Element.FIRE) && player.hasPermission("bending.message.nightmessage")) { + player.sendMessage(Element.FIRE.getColor() + getSunsetMessage()); } } } - if (!times.get(world) && FireMethods.isDay(world)) { + if (!times.get(world) && FireAbility.isDay(world)) { // The hashmap says it is night, but it is day. times.put(world, true); for (Player player : world.getPlayers()) { - if (GeneralMethods.isBender(player.getName(), Element.Water) && player.hasPermission("bending.message.nightmessage")) { - player.sendMessage(WaterMethods.getWaterColor() + moonsetMessage); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + continue; } - if (GeneralMethods.isBender(player.getName(), Element.Fire) && player.hasPermission("bending.message.daymessage")) { - player.sendMessage(FireMethods.getFireColor() + sunriseMessage); + + if (bPlayer.hasElement(Element.WATER) && player.hasPermission("bending.message.nightmessage")) { + player.sendMessage(Element.WATER.getColor() + getMoonsetMessage()); + } + if (bPlayer.hasElement(Element.FIRE) && player.hasPermission("bending.message.daymessage")) { + player.sendMessage(Element.FIRE.getColor() + getSunriseMessage()); } } } @@ -96,29 +100,54 @@ public class BendingManager implements Runnable, ConfigLoadable { time = System.currentTimeMillis(); ProjectKorra.time_step = interval; - AvatarState.manageAvatarStates(); + CoreAbility.progressAll(); TempPotionEffect.progressAll(); handleDayNight(); Flight.handle(); - RapidPunch.startPunchAll(); RevertChecker.revertAirBlocks(); ChiCombo.handleParalysis(); HorizontalVelocityTracker.updateAll(); handleCooldowns(); - } - catch (Exception e) { - //GeneralMethods.stopBending(); + } catch (Exception e) { + GeneralMethods.stopBending(); e.printStackTrace(); } } - @Override - public void reloadVariables() { - sunriseMessage = config.get().getString("Properties.Fire.DayMessage"); - sunsetMessage = config.get().getString("Properties.Fire.NightMessage"); - - moonriseMessage = config.get().getString("Properties.Water.NightMessage"); - moonsetMessage = config.get().getString("Properties.Water.DayMessage"); + public static String getSozinsCometMessage() { + return getConfig().getString("Properties.Fire.CometMessage"); } + public static String getSolarEclipseMessage() { + return getConfig().getString("Properties.Fire.SolarEclipseMessage"); + } + + public static String getSunriseMessage() { + return getConfig().getString("Properties.Fire.DayMessage"); + } + + public static String getSunsetMessage() { + return getConfig().getString("Properties.Fire.NightMessage"); + } + + public static String getMoonriseMessage() { + return getConfig().getString("Properties.Water.NightMessage"); + } + + public static String getFullMoonriseMessage() { + return getConfig().getString("Properties.Water.FullMoonMessage"); + } + + public static String getLunarEclipseMessage() { + return getConfig().getString("Properties.Water.LunarEclipseMessage"); + } + + public static String getMoonsetMessage() { + return getConfig().getString("Properties.Water.DayMessage"); + } + + private static FileConfiguration getConfig() { + return ConfigManager.getConfig(); + } + } diff --git a/src/com/projectkorra/projectkorra/BendingPlayer.java b/src/com/projectkorra/projectkorra/BendingPlayer.java index 2ff87865..23e2785c 100644 --- a/src/com/projectkorra/projectkorra/BendingPlayer.java +++ b/src/com/projectkorra/projectkorra/BendingPlayer.java @@ -1,23 +1,25 @@ package com.projectkorra.projectkorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.ability.api.CoreAbility; -import com.projectkorra.projectkorra.ability.api.FireAbility; -import com.projectkorra.projectkorra.ability.api.SubAbility; -import com.projectkorra.projectkorra.ability.api.WaterAbility; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.chiblocking.ChiMethods; +import com.projectkorra.projectkorra.Element.SubElement; +import com.projectkorra.projectkorra.ability.Ability; +import com.projectkorra.projectkorra.ability.ChiAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.ability.SubAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.chiblocking.Paralyze; import com.projectkorra.projectkorra.command.Commands; import com.projectkorra.projectkorra.configuration.ConfigManager; -import com.projectkorra.projectkorra.earthbending.EarthMethods; +import com.projectkorra.projectkorra.earthbending.MetalClips; import com.projectkorra.projectkorra.event.PlayerCooldownChangeEvent; import com.projectkorra.projectkorra.event.PlayerCooldownChangeEvent.Result; -import com.projectkorra.projectkorra.firebending.FireMethods; import com.projectkorra.projectkorra.storage.DBConnection; -import com.projectkorra.projectkorra.waterbending.WaterMethods; +import com.projectkorra.projectkorra.waterbending.Bloodbending; import org.bukkit.Bukkit; import org.bukkit.GameMode; +import org.bukkit.Location; import org.bukkit.OfflinePlayer; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; @@ -29,30 +31,28 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; /** - * Class that presents a player and stores all bending information about the - * player. + * Class that presents a player and stores all bending information about the player. */ public class BendingPlayer { /** - * ConcurrentHashMap that contains all instances of BendingPlayer, with UUID - * key. + * ConcurrentHashMap that contains all instances of BendingPlayer, with UUID key. */ - private static ConcurrentHashMap players = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap PLAYERS = new ConcurrentHashMap<>(); + private boolean permaRemoved; + private boolean toggled; + private boolean tremorSense; + private boolean chiBlocked; + private long slowTime; + private Player player; private UUID uuid; private String name; - private Player player; - private FileConfiguration config; + private ChiAbility stance; private ArrayList elements; private HashMap abilities; private ConcurrentHashMap cooldowns; - private ConcurrentHashMap toggledElements; - private boolean permaRemoved; - private boolean toggled = true; - private long slowTime = 0; - private boolean tremorSense = true; - private boolean chiBlocked = false; + private ConcurrentHashMap toggledElements; /** * Creates a new {@link BendingPlayer}. @@ -63,44 +63,45 @@ public class BendingPlayer { * @param abilities The known abilities * @param permaRemoved The permanent removed status */ - public BendingPlayer(UUID uuid, String playerName, ArrayList elements, HashMap abilities, boolean permaRemoved) { + public BendingPlayer(UUID uuid, String playerName, ArrayList elements, HashMap abilities, + boolean permaRemoved) { this.uuid = uuid; this.name = playerName; this.elements = elements; this.setAbilities(abilities); this.permaRemoved = permaRemoved; this.player = Bukkit.getPlayer(uuid); - this.config = ConfigManager.getConfig(); + this.toggled = true; + this.tremorSense = true; + this.chiBlocked = false; cooldowns = new ConcurrentHashMap(); toggledElements = new ConcurrentHashMap(); - toggledElements.put(Element.Air, true); - toggledElements.put(Element.Earth, true); - toggledElements.put(Element.Fire, true); - toggledElements.put(Element.Water, true); - toggledElements.put(Element.Chi, true); + toggledElements.put(Element.AIR, true); + toggledElements.put(Element.EARTH, true); + toggledElements.put(Element.FIRE, true); + toggledElements.put(Element.WATER, true); + toggledElements.put(Element.CHI, true); - players.put(uuid, this); + PLAYERS.put(uuid, this); PKListener.login(this); } + + public void addCooldown(Ability ability, long cooldown) { + addCooldown(ability.getName(), cooldown); + } - /** - * Gets the map of {@link BendingPlayer}s. - * - * @return {@link #players} - */ - public static ConcurrentHashMap getPlayers() { - return players; + public void addCooldown(CoreAbility ability) { + addCooldown(ability, ability.getCooldown()); } /** - * Adds an ability to the cooldowns map while firing a - * {@link PlayerCooldownChangeEvent}. + * Adds an ability to the cooldowns map while firing a {@link PlayerCooldownChangeEvent}. * * @param ability Name of the ability * @param cooldown The cooldown time */ public void addCooldown(String ability, long cooldown) { - PlayerCooldownChangeEvent event = new PlayerCooldownChangeEvent(Bukkit.getPlayer(uuid), ability, cooldown, Result.ADDED); + PlayerCooldownChangeEvent event = new PlayerCooldownChangeEvent(Bukkit.getPlayer(uuid), ability, Result.ADDED); Bukkit.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { this.cooldowns.put(ability, cooldown + System.currentTimeMillis()); @@ -112,8 +113,8 @@ public class BendingPlayer { * * @param e The element to add */ - public void addElement(Element e) { - this.elements.add(e); + public void addElement(Element element) { + this.elements.add(element); } /** @@ -123,6 +124,109 @@ public class BendingPlayer { chiBlocked = true; } + /** + * Checks to see if a Player is effected by BloodBending. + * + * @return true If {@link ChiMethods#isChiBlocked(String)} is true
+ * false If player is BloodBender and Bending is toggled on, or if player is in + * AvatarState + */ + public boolean canBeBloodbent() { + if (isAvatarState()) { + if (isChiBlocked()) { + return true; + } + } + if (canBendIgnoreBindsCooldowns(CoreAbility.getAbility("Bloodbending")) && !isToggled()) { + return false; + } + return true; + } + + public boolean canBend(CoreAbility ability) { + return canBend(ability, false, false); + } + + private boolean canBend(CoreAbility ability, boolean ignoreBinds, boolean ignoreCooldowns) { + if (ability == null) { + return false; + } + + List disabledWorlds = getConfig().getStringList("Properties.DisabledWorlds"); + Location location = null; + + if (player != null) { + location = player.getLocation(); + } + + if (player == null || !player.isOnline() || player.isDead()) { + return false; + } else if (location != null && !location.getWorld().equals(player.getWorld())) { + return false; + } else if (!ignoreCooldowns && isOnCooldown(ability.getName())) { + return false; + } else if (!ignoreBinds && !ability.getName().equals(getBoundAbilityName())) { + return false; + } else if (disabledWorlds != null && disabledWorlds.contains(player.getWorld().getName())) { + return false; + } else if (Commands.isToggledForAll || !isToggled() || !isElementToggled(ability.getElement())) { + return false; + } else if (player.getGameMode() == GameMode.SPECTATOR) { + return false; + } + + if (!ignoreCooldowns && cooldowns.containsKey(name)) { // TODO: wtf is this + if (cooldowns.get(name) + getConfig().getLong("Properties.GlobalCooldown") >= System.currentTimeMillis()) { + return false; + } + cooldowns.remove(name); + } + + if (isChiBlocked() || isParalyzed() || isBloodbended() || isControlledByMetalClips()) { + return false; + } else if (GeneralMethods.isRegionProtectedFromBuild(player, ability.getName(), location)) { + return false; + } else if (ability instanceof FireAbility && BendingManager.events.get(player.getWorld()) != null + && BendingManager.events.get(player.getWorld()).equalsIgnoreCase("SolarEclipse")) { + return false; + } else if (ability instanceof WaterAbility && BendingManager.events.get(player.getWorld()) != null + && BendingManager.events.get(player.getWorld()).equalsIgnoreCase("LunarEclipse")) { + return false; + } + + if (!ignoreBinds && !canBind(ability)) { + return false; + } + return true; + } + + public boolean canBendIgnoreBinds(CoreAbility ability) { + return canBend(ability, true, false); + } + + public boolean canBendIgnoreBindsCooldowns(CoreAbility ability) { + return canBend(ability, true, true); + } + + public boolean canBendIgnoreCooldowns(CoreAbility ability) { + return canBend(ability, false, true); + } + + public boolean canBendPassive(Element element) { + if (element == null || player == null) { + return false; + } else if (!player.hasPermission("bending." + element.getName() + ".passive")) { + return false; + } else if (!isToggled() || !hasElement(element) || !isElementToggled(element)) { + return false; + } else if (isChiBlocked() || isParalyzed() || isBloodbended()) { + return false; + } else if (GeneralMethods.isRegionProtectedFromBuild(player, player.getLocation())) { + return false; + } + return true; + } + /** * Checks to see if {@link BendingPlayer} can be slowed. * @@ -132,41 +236,18 @@ public class BendingPlayer { return (System.currentTimeMillis() > slowTime); } - /** - * Checks to see if a player can use Flight. - * - * @return true If player has permission node "bending.air.flight" - */ - public boolean canAirFlight() { - return player.hasPermission("bending.air.flight"); - } - - /** - * Checks to see if a player can use SpiritualProjection. - * - * @param player The player to check - * @return true If player has permission node - * "bending.air.spiritualprojection" - */ - public boolean canUseSpiritualProjection() { - return player.hasPermission("bending.air.spiritualprojection"); - } - - /** - * Checks to see if a Player is effected by BloodBending. - * - * @return true If {@link ChiMethods#isChiBlocked(String)} is true
- * false If player is BloodBender and Bending is toggled on, or if - * player is in AvatarState - */ - public boolean canBeBloodbent() { - if (AvatarState.isAvatarState(player)) { - if (ChiMethods.isChiBlocked(name)) { - return true; - } - } - if (GeneralMethods.canBend(name, "Bloodbending") && !isToggled()) { + public boolean canBind(CoreAbility ability) { + if (ability == null || !player.isOnline()) { return false; + } else if (!player.hasPermission("bending.ability." + ability.getName())) { + return false; + } else if (!hasElement(ability.getElement())) { + return false; + } else if (ability instanceof SubAbility) { + SubAbility subAbil = (SubAbility) ability; + if (!hasElement(subAbil.getParentElement())) { + return false; + } } return true; } @@ -179,30 +260,58 @@ public class BendingPlayer { public boolean canBloodbend() { return player.hasPermission("bending.water.bloodbending"); } - + public boolean canBloodbendAtAnytime() { return canBloodbend() && player.hasPermission("bending.water.bloodbending.anytime"); } + public boolean canCombustionbend() { + return player.hasPermission("bending.fire.combustionbending"); + } + public boolean canIcebend() { return player.hasPermission("bending.water.icebending"); } + /** + * Checks to see if a player can LavaBend. + * + * @param player The player to check + * @return true If player has permission node "bending.earth.lavabending" + */ + public boolean canLavabend() { + return player.hasPermission("bending.earth.lavabending"); + } + + public boolean canLightningbend() { + return player.hasPermission("bending.fire.lightningbending"); + } + + /** + * Checks to see if a player can MetalBend. + * + * @param player The player to check + * @return true If player has permission node "bending.earth.metalbending" + */ + public boolean canMetalbend() { + return player.hasPermission("bending.earth.metalbending"); + } + + public boolean canPackedIcebend() { + return getConfig().getBoolean("Properties.Water.CanBendPackedIce"); + } + /** * Checks to see if a player can PlantBend. * * @param player The player to check * @return true If player has permission node "bending.ability.plantbending" */ - public static boolean canPlantbend(Player player) { + public boolean canPlantbend() { return player.hasPermission("bending.water.plantbending"); } - public boolean canWaterHeal() { - return player.hasPermission("bending.water.healing"); - } - /** * Checks to see if a player can SandBend. * @@ -214,31 +323,26 @@ public class BendingPlayer { } /** - * Checks to see if a player can MetalBend. + * Checks to see if a player can use Flight. * - * @param player The player to check - * @return true If player has permission node "bending.earth.metalbending" + * @return true If player has permission node "bending.air.flight" */ - public boolean canMetalbend() { - return player.hasPermission("bending.earth.metalbending"); + public boolean canUseFlight() { + return player.hasPermission("bending.air.flight"); } /** - * Checks to see if a player can LavaBend. + * Checks to see if a player can use SpiritualProjection. * * @param player The player to check - * @return true If player has permission node "bending.earth.lavabending" + * @return true If player has permission node "bending.air.spiritualprojection" */ - public static boolean canLavabend(Player player) { - return player.hasPermission("bending.earth.lavabending"); + public boolean canUseSpiritualProjection() { + return player.hasPermission("bending.air.spiritualprojection"); } - public static boolean canCombustionbend(Player player) { - return player.hasPermission("bending.fire.combustionbending"); - } - - public static boolean canLightningbend(Player player) { - return player.hasPermission("bending.fire.lightningbending"); + public boolean canWaterHeal() { + return player.hasPermission("bending.water.healing"); } /** @@ -250,6 +354,21 @@ public class BendingPlayer { return this.abilities; } + public CoreAbility getBoundAbility() { + return CoreAbility.getAbility(getBoundAbilityName()); + } + + /** + * Gets the Ability bound to the slot that the player is in. + * + * @return The Ability name bounded to the slot + */ + public String getBoundAbilityName() { + int slot = player.getInventory().getHeldItemSlot() + 1; + String name = getAbilities().get(slot); + return name != null ? name : ""; + } + /** * Gets the cooldown time of the ability. * @@ -265,7 +384,7 @@ public class BendingPlayer { } return -1; } - + /** * Gets the map of cooldowns of the {@link BendingPlayer}. * @@ -293,6 +412,15 @@ public class BendingPlayer { return this.name; } + /** + * Gets the {@link ChiAbility Chi stance} the player is in + * + * @return The player's stance object + */ + public ChiAbility getStance() { + return stance; + } + /** * Gets the unique identifier of the {@link BendingPlayer}. * @@ -310,22 +438,43 @@ public class BendingPlayer { public String getUUIDString() { return this.uuid.toString(); } - + /** * Checks to see if the {@link BendingPlayer} knows a specific element. * - * @param e The element to check + * @param element The element to check * @return true If the player knows the element */ - public boolean hasElement(Element e) { - return this.elements.contains(e); + public boolean hasElement(Element element) { + if (element == null) { + return false; + } else if (element == Element.AVATAR) { + // At the moment we'll allow for both permissions to return true. + // Later on we can consider deleting the bending.ability.avatarstate option. + return player.hasPermission("bending.avatar") || player.hasPermission("bending.ability.AvatarState"); + } else if (!(element instanceof SubElement)) { + return this.elements.contains(element); + } else { + Element parentElement = ((SubElement) element).getParentElement(); + String prefix = "bending." + parentElement.getName() + "."; + + // Some permissions are bending.water.name and some are bending.water.namebending + if (player.hasPermission(prefix + element.getName()) + || player.hasPermission(prefix + element.getName() + "bending")) { + return true; + } + } + return false; } - public boolean hasElement(String elementName) { - //TODO: Finish this - return true; + public boolean isAvatarState() { + return CoreAbility.hasAbility(player, AvatarState.class); } - + + public boolean isBloodbended() { + return Bloodbending.isBloodbended(player); + } + /** * Checks to see if the {@link BendingPlayer} is chi blocked. * @@ -335,12 +484,21 @@ public class BendingPlayer { return this.chiBlocked; } - public boolean isElementToggled(Element e) { - if (e != null) - return this.toggledElements.get(e); + public boolean isControlledByMetalClips() { + return MetalClips.isControlled(player); + } + + public boolean isElementToggled(Element element) { + if (element != null && toggledElements.containsKey(element)) { + return toggledElements.containsKey(element); + } return true; } + public boolean isOnCooldown(Ability ability) { + return isOnCooldown(ability.getName()); + } + /** * Checks to see if a specific ability is on cooldown. * @@ -348,7 +506,14 @@ public class BendingPlayer { * @return true if the cooldown map contains the ability */ public boolean isOnCooldown(String ability) { - return this.cooldowns.containsKey(ability); + if (this.cooldowns.containsKey(ability)) { + return System.currentTimeMillis() < cooldowns.get(ability); + } + return false; + } + + public boolean isParalyzed() { + return Paralyze.isParalyzed(player); } /** @@ -368,11 +533,6 @@ public class BendingPlayer { public boolean isToggled() { return this.toggled; } - - public boolean isElementToggled(String elementName) { - // TODO: Finish this - return true; - } /** * Checks if the {@link BendingPlayer} is tremor sensing. @@ -383,13 +543,19 @@ public class BendingPlayer { return this.tremorSense; } + public void removeCooldown(CoreAbility ability) { + if (ability != null) { + removeCooldown(ability.getName()); + } + } + /** * Removes the cooldown of an ability. * * @param ability The ability's cooldown to remove */ public void removeCooldown(String ability) { - PlayerCooldownChangeEvent event = new PlayerCooldownChangeEvent(Bukkit.getPlayer(uuid), ability, 0, Result.REMOVED); + PlayerCooldownChangeEvent event = new PlayerCooldownChangeEvent(Bukkit.getPlayer(uuid), ability, Result.REMOVED); Bukkit.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { this.cooldowns.remove(ability); @@ -397,8 +563,8 @@ public class BendingPlayer { } /** - * Sets the {@link BendingPlayer}'s abilities. This method also saves the - * abilities to the database. + * Sets the {@link BendingPlayer}'s abilities. This method also saves the abilities to the + * database. * * @param abilities The abilities to set/save */ @@ -410,14 +576,14 @@ public class BendingPlayer { } /** - * Sets the {@link BendingPlayer}'s element. If the player had elements - * before they will be overwritten. + * Sets the {@link BendingPlayer}'s element. If the player had elements before they will be + * overwritten. * * @param e The element to set */ - public void setElement(Element e) { + public void setElement(Element element) { this.elements.clear(); - this.elements.add(e); + this.elements.add(element); } /** @@ -428,6 +594,15 @@ public class BendingPlayer { public void setPermaRemoved(boolean permaRemoved) { this.permaRemoved = permaRemoved; } + + /** + * Sets the player's {@link ChiAbility Chi stance} + * + * @param stance The player's new stance object + */ + public void setStance(ChiAbility stance) { + this.stance = stance; + } /** * Slow the {@link BendingPlayer} for a certain amount of time. @@ -437,7 +612,7 @@ public class BendingPlayer { public void slow(long cooldown) { slowTime = System.currentTimeMillis() + cooldown; } - + /** * Toggles the {@link BendingPlayer}'s bending. */ @@ -445,10 +620,13 @@ public class BendingPlayer { toggled = !toggled; } - public void toggleElement(Element e) { - toggledElements.put(e, !toggledElements.get(e)); + public void toggleElement(Element element) { + if (element == null) { + return; + } + toggledElements.put(element, !toggledElements.get(element)); } - + /** * Toggles the {@link BendingPlayer}'s tremor sensing. */ @@ -462,75 +640,27 @@ public class BendingPlayer { public void unblockChi() { chiBlocked = false; } - - public boolean canBend(CoreAbility ability) { - if (player == null) { - return false; + + public static BendingPlayer getBendingPlayer(OfflinePlayer oPlayer) { + if (oPlayer == null) { + return null; } - if (isOnCooldown(ability.getName())) { - return false; - } - List disabledWorlds = config.getStringList("Properties.DisabledWorlds"); - if (disabledWorlds != null && disabledWorlds.contains(player.getWorld().getName())) { - return false; - } - if (Commands.isToggledForAll || !isToggled() || !isElementToggled(ability.getName())) { - return false; - } - if (player.getGameMode() == GameMode.SPECTATOR) { - return false; - } - if (cooldowns.containsKey(name)) { - if (cooldowns.get(name) + config.getLong("Properties.GlobalCooldown") >= System.currentTimeMillis()) { - return false; - } - cooldowns.remove(name); - } - if (isChiBlocked() || isParalyzed() || isBloodbended() || isControlledByMetalClips()) { - return false; - } - if (GeneralMethods.isRegionProtectedFromBuild(player, ability.getName(), player.getLocation())) { - return false; - } - if (ability instanceof FireAbility && BendingManager.events.get(player.getWorld()) != null && BendingManager.events.get(player.getWorld()).equalsIgnoreCase("SolarEclipse")) { - return false; - } - if (ability instanceof WaterAbility && BendingManager.events.get(player.getWorld()) != null && BendingManager.events.get(player.getWorld()).equalsIgnoreCase("LunarEclipse")) { - return false; - } - if (!canBind(ability)) { - return false; - } - return true; + return BendingPlayer.getPlayers().get(oPlayer.getUniqueId()); } - public boolean canBind(CoreAbility ability) { + public static BendingPlayer getBendingPlayer(Player player) { if (player == null) { - return false; + return null; } - if (!player.hasPermission("bending.ability." + ability)) { - return false; - } - if (!hasElement(ability.getElementName())) { - return false; - } - if (ability instanceof SubAbility) { - SubAbility subAbil = (SubAbility) ability; - if (!hasElement(subAbil.getSubElementName())) { - return false; - } - } - return true; + return getBendingPlayer(player.getName()); } - + /** - * Attempts to get a {@link BendingPlayer} from specified player name. this - * method tries to get a {@link Player} object and gets the uuid and then - * calls {@link #getBendingPlayer(UUID)} + * Attempts to get a {@link BendingPlayer} from specified player name. this method tries to get + * a {@link Player} object and gets the uuid and then calls {@link #getBendingPlayer(UUID)} * * @param playerName The name of the Player - * @return The BendingPlayer object if {@link BendingPlayer#players} - * contains the player name + * @return The BendingPlayer object if {@link BendingPlayer#PLAYERS} contains the player name * * @see #getBendingPlayer(UUID) */ @@ -539,7 +669,19 @@ public class BendingPlayer { if (player == null) { oPlayer = Bukkit.getOfflinePlayer(oPlayer.getUniqueId()); } - return BendingPlayer.getPlayers().get(oPlayer.getUniqueId()); + return getBendingPlayer(oPlayer); } + private static FileConfiguration getConfig() { + return ConfigManager.getConfig(); + } + + /** + * Gets the map of {@link BendingPlayer}s. + * + * @return {@link #PLAYERS} + */ + public static ConcurrentHashMap getPlayers() { + return PLAYERS; + } } diff --git a/src/com/projectkorra/projectkorra/Element.java b/src/com/projectkorra/projectkorra/Element.java index be0dabd3..e3a70196 100644 --- a/src/com/projectkorra/projectkorra/Element.java +++ b/src/com/projectkorra/projectkorra/Element.java @@ -1,92 +1,90 @@ package com.projectkorra.projectkorra; -import java.util.Arrays; - import org.bukkit.ChatColor; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.chiblocking.ChiMethods; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.firebending.FireMethods; -import com.projectkorra.projectkorra.waterbending.WaterMethods; +import java.util.HashMap; -public enum Element { +public class Element { - Air (AirMethods.getAirColor(), AirMethods.getAirSubColor()), - Water (WaterMethods.getWaterColor(), WaterMethods.getWaterSubColor()), - Earth (EarthMethods.getEarthColor(), EarthMethods.getEarthSubColor()), - Fire (FireMethods.getFireColor(), FireMethods.getFireSubColor()), - Chi (ChiMethods.getChiColor(), ChiMethods.getChiColor()); + private static final HashMap ALL_ELEMENTS = new HashMap<>(); // Must be initialized first - private ChatColor color, subcolor; + public static final Element AIR = new Element("Air"); + public static final Element WATER = new Element("Water"); + public static final Element EARTH = new Element("Earth"); + public static final Element FIRE = new Element("Fire"); + public static final Element CHI = new Element("Chi"); + public static final Element AVATAR = new Element("Avatar"); + public static final SubElement FLIGHT = new SubElement("Flight", AIR); + public static final SubElement SPIRITUAL = new SubElement("Spiritual", AIR); + public static final SubElement BLOOD = new SubElement("Blood", WATER); + public static final SubElement HEALING = new SubElement("Healing", WATER); + public static final SubElement ICE = new SubElement("Ice", WATER); + public static final SubElement PLANT = new SubElement("Plant", WATER); + public static final SubElement LAVA = new SubElement("Lava", EARTH); + public static final SubElement METAL = new SubElement("Metal", EARTH); + public static final SubElement SAND = new SubElement("Sand", EARTH); + public static final SubElement LIGHTNING = new SubElement("Lightning", FIRE); + public static final SubElement COMBUSTION = new SubElement("Combustion", FIRE); + + private static final Element[] ELEMENTS = {AIR, WATER, EARTH, FIRE, CHI, FLIGHT, SPIRITUAL, BLOOD, HEALING, ICE, PLANT, LAVA, METAL, SAND, LIGHTNING, COMBUSTION}; + private static final Element[] MAIN_ELEMENTS = {AIR, WATER, EARTH, FIRE, CHI}; + private static final SubElement[] SUB_ELEMENTS = {FLIGHT, SPIRITUAL, BLOOD, HEALING, ICE, PLANT, LAVA, METAL, SAND, LIGHTNING, COMBUSTION}; + + private String name; - Element(ChatColor mainColor, ChatColor subColor) { - this.color = mainColor; - this.subcolor = subColor; + private Element(String name) { + this.name = name; + ALL_ELEMENTS.put(name.toLowerCase(), this); } - /** - * Returns the chatcolor to be used associated with this element - * @return The Element ChatColor - * */ - public ChatColor getChatColor() { - return color; + public ChatColor getColor() { + return ChatColor.valueOf(ProjectKorra.plugin.getConfig().getString("Properties.Chat.Colors." + name)); } - /** - * Returns the chatcolor that's associated the sub-elements of this element - * @return The SubElement ChatColor - * */ - public ChatColor getSubColor() { - return subcolor; + public String getName() { + return name; } - /** - * Returns all the subelements that should be associated with this element - * @return The Element's SubElements - * */ - public SubElement[] getSubElements() { - if (this == Air) { - return new SubElement[] {SubElement.Flight, SubElement.SpiritualProjection}; - } - if (this == Water) { - return new SubElement[] {SubElement.Bloodbending, SubElement.Icebending, SubElement.Plantbending, SubElement.Healing}; - } - if (this == Fire) { - return new SubElement[] {SubElement.Combustion, SubElement.Lightning}; - } - if (this == Earth) { - return new SubElement[] {SubElement.Sandbending, SubElement.Metalbending, SubElement.Lavabending}; - } - return new SubElement[] {}; + @Override + public String toString() { + return getColor() + getName(); } - public static Element getType(String string) { - for (Element element : Element.values()) { - if (element.toString().equalsIgnoreCase(string)) { - return element; - } - } - return null; - } - - public static Element getType(int index) { - if (index == -1) + public static Element getElement(String name) { + if (name == null) { return null; - return Arrays.asList(values()).get(index); + } + return ALL_ELEMENTS.get(name.toLowerCase()); } - /** - * Returns an element based on ChatColor. - * @param color - * @return - */ - public static Element getFromChatColor(ChatColor color) { - for (Element element : Element.values()) { - if (element.getChatColor().equals(color) || element.getSubColor().equals(color)) { - return element; - } + public static Element[] getElements() { + return ELEMENTS; + } + + public static Element[] getMainElements() { + return MAIN_ELEMENTS; + } + + public static SubElement[] getSubElements() { + return SUB_ELEMENTS; + } + + public static class SubElement extends Element { + + private Element parentElement; + + private SubElement(String name, Element parentElement) { + super(name); + this.parentElement = parentElement; + } + + @Override + public ChatColor getColor() { + return ChatColor.valueOf(ProjectKorra.plugin.getConfig().getString("Properties.Chat.Colors." + parentElement.name + "Sub")); + } + + public Element getParentElement() { + return this.parentElement; } - return null; } } diff --git a/src/com/projectkorra/projectkorra/GeneralMethods.java b/src/com/projectkorra/projectkorra/GeneralMethods.java index b58e2494..2577a7ef 100644 --- a/src/com/projectkorra/projectkorra/GeneralMethods.java +++ b/src/com/projectkorra/projectkorra/GeneralMethods.java @@ -26,51 +26,39 @@ import com.palmergames.bukkit.towny.object.WorldCoord; import com.palmergames.bukkit.towny.utils.PlayerCacheUtil; import com.palmergames.bukkit.towny.war.flagwar.TownyWar; import com.palmergames.bukkit.towny.war.flagwar.TownyWarConfig; -import com.projectkorra.projectkorra.ability.AbilityModule; -import com.projectkorra.projectkorra.ability.AbilityModuleManager; -import com.projectkorra.projectkorra.ability.StockAbility; -import com.projectkorra.projectkorra.ability.api.Ability; -import com.projectkorra.projectkorra.ability.combo.ComboAbilityModule; -import com.projectkorra.projectkorra.ability.combo.ComboManager; -import com.projectkorra.projectkorra.ability.combo.ComboManager.AbilityInformation; -import com.projectkorra.projectkorra.ability.combo.ComboManager.ComboAbility; -import com.projectkorra.projectkorra.ability.combo.ComboModuleManager; -import com.projectkorra.projectkorra.ability.multiability.MultiAbilityManager; -import com.projectkorra.projectkorra.ability.multiability.MultiAbilityModuleManager; +import com.projectkorra.projectkorra.ability.Ability; +import com.projectkorra.projectkorra.ability.AddonAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.EarthAbility; +import com.projectkorra.projectkorra.ability.ElementalAbility; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.ability.util.ComboManager; +import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation; +import com.projectkorra.projectkorra.ability.util.MultiAbilityManager; import com.projectkorra.projectkorra.airbending.AirBlast; import com.projectkorra.projectkorra.airbending.AirCombo; -import com.projectkorra.projectkorra.airbending.AirMethods; import com.projectkorra.projectkorra.airbending.AirShield; import com.projectkorra.projectkorra.airbending.AirSpout; import com.projectkorra.projectkorra.airbending.AirSuction; import com.projectkorra.projectkorra.airbending.AirSwipe; -import com.projectkorra.projectkorra.chiblocking.ChiMethods; -import com.projectkorra.projectkorra.chiblocking.Paralyze; import com.projectkorra.projectkorra.command.Commands; import com.projectkorra.projectkorra.configuration.ConfigManager; import com.projectkorra.projectkorra.earthbending.EarthBlast; -import com.projectkorra.projectkorra.earthbending.EarthMethods; import com.projectkorra.projectkorra.earthbending.EarthPassive; -import com.projectkorra.projectkorra.earthbending.MetalClips; import com.projectkorra.projectkorra.event.BendingReloadEvent; import com.projectkorra.projectkorra.event.PlayerBendingDeathEvent; import com.projectkorra.projectkorra.firebending.Combustion; import com.projectkorra.projectkorra.firebending.FireBlast; import com.projectkorra.projectkorra.firebending.FireCombo; -import com.projectkorra.projectkorra.firebending.FireMethods; import com.projectkorra.projectkorra.firebending.FireShield; -import com.projectkorra.projectkorra.object.Preset; import com.projectkorra.projectkorra.storage.DBConnection; +import com.projectkorra.projectkorra.util.BlockCacheElement; import com.projectkorra.projectkorra.util.Flight; import com.projectkorra.projectkorra.util.ParticleEffect; import com.projectkorra.projectkorra.util.TempBlock; -import com.projectkorra.projectkorra.waterbending.Bloodbending; -import com.projectkorra.projectkorra.waterbending.FreezeMelt; -import com.projectkorra.projectkorra.waterbending.WaterCombo; import com.projectkorra.projectkorra.waterbending.WaterManipulation; -import com.projectkorra.projectkorra.waterbending.WaterMethods; import com.projectkorra.projectkorra.waterbending.WaterSpout; -import com.projectkorra.rpg.event.EventManager; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.protection.flags.DefaultFlag; @@ -79,13 +67,10 @@ import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.OfflinePlayer; -import org.bukkit.Sound; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.FallingBlock; @@ -128,39 +113,33 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Random; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @SuppressWarnings("deprecation") public class GeneralMethods { - public static List invincible = new ArrayList<>(); - - static ProjectKorra plugin; - - private static FileConfiguration config = ProjectKorra.plugin.getConfig(); - public static Random rand = new Random(); - - public static double CACHE_TIME = config.getDouble("Properties.RegionProtection.CacheBlockTime"); - public static ConcurrentHashMap cooldowns = new ConcurrentHashMap(); - + public static final Integer[] NON_OPAQUE = { 0, 6, 8, 9, 10, 11, 27, 28, 30, 31, 32, 37, 38, 39, 40, 50, 51, 55, 59, 66, 68, + 69, 70, 72, 75, 76, 77, 78, 83, 90, 93, 94, 104, 105, 106, 111, 115, 119, 127, 131, 132, 175 }; + public static final Material[] INTERACTABLE_MATERIALS = { Material.ACACIA_DOOR, Material.ACACIA_FENCE_GATE, Material.ANVIL, + Material.ARMOR_STAND, Material.BEACON, Material.BED, Material.BED_BLOCK, Material.BIRCH_DOOR, + Material.BIRCH_FENCE_GATE, Material.BOAT, Material.BREWING_STAND, Material.BURNING_FURNACE, + Material.CAKE_BLOCK, Material.CHEST, Material.COMMAND, Material.DARK_OAK_DOOR, + Material.DARK_OAK_FENCE_GATE, Material.DISPENSER, Material.DRAGON_EGG, Material.DROPPER, + Material.ENCHANTMENT_TABLE, Material.ENDER_CHEST, Material.ENDER_PORTAL_FRAME, Material.FENCE_GATE, + Material.FURNACE, Material.HOPPER, Material.HOPPER_MINECART, Material.COMMAND_MINECART, + Material.ITEM_FRAME, Material.JUKEBOX, Material.JUNGLE_DOOR, Material.JUNGLE_FENCE_GATE, + Material.LEVER, Material.MINECART, Material.NOTE_BLOCK, Material.PAINTING, Material.SPRUCE_DOOR, + Material.SPRUCE_FENCE_GATE, Material.STONE_BUTTON, Material.TRAPPED_CHEST, Material.TRAP_DOOR, + Material.WOOD_BUTTON, Material.WOOD_DOOR, Material.WORKBENCH }; + // Represents PlayerName, previously checked blocks, and whether they were true or false - public static ConcurrentHashMap> blockProtectionCache = new ConcurrentHashMap>(); - - public static Integer[] nonOpaque = { 0, 6, 8, 9, 10, 11, 27, 28, 30, 31, 32, 37, 38, 39, 40, 50, 51, 55, 59, 66, 68, 69, 70, 72, 75, 76, 77, 78, 83, 90, 93, 94, 104, 105, 106, 111, 115, 119, 127, 131, 132, 175 }; - public static Material[] interactable = { Material.ACACIA_DOOR, Material.ACACIA_FENCE_GATE, Material.ANVIL, Material.ARMOR_STAND, Material.BEACON, Material.BED, Material.BED_BLOCK, Material.BIRCH_DOOR, Material.BIRCH_FENCE_GATE, Material.BOAT, Material.BREWING_STAND, Material.BURNING_FURNACE, Material.CAKE_BLOCK, Material.CHEST, Material.COMMAND, Material.DARK_OAK_DOOR, Material.DARK_OAK_FENCE_GATE, Material.DISPENSER, Material.DRAGON_EGG, Material.DROPPER, Material.ENCHANTMENT_TABLE, Material.ENDER_CHEST, Material.ENDER_PORTAL_FRAME, Material.FENCE_GATE, Material.FURNACE, Material.HOPPER, Material.HOPPER_MINECART, Material.COMMAND_MINECART, Material.ITEM_FRAME, Material.JUKEBOX, Material.JUNGLE_DOOR, Material.JUNGLE_FENCE_GATE, Material.LEVER, Material.MINECART, Material.NOTE_BLOCK, Material.PAINTING, Material.SPRUCE_DOOR, Material.SPRUCE_FENCE_GATE, Material.STONE_BUTTON, Material.TRAPPED_CHEST, Material.TRAP_DOOR, Material.WOOD_BUTTON, Material.WOOD_DOOR, Material.WORKBENCH }; - - // Stands for toggled = false while logging out - public static List toggledOut = new ArrayList(); + private static final ConcurrentHashMap> BLOCK_CACHE = new ConcurrentHashMap<>(); + private static final ArrayList INVINCIBLE = new ArrayList<>(); + private static ProjectKorra plugin; public GeneralMethods(ProjectKorra plugin) { GeneralMethods.plugin = plugin; - new AirMethods(plugin); - new ChiMethods(plugin); - new EarthMethods(plugin); - new FireMethods(plugin); - new WaterMethods(plugin); } /** @@ -171,11 +150,7 @@ public class GeneralMethods { * @return true if ability exists */ public static boolean abilityExists(String string) { - for (String st : AbilityModuleManager.abilities) { - if (string.equalsIgnoreCase(st)) - return true; - } - return false; + return CoreAbility.getAbility(string) != null; } /** @@ -204,20 +179,16 @@ public class GeneralMethods { return; } - BendingPlayer bPlayer = getBendingPlayer(player.getName()); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player.getName()); + CoreAbility coreAbil = CoreAbility.getAbility(ability); + + if (bPlayer == null) { + return; + } bPlayer.getAbilities().put(slot, ability); - if (AirMethods.isAirAbility(ability)) { - player.sendMessage(AirMethods.getAirColor() + "Succesfully bound " + ability + " to slot " + slot); - } else if (WaterMethods.isWaterAbility(ability)) { - player.sendMessage(WaterMethods.getWaterColor() + "Succesfully bound " + ability + " to slot " + slot); - } else if (EarthMethods.isEarthAbility(ability)) { - player.sendMessage(EarthMethods.getEarthColor() + "Succesfully bound " + ability + " to slot " + slot); - } else if (FireMethods.isFireAbility(ability)) { - player.sendMessage(FireMethods.getFireColor() + "Succesfully bound " + ability + " to slot " + slot); - } else if (ChiMethods.isChiAbility(ability)) { - player.sendMessage(ChiMethods.getChiColor() + "Succesfully bound " + ability + " to slot " + slot); - } else { - player.sendMessage(getAvatarColor() + "Successfully bound " + ability + " to slot " + slot); + + if (coreAbil != null) { + player.sendMessage(coreAbil.getElement().getColor() + "Succesfully bound " + ability + " to slot " + slot); } saveAbility(bPlayer, slot, ability); } @@ -279,137 +250,10 @@ public class GeneralMethods { block.breakNaturally(new ItemStack(Material.AIR)); } - /** - * Checks to see if a Player can bend a specific Ability. - * - * @param player The player name to check - * @param ability The Ability name to check - * @return true If player can bend specified ability and has the permissions - * to do so - */ - public static boolean canBend(String player, String ability) { - BendingPlayer bPlayer = getBendingPlayer(player); - Player p = Bukkit.getPlayer(player); - if (bPlayer == null) - return false; - if (p == null) - return false; - if (plugin.getConfig().getStringList("Properties.DisabledWorlds") != null && p.getWorld() != null && plugin.getConfig().getStringList("Properties.DisabledWorlds").contains(p.getWorld().getName())) - return false; - if (Commands.isToggledForAll) - return false; - if (!bPlayer.isToggled()) - return false; - if (p.getGameMode() == GameMode.SPECTATOR) - return false; - if (cooldowns.containsKey(p.getName())) { - if (cooldowns.get(p.getName()) + ProjectKorra.plugin.getConfig().getLong("Properties.GlobalCooldown") >= System.currentTimeMillis()) { - return false; - } - cooldowns.remove(p.getName()); - } - if (bPlayer.isChiBlocked()) - return false; - if (!p.hasPermission("bending.ability." + ability)) - return false; - if (!canBind(player, ability)) - return false; - if (bPlayer.isElementToggled(GeneralMethods.getAbilityElement(ability)) == false) - return false; - if (isRegionProtectedFromBuild(p, ability, p.getLocation())) - return false; - if (Paralyze.isParalyzed(p) || Bloodbending.isBloodbended(p)) - return false; - if (MetalClips.isControlled(p)) - return false; - if (EventManager.marker.get(p.getWorld()).equalsIgnoreCase("SolarEclipse") && FireMethods.isFireAbility(ability)) - return false; - if (EventManager.marker.get(p.getWorld()).equalsIgnoreCase("LunarEclipse") && WaterMethods.isWaterAbility(ability)) - return false; - return true; - } - - public static boolean canBendPassive(String player, Element element) { - BendingPlayer bPlayer = getBendingPlayer(player); - Player p = Bukkit.getPlayer(player); - if (bPlayer == null) - return false; - if (p == null) - return false; - if (!p.hasPermission("bending." + element.toString().toLowerCase() + ".passive")) - return false; - if (!bPlayer.isToggled()) - return false; - if (!bPlayer.hasElement(element)) - return false; - if (bPlayer.isElementToggled(element) == false) - return false; - if (isRegionProtectedFromBuild(p, null, p.getLocation())) - return false; - if (bPlayer.isChiBlocked()) - return false; - return true; - } - - public static boolean canBind(String player, String ability) { - Player p = Bukkit.getPlayer(player); - if (p == null) - return false; - if (!p.hasPermission("bending.ability." + ability)) - return false; - if (AirMethods.isAirAbility(ability) && !isBender(player, Element.Air)) - return false; - if (WaterMethods.isWaterAbility(ability) && !isBender(player, Element.Water)) - return false; - if (EarthMethods.isEarthAbility(ability) && !isBender(player, Element.Earth)) - return false; - if (FireMethods.isFireAbility(ability) && !isBender(player, Element.Fire)) - return false; - if (ChiMethods.isChiAbility(ability) && !isBender(player, Element.Chi)) - return false; - - if (!EarthMethods.canLavabend(p) && EarthMethods.isLavabendingAbility(ability)) - return false; - else if (!EarthMethods.canMetalbend(p) && EarthMethods.isMetalbendingAbility(ability)) - return false; - else if (!EarthMethods.canSandbend(p) && EarthMethods.isSandbendingAbility(ability)) - return false; - else if (!AirMethods.canAirFlight(p) && AirMethods.isFlightAbility(ability)) - return false; - else if (!AirMethods.canUseSpiritualProjection(p) && AirMethods.isSpiritualProjectionAbility(ability)) - return false; - else if (!FireMethods.canCombustionbend(p) && FireMethods.isCombustionbendingAbility(ability)) - return false; - else if (!FireMethods.canLightningbend(p) && FireMethods.isLightningbendingAbility(ability)) - return false; - else if (!WaterMethods.canBloodbend(p) && WaterMethods.isBloodbendingAbility(ability)) - return false; - else if (!WaterMethods.canIcebend(p) && WaterMethods.isIcebendingAbility(ability)) - return false; - else if (!WaterMethods.canWaterHeal(p) && WaterMethods.isHealingAbility(ability)) - return false; - else if (!WaterMethods.canPlantbend(p) && WaterMethods.isPlantbendingAbility(ability)) - return false; - return true; - } - public static boolean canView(Player player, String ability) { return player.hasPermission("bending.ability." + ability); } - public static boolean comboExists(String string) { - /* - * Previous method only returned non-stock combos. Reason we use - * descriptions is because that contains all valid combos. Not technical - * ones like IceBulletLeftClick, etc. - */ - for (String s : ComboManager.descriptions.keySet()) { - if (s.equalsIgnoreCase(string)) - return true; - } - return false; - } - /** * Creates a {@link BendingPlayer} with the data from the database. This * runs when a player logs in. @@ -430,8 +274,7 @@ public class GeneralMethods { private static void createBendingPlayerAsynchronously(final UUID uuid, final String player) { ResultSet rs2 = DBConnection.sql.readQuery("SELECT * FROM pk_players WHERE uuid = '" + uuid.toString() + "'"); try { - if (!rs2.next()) { // Data doesn't exist, we want a completely new - // player. + if (!rs2.next()) { // Data doesn't exist, we want a completely new player. new BendingPlayer(uuid, player, new ArrayList(), new HashMap(), false); DBConnection.sql.modifyQuery("INSERT INTO pk_players (uuid, player) VALUES ('" + uuid.toString() + "', '" + player + "')"); ProjectKorra.log.info("Created new BendingPlayer for " + player); @@ -449,16 +292,21 @@ public class GeneralMethods { boolean p = false; final ArrayList elements = new ArrayList(); if (element != null) { // Player has an element. - if (element.contains("a")) - elements.add(Element.Air); - if (element.contains("w")) - elements.add(Element.Water); - if (element.contains("e")) - elements.add(Element.Earth); - if (element.contains("f")) - elements.add(Element.Fire); - if (element.contains("c")) - elements.add(Element.Chi); + if (element.contains("a")) { + elements.add(Element.AIR); + } + if (element.contains("w")) { + elements.add(Element.WATER); + } + if (element.contains("e")) { + elements.add(Element.EARTH); + } + if (element.contains("f")) { + elements.add(Element.FIRE); + } + if (element.contains("c")) { + elements.add(Element.CHI); + } } final HashMap abilities = new HashMap(); @@ -485,52 +333,11 @@ public class GeneralMethods { ex.printStackTrace(); } } - - /** - * Damages an Entity by amount of damage specified. Starts a - * {@link EntityDamageByEntityEvent}. - * - * @param player The player dealing the damage - * @param entity The entity receiving the damage - * @param damage The amount of damage to deal - * @param ability The ability that is used to damage the entity - */ - public static void damageEntity(Player player, Entity entity, double damage, String ability) { - if (ability != null && abilityExists(ability)) { - damageEntity(player, entity, damage, getAbilityElement(ability), getAbilitySubElement(ability), ability); - } else { - damageEntity(player, entity, damage, null, null, ability); - } - } - /** - * Damages an Entity by amount of damage specified. Starts a - * {@link EntityDamageByEntityEvent}. - * - * @param player The player dealing the damage - * @param entity The entity receiving the damage - * @param damage The amount of damage to deal - * @param element The element of the ability - * @param ability The ability that is used to damage the entity - */ - public static void damageEntity(Player player, Entity entity, double damage, Element element, String ability) { - damageEntity(player, entity, damage, element, null, ability); + public static void damageEntity(Ability ability, Entity entity, double damage) { + damageEntity(ability.getPlayer(), entity, damage, ability.getName()); } - - /** - * Damages an Entity by amount of damage specified. Starts a - * {@link EntityDamageByEntityEvent}. - * - * @param player The player dealing the damage - * @param entity The entity receiving the damage - * @param damage The amount of damage to deal - * @param sub The subelement of the ability - * @param ability The ability that is used to damage the entity - */ - public static void damageEntity(Player player, Entity entity, double damage, SubElement sub, String ability) { - damageEntity(player, entity, damage, null, sub, ability); - } - + /** * Damages an Entity by amount of damage specified. Starts a * {@link EntityDamageByEntityEvent}. @@ -539,20 +346,20 @@ public class GeneralMethods { * @param entity The entity that is receiving the damage * @param damage The amount of damage to deal * @param element The element of the ability - * @param sub The sub element of the ability * @param ability The ability that is used to damage the entity */ - public static void damageEntity(Player player, Entity entity, double damage, Element element, SubElement sub, String ability) { + public static void damageEntity(Player player, Entity entity, double damage, String ability) { if (entity instanceof LivingEntity) { if (entity instanceof Player) { - if (Commands.invincible.contains(entity.getName())) + if (Commands.invincible.contains(entity.getName())) { return; + } } if (Bukkit.getPluginManager().isPluginEnabled("NoCheatPlus")) { NCPExemptionManager.exemptPermanently(player, CheckType.FIGHT_REACH); } if (((LivingEntity) entity).getHealth() - damage <= 0 && entity instanceof Player && !entity.isDead()) { - PlayerBendingDeathEvent event = new PlayerBendingDeathEvent((Player) entity, player, damage, element, sub, ability); + PlayerBendingDeathEvent event = new PlayerBendingDeathEvent((Player) entity, player, damage, ability); Bukkit.getServer().getPluginManager().callEvent(event); } ((LivingEntity) entity).damage(damage, player); @@ -599,28 +406,31 @@ public class GeneralMethods { R = Integer.valueOf(hexVal.substring(0, 2), 16); G = Integer.valueOf(hexVal.substring(2, 4), 16); B = Integer.valueOf(hexVal.substring(4, 6), 16); - if (R <= 0) + if (R <= 0) { R = 1; + } } else if (hexVal.length() <= 7 && hexVal.substring(0, 1).equals("#")) { R = Integer.valueOf(hexVal.substring(1, 3), 16); G = Integer.valueOf(hexVal.substring(3, 5), 16); B = Integer.valueOf(hexVal.substring(5, 7), 16); - if (R <= 0) + if (R <= 0) { R = 1; + } } loc.setX(loc.getX() + Math.random() * (xOffset / 2 - -(xOffset / 2))); loc.setY(loc.getY() + Math.random() * (yOffset / 2 - -(yOffset / 2))); loc.setZ(loc.getZ() + Math.random() * (zOffset / 2 - -(zOffset / 2))); - if (type == ParticleEffect.RED_DUST || type == ParticleEffect.REDSTONE) - ParticleEffect.RED_DUST.display((float) R, (float) G, (float) B, 0.004F, 0, loc, 257D); - else if (type == ParticleEffect.SPELL_MOB || type == ParticleEffect.MOB_SPELL) + if (type == ParticleEffect.RED_DUST || type == ParticleEffect.REDSTONE) { + ParticleEffect.RED_DUST.display(R, G, B, 0.004F, 0, loc, 257D); + } else if (type == ParticleEffect.SPELL_MOB || type == ParticleEffect.MOB_SPELL) { ParticleEffect.SPELL_MOB.display((float) 255 - R, (float) 255 - G, (float) 255 - B, 1, 0, loc, 257D); - else if (type == ParticleEffect.SPELL_MOB_AMBIENT || type == ParticleEffect.MOB_SPELL_AMBIENT) + } else if (type == ParticleEffect.SPELL_MOB_AMBIENT || type == ParticleEffect.MOB_SPELL_AMBIENT) { ParticleEffect.SPELL_MOB_AMBIENT.display((float) 255 - R, (float) 255 - G, (float) 255 - B, 1, 0, loc, 257D); - else - ParticleEffect.RED_DUST.display((float) 0, (float) 0, (float) 0, 0.004F, 0, loc, 257D); + } else { + ParticleEffect.RED_DUST.display(0, 0, 0, 0.004F, 0, loc, 257D); + } } public static void displayColoredParticle(Location loc, String hexVal) { @@ -632,16 +442,18 @@ public class GeneralMethods { R = Integer.valueOf(hexVal.substring(0, 2), 16); G = Integer.valueOf(hexVal.substring(2, 4), 16); B = Integer.valueOf(hexVal.substring(4, 6), 16); - if (R <= 0) + if (R <= 0) { R = 1; + } } else if (hexVal.length() <= 7 && hexVal.substring(0, 1).equals("#")) { R = Integer.valueOf(hexVal.substring(1, 3), 16); G = Integer.valueOf(hexVal.substring(3, 5), 16); B = Integer.valueOf(hexVal.substring(5, 7), 16); - if (R <= 0) + if (R <= 0) { R = 1; + } } - ParticleEffect.RED_DUST.display((float) R, (float) G, (float) B, 0.004F, 0, loc, 257D); + ParticleEffect.RED_DUST.display(R, G, B, 0.004F, 0, loc, 257D); } public static void displayColoredParticle(Location loc, String hexVal, float xOffset, float yOffset, float zOffset) { @@ -653,42 +465,45 @@ public class GeneralMethods { R = Integer.valueOf(hexVal.substring(0, 2), 16); G = Integer.valueOf(hexVal.substring(2, 4), 16); B = Integer.valueOf(hexVal.substring(4, 6), 16); - if (R <= 0) + if (R <= 0) { R = 1; + } } else if (hexVal.length() <= 7 && hexVal.substring(0, 1).equals("#")) { R = Integer.valueOf(hexVal.substring(1, 3), 16); G = Integer.valueOf(hexVal.substring(3, 5), 16); B = Integer.valueOf(hexVal.substring(5, 7), 16); - if (R <= 0) + if (R <= 0) { R = 1; + } } loc.setX(loc.getX() + Math.random() * (xOffset / 2 - -(xOffset / 2))); loc.setY(loc.getY() + Math.random() * (yOffset / 2 - -(yOffset / 2))); loc.setZ(loc.getZ() + Math.random() * (zOffset / 2 - -(zOffset / 2))); - ParticleEffect.RED_DUST.display((float) R, (float) G, (float) B, 0.004F, 0, loc, 257D); + ParticleEffect.RED_DUST.display(R, G, B, 0.004F, 0, loc, 257D); } public static void displayParticleVector(Location loc, ParticleEffect type, float xTrans, float yTrans, float zTrans) { - if (type == ParticleEffect.FIREWORKS_SPARK) + if (type == ParticleEffect.FIREWORKS_SPARK) { ParticleEffect.FIREWORKS_SPARK.display(xTrans, yTrans, zTrans, 0.09F, 0, loc, 257D); - else if (type == ParticleEffect.SMOKE || type == ParticleEffect.SMOKE_NORMAL) + } else if (type == ParticleEffect.SMOKE || type == ParticleEffect.SMOKE_NORMAL) { ParticleEffect.SMOKE.display(xTrans, yTrans, zTrans, 0.04F, 0, loc, 257D); - else if (type == ParticleEffect.LARGE_SMOKE || type == ParticleEffect.SMOKE_LARGE) + } else if (type == ParticleEffect.LARGE_SMOKE || type == ParticleEffect.SMOKE_LARGE) { ParticleEffect.LARGE_SMOKE.display(xTrans, yTrans, zTrans, 0.04F, 0, loc, 257D); - else if (type == ParticleEffect.ENCHANTMENT_TABLE) + } else if (type == ParticleEffect.ENCHANTMENT_TABLE) { ParticleEffect.ENCHANTMENT_TABLE.display(xTrans, yTrans, zTrans, 0.5F, 0, loc, 257D); - else if (type == ParticleEffect.PORTAL) + } else if (type == ParticleEffect.PORTAL) { ParticleEffect.PORTAL.display(xTrans, yTrans, zTrans, 0.5F, 0, loc, 257D); - else if (type == ParticleEffect.FLAME) + } else if (type == ParticleEffect.FLAME) { ParticleEffect.FLAME.display(xTrans, yTrans, zTrans, 0.04F, 0, loc, 257D); - else if (type == ParticleEffect.CLOUD) + } else if (type == ParticleEffect.CLOUD) { ParticleEffect.CLOUD.display(xTrans, yTrans, zTrans, 0.04F, 0, loc, 257D); - else if (type == ParticleEffect.SNOW_SHOVEL) + } else if (type == ParticleEffect.SNOW_SHOVEL) { ParticleEffect.SNOW_SHOVEL.display(xTrans, yTrans, zTrans, 0.2F, 0, loc, 257D); - else - ParticleEffect.RED_DUST.display((float) 0, (float) 0, (float) 0, 0.004F, 0, loc, 257D); + } else { + ParticleEffect.RED_DUST.display(0, 0, 0, 0.004F, 0, loc, 257D); + } } /** @@ -698,145 +513,9 @@ public class GeneralMethods { * @param items The items to drop. */ public static void dropItems(Block block, Collection items) { - for (ItemStack item : items) + for (ItemStack item : items) { block.getWorld().dropItem(block.getLocation(), item); - } - - /** - * Gets the ability from specified ability name. - * - * @param string The ability name - * @return Ability name if found in {@link AbilityModuleManager#abilities} - *

- * else null - *

- */ - public static String getAbility(String string) { - for (String st : AbilityModuleManager.abilities) { - if (st.equalsIgnoreCase(string)) - return st; } - return null; - } - - /** - * Gets the Element color from the Ability name specified. - * - * @param ability The ability name - * @return {@link ChiMethods#getChiColor()}
- * {@link AirMethods#getAirColor()}
- * {@link WaterMethods#getWaterColor()}
- * {@link EarthMethods#getEarthColor()}
- * {@link FireMethods#getFireColor()}
- * else {@link #getAvatarColor()} - */ - public static ChatColor getAbilityColor(String ability) { - if (AbilityModuleManager.chiabilities.contains(ability)) - return ChiMethods.getChiColor(); - if (AbilityModuleManager.airbendingabilities.contains(ability)) { - if (AbilityModuleManager.subabilities.contains(ability)) - return getSubBendingColor(Element.Air); - return AirMethods.getAirColor(); - } - if (AbilityModuleManager.waterbendingabilities.contains(ability)) { - if (AbilityModuleManager.subabilities.contains(ability)) - return getSubBendingColor(Element.Water); - return WaterMethods.getWaterColor(); - } - if (AbilityModuleManager.earthbendingabilities.contains(ability)) { - if (AbilityModuleManager.subabilities.contains(ability)) - return getSubBendingColor(Element.Earth); - return EarthMethods.getEarthColor(); - } - if (AbilityModuleManager.firebendingabilities.contains(ability)) { - if (AbilityModuleManager.subabilities.contains(ability)) - return getSubBendingColor(Element.Fire); - return FireMethods.getFireColor(); - } - - else - return getAvatarColor(); - } - - /** - * Returns the element an ability belongs to. - * - * @param ability - * @return the element - */ - public static Element getAbilityElement(String ability) { - if (AbilityModuleManager.airbendingabilities.contains(ability)) - return Element.Air; - else if (AbilityModuleManager.earthbendingabilities.contains(ability)) - return Element.Earth; - else if (AbilityModuleManager.firebendingabilities.contains(ability)) - return Element.Fire; - else if (AbilityModuleManager.waterbendingabilities.contains(ability)) - return Element.Water; - else if (AbilityModuleManager.chiabilities.contains(ability)) - return Element.Chi; - else - return null; - } - - /** - * Returns the subelement of the ability if applicable. - * - * @param ability - * @return SubElement - */ - public static SubElement getAbilitySubElement(String ability) { - if (AbilityModuleManager.bloodabilities.contains(ability)) - return SubElement.Bloodbending; - if (AbilityModuleManager.iceabilities.contains(ability)) - return SubElement.Icebending; - if (AbilityModuleManager.plantabilities.contains(ability)) - return SubElement.Plantbending; - if (AbilityModuleManager.healingabilities.contains(ability)) - return SubElement.Healing; - if (AbilityModuleManager.sandabilities.contains(ability)) - return SubElement.Sandbending; - if (AbilityModuleManager.metalabilities.contains(ability)) - return SubElement.Metalbending; - if (AbilityModuleManager.lavaabilities.contains(ability)) - return SubElement.Lavabending; - if (AbilityModuleManager.lightningabilities.contains(ability)) - return SubElement.Lightning; - if (AbilityModuleManager.combustionabilities.contains(ability)) - return SubElement.Combustion; - if (AbilityModuleManager.spiritualprojectionabilities.contains(ability)) - return SubElement.SpiritualProjection; - if (AbilityModuleManager.flightabilities.contains(ability)) - return SubElement.Flight; - return null; - } - - /** - * Gets the AvatarColor from the config. - * - * @return Config specified ChatColor - */ - public static ChatColor getAvatarColor() { - return ChatColor.valueOf(plugin.getConfig().getString("Properties.Chat.Colors.Avatar")); - } - - /** - * Attempts to get a {@link BendingPlayer} from specified player name. this - * method tries to get a {@link Player} object and gets the uuid and then - * calls {@link #getBendingPlayer(UUID)} - * - * @param playerName The name of the Player - * @return The BendingPlayer object if {@link BendingPlayer#players} - * contains the player name - * - * @see #getBendingPlayer(UUID) - */ - public static BendingPlayer getBendingPlayer(String player) { - OfflinePlayer oPlayer = Bukkit.getOfflinePlayer(player); - if (player == null) { - oPlayer = Bukkit.getOfflinePlayer(oPlayer.getUniqueId()); - } - return BendingPlayer.getPlayers().get(oPlayer.getUniqueId()); } public static List getBlocksAlongLine(Location ploc, Location tloc, World w) { @@ -918,7 +597,7 @@ public class GeneralMethods { for (int y = yorg - r; y <= yorg + r; y++) { for (int z = zorg - r; z <= zorg + r; z++) { Block block = location.getWorld().getBlockAt(x, y, z); - if (block.getLocation().distance(location) <= radius) { + if (block.getLocation().distanceSquared(location) <= radius * radius) { blocks.add(block); } } @@ -927,23 +606,6 @@ public class GeneralMethods { return blocks; } - /** - * Gets the Ability bound to the slot that the player is in. - * - * @param player The player to check - * @return The Ability name bounded to the slot - *

- * else null - *

- */ - public static String getBoundAbility(Player player) { - BendingPlayer bPlayer = getBendingPlayer(player.getName()); - if (bPlayer == null) - return null; - int slot = player.getInventory().getHeldItemSlot() + 1; - return bPlayer.getAbilities().get(slot); - } - public static BlockFace getCardinalDirection(Vector vector) { BlockFace[] faces = { BlockFace.NORTH, BlockFace.NORTH_EAST, BlockFace.EAST, BlockFace.SOUTH_EAST, BlockFace.SOUTH, BlockFace.SOUTH_WEST, BlockFace.WEST, BlockFace.NORTH_WEST }; Vector n, ne, e, se, s, sw, w, nw; @@ -991,91 +653,6 @@ public class GeneralMethods { return circleblocks; } - /** - * Returns the ChatColor that should be associated with the combo name. - * - * @param combo - * @return The ChatColor to be used - */ - public static ChatColor getComboColor(String combo) { - for (String ability : ComboManager.comboAbilityList.keySet()) { - ComboAbility comboability = ComboManager.comboAbilityList.get(ability); - if (!comboability.getName().equalsIgnoreCase(combo)) { - continue; - } - - if (!ComboManager.descriptions.containsKey(comboability.getName())) { - return ChatColor.STRIKETHROUGH; //This is so we know it shouldn't be used. Should not come up anyway. - } - - if (comboability.getComboType() instanceof ComboAbilityModule) { - ComboAbilityModule module = (ComboAbilityModule) comboability.getComboType(); - if (module.getSubElement() != null) { - if (module.getSubElement() == SubElement.Bloodbending || module.getSubElement() == SubElement.Icebending || module.getSubElement() == SubElement.Plantbending || module.getSubElement() == SubElement.Healing) - return WaterMethods.getWaterSubColor(); - else if (module.getSubElement() == SubElement.Lightning || module.getSubElement() == SubElement.Combustion) - return FireMethods.getFireSubColor(); - else if (module.getSubElement() == SubElement.Sandbending || module.getSubElement() == SubElement.Metalbending || module.getSubElement() == SubElement.Lavabending) - return EarthMethods.getEarthSubColor(); - else if (module.getSubElement() == SubElement.Flight || module.getSubElement() == SubElement.SpiritualProjection) - return AirMethods.getAirSubColor(); - } - if (module.getElement().equalsIgnoreCase(Element.Water.toString())) - return WaterMethods.getWaterColor(); - else if (module.getElement().equalsIgnoreCase(Element.Earth.toString())) - return EarthMethods.getEarthColor(); - else if (module.getElement().equalsIgnoreCase(Element.Fire.toString())) - return FireMethods.getFireColor(); - else if (module.getElement().equalsIgnoreCase(Element.Air.toString())) - return AirMethods.getAirColor(); - else if (module.getElement().equalsIgnoreCase(Element.Chi.toString())) - return ChiMethods.getChiColor(); - else - return getAvatarColor(); - } else if (combo.equalsIgnoreCase("IceBullet") || combo.equalsIgnoreCase("IceWave")) { - return WaterMethods.getWaterSubColor(); - } else if (comboability.getComboType().equals(WaterCombo.class)) { - return WaterMethods.getWaterColor(); - } else if (comboability.getComboType().equals(FireCombo.class)) { - return FireMethods.getFireColor(); - } else if (comboability.getComboType().equals(AirCombo.class)) { - return AirMethods.getAirColor(); - } else { - Element element = null; - for (AbilityInformation abilityinfo : comboability.getAbilities()) { - Element currElement = getAbilityElement(abilityinfo.getAbilityName()); - if (currElement == null) - return getAvatarColor(); - else if (element == null) - element = currElement; - if (getAbilitySubElement(abilityinfo.getAbilityName()) != null) { - SubElement sub = getAbilitySubElement(abilityinfo.getAbilityName()); - if (sub == SubElement.Bloodbending || sub == SubElement.Icebending || sub == SubElement.Plantbending || sub == SubElement.Healing) - return WaterMethods.getWaterSubColor(); - else if (sub == SubElement.Lightning || sub == SubElement.Combustion) - return FireMethods.getFireSubColor(); - else if (sub == SubElement.Sandbending || sub == SubElement.Metalbending || sub == SubElement.Lavabending) - return EarthMethods.getEarthSubColor(); - else if (sub == SubElement.Flight || sub == SubElement.SpiritualProjection) - return AirMethods.getAirSubColor(); - } - } - if (element == Element.Air) - return AirMethods.getAirColor(); - if (element == Element.Earth) - return EarthMethods.getEarthColor(); - if (element == Element.Fire) - return FireMethods.getFireColor(); - if (element == Element.Water) - return WaterMethods.getWaterColor(); - if (element == Element.Chi) - return ChiMethods.getChiColor(); - return getAvatarColor(); - } - } - return getAvatarColor(); - } - public static String getCurrentDate() { DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); Date date = new Date(); @@ -1151,7 +728,7 @@ public class GeneralMethods { list.remove(entity); } else if (entity instanceof Player && ((Player) entity).getGameMode().equals(GameMode.SPECTATOR)) { list.remove(entity); - } else if (entity.getLocation().distance(location) > radius) { + } else if (entity.getLocation().distanceSquared(location) > radius * radius) { list.remove(entity); } } @@ -1227,12 +804,14 @@ public class GeneralMethods { } public static int getMaxPresets(Player player) { - if (player.isOp()) + if (player.isOp()) { return 500; + } int cap = 0; for (int i = 0; i <= 500; i++) { - if (player.hasPermission("bending.command.presets.create." + i)) + if (player.hasPermission("bending.command.presets.create." + i)) { cap = i; + } } return cap; } @@ -1249,7 +828,7 @@ public class GeneralMethods { Collection players = new HashSet(); for (Player player : Bukkit.getOnlinePlayers()) { if (player.getLocation().getWorld().equals(location.getWorld())) { - if (player.getLocation().distance(location) <= distance) { + if (player.getLocation().distanceSquared(location) <= distance * distance) { players.add(player); } } @@ -1280,26 +859,7 @@ public class GeneralMethods { } return null; } - - public static ChatColor getSubBendingColor(Element element) { - switch (element) { - case Fire: - return ChatColor.valueOf(plugin.getConfig().getString("Properties.Chat.Colors.FireSub")); - case Air: - return ChatColor.valueOf(plugin.getConfig().getString("Properties.Chat.Colors.AirSub")); - case Water: - return ChatColor.valueOf(plugin.getConfig().getString("Properties.Chat.Colors.WaterSub")); - case Earth: - return ChatColor.valueOf(plugin.getConfig().getString("Properties.Chat.Colors.EarthSub")); - default: - return getAvatarColor(); - } - } - public static SubElement getSubElementByString(String sub) { - return SubElement.getType(sub); - } - @SuppressWarnings("unused") public static Entity getTargetedEntity(Player player, double range, List avoid) { double longestr = range + 1; @@ -1307,9 +867,14 @@ public class GeneralMethods { Location origin = player.getEyeLocation(); Vector direction = player.getEyeLocation().getDirection().normalize(); for (Entity entity : origin.getWorld().getEntities()) { - if (avoid.contains(entity)) + if (avoid.contains(entity)) { continue; - if (entity.getLocation().distance(origin) < longestr && getDistanceFromLine(direction, origin, entity.getLocation()) < 2 && (entity instanceof LivingEntity) && entity.getEntityId() != player.getEntityId() && entity.getLocation().distance(origin.clone().add(direction)) < entity.getLocation().distance(origin.clone().add(direction.clone().multiply(-1)))) { + } + if (entity.getLocation().distanceSquared(origin) < longestr * longestr + && getDistanceFromLine(direction, origin, entity.getLocation()) < 2 + && (entity instanceof LivingEntity) + && entity.getEntityId() != player.getEntityId() + && entity.getLocation().distanceSquared(origin.clone().add(direction)) < entity.getLocation().distanceSquared(origin.clone().add(direction.clone().multiply(-1)))) { target = entity; longestr = entity.getLocation().distance(origin); } @@ -1326,6 +891,10 @@ public class GeneralMethods { } return target; } + + public static Entity getTargetedEntity(Player player, double range) { + return getTargetedEntity(player, range, new ArrayList()); + } public static Location getTargetedLocation(Player player, double originselectrange, Integer... nonOpaque2) { Location origin = player.getEyeLocation(); @@ -1368,16 +937,18 @@ public class GeneralMethods { while (blockHolder.getType() != Material.AIR && Math.abs(y) < Math.abs(positiveY)) { y++; Block tempBlock = loc.clone().add(0, y, 0).getBlock(); - if (tempBlock.getType() == Material.AIR) + if (tempBlock.getType() == Material.AIR) { return blockHolder; + } blockHolder = tempBlock; } while (blockHolder.getType() == Material.AIR && Math.abs(y) < Math.abs(negativeY)) { y--; blockHolder = loc.clone().add(0, y, 0).getBlock(); - if (blockHolder.getType() != Material.AIR) + if (blockHolder.getType() != Material.AIR) { return blockHolder; + } } return null; } @@ -1386,64 +957,35 @@ public class GeneralMethods { return Bukkit.getServer().getPluginManager().getPlugin("ProjectKorraItems") != null; } - public static boolean hasPermission(Player player, String ability) { - return player.hasPermission("bending.ability." + ability) && canBind(player.getName(), ability); - } - public static boolean hasRPG() { return Bukkit.getServer().getPluginManager().getPlugin("ProjectKorraRPG") != null; } - public static boolean isAbilityInstalled(String name, String author) { - String ability = getAbility(name); - return ability != null && AbilityModuleManager.authors.get(name).equalsIgnoreCase(author); - } - public static boolean isAdjacentToThreeOrMoreSources(Block block) { - if (TempBlock.isTempBlock(block)) + if (TempBlock.isTempBlock(block)) { return false; + } int sources = 0; byte full = 0x0; BlockFace[] faces = { BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH }; for (BlockFace face : faces) { Block blocki = block.getRelative(face); - if ((blocki.getType() == Material.LAVA || blocki.getType() == Material.STATIONARY_LAVA) && blocki.getData() == full && EarthPassive.canPhysicsChange(blocki)) + if ((blocki.getType() == Material.LAVA || blocki.getType() == Material.STATIONARY_LAVA) && blocki.getData() == full && EarthPassive.canPhysicsChange(blocki)) { sources++; - if ((blocki.getType() == Material.WATER || blocki.getType() == Material.STATIONARY_WATER) && blocki.getData() == full && WaterManipulation.canPhysicsChange(blocki)) + } + if ((WaterAbility.isWater(blocki) || WaterAbility.isIce(blocki)) && blocki.getData() == full && WaterManipulation.canPhysicsChange(blocki)) { sources++; - if (FreezeMelt.frozenblocks.containsKey(blocki)) { - //if (FreezeMelt.frozenblocks.get(blocki) == full) - //sources++; - } else if (blocki.getType() == Material.ICE) { - //sources++; } } return sources >= 2; } - public static boolean isBender(String player, Element element) { - BendingPlayer bPlayer = getBendingPlayer(player); - return bPlayer != null && bPlayer.hasElement(element); - } - - public static boolean isDisabledStockAbility(String string) { - for (String st : AbilityModuleManager.disabledStockAbilities) { - if (string.equalsIgnoreCase(st)) - return true; - } - return false; - } - - public static boolean isHarmlessAbility(String ability) { - return AbilityModuleManager.harmlessabilities.contains(ability); - } - public static boolean isImportEnabled() { return plugin.getConfig().getBoolean("Properties.ImportEnabled"); } public static boolean isInteractable(Block block) { - return Arrays.asList(interactable).contains(block.getType()); + return Arrays.asList(INTERACTABLE_MATERIALS).contains(block.getType()); } public static boolean isObstructed(Location location1, Location location2) { @@ -1460,8 +1002,9 @@ public class GeneralMethods { for (double i = 0; i <= max; i++) { loc = location1.clone().add(direction.clone().multiply(i)); Material type = loc.getBlock().getType(); - if (type != Material.AIR && !(Arrays.asList(EarthMethods.getTransparentEarthbending()).contains(type.getId()) || WaterMethods.isWater(loc.getBlock()))) + if (type != Material.AIR && !(Arrays.asList(ElementalAbility.getTransparentMaterialSet()).contains(type.getId()) || ElementalAbility.isWater(loc.getBlock()))) { return true; + } } return false; } @@ -1475,10 +1018,11 @@ public class GeneralMethods { * in the map first. */ public static boolean isRegionProtectedFromBuild(Player player, String ability, Location loc) { - if (!blockProtectionCache.containsKey(player.getName())) - blockProtectionCache.put(player.getName(), new ConcurrentHashMap()); + if (!BLOCK_CACHE.containsKey(player.getName())) { + BLOCK_CACHE.put(player.getName(), new ConcurrentHashMap()); + } - ConcurrentHashMap blockMap = blockProtectionCache.get(player.getName()); + ConcurrentHashMap blockMap = BLOCK_CACHE.get(player.getName()); Block block = loc.getBlock(); if (blockMap.containsKey(block)) { BlockCacheElement elem = blockMap.get(block); @@ -1493,9 +1037,17 @@ public class GeneralMethods { blockMap.put(block, new BlockCacheElement(player, block, ability, value, System.currentTimeMillis())); return value; } + + public static boolean isRegionProtectedFromBuild(Ability ability, Location loc) { + return isRegionProtectedFromBuild(ability.getPlayer(), ability.getName(), loc); + } + + public static boolean isRegionProtectedFromBuild(Player player, Location loc) { + return isRegionProtectedFromBuild(player, null, loc); + } public static boolean isRegionProtectedFromBuildPostCache(Player player, String ability, Location loc) { - boolean allowharmless = plugin.getConfig().getBoolean("Properties.RegionProtection.AllowHarmlessAbilities"); + boolean allowHarmless = plugin.getConfig().getBoolean("Properties.RegionProtection.AllowHarmlessAbilities"); boolean respectWorldGuard = plugin.getConfig().getBoolean("Properties.RegionProtection.RespectWorldGuard"); boolean respectPreciousStones = plugin.getConfig().getBoolean("Properties.RegionProtection.RespectPreciousStones"); boolean respectFactions = plugin.getConfig().getBoolean("Properties.RegionProtection.RespectFactions"); @@ -1503,13 +1055,22 @@ public class GeneralMethods { boolean respectGriefPrevention = plugin.getConfig().getBoolean("Properties.RegionProtection.RespectGriefPrevention"); boolean respectLWC = plugin.getConfig().getBoolean("Properties.RegionProtection.RespectLWC"); - List ignite = AbilityModuleManager.igniteabilities; - List explode = AbilityModuleManager.explodeabilities; + boolean isIgnite = false; + boolean isExplosive = false; + boolean isHarmless = false; + CoreAbility coreAbil = CoreAbility.getAbility(ability); + if (coreAbil != null) { + isIgnite = coreAbil.isIgniteAbility(); + isExplosive = coreAbil.isExplosiveAbility(); + isHarmless = coreAbil.isHarmlessAbility(); + } - if (ability == null && allowharmless) + if (ability == null && allowHarmless) { return false; - if (isHarmlessAbility(ability) && allowharmless) + } + if (isHarmless && allowHarmless) { return false; + } PluginManager pm = Bukkit.getPluginManager(); @@ -1536,20 +1097,24 @@ public class GeneralMethods { } if (wgp != null && respectWorldGuard && !player.hasPermission("worldguard.region.bypass." + world.getName())) { WorldGuardPlugin wg = (WorldGuardPlugin) Bukkit.getPluginManager().getPlugin("WorldGuard"); - if (!player.isOnline()) + if (!player.isOnline()) { return true; + } - if (ignite.contains(ability)) { + if (isIgnite) { if (!wg.hasPermission(player, "worldguard.override.lighter")) { - if (wg.getGlobalStateManager().get(world).blockLighter) + if (wg.getGlobalStateManager().get(world).blockLighter) { return true; + } } } - if (explode.contains(ability)) { - if (wg.getGlobalStateManager().get(location.getWorld()).blockTNTExplosions) + if (isExplosive) { + if (wg.getGlobalStateManager().get(location.getWorld()).blockTNTExplosions) { return true; - if (!wg.getRegionContainer().createQuery().testBuild(location, player, DefaultFlag.TNT)) + } + if (!wg.getRegionContainer().createQuery().testBuild(location, player, DefaultFlag.TNT)) { return true; + } } if (!wg.canBuild(player, location.getBlock())) { @@ -1560,19 +1125,17 @@ public class GeneralMethods { if (psp != null && respectPreciousStones) { PreciousStones ps = (PreciousStones) psp; - if (ignite.contains(ability)) { - if (ps.getForceFieldManager().hasSourceField(location, FieldFlag.PREVENT_FIRE)) + if (isIgnite) { + if (ps.getForceFieldManager().hasSourceField(location, FieldFlag.PREVENT_FIRE)) { return true; + } } - if (explode.contains(ability)) { - if (ps.getForceFieldManager().hasSourceField(location, FieldFlag.PREVENT_EXPLOSIONS)) + if (isExplosive) { + if (ps.getForceFieldManager().hasSourceField(location, FieldFlag.PREVENT_EXPLOSIONS)) { return true; + } } - // if (ps.getForceFieldManager().hasSourceField(location, - // FieldFlag.PREVENT_PLACE)) - // return true; - if (!PreciousStones.API().canBreak(player, location)) { return true; } @@ -1593,14 +1156,6 @@ public class GeneralMethods { boolean bBuild = PlayerCacheUtil.getCachePermission(player, location, 3, (byte) 0, TownyPermission.ActionType.BUILD); - if (ignite.contains(ability)) { - - } - - if (explode.contains(ability)) { - - } - if (!bBuild) { PlayerCache cache = twn.getCache(player); TownBlockStatus status = cache.getStatus(); @@ -1619,8 +1174,9 @@ public class GeneralMethods { return true; } - if ((cache.hasBlockErrMsg())) + if ((cache.hasBlockErrMsg())) { TownyMessaging.sendErrorMsg(player, cache.getBlockErrMsg()); + } } } catch (Exception e1) { @@ -1630,33 +1186,25 @@ public class GeneralMethods { if (gpp != null && respectGriefPrevention) { Material type = player.getWorld().getBlockAt(location).getType(); - if (type == null) + if (type == null) { type = Material.AIR; + } String reason = GriefPrevention.instance.allowBuild(player, location); // WORKING with WorldGuard 6.0 BETA 4 Claim claim = GriefPrevention.instance.dataStore.getClaimAt(loc, true, null); - if (ignite.contains(ability)) { - } - - if (explode.contains(ability)) { - - } - - if (reason != null && claim.siegeData != null) + if (reason != null && claim.siegeData != null) { return true; + } } } return false; } public static boolean isSolid(Block block) { - return !Arrays.asList(nonOpaque).contains(block.getTypeId()); + return !Arrays.asList(NON_OPAQUE).contains(block.getTypeId()); } - public static boolean isSubAbility(String ability) { - return AbilityModuleManager.subabilities.contains(ability); - } /** Checks if an entity is Undead **/ public static boolean isUndead(Entity entity) { @@ -1667,10 +1215,6 @@ public class GeneralMethods { return mat != null && (mat == Material.WOOD_AXE || mat == Material.WOOD_PICKAXE || mat == Material.WOOD_SPADE || mat == Material.WOOD_SWORD || mat == Material.STONE_AXE || mat == Material.STONE_PICKAXE || mat == Material.STONE_SPADE || mat == Material.STONE_SWORD || mat == Material.IRON_AXE || mat == Material.IRON_PICKAXE || mat == Material.IRON_SWORD || mat == Material.IRON_SPADE || mat == Material.DIAMOND_AXE || mat == Material.DIAMOND_PICKAXE || mat == Material.DIAMOND_SWORD || mat == Material.DIAMOND_SPADE); } - public static void playAvatarSound(Location loc) { - loc.getWorld().playSound(loc, Sound.ANVIL_LAND, 1, 10); - } - public static void reloadPlugin() { ProjectKorra.log.info("Reloading ProjectKorra and configuration"); BendingReloadEvent event = new BendingReloadEvent(); @@ -1681,18 +1225,18 @@ public class GeneralMethods { GeneralMethods.stopBending(); ConfigManager.defaultConfig.reload(); ConfigManager.deathMsgConfig.reload(); - ConfigManager.presetConfig.reload(); - Preset.loadExternalPresets(); - BendingManager.getInstance().reloadVariables(); - new AbilityModuleManager(plugin); + + CoreAbility.registerAbilities(); new ComboManager(); - new MultiAbilityModuleManager(); + new MultiAbilityManager(); + DBConnection.host = plugin.getConfig().getString("Storage.MySQL.host"); DBConnection.port = plugin.getConfig().getInt("Storage.MySQL.port"); DBConnection.pass = plugin.getConfig().getString("Storage.MySQL.pass"); DBConnection.db = plugin.getConfig().getString("Storage.MySQL.db"); DBConnection.user = plugin.getConfig().getString("Storage.MySQL.user"); DBConnection.init(); + if (!DBConnection.isOpen()) { ProjectKorra.log.severe("Unable to enable ProjectKorra due to the database not being open"); stopPlugin(); @@ -1714,15 +1258,19 @@ public class GeneralMethods { } public static void removeUnusableAbilities(String player) { - BendingPlayer bPlayer = getBendingPlayer(player); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + return; + } + HashMap slots = bPlayer.getAbilities(); - HashMap finalabilities = new HashMap(); + HashMap finalAbilities = new HashMap(); for (int i : slots.keySet()) { - if (canBend(player, slots.get(i))) { - finalabilities.put(i, slots.get(i)); + if (bPlayer.canBind(CoreAbility.getAbility(slots.get(i)))) { + finalAbilities.put(i, slots.get(i)); } } - bPlayer.setAbilities(finalabilities); + bPlayer.setAbilities(finalAbilities); } public static Vector rotateVectorAroundVector(Vector axis, Vector rotator, double degrees) { @@ -1783,11 +1331,12 @@ public class GeneralMethods { writeToDebug("===================="); ArrayList stockAbils = new ArrayList(); ArrayList unofficialAbils = new ArrayList(); - for (String ability : AbilityModuleManager.abilities) { - if (StockAbility.isStockAbility(ability)) - stockAbils.add(ability); - else - unofficialAbils.add(ability); + for (CoreAbility ability : CoreAbility.getAbilities()) { + if (ability.getClass().getPackage().getName().startsWith("com.projectkorra")) { + stockAbils.add(ability.getName()); + } else { + unofficialAbils.add(ability.getName()); + } } if (!stockAbils.isEmpty()) { Collections.sort(stockAbils); @@ -1879,44 +1428,58 @@ public class GeneralMethods { } catch (IOException e) { e.printStackTrace(); } + + writeToDebug(""); + writeToDebug("CoreAbility Debugger"); + writeToDebug("===================="); + writeToDebug(CoreAbility.getDebugString()); } public static void saveAbility(BendingPlayer bPlayer, int slot, String ability) { - if (bPlayer == null) + if (bPlayer == null) { return; + } String uuid = bPlayer.getUUIDString(); //Temp code to block modifications of binds, Should be replaced when bind event is added. - if (MultiAbilityManager.playerAbilities.containsKey(Bukkit.getPlayer(bPlayer.getUUID()))) + if (MultiAbilityManager.playerAbilities.containsKey(Bukkit.getPlayer(bPlayer.getUUID()))) { return; + } HashMap abilities = bPlayer.getAbilities(); DBConnection.sql.modifyQuery("UPDATE pk_players SET slot" + slot + " = '" + (abilities.get(slot) == null ? null : abilities.get(slot)) + "' WHERE uuid = '" + uuid + "'"); } public static void saveElements(BendingPlayer bPlayer) { - if (bPlayer == null) + if (bPlayer == null) { return; + } String uuid = bPlayer.getUUIDString(); StringBuilder elements = new StringBuilder(); - if (bPlayer.hasElement(Element.Air)) + if (bPlayer.hasElement(Element.AIR)) { elements.append("a"); - if (bPlayer.hasElement(Element.Water)) + } + if (bPlayer.hasElement(Element.WATER)) { elements.append("w"); - if (bPlayer.hasElement(Element.Earth)) + } + if (bPlayer.hasElement(Element.EARTH)) { elements.append("e"); - if (bPlayer.hasElement(Element.Fire)) + } + if (bPlayer.hasElement(Element.FIRE)) { elements.append("f"); - if (bPlayer.hasElement(Element.Chi)) + } + if (bPlayer.hasElement(Element.CHI)) { elements.append("c"); + } DBConnection.sql.modifyQuery("UPDATE pk_players SET element = '" + elements + "' WHERE uuid = '" + uuid + "'"); } public static void savePermaRemoved(BendingPlayer bPlayer) { - if (bPlayer == null) + if (bPlayer == null) { return; + } String uuid = bPlayer.getUUIDString(); boolean permaRemoved = bPlayer.isPermaRemoved(); DBConnection.sql.modifyQuery("UPDATE pk_players SET permaremoved = '" + (permaRemoved ? "true" : "false") + "' WHERE uuid = '" + uuid + "'"); @@ -1924,13 +1487,15 @@ public class GeneralMethods { public static void setVelocity(Entity entity, Vector velocity) { if (entity instanceof TNTPrimed) { - if (plugin.getConfig().getBoolean("Properties.BendingAffectFallingSand.TNT")) + if (plugin.getConfig().getBoolean("Properties.BendingAffectFallingSand.TNT")) { entity.setVelocity(velocity.multiply(plugin.getConfig().getDouble("Properties.BendingAffectFallingSand.TNTStrengthMultiplier"))); + } return; } if (entity instanceof FallingSand) { - if (plugin.getConfig().getBoolean("Properties.BendingAffectFallingSand.Normal")) + if (plugin.getConfig().getBoolean("Properties.BendingAffectFallingSand.Normal")) { entity.setVelocity(velocity.multiply(plugin.getConfig().getDouble("Properties.BendingAffectFallingSand.NormalStrengthMultiplier"))); + } return; } entity.setVelocity(velocity); @@ -1954,8 +1519,9 @@ public class GeneralMethods { public static void startCacheCleaner(final double period) { new BukkitRunnable() { + @Override public void run() { - for (ConcurrentHashMap map : blockProtectionCache.values()) { + for (ConcurrentHashMap map : BLOCK_CACHE.values()) { for (Iterator i = map.keySet().iterator(); i.hasNext();) { Block key = i.next(); BlockCacheElement value = map.get(key); @@ -1970,28 +1536,23 @@ public class GeneralMethods { } public static void stopBending() { - List abilities = AbilityModuleManager.ability; - for (AbilityModule ab : abilities) { - ab.stop(); + for (CoreAbility ability : CoreAbility.getAbilities()) { + if (ability instanceof AddonAbility) { + ((AddonAbility) ability).stop(); + } } - HashMap combos = ComboManager.comboAbilityList; - for (String combo : combos.keySet()) { - ComboManager.ComboAbility c = combos.get(combo); - if (c.getComboType() instanceof ComboAbilityModule) - ((ComboAbilityModule) c.getComboType()).stop(); - } - AirMethods.stopBending(); - EarthMethods.stopBending(); - WaterMethods.stopBending(); - FireMethods.stopBending(); - ChiMethods.stopBending(); + CoreAbility.removeAll(); + EarthAbility.stopBending(); + WaterAbility.stopBending(); + FireAbility.stopBending(); Flight.removeAll(); TempBlock.removeAll(); MultiAbilityManager.removeAll(); - if (!invincible.isEmpty()) - invincible.clear(); + if (!INVINCIBLE.isEmpty()) { + INVINCIBLE.clear(); + } } public static void stopPlugin() { @@ -2021,84 +1582,4 @@ public class GeneralMethods { e.printStackTrace(); } } - - public ComboAbilityModule getCombo(String name) { - for (ComboAbilityModule c : ComboModuleManager.combo) - if (name.equalsIgnoreCase(c.getName())) - return c; - return null; - } - - public static class BlockCacheElement { - private Player player; - private Block block; - private String ability; - private boolean allowed; - private long time; - - public BlockCacheElement(Player player, Block block, String ability, boolean allowed, long time) { - this.player = player; - this.block = block; - this.ability = ability; - this.allowed = allowed; - this.time = time; - } - - public String getAbility() { - return ability; - } - - public Block getBlock() { - return block; - } - - public Player getPlayer() { - return player; - } - - public long getTime() { - return time; - } - - public boolean isAllowed() { - return allowed; - } - - public void setAbility(String ability) { - this.ability = ability; - } - - public void setAllowed(boolean allowed) { - this.allowed = allowed; - } - - public void setBlock(Block block) { - this.block = block; - } - - public void setPlayer(Player player) { - this.player = player; - } - - public void setTime(long time) { - this.time = time; - } - - } - - public static ChatColor getElementColor(Element element) { - switch (element) { - case Air: - return AirMethods.getAirColor(); - case Fire: - return FireMethods.getFireColor(); - case Earth: - return EarthMethods.getEarthColor(); - case Water: - return WaterMethods.getWaterColor(); - case Chi: - return ChiMethods.getChiColor(); - } - return null; - } } diff --git a/src/com/projectkorra/projectkorra/PKListener.java b/src/com/projectkorra/projectkorra/PKListener.java index 02ab20e7..a27c0838 100644 --- a/src/com/projectkorra/projectkorra/PKListener.java +++ b/src/com/projectkorra/projectkorra/PKListener.java @@ -1,11 +1,98 @@ package com.projectkorra.projectkorra; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Set; -import java.util.UUID; +import com.projectkorra.projectkorra.ability.AddonAbility; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.ChiAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.EarthAbility; +import com.projectkorra.projectkorra.ability.ElementalAbility; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.ability.util.ComboManager; +import com.projectkorra.projectkorra.ability.util.MultiAbilityManager; +import com.projectkorra.projectkorra.airbending.AirBlast; +import com.projectkorra.projectkorra.airbending.AirBubble; +import com.projectkorra.projectkorra.airbending.AirBurst; +import com.projectkorra.projectkorra.airbending.AirFlight; +import com.projectkorra.projectkorra.airbending.AirScooter; +import com.projectkorra.projectkorra.airbending.AirShield; +import com.projectkorra.projectkorra.airbending.AirSpout; +import com.projectkorra.projectkorra.airbending.AirSuction; +import com.projectkorra.projectkorra.airbending.AirSwipe; +import com.projectkorra.projectkorra.airbending.Suffocate; +import com.projectkorra.projectkorra.airbending.Tornado; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.chiblocking.AcrobatStance; +import com.projectkorra.projectkorra.chiblocking.ChiCombo; +import com.projectkorra.projectkorra.chiblocking.ChiPassive; +import com.projectkorra.projectkorra.chiblocking.HighJump; +import com.projectkorra.projectkorra.chiblocking.Paralyze; +import com.projectkorra.projectkorra.chiblocking.QuickStrike; +import com.projectkorra.projectkorra.chiblocking.RapidPunch; +import com.projectkorra.projectkorra.chiblocking.Smokescreen; +import com.projectkorra.projectkorra.chiblocking.SwiftKick; +import com.projectkorra.projectkorra.chiblocking.WarriorStance; +import com.projectkorra.projectkorra.command.Commands; +import com.projectkorra.projectkorra.configuration.ConfigManager; +import com.projectkorra.projectkorra.earthbending.Catapult; +import com.projectkorra.projectkorra.earthbending.Collapse; +import com.projectkorra.projectkorra.earthbending.CollapseWall; +import com.projectkorra.projectkorra.earthbending.EarthArmor; +import com.projectkorra.projectkorra.earthbending.EarthBlast; +import com.projectkorra.projectkorra.earthbending.EarthGrab; +import com.projectkorra.projectkorra.earthbending.EarthPassive; +import com.projectkorra.projectkorra.earthbending.EarthSmash; +import com.projectkorra.projectkorra.earthbending.EarthTunnel; +import com.projectkorra.projectkorra.earthbending.Extraction; +import com.projectkorra.projectkorra.earthbending.LavaFlow; +import com.projectkorra.projectkorra.earthbending.LavaFlow.AbilityType; +import com.projectkorra.projectkorra.earthbending.LavaSurge; +import com.projectkorra.projectkorra.earthbending.LavaSurgeWave; +import com.projectkorra.projectkorra.earthbending.MetalClips; +import com.projectkorra.projectkorra.earthbending.RaiseEarth; +import com.projectkorra.projectkorra.earthbending.RaiseEarthWall; +import com.projectkorra.projectkorra.earthbending.SandSpout; +import com.projectkorra.projectkorra.earthbending.Shockwave; +import com.projectkorra.projectkorra.earthbending.Tremorsense; +import com.projectkorra.projectkorra.event.HorizontalVelocityChangeEvent; +import com.projectkorra.projectkorra.event.PlayerBendingDeathEvent; +import com.projectkorra.projectkorra.event.PlayerChangeElementEvent; +import com.projectkorra.projectkorra.firebending.Blaze; +import com.projectkorra.projectkorra.firebending.BlazeArc; +import com.projectkorra.projectkorra.firebending.BlazeRing; +import com.projectkorra.projectkorra.firebending.Combustion; +import com.projectkorra.projectkorra.firebending.FireBlast; +import com.projectkorra.projectkorra.firebending.FireBlastCharged; +import com.projectkorra.projectkorra.firebending.FireBurst; +import com.projectkorra.projectkorra.firebending.FireDamageTimer; +import com.projectkorra.projectkorra.firebending.FireJet; +import com.projectkorra.projectkorra.firebending.FireShield; +import com.projectkorra.projectkorra.firebending.HeatControlExtinguish; +import com.projectkorra.projectkorra.firebending.HeatControlSolidify; +import com.projectkorra.projectkorra.firebending.Illumination; +import com.projectkorra.projectkorra.firebending.Lightning; +import com.projectkorra.projectkorra.firebending.WallOfFire; +import com.projectkorra.projectkorra.object.HorizontalVelocityTracker; +import com.projectkorra.projectkorra.object.Preset; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.ClickType; +import com.projectkorra.projectkorra.util.Flight; +import com.projectkorra.projectkorra.util.TempBlock; +import com.projectkorra.projectkorra.waterbending.Bloodbending; +import com.projectkorra.projectkorra.waterbending.IceBlast; +import com.projectkorra.projectkorra.waterbending.IceSpikeBlast; +import com.projectkorra.projectkorra.waterbending.OctopusForm; +import com.projectkorra.projectkorra.waterbending.PhaseChangeFreeze; +import com.projectkorra.projectkorra.waterbending.PhaseChangeMelt; +import com.projectkorra.projectkorra.waterbending.PlantArmor; +import com.projectkorra.projectkorra.waterbending.SurgeWall; +import com.projectkorra.projectkorra.waterbending.SurgeWave; +import com.projectkorra.projectkorra.waterbending.Torrent; +import com.projectkorra.projectkorra.waterbending.WaterArms; +import com.projectkorra.projectkorra.waterbending.WaterManipulation; +import com.projectkorra.projectkorra.waterbending.WaterPassive; +import com.projectkorra.projectkorra.waterbending.WaterSpout; +import com.projectkorra.projectkorra.waterbending.WaterSpoutWave; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -58,106 +145,23 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerToggleFlightEvent; import org.bukkit.event.player.PlayerToggleSneakEvent; import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionEffectType; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.ability.combo.ComboManager; -import com.projectkorra.projectkorra.ability.multiability.MultiAbilityManager; -import com.projectkorra.projectkorra.airbending.AirBlast; -import com.projectkorra.projectkorra.airbending.AirBubble; -import com.projectkorra.projectkorra.airbending.AirBurst; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.airbending.AirScooter; -import com.projectkorra.projectkorra.airbending.AirShield; -import com.projectkorra.projectkorra.airbending.AirSpout; -import com.projectkorra.projectkorra.airbending.AirSuction; -import com.projectkorra.projectkorra.airbending.AirSwipe; -import com.projectkorra.projectkorra.airbending.FlightAbility; -import com.projectkorra.projectkorra.airbending.Suffocate; -import com.projectkorra.projectkorra.airbending.Tornado; -import com.projectkorra.projectkorra.chiblocking.AcrobatStance; -import com.projectkorra.projectkorra.chiblocking.ChiCombo; -import com.projectkorra.projectkorra.chiblocking.ChiMethods; -import com.projectkorra.projectkorra.chiblocking.ChiPassive; -import com.projectkorra.projectkorra.chiblocking.HighJump; -import com.projectkorra.projectkorra.chiblocking.Paralyze; -import com.projectkorra.projectkorra.chiblocking.QuickStrike; -import com.projectkorra.projectkorra.chiblocking.RapidPunch; -import com.projectkorra.projectkorra.chiblocking.Smokescreen; -import com.projectkorra.projectkorra.chiblocking.SwiftKick; -import com.projectkorra.projectkorra.chiblocking.WarriorStance; -import com.projectkorra.projectkorra.command.Commands; -import com.projectkorra.projectkorra.configuration.ConfigManager; -import com.projectkorra.projectkorra.earthbending.Catapult; -import com.projectkorra.projectkorra.earthbending.Collapse; -import com.projectkorra.projectkorra.earthbending.CompactColumn; -import com.projectkorra.projectkorra.earthbending.EarthArmor; -import com.projectkorra.projectkorra.earthbending.EarthBlast; -import com.projectkorra.projectkorra.earthbending.EarthColumn; -import com.projectkorra.projectkorra.earthbending.EarthGrab; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.earthbending.EarthPassive; -import com.projectkorra.projectkorra.earthbending.EarthSmash; -import com.projectkorra.projectkorra.earthbending.EarthTunnel; -import com.projectkorra.projectkorra.earthbending.EarthWall; -import com.projectkorra.projectkorra.earthbending.Extraction; -import com.projectkorra.projectkorra.earthbending.LavaFlow; -import com.projectkorra.projectkorra.earthbending.LavaFlow.AbilityType; -import com.projectkorra.projectkorra.earthbending.LavaSurge; -import com.projectkorra.projectkorra.earthbending.LavaWave; -import com.projectkorra.projectkorra.earthbending.MetalClips; -import com.projectkorra.projectkorra.earthbending.SandSpout; -import com.projectkorra.projectkorra.earthbending.Shockwave; -import com.projectkorra.projectkorra.earthbending.Tremorsense; -import com.projectkorra.projectkorra.event.HorizontalVelocityChangeEvent; -import com.projectkorra.projectkorra.event.PlayerBendingDeathEvent; -import com.projectkorra.projectkorra.event.PlayerChangeElementEvent; -import com.projectkorra.projectkorra.firebending.ArcOfFire; -import com.projectkorra.projectkorra.firebending.Combustion; -import com.projectkorra.projectkorra.firebending.Enflamed; -import com.projectkorra.projectkorra.firebending.Extinguish; -import com.projectkorra.projectkorra.firebending.FireBlast; -import com.projectkorra.projectkorra.firebending.FireBurst; -import com.projectkorra.projectkorra.firebending.FireJet; -import com.projectkorra.projectkorra.firebending.FireMethods; -import com.projectkorra.projectkorra.firebending.FireShield; -import com.projectkorra.projectkorra.firebending.FireStream; -import com.projectkorra.projectkorra.firebending.Fireball; -import com.projectkorra.projectkorra.firebending.HeatControl; -import com.projectkorra.projectkorra.firebending.Illumination; -import com.projectkorra.projectkorra.firebending.Lightning; -import com.projectkorra.projectkorra.firebending.RingOfFire; -import com.projectkorra.projectkorra.firebending.WallOfFire; -import com.projectkorra.projectkorra.object.HorizontalVelocityTracker; -import com.projectkorra.projectkorra.object.Preset; -import com.projectkorra.projectkorra.util.ClickType; -import com.projectkorra.projectkorra.util.Flight; -import com.projectkorra.projectkorra.util.TempBlock; -import com.projectkorra.projectkorra.waterbending.Bloodbending; -import com.projectkorra.projectkorra.waterbending.FreezeMelt; -import com.projectkorra.projectkorra.waterbending.IceBlast; -import com.projectkorra.projectkorra.waterbending.IceSpike2; -import com.projectkorra.projectkorra.waterbending.Melt; -import com.projectkorra.projectkorra.waterbending.OctopusForm; -import com.projectkorra.projectkorra.waterbending.PlantArmor; -import com.projectkorra.projectkorra.waterbending.Torrent; -import com.projectkorra.projectkorra.waterbending.WaterArms; -import com.projectkorra.projectkorra.waterbending.WaterManipulation; -import com.projectkorra.projectkorra.waterbending.WaterMethods; -import com.projectkorra.projectkorra.waterbending.WaterPassive; -import com.projectkorra.projectkorra.waterbending.WaterSpout; -import com.projectkorra.projectkorra.waterbending.WaterWall; -import com.projectkorra.projectkorra.waterbending.WaterWave; -import com.projectkorra.projectkorra.waterbending.Wave; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Set; +import java.util.UUID; public class PKListener implements Listener { ProjectKorra plugin; - public static HashMap bendingDeathPlayer = new HashMap(); // Player killed by Bending - public static List interact = new ArrayList(); // Player right click block + private static final HashMap BENDING_PLAYER_DEATH = new HashMap<>(); // Player killed by Bending + private static final List RIGHT_CLICK_INTERACT = new ArrayList(); // Player right click block + private static final ArrayList TOGGLED_OUT = new ArrayList<>(); // Stands for toggled = false while logging out public PKListener(ProjectKorra plugin) { this.plugin = plugin; @@ -166,13 +170,14 @@ public class PKListener implements Listener { public static void login(BendingPlayer pl) { ProjectKorra plugin = ProjectKorra.plugin; Player player = Bukkit.getPlayer(pl.getUUID()); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); - if (player == null) { + if (bPlayer == null) { return; } - if (GeneralMethods.toggledOut.contains(player.getUniqueId())) { - GeneralMethods.getBendingPlayer(player.getName()).toggleBending(); + if (TOGGLED_OUT.contains(player.getUniqueId())) { + bPlayer.toggleBending(); player.sendMessage(ChatColor.YELLOW + "Reminder, you toggled your bending before signing off. Enable it again with /bending toggle."); } @@ -180,27 +185,24 @@ public class PKListener implements Listener { String append = ""; ChatColor color = null; boolean chatEnabled = ProjectKorra.plugin.getConfig().getBoolean("Properties.Chat.Enable"); - if (GeneralMethods.getBendingPlayer(player.getName()).getElements().size() > 1 && chatEnabled) { + if ((player.hasPermission("bending.avatar") || bPlayer.getElements().size() > 1) && chatEnabled) { append = plugin.getConfig().getString("Properties.Chat.Prefixes.Avatar"); color = ChatColor.valueOf(plugin.getConfig().getString("Properties.Chat.Colors.Avatar")); - } else if (GeneralMethods.isBender(player.getName(), Element.Air) && chatEnabled) { + } else if (bPlayer.hasElement(Element.AIR) && chatEnabled) { append = plugin.getConfig().getString("Properties.Chat.Prefixes.Air"); - color = AirMethods.getAirColor(); - } else if (GeneralMethods.isBender(player.getName(), Element.Water) && chatEnabled) { + color = Element.AIR.getColor(); + } else if (bPlayer.hasElement(Element.WATER) && chatEnabled) { append = plugin.getConfig().getString("Properties.Chat.Prefixes.Water"); - color = WaterMethods.getWaterColor(); - } else if (GeneralMethods.isBender(player.getName(), Element.Earth) && chatEnabled) { + color = Element.WATER.getColor(); + } else if (bPlayer.hasElement(Element.EARTH) && chatEnabled) { append = plugin.getConfig().getString("Properties.Chat.Prefixes.Earth"); - color = EarthMethods.getEarthColor(); - } else if (GeneralMethods.isBender(player.getName(), Element.Fire) && chatEnabled) { + color = Element.EARTH.getColor(); + } else if (bPlayer.hasElement(Element.FIRE) && chatEnabled) { append = plugin.getConfig().getString("Properties.Chat.Prefixes.Fire"); - color = FireMethods.getFireColor(); - } else if (GeneralMethods.isBender(player.getName(), Element.Chi) && chatEnabled) { + color = Element.FIRE.getColor(); + } else if (bPlayer.hasElement(Element.CHI) && chatEnabled) { append = plugin.getConfig().getString("Properties.Chat.Prefixes.Chi"); - color = ChiMethods.getChiColor(); - } else { - append = "[Nonbender]"; - color = ChatColor.WHITE; + color = Element.CHI.getColor(); } if (chatEnabled) { @@ -210,11 +212,12 @@ public class PKListener implements Listener { // Handle the AirSpout/WaterSpout login glitches if (player.getGameMode() != GameMode.CREATIVE) { - HashMap bound = GeneralMethods.getBendingPlayer(player.getName()).getAbilities(); + HashMap bound = bPlayer.getAbilities(); for (String str : bound.values()) { if (str.equalsIgnoreCase("AirSpout") || str.equalsIgnoreCase("WaterSpout") || str.equalsIgnoreCase("SandSpout")) { final Player fplayer = player; new BukkitRunnable() { + @Override public void run() { fplayer.setFlying(false); fplayer.setAllowFlight(false); @@ -228,40 +231,34 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlockBreak(BlockBreakEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Block block = event.getBlock(); Player player = event.getPlayer(); - if (WaterWall.wasBrokenFor(player, block) || OctopusForm.wasBrokenFor(player, block) || Torrent.wasBrokenFor(player, block) || WaterWave.wasBrokenFor(player, block)) { + if (SurgeWall.wasBrokenFor(player, block) || OctopusForm.wasBrokenFor(player, block) || Torrent.wasBrokenFor(player, block) || WaterSpoutWave.wasBrokenFor(player, block)) { event.setCancelled(true); return; } EarthBlast blast = EarthBlast.getBlastFromSource(block); if (blast != null) { - blast.cancel(); + blast.remove(); } - if (FreezeMelt.frozenblocks.containsKey(block)) { - FreezeMelt.thaw(block); + if (PhaseChangeFreeze.getFrozenBlocks().containsKey(block)) { + PhaseChangeFreeze.thaw(block); event.setCancelled(true); - // } else if (!WalkOnWater.canThaw(block)) { - // WalkOnWater.thaw(block); - } else if (WaterWall.wallblocks.containsKey(block)) { - WaterWall.thaw(block); + } else if (SurgeWall.getWallBlocks().containsKey(block)) { + SurgeWall.thaw(block); event.setCancelled(true); - } else if (Illumination.blocks.containsKey(block)) { + } else if (Illumination.getBlocks().containsKey(block)) { event.setCancelled(true); - // } else if (Illumination.blocks.containsKey(block - // .getRelative(BlockFace.UP))) { - // event.setCancelled(true); - } else if (!Wave.canThaw(block)) { - Wave.thaw(block); + } else if (!SurgeWave.canThaw(block)) { + SurgeWave.thaw(block); event.setCancelled(true); - // event.setCancelled(true); - } else if (EarthMethods.movedearth.containsKey(block)) { - // Methods.removeEarthbendedBlockIndex(block); - EarthMethods.removeRevertIndex(block); + } else if (EarthAbility.getMovedEarth().containsKey(block)) { + EarthAbility.removeRevertIndex(block); } else if (TempBlock.isTempBlock(block)) { TempBlock.revertBlock(block, Material.AIR); } @@ -269,53 +266,61 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlockFlowTo(BlockFromToEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Block toblock = event.getToBlock(); Block fromblock = event.getBlock(); - if (EarthMethods.isLava(fromblock)) { + if (ElementalAbility.isLava(fromblock)) { event.setCancelled(!EarthPassive.canFlowFromTo(fromblock, toblock)); } - if (WaterMethods.isWater(fromblock)) { + if (ElementalAbility.isWater(fromblock)) { event.setCancelled(!AirBubble.canFlowTo(toblock)); if (!event.isCancelled()) { event.setCancelled(!WaterManipulation.canFlowFromTo(fromblock, toblock)); } if (!event.isCancelled()) { - if (Illumination.blocks.containsKey(toblock)) + if (Illumination.getBlocks().containsKey(toblock)) { toblock.setType(Material.AIR); + } } } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlockForm(BlockFormEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; - if (TempBlock.isTempBlock(event.getBlock())) + } + if (TempBlock.isTempBlock(event.getBlock())) { event.setCancelled(true); - if (!WaterManipulation.canPhysicsChange(event.getBlock())) + } + if (!WaterManipulation.canPhysicsChange(event.getBlock())) { event.setCancelled(true); - if (!EarthPassive.canPhysicsChange(event.getBlock())) + } + if (!EarthPassive.canPhysicsChange(event.getBlock())) { event.setCancelled(true); + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlockIgnite(BlockIgniteEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlockMeltEvent(BlockFadeEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Block block = event.getBlock(); if (block.getType() == Material.FIRE) { return; } - event.setCancelled(Illumination.blocks.containsKey(block)); + event.setCancelled(Illumination.getBlocks().containsKey(block)); if (!event.isCancelled()) { event.setCancelled(!WaterManipulation.canPhysicsChange(block)); } @@ -323,37 +328,41 @@ public class PKListener implements Listener { event.setCancelled(!EarthPassive.canPhysicsChange(block)); } if (!event.isCancelled()) { - event.setCancelled(FreezeMelt.frozenblocks.containsKey(block)); + event.setCancelled(PhaseChangeFreeze.getFrozenBlocks().containsKey(block)); } if (!event.isCancelled()) { - event.setCancelled(!Wave.canThaw(block)); + event.setCancelled(!SurgeWave.canThaw(block)); } if (!event.isCancelled()) { event.setCancelled(!Torrent.canThaw(block)); } - if (FireStream.ignitedblocks.containsKey(block)) { - FireStream.remove(block); + if (BlazeArc.getIgnitedBlocks().containsKey(block)) { + BlazeArc.removeBlock(block); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlockPhysics(BlockPhysicsEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Block block = event.getBlock(); event.setCancelled(!WaterManipulation.canPhysicsChange(block)); event.setCancelled(!EarthPassive.canPhysicsChange(block)); - if (!event.isCancelled()) - event.setCancelled(Illumination.blocks.containsKey(block)); - if (!event.isCancelled()) - event.setCancelled(EarthMethods.tempnophysics.contains(block)); + if (!event.isCancelled()) { + event.setCancelled(Illumination.getBlocks().containsKey(block)); + } + if (!event.isCancelled()) { + event.setCancelled(EarthAbility.getPreventPhysicsBlocks().contains(block)); + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlockPlace(BlockPlaceEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Player player = event.getPlayer(); if (Paralyze.isParalyzed(player) || ChiCombo.isParalyzed(player) || Bloodbending.isBloodbended(player) || Suffocate.isBreathbent(player)) { event.setCancelled(true); @@ -363,31 +372,22 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL) public void onElementChange(PlayerChangeElementEvent event) { Player player = event.getTarget(); - Element e = event.getElement(); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + Element element = event.getElement(); String append = ""; ChatColor color = null; + + if (bPlayer == null) { + return; + } + boolean chatEnabled = ProjectKorra.plugin.getConfig().getBoolean("Properties.Chat.Enable"); - if (GeneralMethods.getBendingPlayer(player.getName()).getElements().size() > 1) { + if (bPlayer.getElements().size() > 1) { append = plugin.getConfig().getString("Properties.Chat.Prefixes.Avatar"); color = ChatColor.valueOf(plugin.getConfig().getString("Properties.Chat.Colors.Avatar")); - } else if (e == Element.Air && chatEnabled) { - append = plugin.getConfig().getString("Properties.Chat.Prefixes.Air"); - color = AirMethods.getAirColor(); - } else if (e == Element.Water && chatEnabled) { - append = plugin.getConfig().getString("Properties.Chat.Prefixes.Water"); - color = WaterMethods.getWaterColor(); - } else if (e == Element.Earth && chatEnabled) { - append = plugin.getConfig().getString("Properties.Chat.Prefixes.Earth"); - color = EarthMethods.getEarthColor(); - } else if (e == Element.Fire && chatEnabled) { - append = plugin.getConfig().getString("Properties.Chat.Prefixes.Fire"); - color = FireMethods.getFireColor(); - } else if (e == Element.Chi && chatEnabled) { - append = plugin.getConfig().getString("Properties.Chat.Prefixes.Chi"); - color = ChiMethods.getChiColor(); - } else { - append = "[Nonbender]"; - color = ChatColor.WHITE; + } else if (element != null) { + append = plugin.getConfig().getString("Properties.Chat.Prefixes." + element.getName()); + color = element.getColor(); } if (chatEnabled) { @@ -398,16 +398,18 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityChangeBlockEvent(EntityChangeBlockEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Entity entity = event.getEntity(); - if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity) || Suffocate.isBreathbent(entity)) + if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity) || Suffocate.isBreathbent(entity)) { event.setCancelled(true); + } if (event.getEntityType() == EntityType.FALLING_BLOCK) { - if (LavaSurge.falling.contains(entity)) { - LavaSurge.falling.remove(entity); + if (LavaSurge.getAllFallingBlocks().contains(entity)) { + LavaSurge.getAllFallingBlocks().remove(entity); event.setCancelled(true); } } @@ -415,13 +417,14 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityCombust(EntityCombustEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Entity entity = event.getEntity(); Block block = entity.getLocation().getBlock(); - if (FireStream.ignitedblocks.containsKey(block) && entity instanceof LivingEntity) { - new Enflamed(entity, FireStream.ignitedblocks.get(block)); + if (BlazeArc.getIgnitedBlocks().containsKey(block) && entity instanceof LivingEntity) { + new FireDamageTimer(entity, BlazeArc.getIgnitedBlocks().get(block)); } } @@ -439,7 +442,7 @@ public class PKListener implements Listener { } if (event.getDamager() != null) { - if (LavaWave.isBlockInWave(event.getDamager())) { + if (LavaSurgeWave.isBlockInWave(event.getDamager())) { event.setCancelled(true); } } @@ -447,25 +450,32 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityDamageEvent(EntityDamageEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Entity entity = event.getEntity(); - if (event.getCause() == DamageCause.FIRE && FireStream.ignitedblocks.containsKey(entity.getLocation().getBlock())) { - new Enflamed(entity, FireStream.ignitedblocks.get(entity.getLocation().getBlock())); + if (event.getCause() == DamageCause.FIRE && BlazeArc.getIgnitedBlocks().containsKey(entity.getLocation().getBlock())) { + new FireDamageTimer(entity, BlazeArc.getIgnitedBlocks().get(entity.getLocation().getBlock())); } - if (Enflamed.isEnflamed(entity) && event.getCause() == DamageCause.FIRE_TICK) { + if (FireDamageTimer.isEnflamed(entity) && event.getCause() == DamageCause.FIRE_TICK) { event.setCancelled(true); - Enflamed.dealFlameDamage(entity); + FireDamageTimer.dealFlameDamage(entity); } if (entity instanceof Player) { Player player = (Player) entity; - if (GeneralMethods.getBendingPlayer(player.getName()).isElementToggled(Element.Fire)) + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { return; - if (GeneralMethods.getBoundAbility(player) != null && GeneralMethods.getBoundAbility(player).equalsIgnoreCase("HeatControl")) { + } + + if (bPlayer.isElementToggled(Element.FIRE)) { + return; + } + if (bPlayer.getBoundAbilityName().equalsIgnoreCase("HeatControl")) { if (event.getCause() == DamageCause.FIRE || event.getCause() == DamageCause.FIRE_TICK) { player.setFireTicks(0); event.setCancelled(true); @@ -476,15 +486,16 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityDeath(EntityDeathEvent event) { - if (MetalClips.clipped.containsKey(event.getEntity())) { + if (MetalClips.getEntityClipsCount().containsKey(event.getEntity())) { List drops = event.getDrops(); List newdrops = new ArrayList(); for (int i = 0; i < drops.size(); i++) { - if (!(drops.get(i).getType() == Material.IRON_HELMET || drops.get(i).getType() == Material.IRON_CHESTPLATE || drops.get(i).getType() == Material.IRON_LEGGINGS || drops.get(i).getType() == Material.IRON_BOOTS || drops.get(i).getType() == Material.AIR)) + if (!(drops.get(i).getType() == Material.IRON_HELMET || drops.get(i).getType() == Material.IRON_CHESTPLATE || drops.get(i).getType() == Material.IRON_LEGGINGS || drops.get(i).getType() == Material.IRON_BOOTS || drops.get(i).getType() == Material.AIR)) { newdrops.add(drops.get(i)); + } } - newdrops.add(new ItemStack(Material.IRON_INGOT, MetalClips.clipped.get(event.getEntity()))); + newdrops.add(new ItemStack(Material.IRON_INGOT, MetalClips.getEntityClipsCount().get(event.getEntity()))); newdrops.add(MetalClips.getOriginalHelmet(event.getEntity())); newdrops.add(MetalClips.getOriginalChestplate(event.getEntity())); newdrops.add(MetalClips.getOriginalLeggings(event.getEntity())); @@ -492,125 +503,104 @@ public class PKListener implements Listener { event.getDrops().clear(); event.getDrops().addAll(newdrops); - MetalClips.clipped.remove(event.getEntity()); - } - if (EarthArmor.instances.containsKey(event.getEntity())) { - List drops = event.getDrops(); - List newdrops = new ArrayList<>(); - for (int i = 0; i < drops.size(); i++) { - if (!(drops.get(i).getType() == Material.LEATHER_BOOTS || drops.get(i).getType() == Material.LEATHER_CHESTPLATE || drops.get(i).getType() == Material.LEATHER_HELMET || drops.get(i).getType() == Material.LEATHER_LEGGINGS || drops.get(i).getType() == Material.AIR)) { - newdrops.add(drops.get(i)); - } - } - - for (int i = 0; i < 4; i++) { - newdrops.add(EarthArmor.instances.get(event.getEntity()).getOriginalArmor(i)); - } - - event.getDrops().clear(); - event.getDrops().addAll(newdrops); - EarthArmor.instances.remove(event.getEntity()); - } - if (PlantArmor.instances.containsKey(event.getEntity())) { - List drops = event.getDrops(); - List newdrops = new ArrayList<>(); - for (int i = 0; i < drops.size(); i++) { - if (!(drops.get(i).getType() == Material.LEATHER_BOOTS || drops.get(i).getType() == Material.LEATHER_CHESTPLATE || drops.get(i).getType() == PlantArmor.instances.get(event.getEntity()).blocktype || drops.get(i).getType() == Material.LEATHER_LEGGINGS || drops.get(i).getType() == Material.AIR)) { - newdrops.add(drops.get(i)); - } - } - - for (int i = 0; i < 4; i++) { - newdrops.add(PlantArmor.instances.get(event.getEntity()).getOriginalArmor(i)); - } - - event.getDrops().clear(); - event.getDrops().addAll(newdrops); - PlantArmor.instances.remove(event.getEntity()); + MetalClips.getEntityClipsCount().remove(event.getEntity()); } } @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onEntityExplode(EntityExplodeEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } for (Block block : event.blockList()) { EarthBlast blast = EarthBlast.getBlastFromSource(block); if (blast != null) { - blast.cancel(); + blast.remove(); } - if (FreezeMelt.frozenblocks.containsKey(block)) { - FreezeMelt.thaw(block); + if (PhaseChangeFreeze.getFrozenBlocks().containsKey(block)) { + PhaseChangeFreeze.thaw(block); } - if (WaterWall.wallblocks.containsKey(block)) { + if (SurgeWall.getWallBlocks().containsKey(block)) { block.setType(Material.AIR); } - if (!Wave.canThaw(block)) { - Wave.thaw(block); + if (!SurgeWave.canThaw(block)) { + SurgeWave.thaw(block); } - if (EarthMethods.movedearth.containsKey(block)) { - EarthMethods.removeRevertIndex(block); + if (EarthAbility.getMovedEarth().containsKey(block)) { + EarthAbility.removeRevertIndex(block); } } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityExplodeEvent(EntityExplodeEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Entity entity = event.getEntity(); - if (entity != null) - if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity) || Suffocate.isBreathbent(entity)) + if (entity != null) { + if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity) || Suffocate.isBreathbent(entity)) { event.setCancelled(true); + } + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityInteractEvent(EntityInteractEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Entity entity = event.getEntity(); - if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity) || Suffocate.isBreathbent(entity)) + if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity) || Suffocate.isBreathbent(entity)) { event.setCancelled(true); + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityProjectileLaunchEvent(ProjectileLaunchEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Entity entity = event.getEntity(); - if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity) || Suffocate.isBreathbent(entity)) + if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity) || Suffocate.isBreathbent(entity)) { event.setCancelled(true); + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityShootBowEvent(EntityShootBowEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Entity entity = event.getEntity(); - if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity) || Suffocate.isBreathbent(entity)) + if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity) || Suffocate.isBreathbent(entity)) { event.setCancelled(true); + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntitySlimeSplitEvent(SlimeSplitEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Entity entity = event.getEntity(); - if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity) || Suffocate.isBreathbent(entity)) + if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity) || Suffocate.isBreathbent(entity)) { event.setCancelled(true); + } } @EventHandler public void onEntitySuffocatedByTempBlocks(EntityDamageEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } if (event.getCause() == DamageCause.SUFFOCATION) { if (TempBlock.isTempBlock(event.getEntity().getLocation().add(0, 1, 0).getBlock())) { @@ -621,8 +611,9 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityTarget(EntityTargetEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Entity entity = event.getEntity(); if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity)) { @@ -632,8 +623,9 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityTargetLiving(EntityTargetLivingEntityEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Entity entity = event.getEntity(); if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity)) { @@ -643,12 +635,14 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityTeleportEvent(EntityTeleportEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Entity entity = event.getEntity(); - if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity) || Suffocate.isBreathbent(entity)) + if (Paralyze.isParalyzed(entity) || ChiCombo.isParalyzed(entity) || Bloodbending.isBloodbended(entity) || Suffocate.isBreathbent(entity)) { event.setCancelled(true); + } } @EventHandler @@ -660,9 +654,9 @@ public class PKListener implements Listener { double damage = ((e.getDistanceTraveled() - minimumDistance) < 0 ? 0 : e.getDistanceTraveled() - minimumDistance) / (e.getDifference().length()); if (damage > 0) { if(damage <= maxDamage) { - GeneralMethods.damageEntity(e.getInstigator(), e.getEntity(), damage, e.getElement(), e.getSubElement(), e.getAbility()); + GeneralMethods.damageEntity(e.getInstigator(), e.getEntity(), damage, e.getAbility()); } else { - GeneralMethods.damageEntity(e.getInstigator(), e.getEntity(), maxDamage, e.getElement(), e.getSubElement(), e.getAbility()); + GeneralMethods.damageEntity(e.getInstigator(), e.getEntity(), maxDamage, e.getAbility()); } } } @@ -671,73 +665,74 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onInventoryClick(InventoryClickEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; - - for (Player p : MetalClips.instances.keySet()) { - if (MetalClips.instances.get(p).getTarget() != null) - if (MetalClips.instances.get(p).getTarget().getEntityId() == event.getWhoClicked().getEntityId()) - event.setCancelled(true); } - if (event.getSlotType() == SlotType.ARMOR && !EarthArmor.canRemoveArmor((Player) event.getWhoClicked())) + for (MetalClips clips : CoreAbility.getAbilities(MetalClips.class)) { + if (clips.getTargetEntity() != null && clips.getTargetEntity().getEntityId() == event.getWhoClicked().getEntityId()) { + event.setCancelled(true); + break; + } + } + + if (event.getSlotType() == SlotType.ARMOR && CoreAbility.hasAbility((Player) event.getWhoClicked(), EarthArmor.class)) { event.setCancelled(true); - if (event.getSlotType() == SlotType.ARMOR && !PlantArmor.canRemoveArmor((Player) event.getWhoClicked())) + } + if (event.getSlotType() == SlotType.ARMOR && !PlantArmor.canRemoveArmor((Player) event.getWhoClicked())) { event.setCancelled(true); + } } @EventHandler(priority = EventPriority.NORMAL) public void onPlayerBendingDeath(PlayerBendingDeathEvent event) { if (ConfigManager.deathMsgConfig.get().getBoolean("Properties.Enabled")) { - if (event.getAbility() != null) { - StringBuilder sb = new StringBuilder(); - if (event.getSubElement() != null) { - sb.append(event.getSubElement().getChatColor()); - } else { - if (event.getElement() != null) { - sb.append(event.getElement().getChatColor()); - } else { - sb.append(GeneralMethods.getAvatarColor()); - } - } - sb.append(event.getAbility()); - bendingDeathPlayer.put(event.getVictim(), sb.toString()); - final Player player = event.getVictim(); - - new BukkitRunnable() { - @Override - public void run() { - bendingDeathPlayer.remove(player); - } - }.runTaskLater(ProjectKorra.plugin, 20); + CoreAbility ability = CoreAbility.getAbility(event.getAbility()); + + if (ability == null) { + return; } + + StringBuilder sb = new StringBuilder(); + sb.append(ability.getElement().getColor()); + sb.append(event.getAbility()); + BENDING_PLAYER_DEATH.put(event.getVictim(), sb.toString()); + final Player player = event.getVictim(); + + new BukkitRunnable() { + @Override + public void run() { + BENDING_PLAYER_DEATH.remove(player); + } + }.runTaskLater(ProjectKorra.plugin, 20); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerChat(AsyncPlayerChatEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; - - if (!plugin.getConfig().getBoolean("Properties.Chat.Enable")) { + } else if (!plugin.getConfig().getBoolean("Properties.Chat.Enable")) { return; } Player player = event.getPlayer(); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); ChatColor color = ChatColor.WHITE; + + if (bPlayer == null) { + return; + } - if (player.hasPermission("bending.avatar") || GeneralMethods.getBendingPlayer(player.getName()).getElements().size() > 1) { + if (player.hasPermission("bending.avatar") || bPlayer.getElements().size() > 1) { color = ChatColor.valueOf(plugin.getConfig().getString("Properties.Chat.Colors.Avatar")); - } else if (GeneralMethods.isBender(player.getName(), Element.Air)) { - color = ChatColor.valueOf(plugin.getConfig().getString("Properties.Chat.Colors.Air")); - } else if (GeneralMethods.isBender(player.getName(), Element.Water)) { - color = ChatColor.valueOf(plugin.getConfig().getString("Properties.Chat.Colors.Water")); - } else if (GeneralMethods.isBender(player.getName(), Element.Earth)) { - color = ChatColor.valueOf(plugin.getConfig().getString("Properties.Chat.Colors.Earth")); - } else if (GeneralMethods.isBender(player.getName(), Element.Fire)) { - color = ChatColor.valueOf(plugin.getConfig().getString("Properties.Chat.Colors.Fire")); - } else if (GeneralMethods.isBender(player.getName(), Element.Chi)) { - color = ChatColor.valueOf(plugin.getConfig().getString("Properties.Chat.Colors.Chi")); + } else { + for (Element element : Element.getMainElements()) { + if (bPlayer.hasElement(element)) { + color = ChatColor.valueOf(plugin.getConfig().getString("Properties.Chat.Colors." + element)); + break; + } + } } String format = plugin.getConfig().getString("Properties.Chat.Format"); @@ -748,26 +743,33 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerDamage(EntityDamageEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } if (event.getEntity() instanceof Player) { Player player = (Player) event.getEntity(); - - if (GeneralMethods.isBender(player.getName(), Element.Earth) && event.getCause() == DamageCause.FALL) { - Shockwave.fallShockwave(player); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + + if (bPlayer == null) { + return; } - if (GeneralMethods.isBender(player.getName(), Element.Air) && event.getCause() == DamageCause.FALL && GeneralMethods.canBendPassive(player.getName(), Element.Air)) { + if (bPlayer.hasElement(Element.EARTH) && event.getCause() == DamageCause.FALL) { + Shockwave shockwave = new Shockwave(player); + shockwave.fallShockwave(); + } + + if (bPlayer.hasElement(Element.AIR) && event.getCause() == DamageCause.FALL && bPlayer.canBendPassive(Element.AIR)) { new Flight(player); player.setAllowFlight(true); - AirBurst.fallBurst(player); + new AirBurst(player, true); player.setFallDistance(0); event.setDamage(0D); event.setCancelled(true); } - if (!event.isCancelled() && GeneralMethods.isBender(player.getName(), Element.Water) && event.getCause() == DamageCause.FALL && GeneralMethods.canBendPassive(player.getName(), Element.Water)) { + if (!event.isCancelled() && bPlayer.hasElement(Element.WATER) && event.getCause() == DamageCause.FALL && bPlayer.canBendPassive(Element.WATER)) { if (WaterPassive.applyNoFall(player)) { new Flight(player); player.setAllowFlight(true); @@ -777,7 +779,7 @@ public class PKListener implements Listener { } } - if (!event.isCancelled() && GeneralMethods.isBender(player.getName(), Element.Earth) && event.getCause() == DamageCause.FALL && GeneralMethods.canBendPassive(player.getName(), Element.Earth)) { + if (!event.isCancelled() && bPlayer.hasElement(Element.EARTH) && event.getCause() == DamageCause.FALL && bPlayer.canBendPassive(Element.EARTH)) { if (EarthPassive.softenLanding(player)) { new Flight(player); player.setAllowFlight(true); @@ -787,13 +789,13 @@ public class PKListener implements Listener { } } - if (!event.isCancelled() && GeneralMethods.isBender(player.getName(), Element.Chi) && event.getCause() == DamageCause.FALL && GeneralMethods.canBendPassive(player.getName(), Element.Chi)) { + if (!event.isCancelled() && bPlayer.hasElement(Element.CHI) && event.getCause() == DamageCause.FALL && bPlayer.canBendPassive(Element.CHI)) { if (player.isSprinting()) { event.setDamage(0); event.setCancelled(true); } else { double initdamage = event.getDamage(); - double newdamage = event.getDamage() * ChiPassive.FallReductionFactor; + double newdamage = event.getDamage() * ChiPassive.getFallReductionFactor(); double finaldamage = initdamage - newdamage; event.setDamage(finaldamage); } @@ -807,11 +809,13 @@ public class PKListener implements Listener { } } - if (GeneralMethods.canBendPassive(player.getName(), Element.Fire) && GeneralMethods.isBender(player.getName(), Element.Fire) && (event.getCause() == DamageCause.FIRE || event.getCause() == DamageCause.FIRE_TICK)) { - event.setCancelled(!Extinguish.canBurn(player)); + if (bPlayer.canBendPassive(Element.FIRE) + && bPlayer.hasElement(Element.FIRE) + && (event.getCause() == DamageCause.FIRE || event.getCause() == DamageCause.FIRE_TICK)) { + event.setCancelled(!HeatControlExtinguish.canBurn(player)); } - if (GeneralMethods.isBender(player.getName(), Element.Earth) && event.getCause() == DamageCause.SUFFOCATION && TempBlock.isTempBlock(player.getEyeLocation().getBlock())) { + if (bPlayer.hasElement(Element.EARTH) && event.getCause() == DamageCause.SUFFOCATION && TempBlock.isTempBlock(player.getEyeLocation().getBlock())) { event.setDamage(0D); event.setCancelled(true); } @@ -820,12 +824,13 @@ public class PKListener implements Listener { @EventHandler public void onPlayerDamageByPlayer(EntityDamageByEntityEvent e) { - if (e.isCancelled()) + if (e.isCancelled()) { return; + } Entity source = e.getDamager(); Entity entity = e.getEntity(); - Fireball fireball = Fireball.getFireball(source); + FireBlastCharged fireball = FireBlastCharged.getFireball(source); if (fireball != null) { e.setCancelled(true); @@ -833,10 +838,6 @@ public class PKListener implements Listener { return; } - // if (Combustion.fireballs.contains(source.getEntityId())) { - // e.setCancelled(true); - // } - if (Paralyze.isParalyzed(e.getDamager()) || ChiCombo.isParalyzed(e.getDamager())) { e.setCancelled(true); return; @@ -848,36 +849,43 @@ public class PKListener implements Listener { Entity en = e.getEntity(); if (en instanceof Player) { - // Player p = (Player) en; // This is the player getting hurt. if (e.getDamager() instanceof Player) { // This is the player hitting someone. - Player sourceplayer = (Player) e.getDamager(); - Player targetplayer = (Player) e.getEntity(); - if (GeneralMethods.canBendPassive(sourceplayer.getName(), Element.Chi)) { - if (GeneralMethods.isBender(sourceplayer.getName(), Element.Chi) && e.getCause() == DamageCause.ENTITY_ATTACK && e.getDamage() == 1) { - if (ChiMethods.isChiAbility(GeneralMethods.getBoundAbility(sourceplayer))) { - if (GeneralMethods.isWeapon(sourceplayer.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Chi.CanBendWithWeapons")) { + Player sourcePlayer = (Player) e.getDamager(); + Player targetPlayer = (Player) e.getEntity(); + BendingPlayer sourceBPlayer = BendingPlayer.getBendingPlayer(sourcePlayer); + if (sourceBPlayer == null) { + return; + } + + String boundAbil = sourceBPlayer.getBoundAbilityName(); + + if (sourceBPlayer.canBendPassive(Element.CHI)) { + if (e.getCause() == DamageCause.ENTITY_ATTACK && e.getDamage() == 1) { + if (sourceBPlayer.getBoundAbility() instanceof ChiAbility) { + if (GeneralMethods.isWeapon(sourcePlayer.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Chi.CanBendWithWeapons")) { return; } - if (GeneralMethods.getBendingPlayer(sourceplayer.getName()).isElementToggled(Element.Chi) == true) { - if (GeneralMethods.getBoundAbility(sourceplayer) != null && GeneralMethods.getBoundAbility(sourceplayer).equalsIgnoreCase("Paralyze")) { - new Paralyze(sourceplayer, targetplayer); + if (sourceBPlayer.isElementToggled(Element.CHI) == true) { + if (boundAbil.equalsIgnoreCase("Paralyze")) { + new Paralyze(sourcePlayer, targetPlayer); } else { - if (ChiPassive.willChiBlock(sourceplayer, targetplayer)) { - ChiPassive.blockChi(targetplayer); + if (ChiPassive.willChiBlock(sourcePlayer, targetPlayer)) { + ChiPassive.blockChi(targetPlayer); } } } } } } - if (GeneralMethods.canBendPassive(sourceplayer.getName(), Element.Chi)) { - if (GeneralMethods.isWeapon(sourceplayer.getItemInHand().getType()) && !ProjectKorra.plugin.getConfig().getBoolean("Properties.Chi.CanBendWithWeapons")) { + if (sourceBPlayer.canBendPassive(Element.CHI)) { + if (GeneralMethods.isWeapon(sourcePlayer.getItemInHand().getType()) && !ProjectKorra.plugin.getConfig().getBoolean("Properties.Chi.CanBendWithWeapons")) { return; } - if (e.getCause() == DamageCause.ENTITY_ATTACK && GeneralMethods.getBendingPlayer(sourceplayer.getName()).isElementToggled(Element.Chi) == true) { - if (GeneralMethods.getBoundAbility(sourceplayer) != null && GeneralMethods.getBoundAbility(sourceplayer).equalsIgnoreCase("Paralyze") && e.getDamage() == 1) { - if (sourceplayer.getWorld().equals(targetplayer.getWorld()) && Math.abs(sourceplayer.getLocation().distance(targetplayer.getLocation())) < 3) { - new Paralyze(sourceplayer, targetplayer); + if (e.getCause() == DamageCause.ENTITY_ATTACK && sourceBPlayer.isElementToggled(Element.CHI) == true) { + if (boundAbil.equalsIgnoreCase("Paralyze") && e.getDamage() == 1) { + if (sourcePlayer.getWorld().equals(targetPlayer.getWorld()) + && Math.abs(sourcePlayer.getLocation().distance(targetPlayer.getLocation())) < 3) { + new Paralyze(sourcePlayer, targetPlayer); } } } @@ -888,49 +896,70 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerDeath(PlayerDeathEvent event) { - if (event.getEntity().getKiller() == null) { + if (!(event.getEntity() instanceof Player)) { return; } - if (EarthArmor.instances.containsKey(event.getEntity())) { + + Player player = event.getEntity(); + EarthArmor earthArmor = CoreAbility.getAbility(player, EarthArmor.class); + PlantArmor plantArmor = CoreAbility.getAbility(player, PlantArmor.class); + + if (earthArmor != null) { List drops = event.getDrops(); - List newdrops = new ArrayList(); + List newDrops = new ArrayList(); for (int i = 0; i < drops.size(); i++) { - if (!(drops.get(i).getType() == Material.LEATHER_BOOTS || drops.get(i).getType() == Material.LEATHER_CHESTPLATE || drops.get(i).getType() == Material.LEATHER_HELMET || drops.get(i).getType() == Material.LEATHER_LEGGINGS || drops.get(i).getType() == Material.AIR)) - newdrops.add((drops.get(i))); + Material type = drops.get(i).getType(); + if (!(type == Material.LEATHER_BOOTS || type == Material.LEATHER_CHESTPLATE + || type == Material.LEATHER_HELMET || type == Material.LEATHER_LEGGINGS + || type == Material.AIR)) { + newDrops.add(drops.get(i)); + } } - if (EarthArmor.instances.get(event.getEntity()).oldarmor != null) { - for (ItemStack is : EarthArmor.instances.get(event.getEntity()).oldarmor) { - if (!(is.getType() == Material.AIR)) - newdrops.add(is); + if (earthArmor.getOldArmor() != null) { + for (ItemStack is : earthArmor.getOldArmor()) { + if (is.getType() != Material.AIR) { + newDrops.add(is); + } } } event.getDrops().clear(); - event.getDrops().addAll(newdrops); - EarthArmor.removeEffect(event.getEntity()); + event.getDrops().addAll(newDrops); + earthArmor.remove(); } - if (PlantArmor.instances.containsKey(event.getEntity())) { + + if (plantArmor != null) { List drops = event.getDrops(); - List newdrops = new ArrayList(); + List newDrops = new ArrayList<>(); + for (int i = 0; i < drops.size(); i++) { - if (!(drops.get(i).getType() == Material.LEATHER_BOOTS || drops.get(i).getType() == Material.LEATHER_CHESTPLATE || drops.get(i).getType() == Material.LEAVES || drops.get(i).getType() == Material.LEAVES_2 || drops.get(i).getType() == Material.LEATHER_LEGGINGS || drops.get(i).getType() == Material.AIR)) - newdrops.add((drops.get(i))); - } - if (PlantArmor.instances.get(event.getEntity()).oldarmor != null) { - for (ItemStack is : PlantArmor.instances.get(event.getEntity()).oldarmor) { - if (!(is.getType() == Material.AIR)) - newdrops.add(is); + Material type = drops.get(i).getType(); + if (!(type == Material.LEATHER_BOOTS || type == Material.LEATHER_CHESTPLATE + || type == Material.LEAVES || type == Material.LEAVES_2 + || type == Material.LEATHER_LEGGINGS || type == Material.AIR)) { + newDrops.add(drops.get(i)); + Bukkit.broadcastMessage("Adding " + drops.get(i)); } } + if (plantArmor.getOldArmor() != null) { + for (ItemStack is : plantArmor.getOldArmor()) { + if (!(is.getType() == Material.AIR)) { + newDrops.add(is); + } + } + } + event.getDrops().clear(); - event.getDrops().addAll(newdrops); - PlantArmor.removeEffect(event.getEntity()); + event.getDrops().addAll(newDrops); + plantArmor.remove(); } - if (MetalClips.clipped.containsKey(event.getEntity())) { + + if (MetalClips.getEntityClipsCount().containsKey(event.getEntity())) { List drops = event.getDrops(); List newdrops = new ArrayList(); for (int i = 0; i < drops.size(); i++) { - if (!(drops.get(i).getType() == Material.IRON_HELMET || drops.get(i).getType() == Material.IRON_CHESTPLATE || drops.get(i).getType() == Material.IRON_LEGGINGS || drops.get(i).getType() == Material.IRON_BOOTS || drops.get(i).getType() == Material.AIR)) + if (!(drops.get(i).getType() == Material.IRON_HELMET || drops.get(i).getType() == Material.IRON_CHESTPLATE || drops.get(i).getType() == Material.IRON_LEGGINGS || drops.get(i).getType() == Material.IRON_BOOTS || drops.get(i).getType() == Material.AIR)) { newdrops.add(drops.get(i)); + } } newdrops.add(MetalClips.getOriginalHelmet(event.getEntity())); @@ -940,87 +969,71 @@ public class PKListener implements Listener { event.getDrops().clear(); event.getDrops().addAll(newdrops); - MetalClips.clipped.remove(event.getEntity()); + MetalClips.getEntityClipsCount().remove(event.getEntity()); } - if (bendingDeathPlayer.containsKey(event.getEntity())) { - String message = ConfigManager.deathMsgConfig.get().getString("Properties.Default"); - String ability = bendingDeathPlayer.get(event.getEntity()); - String tempAbility = ChatColor.stripColor(ability).replaceAll(" ", ""); - Element element = null; - boolean isAvatarAbility = false; - if (GeneralMethods.abilityExists(tempAbility)) { - element = GeneralMethods.getAbilityElement(tempAbility); - if (element == null) { - isAvatarAbility = true; - ability = GeneralMethods.getAvatarColor() + tempAbility; + + if (event.getEntity().getKiller() != null) { + if (BENDING_PLAYER_DEATH.containsKey(event.getEntity())) { + String message = ConfigManager.deathMsgConfig.get().getString("Properties.Default"); + String ability = BENDING_PLAYER_DEATH.get(event.getEntity()); + String tempAbility = ChatColor.stripColor(ability).replaceAll(" ", ""); + CoreAbility coreAbil = CoreAbility.getAbility(ability); + Element element = null; + boolean isAvatarAbility = false; + + if (coreAbil != null) { + element = coreAbil.getElement(); } - } else if (ChatColor.getByChar(ability.substring(1, 2)) != null) { - element = Element.getFromChatColor(ChatColor.getByChar(ability.substring(1, 2))); - } - /* - Player killer = event.getEntity().getKiller(); - String killerAbility = GeneralMethods.getLastUsedAbility(killer, false); - if (ability == null) { - ability = GeneralMethods.getLastUsedAbility(killer, false); - if (ComboManager.checkForValidCombo(killer) != null) { - String combo = ComboManager.checkForValidCombo(killer).getName(); - if (combo != null && !combo.isEmpty()) { - element = GeneralMethods.getAbilityElement(killerAbility).name(); - ability = element + "Combo"; + + if (HorizontalVelocityTracker.hasBeenDamagedByHorizontalVelocity(event.getEntity()) && Arrays.asList(HorizontalVelocityTracker.abils).contains(tempAbility)) { + if (ConfigManager.deathMsgConfig.get().contains("HorizontalVelocity." + tempAbility)) { + message = ConfigManager.deathMsgConfig.get().getString("HorizontalVelocity." + tempAbility); + } + } else if (element != null) { + if (ConfigManager.deathMsgConfig.get().contains(element.toString() + "." + tempAbility)) { + message = ConfigManager.deathMsgConfig.get().getString(element + "." + tempAbility); + } else if (ConfigManager.deathMsgConfig.get().contains("Combo." + tempAbility)) { + message = ConfigManager.deathMsgConfig.get().getString("Combo." + tempAbility); } - } else if (ability != null && GeneralMethods.abilityExists(ability)) { - element = GeneralMethods.getAbilityElement(ability).name(); } else { - bendingDeathPlayer.remove(event.getEntity()); - return; - } - } - */ - if (HorizontalVelocityTracker.hasBeenDamagedByHorizontalVelocity(event.getEntity()) && Arrays.asList(HorizontalVelocityTracker.abils).contains(tempAbility)) { - if (ConfigManager.deathMsgConfig.get().contains("HorizontalVelocity." + tempAbility)) { - message = ConfigManager.deathMsgConfig.get().getString("HorizontalVelocity." + tempAbility); - } - } else if (element != null) { - if (ConfigManager.deathMsgConfig.get().contains(element.toString() + "." + tempAbility)) { - message = ConfigManager.deathMsgConfig.get().getString(element + "." + tempAbility); - } else if (ConfigManager.deathMsgConfig.get().contains("Combo." + tempAbility)) { - message = ConfigManager.deathMsgConfig.get().getString("Combo." + tempAbility); - } - } else { - if (isAvatarAbility) { - if (ConfigManager.deathMsgConfig.get().contains("Avatar." + tempAbility)) { - message = ConfigManager.deathMsgConfig.get().getString("Avatar." + tempAbility); + if (isAvatarAbility) { + if (ConfigManager.deathMsgConfig.get().contains("Avatar." + tempAbility)) { + message = ConfigManager.deathMsgConfig.get().getString("Avatar." + tempAbility); + } + } else if (ConfigManager.deathMsgConfig.get().contains("Combo." + tempAbility)) { + message = ConfigManager.deathMsgConfig.get().getString("Combo." + tempAbility); } - } else if (ConfigManager.deathMsgConfig.get().contains("Combo." + tempAbility)) { - message = ConfigManager.deathMsgConfig.get().getString("Combo." + tempAbility); } + message = message.replace("{victim}", event.getEntity().getName()).replace("{attacker}", event.getEntity().getKiller().getName()).replace("{ability}", ability); + event.setDeathMessage(message); + BENDING_PLAYER_DEATH.remove(event.getEntity()); } - message = message.replace("{victim}", event.getEntity().getName()).replace("{attacker}", event.getEntity().getKiller().getName()).replace("{ability}", ability); - event.setDeathMessage(message); - bendingDeathPlayer.remove(event.getEntity()); } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerInteraction(PlayerInteractEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Player player = event.getPlayer(); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { final UUID uuid = player.getUniqueId(); - interact.add(uuid); + RIGHT_CLICK_INTERACT.add(uuid); new BukkitRunnable() { + @Override public void run() { - interact.remove(uuid); + RIGHT_CLICK_INTERACT.remove(uuid); } }.runTaskLater(plugin, 5); - String ability = GeneralMethods.getBoundAbility(player); ComboManager.addComboAbility(player, ClickType.RIGHT_CLICK); - if (ability != null && ability.equalsIgnoreCase("EarthSmash")) + if (bPlayer.getBoundAbilityName().equalsIgnoreCase("EarthSmash")) { new EarthSmash(player, ClickType.RIGHT_CLICK); + } } if (Paralyze.isParalyzed(player) || ChiCombo.isParalyzed(player) || Bloodbending.isBloodbended(player) || Suffocate.isBreathbent(player)) { event.setCancelled(true); @@ -1035,15 +1048,17 @@ public class PKListener implements Listener { @EventHandler public void onPlayerKick(PlayerKickEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; - FlightAbility.remove(event.getPlayer()); + } + AirFlight.remove(event.getPlayer()); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerMove(PlayerMoveEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Player player = event.getPlayer(); if (Paralyze.isParalyzed(player)) { @@ -1056,7 +1071,9 @@ public class PKListener implements Listener { return; } - if (WaterSpout.instances.containsKey(event.getPlayer()) || AirSpout.getPlayers().contains(event.getPlayer()) || SandSpout.getPlayers().contains(event.getPlayer())) { + if (CoreAbility.hasAbility(player, WaterSpout.class) + || CoreAbility.hasAbility(player, AirSpout.class) + || CoreAbility.hasAbility(player, SandSpout.class)) { Vector vel = new Vector(); vel.setX(event.getTo().getX() - event.getFrom().getX()); vel.setY(event.getTo().getY() - event.getFrom().getY()); @@ -1066,8 +1083,6 @@ public class PKListener implements Listener { double maxspeed = .15; if (currspeed > maxspeed) { // only if moving set a factor - // double recspeed = 0.6; - // vel = vel.ultiply(recspeed * currspeed); vel = vel.normalize().multiply(maxspeed); // apply the new velocity (MAY REQUIRE A SCHEDULED TASK // INSTEAD!) @@ -1085,8 +1100,8 @@ public class PKListener implements Listener { } } - if (FlightAbility.contains(event.getPlayer())) { - if (FlightAbility.isHovering(event.getPlayer())) { + if (AirFlight.isFlying(event.getPlayer())) { + if (AirFlight.isHovering(event.getPlayer())) { Location loc = event.getFrom(); Location toLoc = player.getLocation(); @@ -1115,54 +1130,62 @@ public class PKListener implements Listener { @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { Player player = event.getPlayer(); - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer != null) { - if (GeneralMethods.toggledOut.contains(player.getUniqueId()) && bPlayer.isToggled()) - GeneralMethods.toggledOut.remove(player.getUniqueId()); - if (!bPlayer.isToggled()) - GeneralMethods.toggledOut.add(player.getUniqueId()); - } - - if (Commands.invincible.contains(event.getPlayer().getName())) { - Commands.invincible.remove(event.getPlayer().getName()); - } - Preset.unloadPreset(player); - //BendingPlayer.getPlayers().remove(event.getPlayer().getUniqueId()); - if (EarthArmor.instances.containsKey(event.getPlayer())) { - EarthArmor.removeEffect(event.getPlayer()); - event.getPlayer().removePotionEffect(PotionEffectType.DAMAGE_RESISTANCE); - } - if (PlantArmor.instances.containsKey(event.getPlayer())) { - PlantArmor.removeEffect(event.getPlayer()); - } - - for (Player p : MetalClips.instances.keySet()) { - if (MetalClips.instances.get(p).getTarget() != null) { - MetalClips.instances.get(p).remove(); + if (TOGGLED_OUT.contains(player.getUniqueId()) && bPlayer.isToggled()) { + TOGGLED_OUT.remove(player.getUniqueId()); + } + if (!bPlayer.isToggled()) { + TOGGLED_OUT.add(player.getUniqueId()); } } + if (Commands.invincible.contains(player.getName())) { + Commands.invincible.remove(player.getName()); + } + Preset.unloadPreset(player); + + EarthArmor earthArmor = CoreAbility.getAbility(player, EarthArmor.class); + PlantArmor plantArmor = CoreAbility.getAbility(player, PlantArmor.class); + MetalClips metalClips = CoreAbility.getAbility(player, MetalClips.class); + + if (earthArmor != null) { + earthArmor.remove(); + } + if (plantArmor != null) { + plantArmor.remove(); + } + if (metalClips != null) { + metalClips.remove(); + } + MultiAbilityManager.remove(player); - FlightAbility.remove(event.getPlayer()); + AirFlight.remove(event.getPlayer()); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerSneak(PlayerToggleSneakEvent event) { Player player = event.getPlayer(); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); - if (event.isCancelled()) + if (event.isCancelled() || bPlayer == null) { return; + } - if (player.isSneaking()) + if (player.isSneaking()) { ComboManager.addComboAbility(player, ClickType.SHIFT_UP); - else + } else { ComboManager.addComboAbility(player, ClickType.SHIFT_DOWN); + } + String abilName = bPlayer.getBoundAbilityName(); if (Suffocate.isBreathbent(player)) { - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirSwipe") || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("FireBlast") || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("EarthBlast") || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("WaterManipulation")) { - if(!player.isSneaking()) { - event.setCancelled(true); - } + if (!abilName.equalsIgnoreCase("AirSwipe") + || !abilName.equalsIgnoreCase("FireBlast") + || !abilName.equalsIgnoreCase("EarthBlast") + || !abilName.equalsIgnoreCase("WaterManipulation")) { + event.setCancelled(true); } } @@ -1171,27 +1194,35 @@ public class PKListener implements Listener { return; } - if (!player.isSneaking() && WaterArms.hasPlayer(player)) { - WaterArms.displayBoundMsg(player); + if (!player.isSneaking()) { + BlockSource.update(player, ClickType.SHIFT_DOWN); + } + + WaterArms waterArms = CoreAbility.getAbility(player, WaterArms.class); + if (!player.isSneaking() && waterArms != null) { + waterArms.displayBoundMsg(); return; } AirScooter.check(player); - String abil = GeneralMethods.getBoundAbility(player); - if (abil == null) { + + CoreAbility coreAbil = bPlayer.getBoundAbility(); + String abil = bPlayer.getBoundAbilityName(); + if (coreAbil == null) { return; } - if (ChiMethods.isChiBlocked(player.getName())) { + if (bPlayer.isChiBlocked()) { event.setCancelled(true); return; } - - if (!player.isSneaking() && GeneralMethods.canBend(player.getName(), abil)) { - if (GeneralMethods.isDisabledStockAbility(abil)) + + if (!player.isSneaking() && bPlayer.canBendIgnoreCooldowns(coreAbil)) { + if (coreAbil instanceof AddonAbility) { return; - if (AirMethods.isAirAbility(abil) && GeneralMethods.getBendingPlayer(player.getName()).isElementToggled(Element.Air) == true) { + } + if (coreAbil instanceof AirAbility && bPlayer.isElementToggled(Element.AIR) == true) { if (GeneralMethods.isWeapon(player.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Air.CanBendWithWeapons")) { return; } @@ -1202,13 +1233,13 @@ public class PKListener implements Listener { AirBlast.setOrigin(player); } if (abil.equalsIgnoreCase("AirBurst")) { - new AirBurst(player); + new AirBurst(player, false); } if (abil.equalsIgnoreCase("AirSuction")) { AirSuction.setOrigin(player); } if (abil.equalsIgnoreCase("AirSwipe")) { - AirSwipe.charge(player); + new AirSwipe(player, true); } if (abil.equalsIgnoreCase("AirShield")) { new AirShield(player); @@ -1217,13 +1248,14 @@ public class PKListener implements Listener { new Suffocate(player); } if (abil.equalsIgnoreCase("Flight")) { - if (player.isSneaking() || !AirMethods.canAirFlight(player)) + if (player.isSneaking() || !bPlayer.canUseFlight()) { return; - new FlightAbility(player); + } + new AirFlight(player); } } - if (WaterMethods.isWaterAbility(abil) && GeneralMethods.getBendingPlayer(player.getName()).isElementToggled(Element.Water) == true) { + if (coreAbil instanceof WaterAbility && bPlayer.isElementToggled(Element.WATER) == true) { if (GeneralMethods.isWeapon(player.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Water.CanBendWithWeapons")) { return; } @@ -1234,19 +1266,19 @@ public class PKListener implements Listener { new IceBlast(player); } if (abil.equalsIgnoreCase("IceSpike")) { - new IceSpike2(player); + new IceSpikeBlast(player); } if (abil.equalsIgnoreCase("OctopusForm")) { OctopusForm.form(player); } if (abil.equalsIgnoreCase("PhaseChange")) { - new Melt(player); + new PhaseChangeMelt(player); } if (abil.equalsIgnoreCase("WaterManipulation")) { new WaterManipulation(player); } if (abil.equalsIgnoreCase("Surge")) { - WaterWall.form(player); + SurgeWall.form(player); } if (abil.equalsIgnoreCase("Torrent")) { Torrent.create(player); @@ -1255,8 +1287,8 @@ public class PKListener implements Listener { new WaterArms(player); } } - - if (EarthMethods.isEarthAbility(abil) && GeneralMethods.getBendingPlayer(player.getName()).isElementToggled(Element.Earth) == true) { + + if (coreAbil instanceof EarthAbility && bPlayer.isElementToggled(Element.EARTH) == true) { if (GeneralMethods.isWeapon(player.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Earth.CanBendWithWeapons")) { return; } @@ -1264,38 +1296,39 @@ public class PKListener implements Listener { new EarthBlast(player); } if (abil.equalsIgnoreCase("RaiseEarth")) { - new EarthWall(player); + new RaiseEarthWall(player); } if (abil.equalsIgnoreCase("Collapse")) { - new Collapse(player); + new CollapseWall(player); } if (abil.equalsIgnoreCase("Shockwave")) { new Shockwave(player); } if (abil.equalsIgnoreCase("EarthGrab")) { - EarthGrab.EarthGrabSelf(player); + new EarthGrab(player, false); } if (abil.equalsIgnoreCase("EarthTunnel")) { new EarthTunnel(player); } if (abil.equalsIgnoreCase("Tremorsense")) { - GeneralMethods.getBendingPlayer(player.getName()).toggleTremorSense(); + bPlayer.toggleTremorSense(); } if (abil.equalsIgnoreCase("Extraction")) { new Extraction(player); } if (abil.equalsIgnoreCase("MetalClips")) { - if (MetalClips.instances.containsKey(player)) { - if (MetalClips.instances.get(player).getTarget() == null) - MetalClips.instances.get(player).magnet(); - else - MetalClips.instances.get(player).control(); - } else + MetalClips clips = CoreAbility.getAbility(player, MetalClips.class); + if (clips != null) { + if (clips.getTargetEntity() == null) { + clips.setMagnetized(true); + } else { + clips.setControlling(true); + } + } else { new MetalClips(player, 1); + } } - // if (abil.equalsIgnoreCase("LavaSurge")) { - // new LavaSurge(player); - // } + if (abil.equalsIgnoreCase("LavaFlow")) { new LavaFlow(player, LavaFlow.AbilityType.SHIFT); } @@ -1304,24 +1337,24 @@ public class PKListener implements Listener { } } - if (FireMethods.isFireAbility(abil) && GeneralMethods.getBendingPlayer(player.getName()).isElementToggled(Element.Fire) == true) { + if (coreAbil instanceof FireAbility && bPlayer.isElementToggled(Element.FIRE) == true) { if (GeneralMethods.isWeapon(player.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Fire.CanBendWithWeapons")) { return; } if (abil.equalsIgnoreCase("Blaze")) { - new RingOfFire(player); + new BlazeRing(player); } if (abil.equalsIgnoreCase("FireBlast")) { - new Fireball(player); + new FireBlastCharged(player); } if (abil.equalsIgnoreCase("HeatControl")) { - new HeatControl(player); + new HeatControlSolidify(player); } if (abil.equalsIgnoreCase("FireBurst")) { new FireBurst(player); } if (abil.equalsIgnoreCase("FireShield")) { - FireShield.shield(player); + new FireShield(player, true); } if (abil.equalsIgnoreCase("Lightning")) { new Lightning(player); @@ -1335,46 +1368,48 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerSwing(PlayerAnimationEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } Player player = event.getPlayer(); - - if (interact.contains(player.getUniqueId())) return; + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + return; + } else if (RIGHT_CLICK_INTERACT.contains(player.getUniqueId())) { + return; + } ComboManager.addComboAbility(player, ClickType.LEFT_CLICK); if (Suffocate.isBreathbent(player)) { - if (GeneralMethods.getBoundAbility(player) != null || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirSwipe") || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("FireBlast") || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("EarthBlast") || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("WaterManipulation")) { - event.setCancelled(true); - } - } - - if (Bloodbending.isBloodbended(player) || Paralyze.isParalyzed(player) || ChiCombo.isParalyzed(player)) { - event.setCancelled(true); - return; - } - - if (ChiMethods.isChiBlocked(player.getName())) { - event.setCancelled(true); - return; - } - - if (GeneralMethods.isInteractable(player.getTargetBlock((Set)null, 5))) { + event.setCancelled(true); + return; + } else if (Bloodbending.isBloodbended(player) || Paralyze.isParalyzed(player) || ChiCombo.isParalyzed(player)) { + event.setCancelled(true); + return; + } else if (bPlayer.isChiBlocked()) { + event.setCancelled(true); + return; + } else if (GeneralMethods.isInteractable(player.getTargetBlock((Set)null, 5))) { event.setCancelled(true); return; } + BlockSource.update(player, ClickType.LEFT_CLICK); AirScooter.check(player); - String abil = GeneralMethods.getBoundAbility(player); - if (abil == null && !MultiAbilityManager.hasMultiAbilityBound(player)) + String abil = bPlayer.getBoundAbilityName(); + CoreAbility coreAbil = bPlayer.getBoundAbility(); + + if (coreAbil == null && !MultiAbilityManager.hasMultiAbilityBound(player)) { return; - if (GeneralMethods.canBend(player.getName(), abil)) { - if (GeneralMethods.isDisabledStockAbility(abil)) + } else if (bPlayer.canBendIgnoreCooldowns(coreAbil)) { + if (coreAbil instanceof AddonAbility) { return; + } - if (AirMethods.isAirAbility(abil) && GeneralMethods.getBendingPlayer(player.getName()).isElementToggled(Element.Air) == true) { + if (coreAbil instanceof AirAbility && bPlayer.isElementToggled(Element.AIR) == true) { if (GeneralMethods.isWeapon(player.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Air.CanBendWithWeapons")) { return; } @@ -1397,20 +1432,21 @@ public class PKListener implements Listener { new AirSwipe(player); } if (abil.equalsIgnoreCase("Flight")) { - if (!ProjectKorra.plugin.getConfig().getBoolean("Abilities.Air.Flight.HoverEnabled") || !AirMethods.canAirFlight(player)) + if (!ProjectKorra.plugin.getConfig().getBoolean("Abilities.Air.Flight.HoverEnabled") || !bPlayer.canUseFlight()) { return; + } - if (FlightAbility.contains(event.getPlayer())) { - if (FlightAbility.isHovering(event.getPlayer())) { - FlightAbility.setHovering(event.getPlayer(), false); + if (AirFlight.isFlying(event.getPlayer())) { + if (AirFlight.isHovering(event.getPlayer())) { + AirFlight.setHovering(event.getPlayer(), false); } else { - FlightAbility.setHovering(event.getPlayer(), true); + AirFlight.setHovering(event.getPlayer(), true); } } } } - if (WaterMethods.isWaterAbility(abil) && GeneralMethods.getBendingPlayer(player.getName()).isElementToggled(Element.Water) == true) { + if (coreAbil instanceof WaterAbility && bPlayer.isElementToggled(Element.WATER) == true) { if (GeneralMethods.isWeapon(player.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Water.CanBendWithWeapons")) { return; } @@ -1421,13 +1457,13 @@ public class PKListener implements Listener { IceBlast.activate(player); } if (abil.equalsIgnoreCase("IceSpike")) { - IceSpike2.activate(player); + IceSpikeBlast.activate(player); } if (abil.equalsIgnoreCase("OctopusForm")) { new OctopusForm(player); } if (abil.equalsIgnoreCase("PhaseChange")) { - new FreezeMelt(player); + new PhaseChangeFreeze(player); } if (abil.equalsIgnoreCase("PlantArmor")) { new PlantArmor(player); @@ -1439,14 +1475,14 @@ public class PKListener implements Listener { WaterManipulation.moveWater(player); } if (abil.equalsIgnoreCase("Surge")) { - new WaterWall(player); + new SurgeWall(player); } if (abil.equalsIgnoreCase("Torrent")) { new Torrent(player); } } - if (EarthMethods.isEarthAbility(abil) && GeneralMethods.getBendingPlayer(player.getName()).isElementToggled(Element.Earth) == true) { + if (coreAbil instanceof EarthAbility && bPlayer.isElementToggled(Element.EARTH) == true) { if (GeneralMethods.isWeapon(player.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Earth.CanBendWithWeapons")) { return; } @@ -1457,10 +1493,10 @@ public class PKListener implements Listener { EarthBlast.throwEarth(player); } if (abil.equalsIgnoreCase("RaiseEarth")) { - new EarthColumn(player); + new RaiseEarth(player); } if (abil.equalsIgnoreCase("Collapse")) { - new CompactColumn(player); + new Collapse(player); } if (abil.equalsIgnoreCase("Shockwave")) { Shockwave.coneShockwave(player); @@ -1469,26 +1505,26 @@ public class PKListener implements Listener { new EarthArmor(player); } if (abil.equalsIgnoreCase("EarthGrab")) { - new EarthGrab(player); + new EarthGrab(player, true); } if (abil.equalsIgnoreCase("Tremorsense")) { new Tremorsense(player); } if (abil.equalsIgnoreCase("MetalClips")) { - if (!MetalClips.instances.containsKey(player)) { + MetalClips clips = CoreAbility.getAbility(player, MetalClips.class); + if (clips == null) { new MetalClips(player, 0); - } else if (MetalClips.instances.containsKey(player)) { - if (MetalClips.instances.get(player).metalclips < (player.hasPermission("bending.ability.MetalClips.4clips") ? 4 : 3)) - MetalClips.instances.get(player).shootMetal(); - else { - if (MetalClips.isControllingEntity(player)) - MetalClips.instances.get(player).launch(); - } + } else if (clips.getMetalClipsCount() < (player.hasPermission("bending.ability.MetalClips.4clips") ? 4 : 3)) { + clips.shootMetal(); + } else if (MetalClips.isControllingEntity(player)) { + clips.launch(); } } if (abil.equalsIgnoreCase("LavaSurge")) { - if (LavaSurge.instances.containsKey(player)) - LavaSurge.instances.get(player).launch(); + LavaSurge surge = CoreAbility.getAbility(player, LavaSurge.class); + if (surge != null) { + surge.launch(); + } } if (abil.equalsIgnoreCase("LavaFlow")) { new LavaFlow(player, AbilityType.CLICK); @@ -1501,12 +1537,12 @@ public class PKListener implements Listener { } } - if (FireMethods.isFireAbility(abil) && GeneralMethods.getBendingPlayer(player.getName()).isElementToggled(Element.Fire) == true) { + if (coreAbil instanceof FireAbility && bPlayer.isElementToggled(Element.FIRE) == true) { if (GeneralMethods.isWeapon(player.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Fire.CanBendWithWeapons")) { return; } if (abil.equalsIgnoreCase("Blaze")) { - new ArcOfFire(player); + new Blaze(player); } if (abil.equalsIgnoreCase("FireBlast")) { new FireBlast(player); @@ -1515,7 +1551,7 @@ public class PKListener implements Listener { new FireJet(player); } if (abil.equalsIgnoreCase("HeatControl")) { - new Extinguish(player); + new HeatControlExtinguish(player); } if (abil.equalsIgnoreCase("Illumination")) { new Illumination(player); @@ -1534,7 +1570,7 @@ public class PKListener implements Listener { } } - if (ChiMethods.isChiAbility(abil) && GeneralMethods.getBendingPlayer(player.getName()).isElementToggled(Element.Chi) == true) { + if (coreAbil instanceof ChiAbility && bPlayer.isElementToggled(Element.CHI) == true) { if (GeneralMethods.isWeapon(player.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Chi.CanBendWithWeapons")) { return; } @@ -1576,35 +1612,44 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerToggleFlight(PlayerToggleFlightEvent event) { - if (event.isCancelled()) + if (event.isCancelled()) { return; + } - Player p = event.getPlayer(); - if (Tornado.getPlayers().contains(p) || Bloodbending.isBloodbended(p) || Suffocate.isBreathbent(p) || FireJet.getPlayers().contains(p) || AvatarState.getPlayers().contains(p)) { - event.setCancelled(p.getGameMode() != GameMode.CREATIVE); + Player player = event.getPlayer(); + if (CoreAbility.hasAbility(player, Tornado.class) + || Bloodbending.isBloodbended(player) + || Suffocate.isBreathbent(player) + || CoreAbility.hasAbility(player, FireJet.class) + || CoreAbility.hasAbility(player, AvatarState.class)) { + event.setCancelled(player.getGameMode() != GameMode.CREATIVE); } } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onProjectileHit(ProjectileHitEvent event) { Integer id = event.getEntity().getEntityId(); - if (Smokescreen.snowballs.contains(id)) { + Smokescreen smokescreen = Smokescreen.getSnowballs().get(id); + if (smokescreen != null) { Location loc = event.getEntity().getLocation(); Smokescreen.playEffect(loc); - for (Entity en : GeneralMethods.getEntitiesAroundPoint(loc, Smokescreen.radius)) { - Smokescreen.applyBlindness(en); + for (Entity en : GeneralMethods.getEntitiesAroundPoint(loc, smokescreen.getRadius())) { + smokescreen.applyBlindness(en); } - Smokescreen.snowballs.remove(id); + Smokescreen.getSnowballs().remove(id); } - // if (Combustion.fireballs.contains(id)) { - // Location loc = event.getEntity().getLocation(); - //// for (Entity en: Methods.getEntitiesAroundPoint(loc, 4)) { - //// if (en instanceof LivingEntity) { - //// LivingEntity le = (LivingEntity) en; - //// le.damage(ProjectKorra.plugin.getConfig().getDouble("Abilities.Fire.Combustion.Damage")); - //// } - //// } - // } + } + + public static HashMap getBendingPlayerDeath() { + return BENDING_PLAYER_DEATH; + } + + public static List getRightClickInteract() { + return RIGHT_CLICK_INTERACT; + } + + public static ArrayList getToggledOut() { + return TOGGLED_OUT; } } diff --git a/src/com/projectkorra/projectkorra/ProjectKorra.java b/src/com/projectkorra/projectkorra/ProjectKorra.java index ff53ce8c..84ebd1cf 100644 --- a/src/com/projectkorra/projectkorra/ProjectKorra.java +++ b/src/com/projectkorra/projectkorra/ProjectKorra.java @@ -1,17 +1,14 @@ package com.projectkorra.projectkorra; -import com.projectkorra.projectkorra.ability.AbilityModuleManager; -import com.projectkorra.projectkorra.ability.combo.ComboManager; -import com.projectkorra.projectkorra.ability.combo.ComboModuleManager; -import com.projectkorra.projectkorra.ability.multiability.MultiAbilityManager; -import com.projectkorra.projectkorra.ability.multiability.MultiAbilityModuleManager; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.util.ComboManager; +import com.projectkorra.projectkorra.ability.util.MultiAbilityManager; import com.projectkorra.projectkorra.airbending.AirbendingManager; import com.projectkorra.projectkorra.chiblocking.ChiblockingManager; import com.projectkorra.projectkorra.command.Commands; import com.projectkorra.projectkorra.configuration.ConfigManager; import com.projectkorra.projectkorra.earthbending.EarthbendingManager; import com.projectkorra.projectkorra.firebending.FirebendingManager; -import com.projectkorra.projectkorra.object.Preset; import com.projectkorra.projectkorra.storage.DBConnection; import com.projectkorra.projectkorra.util.MetricsLite; import com.projectkorra.projectkorra.util.RevertChecker; @@ -34,7 +31,7 @@ public class ProjectKorra extends JavaPlugin { public static PKLogHandler handler; public static long time_step = 1; public Updater updater; - public AbilityModuleManager abManager; + @Override public void onEnable() { plugin = this; @@ -50,17 +47,14 @@ public class ProjectKorra extends JavaPlugin { catch (SecurityException | IOException e) { e.printStackTrace(); } + + CoreAbility.registerAbilities(); new ConfigManager(); new GeneralMethods(this); updater = new Updater(this, "http://projectkorra.com/forums/dev-builds.16/index.rss"); new Commands(this); - abManager = new AbilityModuleManager(this); - new MultiAbilityModuleManager(); new MultiAbilityManager(); - new ComboModuleManager(); new ComboManager(); - - Preset.loadExternalPresets(); DBConnection.host = getConfig().getString("Storage.MySQL.host"); DBConnection.port = getConfig().getInt("Storage.MySQL.port"); @@ -94,8 +88,9 @@ public class ProjectKorra extends JavaPlugin { e.printStackTrace(); } + double cacheTime = ConfigManager.getConfig().getDouble("Properties.RegionProtection.CacheBlockTime"); GeneralMethods.deserializeFile(); - GeneralMethods.startCacheCleaner(GeneralMethods.CACHE_TIME); + GeneralMethods.startCacheCleaner(cacheTime); updater.checkUpdate(); } diff --git a/src/com/projectkorra/projectkorra/SubElement.java b/src/com/projectkorra/projectkorra/SubElement.java deleted file mode 100644 index a47a151a..00000000 --- a/src/com/projectkorra/projectkorra/SubElement.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.projectkorra.projectkorra; - -import com.projectkorra.projectkorra.command.Commands; - -import org.bukkit.ChatColor; - -import java.util.Arrays; - -public enum SubElement { - - //Air - Flight (Element.Air, Commands.flightaliases), - SpiritualProjection (Element.Air, Commands.spiritualprojectionaliases), - - //Water - Bloodbending (Element.Water, Commands.bloodaliases), - Healing (Element.Water, Commands.healingaliases), - Icebending (Element.Water, Commands.icealiases), - Plantbending (Element.Water, Commands.plantaliases), - - // Earth - Metalbending (Element.Earth, Commands.metalbendingaliases), - Sandbending (Element.Earth, Commands.sandbendingaliases), - Lavabending (Element.Earth, Commands.lavabendingaliases), - - // Fire - Combustion (Element.Fire, Commands.combustionaliases), - Lightning (Element.Fire, Commands.lightningaliases); - - private Element element; - private String[] aliases; - - SubElement(Element mainElement, String[] aliases) { - this.element = mainElement; - this.aliases = aliases; - } - - /**Returns the main element associated with the subelement - * @return The main element*/ - public Element getMainElement() { - return element; - } - - /**Returns the subelement's chatcolor that should be used - * @return The subelement's ChatColor*/ - public ChatColor getChatColor() { - return element.getSubColor(); - } - - public static SubElement getType(String string) { - for (SubElement se : SubElement.values()) { - if (Arrays.asList(se.aliases).contains(string.toLowerCase())) { - return se; - } - } - return null; - } - - public static SubElement getType(int index) { - if (index == -1) - return null; - return Arrays.asList(values()).get(index); - } - -} diff --git a/src/com/projectkorra/projectkorra/ability/Ability.java b/src/com/projectkorra/projectkorra/ability/Ability.java new file mode 100644 index 00000000..436794d9 --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/Ability.java @@ -0,0 +1,42 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; + +import org.bukkit.Location; +import org.bukkit.entity.Player; + +public interface Ability { + + public void progress(); + + public void remove(); + + public boolean isSneakAbility(); + + /** + * Determines if this ability is considered harmless against other players. A harmless + * ability cannot manipulate another player. For example: AirPassive, + * WaterSpout, AirSpout, and FireJet. + * @return true if the ability is harmless and should be allowed in both PvP and non-PvP zones. + */ + public boolean isHarmlessAbility(); + + public boolean isIgniteAbility(); + + public boolean isExplosiveAbility(); + + public boolean isHiddenAbility(); + + public long getCooldown(); + + public Player getPlayer(); + + public String getName(); + + public String getDescription(); + + public Element getElement(); + + public Location getLocation(); + +} diff --git a/src/com/projectkorra/projectkorra/ability/AbilityModule.java b/src/com/projectkorra/projectkorra/ability/AbilityModule.java deleted file mode 100644 index 5619c9db..00000000 --- a/src/com/projectkorra/projectkorra/ability/AbilityModule.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.projectkorra.projectkorra.ability; - -import com.projectkorra.projectkorra.SubElement; -import com.projectkorra.projectkorra.util.AbilityLoadable; - -public abstract class AbilityModule extends AbilityLoadable implements Cloneable { - - /** - * AbilityModule Constructor. - * - * @param name The name of the ability. - */ - public AbilityModule(final String name) { - super(name); - } - - /** - * Called when the ability is loaded by PK. This is where the developer - * registers Listeners and Permissions. - */ - public abstract void onThisLoad(); - - // Must be overridden - - /** - * Accessor Method to get the version of the ability. - * - * @return The version of the ability as a String. - */ - public abstract String getVersion(); - - /** - * Accessor Method to get the Element of the ability. It is recommended to - * use the Element ENUM to get the returned String. This can be an empty - * String, in which case the ability will not belong to any element (such as - * AvatarState). - * - * @return The Element the ability belongs to. - */ - public abstract String getElement(); - - /** - * Accessor Method to get the name of the author. - * - * @return The name of the author. - */ - public abstract String getAuthor(); - - /** - * Accessor Method to get the description of the ability. This String is - * sent to any player who runs /pk display ability. - * - * @return The Description of the ability. - */ - public abstract String getDescription(); - - /** - * Accessor Method to get whether this ability uses sneaking to operate. - * Some features of the ProjectKorra plugin only work when this is false. - * (Fast Swimming for Waterbenders) - * - * @return Whether or not the ability uses the sneak key. - */ - public abstract boolean isShiftAbility(); - - /** - * Accessor Method to get whether this ability harms entities. AirSpout is - * an example of a harmless ability. For AirSpout, this returns true. - * IceBlast is an example of a harmful ability. For IceBlast, this returns - * false. Torrent is an example of both a harmless and a harmful ability. - * For Torrent, this returns false. - * - * @return Whether of not the ability can hurt entities. - */ - public abstract boolean isHarmlessAbility(); - - /** - * Accessor Method to get whether this ability can set fire to blocks. - * - * @return Whether or not this ability can ignite blocks. - */ - public boolean isIgniteAbility() { - return false; - } - - /** - * Accessor Method to get whether this ability can create explosions. - * - * @return Whether or not this ability creates explosions. - */ - public boolean isExplodeAbility() { - return false; - } - - /** - * Void Method called whenever ProjectKorra stops and the ability is - * unloaded. - * - */ - public void stop() { - } - - /** - * Accessor Method to get which SubElement the ability belongs to. If - * isSubAbility() returns true, the developer absolutely must implement this - * as well. - * - * List of sub-elements: - * - * Water: Icebending. Bloodbending. Plantbending. Healing. - * - * Earth: Sandbending. Metalbending. Lavabending. - * - * Fire: Combustion. Lightning. - * - * Air: Flight. SpiritualProjection. - * - * @return The SubElement the ability belongs to. - */ - public SubElement getSubElement() { - return null; - } -} diff --git a/src/com/projectkorra/projectkorra/ability/AbilityModuleManager.java b/src/com/projectkorra/projectkorra/ability/AbilityModuleManager.java deleted file mode 100644 index 9e5b9646..00000000 --- a/src/com/projectkorra/projectkorra/ability/AbilityModuleManager.java +++ /dev/null @@ -1,427 +0,0 @@ -package com.projectkorra.projectkorra.ability; - -import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.command.Commands; -import com.projectkorra.projectkorra.util.AbilityLoader; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; - -public class AbilityModuleManager { - - static ProjectKorra plugin; - public static List ability; - private final AbilityLoader loader; - - public static HashSet abilities; - public static HashSet disabledStockAbilities; - public static List waterbendingabilities; - public static List airbendingabilities; - public static List earthbendingabilities; - public static List firebendingabilities; - public static List chiabilities; - public static List shiftabilities; - public static HashMap authors; - public static List harmlessabilities; - public static List igniteabilities; - public static List explodeabilities; - public static List metalbendingabilities; - public static List earthsubabilities; - public static List subabilities; - public static List lightningabilities; - public static List combustionabilities; - public static List lavaabilities; - public static List sandabilities; - public static List metalabilities; - public static List flightabilities; - public static List spiritualprojectionabilities; - public static List iceabilities; - public static List healingabilities; - public static List plantabilities; - public static List bloodabilities; - - public static HashMap descriptions; - - public AbilityModuleManager(final ProjectKorra plugin) { - AbilityModuleManager.plugin = plugin; - final File path = new File(plugin.getDataFolder().toString() + "/Abilities/"); - if (!path.exists()) { - path.mkdir(); - } - loader = new AbilityLoader(plugin, path, new Object[] {}); - abilities = new HashSet(); - waterbendingabilities = new ArrayList(); - airbendingabilities = new ArrayList(); - earthbendingabilities = new ArrayList(); - firebendingabilities = new ArrayList(); - chiabilities = new ArrayList(); - shiftabilities = new ArrayList(); - descriptions = new HashMap(); - authors = new HashMap(); - harmlessabilities = new ArrayList(); - explodeabilities = new ArrayList(); - igniteabilities = new ArrayList(); - metalbendingabilities = new ArrayList(); - earthsubabilities = new ArrayList(); - subabilities = new ArrayList(); - ability = loader.load(AbilityModule.class); - disabledStockAbilities = new HashSet(); - lightningabilities = new ArrayList(); - combustionabilities = new ArrayList(); - flightabilities = new ArrayList(); - spiritualprojectionabilities = new ArrayList(); - metalabilities = new ArrayList(); - sandabilities = new ArrayList(); - lavaabilities = new ArrayList(); - healingabilities = new ArrayList(); - plantabilities = new ArrayList(); - iceabilities = new ArrayList(); - bloodabilities = new ArrayList(); - fill(); - } - - private void fill() { - - for (StockAbility a : StockAbility.values()) { - if (StockAbility.isAirbending(a)) { - if (ProjectKorra.plugin.getConfig().getBoolean("Abilities.Air." + a.name() + ".Enabled")) { - abilities.add(a.name()); - airbendingabilities.add(a.name()); - descriptions.put(a.name(), ProjectKorra.plugin.getConfig().getString("Abilities.Air." + a.name() + ".Description")); - if (a == StockAbility.AirScooter) - harmlessabilities.add(a.name()); - if (a == StockAbility.AirSpout) - harmlessabilities.add(a.name()); - if (a == StockAbility.Tornado) - shiftabilities.add(a.name()); - if (a == StockAbility.AirSuction) - shiftabilities.add(a.name()); - if (a == StockAbility.AirSwipe) - shiftabilities.add(a.name()); - if (a == StockAbility.AirBlast) - shiftabilities.add(a.name()); - if (a == StockAbility.AirBurst) - shiftabilities.add(a.name()); - if (a == StockAbility.AirShield) - shiftabilities.add(a.name()); - if (a == StockAbility.Flight) - shiftabilities.add(a.name()); - - // Air Sub Abilities - if (a == StockAbility.Flight) - subabilities.add(a.name()); - if (a == StockAbility.Flight) - flightabilities.add(a.name()); - } - } else if (StockAbility.isWaterbending(a)) { - if (ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water." + a.name() + ".Enabled")) { - abilities.add(a.name()); - waterbendingabilities.add(a.name()); - descriptions.put(a.name(), ProjectKorra.plugin.getConfig().getString("Abilities.Water." + a.name() + ".Description")); - if (a == StockAbility.WaterSpout) - harmlessabilities.add(a.name()); - if (a == StockAbility.HealingWaters) - harmlessabilities.add(a.name()); - if (a == StockAbility.Surge) - shiftabilities.add(a.name()); - if (a == StockAbility.Bloodbending) - shiftabilities.add(a.name()); - if (a == StockAbility.PhaseChange) - shiftabilities.add(a.name()); - if (a == StockAbility.HealingWaters) - shiftabilities.add(a.name()); - if (a == StockAbility.OctopusForm) - shiftabilities.add(a.name()); - if (a == StockAbility.Torrent) - shiftabilities.add(a.name()); - if (a == StockAbility.WaterManipulation) - shiftabilities.add(a.name()); - if (a == StockAbility.IceSpike) - shiftabilities.add(a.name()); - if (a == StockAbility.IceBlast) - shiftabilities.add(a.name()); - if (a == StockAbility.WaterArms) - shiftabilities.add(a.name()); - - // Water Sub Abilities - if (a == StockAbility.HealingWaters) - subabilities.add(a.name()); - if (a == StockAbility.Bloodbending) - subabilities.add(a.name()); - if (a == StockAbility.PhaseChange) - subabilities.add(a.name()); - if (a == StockAbility.IceSpike) - subabilities.add(a.name()); - if (a == StockAbility.IceBlast) - subabilities.add(a.name()); - if (a == StockAbility.PlantArmor) - subabilities.add(a.name()); - - if (a == StockAbility.HealingWaters) - healingabilities.add(a.name()); - if (a == StockAbility.Bloodbending) - bloodabilities.add(a.name()); - if (a == StockAbility.PhaseChange) - iceabilities.add(a.name()); - if (a == StockAbility.IceSpike) - iceabilities.add(a.name()); - if (a == StockAbility.IceBlast) - iceabilities.add(a.name()); - if (a == StockAbility.PlantArmor) - plantabilities.add(a.name()); - } - } else if (StockAbility.isEarthbending(a)) { - if (ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth." + a.name() + ".Enabled")) { - abilities.add(a.name()); - earthbendingabilities.add(a.name()); - descriptions.put(a.name(), ProjectKorra.plugin.getConfig().getString("Abilities.Earth." + a.name() + ".Description")); - if (a == StockAbility.Tremorsense) - harmlessabilities.add(a.name()); - if (a == StockAbility.RaiseEarth) - shiftabilities.add(a.name()); - if (a == StockAbility.Collapse) - shiftabilities.add(a.name()); - if (a == StockAbility.EarthBlast) - shiftabilities.add(a.name()); - if (a == StockAbility.Shockwave) - shiftabilities.add(a.name()); - if (a == StockAbility.EarthTunnel) - shiftabilities.add(a.name()); - if (a == StockAbility.EarthGrab) - shiftabilities.add(a.name()); - if (a == StockAbility.LavaFlow) - shiftabilities.add(a.name()); - if (a == StockAbility.MetalClips) - shiftabilities.add(a.name()); - if (a == StockAbility.EarthSmash) - shiftabilities.add(a.name()); - if (a == StockAbility.SandSpout) - shiftabilities.add(a.name()); - - // Earth Sub Abilities - if (a == StockAbility.MetalClips) - subabilities.add(a.name()); - if (a == StockAbility.Extraction) - subabilities.add(a.name()); - if (a == StockAbility.LavaFlow) - subabilities.add(a.name()); - if (a == StockAbility.SandSpout) - subabilities.add(a.name()); - - if (a == StockAbility.MetalClips) - metalabilities.add(a.name()); - if (a == StockAbility.Extraction) - metalabilities.add(a.name()); - if (a == StockAbility.LavaFlow) - lavaabilities.add(a.name()); - if (a == StockAbility.SandSpout) - sandabilities.add(a.name()); - // if (a == StockAbility.LavaSurge) earthsubabilities.add(a.name()); - - } - } else if (StockAbility.isFirebending(a)) { - if (ProjectKorra.plugin.getConfig().getBoolean("Abilities.Fire." + a.name() + ".Enabled")) { - abilities.add(a.name()); - firebendingabilities.add(a.name()); - descriptions.put(a.name(), ProjectKorra.plugin.getConfig().getString("Abilities.Fire." + a.name() + ".Description")); - if (a == StockAbility.Illumination) - harmlessabilities.add(a.name()); - if (a == StockAbility.Blaze) - igniteabilities.add(a.name()); - if (a == StockAbility.FireBlast) - explodeabilities.add(a.name()); - if (a == StockAbility.Lightning) - explodeabilities.add(a.name()); - if (a == StockAbility.Combustion) - explodeabilities.add(a.name()); - if (a == StockAbility.HeatControl) - shiftabilities.add(a.name()); - if (a == StockAbility.Lightning) - shiftabilities.add(a.name()); - if (a == StockAbility.FireBlast) - shiftabilities.add(a.name()); - if (a == StockAbility.Blaze) - shiftabilities.add(a.name()); - if (a == StockAbility.FireBurst) - shiftabilities.add(a.name()); - - // Fire Sub Abilities - if (a == StockAbility.Lightning) - subabilities.add(a.name()); - if (a == StockAbility.Combustion) - subabilities.add(a.name()); - - if (a == StockAbility.Lightning) - lightningabilities.add(a.name()); - if (a == StockAbility.Combustion) - combustionabilities.add(a.name()); - } - } else if (StockAbility.isChiBlocking(a)) { - if (ProjectKorra.plugin.getConfig().getBoolean("Abilities.Chi." + a.name() + ".Enabled")) { - abilities.add(a.name()); - chiabilities.add(a.name()); - descriptions.put(a.name(), ProjectKorra.plugin.getConfig().getString("Abilities.Chi." + a.name() + ".Description")); - if (a == StockAbility.HighJump) - harmlessabilities.add(a.name()); - } - } else { - if (ProjectKorra.plugin.getConfig().getBoolean("Abilities." + a.name() + ".Enabled")) { - abilities.add(a.name()); // AvatarState, etc. - descriptions.put(a.name(), ProjectKorra.plugin.getConfig().getString("Abilities." + a.name() + ".Description")); - } - } - } - for (AbilityModule ab : ability) { - try { - //To check if EarthBlast == Earthblast or for example, EarthBlast == EARTHBLAST - boolean succes = true; - for (String enabledAbility : abilities) { - if (enabledAbility.equalsIgnoreCase(ab.getName())) { - succes = false; - } - } - if (!succes) - continue; - ab.onThisLoad(); - abilities.add(ab.getName()); - for (StockAbility a : StockAbility.values()) { - if (a.name().equalsIgnoreCase(ab.getName())) { - disabledStockAbilities.add(a.name()); - } - } - if (ab.getElement() == Element.Air.toString()) - airbendingabilities.add(ab.getName()); - if (ab.getElement() == Element.Water.toString()) - waterbendingabilities.add(ab.getName()); - if (ab.getElement() == Element.Earth.toString()) - earthbendingabilities.add(ab.getName()); - if (ab.getElement() == Element.Fire.toString()) - firebendingabilities.add(ab.getName()); - if (ab.getElement() == Element.Chi.toString()) - chiabilities.add(ab.getName()); - if (ab.isShiftAbility()) - shiftabilities.add(ab.getName()); - if (ab.isHarmlessAbility()) - harmlessabilities.add(ab.getName()); - - if (ab.getSubElement() != null) { - subabilities.add(ab.getName()); - switch (ab.getSubElement()) { - case Bloodbending: - bloodabilities.add(ab.getName()); - break; - case Combustion: - combustionabilities.add(ab.getName()); - break; - case Flight: - flightabilities.add(ab.getName()); - break; - case Healing: - healingabilities.add(ab.getName()); - break; - case Icebending: - iceabilities.add(ab.getName()); - break; - case Lavabending: - lavaabilities.add(ab.getName()); - break; - case Lightning: - lightningabilities.add(ab.getName()); - break; - case Metalbending: - metalabilities.add(ab.getName()); - break; - case Plantbending: - plantabilities.add(ab.getName()); - break; - case Sandbending: - sandabilities.add(ab.getName()); - break; - case SpiritualProjection: - spiritualprojectionabilities.add(ab.getName()); - break; - } - } - - // if (ab.isMetalbendingAbility()) metalbendingabilities.add(ab.getName()); - descriptions.put(ab.getName(), ab.getDescription()); - authors.put(ab.getName(), ab.getAuthor()); - } - catch (Exception | Error e) { //If triggered means ability was made before specific version . - ProjectKorra.log.warning("The ability " + ab.getName() + " was not able to load, if this message shows again please remove it!"); - //ProjectKorra.log.warning("The ability " + ab.getName() + " is either broken or outdated. Please remove it!"); - e.printStackTrace(); - ab.stop(); - abilities.remove(ab.getName()); - final AbilityModule skill = ab; - //Bellow to avoid ConcurrentModificationException - plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { - public void run() { - ability.remove(skill); - } - }, 10); - continue; - } - } - - Collections.sort(airbendingabilities); - Collections.sort(firebendingabilities); - Collections.sort(earthbendingabilities); - Collections.sort(waterbendingabilities); - Collections.sort(chiabilities); - Collections.sort(iceabilities); - Collections.sort(lavaabilities); - Collections.sort(bloodabilities); - Collections.sort(sandabilities); - Collections.sort(metalabilities); - Collections.sort(lightningabilities); - Collections.sort(combustionabilities); - Collections.sort(healingabilities); - Collections.sort(flightabilities); - Collections.sort(plantabilities); - Collections.sort(spiritualprojectionabilities); - } - - public List getAbilities(String element) { - element = element.toLowerCase(); - if (Arrays.asList(Commands.wateraliases).contains(element)) - return waterbendingabilities; - else if (Arrays.asList(Commands.icealiases).contains(element)) - return iceabilities; - else if (Arrays.asList(Commands.plantaliases).contains(element)) - return plantabilities; - else if (Arrays.asList(Commands.healingaliases).contains(element)) - return healingabilities; - else if (Arrays.asList(Commands.bloodaliases).contains(element)) - return bloodabilities; - else if (Arrays.asList(Commands.airaliases).contains(element)) - return airbendingabilities; - else if (Arrays.asList(Commands.flightaliases).contains(element)) - return flightabilities; - else if (Arrays.asList(Commands.spiritualprojectionaliases).contains(element)) - return spiritualprojectionabilities; - else if (Arrays.asList(Commands.earthaliases).contains(element)) - return earthbendingabilities; - else if (Arrays.asList(Commands.lavabendingaliases).contains(element)) - return lavaabilities; - else if (Arrays.asList(Commands.metalbendingaliases).contains(element)) - return metalabilities; - else if (Arrays.asList(Commands.sandbendingaliases).contains(element)) - return sandabilities; - else if (Arrays.asList(Commands.firealiases).contains(element)) - return firebendingabilities; - else if (Arrays.asList(Commands.combustionaliases).contains(element)) - return combustionabilities; - else if (Arrays.asList(Commands.lightningaliases).contains(element)) - return lightningabilities; - else if (Arrays.asList(Commands.chialiases).contains(element)) - return chiabilities; - return null; - } -} diff --git a/src/com/projectkorra/projectkorra/ability/AddonAbility.java b/src/com/projectkorra/projectkorra/ability/AddonAbility.java new file mode 100644 index 00000000..2e7b836d --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/AddonAbility.java @@ -0,0 +1,25 @@ +package com.projectkorra.projectkorra.ability; + +public interface AddonAbility { + + /** + * Called when the ability is loaded by PK. This is where the developer + * registers Listeners and Permissions. + */ + public void load(); + + /** + * Void Method called whenever ProjectKorra stops and the ability is + * unloaded. + */ + public void stop(); + + public String getAuthor(); + + /** + * Accessor Method to get the version of the ability. + * + * @return The version of the ability as a String. + */ + public String getVersion(); +} diff --git a/src/com/projectkorra/projectkorra/ability/AirAbility.java b/src/com/projectkorra/projectkorra/ability/AirAbility.java new file mode 100644 index 00000000..ec1b5665 --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/AirAbility.java @@ -0,0 +1,147 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.airbending.AirSpout; +import com.projectkorra.projectkorra.airbending.Suffocate; +import com.projectkorra.projectkorra.util.ParticleEffect; + +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +public abstract class AirAbility extends ElementalAbility { + + public AirAbility(Player player) { + super(player); + } + + @Override + public boolean isIgniteAbility() { + return false; + } + + @Override + public boolean isExplosiveAbility() { + return false; + } + + @Override + public Element getElement() { + return Element.AIR; + } + + /** + * Breaks a breathbendng hold on an entity or one a player is inflicting on an entity. + * + * @param entity The entity to be acted upon + */ + public static void breakBreathbendingHold(Entity entity) { + if (Suffocate.isBreathbent(entity)) { + Suffocate.breakSuffocate(entity); + return; + } + + if (entity instanceof Player) { + Player player = (Player) entity; + if (Suffocate.isChannelingSphere(player)) { + Suffocate.remove(player); + } + } + } + + /** + * Gets the Air Particles from the config. + * + * @return Config specified ParticleEffect + */ + public static ParticleEffect getAirbendingParticles() { + String particle = getConfig().getString("Properties.Air.Particles"); + if (particle == null) { + return ParticleEffect.CLOUD; + } else if (particle.equalsIgnoreCase("spell")) { + return ParticleEffect.SPELL; + } else if (particle.equalsIgnoreCase("blacksmoke")) { + return ParticleEffect.SMOKE; + } else if (particle.equalsIgnoreCase("smoke")) { + return ParticleEffect.CLOUD; + } else if (particle.equalsIgnoreCase("smallsmoke")) { + return ParticleEffect.SNOW_SHOVEL; + } else { + return ParticleEffect.CLOUD; + } + } + + /** + * Checks whether a location is within an AirShield. + * + * @param loc The location to check + * @return true If the location is inside an AirShield. + */ + public static boolean isWithinAirShield(Location loc) { + List list = new ArrayList(); + list.add("AirShield"); + return GeneralMethods.blockAbilities(null, list, loc, 0); + } + + /** + * Plays an integer amount of air particles in a location. + * + * @param loc The location to use + * @param amount The amount of particles + */ + public static void playAirbendingParticles(Location loc, int amount) { + playAirbendingParticles(loc, amount, (float) Math.random(), (float) Math.random(), (float) Math.random()); + } + + /** + * Plays an integer amount of air particles in a location with a given xOffset, yOffset, and + * zOffset. + * + * @param loc The location to use + * @param amount The amount of particles + * @param xOffset The xOffset to use + * @param yOffset The yOffset to use + * @param zOffset The zOffset to use + */ + public static void playAirbendingParticles(Location loc, int amount, float xOffset, float yOffset, float zOffset) { + getAirbendingParticles().display(loc, xOffset, yOffset, zOffset, 0, amount); + } + + /** + * Plays the Airbending Sound at a location if enabled in the config. + * + * @param loc The location to play the sound at + */ + public static void playAirbendingSound(Location loc) { + if (getConfig().getBoolean("Properties.Air.PlaySound")) { + loc.getWorld().playSound(loc, Sound.CREEPER_HISS, 1, 5); + } + } + + /** + * Removes all air spouts in a location within a certain radius. + * + * @param loc The location to use + * @param radius The radius around the location to remove spouts in + * @param source The player causing the removal + */ + public static void removeAirSpouts(Location loc, double radius, Player source) { + AirSpout.removeSpouts(loc, radius, source); + } + + /** + * Removes all air spouts in a location with a radius of 1.5. + * + * @param loc The location to use + * @param source The player causing the removal + */ + public static void removeAirSpouts(Location loc, Player source) { + removeAirSpouts(loc, 1.5, source); + } + +} diff --git a/src/com/projectkorra/projectkorra/ability/AvatarAbility.java b/src/com/projectkorra/projectkorra/ability/AvatarAbility.java new file mode 100644 index 00000000..36530ca6 --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/AvatarAbility.java @@ -0,0 +1,34 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; + +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.Player; + +public abstract class AvatarAbility extends ElementalAbility { + + public AvatarAbility(Player player) { + super(player); + } + + @Override + public boolean isIgniteAbility() { + return false; + } + + @Override + public boolean isExplosiveAbility() { + return false; + } + + @Override + public final Element getElement() { + return Element.AVATAR; + } + + public static void playAvatarSound(Location loc) { + loc.getWorld().playSound(loc, Sound.ANVIL_LAND, 1, 10); + } + +} diff --git a/src/com/projectkorra/projectkorra/ability/AvatarState.java b/src/com/projectkorra/projectkorra/ability/AvatarState.java deleted file mode 100644 index 558c3eff..00000000 --- a/src/com/projectkorra/projectkorra/ability/AvatarState.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.projectkorra.projectkorra.ability; - -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.util.Flight; - -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public class AvatarState { - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - //public static Map cooldowns = new HashMap(); - public static Map startTimes = new HashMap(); - - public static FileConfiguration config = ProjectKorra.plugin.getConfig(); - private static final long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.AvatarState.Cooldown"); - private static boolean regenEnabled = config.getBoolean("Abilities.AvatarState.PotionEffects.Regeneration.Enabled"); - private static int regenPower = config.getInt("Abilities.AvatarState.PotionEffects.Regeneration.Power") - 1; - private static boolean speedEnabled = config.getBoolean("Abilities.AvatarState.PotionEffects.Speed.Enabled"); - private static int speedPower = config.getInt("Abilities.AvatarState.PotionEffects.Speed.Power") - 1; - private static boolean resistanceEnabled = config.getBoolean("Abilities.AvatarState.PotionEffects.DamageResistance.Enabled"); - private static int resistancePower = config.getInt("Abilities.AvatarState.PotionEffects.DamageResistance.Power") - 1; - private static boolean fireResistanceEnabled = config.getBoolean("Abilities.AvatarState.PotionEffects.FireResistance.Enabled"); - private static int fireResistancePower = config.getInt("Abilities.AvatarState.PotionEffects.FireResistance.Power") - 1; - private static long duration = config.getLong("Abilities.AvatarState.Duration"); - - public static final double factor = config.getDouble("Abilities.AvatarState.PowerMultiplier"); - - Player player; - - // boolean canfly = false; - - public AvatarState(Player player) { - this.player = player; - if (instances.containsKey(player)) { - instances.remove(player); - return; - } - //if (cooldowns.containsKey(player.getName())) { - //if (cooldowns.get(player.getName()) + cooldown >= System.currentTimeMillis()) { - //return; - //} else { - //cooldowns.remove(player.getName()); - //} - //} - if (GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("AvatarState")) { - return; - } - new Flight(player); - GeneralMethods.playAvatarSound(player.getLocation()); - instances.put(player, this); - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("AvatarState", cooldown); - if (duration != 0) { - startTimes.put(player.getName(), System.currentTimeMillis()); - } - } - - public static void manageAvatarStates() { - for (Player player : instances.keySet()) { - progress(player); - } - } - - public static boolean progress(Player player) { - return instances.get(player).progress(); - } - - private boolean progress() { - if (player.isDead() || !player.isOnline()) { - instances.remove(player); - return false; - } - if (!GeneralMethods.canBend(player.getName(), StockAbility.AvatarState.name())) { - instances.remove(player); - if (player != null) { - if (GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("AvatarState")) { - GeneralMethods.getBendingPlayer(player.getName()).removeCooldown("AvatarState"); - } - return false; - } - } - - if (startTimes.containsKey(player.getName())) { - if (startTimes.get(player.getName()) + duration < System.currentTimeMillis()) { - startTimes.remove(player.getName()); - instances.remove(player); - } - } - - addPotionEffects(); - return true; - } - - private void addPotionEffects() { - int duration = 70; - if (regenEnabled) { - player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, duration, regenPower)); - } - if (speedEnabled) { - player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, duration, speedPower)); - } - if (resistanceEnabled) { - player.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, duration, resistancePower)); - } - if (fireResistanceEnabled) { - player.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, duration, fireResistancePower)); - } - } - - public static boolean isAvatarState(Player player) { - if (instances.containsKey(player)) - return true; - return false; - } - - public static double getValue(double value) { - return factor * value; - } - - public static int getValue(int value) { - return (int) factor * value; - } - - public static ArrayList getPlayers() { - ArrayList players = new ArrayList(); - for (Player player : instances.keySet()) { - players.add(player); - } - return players; - } -} diff --git a/src/com/projectkorra/projectkorra/ability/BlockAbility.java b/src/com/projectkorra/projectkorra/ability/BlockAbility.java new file mode 100644 index 00000000..c8246976 --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/BlockAbility.java @@ -0,0 +1,11 @@ +package com.projectkorra.projectkorra.ability; + +import org.bukkit.entity.Player; + +public abstract class BlockAbility extends ElementalAbility { + + public BlockAbility(Player player) { + super(player); + } + +} diff --git a/src/com/projectkorra/projectkorra/ability/BloodAbility.java b/src/com/projectkorra/projectkorra/ability/BloodAbility.java new file mode 100644 index 00000000..106e68f2 --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/BloodAbility.java @@ -0,0 +1,27 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; + +import org.bukkit.entity.Player; + +public abstract class BloodAbility extends WaterAbility implements SubAbility { + + public BloodAbility(Player player) { + super(player); + } + + @Override + public Class getParentAbility() { + return WaterAbility.class; + } + + @Override + public Element getElement() { + return Element.BLOOD; + } + + @Override + public Element getParentElement() { + return Element.WATER; + } +} diff --git a/src/com/projectkorra/projectkorra/ability/ChiAbility.java b/src/com/projectkorra/projectkorra/ability/ChiAbility.java new file mode 100644 index 00000000..c4d0f09f --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/ChiAbility.java @@ -0,0 +1,28 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; + +import org.bukkit.entity.Player; + +public abstract class ChiAbility extends ElementalAbility { + + public ChiAbility(Player player) { + super(player); + } + + @Override + public boolean isIgniteAbility() { + return false; + } + + @Override + public boolean isExplosiveAbility() { + return false; + } + + @Override + public Element getElement() { + return Element.CHI; + } + +} diff --git a/src/com/projectkorra/projectkorra/ability/ComboAbility.java b/src/com/projectkorra/projectkorra/ability/ComboAbility.java new file mode 100644 index 00000000..0e9ee09e --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/ComboAbility.java @@ -0,0 +1,35 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation; + +import org.bukkit.entity.Player; + +import java.util.ArrayList; + +public interface ComboAbility { + + /** + * Accessor Method to get the instructions for using this combo. + * + * @return The steps for the combo. + */ + public abstract String getInstructions(); + + /** + * Creates a new instance of the combo from a specific player. + * ProjectKorra's ComboModuleManager will use this method once the combo + * steps have been used by the player. + * + * @return A new instance of the ability. + * @param player The player using the combo. + */ + public abstract Object createNewComboInstance(Player player); + + /** + * Returns the list of abilities which constitute the combo. + * + * @return An ArrayList containing the combo's steps. + */ + public abstract ArrayList getCombination(); + +} diff --git a/src/com/projectkorra/projectkorra/ability/api/CombustionAbility.java b/src/com/projectkorra/projectkorra/ability/CombustionAbility.java similarity index 52% rename from src/com/projectkorra/projectkorra/ability/api/CombustionAbility.java rename to src/com/projectkorra/projectkorra/ability/CombustionAbility.java index 0b34aee6..084e4fcd 100644 --- a/src/com/projectkorra/projectkorra/ability/api/CombustionAbility.java +++ b/src/com/projectkorra/projectkorra/ability/CombustionAbility.java @@ -1,19 +1,27 @@ -package com.projectkorra.projectkorra.ability.api; +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; import org.bukkit.entity.Player; public abstract class CombustionAbility extends FireAbility implements SubAbility { - - public CombustionAbility(Player player, boolean autoStart) { - super(player, autoStart); - } - + public CombustionAbility(Player player) { super(player); } + @Override public Class getParentAbility() { return FireAbility.class; } + @Override + public Element getElement() { + return Element.COMBUSTION; + } + + @Override + public Element getParentElement() { + return Element.FIRE; + } } diff --git a/src/com/projectkorra/projectkorra/ability/CoreAbility.java b/src/com/projectkorra/projectkorra/ability/CoreAbility.java new file mode 100644 index 00000000..20a9330f --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/CoreAbility.java @@ -0,0 +1,386 @@ +package com.projectkorra.projectkorra.ability; + +import sun.reflect.ReflectionFactory; + +import com.google.common.reflect.ClassPath; +import com.google.common.reflect.ClassPath.ClassInfo; +import com.projectkorra.projectkorra.BendingPlayer; +import com.projectkorra.projectkorra.Element; +import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.util.AbilityLoader; +import com.projectkorra.projectkorra.ability.util.ComboManager; +import com.projectkorra.projectkorra.ability.util.MultiAbilityManager; +import com.projectkorra.projectkorra.ability.util.MultiAbilityManager.MultiAbilityInfo; +import com.projectkorra.projectkorra.configuration.ConfigManager; + +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListMap; + +public abstract class CoreAbility implements Ability { + + private static final ConcurrentHashMap, ConcurrentHashMap>> INSTANCES = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap, Set> INSTANCES_BY_CLASS = new ConcurrentHashMap<>(); + private static final ConcurrentSkipListMap ABILITIES_BY_NAME = new ConcurrentSkipListMap<>(); + + private static int idCounter; + + protected long startTime; + protected Player player; + protected BendingPlayer bPlayer; + + private boolean started; + private boolean removed; + private int id; + + static { + idCounter = Integer.MIN_VALUE; + } + + public CoreAbility() { + // Need the default constructor for reflection purposes + } + + public CoreAbility(Player player) { + if (player == null) { + return; + } + + this.player = player; + this.bPlayer = BendingPlayer.getBendingPlayer(player); + this.startTime = System.currentTimeMillis(); + this.started = false; + this.id = CoreAbility.idCounter; + + if (idCounter == Integer.MAX_VALUE) { + idCounter = Integer.MIN_VALUE; + } else { + idCounter++; + } + } + + public void start() { + if (player == null) { + return; + } + + this.started = true; + this.startTime = System.currentTimeMillis(); + Class clazz = getClass(); + UUID uuid = player.getUniqueId(); + + if (!INSTANCES.containsKey(clazz)) { + INSTANCES.put(clazz, new ConcurrentHashMap>()); + } + if (!INSTANCES.get(clazz).containsKey(uuid)) { + INSTANCES.get(clazz).put(uuid, new ConcurrentHashMap()); + } + if (!INSTANCES_BY_CLASS.containsKey(clazz)) { + INSTANCES_BY_CLASS.put(clazz, Collections.newSetFromMap(new ConcurrentHashMap())); + } + + INSTANCES.get(clazz).get(uuid).put(this.id, this); + INSTANCES_BY_CLASS.get(clazz).add(this); + } + + @Override + public void remove() { + if (player == null) { + return; + } + + removed = true; + + ConcurrentHashMap> classMap = INSTANCES.get(getClass()); + if (classMap != null) { + ConcurrentHashMap playerMap = classMap.get(player.getUniqueId()); + if (playerMap != null) { + playerMap.remove(this.id); + if (playerMap.size() == 0) { + classMap.remove(player.getUniqueId()); + } + } + + if (classMap.size() == 0) { + INSTANCES.remove(getClass()); + } + } + + if (INSTANCES_BY_CLASS.containsKey(getClass())) { + INSTANCES_BY_CLASS.get(getClass()).remove(this); + } + } + + public static void progressAll() { + for (Set setAbils : INSTANCES_BY_CLASS.values()) { + for (CoreAbility abil : setAbils) { + abil.progress(); + } + } + } + + public static void removeAll() { + for (Set setAbils : INSTANCES_BY_CLASS.values()) { + for (CoreAbility abil : setAbils) { + abil.remove(); + } + } + } + + public static void removeAll(Class clazz) { + for (CoreAbility abil : getAbilities(clazz)) { + abil.remove(); + } + } + + public static T getAbility(Player player, Class clazz) { + Collection abils = getAbilities(player, clazz); + if (abils.iterator().hasNext()) { + return abils.iterator().next(); + } + return null; + } + + public static CoreAbility getAbility(String abilityName) { + return abilityName != null ? ABILITIES_BY_NAME.get(abilityName.toLowerCase()) : null; + } + + public static ArrayList getAbilities() { + return new ArrayList(ABILITIES_BY_NAME.values()); + } + + @SuppressWarnings("unchecked") + public static Collection getAbilities(Class clazz) { + if (clazz == null || INSTANCES_BY_CLASS.get(clazz) == null || INSTANCES_BY_CLASS.get(clazz).size() == 0) { + return Collections.emptySet(); + } + return (Collection) CoreAbility.INSTANCES_BY_CLASS.get(clazz); + } + + @SuppressWarnings("unchecked") + public static Collection getAbilities(Player player, Class clazz) { + if (player == null || clazz == null || INSTANCES.get(clazz) == null || INSTANCES.get(clazz).get(player.getUniqueId()) == null) { + return Collections.emptySet(); + } + return (Collection) INSTANCES.get(clazz).get(player.getUniqueId()).values(); + } + + public static ArrayList getAbilitiesByElement(Element element) { + ArrayList abilities = new ArrayList(); + if (element != null) { + for (CoreAbility ability : getAbilities()) { + if (ability.getElement() == element) { + abilities.add(ability); + } else if (ability instanceof SubAbility) { + SubAbility subAbil = (SubAbility) ability; + if (subAbil.getParentElement() == element) { + abilities.add(ability); + } + } + } + } + return abilities; + } + + public static boolean hasAbility(Player player, Class clazz) { + return getAbility(player, clazz) != null; + } + + public static HashSet getPlayers(Class clazz) { + HashSet players = new HashSet<>(); + if (clazz != null) { + ConcurrentHashMap> uuidMap = INSTANCES.get(clazz); + if (uuidMap != null) { + for (UUID uuid : uuidMap.keySet()) { + Player uuidPlayer = Bukkit.getPlayer(uuid); + if (uuidPlayer != null) { + players.add(uuidPlayer); + } + } + } + } + return players; + } + + public static void registerAbilities() { + ABILITIES_BY_NAME.clear(); + registerPluginAbilities(ProjectKorra.plugin, "com.projectkorra"); + registerAddonAbilities("/Abilities/"); + } + + public static void registerPluginAbilities(JavaPlugin plugin, String packagePrefix) { + if (plugin == null) { + return; + } + + Class pluginClass = plugin.getClass(); + ClassLoader loader = pluginClass.getClassLoader(); + ReflectionFactory rf = ReflectionFactory.getReflectionFactory(); + + try { + for (final ClassInfo info : ClassPath.from(loader).getAllClasses()) { + if (!info.getPackageName().startsWith(packagePrefix)) { + continue; + } + + Class clazz = null; + try { + clazz = info.load(); + if (!CoreAbility.class.isAssignableFrom(clazz) || clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) { + continue; + } + + Constructor objDef = CoreAbility.class.getDeclaredConstructor(); + Constructor intConstr = rf.newConstructorForSerialization(clazz, objDef);; + CoreAbility ability = (CoreAbility) clazz.cast(intConstr.newInstance()); + + if (ability != null && ability.getName() != null) { + ABILITIES_BY_NAME.put(ability.getName().toLowerCase(), ability); + } + } catch (Exception e) { + } catch (Error e) { + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void registerAddonAbilities(String folder) { + ProjectKorra plugin = ProjectKorra.plugin; + File path = new File(plugin.getDataFolder().toString() + folder); + AbilityLoader abilityLoader = new AbilityLoader(plugin, path); + List loadedAbilities = abilityLoader.load(CoreAbility.class, CoreAbility.class); + + for (CoreAbility coreAbil : loadedAbilities) { + if (!(coreAbil instanceof AddonAbility)) { + plugin.getLogger().warning(coreAbil.getName() + " is an addon ability and must implement the AddonAbility interface"); + continue; + } + + AddonAbility addon = (AddonAbility) coreAbil; + String name = coreAbil.getName(); + + try { + addon.load(); + ABILITIES_BY_NAME.put(name.toLowerCase(), coreAbil); + + if (coreAbil instanceof ComboAbility) { + ComboAbility combo = (ComboAbility) coreAbil; + if (combo.getCombination() != null) { + ComboManager.getComboAbilities().put(name, new ComboManager.ComboAbilityInfo(name, combo.getCombination(), combo)); + ComboManager.getDescriptions().put(name, coreAbil.getDescription()); + ComboManager.getInstructions().put(name, combo.getInstructions()); + ComboManager.getAuthors().put(name, addon.getAuthor()); + } + } + + if (coreAbil instanceof MultiAbility) { + MultiAbility multiAbil = (MultiAbility) coreAbil; + MultiAbilityManager.multiAbilityList.add(new MultiAbilityInfo(name, multiAbil.getMultiAbilities())); + } + } catch (Exception | Error e) { + plugin.getLogger().warning("The ability " + coreAbil.getName() + " was not able to load, if this message shows again please remove it!"); + e.printStackTrace(); + addon.stop(); + ABILITIES_BY_NAME.remove(coreAbil.getName(), coreAbil); + } + } + } + + public long getStartTime() { + return startTime; + } + + public boolean isStarted() { + return started; + } + + public boolean isRemoved() { + return removed; + } + + public BendingPlayer getBendingPlayer() { + return bPlayer; + } + + public int getId() { + return id; + } + + public boolean isHiddenAbility() { + return false; + } + + @Override + public String getDescription() { + if (this instanceof SubAbility) { + return getConfig().getString("Abilities." + ((SubAbility) this).getParentElement().getName() + "." + getName() + ".Description"); + } + return getConfig().getString("Abilities." + getElement().getName() + "." + getName() + ".Description"); + } + + @Override + public Player getPlayer() { + return player; + } + + public static FileConfiguration getConfig() { + return ConfigManager.getConfig(); + } + + public static String getDebugString() { + StringBuilder sb = new StringBuilder(); + int playerCounter = 0; + HashMap classCounter = new HashMap<>(); + + for (ConcurrentHashMap> map1 : INSTANCES.values()) { + playerCounter++; + for (ConcurrentHashMap map2 : map1.values()) { + for (CoreAbility coreAbil : map2.values()) { + String simpleName = coreAbil.getClass().getSimpleName(); + + if (classCounter.containsKey(simpleName)) { + classCounter.put(simpleName, classCounter.get(simpleName) + 1); + } else { + classCounter.put(simpleName, 1); + } + } + } + } + + for (Set set : INSTANCES_BY_CLASS.values()) { + for (CoreAbility coreAbil : set) { + String simpleName = coreAbil.getClass().getSimpleName(); + if (classCounter.containsKey(simpleName)) { + classCounter.put(simpleName, classCounter.get(simpleName) + 1); + } else { + classCounter.put(simpleName, 1); + } + } + } + + sb.append("Class->UUID's in memory: " + playerCounter + "\n"); + sb.append("Abilities in memory\n"); + for (String className : classCounter.keySet()) { + sb.append(className + ": " + classCounter.get(className)); + } + return sb.toString(); + } +} diff --git a/src/com/projectkorra/projectkorra/ability/EarthAbility.java b/src/com/projectkorra/projectkorra/ability/EarthAbility.java new file mode 100644 index 00000000..d322e53f --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/EarthAbility.java @@ -0,0 +1,595 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.BendingPlayer; +import com.projectkorra.projectkorra.Element; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.configuration.ConfigManager; +import com.projectkorra.projectkorra.earthbending.EarthPassive; +import com.projectkorra.projectkorra.earthbending.LavaFlow; +import com.projectkorra.projectkorra.earthbending.RaiseEarth; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.Information; +import com.projectkorra.projectkorra.util.ParticleEffect; +import com.projectkorra.projectkorra.util.TempBlock; + +import org.bukkit.ChatColor; +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.concurrent.ConcurrentHashMap; + +public abstract class EarthAbility extends BlockAbility { + + private static final HashSet PREVENT_EARTHBENDING = new HashSet(); + private static final ConcurrentHashMap MOVED_EARTH = new ConcurrentHashMap(); + private static final ConcurrentHashMap TEMP_AIR_LOCATIONS = new ConcurrentHashMap(); + private static final ArrayList PREVENT_PHYSICS = new ArrayList(); + private static final ItemStack DIAMOND_PICKAXE = new ItemStack(Material.DIAMOND_PICKAXE); + + public EarthAbility(Player player) { + super(player); + } + + public int getEarthbendableBlocksLength(Block block, Vector direction, int maxlength) { + Location location = block.getLocation(); + direction = direction.normalize(); + for (int i = 0; i <= maxlength; i++) { + double j = i; + if (!isEarthbendable(location.clone().add(direction.clone().multiply(j)).getBlock())) { + return i; + } + } + return maxlength; + } + + public Block getEarthSourceBlock(double range) { + return getEarthSourceBlock(player, getName(), range); + } + + @Override + public Element getElement() { + return Element.EARTH; + } + + public Block getLavaSourceBlock(double range) { + return getLavaSourceBlock(player, getName(), range); + } + + public Block getTargetEarthBlock(int range) { + return getTargetEarthBlock(player, range); + } + + public boolean isEarthbendable(Block block) { + return isEarthbendable(player, getName(), block); + } + + @Override + public boolean isExplosiveAbility() { + return false; + } + + @Override + public boolean isIgniteAbility() { + return false; + } + + public boolean isMetalbendable(Block block) { + return isMetalbendable(block.getType()); + } + + public boolean isMetalbendable(Material material) { + return isMetalbendable(player, material); + } + + public void moveEarth(Block block, Vector direction, int chainlength) { + moveEarth(block, direction, chainlength, true); + } + + public boolean moveEarth(Block block, Vector direction, int chainlength, boolean throwplayer) { + if (isEarthbendable(block) && !GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + boolean up = false; + boolean down = false; + Vector norm = direction.clone().normalize(); + if (norm.dot(new Vector(0, 1, 0)) == 1) { + up = true; + } else if (norm.dot(new Vector(0, -1, 0)) == 1) { + down = true; + } + + Vector negnorm = norm.clone().multiply(-1); + Location location = block.getLocation(); + ArrayList blocks = new ArrayList(); + + for (double j = -2; j <= chainlength; j++) { + Block checkblock = location.clone().add(negnorm.clone().multiply(j)).getBlock(); + if (!PREVENT_PHYSICS.contains(checkblock)) { + blocks.add(checkblock); + PREVENT_PHYSICS.add(checkblock); + } + } + + Block affectedblock = location.clone().add(norm).getBlock(); + if (EarthPassive.isPassiveSand(block)) { + EarthPassive.revertSand(block); + } + + if (affectedblock == null) { + return false; + } else if (isTransparent(affectedblock)) { + if (throwplayer) { + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(affectedblock.getLocation(), 1.75)) { + if (entity instanceof LivingEntity) { + LivingEntity lentity = (LivingEntity) entity; + if (lentity.getEyeLocation().getBlockX() == affectedblock.getX() + && lentity.getEyeLocation().getBlockZ() == affectedblock.getZ()) { + if (!(entity instanceof FallingBlock)) { + entity.setVelocity(norm.clone().multiply(.75)); + } + } + } else { + if (entity.getLocation().getBlockX() == affectedblock.getX() + && entity.getLocation().getBlockZ() == affectedblock.getZ()) { + if (!(entity instanceof FallingBlock)) { + entity.setVelocity(norm.clone().multiply(.75)); + } + } + } + } + } + if (up) { + Block topblock = affectedblock.getRelative(BlockFace.UP); + if (topblock.getType() != Material.AIR) { + GeneralMethods.breakBlock(affectedblock); + } else if (!affectedblock.isLiquid() && affectedblock.getType() != Material.AIR) { + moveEarthBlock(affectedblock, topblock); + } + } else { + GeneralMethods.breakBlock(affectedblock); + } + + moveEarthBlock(block, affectedblock); + playEarthbendingSound(block.getLocation()); + + for (double i = 1; i < chainlength; i++) { + affectedblock = location.clone().add(negnorm.getX() * i, negnorm.getY() * i, negnorm.getZ() * i).getBlock(); + if (!isEarthbendable(affectedblock)) { + if (down) { + if (isTransparent(affectedblock) && !affectedblock.isLiquid() + && affectedblock.getType() != Material.AIR) { + moveEarthBlock(affectedblock, block); + } + } + break; + } + if (EarthPassive.isPassiveSand(affectedblock)) { + EarthPassive.revertSand(affectedblock); + } + if (block == null) { + for (Block checkblock : blocks) { + PREVENT_PHYSICS.remove(checkblock); + } + return false; + } + moveEarthBlock(affectedblock, block); + block = affectedblock; + } + + int i = chainlength; + affectedblock = location.clone().add(negnorm.getX() * i, negnorm.getY() * i, negnorm.getZ() * i).getBlock(); + if (!isEarthbendable(affectedblock)) { + if (down) { + if (isTransparent(affectedblock) && !affectedblock.isLiquid()) { + moveEarthBlock(affectedblock, block); + } + } + } + } else { + for (Block checkblock : blocks) { + PREVENT_PHYSICS.remove(checkblock); + } + return false; + } + for (Block checkblock : blocks) { + PREVENT_PHYSICS.remove(checkblock); + } + return true; + } + return false; + } + + public void moveEarth(Location location, Vector direction, int chainlength) { + moveEarth(location, direction, chainlength, true); + } + + public void moveEarth(Location location, Vector direction, int chainlength, boolean throwplayer) { + moveEarth(location.getBlock(), direction, chainlength, throwplayer); + } + + /** + * Creates a temporary air block. + * + * @param block The block to use as a base + */ + public static void addTempAirBlock(Block block) { + Information info; + if (MOVED_EARTH.containsKey(block)) { + info = MOVED_EARTH.get(block); + MOVED_EARTH.remove(block); + } else { + info = new Information(); + info.setBlock(block); + info.setState(block.getState()); + } + block.setType(Material.AIR); + info.setTime(System.currentTimeMillis()); + TEMP_AIR_LOCATIONS.put(info.getID(), info); + } + + public static void displaySandParticle(Location loc, float xOffset, float yOffset, float zOffset, float amount, float speed, boolean red) { + if (amount <= 0) + return; + + for (int x = 0; x < amount; x++) { + if (!red) { + ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.SAND, (byte) 0), new Vector(((Math.random() - 0.5) * xOffset), ((Math.random() - 0.5) * yOffset), ((Math.random() - 0.5) * zOffset)), speed, loc, 257.0D); + ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.SANDSTONE, (byte) 0), new Vector(((Math.random() - 0.5) * xOffset), ((Math.random() - 0.5) * yOffset), ((Math.random() - 0.5) * zOffset)), speed, loc, 257.0D); + } else if (red) { + ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.SAND, (byte) 1), new Vector(((Math.random() - 0.5) * xOffset), ((Math.random() - 0.5) * yOffset), ((Math.random() - 0.5) * zOffset)), speed, loc, 257.0D); + ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.RED_SANDSTONE, (byte) 0), new Vector(((Math.random() - 0.5) * xOffset), ((Math.random() - 0.5) * yOffset), ((Math.random() - 0.5) * zOffset)), speed, loc, 257.0D); + } + + } + } + + /** + * Finds a valid Earth source for a Player. To use dynamic source selection, use + * BlockSource.getEarthSourceBlock() instead of this method. Dynamic source selection saves the + * user's previous source for future use. + * {@link BlockSource#getEarthSourceBlock(Player, double, com.projectkorra.projectkorra.util.ClickType)} + * + * @param range the maximum block selection range. + * @return a valid Earth source block, or null if one could not be found. + */ + @SuppressWarnings("deprecation") + public static Block getEarthSourceBlock(Player player, String abilityName, double range) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + Block testblock = player.getTargetBlock(getTransparentMaterialSet(), (int) range); + if (bPlayer == null) { + return null; + } else if (isEarthbendable(player, testblock) || isMetalbendable(player, testblock.getType())) { + return testblock; + } + + Location location = player.getEyeLocation(); + Vector vector = location.getDirection().clone().normalize(); + + for (double i = 0; i <= range; i++) { + Block block = location.clone().add(vector.clone().multiply(i)).getBlock(); + if (GeneralMethods.isRegionProtectedFromBuild(player, abilityName, location)) { + continue; + } else if (isEarthbendable(player, block)) { + return block; + } + } + return null; + } + + public static Block getLavaSourceBlock(Player player, double range) { + return getLavaSourceBlock(player, null, range); + } + + /** + * Finds a valid Lava source for a Player. To use dynamic source selection, use + * BlockSource.getLavaSourceBlock() instead of this method. Dynamic source selection saves the + * user's previous source for future use. + * {@link BlockSource#getLavaSourceBlock(Player, double, com.projectkorra.projectkorra.util.ClickType)} + * + * @param range the maximum block selection range. + * @return a valid Lava source block, or null if one could not be found. + */ + @SuppressWarnings("deprecation") + public static Block getLavaSourceBlock(Player player, String abilityName, double range) { + Location location = player.getEyeLocation(); + Vector vector = location.getDirection().clone().normalize(); + + for (double i = 0; i <= range; i++) { + Block block = location.clone().add(vector.clone().multiply(i)).getBlock(); + if (GeneralMethods.isRegionProtectedFromBuild(player, abilityName, location)) { + continue; + } + if (isLavabendable(block)) { + if (TempBlock.isTempBlock(block)) { + TempBlock tb = TempBlock.get(block); + byte full = 0x0; + if (tb.getState().getRawData() != full && !isLava(tb.getState().getType())) { + continue; + } + } + return block; + } + } + return null; + } + + public static double getMetalAugment(double value) { + return value * getConfig().getDouble("Properties.Earth.MetalPowerFactor"); + } + + public static ConcurrentHashMap getMovedEarth() { + return MOVED_EARTH; + } + + /** + * Attempts to find the closest earth block near a given location. + * + * @param loc the initial location to search from. + * @param radius the maximum radius to search for the earth block. + * @param maxVertical the maximum block height difference between the starting location and the + * earth bendable block. + * @return an earth bendable block, or null. + */ + public static Block getNearbyEarthBlock(Location loc, double radius, int maxVertical) { + if (loc == null) { + return null; + } + + int rotation = 30; + for (int i = 0; i < radius; i++) { + Vector tracer = new Vector(i, 0, 0); + for (int deg = 0; deg < 360; deg += rotation) { + Location searchLoc = loc.clone().add(tracer); + Block block = GeneralMethods.getTopBlock(searchLoc, maxVertical); + + if (block != null && isEarthbendable(block.getType())) { + return block; + } + tracer = GeneralMethods.rotateXZ(tracer, rotation); + } + } + return null; + } + + public static HashSet getPreventEarthbendingBlocks() { + return PREVENT_EARTHBENDING; + } + + public static ArrayList getPreventPhysicsBlocks() { + return PREVENT_PHYSICS; + } + + public static ChatColor getSubChatColor() { + return ChatColor.valueOf(ConfigManager.getConfig().getString("Properties.Chat.Colors.EarthSub")); + } + + @SuppressWarnings("deprecation") + public static Block getTargetEarthBlock(Player player, int range) { + return player.getTargetBlock(getTransparentMaterialSet(), range); + } + + public static ConcurrentHashMap getTempAirLocations() { + return TEMP_AIR_LOCATIONS; + } + + public static boolean isEarthbendable(Material material) { + return getConfig().getStringList("Properties.Earth.EarthbendableBlocks").contains(material.toString()); + } + + public static boolean isEarthbendable(Player player, Block block) { + return isEarthbendable(player, null, block); + } + + public static boolean isEarthbendable(Player player, String abilityName, Block block) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null || !isEarthbendable(block.getType()) || PREVENT_EARTHBENDING.contains(block) + || GeneralMethods.isRegionProtectedFromBuild(player, abilityName, block.getLocation())) { + return false; + } else if (isMetal(block) && !bPlayer.canMetalbend()) { + return false; + } + return true; + } + + public static boolean isEarthRevertOn() { + return getConfig().getBoolean("Properties.Earth.RevertEarthbending"); + } + + @SuppressWarnings("deprecation") + public static boolean isLavabendable(Block block) { + byte full = 0x0; + if (TempBlock.isTempBlock(block)) { + TempBlock tblock = TempBlock.instances.get(block); + if (tblock == null || !LavaFlow.getTempLavaBlocks().contains(tblock)) { + return false; + } + } + if (isLava(block) && block.getData() == full) { + return true; + } + return false; + } + + public static boolean isMetalbendable(Player player, Material material) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + return bPlayer == null ? null : isMetal(material) && bPlayer.canMetalbend(); + } + + @SuppressWarnings("deprecation") + public static void moveEarthBlock(Block source, Block target) { + byte full = 0x0; + Information info; + + if (MOVED_EARTH.containsKey(source)) { + info = MOVED_EARTH.get(source); + MOVED_EARTH.remove(source); + } else { + info = new Information(); + info.setBlock(source); + info.setTime(System.currentTimeMillis()); + info.setState(source.getState()); + } + info.setTime(System.currentTimeMillis()); + MOVED_EARTH.put(target, info); + + if (GeneralMethods.isAdjacentToThreeOrMoreSources(source)) { + source.setType(Material.WATER); + source.setData(full); + } else { + source.setType(Material.AIR); + } + if (info.getState().getType() == Material.SAND) { + if (info.getState().getRawData() == (byte) 0x1) { + target.setType(Material.RED_SANDSTONE); + } else { + target.setType(Material.SANDSTONE); + } + } else { + target.setType(info.getState().getType()); + target.setData(info.getState().getRawData()); + } + } + + public static void playEarthbendingSound(Location loc) { + if (getConfig().getBoolean("Properties.Earth.PlaySound")) { + loc.getWorld().playEffect(loc, Effect.GHAST_SHOOT, 0, 10); + } + } + + public static void playMetalbendingSound(Location loc) { + if (getConfig().getBoolean("Properties.Earth.PlaySound")) { + loc.getWorld().playSound(loc, Sound.IRONGOLEM_HIT, 1, 10); + } + } + + public static void playSandBendingSound(Location loc) { + if (getConfig().getBoolean("Properties.Earth.PlaySound")) { + loc.getWorld().playSound(loc, Sound.DIG_SAND, 1.5f, 5); + } + } + + public static void removeAllEarthbendedBlocks() { + for (Block block : MOVED_EARTH.keySet()) { + revertBlock(block); + } + for (Integer i : TEMP_AIR_LOCATIONS.keySet()) { + revertAirBlock(i, true); + } + } + + public static void removeRevertIndex(Block block) { + if (MOVED_EARTH.containsKey(block)) { + Information info = MOVED_EARTH.get(block); + if (block.getType() == Material.SANDSTONE && info.getType() == Material.SAND) { + block.setType(Material.SAND); + } + if (RaiseEarth.blockInAllAffectedBlocks(block)) { + EarthAbility.revertBlock(block); + } + + MOVED_EARTH.remove(block); + } + } + + public static void revertAirBlock(int i) { + revertAirBlock(i, false); + } + + public static void revertAirBlock(int i, boolean force) { + if (!TEMP_AIR_LOCATIONS.containsKey(i)) { + return; + } + + Information info = TEMP_AIR_LOCATIONS.get(i); + Block block = info.getState().getBlock(); + + if (block.getType() != Material.AIR && !block.isLiquid()) { + if (force || !MOVED_EARTH.containsKey(block)) { + TEMP_AIR_LOCATIONS.remove(i); + } else { + info.setTime(info.getTime() + 10000); + } + return; + } else { + info.getState().update(true); + TEMP_AIR_LOCATIONS.remove(i); + } + } + + @SuppressWarnings("deprecation") + public static boolean revertBlock(Block block) { + byte full = 0x0; + if (!isEarthRevertOn()) { + MOVED_EARTH.remove(block); + return false; + } + if (MOVED_EARTH.containsKey(block)) { + Information info = MOVED_EARTH.get(block); + Block sourceblock = info.getState().getBlock(); + + if (info.getState().getType() == Material.AIR) { + MOVED_EARTH.remove(block); + return true; + } + + if (block.equals(sourceblock)) { + info.getState().update(true); + if (RaiseEarth.blockInAllAffectedBlocks(sourceblock)) { + EarthAbility.revertBlock(sourceblock); + } + if (RaiseEarth.blockInAllAffectedBlocks(block)) { + EarthAbility.revertBlock(block); + } + MOVED_EARTH.remove(block); + return true; + } + + if (MOVED_EARTH.containsKey(sourceblock)) { + addTempAirBlock(block); + MOVED_EARTH.remove(block); + return true; + } + + if (sourceblock.getType() == Material.AIR || sourceblock.isLiquid()) { + info.getState().update(true); + } else { + GeneralMethods.dropItems(block, + GeneralMethods.getDrops(block, info.getState().getType(), info.getState().getRawData(), DIAMOND_PICKAXE)); + } + + if (GeneralMethods.isAdjacentToThreeOrMoreSources(block)) { + block.setType(Material.WATER); + block.setData(full); + } else { + block.setType(Material.AIR); + } + + if (RaiseEarth.blockInAllAffectedBlocks(sourceblock)) { + EarthAbility.revertBlock(sourceblock); + } + if (RaiseEarth.blockInAllAffectedBlocks(block)) { + EarthAbility.revertBlock(block); + } + MOVED_EARTH.remove(block); + } + return true; + } + + public static void stopBending() { + EarthPassive.removeAll(); + + if (isEarthRevertOn()) { + removeAllEarthbendedBlocks(); + } + } +} diff --git a/src/com/projectkorra/projectkorra/ability/ElementalAbility.java b/src/com/projectkorra/projectkorra/ability/ElementalAbility.java new file mode 100644 index 00000000..f420a104 --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/ElementalAbility.java @@ -0,0 +1,205 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.rpg.event.EventManager; + +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.World.Environment; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffectType; + +import java.util.Arrays; +import java.util.HashSet; + +// Contains methods that all 5 elements should be capable of accessing +public abstract class ElementalAbility extends CoreAbility { + + private static final Integer[] TRANSPARENT_MATERIAL = { 0, 6, 8, 9, 10, 11, 30, 31, 32, 37, 38, 39, 40, 50, 51, 59, 78, 83, 106, 175 }; + private static final Integer[] PLANT_IDS = { 6, 18, 31, 37, 38, 39, 40, 59, 81, 83, 86, 99, 100, 103, 104, 105, 106, 111, 161, 175 }; + private static final PotionEffectType[] POSITIVE_EFFECTS = {PotionEffectType.ABSORPTION, PotionEffectType.DAMAGE_RESISTANCE, PotionEffectType.FAST_DIGGING, + PotionEffectType.FIRE_RESISTANCE, PotionEffectType.HEAL, PotionEffectType.HEALTH_BOOST, PotionEffectType.INCREASE_DAMAGE, PotionEffectType.JUMP, + PotionEffectType.NIGHT_VISION, PotionEffectType.REGENERATION, PotionEffectType.SATURATION, PotionEffectType.SPEED, PotionEffectType.WATER_BREATHING}; + private static final PotionEffectType[] NEUTRAL_EFFECTS = {PotionEffectType.INVISIBILITY}; + private static final PotionEffectType[] NEGATIVE_EFFECTS = {PotionEffectType.POISON, PotionEffectType.BLINDNESS, PotionEffectType.CONFUSION, + PotionEffectType.HARM, PotionEffectType.HUNGER, PotionEffectType.SLOW, PotionEffectType.SLOW_DIGGING, PotionEffectType.WEAKNESS, PotionEffectType.WITHER}; + + public ElementalAbility(Player player) { + super(player); + } + + public boolean isTransparent(Block block) { + return isTransparent(player, getName(), block); + } + + public static Integer[] getTransparentMaterial() { + return TRANSPARENT_MATERIAL; + } + + public static HashSet getTransparentMaterialSet() { + HashSet set = new HashSet(); + for (int i : TRANSPARENT_MATERIAL) { + set.add((byte) i); + } + return set; + } + + public static boolean isDay(World world) { + long time = world.getTime(); + if (world.getEnvironment() == Environment.NETHER || world.getEnvironment() == Environment.THE_END) { + return true; + } + if (time >= 23500 || time <= 12500) { + return true; + } + return false; + } + + public static boolean isFullMoon(World world) { + if (GeneralMethods.hasRPG()) { + return EventManager.marker.get(world).equalsIgnoreCase("FullMoon"); + } else { + long days = world.getFullTime() / 24000; + long phase = days % 8; + if (phase == 0) { + return true; + } + return false; + } + } + + public static boolean isIce(Block block) { + return isIce(block.getType()); + } + + public static boolean isIce(Material material) { + return material == Material.ICE || material == Material.PACKED_ICE; + } + + public static boolean isLava(Block block) { + return block != null ? isLava(block.getType()) : false; + } + + public static boolean isLava(Material material) { + return material == Material.LAVA || material == Material.STATIONARY_LAVA; + } + + public static boolean isLunarEclipse(World world) { + if (world == null) { + return false; + } + return EventManager.marker.get(world).equalsIgnoreCase("SolarEclipse"); + } + + public static boolean isMeltable(Block block) { + if (block.getType() == Material.ICE || block.getType() == Material.SNOW) { + return true; + } + return false; + } + + public static boolean isMetal(Block block) { + return block != null ? isMetal(block.getType()) : false; + } + + public static boolean isMetal(Material material) { + return getConfig().getStringList("Properties.Earth.MetalBlocks").contains(material.toString()); + } + + public static boolean isMetalBlock(Block block) { + if (block.getType() == Material.GOLD_BLOCK || block.getType() == Material.IRON_BLOCK + || block.getType() == Material.IRON_ORE || block.getType() == Material.GOLD_ORE + || block.getType() == Material.QUARTZ_BLOCK || block.getType() == Material.QUARTZ_ORE) { + return true; + } + return false; + } + + public static boolean isNegativeEffect(PotionEffectType effect) { + for (PotionEffectType effect2 : NEGATIVE_EFFECTS) { + if (effect2.equals(effect)) { + return true; + } + } + return false; + } + + public static boolean isNeutralEffect(PotionEffectType effect) { + for (PotionEffectType effect2 : NEUTRAL_EFFECTS) { + if (effect2.equals(effect)) { + return true; + } + } + return false; + } + + public static boolean isNight(World world) { + if (world.getEnvironment() == Environment.NETHER || world.getEnvironment() == Environment.THE_END) { + return false; + } + + long time = world.getTime(); + if (time >= 12950 && time <= 23050) { + return true; + } + return false; + } + + @SuppressWarnings("deprecation") + public static boolean isPlant(Block block) { + if (block == null) { + return false; + } else if (Arrays.asList(PLANT_IDS).contains(block.getTypeId())) { + return true; + } + return false; + } + + public static boolean isPositiveEffect(PotionEffectType effect) { + for (PotionEffectType effect2 : POSITIVE_EFFECTS) { + if (effect2.equals(effect)) { + return true; + } + } + return false; + } + + public static boolean isSozinsComet(World world) { + return world != null ? EventManager.marker.get(world).equalsIgnoreCase("SozinsComet") : false; + } + + @SuppressWarnings("deprecation") + public static boolean isTransparent(Player player, String abilityName, Block block) { + return Arrays.asList(TRANSPARENT_MATERIAL).contains(block.getTypeId()) + && !GeneralMethods.isRegionProtectedFromBuild(player, abilityName, block.getLocation()); + } + + public static boolean isTransparentToEarthbending(Player player, Block block) { + return isTransparent(player, null, block); + } + + public static boolean isUndead(Entity entity) { + if (entity == null) { + return false; + } else if (entity.getType() == EntityType.ZOMBIE || entity.getType() == EntityType.BLAZE + || entity.getType() == EntityType.GIANT || entity.getType() == EntityType.IRON_GOLEM + || entity.getType() == EntityType.MAGMA_CUBE || entity.getType() == EntityType.PIG_ZOMBIE + || entity.getType() == EntityType.SKELETON || entity.getType() == EntityType.SLIME + || entity.getType() == EntityType.SNOWMAN || entity.getType() == EntityType.ZOMBIE) { + return true; + } + return false; + } + + public static boolean isWater(Block block) { + return block != null ? isWater(block.getType()) : null; + } + + public static boolean isWater(Material material) { + return material == Material.WATER || material == Material.STATIONARY_WATER; + } + +} diff --git a/src/com/projectkorra/projectkorra/firebending/FireMethods.java b/src/com/projectkorra/projectkorra/ability/FireAbility.java similarity index 53% rename from src/com/projectkorra/projectkorra/firebending/FireMethods.java rename to src/com/projectkorra/projectkorra/ability/FireAbility.java index 1ace760e..00c382eb 100644 --- a/src/com/projectkorra/projectkorra/firebending/FireMethods.java +++ b/src/com/projectkorra/projectkorra/ability/FireAbility.java @@ -1,242 +1,224 @@ -package com.projectkorra.projectkorra.firebending; - -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AbilityModuleManager; -import com.projectkorra.projectkorra.util.Information; -import com.projectkorra.projectkorra.util.ParticleEffect; -import com.projectkorra.rpg.RPGMethods; -import com.projectkorra.rpg.event.EventManager; - -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.World; -import org.bukkit.World.Environment; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -public class FireMethods { - - static ProjectKorra plugin; - private static FileConfiguration config = ProjectKorra.plugin.getConfig(); - - public static ConcurrentHashMap tempFire = new ConcurrentHashMap(); - - public FireMethods(ProjectKorra plugin) { - FireMethods.plugin = plugin; - } - - public static boolean canCombustionbend(Player player) { - if (player.hasPermission("bending.fire.combustionbending")) - return true; - return false; - } - - public static boolean canLightningbend(Player player) { - if (player.hasPermission("bending.fire.lightningbending")) - return true; - return false; - } - - /** - * Returns if fire is allowed to completely replace blocks or if it should place a temp fire - * block. - */ - public static boolean canFireGrief() { - return config.getBoolean("Properties.Fire.FireGriefing"); - } - - /** - * Creates a fire block meant to replace other blocks but reverts when the fire dissipates or is - * destroyed. - */ - public static void createTempFire(Location loc) { - if (loc.getBlock().getType() == Material.AIR) { - loc.getBlock().setType(Material.FIRE); - return; - } - Information info = new Information(); - long time = config.getLong("Properties.Fire.RevertTicks") - + (long) (GeneralMethods.rand.nextDouble() * config.getLong("Properties.Fire.RevertTicks")); - if (tempFire.containsKey(loc)) { - info = tempFire.get(loc); - } else { - info.setBlock(loc.getBlock()); - info.setLocation(loc); - info.setState(loc.getBlock().getState()); - } - info.setTime(time + System.currentTimeMillis()); - loc.getBlock().setType(Material.FIRE); - tempFire.put(loc, info); - } - - /** - * Gets the firebending dayfactor from the config multiplied by a specific value if it is day. - * - * @param value The value - * @param world The world to pass into {@link #isDay(World)} - * @return value DayFactor multiplied by specified value when {@link #isDay(World)} is true
- * else
- * value The specified value in the parameters - */ - public static double getFirebendingDayAugment(double value, World world) { - if (isDay(world)) { - if (GeneralMethods.hasRPG()) { - if (EventManager.marker.get(world).equalsIgnoreCase("SozinsComet")) { - return RPGMethods.getFactor("SozinsComet") * value; - } else if (EventManager.marker.get(world).equalsIgnoreCase("SolarEclipse")) { - return RPGMethods.getFactor("SolarEclipse") * value; - } else { - return value * config.getDouble("Properties.Fire.DayFactor"); - } - } else { - return value * config.getDouble("Properties.Fire.DayFactor"); - } - } - return value; - } - - /** - * Gets the FireColor from the config. - * - * @return Config specified ChatColor - */ - public static ChatColor getFireColor() { - return ChatColor.valueOf(config.getString("Properties.Chat.Colors.Fire")); - } - - /** - * Gets the FireSubColor from the config. - * - * @return Config specified ChatColor - */ - public static ChatColor getFireSubColor() { - return ChatColor.valueOf(config.getString("Properties.Chat.Colors.FireSub")); - } - - public static boolean isCombustionbendingAbility(String ability) { - return AbilityModuleManager.combustionabilities.contains(ability); - } - - public static boolean isLightningbendingAbility(String ability) { - return AbilityModuleManager.lightningabilities.contains(ability); - } - - public static boolean isDay(World world) { - long time = world.getTime(); - if (world.getEnvironment() == Environment.NETHER || world.getEnvironment() == Environment.THE_END) - return true; - if (time >= 23500 || time <= 12500) { - return true; - } - return false; - } - - public static boolean isFireAbility(String ability) { - return AbilityModuleManager.firebendingabilities.contains(ability); - } - - public static void playLightningbendingParticle(Location loc) { - playLightningbendingParticle(loc, (float) Math.random(), (float) Math.random(), (float) Math.random()); - } - - public static void playLightningbendingParticle(Location loc, float xOffset, float yOffset, float zOffset) { - loc.setX(loc.getX() + Math.random() * (xOffset / 2 - -(xOffset / 2))); - loc.setY(loc.getY() + Math.random() * (yOffset / 2 - -(yOffset / 2))); - loc.setZ(loc.getZ() + Math.random() * (zOffset / 2 - -(zOffset / 2))); - GeneralMethods.displayColoredParticle(loc, "#01E1FF"); - } - - public static void playFirebendingParticles(Location loc, int amount, float xOffset, float yOffset, float zOffset) { - ParticleEffect.FLAME.display(loc, xOffset, yOffset, zOffset, 0, amount); - } - - public static void playFirebendingSound(Location loc) { - if (plugin.getConfig().getBoolean("Properties.Fire.PlaySound")) { - loc.getWorld().playSound(loc, Sound.FIRE, 1, 10); - } - } - - public static void playCombustionSound(Location loc) { - if (plugin.getConfig().getBoolean("Properties.Fire.PlaySound")) { - loc.getWorld().playSound(loc, Sound.FIREWORK_BLAST, 1, -1); - } - } - - /** - * Checks whether a location is within a FireShield. - * - * @param loc The location to check - * @return true If the location is inside a FireShield. - */ - public static boolean isWithinFireShield(Location loc) { - List list = new ArrayList(); - list.add("FireShield"); - return GeneralMethods.blockAbilities(null, list, loc, 0); - } - - /** Removes all temp fire that no longer needs to be there */ - public static void removeFire() { - Iterator it = tempFire.keySet().iterator(); - while (it.hasNext()) { - Location loc = it.next(); - Information info = tempFire.get(loc); - if (info.getLocation().getBlock().getType() != Material.FIRE - && info.getLocation().getBlock().getType() != Material.AIR) { - revertTempFire(loc); - } else if (info.getBlock().getType() == Material.AIR || System.currentTimeMillis() > info.getTime()) { - revertTempFire(loc); - } - } - } - - /** - * Revert the temp fire at the location if any is there. - * - * @param location The Location - * */ - @SuppressWarnings("deprecation") - public static void revertTempFire(Location location) { - if (!tempFire.containsKey(location)) - return; - Information info = tempFire.get(location); - if (info.getLocation().getBlock().getType() != Material.FIRE && info.getLocation().getBlock().getType() != Material.AIR) { - if (info.getState().getType() == Material.RED_ROSE || info.getState().getType() == Material.YELLOW_FLOWER) { - info.getState() - .getBlock() - .getWorld() - .dropItemNaturally(info.getLocation(), - new ItemStack(info.getState().getData().getItemType(), 1, info.getState().getRawData())); - } - } else { - info.getBlock().setType(info.getState().getType()); - info.getBlock().setData(info.getState().getRawData()); - } - tempFire.remove(location); - } - - public static void stopBending() { - FireStream.removeAll(); - Fireball.removeAll(); - WallOfFire.removeAll(); - Lightning.removeAll(); - FireShield.removeAll(); - FireBlast.removeAll(); - FireBurst.removeAll(); - FireJet.removeAll(); - Cook.removeAll(); - Illumination.removeAll(); - FireCombo.removeAll(); - for (Location loc : tempFire.keySet()) { - revertTempFire(loc); - } - } -} +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.configuration.ConfigManager; +import com.projectkorra.projectkorra.firebending.BlazeArc; +import com.projectkorra.projectkorra.util.Information; +import com.projectkorra.projectkorra.util.ParticleEffect; +import com.projectkorra.rpg.RPGMethods; + +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; + +public abstract class FireAbility extends ElementalAbility { + + private static final ConcurrentHashMap TEMP_FIRE = new ConcurrentHashMap(); + private static final Material[] IGNITABLE_MATERIALS = { Material.BEDROCK, Material.BOOKSHELF, Material.BRICK, Material.CLAY, Material.CLAY_BRICK, + Material.COAL_ORE, Material.COBBLESTONE, Material.DIAMOND_ORE, Material.DIAMOND_BLOCK, Material.DIRT, + Material.ENDER_STONE, Material.GLOWING_REDSTONE_ORE, Material.GOLD_BLOCK, Material.GRAVEL, Material.GRASS, + Material.HUGE_MUSHROOM_1, Material.HUGE_MUSHROOM_2, Material.LAPIS_BLOCK, Material.LAPIS_ORE, Material.LOG, + Material.MOSSY_COBBLESTONE, Material.MYCEL, Material.NETHER_BRICK, Material.NETHERRACK, Material.OBSIDIAN, + Material.REDSTONE_ORE, Material.SAND, Material.SANDSTONE, Material.SMOOTH_BRICK, Material.STONE, Material.SOUL_SAND, + Material.WOOD, Material.WOOL, Material.LEAVES, Material.LEAVES_2, Material.MELON_BLOCK, Material.PUMPKIN, + Material.JACK_O_LANTERN, Material.NOTE_BLOCK, Material.GLOWSTONE, Material.IRON_BLOCK, Material.DISPENSER, + Material.SPONGE, Material.IRON_ORE, Material.GOLD_ORE, Material.COAL_BLOCK, Material.WORKBENCH, + Material.HAY_BLOCK, Material.REDSTONE_LAMP_OFF, Material.REDSTONE_LAMP_ON, Material.EMERALD_ORE, + Material.EMERALD_BLOCK, Material.REDSTONE_BLOCK, Material.QUARTZ_BLOCK, Material.QUARTZ_ORE, + Material.STAINED_CLAY, Material.HARD_CLAY }; + + public FireAbility(Player player) { + super(player); + } + + @Override + public boolean isIgniteAbility() { + return true; + } + + @Override + public boolean isExplosiveAbility() { + return true; + } + + @Override + public Element getElement() { + return Element.FIRE; + } + + public double getDayFactor(double value) { + return player != null ? getDayFactor(value, player.getWorld()) : 1; + } + + /** + * Returns if fire is allowed to completely replace blocks or if it should place a temp fire + * block. + */ + public static boolean canFireGrief() { + return getConfig().getBoolean("Properties.Fire.FireGriefing"); + } + + /** + * Creates a fire block meant to replace other blocks but reverts when the fire dissipates or is + * destroyed. + */ + public static void createTempFire(Location loc) { + if (loc.getBlock().getType() == Material.AIR) { + loc.getBlock().setType(Material.FIRE); + return; + } + Information info = new Information(); + long time = getConfig().getLong("Properties.Fire.RevertTicks") + + (long) ((new Random()).nextDouble() * getConfig().getLong("Properties.Fire.RevertTicks")); + if (TEMP_FIRE.containsKey(loc)) { + info = TEMP_FIRE.get(loc); + } else { + info.setBlock(loc.getBlock()); + info.setLocation(loc); + info.setState(loc.getBlock().getState()); + } + info.setTime(time + System.currentTimeMillis()); + loc.getBlock().setType(Material.FIRE); + TEMP_FIRE.put(loc, info); + } + + public static double getDayFactor() { + return getConfig().getDouble("Properties.Fire.DayFactor"); + } + + /** + * Gets the firebending dayfactor from the config multiplied by a specific value if it is day. + * + * @param value The value + * @param world The world to pass into {@link #isDay(World)} + * @return value DayFactor multiplied by specified value when {@link #isDay(World)} is true
+ * else
+ * value The specified value in the parameters + */ + public static double getDayFactor(double value, World world) { + if (isDay(world)) { + if (GeneralMethods.hasRPG()) { + if (isSozinsComet(world)) { + return RPGMethods.getFactor("SozinsComet") * value; + } else if (isLunarEclipse(world)) { + return RPGMethods.getFactor("SolarEclipse") * value; + } else { + return value * getDayFactor(); + } + } else { + return value * getDayFactor(); + } + } + return value; + } + + public static ChatColor getSubChatColor() { + return ChatColor.valueOf(ConfigManager.getConfig().getString("Properties.Chat.Colors.FireSub")); + } + + public static boolean isIgnitable(Block block) { + return block != null ? isIgnitable(block.getType()) : false; + } + + public static boolean isIgnitable(Material material) { + return Arrays.asList(IGNITABLE_MATERIALS).contains(material); + } + + /** + * Checks whether a location is within a FireShield. + * + * @param loc The location to check + * @return true If the location is inside a FireShield. + */ + public static boolean isWithinFireShield(Location loc) { + List list = new ArrayList(); + list.add("FireShield"); + return GeneralMethods.blockAbilities(null, list, loc, 0); + } + + public static void playCombustionSound(Location loc) { + if (getConfig().getBoolean("Properties.Fire.PlaySound")) { + loc.getWorld().playSound(loc, Sound.FIREWORK_BLAST, 1, -1); + } + } + + public static void playFirebendingParticles(Location loc, int amount, float xOffset, float yOffset, float zOffset) { + ParticleEffect.FLAME.display(loc, xOffset, yOffset, zOffset, 0, amount); + } + + public static void playFirebendingSound(Location loc) { + if (getConfig().getBoolean("Properties.Fire.PlaySound")) { + loc.getWorld().playSound(loc, Sound.FIRE, 1, 10); + } + } + + public static void playLightningbendingParticle(Location loc) { + playLightningbendingParticle(loc, (float) Math.random(), (float) Math.random(), (float) Math.random()); + } + + public static void playLightningbendingParticle(Location loc, float xOffset, float yOffset, float zOffset) { + loc.setX(loc.getX() + Math.random() * (xOffset / 2 - -(xOffset / 2))); + loc.setY(loc.getY() + Math.random() * (yOffset / 2 - -(yOffset / 2))); + loc.setZ(loc.getZ() + Math.random() * (zOffset / 2 - -(zOffset / 2))); + GeneralMethods.displayColoredParticle(loc, "#01E1FF"); + } + + /** Removes all temp fire that no longer needs to be there */ + public static void removeFire() { + Iterator it = TEMP_FIRE.keySet().iterator(); + while (it.hasNext()) { + Location loc = it.next(); + Information info = TEMP_FIRE.get(loc); + if (info.getLocation().getBlock().getType() != Material.FIRE + && info.getLocation().getBlock().getType() != Material.AIR) { + revertTempFire(loc); + } else if (info.getBlock().getType() == Material.AIR || System.currentTimeMillis() > info.getTime()) { + revertTempFire(loc); + } + } + } + + /** + * Revert the temp fire at the location if any is there. + * + * @param location The Location + * */ + @SuppressWarnings("deprecation") + public static void revertTempFire(Location location) { + if (!TEMP_FIRE.containsKey(location)) { + return; + } + Information info = TEMP_FIRE.get(location); + if (info.getLocation().getBlock().getType() != Material.FIRE && info.getLocation().getBlock().getType() != Material.AIR) { + if (info.getState().getType() == Material.RED_ROSE || info.getState().getType() == Material.YELLOW_FLOWER) { + ItemStack itemStack = new ItemStack(info.getState().getData().getItemType(), 1, info.getState().getRawData()); + info.getState().getBlock().getWorld().dropItemNaturally(info.getLocation(), itemStack); + } + } else { + info.getBlock().setType(info.getState().getType()); + info.getBlock().setData(info.getState().getRawData()); + } + TEMP_FIRE.remove(location); + } + + public static void stopBending() { + BlazeArc.removeAllCleanup(); + for (Location loc : TEMP_FIRE.keySet()) { + revertTempFire(loc); + } + } + +} diff --git a/src/com/projectkorra/projectkorra/ability/api/FlightAbility.java b/src/com/projectkorra/projectkorra/ability/FlightAbility.java similarity index 53% rename from src/com/projectkorra/projectkorra/ability/api/FlightAbility.java rename to src/com/projectkorra/projectkorra/ability/FlightAbility.java index b7b2eede..48767f38 100644 --- a/src/com/projectkorra/projectkorra/ability/api/FlightAbility.java +++ b/src/com/projectkorra/projectkorra/ability/FlightAbility.java @@ -1,13 +1,11 @@ -package com.projectkorra.projectkorra.ability.api; +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; import org.bukkit.entity.Player; public abstract class FlightAbility extends AirAbility implements SubAbility { - public FlightAbility(Player player, boolean autoStart) { - super(player, autoStart); - } - public FlightAbility(Player player) { super(player); } @@ -16,4 +14,14 @@ public abstract class FlightAbility extends AirAbility implements SubAbility { public Class getParentAbility() { return AirAbility.class; } + + @Override + public Element getElement() { + return Element.FLIGHT; + } + + @Override + public Element getParentElement() { + return Element.AIR; + } } diff --git a/src/com/projectkorra/projectkorra/ability/api/HealingAbility.java b/src/com/projectkorra/projectkorra/ability/HealingAbility.java similarity index 53% rename from src/com/projectkorra/projectkorra/ability/api/HealingAbility.java rename to src/com/projectkorra/projectkorra/ability/HealingAbility.java index dff4ce98..a273cc79 100644 --- a/src/com/projectkorra/projectkorra/ability/api/HealingAbility.java +++ b/src/com/projectkorra/projectkorra/ability/HealingAbility.java @@ -1,13 +1,11 @@ -package com.projectkorra.projectkorra.ability.api; +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; import org.bukkit.entity.Player; public abstract class HealingAbility extends WaterAbility implements SubAbility { - - public HealingAbility(Player player, boolean autoStart) { - super(player, autoStart); - } - + public HealingAbility(Player player) { super(player); } @@ -16,4 +14,14 @@ public abstract class HealingAbility extends WaterAbility implements SubAbility public Class getParentAbility() { return WaterAbility.class; } + + @Override + public Element getElement() { + return Element.HEALING; + } + + @Override + public Element getParentElement() { + return Element.WATER; + } } diff --git a/src/com/projectkorra/projectkorra/ability/IceAbility.java b/src/com/projectkorra/projectkorra/ability/IceAbility.java new file mode 100644 index 00000000..06645e3f --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/IceAbility.java @@ -0,0 +1,27 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; + +import org.bukkit.entity.Player; + +public abstract class IceAbility extends WaterAbility implements SubAbility { + + public IceAbility(Player player) { + super(player); + } + + @Override + public Class getParentAbility() { + return WaterAbility.class; + } + + @Override + public Element getElement() { + return Element.ICE; + } + + @Override + public Element getParentElement() { + return Element.WATER; + } +} diff --git a/src/com/projectkorra/projectkorra/ability/api/LavaAbility.java b/src/com/projectkorra/projectkorra/ability/LavaAbility.java similarity index 53% rename from src/com/projectkorra/projectkorra/ability/api/LavaAbility.java rename to src/com/projectkorra/projectkorra/ability/LavaAbility.java index c02e1c47..6567493c 100644 --- a/src/com/projectkorra/projectkorra/ability/api/LavaAbility.java +++ b/src/com/projectkorra/projectkorra/ability/LavaAbility.java @@ -1,13 +1,11 @@ -package com.projectkorra.projectkorra.ability.api; +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; import org.bukkit.entity.Player; public abstract class LavaAbility extends EarthAbility implements SubAbility { - - public LavaAbility(Player player, boolean autoStart) { - super(player, autoStart); - } - + public LavaAbility(Player player) { super(player); } @@ -17,4 +15,14 @@ public abstract class LavaAbility extends EarthAbility implements SubAbility { return EarthAbility.class; } + @Override + public Element getElement() { + return Element.LAVA; + } + + @Override + public Element getParentElement() { + return Element.EARTH; + } + } diff --git a/src/com/projectkorra/projectkorra/ability/api/LightningAbility.java b/src/com/projectkorra/projectkorra/ability/LightningAbility.java similarity index 54% rename from src/com/projectkorra/projectkorra/ability/api/LightningAbility.java rename to src/com/projectkorra/projectkorra/ability/LightningAbility.java index 7fdcaad8..ca4250ab 100644 --- a/src/com/projectkorra/projectkorra/ability/api/LightningAbility.java +++ b/src/com/projectkorra/projectkorra/ability/LightningAbility.java @@ -1,13 +1,11 @@ -package com.projectkorra.projectkorra.ability.api; +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; import org.bukkit.entity.Player; public abstract class LightningAbility extends FireAbility implements SubAbility { - public LightningAbility(Player player, boolean autoStart) { - super(player, autoStart); - } - public LightningAbility(Player player) { super(player); } @@ -16,4 +14,14 @@ public abstract class LightningAbility extends FireAbility implements SubAbility public Class getParentAbility() { return FireAbility.class; } + + @Override + public Element getElement() { + return Element.LIGHTNING; + } + + @Override + public Element getParentElement() { + return Element.FIRE; + } } diff --git a/src/com/projectkorra/projectkorra/ability/api/MetalAbility.java b/src/com/projectkorra/projectkorra/ability/MetalAbility.java similarity index 50% rename from src/com/projectkorra/projectkorra/ability/api/MetalAbility.java rename to src/com/projectkorra/projectkorra/ability/MetalAbility.java index bc32e113..16d26bf4 100644 --- a/src/com/projectkorra/projectkorra/ability/api/MetalAbility.java +++ b/src/com/projectkorra/projectkorra/ability/MetalAbility.java @@ -1,19 +1,27 @@ -package com.projectkorra.projectkorra.ability.api; +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; import org.bukkit.entity.Player; public abstract class MetalAbility extends EarthAbility implements SubAbility { - public MetalAbility(Player player, boolean autoStart) { - super(player, autoStart); - } - public MetalAbility(Player player) { - super(player, false); + super(player); } + @Override public Class getParentAbility() { return EarthAbility.class; } + + @Override + public Element getElement() { + return Element.METAL; + } + @Override + public Element getParentElement() { + return Element.EARTH; + } } diff --git a/src/com/projectkorra/projectkorra/ability/MultiAbility.java b/src/com/projectkorra/projectkorra/ability/MultiAbility.java new file mode 100644 index 00000000..67a6459a --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/MultiAbility.java @@ -0,0 +1,17 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.ability.util.MultiAbilityManager.MultiAbilityInfoSub; + +import java.util.ArrayList; + +public interface MultiAbility { + + /** + * Returns the sub abilities of a MultiAbility. e.g. {@code new + * MultiAbilitySub("SubAbility", Element.Fire, SubElement.Lightning);} + * + * @return arraylist of multiabilitysub + */ + public abstract ArrayList getMultiAbilities(); + +} diff --git a/src/com/projectkorra/projectkorra/ability/PlantAbility.java b/src/com/projectkorra/projectkorra/ability/PlantAbility.java new file mode 100644 index 00000000..ecd73ace --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/PlantAbility.java @@ -0,0 +1,27 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; + +import org.bukkit.entity.Player; + +public abstract class PlantAbility extends WaterAbility implements SubAbility { + + public PlantAbility(Player player) { + super(player); + } + + @Override + public Class getParentAbility() { + return WaterAbility.class; + } + + @Override + public Element getElement() { + return Element.PLANT; + } + + @Override + public Element getParentElement() { + return Element.WATER; + } +} diff --git a/src/com/projectkorra/projectkorra/ability/api/SandAbility.java b/src/com/projectkorra/projectkorra/ability/SandAbility.java similarity index 50% rename from src/com/projectkorra/projectkorra/ability/api/SandAbility.java rename to src/com/projectkorra/projectkorra/ability/SandAbility.java index ed90cb4d..8fcbe643 100644 --- a/src/com/projectkorra/projectkorra/ability/api/SandAbility.java +++ b/src/com/projectkorra/projectkorra/ability/SandAbility.java @@ -1,15 +1,13 @@ -package com.projectkorra.projectkorra.ability.api; +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; import org.bukkit.entity.Player; public abstract class SandAbility extends EarthAbility implements SubAbility { - - public SandAbility(Player player, boolean autoStart) { - super(player, autoStart); - } - + public SandAbility(Player player) { - super(player, false); + super(player); } @Override @@ -17,4 +15,14 @@ public abstract class SandAbility extends EarthAbility implements SubAbility { return EarthAbility.class; } + @Override + public Element getElement() { + return Element.SAND; + } + + @Override + public Element getParentElement() { + return Element.EARTH; + } + } diff --git a/src/com/projectkorra/projectkorra/ability/SpiritualAbility.java b/src/com/projectkorra/projectkorra/ability/SpiritualAbility.java new file mode 100644 index 00000000..8a6f409f --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/SpiritualAbility.java @@ -0,0 +1,27 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; + +import org.bukkit.entity.Player; + +public abstract class SpiritualAbility extends AirAbility implements SubAbility { + + public SpiritualAbility(Player player) { + super(player); + } + + @Override + public Class getParentAbility() { + return AirAbility.class; + } + + @Override + public Element getElement() { + return Element.SPIRITUAL; + } + + @Override + public Element getParentElement() { + return Element.WATER; + } +} diff --git a/src/com/projectkorra/projectkorra/ability/StockAbility.java b/src/com/projectkorra/projectkorra/ability/StockAbility.java deleted file mode 100644 index 5dfc84c9..00000000 --- a/src/com/projectkorra/projectkorra/ability/StockAbility.java +++ /dev/null @@ -1,240 +0,0 @@ -package com.projectkorra.projectkorra.ability; - -import java.util.Arrays; - -/** - * An enum representation of all ProjectKorra core abilities. - */ -public enum StockAbility { - - // Old Bending - AirBlast, AirBubble, AirShield, AirSuction, AirSwipe, Tornado, AirScooter, AirSpout, AirBurst, - - Catapult, RaiseEarth, EarthGrab, EarthTunnel, EarthBlast, Collapse, Tremorsense, EarthArmor, Shockwave, - - HeatControl, Blaze, FireJet, Illumination, WallOfFire, FireBlast, Lightning, FireBurst, FireShield, - - WaterBubble, PhaseChange, HealingWaters, WaterManipulation, Surge, Bloodbending, WaterSpout, IceSpike, OctopusForm, Torrent, - - HighJump, RapidPunch, Paralyze, - - AvatarState, - - // Project Korra - Extraction, MetalClips, Smokescreen, Combustion, LavaFlow, Suffocate, IceBlast, WarriorStance, AcrobatStance, QuickStrike, SwiftKick, EarthSmash, Flight, WaterArms, SandSpout, PlantArmor; - - public enum AirbendingAbilities { - AirBlast, AirBubble, AirShield, AirSuction, AirSwipe, Tornado, AirScooter, AirSpout, AirBurst, Suffocate, Flight; - } - - public enum WaterbendingAbilities { - WaterBubble, PhaseChange, HealingWaters, WaterManipulation, Surge, Bloodbending, WaterSpout, IceSpike, IceBlast, OctopusForm, Torrent, WaterArms, PlantArmor; - - } - - public enum EarthbendingAbilities { - Catapult, RaiseEarth, EarthGrab, EarthTunnel, EarthBlast, Collapse, Tremorsense, EarthArmor, Shockwave, Extraction, MetalClips, LavaFlow, EarthSmash, SandSpout; - } - - public enum FirebendingAbilities { - HeatControl, Blaze, FireJet, Illumination, WallOfFire, FireBlast, Lightning, FireBurst, FireShield, Combustion; - } - - public enum ChiblockingAbilities { - HighJump, RapidPunch, Paralyze, Smokescreen, WarriorStance, AcrobatStance, QuickStrike, SwiftKick; - } - - public enum FlightAbilities { - Flight; - } - - private enum SpiritualProjectionAbilities { - ; - } - - public enum CombustionbendingAbilities { - Combustion; - } - - public enum LightningbendingAbilities { - Lightning; - } - - public enum LavabendingAbilities { - LavaFlow; - } - - public enum MetalbendingAbilities { - Extraction, MetalClips; - } - - public enum SandbendingAbilities { - SandSpout; - } - - public enum HealingAbilities { - HealingWaters; - } - - public enum IcebendingAbilities { - PhaseChange, IceBlast, IceSpike; - } - - public enum BloodbendingAbilities { - Bloodbending; - } - - public enum PlantbendingAbilities { - PlantArmor; - } - - public enum MultiAbilities { - WaterArms; - } - - public enum AvatarAbilities { - AvatarState; - } - - public static boolean isFlightAbility(String ability) { - for (FlightAbilities a : FlightAbilities.values()) - if (a.name().equalsIgnoreCase(ability)) - return true; - return false; - } - - public static boolean isSpiritualProjectionAbility(String ability) { - for (SpiritualProjectionAbilities a : SpiritualProjectionAbilities.values()) - if (a.name().equalsIgnoreCase(ability)) - return true; - return false; - } - - public static boolean isCombustionbendingAbility(String ability) { - for (CombustionbendingAbilities a : CombustionbendingAbilities.values()) - if (a.name().equalsIgnoreCase(ability)) - return true; - return false; - } - - public static boolean isLightningbendingAbility(String ability) { - for (LightningbendingAbilities a : LightningbendingAbilities.values()) - if (a.name().equalsIgnoreCase(ability)) - return true; - return false; - } - - public static boolean isLavabendingAbility(String ability) { - for (LavabendingAbilities a : LavabendingAbilities.values()) - if (a.name().equalsIgnoreCase(ability)) - return true; - return false; - } - - public static boolean isMetalbendingAbility(String ability) { - for (MetalbendingAbilities a : MetalbendingAbilities.values()) - if (a.name().equalsIgnoreCase(ability)) - return true; - return false; - } - - public static boolean isSandbendingAbility(String ability) { - for (SandbendingAbilities a : SandbendingAbilities.values()) - if (a.name().equalsIgnoreCase(ability)) - return true; - return false; - } - - public static boolean isHealingAbility(String ability) { - for (HealingAbilities a : HealingAbilities.values()) - if (a.name().equalsIgnoreCase(ability)) - return true; - return false; - } - - public static boolean isIcebendingAbility(String ability) { - for (IcebendingAbilities a : IcebendingAbilities.values()) - if (a.name().equalsIgnoreCase(ability)) - return true; - return false; - } - - public static boolean isBloodbendingAbility(String ability) { - for (BloodbendingAbilities a : BloodbendingAbilities.values()) - if (a.name().equalsIgnoreCase(ability)) - return true; - return false; - } - - public static boolean isPlantbendingAbility(String ability) { - for (PlantbendingAbilities a : PlantbendingAbilities.values()) - if (a.name().equalsIgnoreCase(ability)) - return true; - return false; - } - - public static boolean isStockAbility(String ability) { - for (StockAbility a : StockAbility.values()) { - if (a.name().equalsIgnoreCase(ability)) - return true; - } - return false; - } - - public static boolean isAirbending(StockAbility ability) { - for (AirbendingAbilities a : AirbendingAbilities.values()) { - if (a.name().equalsIgnoreCase(ability.name())) - return true; - } - return false; - } - - public static boolean isWaterbending(StockAbility ability) { - for (WaterbendingAbilities a : WaterbendingAbilities.values()) { - if (a.name().equalsIgnoreCase(ability.name())) - return true; - } - return false; - } - - public static boolean isEarthbending(StockAbility ability) { - for (EarthbendingAbilities a : EarthbendingAbilities.values()) { - if (a.name().equalsIgnoreCase(ability.name())) - return true; - } - return false; - } - - public static boolean isFirebending(StockAbility ability) { - for (FirebendingAbilities a : FirebendingAbilities.values()) { - if (a.name().equalsIgnoreCase(ability.name())) - return true; - } - return false; - } - - public static boolean isChiBlocking(StockAbility ability) { - for (ChiblockingAbilities a : ChiblockingAbilities.values()) { - if (a.name().equalsIgnoreCase(ability.name())) - return true; - } - - return false; - } - - public static boolean isMultiAbility(StockAbility ability) { - for (MultiAbilities a : MultiAbilities.values()) { - if (a.name().equalsIgnoreCase(ability.name())) - return true; - } - return false; - } - - public static StockAbility getAbility(int index) { - if (index == -1) - return null; - if (index > StockAbility.values().length) - return null; - return Arrays.asList(StockAbility.values()).get(index); - } -} diff --git a/src/com/projectkorra/projectkorra/ability/SubAbility.java b/src/com/projectkorra/projectkorra/ability/SubAbility.java new file mode 100644 index 00000000..c236eb57 --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/SubAbility.java @@ -0,0 +1,10 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.Element; + +public interface SubAbility { + + public Class getParentAbility(); + + public Element getParentElement(); +} diff --git a/src/com/projectkorra/projectkorra/ability/WaterAbility.java b/src/com/projectkorra/projectkorra/ability/WaterAbility.java new file mode 100644 index 00000000..33192a96 --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/WaterAbility.java @@ -0,0 +1,298 @@ +package com.projectkorra.projectkorra.ability; + +import com.projectkorra.projectkorra.BendingPlayer; +import com.projectkorra.projectkorra.Element; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.TempBlock; +import com.projectkorra.projectkorra.waterbending.PhaseChangeFreeze; +import com.projectkorra.projectkorra.waterbending.SurgeWall; +import com.projectkorra.projectkorra.waterbending.SurgeWave; +import com.projectkorra.projectkorra.waterbending.WaterArms; +import com.projectkorra.projectkorra.waterbending.WaterSpout; +import com.projectkorra.rpg.RPGMethods; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +public abstract class WaterAbility extends BlockAbility { + + public WaterAbility(Player player) { + super(player); + } + + public boolean canAutoSource() { + return getConfig().getBoolean("Abilities." + getElement() + "." + getName() + ".CanAutoSource"); + } + + public boolean canDynamicSource() { + return getConfig().getBoolean("Abilities." + getElement() + "." + getName() + ".CanDynamicSource"); + } + + @Override + public Element getElement() { + return Element.WATER; + } + + public Block getIceSourceBlock(double range) { + return getIceSourceBlock(player, range); + } + + public double getNightFactor() { + if (getLocation() != null) { + return getNightFactor(getLocation().getWorld()); + } + return player != null ? getNightFactor(player.getLocation().getWorld()) : 1; + } + + public double getNightFactor(double value) { + return player != null ? getNightFactor(value, player.getWorld()) : value; + } + + public Block getPlantSourceBlock(double range) { + return getPlantSourceBlock(range, false); + } + + public Block getPlantSourceBlock(double range, boolean onlyLeaves) { + return getPlantSourceBlock(player, range, onlyLeaves); + } + + @Override + public boolean isExplosiveAbility() { + return false; + } + + @Override + public boolean isIgniteAbility() { + return false; + } + + public boolean isWaterbendable(Block block) { + return isWaterbendable(block, player); + } + + public static boolean canBendPackedIce() { + return getConfig().getBoolean("Properties.Water.CanBendPackedIce"); + } + + public static Block getIceSourceBlock(Player player, double range) { + Location location = player.getEyeLocation(); + Vector vector = location.getDirection().clone().normalize(); + for (double i = 0; i <= range; i++) { + Block block = location.clone().add(vector.clone().multiply(i)).getBlock(); + if (GeneralMethods.isRegionProtectedFromBuild(player, "IceBlast", location)) { + continue; + } + if (isIcebendable(block)) { + if (TempBlock.isTempBlock(block)) { + continue; + } + return block; + } + } + return null; + } + + public static double getNightFactor(double value, World world) { + if (isNight(world)) { + if (GeneralMethods.hasRPG()) { + if (isLunarEclipse(world)) { + return RPGMethods.getFactor("LunarEclipse"); + } else if (isFullMoon(world)) { + return RPGMethods.getFactor("FullMoon"); + } else { + return value; + } + } else { + if (isFullMoon(world)) { + return getConfig().getDouble("Properties.Water.FullMoonFactor") * value; + } else { + return getConfig().getDouble("Properties.Water.NightFactor") * value; + } + } + } else { + return value; + } + } + + public static double getNightFactor(World world) { + return getNightFactor(1, world); + } + + public static Block getPlantSourceBlock(Player player, double range, boolean onlyLeaves) { + Location location = player.getEyeLocation(); + Vector vector = location.getDirection().clone().normalize(); + + for (double i = 0; i <= range; i++) { + Block block = location.clone().add(vector.clone().multiply(i)).getBlock(); + if (GeneralMethods.isRegionProtectedFromBuild(player, "PlantDisc", location)) { + continue; + } else if (isPlantbendable(block, onlyLeaves)) { + if (TempBlock.isTempBlock(block)) { + continue; + } + return block; + } + } + return null; + } + + /** + * Finds a valid Water source for a Player. To use dynamic source selection, + * use BlockSource.getWaterSourceBlock() instead of this method. Dynamic + * source selection saves the user's previous source for future use. + * {@link BlockSource#getWaterSourceBlock(Player, double)} + * + * @param player the player that is attempting to Waterbend. + * @param range the maximum block selection range. + * @param plantbending true if the player can bend plants. + * @return a valid Water source block, or null if one could not be found. + */ + @SuppressWarnings("deprecation") + public static Block getWaterSourceBlock(Player player, double range, boolean plantbending) { + Location location = player.getEyeLocation(); + Vector vector = location.getDirection().clone().normalize(); + + for (double i = 0; i <= range; i++) { + Block block = location.clone().add(vector.clone().multiply(i)).getBlock(); + if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", location)) { + continue; + } else if (isWaterbendable(block, player) && (!isPlant(block) || plantbending)) { + if (TempBlock.isTempBlock(block)) { + TempBlock tb = TempBlock.get(block); + byte full = 0x0; + if (tb.getState().getRawData() != full + && (tb.getState().getType() != Material.WATER || tb.getState().getType() != Material.STATIONARY_WATER)) { + continue; + } + } + return block; + } + } + return null; + } + + public static boolean isAdjacentToFrozenBlock(Block block) { + BlockFace[] faces = { BlockFace.DOWN, BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.WEST, BlockFace.SOUTH }; + boolean adjacent = false; + for (BlockFace face : faces) { + if (PhaseChangeFreeze.getFrozenBlocks().containsKey((block.getRelative(face)))) { + adjacent = true; + } + } + return adjacent; + } + + public static boolean isIcebendable(Block block) { + return block != null ? isIcebendable(block.getType()) : false; + } + + public static boolean isIcebendable(Material material) { + if (material == Material.ICE) { + return true; + } else if (material == Material.PACKED_ICE && canBendPackedIce()) { + return true; + } + return false; + } + + public static boolean isPlantbendable(Block block) { + return isPlantbendable(block, false); + } + + public static boolean isPlantbendable(Block block, boolean leavesOnly) { + if (block.getType() == Material.LEAVES) { + return true; + } else if (block.getType() == Material.LEAVES_2) { + return true; + } else if (isPlant(block) && !leavesOnly) { + return true; + } + return false; + } + + public static boolean isSnow(Block block) { + return block != null ? isSnow(block.getType()) : false; + } + + public static boolean isSnow(Material material) { + return material == Material.SNOW || material == Material.SNOW_BLOCK; + } + + @SuppressWarnings("deprecation") + public static boolean isWaterbendable(Block block, Player player) { + byte full = 0x0; + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + + if (TempBlock.isTempBlock(block)) { + return false; + } else if (isWater(block) && block.getData() == full) { + return true; + } else if (block.getType() == Material.ICE || block.getType() == Material.SNOW) { + return true; + } else if (block.getType() == Material.PACKED_ICE && canBendPackedIce()) { + return true; + } else if (bPlayer != null && bPlayer.canPlantbend() && isPlant(block)) { + return true; + } + return false; + } + + public static void playFocusWaterEffect(Block block) { + block.getWorld().playEffect(block.getLocation(), Effect.SMOKE, 4, 20); + } + + public static void playIcebendingSound(Location loc) { + if (getConfig().getBoolean("Properties.Water.PlaySound")) { + loc.getWorld().playSound(loc, Sound.FIRE_IGNITE, 2, 10); + } + } + + public static void playPlantbendingSound(Location loc) { + if (getConfig().getBoolean("Properties.Water.PlaySound")) { + loc.getWorld().playSound(loc, Sound.STEP_GRASS, 1, 10); + } + } + + public static void playWaterbendingSound(Location loc) { + if (getConfig().getBoolean("Properties.Water.PlaySound")) { + loc.getWorld().playSound(loc, Sound.WATER, 1, 10); + } + } + + /** + * Removes all water spouts in a location within a certain radius. + * + * @param loc The location to use + * @param radius The radius around the location to remove spouts in + * @param source The player causing the removal + */ + public static void removeWaterSpouts(Location loc, double radius, Player source) { + WaterSpout.removeSpouts(loc, radius, source); + } + + /** + * Removes all water spouts in a location with a radius of 1.5. + * + * @param loc The location to use + * @param source The player causing the removal + */ + public static void removeWaterSpouts(Location loc, Player source) { + removeWaterSpouts(loc, 1.5, source); + } + + public static void stopBending() { + PhaseChangeFreeze.removeAllCleanup(); + WaterSpout.removeAllCleanup(); + SurgeWall.removeAllCleanup(); + SurgeWave.removeAllCleanup(); + WaterArms.removeAllCleanup(); + } +} diff --git a/src/com/projectkorra/projectkorra/ability/api/Ability.java b/src/com/projectkorra/projectkorra/ability/api/Ability.java deleted file mode 100644 index 316459cf..00000000 --- a/src/com/projectkorra/projectkorra/ability/api/Ability.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.projectkorra.projectkorra.ability.api; - -public interface Ability { - - public String getName(); - - public String getDescription(); - - public void progress(); - - public void remove(); -} diff --git a/src/com/projectkorra/projectkorra/ability/api/AirAbility.java b/src/com/projectkorra/projectkorra/ability/api/AirAbility.java deleted file mode 100644 index 537f8796..00000000 --- a/src/com/projectkorra/projectkorra/ability/api/AirAbility.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.projectkorra.projectkorra.ability.api; - -import com.projectkorra.projectkorra.configuration.ConfigManager; - -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; - -public abstract class AirAbility extends CoreAbility { - - public AirAbility(Player player, boolean autoStart) { - super(player, autoStart); - } - - public AirAbility(Player player) { - this(player, false); - } - - @Override - public final String getElementName() { - return "Air"; - } - - /** - * Gets the AirColor from the config. - * - * @return Config specified ChatColor - */ - public static ChatColor getAirColor() { - return ChatColor.valueOf(ConfigManager.getConfig().getString("Properties.Chat.Colors.Air")); - } - -} diff --git a/src/com/projectkorra/projectkorra/ability/api/CoreAbility.java b/src/com/projectkorra/projectkorra/ability/api/CoreAbility.java deleted file mode 100644 index 633b670f..00000000 --- a/src/com/projectkorra/projectkorra/ability/api/CoreAbility.java +++ /dev/null @@ -1,155 +0,0 @@ -package com.projectkorra.projectkorra.ability.api; - -import com.projectkorra.projectkorra.SubElement; -import com.projectkorra.projectkorra.configuration.ConfigManager; - -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; - -import java.util.Collection; -import java.util.Collections; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - -public abstract class CoreAbility implements Ability { - - private static ConcurrentHashMap, ConcurrentHashMap>> instances = new ConcurrentHashMap<>(); - private static ConcurrentHashMap, Set> instancesByClass = new ConcurrentHashMap<>(); - private static Integer idCounter; - - private long startTime; - private Player player; - private Integer id; - private FileConfiguration config; - - static { - idCounter = Integer.MIN_VALUE; - } - - public CoreAbility(Player player, boolean autoStart) { - if (player == null) { - throw new IllegalArgumentException("Player cannot be null"); - } - - this.player = player; - this.startTime = System.currentTimeMillis(); - this.config = ConfigManager.defaultConfig.get(); - - if (autoStart) { - start(); - } - } - - private void start() { - Class clazz = getClass(); - UUID uuid = player.getUniqueId(); - - if (!CoreAbility.instances.containsKey(clazz)) { - CoreAbility.instances.put(clazz, new ConcurrentHashMap>()); - CoreAbility.instancesByClass.put(clazz, Collections.newSetFromMap(new ConcurrentHashMap())); - } - if (!CoreAbility.instances.get(clazz).containsKey(uuid)) { - CoreAbility.instances.get(clazz).put(uuid, new ConcurrentHashMap()); - } - - this.id = CoreAbility.idCounter; - if (CoreAbility.idCounter == Integer.MAX_VALUE) { - CoreAbility.idCounter = Integer.MIN_VALUE; - } else { - CoreAbility.idCounter++; - } - - CoreAbility.instances.get(clazz).get(uuid).put(this.id, this); - CoreAbility.instancesByClass.get(clazz).add(this); - } - - public CoreAbility(Player player) { - this(player, true); - } - - public long getStartTime() { - return startTime; - } - - public Player getPlayer() { - return player; - } - - public Integer getId() { - return id; - } - - public String getDescription() { - return config.getString("Properties." + getElementName() + "." + getName() + ".Description"); - } - - public FileConfiguration getConfig() { - return config; - } - - @Override - public void remove() { - ConcurrentHashMap> classMap = CoreAbility.instances.get(getClass()); - ConcurrentHashMap playerMap = classMap.get(player.getUniqueId()); - playerMap.remove(this.id); - if (playerMap.size() == 0) { - classMap.remove(playerMap); - } - CoreAbility.instancesByClass.get(getClass()).remove(this); - } - - public static void progressAll() { - for (Set setAbils : CoreAbility.instancesByClass.values()) { - for (CoreAbility abil : setAbils) { - abil.progress(); - } - } - } - - public static void removeAll() { - for (Set setAbils : CoreAbility.instancesByClass.values()) { - for (CoreAbility abil : setAbils) { - abil.remove(); - } - } - } - - public static CoreAbility getAbility(Player player, Class clazz) { - Collection abils = CoreAbility.getAbilities(player, clazz); - if (abils.iterator().hasNext()) { - return abils.iterator().next(); - } - return null; - } - - public static Collection getAbilities(Class clazz) { - if (CoreAbility.instancesByClass.get(clazz).size() == 0) { - return Collections.emptySet(); - } - return CoreAbility.instancesByClass.get(clazz); - } - - public static Collection getAbilities(Player player, Class clazz) { - if (player == null || CoreAbility.instances.get(clazz) == null || CoreAbility.instances.get(clazz).get(player.getUniqueId()) == null) { - return Collections.emptySet(); - } - return CoreAbility.instances.get(clazz).get(player.getUniqueId()).values(); - } - - public ChatColor getElementColor() { - String element = (this instanceof SubAbility) ? getParentAbility().getElementName() + "Sub" : getElementName(); - return ChatColor.valueOf(ConfigManager.getConfig().getString("Properties.Chat.Colors."+element)); - } - - public abstract String getName(); - - public abstract String getElementName(); - - public abstract Location getLocation(); - - public abstract long getCooldown(); - -} diff --git a/src/com/projectkorra/projectkorra/ability/api/EarthAbility.java b/src/com/projectkorra/projectkorra/ability/api/EarthAbility.java deleted file mode 100644 index 1882a674..00000000 --- a/src/com/projectkorra/projectkorra/ability/api/EarthAbility.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.projectkorra.projectkorra.ability.api; - -import com.projectkorra.projectkorra.configuration.ConfigManager; - -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; - -public abstract class EarthAbility extends CoreAbility implements SourceAbility { - private boolean canAutoSource; - private boolean canDynamicSource; - private boolean canSelfSource; - - public EarthAbility(Player player, boolean autoStart) { - super(player, autoStart); - } - - public EarthAbility(Player player) { - this(player, false); - } - - @Override - public final String getElementName() { - return "Earth"; - } - - /** - * Gets the EarthColor from the config. - * - * @return Config specified ChatColor - */ - public static ChatColor getEarthColor() { - return ChatColor.valueOf(ConfigManager.getConfig().getString("Properties.Chat.Colors.Earth")); - } - - public boolean canAutoSource() { - return canAutoSource; - } - - public boolean canDynamicSource() { - return canDynamicSource; - } - - public boolean canSelfSource() { - return canSelfSource; - } -} diff --git a/src/com/projectkorra/projectkorra/ability/api/FireAbility.java b/src/com/projectkorra/projectkorra/ability/api/FireAbility.java deleted file mode 100644 index 3ee7453a..00000000 --- a/src/com/projectkorra/projectkorra/ability/api/FireAbility.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.projectkorra.projectkorra.ability.api; - -import com.projectkorra.projectkorra.BendingManager; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.configuration.ConfigManager; -import com.projectkorra.projectkorra.firebending.FireMethods; -import com.projectkorra.rpg.RPGMethods; -import com.projectkorra.rpg.WorldEvents; - -import org.bukkit.ChatColor; -import org.bukkit.World; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; - -public abstract class FireAbility extends CoreAbility { - - private double dayFactor; - - public FireAbility(Player player, boolean autoStart) { - super(player, autoStart); - this.dayFactor = FireAbility.getFirebendingDayAugment(1, player.getWorld()); - } - - public FireAbility(Player player) { - this(player, false); - } - - public double getDayFactor() { - return dayFactor; - } - - public double getDayFactor(double value) { - return dayFactor * value; - } - - @Override - public final String getElementName() { - return "Fire"; - } - - /** - * Gets the FireColor from the config. - * - * @return Config specified ChatColor - */ - public static ChatColor getFireColor() { - return ChatColor.valueOf(ConfigManager.getConfig().getString("Properties.Chat.Colors.Fire")); - } - - public static boolean canFireGrief() { - return ConfigManager.getConfig().getBoolean("Properties.Fire.FireGriefing"); - } - - /** - * Gets the firebending dayfactor from the config multiplied by a specific value if it is day. - * - * @param value The value - * @param world The world to pass into {@link #isDay(World)} - * @return value DayFactor multiplied by specified value when {@link #isDay(World)} is true
- * else
- * value The specified value in the parameters - */ - public static double getFirebendingDayAugment(double value, World world) { - FileConfiguration config = ConfigManager.getConfig(); - if (FireMethods.isDay(world)) { // TODO move the isDay method - if (GeneralMethods.hasRPG()) { - if (BendingManager.events.get(world).equalsIgnoreCase(WorldEvents.SozinsComet.toString())) { - return RPGMethods.getFactor(WorldEvents.SozinsComet) * value; - } else if (BendingManager.events.get(world).equalsIgnoreCase(WorldEvents.SolarEclipse.toString())) { - return RPGMethods.getFactor(WorldEvents.SolarEclipse) * value; - } else { - return value * config.getDouble("Properties.Fire.DayFactor"); - } - } else { - return value * config.getDouble("Properties.Fire.DayFactor"); - } - } - return value; - } - -} diff --git a/src/com/projectkorra/projectkorra/ability/api/SourceAbility.java b/src/com/projectkorra/projectkorra/ability/api/SourceAbility.java deleted file mode 100644 index 3a2f0d3c..00000000 --- a/src/com/projectkorra/projectkorra/ability/api/SourceAbility.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.projectkorra.projectkorra.ability.api; - -import org.bukkit.block.Block; - -public interface SourceAbility { - - public Block getSource(); - - public boolean canAutoSource(); - - public boolean canDynamicSource(); - - public boolean canSelfSource(); -} diff --git a/src/com/projectkorra/projectkorra/ability/api/SubAbility.java b/src/com/projectkorra/projectkorra/ability/api/SubAbility.java deleted file mode 100644 index 7c30d9eb..00000000 --- a/src/com/projectkorra/projectkorra/ability/api/SubAbility.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.projectkorra.projectkorra.ability.api; - -public interface SubAbility { - - public Class getParentAbility(); -} diff --git a/src/com/projectkorra/projectkorra/ability/api/WaterAbility.java b/src/com/projectkorra/projectkorra/ability/api/WaterAbility.java deleted file mode 100644 index bddea8dd..00000000 --- a/src/com/projectkorra/projectkorra/ability/api/WaterAbility.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.projectkorra.projectkorra.ability.api; - -import com.projectkorra.projectkorra.configuration.ConfigManager; - -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; - -public abstract class WaterAbility extends CoreAbility implements SourceAbility { - - private boolean canAutoSource; - private boolean canDynamicSource; - private boolean canSelfSource; - - public WaterAbility(Player player, boolean autoStart) { - super(player, autoStart); - } - - public WaterAbility(Player player) { - this(player, false); - } - - @Override - public final String getElementName() { - return "Water"; - } - - /** - * Gets the WaterColor from the config. - * - * @return Config specified ChatColor - */ - public static ChatColor getWaterColor() { - return ChatColor.valueOf(ConfigManager.getConfig().getString("Properties.Chat.Colors.Water")); - } - - public boolean canAutoSource() { - return canAutoSource; - } - - public boolean canDynamicSource() { - return canDynamicSource; - } - - public boolean canSelfSource() { - return canSelfSource; - } -} diff --git a/src/com/projectkorra/projectkorra/ability/combo/ComboAbilityModule.java b/src/com/projectkorra/projectkorra/ability/combo/ComboAbilityModule.java deleted file mode 100644 index 879bd13e..00000000 --- a/src/com/projectkorra/projectkorra/ability/combo/ComboAbilityModule.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.projectkorra.projectkorra.ability.combo; - -import com.projectkorra.projectkorra.SubElement; -import com.projectkorra.projectkorra.util.AbilityLoadable; - -import org.bukkit.entity.Player; - -import java.util.ArrayList; - -/** - * Created by Carbogen on 2/7/2015. - */ -public abstract class ComboAbilityModule extends AbilityLoadable implements Cloneable { - /** - * AbilityModule Constructor. - * - * @param name The name of the ability. - */ - public ComboAbilityModule(final String name) { - super(name); - } - - /** - * Called when the ability is loaded by PK. This is where the developer - * registers Listeners and Permissions. - */ - public abstract void onThisLoad(); - - // Must be overridden - - /** - * Accessor Method to get the version of the ability. - * - * @return The version of the ability as a String. - */ - public abstract String getVersion(); - - /** - * Accessor Method to get the Element of the ability. It is recommended to - * use the Element ENUM to get the returned String. This can be an empty - * String, in which case the ability will not belong to any element (such as - * AvatarState). - * - * @return The Element the ability belongs to. - */ - public abstract String getElement(); - - /** - * Accessor Method to get the name of the author. - * - * @return The name of the author. - */ - public abstract String getAuthor(); - - /** - * Accessor Method to get the description of the ability. This String is - * sent to any player who runs /pk display ability. - * - * @return The Description of the ability. - */ - public abstract String getDescription(); - - /** - * Accessor Method to get the instructions for using this combo. - * - * @return The steps for the combo. - */ - public abstract String getInstructions(); - - /** - * Creates a new instance of the combo from a specific player. - * ProjectKorra's ComboModuleManager will use this method once the combo - * steps have been used by the player. - * - * @return A new instance of the ability. - * @param player The player using the combo. - */ - public abstract Object createNewComboInstance(Player player); - - /** - * Returns the list of abilities which constitute the combo. - * - * @return An ArrayList containing the combo's steps. - */ - public abstract ArrayList getCombination(); - - /** - * Void Method called whenever ProjectKorra stops and the ability is - * unloaded. - * - */ - public void stop() { - - } - - /** - * Accessor Method to get which SubElement the ability belongs to. If - * isSubAbility() returns true, the developer absolutely must implement this - * as well. - * - * List of sub-elements: - * - * Water: Icebending. Bloodbending. Plantbending. Healing. - * - * Earth: Sandbending. Metalbending. Lavabending. - * - * Fire: Combustion. Lightning. - * - * Air: Flight. SpiritualProjection. - * - * @return The SubElement the ability belongs to. - */ - public SubElement getSubElement() { - return null; - } -} diff --git a/src/com/projectkorra/projectkorra/ability/combo/ComboModuleManager.java b/src/com/projectkorra/projectkorra/ability/combo/ComboModuleManager.java deleted file mode 100644 index 21edb40b..00000000 --- a/src/com/projectkorra/projectkorra/ability/combo/ComboModuleManager.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.projectkorra.projectkorra.ability.combo; - -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.util.AbilityLoader; - -import java.io.File; -import java.util.List; - -public class ComboModuleManager { - private final AbilityLoader loader; - public static List combo; - - public ComboModuleManager() { - final File path = new File(ProjectKorra.plugin.getDataFolder().toString() + "/Combos/"); - if (!path.exists()) { - path.mkdir(); - } - - loader = new AbilityLoader(ProjectKorra.plugin, path, new Object[] {}); - - combo = loader.load(ComboAbilityModule.class); - - loadComboModules(); - } - - private void loadComboModules() { - for (ComboAbilityModule cm : combo) { - cm.onThisLoad(); - ComboManager.comboAbilityList.put(cm.getName(), new ComboManager.ComboAbility(cm.getName(), cm.getCombination(), cm)); - ComboManager.descriptions.put(cm.getName(), cm.getDescription()); - ComboManager.instructions.put(cm.getName(), cm.getInstructions()); - ComboManager.authors.put(cm.getName(), cm.getAuthor()); - } - } -} diff --git a/src/com/projectkorra/projectkorra/ability/multiability/MultiAbilityModule.java b/src/com/projectkorra/projectkorra/ability/multiability/MultiAbilityModule.java deleted file mode 100644 index a819376f..00000000 --- a/src/com/projectkorra/projectkorra/ability/multiability/MultiAbilityModule.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.projectkorra.projectkorra.ability.multiability; - -import com.projectkorra.projectkorra.SubElement; -import com.projectkorra.projectkorra.ability.multiability.MultiAbilityManager.MultiAbilitySub; -import com.projectkorra.projectkorra.util.AbilityLoadable; - -import java.util.ArrayList; - -public abstract class MultiAbilityModule extends AbilityLoadable implements Cloneable { - - public MultiAbilityModule(String name) { - super(name); - } - - /** - * Called when the ability is loaded by PK. This is where the developer - * registers Listeners and Permissions. - */ - public abstract void onThisLoad(); - - /** - * Accessor Method to get the version of the ability. - * - * @return The version of the ability as a String. - */ - public abstract String getVersion(); - - /** - * Accessor Method to get the Element of the ability. It is recommended to - * use the Element ENUM to get the returned String. This can be an empty - * String, in which case the ability will not belong to any element (such as - * AvatarState). - * - * @return The Element the ability belongs to. - */ - public abstract String getElement(); - - /** - * Accessor Method to get the name of the author. - * - * @return The name of the author. - */ - public abstract String getAuthor(); - - /** - * Accessor Method to get the description of the ability. This String is - * sent to any player who runs /pk display ability. - * - * @return The Description of the ability. - */ - public abstract String getDescription(); - - /** - * Accessor Method to get whether this ability uses sneaking to operate. - * Some features of the ProjectKorra plugin only work when this is false. - * (Fast Swimming for Waterbenders) - * - * @return Whether or not the ability uses the sneak key. - */ - public boolean isShiftAbility() { - return true; - } - - /** - * Accessor Method to get whether this ability harms entities. AirSpout is - * an example of a harmless ability. For AirSpout, this returns true. - * IceBlast is an example of a harmful ability. For IceBlast, this returns - * false. Torrent is an example of both a harmless and a harmful ability. - * For Torrent, this returns false. - * - * @return Whether of not the ability can hurt entities. - */ - public abstract boolean isHarmlessAbility(); - - /** - * Accessor Method to get whether this ability can set fire to blocks. - * - * @return Whether or not this ability can ignite blocks. - */ - public boolean isIgniteAbility() { - return false; - } - - /** - * Accessor Method to get whether this ability can create explosions. - * - * @return Whether or not this ability creates explosions. - */ - public boolean isExplodeAbility() { - return false; - } - - /** - * Accessor Method to get which SubElement the ability belongs to. If - * isSubAbility() returns true, the developer absolutely must implement this - * as well. - * - * List of sub-elements: - * - * Water: Icebending. Bloodbending. Plantbending. Healing. - * - * Earth: Sandbending. Metalbending. Lavabending. - * - * Fire: Combustion. Lightning. - * - * Air: Flight. SpiritualProjection. - * - * @return The SubElement the ability belongs to. - */ - public SubElement getSubElement() { - return null; - } - - /** - * Returns the sub abilities of a MultiAbility. e.g. {@code new - * MultiAbilitySub("SubAbility", Element.Fire, SubElement.Lightning);} - * - * @return arraylist of multiabilitysub - */ - public abstract ArrayList getAbilities(); - - /** - * Void Method called whenever ProjectKorra stops and the ability is - * unloaded. - */ - public void stop() { - - } - -} diff --git a/src/com/projectkorra/projectkorra/ability/multiability/MultiAbilityModuleManager.java b/src/com/projectkorra/projectkorra/ability/multiability/MultiAbilityModuleManager.java deleted file mode 100644 index b14a604e..00000000 --- a/src/com/projectkorra/projectkorra/ability/multiability/MultiAbilityModuleManager.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.projectkorra.projectkorra.ability.multiability; - -import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AbilityModuleManager; -import com.projectkorra.projectkorra.ability.StockAbility; -import com.projectkorra.projectkorra.ability.multiability.MultiAbilityManager.MultiAbility; -import com.projectkorra.projectkorra.util.AbilityLoader; - -import java.io.File; -import java.util.List; - -public class MultiAbilityModuleManager { - private final AbilityLoader loader; - public static List multiAbility; - - public MultiAbilityModuleManager() { - final File path = new File(ProjectKorra.plugin.getDataFolder().toString() + "/MultiAbilities/"); - if (!path.exists()) { - path.mkdir(); - } - - loader = new AbilityLoader(ProjectKorra.plugin, path, new Object[] {}); - multiAbility = loader.load(MultiAbilityModule.class); - - loadMAModules(); - } - - private void loadMAModules() { - for (MultiAbilityModule mam : multiAbility) { - mam.onThisLoad(); - AbilityModuleManager.abilities.add(mam.getName()); - for (StockAbility a : StockAbility.values()) { - if (a.name().equalsIgnoreCase(mam.getName())) { - AbilityModuleManager.disabledStockAbilities.add(a.name()); - } - } - if (mam.getElement() == Element.Air.toString()) - AbilityModuleManager.airbendingabilities.add(mam.getName()); - if (mam.getElement() == Element.Water.toString()) - AbilityModuleManager.waterbendingabilities.add(mam.getName()); - if (mam.getElement() == Element.Earth.toString()) - AbilityModuleManager.earthbendingabilities.add(mam.getName()); - if (mam.getElement() == Element.Fire.toString()) - AbilityModuleManager.firebendingabilities.add(mam.getName()); - if (mam.getElement() == Element.Chi.toString()) - AbilityModuleManager.chiabilities.add(mam.getName()); - AbilityModuleManager.shiftabilities.add(mam.getName()); - if (mam.isHarmlessAbility()) - AbilityModuleManager.harmlessabilities.add(mam.getName()); - - if (mam.getSubElement() != null) { - AbilityModuleManager.subabilities.add(mam.getName()); - switch (mam.getSubElement()) { - case Bloodbending: - AbilityModuleManager.bloodabilities.add(mam.getName()); - break; - case Combustion: - AbilityModuleManager.combustionabilities.add(mam.getName()); - break; - case Flight: - AbilityModuleManager.flightabilities.add(mam.getName()); - break; - case Healing: - AbilityModuleManager.healingabilities.add(mam.getName()); - break; - case Icebending: - AbilityModuleManager.iceabilities.add(mam.getName()); - break; - case Lavabending: - AbilityModuleManager.lavaabilities.add(mam.getName()); - break; - case Lightning: - AbilityModuleManager.lightningabilities.add(mam.getName()); - break; - case Metalbending: - AbilityModuleManager.metalabilities.add(mam.getName()); - break; - case Plantbending: - AbilityModuleManager.plantabilities.add(mam.getName()); - break; - case Sandbending: - AbilityModuleManager.sandabilities.add(mam.getName()); - break; - case SpiritualProjection: - AbilityModuleManager.spiritualprojectionabilities.add(mam.getName()); - break; - } - } - - MultiAbilityManager.multiAbilityList.add(new MultiAbility(mam.getName(), mam.getAbilities())); - AbilityModuleManager.descriptions.put(mam.getName(), mam.getDescription()); - AbilityModuleManager.authors.put(mam.getName(), mam.getAuthor()); - } - } -} diff --git a/src/com/projectkorra/projectkorra/ability/util/AbilityLoader.java b/src/com/projectkorra/projectkorra/ability/util/AbilityLoader.java new file mode 100644 index 00000000..8013e03e --- /dev/null +++ b/src/com/projectkorra/projectkorra/ability/util/AbilityLoader.java @@ -0,0 +1,129 @@ +package com.projectkorra.projectkorra.ability.util; + +import sun.reflect.ReflectionFactory; + +import com.projectkorra.projectkorra.event.AbilityLoadEvent; +import com.projectkorra.projectkorra.util.FileExtensionFilter; + +import org.bukkit.event.Listener; +import org.bukkit.plugin.Plugin; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.logging.Level; + +public class AbilityLoader implements Listener { + + private final Plugin plugin; + private final File directory; + private final ArrayList files; + private ClassLoader loader; + + public AbilityLoader(Plugin plugin, File directory) { + this.plugin = plugin; + this.directory = directory; + this.files = new ArrayList(); + + for (File f : directory.listFiles(new FileExtensionFilter(".jar"))) { + files.add(f); + } + + List urls = new ArrayList(); + for (File file : files) { + try { + urls.add(file.toURI().toURL()); + } + catch (MalformedURLException e) { + e.printStackTrace(); + } + } + this.loader = URLClassLoader.newInstance(urls.toArray(new URL[0]), plugin.getClass().getClassLoader()); + } + + /** + * @param classType + * @param parentClass a parent of classType that has a visible default constructor + * @return A list of all of the T objects that were loaded from the jar files within @param directory + */ + @SuppressWarnings("unchecked") + public List load(Class classType, Class parentClass) { + ArrayList loadables = new ArrayList<>(); + + for (File file : files) { + JarFile jarFile = null; + try { + jarFile = new JarFile(file); + Enumeration entries = jarFile.entries(); + + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + if (!entry.getName().endsWith(".class")) { + continue; + } + + String className = entry.getName().replace('/', '.').substring(0, entry.getName().length() - 6); + Class clazz = null; + try { + clazz = Class.forName(className, true, loader); + } catch (Exception e) { + continue; + } + + if (!classType.isAssignableFrom(clazz) || clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) { + continue; + } + + ReflectionFactory rf = ReflectionFactory.getReflectionFactory(); + Constructor objDef = parentClass.getDeclaredConstructor(); + Constructor intConstr = rf.newConstructorForSerialization(clazz, objDef); + T loadable = (T) clazz.cast(intConstr.newInstance()); + + loadables.add(loadable); + AbilityLoadEvent event = new AbilityLoadEvent(plugin, loadable, jarFile); + plugin.getServer().getPluginManager().callEvent(event); + } + + } catch (Exception e) { + e.printStackTrace(); + plugin.getLogger().log(Level.WARNING, "Unknown cause"); + plugin.getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load"); + } finally { + if (jarFile != null) { + try { + jarFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return loadables; + } + + public ClassLoader getLoader() { + return loader; + } + + public Plugin getPlugin() { + return plugin; + } + + public File getDirectory() { + return directory; + } + + public ArrayList getFiles() { + return files; + } + +} diff --git a/src/com/projectkorra/projectkorra/ability/combo/ComboManager.java b/src/com/projectkorra/projectkorra/ability/util/ComboManager.java similarity index 61% rename from src/com/projectkorra/projectkorra/ability/combo/ComboManager.java rename to src/com/projectkorra/projectkorra/ability/util/ComboManager.java index fc8a2c47..64f4eaf7 100644 --- a/src/com/projectkorra/projectkorra/ability/combo/ComboManager.java +++ b/src/com/projectkorra/projectkorra/ability/util/ComboManager.java @@ -1,404 +1,427 @@ -package com.projectkorra.projectkorra.ability.combo; - -import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.airbending.AirCombo; -import com.projectkorra.projectkorra.chiblocking.ChiCombo; -import com.projectkorra.projectkorra.firebending.FireCombo; -import com.projectkorra.projectkorra.util.ClickType; -import com.projectkorra.projectkorra.waterbending.WaterCombo; - -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.concurrent.ConcurrentHashMap; - -public class ComboManager { - private static final long CLEANUP_DELAY = 20 * 600; - public static ConcurrentHashMap> recentlyUsedAbilities = new ConcurrentHashMap>(); - public static HashMap comboAbilityList = new HashMap(); - public static HashMap authors = new HashMap(); - public static HashMap descriptions = new HashMap(); - public static HashMap instructions = new HashMap(); - - public ComboManager() { - ArrayList fireKick = new ArrayList(); - fireKick.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK)); - fireKick.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK)); - fireKick.add(new AbilityInformation("FireBlast", ClickType.SHIFT_DOWN)); - fireKick.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK)); - comboAbilityList.put("FireKick", new ComboAbility("FireKick", fireKick, FireCombo.class)); - descriptions.put("FireKick", "A short ranged arc of fire launches from the player's feet dealing moderate damage to enemies."); - instructions.put("FireKick", "FireBlast > FireBlast > (Hold Shift) > FireBlast."); - - ArrayList fireSpin = new ArrayList(); - fireSpin.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK)); - fireSpin.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK)); - fireSpin.add(new AbilityInformation("FireShield", ClickType.LEFT_CLICK)); - fireSpin.add(new AbilityInformation("FireShield", ClickType.SHIFT_DOWN)); - fireSpin.add(new AbilityInformation("FireShield", ClickType.SHIFT_UP)); - comboAbilityList.put("FireSpin", new ComboAbility("FireSpin", fireSpin, FireCombo.class)); - descriptions.put("FireSpin", "A circular array of fire that causes damage and massive knockback to nearby enemies."); - instructions.put("FireSpin", "FireBlast > FireBlast > FireShield > (Tap Shift)."); - - ArrayList jetBlast = new ArrayList(); - jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN)); - jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP)); - jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN)); - jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP)); - jetBlast.add(new AbilityInformation("FireShield", ClickType.SHIFT_DOWN)); - jetBlast.add(new AbilityInformation("FireShield", ClickType.SHIFT_UP)); - jetBlast.add(new AbilityInformation("FireJet", ClickType.LEFT_CLICK)); - comboAbilityList.put("JetBlast", new ComboAbility("JetBlast", jetBlast, FireCombo.class)); - descriptions.put("JetBlast", "Create an explosive blast that propels your FireJet at higher speeds."); - instructions.put("JetBlast", "FireJet (Tap Shift) > FireJet (Tap Shift) > FireShield (Tap Shift) > FireJet."); - - ArrayList jetBlaze = new ArrayList(); - jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN)); - jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP)); - jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN)); - jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP)); - jetBlaze.add(new AbilityInformation("Blaze", ClickType.SHIFT_DOWN)); - jetBlaze.add(new AbilityInformation("Blaze", ClickType.SHIFT_UP)); - jetBlaze.add(new AbilityInformation("FireJet", ClickType.LEFT_CLICK)); - comboAbilityList.put("JetBlaze", new ComboAbility("JetBlaze", jetBlaze, FireCombo.class)); - descriptions.put("JetBlaze", "Damages and burns all enemies in the proximity of your FireJet."); - instructions.put("JetBlaze", "FireJet (Tap Shift) > FireJet (Tap Shift) > Blaze (Tap Shift) > FireJet."); - - ArrayList fireWheel = new ArrayList(); - fireWheel.add(new AbilityInformation("FireShield", ClickType.SHIFT_DOWN)); - fireWheel.add(new AbilityInformation("FireShield", ClickType.RIGHT_CLICK)); - fireWheel.add(new AbilityInformation("FireShield", ClickType.RIGHT_CLICK)); - fireWheel.add(new AbilityInformation("Blaze", ClickType.SHIFT_UP)); - comboAbilityList.put("FireWheel", new ComboAbility("FireWheel", fireWheel, FireCombo.class)); - descriptions.put("FireWheel", "A high-speed wheel of fire that travels along the ground for long distances dealing high damage."); - instructions.put("FireWheel", "FireShield (Hold Shift) > Right Click a block in front of you twice > Switch to Blaze > Release Shift."); - - ArrayList twister = new ArrayList(); - twister.add(new AbilityInformation("AirShield", ClickType.SHIFT_DOWN)); - twister.add(new AbilityInformation("AirShield", ClickType.SHIFT_UP)); - twister.add(new AbilityInformation("Tornado", ClickType.SHIFT_DOWN)); - twister.add(new AbilityInformation("AirBlast", ClickType.LEFT_CLICK)); - comboAbilityList.put("Twister", new ComboAbility("Twister", twister, AirCombo.class)); - descriptions.put("Twister", "Create a cyclone of air that travels along the ground grabbing nearby entities."); - instructions.put("Twister", "AirShield (Tap Shift) > Tornado (Hold Shift) > AirBlast (Left Click)"); - - ArrayList airStream = new ArrayList(); - airStream.add(new AbilityInformation("AirShield", ClickType.SHIFT_DOWN)); - airStream.add(new AbilityInformation("AirSuction", ClickType.LEFT_CLICK)); - airStream.add(new AbilityInformation("AirBlast", ClickType.LEFT_CLICK)); - comboAbilityList.put("AirStream", new ComboAbility("AirStream", airStream, AirCombo.class)); - descriptions.put("AirStream", "Control a large stream of air that grabs onto enemies allowing you to direct them temporarily."); - instructions.put("AirStream", "AirShield (Hold Shift) > AirSuction (Left Click) > AirBlast (Left Click)"); - - /* - ArrayList airSlice = new ArrayList(); - airSlice.add(new AbilityInformation("AirBlast",ClickType.LEFT_CLICK)); - airSlice.add(new AbilityInformation("AirScooter",ClickType.SHIFT_DOWN)); - airSlice.add(new AbilityInformation("AirScooter",ClickType.LEFT_CLICK)); - comboAbilityList.put("AirSlice", new ComboAbility("AirSlice",airSlice,AirCombo.class)); - */ - - ArrayList airSweep = new ArrayList(); - airSweep.add(new AbilityInformation("AirSwipe", ClickType.LEFT_CLICK)); - airSweep.add(new AbilityInformation("AirSwipe", ClickType.LEFT_CLICK)); - airSweep.add(new AbilityInformation("AirBurst", ClickType.SHIFT_DOWN)); - airSweep.add(new AbilityInformation("AirBurst", ClickType.LEFT_CLICK)); - comboAbilityList.put("AirSweep", new ComboAbility("AirSweep", airSweep, AirCombo.class)); - descriptions.put("AirSweep", "Sweep the air in front of you hitting multiple enemies, causing moderate damage and a large knockback. The radius and direction of AirSweep is controlled by moving your mouse in a sweeping motion. For example, if you want to AirSweep upward, then move your mouse upward right after you left click AirBurst"); - instructions.put("AirSweep", "AirSwipe (Left Click) > AirSwipe (Left Click) > AirBurst (Hold Shift) > AirBurst (Left Click)"); - - ArrayList iceWave = new ArrayList(); - iceWave.add(new AbilityInformation("WaterSpout", ClickType.SHIFT_UP)); - iceWave.add(new AbilityInformation("PhaseChange", ClickType.LEFT_CLICK)); - comboAbilityList.put("IceWave", new ComboAbility("IceWave", iceWave, WaterCombo.class)); - descriptions.put("IceWave", "PhaseChange your WaterWave into an IceWave that freezes and damages enemies."); - instructions.put("IceWave", "Create a WaterSpout Wave > PhaseChange (Left Click)"); - - /* - * ArrayList icePillar = new - * ArrayList(); icePillar.add(new - * AbilityInformation("IceSpike", ClickType.LEFT_CLICK)); - * icePillar.add(new AbilityInformation("IceSpike", - * ClickType.LEFT_CLICK)); icePillar.add(new - * AbilityInformation("WaterSpout", ClickType.LEFT_CLICK)); - * comboAbilityList.put(new ComboAbility("IcePillar", icePillar, - * WaterCombo.class)); - */ - - ArrayList iceBullet = new ArrayList(); - iceBullet.add(new AbilityInformation("WaterBubble", ClickType.SHIFT_DOWN)); - iceBullet.add(new AbilityInformation("WaterBubble", ClickType.SHIFT_UP)); - iceBullet.add(new AbilityInformation("IceBlast", ClickType.SHIFT_DOWN)); - comboAbilityList.put("IceBullet", new ComboAbility("IceBullet", iceBullet, WaterCombo.class)); - descriptions.put("IceBullet", "Using a large cavern of ice, you can punch ice shards at your opponent causing moderate damage. To rapid fire, you must alternate between Left clicking and right clicking with IceBlast."); - instructions.put("IceBullet", "WaterBubble (Tap Shift) > IceBlast (Hold Shift) > Wait for ice to Form > Then alternate between Left and Right click with IceBlast"); - - ArrayList iceBulletLeft = new ArrayList(); - iceBulletLeft.add(new AbilityInformation("IceBlast", ClickType.LEFT_CLICK)); - comboAbilityList.put("IceBulletLeftClick", new ComboAbility("IceBulletLeftClick", iceBulletLeft, WaterCombo.class)); - ArrayList iceBulletRight = new ArrayList(); - iceBulletRight.add(new AbilityInformation("IceBlast", ClickType.RIGHT_CLICK)); - comboAbilityList.put("IceBulletRightClick", new ComboAbility("IceBulletRightClick", iceBulletRight, WaterCombo.class)); - - ArrayList immobilize = new ArrayList(); - immobilize.add(new AbilityInformation("QuickStrike", ClickType.LEFT_CLICK)); - immobilize.add(new AbilityInformation("SwiftKick", ClickType.LEFT_CLICK)); - immobilize.add(new AbilityInformation("QuickStrike", ClickType.LEFT_CLICK)); - immobilize.add(new AbilityInformation("QuickStrike", ClickType.LEFT_CLICK)); - comboAbilityList.put("Immobilize", new ComboAbility("Immobilize", immobilize, ChiCombo.class)); - descriptions.put("Immobilize", "Immobilizes the opponent for several seconds."); - instructions.put("Immobilize", "QuickStrike (Left Click) > SwiftKick (Left Click) > QuickStrike (Left Click) > QuickStrike (Left Click)"); - - startCleanupTask(); - } - - public static void addComboAbility(Player player, ClickType type) { - String abilityName = GeneralMethods.getBoundAbility(player); - if (abilityName == null) - return; - AbilityInformation info = new AbilityInformation(abilityName, type, System.currentTimeMillis()); - addRecentAbility(player, info); - - ComboAbility comboAbil = checkForValidCombo(player); - if (comboAbil == null) { - return; - } else if (!player.hasPermission("bending.ability." + comboAbil.getName())) { - return; - } - - if (comboAbil.getComboType().equals(FireCombo.class)) - new FireCombo(player, comboAbil.getName()); - else if (comboAbil.getComboType().equals(AirCombo.class)) - new AirCombo(player, comboAbil.getName()); - else if (comboAbil.getComboType().equals(WaterCombo.class)) - new WaterCombo(player, comboAbil.getName()); - else if (comboAbil.getComboType().equals(ChiCombo.class)) - new ChiCombo(player, comboAbil.getName()); - else { - if (comboAbil.getComboType() instanceof ComboAbilityModule) { - ((ComboAbilityModule) comboAbil.getComboType()).createNewComboInstance(player); - return; - } - } - } - - /** - * Adds an {@link AbilityInformation} to the player's - * {@link ComboManager#recentlyUsedAbilities recentlyUsedAbilities}. - * - * @param player The player to add the AbilityInformation for - * @param info The AbilityInformation to add - */ - public static void addRecentAbility(Player player, AbilityInformation info) { - ArrayList list; - String name = player.getName(); - if (recentlyUsedAbilities.containsKey(name)) - list = recentlyUsedAbilities.get(name); - else - list = new ArrayList(); - list.add(info); - recentlyUsedAbilities.put(name, list); - //Bukkit.broadcastMessage("recentlyUsedAbilities: " + recentlyUsedAbilities.get(name).size()); - } - - /** - * Checks if a Player's {@link ComboManager#recentlyUsedAbilities - * recentlyUsedAbilities} contains a valid set of moves to perform any - * combos. If it does, it returns the valid combo. - * - * @param player The player for whom to check if a valid combo has been - * performed - * @return The ComboAbility of the combo that has been performed, or null if - * no valid combo was found - */ - public static ComboAbility checkForValidCombo(Player player) { - ArrayList playerCombo = getRecentlyUsedAbilities(player, 8); - for (String ability : comboAbilityList.keySet()) { - ComboAbility customAbility = comboAbilityList.get(ability); - ArrayList abilityCombo = customAbility.getAbilities(); - int size = abilityCombo.size(); - - if (playerCombo.size() < size) - continue; - - boolean isValid = true; - for (int i = 1; i <= size; i++) { - if (!playerCombo.get(playerCombo.size() - i).equalsWithoutTime(abilityCombo.get(abilityCombo.size() - i))) { - isValid = false; - break; - } - } - if (isValid) - return customAbility; - } - return null; - } - - public static void cleanupOldCombos() { - recentlyUsedAbilities.clear(); - } - - /** - * Gets the player's most recently used abilities, up to a maximum of 10. - * - * @param player The player to get recent abilities for - * @param amount The amount of recent abilities to get, starting from most - * recent and getting older - * @return An ArrayList<{@link AbilityInformation}> of the player's recently - * used abilities - */ - public static ArrayList getRecentlyUsedAbilities(Player player, int amount) { - String name = player.getName(); - if (!recentlyUsedAbilities.containsKey(name)) - return new ArrayList(); - - ArrayList list = recentlyUsedAbilities.get(name); - if (list.size() < amount) - return new ArrayList(list); - - ArrayList tempList = new ArrayList(); - for (int i = 0; i < amount; i++) - tempList.add(0, list.get(list.size() - 1 - i)); - return tempList; - } - - /** - * Gets all of the combos for a given element. - * - * @param element The element to get combos for - * @return An ArrayList of the combos for that element - */ - public static ArrayList getCombosForElement(Element element) { - ArrayList list = new ArrayList(); - for (String comboab : descriptions.keySet()) { - if (GeneralMethods.getAbilityElement(comboAbilityList.get(comboab).getAbilities().get(0).getAbilityName()) == element) - list.add(comboab); - } - Collections.sort(list); - return list; - } - - public static void startCleanupTask() { - new BukkitRunnable() { - public void run() { - cleanupOldCombos(); - } - }.runTaskTimer(ProjectKorra.plugin, 0, CLEANUP_DELAY); - } - - /** - * Contains information on an ability used in a combo. - * - * @author kingbirdy - * - */ - public static class AbilityInformation { - private String abilityName; - private ClickType clickType; - private long time; - - public AbilityInformation(String name, ClickType type) { - this(name, type, 0); - } - - public AbilityInformation(String name, ClickType type, long time) { - this.abilityName = name; - this.clickType = type; - this.time = time; - } - - /** - * Compares if two {@link AbilityInformation}'s are equal without - * respect to {@link AbilityInformation#time time}. - * - * @param info The AbilityInformation to compare against - * @return True if they are equal without respect to time - */ - public boolean equalsWithoutTime(AbilityInformation info) { - return this.getAbilityName().equals(info.getAbilityName()) && this.getClickType().equals(info.getClickType()); - } - - /** - * Gets the name of the ability. - * - * @return The name of the ability. - */ - public String getAbilityName() { - return abilityName; - } - - /** - * Gets the {@link ClickType} of the {@link AbilityInformation}. - * - * @return The ClickType - */ - public ClickType getClickType() { - return clickType; - } - - public long getTime() { - return time; - } - - public void setAbilityName(String abilityName) { - this.abilityName = abilityName; - } - - public void setClickType(ClickType clickType) { - this.clickType = clickType; - } - - public void setTime(long time) { - this.time = time; - } - - public String toString() { - return abilityName + " " + clickType + " " + time; - } - } - - public static class ComboAbility { - private String name; - private ArrayList abilities; - private Object comboType; - - public ComboAbility(String name, ArrayList abilities, Object comboType) { - this.name = name; - this.abilities = abilities; - this.comboType = comboType; - } - - public ArrayList getAbilities() { - return abilities; - } - - public Object getComboType() { - return comboType; - } - - public String getName() { - return name; - } - - public void setAbilities(ArrayList abilities) { - this.abilities = abilities; - } - - public void setComboType(Object comboType) { - this.comboType = comboType; - } - - public void setName(String name) { - this.name = name; - } - - public String toString() { - return name; - } - } -} +package com.projectkorra.projectkorra.ability.util; + +import com.projectkorra.projectkorra.BendingPlayer; +import com.projectkorra.projectkorra.Element; +import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.ComboAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.airbending.AirCombo; +import com.projectkorra.projectkorra.chiblocking.ChiCombo; +import com.projectkorra.projectkorra.firebending.FireCombo; +import com.projectkorra.projectkorra.util.ClickType; +import com.projectkorra.projectkorra.waterbending.WaterCombo; + +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; + +public class ComboManager { + + private static final long CLEANUP_DELAY = 20 * 600; + private static final ConcurrentHashMap> RECENTLY_USED = new ConcurrentHashMap<>(); + private static final HashMap COMBO_ABILITIES = new HashMap<>(); + private static final HashMap AUTHORS = new HashMap<>(); + private static final HashMap DESCRIPTIONS = new HashMap<>(); + private static final HashMap INSTRUCTIONS = new HashMap<>(); + + public ComboManager() { + ArrayList fireKick = new ArrayList<>(); + fireKick.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK)); + fireKick.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK)); + fireKick.add(new AbilityInformation("FireBlast", ClickType.SHIFT_DOWN)); + fireKick.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK)); + COMBO_ABILITIES.put("FireKick", new ComboAbilityInfo("FireKick", fireKick, FireCombo.class)); + DESCRIPTIONS.put("FireKick", "A short ranged arc of fire launches from the player's feet dealing moderate damage to enemies."); + INSTRUCTIONS.put("FireKick", "FireBlast > FireBlast > (Hold Shift) > FireBlast."); + + ArrayList fireSpin = new ArrayList<>(); + fireSpin.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK)); + fireSpin.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK)); + fireSpin.add(new AbilityInformation("FireShield", ClickType.LEFT_CLICK)); + fireSpin.add(new AbilityInformation("FireShield", ClickType.SHIFT_DOWN)); + fireSpin.add(new AbilityInformation("FireShield", ClickType.SHIFT_UP)); + COMBO_ABILITIES.put("FireSpin", new ComboAbilityInfo("FireSpin", fireSpin, FireCombo.class)); + DESCRIPTIONS.put("FireSpin", "A circular array of fire that causes damage and massive knockback to nearby enemies."); + INSTRUCTIONS.put("FireSpin", "FireBlast > FireBlast > FireShield > (Tap Shift)."); + + ArrayList jetBlast = new ArrayList<>(); + jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN)); + jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP)); + jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN)); + jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP)); + jetBlast.add(new AbilityInformation("FireShield", ClickType.SHIFT_DOWN)); + jetBlast.add(new AbilityInformation("FireShield", ClickType.SHIFT_UP)); + jetBlast.add(new AbilityInformation("FireJet", ClickType.LEFT_CLICK)); + COMBO_ABILITIES.put("JetBlast", new ComboAbilityInfo("JetBlast", jetBlast, FireCombo.class)); + DESCRIPTIONS.put("JetBlast", "Create an explosive blast that propels your FireJet at higher speeds."); + INSTRUCTIONS.put("JetBlast", "FireJet (Tap Shift) > FireJet (Tap Shift) > FireShield (Tap Shift) > FireJet."); + + ArrayList jetBlaze = new ArrayList<>(); + jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN)); + jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP)); + jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN)); + jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP)); + jetBlaze.add(new AbilityInformation("Blaze", ClickType.SHIFT_DOWN)); + jetBlaze.add(new AbilityInformation("Blaze", ClickType.SHIFT_UP)); + jetBlaze.add(new AbilityInformation("FireJet", ClickType.LEFT_CLICK)); + COMBO_ABILITIES.put("JetBlaze", new ComboAbilityInfo("JetBlaze", jetBlaze, FireCombo.class)); + DESCRIPTIONS.put("JetBlaze", "Damages and burns all enemies in the proximity of your FireJet."); + INSTRUCTIONS.put("JetBlaze", "FireJet (Tap Shift) > FireJet (Tap Shift) > Blaze (Tap Shift) > FireJet."); + + ArrayList fireWheel = new ArrayList<>(); + fireWheel.add(new AbilityInformation("FireShield", ClickType.SHIFT_DOWN)); + fireWheel.add(new AbilityInformation("FireShield", ClickType.RIGHT_CLICK)); + fireWheel.add(new AbilityInformation("FireShield", ClickType.RIGHT_CLICK)); + fireWheel.add(new AbilityInformation("Blaze", ClickType.SHIFT_UP)); + COMBO_ABILITIES.put("FireWheel", new ComboAbilityInfo("FireWheel", fireWheel, FireCombo.class)); + DESCRIPTIONS.put("FireWheel", "A high-speed wheel of fire that travels along the ground for long distances dealing high damage."); + INSTRUCTIONS.put("FireWheel", "FireShield (Hold Shift) > Right Click a block in front of you twice > Switch to Blaze > Release Shift."); + + ArrayList twister = new ArrayList(); + twister.add(new AbilityInformation("AirShield", ClickType.SHIFT_DOWN)); + twister.add(new AbilityInformation("AirShield", ClickType.SHIFT_UP)); + twister.add(new AbilityInformation("Tornado", ClickType.SHIFT_DOWN)); + twister.add(new AbilityInformation("AirBlast", ClickType.LEFT_CLICK)); + COMBO_ABILITIES.put("Twister", new ComboAbilityInfo("Twister", twister, AirCombo.class)); + DESCRIPTIONS.put("Twister", "Create a cyclone of air that travels along the ground grabbing nearby entities."); + INSTRUCTIONS.put("Twister", "AirShield (Tap Shift) > Tornado (Hold Shift) > AirBlast (Left Click)"); + + ArrayList airStream = new ArrayList<>(); + airStream.add(new AbilityInformation("AirShield", ClickType.SHIFT_DOWN)); + airStream.add(new AbilityInformation("AirSuction", ClickType.LEFT_CLICK)); + airStream.add(new AbilityInformation("AirBlast", ClickType.LEFT_CLICK)); + COMBO_ABILITIES.put("AirStream", new ComboAbilityInfo("AirStream", airStream, AirCombo.class)); + DESCRIPTIONS.put("AirStream", "Control a large stream of air that grabs onto enemies allowing you to direct them temporarily."); + INSTRUCTIONS.put("AirStream", "AirShield (Hold Shift) > AirSuction (Left Click) > AirBlast (Left Click)"); + + ArrayList airSweep = new ArrayList<>(); + airSweep.add(new AbilityInformation("AirSwipe", ClickType.LEFT_CLICK)); + airSweep.add(new AbilityInformation("AirSwipe", ClickType.LEFT_CLICK)); + airSweep.add(new AbilityInformation("AirBurst", ClickType.SHIFT_DOWN)); + airSweep.add(new AbilityInformation("AirBurst", ClickType.LEFT_CLICK)); + COMBO_ABILITIES.put("AirSweep", new ComboAbilityInfo("AirSweep", airSweep, AirCombo.class)); + DESCRIPTIONS.put("AirSweep", "Sweep the air in front of you hitting multiple enemies, causing moderate damage and a large knockback. The radius and direction of AirSweep is controlled by moving your mouse in a sweeping motion. For example, if you want to AirSweep upward, then move your mouse upward right after you left click AirBurst"); + INSTRUCTIONS.put("AirSweep", "AirSwipe (Left Click) > AirSwipe (Left Click) > AirBurst (Hold Shift) > AirBurst (Left Click)"); + + ArrayList iceWave = new ArrayList<>(); + iceWave.add(new AbilityInformation("WaterSpout", ClickType.SHIFT_UP)); + iceWave.add(new AbilityInformation("PhaseChange", ClickType.LEFT_CLICK)); + COMBO_ABILITIES.put("IceWave", new ComboAbilityInfo("IceWave", iceWave, WaterCombo.class)); + DESCRIPTIONS.put("IceWave", "PhaseChange your WaterWave into an IceWave that freezes and damages enemies."); + INSTRUCTIONS.put("IceWave", "Create a WaterSpout Wave > PhaseChange (Left Click)"); + + ArrayList iceBullet = new ArrayList<>(); + iceBullet.add(new AbilityInformation("WaterBubble", ClickType.SHIFT_DOWN)); + iceBullet.add(new AbilityInformation("WaterBubble", ClickType.SHIFT_UP)); + iceBullet.add(new AbilityInformation("IceBlast", ClickType.SHIFT_DOWN)); + COMBO_ABILITIES.put("IceBullet", new ComboAbilityInfo("IceBullet", iceBullet, WaterCombo.class)); + DESCRIPTIONS.put("IceBullet", "Using a large cavern of ice, you can punch ice shards at your opponent causing moderate damage. To rapid fire, you must alternate between Left clicking and right clicking with IceBlast."); + INSTRUCTIONS.put("IceBullet", "WaterBubble (Tap Shift) > IceBlast (Hold Shift) > Wait for ice to Form > Then alternate between Left and Right click with IceBlast"); + + ArrayList iceBulletLeft = new ArrayList<>(); + iceBulletLeft.add(new AbilityInformation("IceBlast", ClickType.LEFT_CLICK)); + COMBO_ABILITIES.put("IceBulletLeftClick", new ComboAbilityInfo("IceBulletLeftClick", iceBulletLeft, WaterCombo.class)); + ArrayList iceBulletRight = new ArrayList<>(); + iceBulletRight.add(new AbilityInformation("IceBlast", ClickType.RIGHT_CLICK)); + COMBO_ABILITIES.put("IceBulletRightClick", new ComboAbilityInfo("IceBulletRightClick", iceBulletRight, WaterCombo.class)); + + ArrayList immobilize = new ArrayList<>(); + immobilize.add(new AbilityInformation("QuickStrike", ClickType.LEFT_CLICK)); + immobilize.add(new AbilityInformation("SwiftKick", ClickType.LEFT_CLICK)); + immobilize.add(new AbilityInformation("QuickStrike", ClickType.LEFT_CLICK)); + immobilize.add(new AbilityInformation("QuickStrike", ClickType.LEFT_CLICK)); + COMBO_ABILITIES.put("Immobilize", new ComboAbilityInfo("Immobilize", immobilize, ChiCombo.class)); + DESCRIPTIONS.put("Immobilize", "Immobilizes the opponent for several seconds."); + INSTRUCTIONS.put("Immobilize", "QuickStrike (Left Click) > SwiftKick (Left Click) > QuickStrike (Left Click) > QuickStrike (Left Click)"); + + startCleanupTask(); + } + + public static void addComboAbility(Player player, ClickType type) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + return; + } + + String abilityName = bPlayer.getBoundAbilityName(); + if (abilityName == null) { + return; + } + AbilityInformation info = new AbilityInformation(abilityName, type, System.currentTimeMillis()); + addRecentAbility(player, info); + + ComboAbilityInfo comboAbil = checkForValidCombo(player); + if (comboAbil == null) { + return; + } else if (!player.hasPermission("bending.ability." + comboAbil.getName())) { + return; + } + + if (comboAbil.getComboType().equals(FireCombo.class)) { + new FireCombo(player, comboAbil.getName()); + } else if (comboAbil.getComboType().equals(AirCombo.class)) { + new AirCombo(player, comboAbil.getName()); + } else if (comboAbil.getComboType().equals(WaterCombo.class)) { + new WaterCombo(player, comboAbil.getName()); + } else if (comboAbil.getComboType().equals(ChiCombo.class)) { + new ChiCombo(player, comboAbil.getName()); + } else { + if (comboAbil.getComboType() instanceof ComboAbility) { + ((ComboAbility) comboAbil.getComboType()).createNewComboInstance(player); + return; + } + } + } + + /** + * Adds an {@link AbilityInformation} to the player's + * {@link ComboManager#RECENTLY_USED recentlyUsedAbilities}. + * + * @param player The player to add the AbilityInformation for + * @param info The AbilityInformation to add + */ + public static void addRecentAbility(Player player, AbilityInformation info) { + ArrayList list; + String name = player.getName(); + if (RECENTLY_USED.containsKey(name)) { + list = RECENTLY_USED.get(name); + } else { + list = new ArrayList(); + } + list.add(info); + RECENTLY_USED.put(name, list); + //Bukkit.broadcastMessage("recentlyUsedAbilities: " + recentlyUsedAbilities.get(name).size()); + } + + /** + * Checks if a Player's {@link ComboManager#RECENTLY_USED + * recentlyUsedAbilities} contains a valid set of moves to perform any + * combos. If it does, it returns the valid combo. + * + * @param player The player for whom to check if a valid combo has been + * performed + * @return The ComboAbility of the combo that has been performed, or null if + * no valid combo was found + */ + public static ComboAbilityInfo checkForValidCombo(Player player) { + ArrayList playerCombo = getRecentlyUsedAbilities(player, 8); + for (String ability : COMBO_ABILITIES.keySet()) { + ComboAbilityInfo customAbility = COMBO_ABILITIES.get(ability); + ArrayList abilityCombo = customAbility.getAbilities(); + int size = abilityCombo.size(); + + if (playerCombo.size() < size) { + continue; + } + + boolean isValid = true; + for (int i = 1; i <= size; i++) { + if (!playerCombo.get(playerCombo.size() - i).equalsWithoutTime(abilityCombo.get(abilityCombo.size() - i))) { + isValid = false; + break; + } + } + if (isValid) { + return customAbility; + } + } + return null; + } + + public static void cleanupOldCombos() { + RECENTLY_USED.clear(); + } + + /** + * Gets the player's most recently used abilities, up to a maximum of 10. + * + * @param player The player to get recent abilities for + * @param amount The amount of recent abilities to get, starting from most + * recent and getting older + * @return An ArrayList<{@link AbilityInformation}> of the player's recently + * used abilities + */ + public static ArrayList getRecentlyUsedAbilities(Player player, int amount) { + String name = player.getName(); + if (!RECENTLY_USED.containsKey(name)) { + return new ArrayList(); + } + + ArrayList list = RECENTLY_USED.get(name); + if (list.size() < amount) { + return new ArrayList(list); + } + + ArrayList tempList = new ArrayList(); + for (int i = 0; i < amount; i++) { + tempList.add(0, list.get(list.size() - 1 - i)); + } + return tempList; + } + + /** + * Gets all of the combos for a given element. + * + * @param element The element to get combos for + * @return An ArrayList of the combos for that element + */ + public static ArrayList getCombosForElement(Element element) { + ArrayList list = new ArrayList(); + for (String comboab : DESCRIPTIONS.keySet()) { + CoreAbility coreAbil = CoreAbility.getAbility(COMBO_ABILITIES.get(comboab).getAbilities().get(0).getAbilityName()); + if (coreAbil != null && coreAbil.getElement() == element) { + list.add(comboab); + } + } + Collections.sort(list); + return list; + } + + public static void startCleanupTask() { + new BukkitRunnable() { + @Override + public void run() { + cleanupOldCombos(); + } + }.runTaskTimer(ProjectKorra.plugin, 0, CLEANUP_DELAY); + } + + public static long getCleanupDelay() { + return CLEANUP_DELAY; + } + + public static HashMap getComboAbilities() { + return COMBO_ABILITIES; + } + + public static HashMap getAuthors() { + return AUTHORS; + } + + public static HashMap getDescriptions() { + return DESCRIPTIONS; + } + + public static HashMap getInstructions() { + return INSTRUCTIONS; + } + + + + /** + * Contains information on an ability used in a combo. + * + * @author kingbirdy + * + */ + public static class AbilityInformation { + private String abilityName; + private ClickType clickType; + private long time; + + public AbilityInformation(String name, ClickType type) { + this(name, type, 0); + } + + public AbilityInformation(String name, ClickType type, long time) { + this.abilityName = name; + this.clickType = type; + this.time = time; + } + + /** + * Compares if two {@link AbilityInformation}'s are equal without + * respect to {@link AbilityInformation#time time}. + * + * @param info The AbilityInformation to compare against + * @return True if they are equal without respect to time + */ + public boolean equalsWithoutTime(AbilityInformation info) { + return this.getAbilityName().equals(info.getAbilityName()) && this.getClickType().equals(info.getClickType()); + } + + /** + * Gets the name of the ability. + * + * @return The name of the ability. + */ + public String getAbilityName() { + return abilityName; + } + + /** + * Gets the {@link ClickType} of the {@link AbilityInformation}. + * + * @return The ClickType + */ + public ClickType getClickType() { + return clickType; + } + + public long getTime() { + return time; + } + + public void setAbilityName(String abilityName) { + this.abilityName = abilityName; + } + + public void setClickType(ClickType clickType) { + this.clickType = clickType; + } + + public void setTime(long time) { + this.time = time; + } + + @Override + public String toString() { + return abilityName + " " + clickType + " " + time; + } + } + + public static class ComboAbilityInfo { + private String name; + private ArrayList abilities; + private Object comboType; + + public ComboAbilityInfo(String name, ArrayList abilities, Object comboType) { + this.name = name; + this.abilities = abilities; + this.comboType = comboType; + } + + public ArrayList getAbilities() { + return abilities; + } + + public Object getComboType() { + return comboType; + } + + public String getName() { + return name; + } + + public void setAbilities(ArrayList abilities) { + this.abilities = abilities; + } + + public void setComboType(Object comboType) { + this.comboType = comboType; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } + } +} diff --git a/src/com/projectkorra/projectkorra/ability/multiability/MultiAbilityManager.java b/src/com/projectkorra/projectkorra/ability/util/MultiAbilityManager.java similarity index 65% rename from src/com/projectkorra/projectkorra/ability/multiability/MultiAbilityManager.java rename to src/com/projectkorra/projectkorra/ability/util/MultiAbilityManager.java index 04351430..26ba654c 100644 --- a/src/com/projectkorra/projectkorra/ability/multiability/MultiAbilityManager.java +++ b/src/com/projectkorra/projectkorra/ability/util/MultiAbilityManager.java @@ -1,315 +1,286 @@ -package com.projectkorra.projectkorra.ability.multiability; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.SubElement; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.chiblocking.ChiMethods; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.firebending.FireMethods; -import com.projectkorra.projectkorra.waterbending.WaterMethods; - -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -public class MultiAbilityManager { - - public static ConcurrentHashMap> playerAbilities = new ConcurrentHashMap<>(); - public static ConcurrentHashMap playerSlot = new ConcurrentHashMap<>(); - public static ConcurrentHashMap playerBoundAbility = new ConcurrentHashMap<>(); - public static ArrayList multiAbilityList = new ArrayList(); - - public MultiAbilityManager() { - ArrayList waterArms = new ArrayList(); - waterArms.add(new MultiAbilitySub("Pull", Element.Water, null)); - waterArms.add(new MultiAbilitySub("Punch", Element.Water, null)); - waterArms.add(new MultiAbilitySub("Grapple", Element.Water, null)); - waterArms.add(new MultiAbilitySub("Grab", Element.Water, null)); - waterArms.add(new MultiAbilitySub("Freeze", Element.Water, SubElement.Icebending)); - waterArms.add(new MultiAbilitySub("Spear", Element.Water, SubElement.Icebending)); - multiAbilityList.add(new MultiAbility("WaterArms", waterArms)); - manage(); - } - - /** - * Sets up a player's binds for a MultiAbility. - * - * @param player - * @param multiAbility - */ - public static void bindMultiAbility(Player player, String multiAbility) { - if (playerAbilities.containsKey(player)) - unbindMultiAbility(player); - playerSlot.put(player, player.getInventory().getHeldItemSlot()); - playerBoundAbility.put(player, multiAbility); - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - HashMap currAbilities = new HashMap(); - for (int i : bPlayer.getAbilities().keySet()) { - currAbilities.put(i, bPlayer.getAbilities().get(i)); - } - playerAbilities.put(player, currAbilities); - - List modes = getMultiAbility(multiAbility).getAbilities(); - - bPlayer.getAbilities().clear(); - for (int i = 0; i < modes.size(); i++) { - if (!player.hasPermission("bending.ability." + multiAbility + "." + modes.get(i).getName())) { - bPlayer.getAbilities().put(i + 1, new StringBuilder().append(modes.get(i).getAbilityColor()).append(ChatColor.STRIKETHROUGH).append(modes.get(i).getName()).toString()); - } else { - bPlayer.getAbilities().put(i + 1, modes.get(i).getAbilityColor() + modes.get(i).getName()); - } - } - - if (player.isOnline()) { - bPlayer.addCooldown("MAM_Setup", 1L); // Support for bending - // scoreboards. - player.getInventory().setHeldItemSlot(0); - } - } - - /** - * Returns the MultiAbility the player has bound. Returns null if no - * multiability is bound and active. - * - * @param player The player to use - * @return name of multi ability bounded - */ - public static String getBoundMultiAbility(Player player) { - if (playerBoundAbility.containsKey(player)) - return playerBoundAbility.get(player); - return null; - } - - /** - * Returns a MultiAbility based on name. - * - * @param multiAbility Name of the multiability - * @return the multiability object or null - */ - public static MultiAbility getMultiAbility(String multiAbility) { - for (MultiAbility ma : multiAbilityList) { - if (ma.getName().equalsIgnoreCase(multiAbility)) - return ma; - } - return null; - } - - /** - * Returns a boolean based on whether a player has a MultiAbility active. - * - * @param player The player to check - * @return true If player has a multiability active - */ - public static boolean hasMultiAbilityBound(Player player) { - if (playerAbilities.containsKey(player)) - return true; - return false; - } - - /** - * MultiAbility equivalent of {@link GeneralMethods#getBoundAbility(Player)}. Returns a - * boolean based on whether a player has a specific MultiAbility active. - * - * @param player The player to check - * @param multiAbility The multiability name - * @return true If player has the specified multiability active - */ - public static boolean hasMultiAbilityBound(Player player, String multiAbility) { - if (playerAbilities.containsKey(player)) { - if (!playerBoundAbility.get(player).equals(multiAbility) && GeneralMethods.getBoundAbility(player) != null) - return false; - return true; - } - return false; - } - - public static void manage() { - new BukkitRunnable() { - public void run() { - scrollHotBarSlots(); - } - }.runTaskTimer(ProjectKorra.plugin, 0, 1); - } - - /** - * Clears all MultiAbility data for a player. Called on player quit event. - * - * @param player - */ - public static void remove(Player player) { - playerAbilities.remove(player); - playerBoundAbility.remove(player); - playerSlot.remove(player); - } - - /** - * Cleans up all MultiAbilities. - */ - public static void removeAll() { - List abilities = MultiAbilityModuleManager.multiAbility; - for (MultiAbilityModule mam : abilities) - mam.stop(); - - playerAbilities.clear(); - playerSlot.clear(); - playerBoundAbility.clear(); - } - - /** - * Keeps track of the player's selected slot while a MultiAbility is active. - */ - public static void scrollHotBarSlots() { - if (!playerAbilities.isEmpty()) { - for (Player player : playerAbilities.keySet()) { - if (playerBoundAbility.containsKey(player)) { - if (GeneralMethods.getBoundAbility(player) == null) { - if (multiAbilityList.contains(getMultiAbility(playerBoundAbility.get(player)))) { - if (player.getInventory().getHeldItemSlot() > getMultiAbility(playerBoundAbility.get(player)).getAbilities().size()) { - player.getInventory().setHeldItemSlot(getMultiAbility(playerBoundAbility.get(player)).getAbilities().size() - 1); - } else { - player.getInventory().setHeldItemSlot(0); - } - } - } - } - } - } - } - - /** - * Reverts a player's binds to a previous state before use of a - * MultiAbility. - * - * @param player - */ - public static void unbindMultiAbility(Player player) { - if (playerAbilities.containsKey(player)) { - HashMap prevBinds = playerAbilities.get(player); - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - int lastNonNull = -1; - for (int i = 1; i < 10; i++) { - if (prevBinds.get(i) != null) - lastNonNull = i; - bPlayer.getAbilities().put(i, prevBinds.get(i)); - } - if (lastNonNull > -1) - GeneralMethods.saveAbility(bPlayer, lastNonNull, prevBinds.get(lastNonNull)); - - if (player.isOnline()) - bPlayer.addCooldown("MAM_Setup", 1L); // Support for bending - // scoreboards. - playerAbilities.remove(player); - } - - if (playerSlot.containsKey(player)) { - if (player.isOnline()) - player.getInventory().setHeldItemSlot(playerSlot.get(player)); - playerSlot.remove(player); - } else { - if (player.isOnline()) - player.getInventory().setHeldItemSlot(0); - } - - if (playerBoundAbility.containsKey(player)) - playerBoundAbility.remove(player); - } - - /** - * MultiAbility class. Manages each MultiAbility's sub abilities. - * - */ - public static class MultiAbility { - private String name; - private ArrayList abilities; - - public MultiAbility(String name, ArrayList abilities) { - this.name = name; - this.abilities = abilities; - } - - public ArrayList getAbilities() { - return abilities; - } - - public String getName() { - return name; - } - - public void setAbilities(ArrayList abilities) { - this.abilities = abilities; - } - - public void setName(String name) { - this.name = name; - } - } - - public static class MultiAbilitySub { - private String name; - private Element element; - private SubElement sub; - - public MultiAbilitySub(String name, Element element, SubElement sub) { - this.name = name; - this.element = element; - this.sub = sub; - } - - public Element getElement() { - return element; - } - - public String getName() { - return name; - } - - public SubElement getSubElement() { - return sub; - } - - public void setElement(Element element) { - this.element = element; - } - - public void setName(String name) { - this.name = name; - } - - public void setSubElement(SubElement sub) { - this.sub = sub; - } - - public ChatColor getAbilityColor() { - if (element == null) { - return GeneralMethods.getAvatarColor(); - } - if (sub == null) { - switch (element) { - case Air: - return AirMethods.getAirColor(); - case Water: - return WaterMethods.getWaterColor(); - case Fire: - return FireMethods.getFireColor(); - case Earth: - return EarthMethods.getEarthColor(); - case Chi: - return ChiMethods.getChiColor(); - default: - return GeneralMethods.getAvatarColor(); - } - } else { - return GeneralMethods.getSubBendingColor(element); - } - } - } - -} +package com.projectkorra.projectkorra.ability.util; + +import com.projectkorra.projectkorra.BendingPlayer; +import com.projectkorra.projectkorra.Element; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ProjectKorra; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +public class MultiAbilityManager { + + public static ConcurrentHashMap> playerAbilities = new ConcurrentHashMap<>(); + public static ConcurrentHashMap playerSlot = new ConcurrentHashMap<>(); + public static ConcurrentHashMap playerBoundAbility = new ConcurrentHashMap<>(); + public static ArrayList multiAbilityList = new ArrayList(); + + public MultiAbilityManager() { + ArrayList waterArms = new ArrayList(); + waterArms.add(new MultiAbilityInfoSub("Pull", Element.WATER)); + waterArms.add(new MultiAbilityInfoSub("Punch", Element.WATER)); + waterArms.add(new MultiAbilityInfoSub("Grapple", Element.WATER)); + waterArms.add(new MultiAbilityInfoSub("Grab", Element.WATER)); + waterArms.add(new MultiAbilityInfoSub("Freeze", Element.ICE)); + waterArms.add(new MultiAbilityInfoSub("Spear", Element.ICE)); + multiAbilityList.add(new MultiAbilityInfo("WaterArms", waterArms)); + manage(); + } + + /** + * Sets up a player's binds for a MultiAbility. + * + * @param player + * @param multiAbility + */ + public static void bindMultiAbility(Player player, String multiAbility) { + if (playerAbilities.containsKey(player)) + unbindMultiAbility(player); + playerSlot.put(player, player.getInventory().getHeldItemSlot()); + playerBoundAbility.put(player, multiAbility); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + HashMap currAbilities = new HashMap(); + for (int i : bPlayer.getAbilities().keySet()) { + currAbilities.put(i, bPlayer.getAbilities().get(i)); + } + playerAbilities.put(player, currAbilities); + + List modes = getMultiAbility(multiAbility).getAbilities(); + + bPlayer.getAbilities().clear(); + for (int i = 0; i < modes.size(); i++) { + if (!player.hasPermission("bending.ability." + multiAbility + "." + modes.get(i).getName())) { + bPlayer.getAbilities().put(i + 1, new StringBuilder().append(modes.get(i).getAbilityColor()).append(ChatColor.STRIKETHROUGH).append(modes.get(i).getName()).toString()); + } else { + bPlayer.getAbilities().put(i + 1, modes.get(i).getAbilityColor() + modes.get(i).getName()); + } + } + + if (player.isOnline()) { + bPlayer.addCooldown("MAM_Setup", 1L); // Support for bending + // scoreboards. + player.getInventory().setHeldItemSlot(0); + } + } + + /** + * Returns the MultiAbility the player has bound. Returns null if no + * multiability is bound and active. + * + * @param player The player to use + * @return name of multi ability bounded + */ + public static String getBoundMultiAbility(Player player) { + if (playerBoundAbility.containsKey(player)) + return playerBoundAbility.get(player); + return null; + } + + /** + * Returns a MultiAbility based on name. + * + * @param multiAbility Name of the multiability + * @return the multiability object or null + */ + public static MultiAbilityInfo getMultiAbility(String multiAbility) { + for (MultiAbilityInfo ma : multiAbilityList) { + if (ma.getName().equalsIgnoreCase(multiAbility)) + return ma; + } + return null; + } + + /** + * Returns a boolean based on whether a player has a MultiAbility active. + * + * @param player The player to check + * @return true If player has a multiability active + */ + public static boolean hasMultiAbilityBound(Player player) { + if (playerAbilities.containsKey(player)) + return true; + return false; + } + + /** + * MultiAbility equivalent of {@link GeneralMethods#getBoundAbility(Player)}. Returns a + * boolean based on whether a player has a specific MultiAbility active. + * + * @param player The player to check + * @param multiAbility The multiability name + * @return true If player has the specified multiability active + */ + public static boolean hasMultiAbilityBound(Player player, String multiAbility) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + return false; + } + + if (playerAbilities.containsKey(player)) { + if (!playerBoundAbility.get(player).equals(multiAbility) && bPlayer.getBoundAbility() != null) + return false; + return true; + } + return false; + } + + public static void manage() { + new BukkitRunnable() { + public void run() { + scrollHotBarSlots(); + } + }.runTaskTimer(ProjectKorra.plugin, 0, 1); + } + + /** + * Clears all MultiAbility data for a player. Called on player quit event. + * + * @param player + */ + public static void remove(Player player) { + playerAbilities.remove(player); + playerBoundAbility.remove(player); + playerSlot.remove(player); + } + + /** + * Cleans up all MultiAbilities. + */ + public static void removeAll() { + playerAbilities.clear(); + playerSlot.clear(); + playerBoundAbility.clear(); + } + + /** + * Keeps track of the player's selected slot while a MultiAbility is active. + */ + public static void scrollHotBarSlots() { + if (!playerAbilities.isEmpty()) { + for (Player player : playerAbilities.keySet()) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + continue; + } + if (playerBoundAbility.containsKey(player)) { + if (bPlayer.getBoundAbility() == null) { + if (multiAbilityList.contains(getMultiAbility(playerBoundAbility.get(player)))) { + if (player.getInventory().getHeldItemSlot() >= getMultiAbility(playerBoundAbility.get(player)).getAbilities().size()) { + player.getInventory().setHeldItemSlot(getMultiAbility(playerBoundAbility.get(player)).getAbilities().size() - 1); + } + } + } + } + } + } + } + + /** + * Reverts a player's binds to a previous state before use of a + * MultiAbility. + * + * @param player + */ + public static void unbindMultiAbility(Player player) { + if (playerAbilities.containsKey(player)) { + HashMap prevBinds = playerAbilities.get(player); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + return; + } + + int lastNonNull = -1; + for (int i = 1; i < 10; i++) { + if (prevBinds.get(i) != null) + lastNonNull = i; + bPlayer.getAbilities().put(i, prevBinds.get(i)); + } + if (lastNonNull > -1) + GeneralMethods.saveAbility(bPlayer, lastNonNull, prevBinds.get(lastNonNull)); + + if (player.isOnline()) + bPlayer.addCooldown("MAM_Setup", 1L); // Support for bending + // scoreboards. + playerAbilities.remove(player); + } + + if (playerSlot.containsKey(player)) { + if (player.isOnline()) + player.getInventory().setHeldItemSlot(playerSlot.get(player)); + playerSlot.remove(player); + } else { + if (player.isOnline()) + player.getInventory().setHeldItemSlot(0); + } + + if (playerBoundAbility.containsKey(player)) + playerBoundAbility.remove(player); + } + + /** + * MultiAbility class. Manages each MultiAbility's sub abilities. + * + */ + public static class MultiAbilityInfo { + private String name; + private ArrayList abilities; + + public MultiAbilityInfo(String name, ArrayList abilities) { + this.name = name; + this.abilities = abilities; + } + + public ArrayList getAbilities() { + return abilities; + } + + public String getName() { + return name; + } + + public void setAbilities(ArrayList abilities) { + this.abilities = abilities; + } + + public void setName(String name) { + this.name = name; + } + } + + public static class MultiAbilityInfoSub { + private String name; + private Element element; + + public MultiAbilityInfoSub(String name, Element element) { + this.name = name; + this.element = element; + } + + public Element getElement() { + return element; + } + + public String getName() { + return name; + } + + public void setElement(Element element) { + this.element = element; + } + + public void setName(String name) { + this.name = name; + } + + public ChatColor getAbilityColor() { + return element != null ? element.getColor() : null; + } + } + +} diff --git a/src/com/projectkorra/projectkorra/airbending/AirBlast.java b/src/com/projectkorra/projectkorra/airbending/AirBlast.java index 6c05c571..ca397ea3 100644 --- a/src/com/projectkorra/projectkorra/airbending/AirBlast.java +++ b/src/com/projectkorra/projectkorra/airbending/AirBlast.java @@ -4,9 +4,10 @@ import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.Element; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; import com.projectkorra.projectkorra.command.Commands; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; import com.projectkorra.projectkorra.object.HorizontalVelocityTracker; import com.projectkorra.projectkorra.util.Flight; @@ -27,191 +28,184 @@ import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.Arrays; +import java.util.Random; import java.util.concurrent.ConcurrentHashMap; -public class AirBlast implements ConfigLoadable { - - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static ConcurrentHashMap origins = new ConcurrentHashMap(); +public class AirBlast extends AirAbility { - public static double speed = config.get().getDouble("Abilities.Air.AirBlast.Speed"); - public static double defaultrange = config.get().getDouble("Abilities.Air.AirBlast.Range"); - public static double affectingradius = config.get().getDouble("Abilities.Air.AirBlast.Radius"); - public static double defaultpushfactor = config.get().getDouble("Abilities.Air.AirBlast.Push.Entities"); - public static double otherpushfactor = config.get().getDouble("Abilities.Air.AirBlast.Push.Self"); + private static final int MAX_TICKS = 10000; + private static final int ORIGIN_PARTICLE_COUNT = 4; + private static final double ORIGIN_SELECT_RANGE = 10; + private static final ConcurrentHashMap ORIGINS = new ConcurrentHashMap<>(); - public static boolean flickLevers = config.get().getBoolean("Abilities.Air.AirBlast.CanFlickLevers"); - public static boolean openDoors = config.get().getBoolean("Abilities.Air.AirBlast.CanOpenDoors"); - public static boolean pressButtons = config.get().getBoolean("Abilities.Air.AirBlast.CanPressButtons"); - public static boolean coolLava = config.get().getBoolean("Abilities.Air.AirBlast.CanCoolLava"); - - private static double originselectrange = 10; - private static int idCounter = 0; - private static final int maxticks = 10000; - /* Package visible variables */ - static double maxspeed = 1. / defaultpushfactor; - /* End Package visible variables */ - - // public static long interval = 2000; - public static byte full = 0x0; - - Location location; + private boolean canFlickLevers; + private boolean canOpenDoors; + private boolean canPressButtons; + private boolean canCoolLava; + private boolean isFromOtherOrigin; + private boolean showParticles; + private int ticks; + private int particleCount; + private long cooldown; + private double speedFactor; + private double range; + private double pushFactor; + private double pushFactorForOthers; + private double damage; + private double speed; + private double radius; + private Location location; private Location origin; private Vector direction; - private Player player; - private double speedfactor; - private double range = defaultrange; - private double pushfactor = defaultpushfactor; - private double damage = 0; - - private boolean otherorigin = false; - private boolean showParticles = true; - private int ticks = 0; - private int id = 0; - - private ArrayList affectedlevers = new ArrayList(); - private ArrayList affectedentities = new ArrayList(); - - private AirBurst source = null; - - public AirBlast(Location location, Vector direction, Player player, double factorpush, AirBurst burst) { - if (location.getBlock().isLiquid()) { - return; - } - source = burst; - - this.player = player; - origin = location.clone(); - this.direction = direction.clone(); - this.location = location.clone(); - pushfactor *= factorpush; - instances.put(idCounter, this); - this.id = idCounter; - idCounter = (idCounter + 1) % Integer.MAX_VALUE; - } + private AirBurst source; + private Random random; + private ArrayList affectedLevers; + private ArrayList affectedEntities; public AirBlast(Player player) { - /* Initial Checks */ - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("AirBlast")) + super(player); + if (bPlayer.isOnCooldown(this)) { return; - if (player.getEyeLocation().getBlock().isLiquid()) { + } else if (player.getEyeLocation().getBlock().isLiquid()) { return; } - /* End Initial Checks */ - // reloadVariables(); - this.player = player; - if (origins.containsKey(player)) { - otherorigin = true; - origin = origins.get(player); - origins.remove(player); - Entity entity = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); + + setFields(); + + if (ORIGINS.containsKey(player)) { + Entity entity = GeneralMethods.getTargetedEntity(player, range); + this.isFromOtherOrigin = true; + this.origin = ORIGINS.get(player); + ORIGINS.remove(player); + if (entity != null) { - direction = GeneralMethods.getDirection(origin, entity.getLocation()).normalize(); + this.direction = GeneralMethods.getDirection(origin, entity.getLocation()).normalize(); } else { - direction = GeneralMethods.getDirection(origin, GeneralMethods.getTargetedLocation(player, range)).normalize(); + this.direction = GeneralMethods.getDirection(origin, GeneralMethods.getTargetedLocation(player, range)) .normalize(); } } else { origin = player.getEyeLocation(); direction = player.getEyeLocation().getDirection().normalize(); } - location = origin.clone(); - instances.put(idCounter, this); - this.id = idCounter; - idCounter = (idCounter + 1) % Integer.MAX_VALUE; - bPlayer.addCooldown("AirBlast", GeneralMethods.getGlobalCooldown()); - // time = System.currentTimeMillis(); - // timers.put(player, System.currentTimeMillis()); + this.location = origin.clone(); + bPlayer.addCooldown(this); + start(); + } + + public AirBlast(Player player, Location location, Vector direction, double modifiedPushFactor, AirBurst burst) { + super(player); + if (location.getBlock().isLiquid()) { + return; + } + this.source = burst; + this.origin = location.clone(); + this.direction = direction.clone(); + this.location = location.clone(); + + setFields(); + this.pushFactor *= modifiedPushFactor; + this.affectedLevers = new ArrayList<>(); + this.affectedEntities = new ArrayList<>(); + start(); + } + + private void setFields() { + this.range = getConfig().getDouble("Abilities.Air.AirBlast.Range"); + this.speed = getConfig().getDouble("Abilities.Air.AirBlast.Speed"); + this.range = getConfig().getDouble("Abilities.Air.AirBlast.Range"); + this.radius = getConfig().getDouble("Abilities.Air.AirBlast.Radius"); + this.pushFactor = getConfig().getDouble("Abilities.Air.AirBlast.Push.Entities"); + this.pushFactorForOthers = getConfig().getDouble("Abilities.Air.AirBlast.Push.Self"); + this.canFlickLevers = getConfig().getBoolean("Abilities.Air.AirBlast.CanFlickLevers"); + this.canOpenDoors = getConfig().getBoolean("Abilities.Air.AirBlast.CanOpenDoors"); + this.canPressButtons = getConfig().getBoolean("Abilities.Air.AirBlast.CanPressButtons"); + this.canCoolLava = getConfig().getBoolean("Abilities.Air.AirBlast.CanCoolLava"); + + this.particleCount = 6; + this.cooldown = GeneralMethods.getGlobalCooldown(); + this.isFromOtherOrigin = false; + this.showParticles = true; + this.random = new Random(); + this.affectedLevers = new ArrayList<>(); + this.affectedEntities = new ArrayList<>(); } private static void playOriginEffect(Player player) { - if (!origins.containsKey(player)) - return; - Location origin = origins.get(player); - if (player.isDead() || !player.isOnline()) - return; - - if (!origin.getWorld().equals(player.getWorld())) { - origins.remove(player); + if (!ORIGINS.containsKey(player)) { return; } - if (GeneralMethods.getBoundAbility(player) == null) { - origins.remove(player); + Location origin = ORIGINS.get(player); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null || player.isDead() || !player.isOnline()) { + return; + } else if (!origin.getWorld().equals(player.getWorld())) { + ORIGINS.remove(player); + return; + } else if (!bPlayer.canBendIgnoreCooldowns(getAbility("AirBlast"))) { + ORIGINS.remove(player); + return; + } else if (origin.distanceSquared(player.getEyeLocation()) > ORIGIN_SELECT_RANGE * ORIGIN_SELECT_RANGE) { + ORIGINS.remove(player); return; } - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirBlast") - || !GeneralMethods.canBend(player.getName(), "AirBlast")) { - origins.remove(player); - return; - } - - if (origin.distance(player.getEyeLocation()) > originselectrange) { - origins.remove(player); - return; - } - - AirMethods.playAirbendingParticles(origin, 4); - // origin.getWorld().playEffect(origin, Effect.SMOKE, 4, - // (int) originselectrange); + playAirbendingParticles(origin, ORIGIN_PARTICLE_COUNT); } - public static void progressAll() { - for (AirBlast blast : instances.values()) { - blast.progress(); - } - for (Player player : origins.keySet()) { + public static void progressOrigins() { + for (Player player : ORIGINS.keySet()) { playOriginEffect(player); } } public static void setOrigin(Player player) { - Location location = GeneralMethods.getTargetedLocation(player, originselectrange, GeneralMethods.nonOpaque); - if (location.getBlock().isLiquid() || GeneralMethods.isSolid(location.getBlock())) + Location location = GeneralMethods.getTargetedLocation(player, ORIGIN_SELECT_RANGE, GeneralMethods.NON_OPAQUE); + if (location.getBlock().isLiquid() || GeneralMethods.isSolid(location.getBlock())) { return; - - if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", location)) + } else if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", location)) { return; + } - if (origins.containsKey(player)) { - origins.replace(player, location); + if (ORIGINS.containsKey(player)) { + ORIGINS.replace(player, location); } else { - origins.put(player, location); + ORIGINS.put(player, location); } } private void advanceLocation() { - if (showParticles) - AirMethods.playAirbendingParticles(location, 6, 0.275F, 0.275F, 0.275F); - if (GeneralMethods.rand.nextInt(4) == 0) { - AirMethods.playAirbendingSound(location); + if (showParticles) { + playAirbendingParticles(location, particleCount, 0.275F, 0.275F, 0.275F); } - location = location.add(direction.clone().multiply(speedfactor)); + if (random.nextInt(4) == 0) { + playAirbendingSound(location); + } + location = location.add(direction.clone().multiply(speedFactor)); } private void affect(Entity entity) { boolean isUser = entity.getUniqueId() == player.getUniqueId(); - if (!isUser || otherorigin) { - pushfactor = otherpushfactor; + if (!isUser || isFromOtherOrigin) { + pushFactor = pushFactorForOthers; Vector velocity = entity.getVelocity(); - // double mag = Math.abs(velocity.getY()); - double max = maxspeed; - double factor = pushfactor; - if (AvatarState.isAvatarState(player)) { - max = AvatarState.getValue(maxspeed); + double max = speed / speedFactor; + double factor = pushFactor; + + if (bPlayer.isAvatarState()) { + max = AvatarState.getValue(max); factor = AvatarState.getValue(factor); } Vector push = direction.clone(); if (Math.abs(push.getY()) > max && !isUser) { - if (push.getY() < 0) + if (push.getY() < 0) { push.setY(-max); - else + } else { push.setY(max); + } } factor *= 1 - location.distance(origin) / (2 * range); @@ -231,87 +225,72 @@ public class AirBlast implements ConfigLoadable { } if (entity instanceof Player) { - if (Commands.invincible.contains(((Player) entity).getName())) + if (Commands.invincible.contains(((Player) entity).getName())) { return; + } } - if (Double.isNaN(velocity.length())) + if (Double.isNaN(velocity.length())) { return; + } GeneralMethods.setVelocity(entity, velocity); - if (source != null) - new HorizontalVelocityTracker(entity, player, 200l, "AirBurst", Element.Air, null); - else - new HorizontalVelocityTracker(entity, player, 200l, "AirBlast", Element.Air, null); + if (source != null) { + new HorizontalVelocityTracker(entity, player, 200l, "AirBurst", Element.AIR); + } else { + new HorizontalVelocityTracker(entity, player, 200l, "AirBlast", Element.AIR); + } + entity.setFallDistance(0); if (!isUser && entity instanceof Player) { new Flight((Player) entity, player); } - if (entity.getFireTicks() > 0) + if (entity.getFireTicks() > 0) { entity.getWorld().playEffect(entity.getLocation(), Effect.EXTINGUISH, 0); - entity.setFireTicks(0); - AirMethods.breakBreathbendingHold(entity); + } - if (source != null && (this.damage > 0 && entity instanceof LivingEntity && !entity.equals(player) && !affectedentities.contains(entity))) { - GeneralMethods.damageEntity(player, entity, damage, "AirBurst"); - affectedentities.add(entity); - } else if (source == null && (damage > 0 && entity instanceof LivingEntity && !entity.equals(player) && !affectedentities.contains(entity))) { - GeneralMethods.damageEntity(player, entity, damage, "AirBlast"); - affectedentities.add(entity); + entity.setFireTicks(0); + breakBreathbendingHold(entity); + + if (damage > 0 && entity instanceof LivingEntity && !entity.equals(player) && !affectedEntities.contains(entity)) { + GeneralMethods.damageEntity(this, entity, damage); + affectedEntities.add(entity); } } } - public Player getPlayer() { - return player; - } - - public double getPushfactor() { - return pushfactor; - } - - public double getRange() { - return range; - } - - public boolean getShowParticles() { - return this.showParticles; - } - @SuppressWarnings("deprecation") - public boolean progress() { - // ProjectKorra.log.info("FireBlast id: " + getID()); + @Override + public void progress() { if (player.isDead() || !player.isOnline()) { remove(); - return false; - } - - if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", location)) { + return; + } else if (GeneralMethods.isRegionProtectedFromBuild(this, location)) { remove(); - return false; + return; } - speedfactor = speed * (ProjectKorra.time_step / 1000.); - + speedFactor = speed * (ProjectKorra.time_step / 1000.0); ticks++; - if (ticks > maxticks) { + if (ticks > MAX_TICKS) { remove(); - return false; + return; } + Block block = location.getBlock(); - for (Block testblock : GeneralMethods.getBlocksAroundPoint(location, affectingradius)) { + for (Block testblock : GeneralMethods.getBlocksAroundPoint(location, radius)) { if (testblock.getType() == Material.FIRE) { testblock.setType(Material.AIR); testblock.getWorld().playEffect(testblock.getLocation(), Effect.EXTINGUISH, 0); } - - if (GeneralMethods.isRegionProtectedFromBuild(getPlayer(), "AirBlast", block.getLocation())) + if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { continue; + } Material doorTypes[] = { Material.WOODEN_DOOR, Material.SPRUCE_DOOR, Material.BIRCH_DOOR, Material.JUNGLE_DOOR, Material.ACACIA_DOOR, Material.DARK_OAK_DOOR }; - if (Arrays.asList(doorTypes).contains(block.getType()) && openDoors) { + if (Arrays.asList(doorTypes).contains(block.getType()) && canOpenDoors) { if (block.getData() >= 8) { block = block.getRelative(BlockFace.DOWN); } @@ -324,21 +303,7 @@ public class AirBlast implements ConfigLoadable { block.getWorld().playSound(block.getLocation(), Sound.DOOR_OPEN, 10, 1); } } - if ((block.getType() == Material.LEVER) && !affectedlevers.contains(block) && flickLevers) { - // BlockState state = block.getState(); - // Lever lever = (Lever) (state.getData()); - // lever.setPowered(!lever.isPowered()); - // state.setData(lever); - // state.update(true, true); - // - // Block relative = block.getRelative(((Attachable) block - // .getState().getData()).getFacing(), -1); - // relative.getState().update(true, true); - // - // for (Block block2 : Methods.getBlocksAroundPoint( - // relative.getLocation(), 2)) - // block2.getState().update(true, true); - + if ((block.getType() == Material.LEVER) && !affectedLevers.contains(block) && canFlickLevers) { Lever lever = new Lever(Material.LEVER, block.getData()); lever.setPowered(!lever.isPowered()); block.setData(lever.getData()); @@ -351,11 +316,8 @@ public class AirBlast implements ConfigLoadable { supportState.update(true, false); initialSupportState.update(true); } - - affectedlevers.add(block); - - } else if ((block.getType() == Material.STONE_BUTTON) && !affectedlevers.contains(block) && pressButtons) { - + affectedLevers.add(block); + } else if ((block.getType() == Material.STONE_BUTTON) && !affectedLevers.contains(block) && canPressButtons) { final Button button = new Button(Material.STONE_BUTTON, block.getData()); button.setPowered(!button.isPowered()); block.setData(button.getData()); @@ -370,7 +332,6 @@ public class AirBlast implements ConfigLoadable { } final Block btBlock = block; - new BukkitRunnable() { public void run() { button.setPowered(!button.isPowered()); @@ -387,9 +348,8 @@ public class AirBlast implements ConfigLoadable { } }.runTaskLater(ProjectKorra.plugin, 10); - affectedlevers.add(block); - } else if ((block.getType() == Material.WOOD_BUTTON) && !affectedlevers.contains(block) && pressButtons) { - + affectedLevers.add(block); + } else if ((block.getType() == Material.WOOD_BUTTON) && !affectedLevers.contains(block) && canPressButtons) { final Button button = new Button(Material.WOOD_BUTTON, block.getData()); button.setPowered(!button.isPowered()); block.setData(button.getData()); @@ -421,19 +381,19 @@ public class AirBlast implements ConfigLoadable { } }.runTaskLater(ProjectKorra.plugin, 15); - affectedlevers.add(block); + affectedLevers.add(block); } } - if ((GeneralMethods.isSolid(block) || block.isLiquid()) && !affectedlevers.contains(block) && coolLava) { + if ((GeneralMethods.isSolid(block) || block.isLiquid()) && !affectedLevers.contains(block) && canCoolLava) { if (block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA) { - if (block.getData() == full) { + if (block.getData() == 0x0) { block.setType(Material.OBSIDIAN); } else { block.setType(Material.COBBLESTONE); } } remove(); - return false; + return; } /* @@ -444,70 +404,206 @@ public class AirBlast implements ConfigLoadable { double dist = location.distance(origin); if (Double.isNaN(dist) || dist > range) { remove(); - return false; + return; } - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, affectingradius)) { + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, radius)) { affect(entity); } advanceLocation(); - return true; + return; } public static boolean removeAirBlastsAroundPoint(Location location, double radius) { boolean removed = false; - for (AirBlast airBlast : instances.values()) { + for (AirBlast airBlast : CoreAbility.getAbilities(AirBlast.class)) { Location airBlastlocation = airBlast.location; if (location.getWorld() == airBlastlocation.getWorld()) { - if (location.distance(airBlastlocation) <= radius) + if (location.distanceSquared(airBlastlocation) <= radius * radius) { airBlast.remove(); + } removed = true; } } return removed; } - public void remove() { - instances.remove(id); - } - - public static void removeAll() { - for (AirBlast ability : instances.values()) { - ability.remove(); - } + @Override + public String getName() { + return "AirBlast"; } @Override - public void reloadVariables() { - speed = config.get().getDouble("Abilities.Air.AirBlast.Speed"); - defaultrange = config.get().getDouble("Abilities.Air.AirBlast.Range"); - affectingradius = config.get().getDouble("Abilities.Air.AirBlast.Radius"); - defaultpushfactor = config.get().getDouble("Abilities.Air.AirBlast.Push"); - - flickLevers = config.get().getBoolean("Abilities.Air.AirBlast.CanFlickLevers"); - openDoors = config.get().getBoolean("Abilities.Air.AirBlast.CanOpenDoors"); - pressButtons = config.get().getBoolean("Abilities.Air.AirBlast.CanPressButtons"); - coolLava = config.get().getBoolean("Abilities.Air.AirBlast.CanCoolLava"); - maxspeed = 1. / defaultpushfactor; - range = defaultrange; - pushfactor = defaultpushfactor; + public Location getLocation() { + return location; } - public void setDamage(double dmg) { - this.damage = dmg; + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; } - public void setPushfactor(double pushfactor) { - this.pushfactor = pushfactor; + @Override + public boolean isHarmlessAbility() { + return false; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public int getTicks() { + return ticks; + } + + public void setTicks(int ticks) { + this.ticks = ticks; + } + + public double getSpeedFactor() { + return speedFactor; + } + + public void setSpeedFactor(double speedFactor) { + this.speedFactor = speedFactor; + } + + public double getRange() { + return range; } public void setRange(double range) { this.range = range; } - public void setShowParticles(boolean show) { - this.showParticles = show; + public double getPushFactor() { + return pushFactor; + } + + public void setPushFactor(double pushFactor) { + this.pushFactor = pushFactor; + } + + public double getPushFactorForOthers() { + return pushFactorForOthers; + } + + public void setPushFactorForOthers(double pushFactorForOthers) { + this.pushFactorForOthers = pushFactorForOthers; + } + + public double getDamage() { + return damage; + } + + public void setDamage(double damage) { + this.damage = damage; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public boolean isCanFlickLevers() { + return canFlickLevers; + } + + public void setCanFlickLevers(boolean canFlickLevers) { + this.canFlickLevers = canFlickLevers; + } + + public boolean isCanOpenDoors() { + return canOpenDoors; + } + + public void setCanOpenDoors(boolean canOpenDoors) { + this.canOpenDoors = canOpenDoors; + } + + public boolean isCanPressButtons() { + return canPressButtons; + } + + public void setCanPressButtons(boolean canPressButtons) { + this.canPressButtons = canPressButtons; + } + + public boolean isCanCoolLava() { + return canCoolLava; + } + + public void setCanCoolLava(boolean canCoolLava) { + this.canCoolLava = canCoolLava; + } + + public boolean isFromOtherOrigin() { + return isFromOtherOrigin; + } + + public void setFromOtherOrigin(boolean isFromOtherOrigin) { + this.isFromOtherOrigin = isFromOtherOrigin; + } + + public boolean isShowParticles() { + return showParticles; + } + + public void setShowParticles(boolean showParticles) { + this.showParticles = showParticles; + } + + public AirBurst getSource() { + return source; + } + + public void setSource(AirBurst source) { + this.source = source; + } + + public ArrayList getAffectedLevers() { + return affectedLevers; + } + + public ArrayList getAffectedEntities() { + return affectedEntities; + } + + public void setLocation(Location location) { + this.location = location; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; } } diff --git a/src/com/projectkorra/projectkorra/airbending/AirBubble.java b/src/com/projectkorra/projectkorra/airbending/AirBubble.java index 86648f19..113815b0 100644 --- a/src/com/projectkorra/projectkorra/airbending/AirBubble.java +++ b/src/com/projectkorra/projectkorra/airbending/AirBubble.java @@ -1,42 +1,42 @@ package com.projectkorra.projectkorra.airbending; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.BendingPlayer; +import com.projectkorra.projectkorra.Element; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.waterbending.WaterManipulation; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.Server; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.entity.Player; -import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.waterbending.WaterManipulation; -import com.projectkorra.projectkorra.waterbending.WaterMethods; +import java.util.concurrent.ConcurrentHashMap; -public class AirBubble implements ConfigLoadable { - - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static double DEFAULT_AIR_RADIUS = config.get().getDouble("Abilities.Air.AirBubble.Radius"); - private static double DEFAULT_WATER_RADIUS = config.get().getDouble("Abilities.Water.WaterBubble.Radius"); +public class AirBubble extends AirAbility { - private Player player; + private boolean waterBubble; private double radius; - private double defaultAirRadius = DEFAULT_AIR_RADIUS; - private double defaultWaterRadius = DEFAULT_WATER_RADIUS; - private ConcurrentHashMap waterorigins; + private double airRadius; + private double waterRadius; + private ConcurrentHashMap waterOrigins; public AirBubble(Player player) { - // reloadVariables(); - this.player = player; - waterorigins = new ConcurrentHashMap(); - instances.put(player, this); + super(player); + + this.radius = 0; + this.airRadius = getConfig().getDouble("Abilities.Air.AirBubble.Radius"); + this.waterRadius = getConfig().getDouble("Abilities.Water.WaterBubble.Radius"); + this.waterOrigins = new ConcurrentHashMap<>(); + start(); } public static boolean canFlowTo(Block block) { - for (AirBubble airBubble : instances.values()) { + for (AirBubble airBubble : CoreAbility.getAbilities(AirBubble.class)) { if (airBubble.blockInBubble(block)) { return false; } @@ -44,167 +44,159 @@ public class AirBubble implements ConfigLoadable { return true; } - public static String getDescription() { - return "To use, the bender must merely have the ability selected." - + " All water around the user in a small bubble will vanish," - + " replacing itself once the user either gets too far away or selects a different ability."; - } - - public static void handleBubbles(Server server) { - for (Player player : server.getOnlinePlayers()) { - if (GeneralMethods.getBoundAbility(player) != null) { - if (GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirBubble") - || GeneralMethods.getBoundAbility(player).equalsIgnoreCase("WaterBubble")) { - if (!instances.containsKey(player) && player.isSneaking()) { - new AirBubble(player); + public static void handleBubbles() { + for (Player player : Bukkit.getServer().getOnlinePlayers()) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + continue; + } + + String name = bPlayer.getBoundAbilityName(); + if (name.equalsIgnoreCase("AirBubble") | name.equalsIgnoreCase("WaterBubble")) { + if (!CoreAbility.hasAbility(player, AirBubble.class) && player.isSneaking()) { + AirBubble airBubble = new AirBubble(player); + if (name.equalsIgnoreCase("WaterBubble")) { + airBubble.waterBubble = true; } } } } - - AirBubble.progressAll(); } public boolean blockInBubble(Block block) { if (block.getWorld() != player.getWorld()) { return false; - } - if (block.getLocation().distance(player.getLocation()) <= radius) { + } else if (block.getLocation().distanceSquared(player.getLocation()) <= radius * radius) { return true; } return false; } - public double getDefaultAirRadius() { - return defaultAirRadius; + @Override + public void progress() { + if (!player.isSneaking() || !bPlayer.canBend(this)) { + remove(); + return; + } else { + pushWater(); + } } - public double getDefaultWaterRadius() { - return defaultWaterRadius; + private void pushWater() { + if (bPlayer.hasElement(Element.AIR)) { + radius = airRadius; + } else { + radius = waterRadius; + } + + if (bPlayer.hasElement(Element.WATER) && isNight(player.getWorld())) { + radius = WaterAbility.getNightFactor(waterRadius, player.getWorld()); + } + if (airRadius > radius && bPlayer.hasElement(Element.AIR)) { + radius = airRadius; + } + + Location location = player.getLocation(); + + for (Block block : waterOrigins.keySet()) { + if (block.getWorld() != location.getWorld()) { + if (block.getType() == Material.AIR || isWater(block)) { + waterOrigins.get(block).update(true); + } + waterOrigins.remove(block); + } else if (block.getLocation().distanceSquared(location) > radius * radius) { + if (block.getType() == Material.AIR || isWater(block)) { + waterOrigins.get(block).update(true); + } + waterOrigins.remove(block); + } + } + + for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) { + if (waterOrigins.containsKey(block)) { + continue; + } else if (!isWater(block)) { + continue; + } else if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBubble", block.getLocation())) { + continue; + } else if (block.getType() == Material.STATIONARY_WATER || block.getType() == Material.WATER) { + if (WaterManipulation.canBubbleWater(block)) { + waterOrigins.put(block, block.getState()); + block.setType(Material.AIR); + } + } + } } - public Player getPlayer() { - return player; + @Override + public void remove() { + super.remove(); + for (Block block : waterOrigins.keySet()) { + if (block.getType() == Material.AIR || block.isLiquid()) { + waterOrigins.get(block).update(true); + } + } + } + + @Override + public String getName() { + return waterBubble ? "WaterBubble" : "AirBubble"; + } + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isWaterBubble() { + return waterBubble; + } + + public void setWaterBubble(boolean waterBubble) { + this.waterBubble = waterBubble; } public double getRadius() { return radius; } - public boolean progress() { - if (player.isDead() || !player.isOnline()) { - remove(); - return false; - } - - if (!player.isSneaking()) { - remove(); - return false; - } - if (GeneralMethods.getBoundAbility(player) != null) { - if (GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirBubble") - && GeneralMethods.canBend(player.getName(), "AirBubble")) { - pushWater(); - return false; - } - if (GeneralMethods.getBoundAbility(player).equalsIgnoreCase("WaterBubble") - && GeneralMethods.canBend(player.getName(), "WaterBubble")) { - pushWater(); - return false; - } - } - - remove(); - return true; - } - - private void pushWater() { - if (GeneralMethods.isBender(player.getName(), Element.Air)) { - radius = defaultAirRadius; - } else { - radius = defaultWaterRadius; - } - if (GeneralMethods.isBender(player.getName(), Element.Water) && WaterMethods.isNight(player.getWorld())) { - radius = WaterMethods.waterbendingNightAugment(defaultWaterRadius, player.getWorld()); - } - if (defaultAirRadius > radius && GeneralMethods.isBender(player.getName(), Element.Air)) - radius = defaultAirRadius; - Location location = player.getLocation(); - - for (Block block : waterorigins.keySet()) { - if (block.getWorld() != location.getWorld()) { - if (block.getType() == Material.AIR || WaterMethods.isWater(block)) - waterorigins.get(block).update(true); - waterorigins.remove(block); - } else if (block.getLocation().distance(location) > radius) { - if (block.getType() == Material.AIR || WaterMethods.isWater(block)) - waterorigins.get(block).update(true); - waterorigins.remove(block); - } - } - - for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) { - if (waterorigins.containsKey(block)) - continue; - if (!WaterMethods.isWater(block)) - continue; - if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBubble", block.getLocation())) - continue; - if (block.getType() == Material.STATIONARY_WATER || block.getType() == Material.WATER) { - if (WaterManipulation.canBubbleWater(block)) { - waterorigins.put(block, block.getState()); - block.setType(Material.AIR); - } - } - } - } - - public static void progressAll() { - for (AirBubble ability : instances.values()) { - ability.progress(); - } - } - - @Override - public void reloadVariables() { - DEFAULT_AIR_RADIUS = config.get().getDouble("Abilities.Air.AirBubble.Radius"); - DEFAULT_WATER_RADIUS = config.get().getDouble("Abilities.Water.WaterBubble.Radius"); - defaultAirRadius = DEFAULT_AIR_RADIUS; - defaultWaterRadius = DEFAULT_WATER_RADIUS; - } - - public void remove() { - for (Block block : waterorigins.keySet()) { - // byte data = waterorigins.get(block); - // byte data = 0x0; - // block = block.getLocation().getBlock(); - // if (block.getType() == Material.AIR) { - // block.setType(Material.WATER); - // block.setData(data); - // } - if (block.getType() == Material.AIR || block.isLiquid()) - waterorigins.get(block).update(true); - } - // instances.remove(uuid); - instances.remove(player); - } - - public static void removeAll() { - for (AirBubble ability : instances.values()) { - ability.remove(); - } - } - - public void setDefaultAirRadius(double defaultAirRadius) { - this.defaultAirRadius = defaultAirRadius; - } - - public void setDefaultWaterRadius(double defaultWaterRadius) { - this.defaultWaterRadius = defaultWaterRadius; - } - public void setRadius(double radius) { this.radius = radius; } + public double getAirRadius() { + return airRadius; + } + + public void setAirRadius(double airRadius) { + this.airRadius = airRadius; + } + + public double getWaterRadius() { + return waterRadius; + } + + public void setWaterRadius(double waterRadius) { + this.waterRadius = waterRadius; + } + + public ConcurrentHashMap getWaterOrigins() { + return waterOrigins; + } + } diff --git a/src/com/projectkorra/projectkorra/airbending/AirBurst.java b/src/com/projectkorra/projectkorra/airbending/AirBurst.java index f7a64eb9..53c3590c 100644 --- a/src/com/projectkorra/projectkorra/airbending/AirBurst.java +++ b/src/com/projectkorra/projectkorra/airbending/AirBurst.java @@ -1,7 +1,6 @@ package com.projectkorra.projectkorra.airbending; import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; import org.bukkit.Location; import org.bukkit.entity.Entity; @@ -9,87 +8,95 @@ import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; -public class AirBurst implements ConfigLoadable { +public class AirBurst extends AirAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); + private static final int CHARGED_SNEAK_PARTICLES = 10; + private static final double PARTICLES_PERCENTAGE = 50; - private static double PARTICLES_PERCENTAGE = 50; - - private static double threshold = config.get().getDouble("Abilities.Air.AirBurst.FallThreshold"); - private static double pushfactor = config.get().getDouble("Abilities.Air.AirBurst.PushFactor"); - private static double damage = config.get().getDouble("Abilities.Air.AirBurst.Damage"); - private static double deltheta = 10; - private static double delphi = 10; + private boolean isCharged; + private boolean isFallBurst; + private float playerFallDistance; + private long chargeTime; + private double fallThreshold; + private double pushFactor; + private double damage; + private double blastAngleTheta; + private double blastAnglePhi; + private ArrayList blasts; + private ArrayList affectedEntities; - private static long cooldown = config.get().getLong("Abilities.Air.AirBurst.Cooldown"); - - private Player player; - private long starttime; - private long chargetime = config.get().getLong("Abilities.Air.AirBurst.ChargeTime"); - private boolean charged = false; - private ArrayList blasts = new ArrayList(); - private ArrayList affectedentities = new ArrayList(); + public AirBurst(Player player, boolean isFallBurst) { + super(player); + if (bPlayer.isOnCooldown(this)) { + remove(); + return; + } - public AirBurst() { - // reloadVariables(); + this.isFallBurst = isFallBurst; + this.isCharged = false; + this.blastAnglePhi = 10; + this.blastAngleTheta = 10; + this.playerFallDistance = player.getFallDistance(); + this.chargeTime = getConfig().getLong("Abilities.Air.AirBurst.ChargeTime"); + this.fallThreshold = getConfig().getDouble("Abilities.Air.AirBurst.FallThreshold"); + this.pushFactor = getConfig().getDouble("Abilities.Air.AirBurst.PushFactor"); + this.damage = getConfig().getDouble("Abilities.Air.AirBurst.Damage"); + this.blasts = new ArrayList<>(); + this.affectedEntities = new ArrayList<>(); + + if (bPlayer.isAvatarState()) { + this.chargeTime = 0; + this.damage = AvatarState.getValue(this.damage); + } + start(); } - public AirBurst(Player player) { - /* Initial Checks */ - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("AirBurst")) + @Override + public void progress() { + if (!bPlayer.canBendIgnoreCooldowns(this)) { + remove(); return; - if (instances.containsKey(player)) - return; - /* End Initial Checks */ - // reloadVariables(); - starttime = System.currentTimeMillis(); - if (AvatarState.isAvatarState(player)) - chargetime = 0; - this.player = player; - bPlayer.addCooldown("AirBurst", cooldown); - instances.put(player, this); - } + } - public static void coneBurst(Player player) { - if (instances.containsKey(player)) { - instances.get(player).coneBurst(); + if (isFallBurst) { + if (playerFallDistance >= fallThreshold) { + fallBurst(); + } + remove(); + return; + } + + if (System.currentTimeMillis() > startTime + chargeTime && !isCharged) { + isCharged = true; + } + + if (!player.isSneaking()) { + if (isCharged) { + sphereBurst(); + remove(); + return; + } else { + remove(); + return; + } + } else if (isCharged) { + Location location = player.getEyeLocation(); + playAirbendingParticles(location, CHARGED_SNEAK_PARTICLES); } } - public static void fallBurst(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (!GeneralMethods.canBend(player.getName(), "AirBurst")) { - return; - } - if (player.getFallDistance() < threshold) { - return; - } - if (GeneralMethods.getBoundAbility(player) == null) { - return; - } - if (instances.containsKey(player)) { - return; - } - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirBurst")) { - return; - } - if (bPlayer.isOnCooldown("AirBurst")) { - return; - } - + private void fallBurst() { Location location = player.getLocation(); double x, y, z; double r = 1; - for (double theta = 75; theta < 105; theta += deltheta) { - double dphi = delphi / Math.sin(Math.toRadians(theta)); + + for (double theta = 75; theta < 105; theta += blastAngleTheta) { + double dphi = blastAnglePhi / Math.sin(Math.toRadians(theta)); for (double phi = 0; phi < 360; phi += dphi) { double rphi = Math.toRadians(phi); double rtheta = Math.toRadians(theta); @@ -97,25 +104,29 @@ public class AirBurst implements ConfigLoadable { y = r * Math.sin(rphi) * Math.sin(rtheta); z = r * Math.cos(rtheta); Vector direction = new Vector(x, z, y); - AirBlast blast = new AirBlast(location, direction.normalize(), player, pushfactor, new AirBurst()); + AirBlast blast = new AirBlast(player, location, direction.normalize(), pushFactor, this); blast.setDamage(damage); } } } - void addAffectedEntity(Entity entity) { - affectedentities.add(entity); + public static void coneBurst(Player player) { + if (CoreAbility.hasAbility(player, AirBurst.class)) { + AirBurst airBurst = CoreAbility.getAbility(player, AirBurst.class); + airBurst.startConeBurst(); + airBurst.remove(); + } } - private void coneBurst() { - if (charged) { + private void startConeBurst() { + if (isCharged) { Location location = player.getEyeLocation(); Vector vector = location.getDirection(); double angle = Math.toRadians(30); double x, y, z; double r = 1; - for (double theta = 0; theta <= 180; theta += deltheta) { - double dphi = delphi / Math.sin(Math.toRadians(theta)); + for (double theta = 0; theta <= 180; theta += blastAngleTheta) { + double dphi = blastAnglePhi / Math.sin(Math.toRadians(theta)); for (double phi = 0; phi < 360; phi += dphi) { double rphi = Math.toRadians(phi); double rtheta = Math.toRadians(theta); @@ -124,21 +135,22 @@ public class AirBurst implements ConfigLoadable { z = r * Math.cos(rtheta); Vector direction = new Vector(x, z, y); if (direction.angle(vector) <= angle) { - AirBlast blast = new AirBlast(location, direction.normalize(), player, pushfactor, this); + AirBlast blast = new AirBlast(player, location, direction.normalize(), pushFactor, this); blast.setDamage(damage); } } } } - remove(); } public void handleSmoothParticles() { for (int i = 0; i < blasts.size(); i++) { final AirBlast blast = blasts.get(i); int toggleTime = 0; - if (i % 4 != 0) + + if (i % 4 != 0) { toggleTime = (int) (i % (100 / PARTICLES_PERCENTAGE)) + 3; + } new BukkitRunnable() { public void run() { blast.setShowParticles(true); @@ -147,80 +159,15 @@ public class AirBurst implements ConfigLoadable { } } - boolean isAffectedEntity(Entity entity) { - return affectedentities.contains(entity); - } - - public boolean progress() { - if (!GeneralMethods.canBend(player.getName(), "AirBurst")) { - remove(); - return false; - } - if (GeneralMethods.getBoundAbility(player) == null) { - remove(); - return false; - } - - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirBurst")) { - remove(); - return false; - } - - if (System.currentTimeMillis() > starttime + chargetime && !charged) { - charged = true; - } - - if (!player.isSneaking()) { - if (charged) { - sphereBurst(); - } else { - remove(); - return false; - } - } else if (charged) { - Location location = player.getEyeLocation(); - // location = location.add(location.getDirection().normalize()); - AirMethods.playAirbendingParticles(location, 10); - // location.getWorld().playEffect( - // location, - // Effect.SMOKE, - // Methods.getIntCardinalDirection(player.getEyeLocation() - // .getDirection()), 3); - } - return true; - } - - public static void progressAll() { - for (AirBurst ability : instances.values()) { - ability.progress(); - } - } - - public void remove() { - instances.remove(player); - } - - public static void removeAll() { - for (AirBurst ability : instances.values()) { - ability.remove(); - } - } - - @Override - public void reloadVariables() { - threshold = config.get().getDouble("Abilities.Air.AirBurst.FallThreshold"); - pushfactor = config.get().getDouble("Abilities.Air.AirBurst.PushFactor"); - damage = config.get().getDouble("Abilities.Air.AirBurst.Damage"); - chargetime = config.get().getLong("Abilities.Air.AirBurst.ChargeTime"); - } - private void sphereBurst() { - if (charged) { + if (isCharged) { Location location = player.getEyeLocation(); double x, y, z; double r = 1; - for (double theta = 0; theta <= 180; theta += deltheta) { - double dphi = delphi / Math.sin(Math.toRadians(theta)); + + for (double theta = 0; theta <= 180; theta += blastAngleTheta) { + double dphi = blastAnglePhi / Math.sin(Math.toRadians(theta)); + for (double phi = 0; phi < 360; phi += dphi) { double rphi = Math.toRadians(phi); double rtheta = Math.toRadians(theta); @@ -228,15 +175,119 @@ public class AirBurst implements ConfigLoadable { y = r * Math.sin(rphi) * Math.sin(rtheta); z = r * Math.cos(rtheta); Vector direction = new Vector(x, z, y); - AirBlast blast = new AirBlast(location, direction.normalize(), player, pushfactor, this); + AirBlast blast = new AirBlast(player, location, direction.normalize(), pushFactor, this); blast.setDamage(damage); blast.setShowParticles(false); blasts.add(blast); } } } - // Methods.verbose("--" + AirBlast.instances.size() + "--"); - remove(); handleSmoothParticles(); } + + @Override + public String getName() { + return "AirBurst"; + } + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + + public void addAffectedEntity(Entity entity) { + affectedEntities.add(entity); + } + + public boolean isAffectedEntity(Entity entity) { + return affectedEntities.contains(entity); + } + + public long getChargeTime() { + return chargeTime; + } + + public void setChargeTime(long chargeTime) { + this.chargeTime = chargeTime; + } + + public double getFallThreshold() { + return fallThreshold; + } + + public void setFallThreshold(double fallThreshold) { + this.fallThreshold = fallThreshold; + } + + public double getPushFactor() { + return pushFactor; + } + + public void setPushFactor(double pushFactor) { + this.pushFactor = pushFactor; + } + + public double getDamage() { + return damage; + } + + public void setDamage(double damage) { + this.damage = damage; + } + + public double getBlastAngleTheta() { + return blastAngleTheta; + } + + public void setBlastAngleTheta(double blastAngleTheta) { + this.blastAngleTheta = blastAngleTheta; + } + + public double getBlastAnglePhi() { + return blastAnglePhi; + } + + public void setBlastAnglePhi(double blastAnglePhi) { + this.blastAnglePhi = blastAnglePhi; + } + + public boolean isCharged() { + return isCharged; + } + + public void setCharged(boolean isCharged) { + this.isCharged = isCharged; + } + + public boolean isFallBurst() { + return isFallBurst; + } + + public void setFallBurst(boolean isFallBurst) { + this.isFallBurst = isFallBurst; + } + + public ArrayList getBlasts() { + return blasts; + } + + public ArrayList getAffectedEntities() { + return affectedEntities; + } } diff --git a/src/com/projectkorra/projectkorra/airbending/AirCombo.java b/src/com/projectkorra/projectkorra/airbending/AirCombo.java index 20c58b1c..1177fe84 100644 --- a/src/com/projectkorra/projectkorra/airbending/AirCombo.java +++ b/src/com/projectkorra/projectkorra/airbending/AirCombo.java @@ -1,17 +1,16 @@ package com.projectkorra.projectkorra.airbending; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.Element; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.ComboAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation; +import com.projectkorra.projectkorra.avatar.AvatarState; import com.projectkorra.projectkorra.command.Commands; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.earthbending.EarthMethods; import com.projectkorra.projectkorra.firebending.FireCombo; -import com.projectkorra.projectkorra.firebending.FireMethods; import com.projectkorra.projectkorra.firebending.FireCombo.FireComboStream; -import com.projectkorra.projectkorra.util.ClickType; import com.projectkorra.projectkorra.util.Flight; import org.bukkit.Location; @@ -24,128 +23,102 @@ import org.bukkit.util.Vector; import java.util.ArrayList; -public class AirCombo implements ConfigLoadable { +/* + * TODO: Combo classes should eventually be rewritten so that each combo is treated + * as an individual ability. In the mean time, we will just place "fake" + * classes so that CoreAbility will register each ability. + */ +public class AirCombo extends AirAbility implements ComboAbility { public static enum AbilityState { TWISTER_MOVING, TWISTER_STATIONARY } - public static ArrayList instances = new ArrayList(); - - public static double twisterSpeed = config.get().getDouble("Abilities.Air.AirCombo.Twister.Speed"); - public static double twisterRange = config.get().getDouble("Abilities.Air.AirCombo.Twister.Range"); - public static double twisterHeight = config.get().getDouble("Abilities.Air.AirCombo.Twister.Height"); - public static double twisterRadius = config.get().getDouble("Abilities.Air.AirCombo.Twister.Radius"); - public static double twisterDegreePerParticle = config.get().getDouble("Abilities.Air.AirCombo.Twister.DegreesPerParticle"); - public static double twisterHeightPerParticle = config.get().getDouble("Abilities.Air.AirCombo.Twister.HeightPerParticle"); - public static long twisterRemoveDelay = config.get().getLong("Abilities.Air.AirCombo.Twister.RemoveDelay"); - public static long twisterCooldown = config.get().getLong("Abilities.Air.AirCombo.Twister.Cooldown"); - - public static double airStreamSpeed = config.get().getDouble("Abilities.Air.AirCombo.AirStream.Speed"); - public static double airStreamRange = config.get().getDouble("Abilities.Air.AirCombo.AirStream.Range"); - public static double airStreamEntityHeight = config.get().getDouble("Abilities.Air.AirCombo.AirStream.EntityHeight"); - public static long airStreamEntityDuration = config.get().getLong("Abilities.Air.AirCombo.AirStream.EntityDuration"); - public static long airStreamCooldown = config.get().getLong("Abilities.Air.AirCombo.AirStream.Cooldown"); - - public static double airSweepSpeed = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Speed"); - public static double airSweepRange = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Range"); - public static double airSweepDamage = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Damage"); - public static double airSweepKnockback = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Knockback"); - public static long airSweepCooldown = config.get().getLong("Abilities.Air.AirCombo.AirSweep.Cooldown"); - - private static boolean enabled = config.get().getBoolean("Abilities.Air.AirCombo.Enabled"); - - public double airSliceSpeed = 0.7; - public double airSliceRange = 10; - public double airSliceDamage = 3; - public long airSliceCooldown = 500; - - private Player player; - private BendingPlayer bPlayer; - private ClickType type; - private String ability; - + private boolean isEnabled; + private int progressCounter; + private long cooldown; private long time; + private double damage; + private double speed; + private double range; + private double knockback; + private double airStreamMaxEntityHeight; + private double airStreamEntityCarryDuration; + private double twisterHeight; + private double twisterRadius; + private double twisterDegreeParticles; + private double twisterHeightParticles; + private double twisterRemoveDelay; + private AbilityState state; + private String abilityName; private Location origin; private Location currentLoc; private Location destination; private Vector direction; - private int progressCounter = 0; - private double damage = 0, speed = 0, range = 0, knockback = 0; - private long cooldown = 0; - private AbilityState state; - private ArrayList affectedEntities = new ArrayList(); - private ArrayList tasks = new ArrayList(); - private ArrayList flights = new ArrayList(); + private ArrayList affectedEntities; + private ArrayList tasks; + private ArrayList flights; public AirCombo(Player player, String ability) { - /* Initial Checks */ + super(player); + + this.abilityName = ability; + this.isEnabled = getConfig().getBoolean("Abilities.Air.AirCombo.Enabled"); + this.affectedEntities = new ArrayList<>(); + this.tasks = new ArrayList<>(); + this.flights = new ArrayList<>(); - if (!enabled) - return; - if (Commands.isToggledForAll) - return; - this.bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (!bPlayer.isToggled()) - return; - if (!bPlayer.hasElement(Element.Air)) - return; - if (!GeneralMethods.canBend(player.getName(), ability)) { + if (!this.isEnabled || !bPlayer.canBendIgnoreBindsCooldowns(this)) { return; } - if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", player.getLocation())) - return; - /* End Initial Checks */ - // reloadVariables(); - time = System.currentTimeMillis(); - this.player = player; - this.ability = ability; if (ability.equalsIgnoreCase("Twister")) { - damage = 0; - range = twisterRange; - speed = twisterSpeed; - cooldown = twisterCooldown; + this.range = getConfig().getDouble("Abilities.Air.AirCombo.Twister.Range"); + this.speed = getConfig().getDouble("Abilities.Air.AirCombo.Twister.Speed"); + this.cooldown = getConfig().getLong("Abilities.Air.AirCombo.Twister.Cooldown"); + this.twisterHeight = getConfig().getDouble("Abilities.Air.AirCombo.Twister.Height"); + this.twisterDegreeParticles = getConfig().getDouble("Abilities.Air.AirCombo.Twister.DegreesPerParticle"); + this.twisterHeightParticles = getConfig().getDouble("Abilities.Air.AirCombo.Twister.HeightPerParticle"); + this.twisterRemoveDelay = getConfig().getLong("Abilities.Air.AirCombo.Twister.RemoveDelay"); } else if (ability.equalsIgnoreCase("AirStream")) { - damage = 0; - range = airStreamRange; - speed = airStreamSpeed; - cooldown = airStreamCooldown; - } else if (ability.equalsIgnoreCase("AirSlice")) { - damage = airSliceDamage; - range = airSliceRange; - speed = airSliceSpeed; - cooldown = airSliceCooldown; + this.range = getConfig().getDouble("Abilities.Air.AirCombo.AirStream.Range"); + this.speed = getConfig().getDouble("Abilities.Air.AirCombo.AirStream.Speed"); + this.cooldown = getConfig().getLong("Abilities.Air.AirCombo.AirStream.Cooldown"); + this.airStreamMaxEntityHeight = getConfig().getDouble("Abilities.Air.AirCombo.AirStream.EntityHeight"); + this.airStreamEntityCarryDuration = getConfig().getLong("Abilities.Air.AirCombo.AirStream.EntityDuration"); } else if (ability.equalsIgnoreCase("AirSweep")) { - damage = airSweepDamage; - range = airSweepRange; - speed = airSweepSpeed; - knockback = airSweepKnockback; - cooldown = airSweepCooldown; + this.damage = getConfig().getDouble("Abilities.Air.AirCombo.AirSweep.Damage"); + this.range = getConfig().getDouble("Abilities.Air.AirCombo.AirSweep.Range"); + this.speed = getConfig().getDouble("Abilities.Air.AirCombo.AirSweep.Speed"); + this.knockback = getConfig().getDouble("Abilities.Air.AirCombo.AirSweep.Knockback"); + this.cooldown = getConfig().getLong("Abilities.Air.AirCombo.AirSweep.Cooldown"); } - if (AvatarState.isAvatarState(player)) { - cooldown = 0; - damage = AvatarState.getValue(damage); - range = AvatarState.getValue(range); - knockback = knockback * 1.4; + + if (bPlayer.isAvatarState()) { + this.cooldown = 0; + this.damage = AvatarState.getValue(damage); + this.range = AvatarState.getValue(range); + this.knockback = knockback * 1.4; + this.airStreamMaxEntityHeight = AvatarState.getValue(airStreamMaxEntityHeight); + this.airStreamEntityCarryDuration = AvatarState.getValue(airStreamEntityCarryDuration); } - instances.add(this); + bPlayer.addCooldown(this); + start(); } + @Override public void progress() { progressCounter++; if (player.isDead() || !player.isOnline()) { remove(); return; + } else if (currentLoc != null && GeneralMethods.isRegionProtectedFromBuild(this, currentLoc)) { + remove(); + return; } - if (ability.equalsIgnoreCase("Twister")) { + if (abilityName.equalsIgnoreCase("Twister")) { if (destination == null) { - if (bPlayer.isOnCooldown("Twister") && !AvatarState.isAvatarState(player)) { - remove(); - return; - } - bPlayer.addCooldown("Twister", cooldown); state = AbilityState.TWISTER_MOVING; direction = player.getEyeLocation().getDirection().clone().normalize(); direction.setY(0); @@ -153,15 +126,15 @@ public class AirCombo implements ConfigLoadable { destination = player.getLocation().add(direction.clone().multiply(range)); currentLoc = origin.clone(); } - if (origin.distance(currentLoc) < origin.distance(destination) && state == AbilityState.TWISTER_MOVING) + if (origin.distanceSquared(currentLoc) < origin.distanceSquared(destination) && state == AbilityState.TWISTER_MOVING) { currentLoc.add(direction.clone().multiply(speed)); - else if (state == AbilityState.TWISTER_MOVING) { + } else if (state == AbilityState.TWISTER_MOVING) { state = AbilityState.TWISTER_STATIONARY; time = System.currentTimeMillis(); } else if (System.currentTimeMillis() - time >= twisterRemoveDelay) { remove(); return; - } else if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", currentLoc)) { + } else if (GeneralMethods.isRegionProtectedFromBuild(this, currentLoc)) { remove(); return; } @@ -175,90 +148,84 @@ public class AirCombo implements ConfigLoadable { double height = twisterHeight; double radius = twisterRadius; - for (double y = 0; y < height; y += twisterHeightPerParticle) { + for (double y = 0; y < height; y += twisterHeightParticles) { double animRadius = ((radius / height) * y); - for (double i = -180; i <= 180; i += twisterDegreePerParticle) { + for (double i = -180; i <= 180; i += twisterDegreeParticles) { Vector animDir = GeneralMethods.rotateXZ(new Vector(1, 0, 1), i); Location animLoc = currentLoc.clone().add(animDir.multiply(animRadius)); animLoc.add(0, y, 0); - AirMethods.playAirbendingParticles(animLoc, 1, 0, 0, 0); + playAirbendingParticles(animLoc, 1, 0, 0, 0); } } - AirMethods.playAirbendingSound(currentLoc); + playAirbendingSound(currentLoc); - for (int i = 0; i < height; i += 3) - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(currentLoc.clone().add(0, i, 0), radius * 0.75)) - if (!affectedEntities.contains(entity) && !entity.equals(player)) + for (int i = 0; i < height; i += 3) { + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(currentLoc.clone().add(0, i, 0), radius * 0.75)) { + if (!affectedEntities.contains(entity) && !entity.equals(player)) { affectedEntities.add(entity); + } + } + } for (Entity entity : affectedEntities) { Vector forceDir = GeneralMethods.getDirection(entity.getLocation(), currentLoc.clone().add(0, height, 0)); - if (entity instanceof Player) { - if (Commands.invincible.contains(((Player) entity).getName())) + if (Commands.invincible.contains(((Player) entity).getName())) { break; + } } - entity.setVelocity(forceDir.clone().normalize().multiply(0.3)); } - } - - else if (ability.equalsIgnoreCase("AirStream")) { + } else if (abilityName.equalsIgnoreCase("AirStream")) { if (destination == null) { - if (bPlayer.isOnCooldown("AirStream") && !AvatarState.isAvatarState(player)) { - remove(); - return; - } - bPlayer.addCooldown("AirStream", cooldown); origin = player.getEyeLocation(); currentLoc = origin.clone(); } - Entity target = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); - + Entity target = GeneralMethods.getTargetedEntity(player, range); if (target instanceof Player) { - if (Commands.invincible.contains(((Player) target).getName())) + if (Commands.invincible.contains(((Player) target).getName())) { return; + } } - if (target != null && target.getLocation().distance(currentLoc) > 7) + if (target != null && target.getLocation().distanceSquared(currentLoc) > 49) { destination = target.getLocation(); - else - destination = GeneralMethods.getTargetedLocation(player, range, EarthMethods.transparentToEarthbending); + } else { + destination = GeneralMethods.getTargetedLocation(player, range, getTransparentMaterial()); + } direction = GeneralMethods.getDirection(currentLoc, destination).normalize(); currentLoc.add(direction.clone().multiply(speed)); - if (!EarthMethods.isTransparentToEarthbending(player, currentLoc.getBlock())) - currentLoc.subtract(direction.clone().multiply(speed)); if (player.getWorld() != currentLoc.getWorld()) { remove(); return; - } - - if (Math.abs(player.getLocation().distance(currentLoc)) > range) { - remove(); - return; - } else if (affectedEntities.size() > 0 && System.currentTimeMillis() - time >= airStreamEntityDuration) { - remove(); - return; } else if (!player.isSneaking()) { remove(); return; - } else if (!EarthMethods.isTransparentToEarthbending(player, currentLoc.getBlock())) { + } else if (Math.abs(player.getLocation().distanceSquared(currentLoc)) > range * range) { remove(); return; - } else if (currentLoc.getY() - origin.getY() > airStreamEntityHeight) { + } else if (affectedEntities.size() > 0 && System.currentTimeMillis() - time >= airStreamEntityCarryDuration) { remove(); return; - } else if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", currentLoc)) { + } else if (!isTransparent(currentLoc.getBlock())) { remove(); return; - } else if (FireMethods.isWithinFireShield(currentLoc)) { + } else if (currentLoc.getY() - origin.getY() > airStreamMaxEntityHeight) { remove(); return; - } else if (AirMethods.isWithinAirShield(currentLoc)) { + } else if (GeneralMethods.isRegionProtectedFromBuild(this, currentLoc)) { remove(); return; + } else if (FireAbility.isWithinFireShield(currentLoc)) { + remove(); + return; + } else if (isWithinAirShield(currentLoc)) { + remove(); + return; + } else if (!isTransparent(currentLoc.getBlock())) { + currentLoc.subtract(direction.clone().multiply(speed)); } for (int i = 0; i < 10; i++) { @@ -270,7 +237,7 @@ public class AirCombo implements ConfigLoadable { public void run() { for (int angle = -180; angle <= 180; angle += 45) { Vector orthog = GeneralMethods.getOrthogonalVector(dir.clone(), angle, 0.5); - AirMethods.playAirbendingParticles(loc.clone().add(orthog), 1, 0F, 0F, 0F); + playAirbendingParticles(loc.clone().add(orthog), 1, 0F, 0F, 0F); } } }; @@ -296,61 +263,16 @@ public class AirCombo implements ConfigLoadable { entity.setVelocity(force.clone().normalize().multiply(speed)); entity.setFallDistance(0F); } - } - - else if (ability.equalsIgnoreCase("AirSlice")) { + } else if (abilityName.equalsIgnoreCase("AirSweep")) { if (origin == null) { - if (bPlayer.isOnCooldown("AirSlice") && !AvatarState.isAvatarState(player)) { - remove(); - return; - } - bPlayer.addCooldown("AirSlice", cooldown); - origin = player.getLocation(); - currentLoc = origin.clone(); - direction = player.getEyeLocation().getDirection(); - - for (double i = -5; i < 10; i += 1) { - FireComboStream fs = new FireComboStream(null, direction.clone().add(new Vector(0, 0.03 * i, 0)), - player.getLocation(), range, speed, "AirSlice"); - fs.setDensity(1); - fs.setSpread(0F); - fs.setUseNewParticles(true); - fs.setParticleEffect(AirMethods.getAirbendingParticles()); - fs.setCollides(false); - fs.runTaskTimer(ProjectKorra.plugin, 0, 1L); - tasks.add(fs); - } - } - manageAirVectors(); - for (Entity entity : affectedEntities) - if (entity instanceof LivingEntity) { - remove(); - return; - } - } - - else if (ability.equalsIgnoreCase("AirSweep")) { - if (origin == null) { - if (bPlayer.isOnCooldown("AirSweep") && !AvatarState.isAvatarState(player)) { - remove(); - return; - } - bPlayer.addCooldown("AirSweep", cooldown); direction = player.getEyeLocation().getDirection().normalize(); origin = player.getLocation().add(direction.clone().multiply(10)); - } - if (progressCounter < 8) + if (progressCounter < 8) { return; - + } if (destination == null) { destination = player.getLocation().add(player.getEyeLocation().getDirection().normalize().multiply(10)); - - // if (Math.abs(origin.distance(destination)) < 7) { - // remove(); - // return; - // } - Vector origToDest = GeneralMethods.getDirection(origin, destination); for (double i = 0; i < 30; i++) { Vector vec = GeneralMethods.getDirection(player.getLocation(), @@ -360,7 +282,7 @@ public class AirCombo implements ConfigLoadable { fs.setDensity(1); fs.setSpread(0F); fs.setUseNewParticles(true); - fs.setParticleEffect(AirMethods.getAirbendingParticles()); + fs.setParticleEffect(getAirbendingParticles()); fs.setCollides(false); fs.runTaskTimer(ProjectKorra.plugin, (long) (i / 2.5), 1L); tasks.add(fs); @@ -385,15 +307,20 @@ public class AirCombo implements ConfigLoadable { FireComboStream fstream = (FireComboStream) tasks.get(i); Location loc = fstream.getLocation(); - if (!EarthMethods.isTransparentToEarthbending(player, loc.getBlock())) { - if (!EarthMethods.isTransparentToEarthbending(player, loc.clone().add(0, 0.2, 0).getBlock())) { + if (GeneralMethods.isRegionProtectedFromBuild(this, loc)) { + fstream.remove(); + return; + } + + if (!isTransparent(loc.getBlock())) { + if (!isTransparent(loc.clone().add(0, 0.2, 0).getBlock())) { fstream.remove(); return; } } if (i % 3 == 0) { for (Entity entity : GeneralMethods.getEntitiesAroundPoint(loc, 2.5)) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", entity.getLocation())) { + if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) { remove(); return; } @@ -403,89 +330,53 @@ public class AirCombo implements ConfigLoadable { Vector force = fstream.getDirection(); entity.setVelocity(force.multiply(knockback)); } - if (damage != 0) - if (entity instanceof LivingEntity) + if (damage != 0) { + if (entity instanceof LivingEntity) { if (fstream.getAbility().equalsIgnoreCase("AirSweep")) { - GeneralMethods.damageEntity(player, entity, damage, Element.Air, "AirSweep"); + GeneralMethods.damageEntity(this, entity, damage); } else { - GeneralMethods.damageEntity(player, entity, damage, Element.Air, "AirCombo"); + GeneralMethods.damageEntity(this, entity, damage); } + } + } } } - if (GeneralMethods.blockAbilities(player, FireCombo.abilitiesToBlock, loc, 1)) { + if (GeneralMethods.blockAbilities(player, FireCombo.getBlockableAbilities(), loc, 1)) { fstream.remove(); } } } } + @Override public void remove() { - instances.remove(this); - for (BukkitRunnable task : tasks) + super.remove(); + for (BukkitRunnable task : tasks) { task.cancel(); - for (int i = 0; i < flights.size(); i++) { - Flight flight = flights.get(i); + } + for (Flight flight : flights) { flight.revert(); flight.remove(); - flights.remove(i); - i--; } } - public static void progressAll() { - for (int i = instances.size() - 1; i >= 0; i--) - instances.get(i).progress(); - } - - public static void removeAll() { - for (int i = instances.size() - 1; i >= 0; i--) { - instances.get(i).remove(); - } - } - - public Player getPlayer() { - return player; - } - - public static ArrayList getAirCombo(Player player) { - ArrayList list = new ArrayList(); - for (AirCombo combo : instances) - if (combo.player != null && combo.player == player) - list.add(combo); - return list; - } - - public static ArrayList getAirCombo(Player player, ClickType type) { - ArrayList list = new ArrayList(); - for (AirCombo combo : instances) - if (combo.player != null && combo.player == player && combo.type != null && combo.type == type) - list.add(combo); - return list; - } - public static boolean removeAroundPoint(Player player, String ability, Location loc, double radius) { boolean removed = false; - for (int i = 0; i < instances.size(); i++) { - AirCombo combo = instances.get(i); - if (combo.getPlayer().equals(player)) + for (AirCombo combo : CoreAbility.getAbilities(AirCombo.class)) { + if (combo.getPlayer().equals(player)) { continue; - - if (ability.equalsIgnoreCase("Twister") && combo.ability.equalsIgnoreCase("Twister")) { + } else if (ability.equalsIgnoreCase("Twister") && combo.abilityName.equalsIgnoreCase("Twister")) { if (combo.currentLoc != null && Math.abs(combo.currentLoc.distance(loc)) <= radius) { - instances.remove(combo); + combo.remove(); removed = true; } - } - - else if (ability.equalsIgnoreCase("AirStream") && combo.ability.equalsIgnoreCase("AirStream")) { + } else if (ability.equalsIgnoreCase("AirStream") && combo.abilityName.equalsIgnoreCase("AirStream")) { if (combo.currentLoc != null && Math.abs(combo.currentLoc.distance(loc)) <= radius) { - instances.remove(combo); + combo.remove(); removed = true; } - } - - else if (ability.equalsIgnoreCase("AirSweep") && combo.ability.equalsIgnoreCase("AirSweep")) { + } else if (ability.equalsIgnoreCase("AirSweep") && combo.abilityName.equalsIgnoreCase("AirSweep")) { for (int j = 0; j < combo.tasks.size(); j++) { FireComboStream fs = (FireComboStream) combo.tasks.get(j); if (fs.getLocation() != null && fs.getLocation().getWorld().equals(loc.getWorld()) @@ -500,28 +391,271 @@ public class AirCombo implements ConfigLoadable { } @Override - public void reloadVariables() { - twisterSpeed = config.get().getDouble("Abilities.Air.AirCombo.Twister.Speed"); - twisterRange = config.get().getDouble("Abilities.Air.AirCombo.Twister.Range"); - twisterHeight = config.get().getDouble("Abilities.Air.AirCombo.Twister.Height"); - twisterRadius = config.get().getDouble("Abilities.Air.AirCombo.Twister.Radius"); - twisterDegreePerParticle = config.get().getDouble("Abilities.Air.AirCombo.Twister.DegreesPerParticle"); - twisterHeightPerParticle = config.get().getDouble("Abilities.Air.AirCombo.Twister.HeightPerParticle"); - twisterRemoveDelay = config.get().getLong("Abilities.Air.AirCombo.Twister.RemoveDelay"); - twisterCooldown = config.get().getLong("Abilities.Air.AirCombo.Twister.Cooldown"); - - airStreamSpeed = config.get().getDouble("Abilities.Air.AirCombo.AirStream.Speed"); - airStreamRange = config.get().getDouble("Abilities.Air.AirCombo.AirStream.Range"); - airStreamEntityHeight = config.get().getDouble("Abilities.Air.AirCombo.AirStream.EntityHeight"); - airStreamEntityDuration = config.get().getLong("Abilities.Air.AirCombo.AirStream.EntityDuration"); - airStreamCooldown = config.get().getLong("Abilities.Air.AirCombo.AirStream.Cooldown"); - - airSweepSpeed = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Speed"); - airSweepRange = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Range"); - airSweepDamage = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Damage"); - airSweepKnockback = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Knockback"); - airSweepCooldown = config.get().getLong("Abilities.Air.AirCombo.AirSweep.Cooldown"); - - enabled = config.get().getBoolean("Abilities.Air.AirCombo.Enabled"); + public String getName() { + return abilityName == null ? "AirCombo" : abilityName; } + + @Override + public Location getLocation() { + if (currentLoc != null) { + return currentLoc; + } else if (origin != null) { + return origin; + } else if (player != null) { + return player.getLocation(); + } + return null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isHiddenAbility() { + return true; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + @Override + public String getInstructions() { + return null; + } + + @Override + public Object createNewComboInstance(Player player) { + return null; + } + + @Override + public ArrayList getCombination() { + return null; + } + + + public String getAbilityName() { + return abilityName; + } + + public void setAbilityName(String abilityName) { + this.abilityName = abilityName; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public Location getCurrentLoc() { + return currentLoc; + } + + public void setCurrentLoc(Location currentLoc) { + this.currentLoc = currentLoc; + } + + public Location getDestination() { + return destination; + } + + public void setDestination(Location destination) { + this.destination = destination; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public AbilityState getState() { + return state; + } + + public void setState(AbilityState state) { + this.state = state; + } + + public boolean isEnabled() { + return isEnabled; + } + + public void setEnabled(boolean isEnabled) { + this.isEnabled = isEnabled; + } + + public int getProgressCounter() { + return progressCounter; + } + + public void setProgressCounter(int progressCounter) { + this.progressCounter = progressCounter; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public double getDamage() { + return damage; + } + + public void setDamage(double damage) { + this.damage = damage; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getKnockback() { + return knockback; + } + + public void setKnockback(double knockback) { + this.knockback = knockback; + } + + public double getAirStreamMaxEntityHeight() { + return airStreamMaxEntityHeight; + } + + public void setAirStreamMaxEntityHeight(double airStreamMaxEntityHeight) { + this.airStreamMaxEntityHeight = airStreamMaxEntityHeight; + } + + public double getAirStreamEntityCarryDuration() { + return airStreamEntityCarryDuration; + } + + public void setAirStreamEntityCarryDuration(double airStreamEntityCarryDuration) { + this.airStreamEntityCarryDuration = airStreamEntityCarryDuration; + } + + public double getTwisterHeight() { + return twisterHeight; + } + + public void setTwisterHeight(double twisterHeight) { + this.twisterHeight = twisterHeight; + } + + public double getTwisterRadius() { + return twisterRadius; + } + + public void setTwisterRadius(double twisterRadius) { + this.twisterRadius = twisterRadius; + } + + public double getTwisterDegreeParticles() { + return twisterDegreeParticles; + } + + public void setTwisterDegreeParticles(double twisterDegreeParticles) { + this.twisterDegreeParticles = twisterDegreeParticles; + } + + public double getTwisterHeightParticles() { + return twisterHeightParticles; + } + + public void setTwisterHeightParticles(double twisterHeightParticles) { + this.twisterHeightParticles = twisterHeightParticles; + } + + public double getTwisterRemoveDelay() { + return twisterRemoveDelay; + } + + public void setTwisterRemoveDelay(double twisterRemoveDelay) { + this.twisterRemoveDelay = twisterRemoveDelay; + } + + public ArrayList getAffectedEntities() { + return affectedEntities; + } + + public ArrayList getTasks() { + return tasks; + } + + public ArrayList getFlights() { + return flights; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public class AirStream extends AirCombo { + + public AirStream(Player player, String name) { + super(player, "AirStream"); + } + + @Override + public String getName() { + return "AirStream"; + } + + } + + public class AirSweep extends AirCombo { + + public AirSweep(Player player, String name) { + super(player, "AirSweep"); + } + + @Override + public String getName() { + return "AirSweep"; + } + + } + + public class Twister extends AirCombo { + + public Twister(Player player, String name) { + super(player, "Twister"); + } + + @Override + public String getName() { + return "Twister"; + } + + } + } diff --git a/src/com/projectkorra/projectkorra/airbending/AirFlight.java b/src/com/projectkorra/projectkorra/airbending/AirFlight.java new file mode 100644 index 00000000..63055969 --- /dev/null +++ b/src/com/projectkorra/projectkorra/airbending/AirFlight.java @@ -0,0 +1,142 @@ +package com.projectkorra.projectkorra.airbending; + +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.FlightAbility; +import com.projectkorra.projectkorra.util.Flight; + +public class AirFlight extends FlightAbility { + + private static final ConcurrentHashMap HITS = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap HOVERING = new ConcurrentHashMap<>(); + + private boolean firstProgressIteration; + private int maxHitsBeforeRemoval; + private Flight flight; + + public AirFlight(Player player) { + super(player); + this.maxHitsBeforeRemoval = 4; + this.firstProgressIteration = true; + start(); + } + + public static void addHit(Player player) { + AirFlight airFlight = CoreAbility.getAbility(player, AirFlight.class); + if (airFlight != null) { + if (HITS.containsKey(player.getName())) { + if (HITS.get(player.getName()) >= airFlight.maxHitsBeforeRemoval) { + HITS.remove(player.getName()); + remove(player); + } + } else { + HITS.put(player.getName(), 1); + } + } + } + + public static boolean isFlying(Player player) { + return CoreAbility.hasAbility(player, AirFlight.class); + } + + public static boolean isHovering(Player player) { + return HOVERING.containsKey(player.getName()); + } + + public static void remove(Player player) { + if (isFlying(player)) { + CoreAbility.getAbility(player, AirFlight.class).remove(); + } + } + + public static void cleanup() { + HITS.clear(); + HOVERING.clear(); + } + + public static void setHovering(Player player, boolean bool) { + String playername = player.getName(); + + if (bool) { + if (!HOVERING.containsKey(playername)) { + HOVERING.put(playername, true); + player.setVelocity(new Vector(0, 0, 0)); + } + } else { + if (HOVERING.containsKey(playername)) { + HOVERING.remove(playername); + } + } + } + + @Override + public void progress() { + boolean isHovering = isHovering(player); + if (!bPlayer.canBend(this)) { + remove(); + return; + } else if (!player.isSneaking() && !isHovering && !firstProgressIteration) { + remove(); + return; + } else if (player.getLocation().subtract(0, 0.5, 0).getBlock().getType() != Material.AIR) { + remove(); + return; + } + + if (flight == null) { + flight = new Flight(player); + player.setAllowFlight(true); + player.setVelocity(player.getEyeLocation().getDirection().normalize()); + } + + if (isHovering) { + Vector vec = player.getVelocity().clone(); + vec.setY(0); + player.setVelocity(vec); + } else { + player.setVelocity(player.getEyeLocation().getDirection().normalize()); + } + } + + @Override + public void remove() { + super.remove(); + HITS.remove(player.getName()); + HOVERING.remove(player.getName()); + if (flight != null) { + flight.revert(); + } + } + + @Override + public String getName() { + return "Flight"; + } + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return true; + } + +} diff --git a/src/com/projectkorra/projectkorra/airbending/AirMethods.java b/src/com/projectkorra/projectkorra/airbending/AirMethods.java deleted file mode 100644 index 44e177a7..00000000 --- a/src/com/projectkorra/projectkorra/airbending/AirMethods.java +++ /dev/null @@ -1,268 +0,0 @@ -package com.projectkorra.projectkorra.airbending; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AbilityModuleManager; -import com.projectkorra.projectkorra.util.ParticleEffect; - -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.List; - -public class AirMethods { - - private static ProjectKorra plugin; - private static FileConfiguration config = ProjectKorra.plugin.getConfig(); - - public AirMethods(ProjectKorra plugin) { - AirMethods.plugin = plugin; - } - - /** - * Checks to see if a player can use Flight. - * - * @param player The player to check - * @return true If player has permission node "bending.air.flight" - */ - public static boolean canAirFlight(Player player) { - if (player.hasPermission("bending.air.flight")) - return true; - return false; - } - - /** - * Checks to see if a player can use SpiritualProjection. - * - * @param player The player to check - * @return true If player has permission node "bending.air.spiritualprojection" - */ - public static boolean canUseSpiritualProjection(Player player) { - if (player.hasPermission("bending.air.spiritualprojection")) - return true; - return false; - } - - /** - * Gets the AirColor from the config. - * - * @return Config specified ChatColor - */ - public static ChatColor getAirColor() { - return ChatColor.valueOf(config.getString("Properties.Chat.Colors.Air")); - } - - /** - * Gets the AirSubColor from the config. - * - * @return Config specified ChatColor - */ - public static ChatColor getAirSubColor() { - return ChatColor.valueOf(config.getString("Properties.Chat.Colors.AirSub")); - } - - /** - * Checks whether an ability is an air ability. - * - * @param ability The ability to check - * @return true If the ability is an air ability. - */ - public static boolean isAirAbility(String ability) { - return AbilityModuleManager.airbendingabilities.contains(ability); - } - - /** - * Checks whether an ability is a Flight ability. - * - * @param ability The ability to check - * @return true If the ability is a Flight ability. - */ - public static boolean isFlightAbility(String ability) { - return AbilityModuleManager.flightabilities.contains(ability); - } - - /** - * Checks whether an ability is a SpiritualProjection ability. - * - * @param ability The ability to check - * @return true If the ability is a SpiritualProjection ability. - */ - public static boolean isSpiritualProjectionAbility(String ability) { - return AbilityModuleManager.spiritualprojectionabilities.contains(ability); - } - - /** - * Gets the Air Particles from the config. - * - * @return Config specified ParticleEffect - */ - public static ParticleEffect getAirbendingParticles() { - String particle = plugin.getConfig().getString("Properties.Air.Particles"); - if (particle == null) - return ParticleEffect.CLOUD; - else if (particle.equalsIgnoreCase("spell")) - return ParticleEffect.SPELL; - else if (particle.equalsIgnoreCase("blacksmoke")) - return ParticleEffect.SMOKE; - else if (particle.equalsIgnoreCase("smoke")) - return ParticleEffect.CLOUD; - else if (particle.equalsIgnoreCase("smallsmoke")) - return ParticleEffect.SNOW_SHOVEL; - else - return ParticleEffect.CLOUD; - } - - /** - * Plays an integer amount of air particles in a location. - * - * @param loc The location to use - * @param amount The amount of particles - */ - public static void playAirbendingParticles(Location loc, int amount) { - playAirbendingParticles(loc, amount, (float) Math.random(), (float) Math.random(), (float) Math.random()); - } - - /** - * Plays an integer amount of air particles in a location with a given xOffset, yOffset, and - * zOffset. - * - * @param loc The location to use - * @param amount The amount of particles - * @param xOffset The xOffset to use - * @param yOffset The yOffset to use - * @param zOffset The zOffset to use - */ - public static void playAirbendingParticles(Location loc, int amount, float xOffset, float yOffset, float zOffset) { - getAirbendingParticles().display(loc, xOffset, yOffset, zOffset, 0, amount); - } - - /** - * Removes all air spouts in a location within a certain radius. - * - * @param loc The location to use - * @param radius The radius around the location to remove spouts in - * @param source The player causing the removal - */ - public static void removeAirSpouts(Location loc, double radius, Player source) { - AirSpout.removeSpouts(loc, radius, source); - } - - /** - * Removes all air spouts in a location with a radius of 1.5. - * - * @param loc The location to use - * @param source The player causing the removal - */ - public static void removeAirSpouts(Location loc, Player source) { - removeAirSpouts(loc, 1.5, source); - } - - /** - * Stops all airbending systems. SHOULD ONLY BE USED ON PLUGIN DISABLING! - */ - public static void stopBending() { - AirBlast.removeAll(); - AirBubble.removeAll(); - AirShield.removeAll(); - AirSuction.removeAll(); - AirScooter.removeAll(); - AirSpout.removeAll(); - AirSwipe.removeAll(); - Tornado.removeAll(); - AirBurst.removeAll(); - Suffocate.removeAll(); - AirCombo.removeAll(); - FlightAbility.removeAll(); - } - - /** - * Breaks a breathbendng hold on an entity or one a player is inflicting on an entity. - * - * @param entity The entity to be acted upon - */ - public static void breakBreathbendingHold(Entity entity) { - if (Suffocate.isBreathbent(entity)) { - Suffocate.breakSuffocate(entity); - return; - } - - if (entity instanceof Player) { - Player player = (Player) entity; - if (Suffocate.isChannelingSphere(player)) { - Suffocate.remove(player); - } - } - } - - /** - * Plays the Airbending Sound at a location if enabled in the config. - * - * @param loc The location to play the sound at - */ - public static void playAirbendingSound(Location loc) { - if (plugin.getConfig().getBoolean("Properties.Air.PlaySound")) { - loc.getWorld().playSound(loc, Sound.CREEPER_HISS, 1, 5); - } - } - - /** - * Checks whether a location is within an AirShield. - * - * @param loc The location to check - * @return true If the location is inside an AirShield. - */ - public static boolean isWithinAirShield(Location loc) { - List list = new ArrayList(); - list.add("AirShield"); - return GeneralMethods.blockAbilities(null, list, loc, 0); - } - - /** - * Checks whether a player can use the Flight ability. - * - * @param player The player to check - * @param first If the move is being activated - * @param hovering If the player is using the move to hover - * @return true If the player can use the move. - */ - public static boolean canFly(Player player, boolean first, boolean hovering) { - BendingPlayer bender = GeneralMethods.getBendingPlayer(player.getName()); - - if (!player.isOnline()) - return false; - if (!player.isSneaking()) { - if (first) { - } else if (hovering) { - - } else { - return false; - } - } - if (bender.isChiBlocked()) - return false; - if (!player.isOnline()) - return false; - if (bender.isPermaRemoved()) - return false; - if (!bender.getElements().contains(Element.Air)) - return false; - if (!GeneralMethods.canBend(player.getName(), "Flight")) - return false; - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("Flight")) - return false; - if (GeneralMethods.isRegionProtectedFromBuild(player, "Flight", player.getLocation())) - return false; - if (player.getLocation().subtract(0, 0.5, 0).getBlock().getType() != Material.AIR) - return false; - return true; - } - -} diff --git a/src/com/projectkorra/projectkorra/airbending/AirPassive.java b/src/com/projectkorra/projectkorra/airbending/AirPassive.java index b2edef9b..36a106d2 100644 --- a/src/com/projectkorra/projectkorra/airbending/AirPassive.java +++ b/src/com/projectkorra/projectkorra/airbending/AirPassive.java @@ -1,10 +1,10 @@ package com.projectkorra.projectkorra.airbending; +import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; +import com.projectkorra.projectkorra.configuration.ConfigManager; -import org.bukkit.Server; +import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffect; @@ -12,65 +12,53 @@ import org.bukkit.potion.PotionEffectType; import java.util.concurrent.ConcurrentHashMap; -public class AirPassive implements ConfigLoadable { +public class AirPassive { - private static ConcurrentHashMap food = new ConcurrentHashMap(); - private static float factor = (float) config.get().getDouble("Abilities.Air.Passive.Factor"); - - private static int speedPower = config.get().getInt("Abilities.Air.Passive.Speed"); - private static int jumpPower = config.get().getInt("Abilities.Air.Passive.Jump"); + private static final ConcurrentHashMap FOOD = new ConcurrentHashMap<>(); public static float getExhaustion(Player player, float level) { - if (!food.keySet().contains(player)) { - food.put(player, level); + if (!FOOD.keySet().contains(player)) { + FOOD.put(player, level); return level; } else { - float oldlevel = food.get(player); + float oldlevel = FOOD.get(player); if (level < oldlevel) { level = 0; } else { - factor = (float) config.get().getDouble("Abilities.Air.Passive.Factor"); - level = (level - oldlevel) * factor + oldlevel; + double factor = getFactor(); + level = (float) ((level - oldlevel) * factor + oldlevel); } - food.replace(player, level); + FOOD.replace(player, level); return level; } } - public static void handlePassive(Server server) { - for (World world : server.getWorlds()) { + public static void handlePassive() { + for (World world : Bukkit.getServer().getWorlds()) { for (Player player : world.getPlayers()) { - if (!player.isOnline()) + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (!player.isOnline() || bPlayer == null) { return; - if (GeneralMethods.canBendPassive(player.getName(), Element.Air)) { - player.setExhaustion(getExhaustion(player, player.getExhaustion())); // Handles - // Food - // Passive + } + + if (bPlayer.canBendPassive(Element.AIR)) { + player.setExhaustion(getExhaustion(player, player.getExhaustion())); if (player.isSprinting()) { if (!player.hasPotionEffect(PotionEffectType.SPEED)) { - speedPower = config.get().getInt("Abilities.Air.Passive.Speed"); - player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 60, speedPower - 1)); // Handles - // Speed - // Passive + int speedPower = ConfigManager.getConfig().getInt("Abilities.Air.Passive.Speed"); + player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 60, speedPower - 1)); } if (!player.hasPotionEffect(PotionEffectType.JUMP)) { - jumpPower = config.get().getInt("Abilities.Air.Passive.Jump"); - player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 60, jumpPower - 1)); // Handles - // jump - // passive. + int jumpPower = ConfigManager.getConfig().getInt("Abilities.Air.Passive.Jump"); + player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 60, jumpPower - 1)); } } } } } } - - @Override - public void reloadVariables() { - factor = (float) config.get().getDouble("Abilities.Air.Passive.Factor"); - - speedPower = config.get().getInt("Abilities.Air.Passive.Speed"); - jumpPower = config.get().getInt("Abilities.Air.Passive.Jump"); + + public static double getFactor() { + return ConfigManager.getConfig().getDouble("Abilities.Air.Passive.Factor"); } - } diff --git a/src/com/projectkorra/projectkorra/airbending/AirScooter.java b/src/com/projectkorra/projectkorra/airbending/AirScooter.java index 71775ef2..9806fc14 100644 --- a/src/com/projectkorra/projectkorra/airbending/AirScooter.java +++ b/src/com/projectkorra/projectkorra/airbending/AirScooter.java @@ -1,9 +1,10 @@ package com.projectkorra.projectkorra.airbending; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; import com.projectkorra.projectkorra.util.Flight; -import com.projectkorra.projectkorra.waterbending.WaterMethods; import org.bukkit.Location; import org.bukkit.block.Block; @@ -13,48 +14,50 @@ import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Random; -public class AirScooter implements ConfigLoadable { +public class AirScooter extends AirAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); + private static final long SPIN_INTERVAL = 100; + private static final double SCOOTER_RADIUS = 1; + private static final double MAX_HEIGHT_FROM_GROUND = 7; - private static double configSpeed = config.get().getDouble("Abilities.Air.AirScooter.Speed"); - private static final long interval = 100; - private static final double scooterradius = 1; - - private Player player; - private Block floorblock; - private long time; private double speed; - private ArrayList angles = new ArrayList(); + private double spinInterval; + private double radius; + private double maxHeightFromGround; + private Block floorblock; + private Random random; + private ArrayList angles; public AirScooter(Player player) { - /* Initial Check */ + super(player); if (check(player)) { return; + } else if (!player.isSprinting() || GeneralMethods.isSolid(player.getEyeLocation().getBlock()) + || player.getEyeLocation().getBlock().isLiquid()) { + return; + } else if (GeneralMethods.isSolid(player.getLocation().add(0, -.5, 0).getBlock())) { + return; } - if (!player.isSprinting() || GeneralMethods.isSolid(player.getEyeLocation().getBlock()) - || player.getEyeLocation().getBlock().isLiquid()) - return; - if (GeneralMethods.isSolid(player.getLocation().add(0, -.5, 0).getBlock())) - return; - /* End Initial Check */ - // reloadVariables(); - this.player = player; - // wasflying = player.isFlying(); - // canfly = player.getAllowFlight(); + + this.speed = getConfig().getDouble("Abilities.Air.AirScooter.Speed"); + this.spinInterval = SPIN_INTERVAL; + this.radius = SCOOTER_RADIUS; + this.maxHeightFromGround = MAX_HEIGHT_FROM_GROUND; + this.random = new Random(); + this.angles = new ArrayList<>(); + new Flight(player); player.setAllowFlight(true); player.setFlying(true); player.setSprinting(false); - time = System.currentTimeMillis(); + for (int i = 0; i < 5; i++) { angles.add((double) (60 * i)); } - instances.put(player, this); - speed = configSpeed; - progress(); + + start(); } /** @@ -64,24 +67,16 @@ public class AirScooter implements ConfigLoadable { * @return false If player doesn't have an instance */ public static boolean check(Player player) { - if (instances.containsKey(player)) { - instances.get(player).remove(); + if (CoreAbility.hasAbility(player, AirScooter.class)) { + CoreAbility.getAbility(player, AirScooter.class).remove(); return true; } return false; } - public static ArrayList getPlayers() { - ArrayList players = new ArrayList(); - for (AirScooter scooter : instances.values()) { - players.add(scooter.getPlayer()); - } - return players; - } - private void getFloor() { floorblock = null; - for (int i = 0; i <= 7; i++) { + for (int i = 0; i <= maxHeightFromGround; i++) { Block block = player.getEyeLocation().getBlock().getRelative(BlockFace.DOWN, i); if (GeneralMethods.isSolid(block) || block.isLiquid()) { floorblock = block; @@ -90,62 +85,26 @@ public class AirScooter implements ConfigLoadable { } } - public Player getPlayer() { - return player; - } - - public double getSpeed() { - return speed; - } - - public void setSpeed(double value) { - this.speed = value; // Used in PK Items - } - - public boolean progress() { - if (player.isDead() || !player.isOnline()) { - remove(); - return false; - } + @Override + public void progress() { getFloor(); - // Methods.verbose(player); - if (floorblock == null) { + if (floorblock == null || !bPlayer.canBend(this) || !player.isFlying()) { remove(); - return false; + return; } - if (!GeneralMethods.canBend(player.getName(), "AirScooter")) { - remove(); - return false; - } - - if (GeneralMethods.isRegionProtectedFromBuild(player, "AirScooter", player.getLocation())) { - remove(); - return false; - } - - // if (Methods - // .isSolid(player - // .getEyeLocation() - // .clone() - // .add(player.getEyeLocation().getDirection().clone() - // .normalize()).getBlock())) { - // remove(); - // return; - // } - // player.sendBlockChange(floorblock.getLocation(), 89, (byte) 1); - // player.getLocation().setY((double) floorblock.getY() + 2.5); Vector velocity = player.getEyeLocation().getDirection().clone(); velocity.setY(0); velocity = velocity.clone().normalize().multiply(speed); - if (System.currentTimeMillis() > time + interval) { - time = System.currentTimeMillis(); + + if (System.currentTimeMillis() > startTime + spinInterval) { if (player.getVelocity().length() < speed * .5) { remove(); - return false; + return; } spinScooter(); } + double distance = player.getLocation().getY() - (double) floorblock.getY(); double dx = Math.abs(distance - 2.4); if (distance > 2.75) { @@ -155,58 +114,108 @@ public class AirScooter implements ConfigLoadable { } else { velocity.setY(0); } + Location loc = player.getLocation(); - if (!WaterMethods.isWater(player.getLocation().add(0, 2, 0).getBlock())) + if (!WaterAbility.isWater(player.getLocation().add(0, 2, 0).getBlock())) { loc.setY((double) floorblock.getY() + 1.5); - else - return false; - // player.setFlying(true); - // player.teleport(loc.add(velocity)); + } else { + return; + } + player.setSprinting(false); player.removePotionEffect(PotionEffectType.SPEED); player.setVelocity(velocity); - if (GeneralMethods.rand.nextInt(4) == 0) { - AirMethods.playAirbendingSound(player.getLocation()); - } - return true; - } - - public static void progressAll() { - for (AirScooter ability : instances.values()) { - ability.progress(); + if (random.nextInt(4) == 0) { + playAirbendingSound(player.getLocation()); } } @Override - public void reloadVariables() { - configSpeed = config.get().getDouble("Abilities.Air.AirScooter.Speed"); - this.speed = configSpeed; - } - public void remove() { - instances.remove(player); - } - - public static void removeAll() { - for (AirScooter ability : instances.values()) { - ability.remove(); - } + super.remove(); + player.setFlying(false); + player.setAllowFlight(false); + player.setSprinting(false); } private void spinScooter() { Location origin = player.getLocation().clone(); - origin.add(0, -scooterradius, 0); + origin.add(0, -radius, 0); + for (int i = 0; i < 5; i++) { - double x = Math.cos(Math.toRadians(angles.get(i))) * scooterradius; - double y = ((double) i) / 2 * scooterradius - scooterradius; - double z = Math.sin(Math.toRadians(angles.get(i))) * scooterradius; - AirMethods.playAirbendingParticles(origin.clone().add(x, y, z), 7); - // player.getWorld().playEffect(origin.clone().add(x, y, z), - // Effect.SMOKE, 4, (int) AirBlast.defaultrange); + double x = Math.cos(Math.toRadians(angles.get(i))) * radius; + double y = ((double) i) / 2 * radius - radius; + double z = Math.sin(Math.toRadians(angles.get(i))) * radius; + playAirbendingParticles(origin.clone().add(x, y, z), 7); } for (int i = 0; i < 5; i++) { angles.set(i, angles.get(i) + 10); } } + @Override + public String getName() { + return "AirScooter"; + } + + @Override + public Location getLocation() { + return player.getLocation() != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return true; + } + + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public double getSpinInterval() { + return spinInterval; + } + + public void setSpinInterval(double spinInterval) { + this.spinInterval = spinInterval; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getMaxHeightFromGround() { + return maxHeightFromGround; + } + + public void setMaxHeightFromGround(double maxHeightFromGround) { + this.maxHeightFromGround = maxHeightFromGround; + } + + public Block getFloorblock() { + return floorblock; + } + + public void setFloorblock(Block floorblock) { + this.floorblock = floorblock; + } } diff --git a/src/com/projectkorra/projectkorra/airbending/AirShield.java b/src/com/projectkorra/projectkorra/airbending/AirShield.java index 4b9f7304..abb6101b 100644 --- a/src/com/projectkorra/projectkorra/airbending/AirShield.java +++ b/src/com/projectkorra/projectkorra/airbending/AirShield.java @@ -1,14 +1,15 @@ package com.projectkorra.projectkorra.airbending; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ability.AvatarState; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; import com.projectkorra.projectkorra.command.Commands; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; import com.projectkorra.projectkorra.earthbending.EarthBlast; import com.projectkorra.projectkorra.earthbending.SandSpout; +import com.projectkorra.projectkorra.firebending.BlazeArc; import com.projectkorra.projectkorra.firebending.Combustion; import com.projectkorra.projectkorra.firebending.FireBlast; -import com.projectkorra.projectkorra.firebending.FireStream; import com.projectkorra.projectkorra.waterbending.WaterManipulation; import com.projectkorra.projectkorra.waterbending.WaterSpout; @@ -21,146 +22,84 @@ import org.bukkit.entity.Player; import org.bukkit.util.Vector; import java.util.HashMap; +import java.util.Random; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -public class AirShield implements ConfigLoadable { - - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static double MAX_RADIUS = config.get().getDouble("Abilities.Air.AirShield.Radius"); - private static boolean isToggle = config.get().getBoolean("Abilities.Air.AirShield.IsAvatarStateToggle"); - private static int numberOfStreams = (int) (.75 * (double) MAX_RADIUS); - - private double maxradius = MAX_RADIUS; - private double radius = MAX_RADIUS; - private double speedfactor; - - private Player player; - private HashMap angles = new HashMap(); +public class AirShield extends AirAbility { + private boolean isToggledByAvatarState; + private double maxRadius; + private double radius; + private double speed; + private int numberOfStreams; + private int particleCount; + private Random random; + private HashMap angles; + public AirShield(Player player) { - /* Initial Check */ - if (AvatarState.isAvatarState(player) && instances.containsKey(player) && isToggle) { - // instances.remove(player.getUniqueId()); - instances.get(player).remove(); + super(player); + + this.maxRadius = getConfig().getDouble("Abilities.Air.AirShield.Radius"); + this.isToggledByAvatarState = getConfig().getBoolean("Abilities.Air.AirShield.IsAvatarStateToggle"); + this.radius = this.maxRadius; + this.speed = 10; + this.numberOfStreams = (int) (.75 * this.maxRadius); + this.particleCount = 5; + this.random = new Random(); + this.angles = new HashMap<>(); + + if (bPlayer.isAvatarState() && CoreAbility.hasAbility(player, AirShield.class) && isToggledByAvatarState) { + CoreAbility.getAbility(player, AirShield.class).remove(); return; } - /* End Initial Check */ - // reloadVariables(); - this.player = player; + int angle = 0; - int di = (int) (maxradius * 2 / numberOfStreams); - for (int i = -(int) maxradius + di; i < (int) maxradius; i += di) { + int di = (int) (maxRadius * 2 / numberOfStreams); + for (int i = -(int) maxRadius + di; i < (int) maxRadius; i += di) { angles.put(i, angle); angle += 90; - if (angle == 360) + if (angle == 360) { angle = 0; + } } - - instances.put(player, this); - } - - public static String getDescription() { - return "Air Shield is one of the most powerful defensive techniques in existence. " - + "To use, simply sneak (default: shift). " + "This will create a whirlwind of air around the user, " - + "with a small pocket of safe space in the center. " - + "This wind will deflect all projectiles and will prevent any creature from " - + "entering it for as long as its maintained. "; + + start(); } public static boolean isWithinShield(Location loc) { - for (AirShield ashield : instances.values()) { - if (ashield.player.getLocation().getWorld() != loc.getWorld()) + for (AirShield ashield : CoreAbility.getAbilities(AirShield.class)) { + if (!ashield.player.getWorld().equals(loc.getWorld())) { return false; - if (ashield.player.getLocation().distance(loc) <= ashield.radius) + } else if (ashield.player.getLocation().distanceSquared(loc) <= ashield.radius * ashield.radius) { return true; + } } return false; } - public double getMaxradius() { - return maxradius; - } - - public Player getPlayer() { - return player; - } - - public boolean progress() { - if (player.isDead() || !player.isOnline()) { - remove(); - return false; - } - if (GeneralMethods.isRegionProtectedFromBuild(player, "AirShield", player.getLocation())) { - remove(); - return false; - } - speedfactor = 1; - if (!GeneralMethods.canBend(player.getName(), "AirShield") || player.getEyeLocation().getBlock().isLiquid()) { - remove(); - return false; - } - - if (GeneralMethods.getBoundAbility(player) == null) { - remove(); - return false; - } - - if (isToggle) { - if (((!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirShield")) || (!player.isSneaking())) - && !AvatarState.isAvatarState(player)) { - remove(); - return false; - } - } else { - if (((!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirShield")) || (!player.isSneaking()))) { - remove(); - return false; - } - } - - // - // if (((!Methods.getBoundAbility(player).equalsIgnoreCase("AirShield")) || (!player - // .isSneaking()))) { - // remove(); - // return false; - // } - rotateShield(); - return true; - } - - public static void progressAll() { - for (AirShield ability : instances.values()) { - ability.progress(); - } - } - - public void remove() { - instances.remove(player); - } - - public static void removeAll() { - for (AirShield ability : instances.values()) { - ability.remove(); - } - } - @Override - public void reloadVariables() { - MAX_RADIUS = config.get().getDouble("Abilities.Air.AirShield.Radius"); - isToggle = config.get().getBoolean("Abilities.Air.AirShield.IsAvatarStateToggle"); - numberOfStreams = (int) (.75 * (double) MAX_RADIUS); - - maxradius = MAX_RADIUS; + public void progress() { + // AvatarState can use AirShield even when AirShield is not in the bound slot + if (player.getEyeLocation().getBlock().isLiquid()) { + remove(); + return; + } else if (!bPlayer.isAvatarState() || !isToggledByAvatarState) { + if (!player.isSneaking() || !bPlayer.canBend(this)) { + remove(); + return; + } + } else if (!bPlayer.canBendIgnoreBinds(this)) { + remove(); + return; + } + rotateShield(); } private void rotateShield() { Location origin = player.getLocation(); - FireBlast.removeFireBlastsAroundPoint(origin, radius); Combustion.removeAroundPoint(origin, radius); - FireStream.removeAroundPoint(origin, radius); + BlazeArc.removeAroundPoint(origin, radius); AirBlast.removeAirBlastsAroundPoint(origin, radius); AirSuction.removeAirSuctionsAroundPoint(origin, radius); EarthBlast.removeAroundPoint(origin, radius); @@ -169,9 +108,10 @@ public class AirShield implements ConfigLoadable { WaterManipulation.removeAroundPoint(origin, radius); for (Entity entity : GeneralMethods.getEntitiesAroundPoint(origin, radius)) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "AirShield", entity.getLocation())) + if (GeneralMethods.isRegionProtectedFromBuild(player, "AirShield", entity.getLocation())) { continue; - if (origin.distance(entity.getLocation()) > 2) { + } + if (origin.distanceSquared(entity.getLocation()) > 4) { double x, z, vx, vz, mag; double angle = 50; angle = Math.toRadians(angle); @@ -185,7 +125,7 @@ public class AirShield implements ConfigLoadable { vz = (x * Math.sin(angle) + z * Math.cos(angle)) / mag; Vector velocity = entity.getVelocity(); - if (AvatarState.isAvatarState(player)) { + if (bPlayer.isAvatarState()) { velocity.setX(AvatarState.getValue(vx)); velocity.setZ(AvatarState.getValue(vz)); } else { @@ -199,7 +139,7 @@ public class AirShield implements ConfigLoadable { } } - velocity.multiply(radius / maxradius); + velocity.multiply(radius / maxRadius); GeneralMethods.setVelocity(entity, velocity); entity.setFallDistance(0); } @@ -215,43 +155,108 @@ public class AirShield implements ConfigLoadable { Set keys = angles.keySet(); for (int i : keys) { double x, y, z; + double factor = radius / maxRadius; double angle = (double) angles.get(i); angle = Math.toRadians(angle); - - double factor = radius / maxradius; - y = origin.getY() + factor * (double) i; - - // double theta = Math.asin(y/radius); double f = Math.sqrt(1 - factor * factor * ((double) i / radius) * ((double) i / radius)); x = origin.getX() + radius * Math.cos(angle) * f; z = origin.getZ() + radius * Math.sin(angle) * f; Location effect = new Location(origin.getWorld(), x, y, z); - if (!GeneralMethods.isRegionProtectedFromBuild(player, "AirShield", effect)) { - AirMethods.playAirbendingParticles(effect, 5); - if (GeneralMethods.rand.nextInt(4) == 0) { - AirMethods.playAirbendingSound(effect); + if (!GeneralMethods.isRegionProtectedFromBuild(this, effect)) { + playAirbendingParticles(effect, particleCount); + if (random.nextInt(4) == 0) { + playAirbendingSound(effect); } } - // origin.getWorld().playEffect(effect, Effect.SMOKE, 4, - // (int) AirBlast.defaultrange); - - angles.put(i, angles.get(i) + (int) (10 * speedfactor)); + angles.put(i, angles.get(i) + (int) (speed)); } - if (radius < maxradius) { + if (radius < maxRadius) { radius += .3; } - - if (radius > maxradius) - radius = maxradius; - + if (radius > maxRadius) { + radius = maxRadius; + } + } + + @Override + public String getName() { + return "AirShield"; } - public void setMaxradius(double maxradius) { - this.maxradius = maxradius; + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isToggledByAvatarState() { + return isToggledByAvatarState; + } + + public void setToggledByAvatarState(boolean isToggledByAvatarState) { + this.isToggledByAvatarState = isToggledByAvatarState; + } + + public double getMaxRadius() { + return maxRadius; + } + + public void setMaxRadius(double maxRadius) { + this.maxRadius = maxRadius; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public int getNumberOfStreams() { + return numberOfStreams; + } + + public void setNumberOfStreams(int numberOfStreams) { + this.numberOfStreams = numberOfStreams; + } + + public int getParticleCount() { + return particleCount; + } + + public void setParticleCount(int particleCount) { + this.particleCount = particleCount; + } + + public HashMap getAngles() { + return angles; } } diff --git a/src/com/projectkorra/projectkorra/airbending/AirSpout.java b/src/com/projectkorra/projectkorra/airbending/AirSpout.java index 581c1b09..d3986178 100644 --- a/src/com/projectkorra/projectkorra/airbending/AirSpout.java +++ b/src/com/projectkorra/projectkorra/airbending/AirSpout.java @@ -1,57 +1,55 @@ package com.projectkorra.projectkorra.airbending; -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.util.Flight; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.util.Flight; +import java.util.Random; -public class AirSpout implements ConfigLoadable { +public class AirSpout extends AirAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); + private static final Integer[] DIRECTIONS = { 0, 1, 2, 3, 5, 6, 7, 8 }; - private static double HEIGHT = config.get().getDouble("Abilities.Air.AirSpout.Height"); - private static final long interval = 100; - - private Player player; - private long time; - private int angle = 0; - private double height = HEIGHT; + private int angle; + private long updateInterval; + private long cooldown; + private double height; public AirSpout(Player player) { - /* Initial Check */ - if (instances.containsKey(player)) { - instances.get(player).remove(); + super(player); + + AirSpout spout = CoreAbility.getAbility(player, AirSpout.class); + if (spout != null) { + spout.remove(); return; } - /* End Initial Check */ - // reloadVariables(); - this.player = player; - time = System.currentTimeMillis(); - new Flight(player); - instances.put(player, this); - progress(); - } - - public static ArrayList getPlayers() { - ArrayList players = new ArrayList(); - for (AirSpout spout : instances.values()) { - players.add(spout.getPlayer()); + + if (!bPlayer.canBend(this)) { + remove(); + return; } - return players; + + this.angle = 0; + this.cooldown = 0; + this.height = getConfig().getDouble("Abilities.Air.AirSpout.Height"); + this.updateInterval = 100; + + new Flight(player); + start(); + bPlayer.addCooldown(this); } public static boolean removeSpouts(Location loc0, double radius, Player sourceplayer) { boolean removed = false; - for (Player player : instances.keySet()) { - if (!player.equals(sourceplayer)) { - Location loc1 = player.getLocation().getBlock().getLocation(); + for (AirSpout spout : CoreAbility.getAbilities(AirSpout.class)) { + if (!spout.player.equals(sourceplayer)) { + Location loc1 = spout.player.getLocation().getBlock().getLocation(); loc0 = loc0.getBlock().getLocation(); double dx = loc1.getX() - loc0.getX(); double dy = loc1.getY() - loc0.getY(); @@ -59,8 +57,8 @@ public class AirSpout implements ConfigLoadable { double distance = Math.sqrt(dx * dx + dz * dz); - if (distance <= radius && dy > 0 && dy < HEIGHT) { - instances.get(player).remove(); + if (distance <= radius && dy > 0 && dy < spout.height) { + spout.remove(); removed = true; } } @@ -71,7 +69,6 @@ public class AirSpout implements ConfigLoadable { private void allowFlight() { player.setAllowFlight(true); player.setFlying(true); - // flight speed too } private Block getGround() { @@ -85,26 +82,25 @@ public class AirSpout implements ConfigLoadable { return null; } - public double getHeight() { - return height; - } - - public Player getPlayer() { - return player; - } - - public boolean progress() { - if (player.isDead() || !player.isOnline() || !GeneralMethods.canBend(player.getName(), "AirSpout") - // || !Methods.hasAbility(player, Abilities.AirSpout) - || player.getEyeLocation().getBlock().isLiquid() || GeneralMethods.isSolid(player.getEyeLocation().getBlock())) { + @Override + public void progress() { + if (player.isDead() || !player.isOnline() || !bPlayer.canBind(this)) { remove(); - return false; + return; } + + Block eyeBlock = player.getEyeLocation().getBlock(); + if (eyeBlock.isLiquid() || GeneralMethods.isSolid(eyeBlock)) { + remove(); + return; + } + player.setFallDistance(0); player.setSprinting(false); - if (GeneralMethods.rand.nextInt(4) == 0) { - AirMethods.playAirbendingSound(player.getLocation()); + if ((new Random()).nextInt(4) == 0) { + playAirbendingSound(player.getLocation()); } + Block block = getGround(); if (block != null) { double dy = player.getLocation().getY() - block.getY(); @@ -117,92 +113,91 @@ public class AirSpout implements ConfigLoadable { } else { remove(); } - return true; - } - - public static void progressAll() { - for (AirSpout ability : instances.values()) { - ability.progress(); - } - } - - @Override - public void reloadVariables() { - HEIGHT = config.get().getDouble("Abilities.Air.AirSpout.Height"); - height = HEIGHT; } public void remove() { + super.remove(); removeFlight(); - instances.remove(player); - } - - public static void removeAll() { - for (AirSpout ability : instances.values()) { - ability.remove(); - } } private void removeFlight() { player.setAllowFlight(false); player.setFlying(false); - // player.setAllowFlight(player.getGameMode() == GameMode.CREATIVE); - // flight speed too } private void rotateAirColumn(Block block) { - if (player.getWorld() != block.getWorld()) + if (!player.getWorld().equals(block.getWorld())) { return; - - if (System.currentTimeMillis() >= time + interval) { - time = System.currentTimeMillis(); - + } + if (System.currentTimeMillis() >= startTime + updateInterval) { + startTime = System.currentTimeMillis(); Location location = block.getLocation(); Location playerloc = player.getLocation(); location = new Location(location.getWorld(), playerloc.getX(), location.getY(), playerloc.getZ()); - double dy = playerloc.getY() - block.getY(); - if (dy > height) - dy = height; - Integer[] directions = { 0, 1, 2, 3, 5, 6, 7, 8 }; int index = angle; + double dy = Math.min(playerloc.getY() - block.getY(), height); + angle = angle >= DIRECTIONS.length ? 0 : angle + 1; - angle++; - if (angle >= directions.length) - angle = 0; for (int i = 1; i <= dy; i++) { - - index += 1; - if (index >= directions.length) - index = 0; - + index = index >= DIRECTIONS.length ? 0 : index + 1; Location effectloc2 = new Location(location.getWorld(), location.getX(), block.getY() + i, location.getZ()); - AirMethods.playAirbendingParticles(effectloc2, 3, 0.4F, 0.4F, 0.4F); - - // Methods.verbose(directions[index]); - - // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 0, - // (int) height + 5); - // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 1, - // (int) height + 5); - // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 2, - // (int) height + 5); - // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 3, - // (int) height + 5); - // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 5, - // (int) height + 5); - // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 6, - // (int) height + 5); - // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 7, - // (int) height + 5); - // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 8, - // (int) height + 5); + playAirbendingParticles(effectloc2, 3, 0.4F, 0.4F, 0.4F); } } } + @Override + public String getName() { + return "AirSpout"; + } + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return true; + } + + public int getAngle() { + return angle; + } + + public void setAngle(int angle) { + this.angle = angle; + } + + public long getUpdateInterval() { + return updateInterval; + } + + public void setUpdateInterval(long updateInterval) { + this.updateInterval = updateInterval; + } + + public double getHeight() { + return height; + } + public void setHeight(double height) { this.height = height; } + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/airbending/AirSuction.java b/src/com/projectkorra/projectkorra/airbending/AirSuction.java index 8a667612..1fd2f90b 100644 --- a/src/com/projectkorra/projectkorra/airbending/AirSuction.java +++ b/src/com/projectkorra/projectkorra/airbending/AirSuction.java @@ -4,10 +4,10 @@ import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.Element; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; import com.projectkorra.projectkorra.command.Commands; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.earthbending.EarthMethods; import com.projectkorra.projectkorra.object.HorizontalVelocityTracker; import com.projectkorra.projectkorra.util.Flight; import com.projectkorra.projectkorra.waterbending.WaterSpout; @@ -18,233 +18,172 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import java.util.ArrayList; +import java.util.Random; import java.util.concurrent.ConcurrentHashMap; -public class AirSuction implements ConfigLoadable { - - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static ConcurrentHashMap origins = new ConcurrentHashMap(); - - private static final double maxspeed = AirBlast.maxspeed; - private static final int maxticks = 10000; - - // private static long soonesttime = config.get().getLong("Properties.GlobalCooldown"); - private static double SPEED = config.get().getDouble("Abilities.Air.AirSuction.Speed"); - private static double RANGE = config.get().getDouble("Abilities.Air.AirSuction.Range"); - private static double RADIUS = config.get().getDouble("Abilities.Air.AirSuction.Radius"); - private static double PUSH_FACTOR = config.get().getDouble("Abilities.Air.AirSuction.Push"); - private static double originselectrange = 10; +public class AirSuction extends AirAbility { + private static final int ORIGIN_PARTICLE_COUNT = 6; + private static final int ABILITY_PARTICLE_COUNT = 6; + private static final int MAX_TICKS = 10000; + private static final double ORIGIN_SELECT_RANGE = 10; + private static final ConcurrentHashMap ORIGINS = new ConcurrentHashMap<>(); + + private boolean hasOtherOrigin; + private int ticks; + private int particleCount; + private long cooldown; + private double speed; + private double range; + private double radius; + private double pushFactor; + private Random random; private Location location; private Location origin; private Vector direction; - private Player player; - private boolean otherorigin = false; - private int ticks = 0; - private double speed = SPEED; - private double range = RANGE; - private double affectingradius = RADIUS; - private double pushfactor = PUSH_FACTOR; - // private long time; - - private double speedfactor; - - @SuppressWarnings("unused") - private ArrayList affectedentities = new ArrayList(); - + public AirSuction(Player player) { - /* Initial Check */ - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("AirSuction")) + super(player); + if (bPlayer.isOnCooldown("AirSuction")) { return; + } if (player.getEyeLocation().getBlock().isLiquid()) { return; } - if (AirSpout.getPlayers().contains(player) || WaterSpout.getPlayers().contains(player)) { + if ( CoreAbility.hasAbility(player, AirSpout.class) || CoreAbility.hasAbility(player, WaterSpout.class)) { return; } - /* End Initial Check */ - // reloadVariables(); - this.player = player; - if (origins.containsKey(player)) { - origin = origins.get(player); - otherorigin = true; - origins.remove(player); + + this.hasOtherOrigin = false; + this.ticks = 0; + this.particleCount = ABILITY_PARTICLE_COUNT; + this.speed = getConfig().getDouble("Abilities.Air.AirSuction.Speed"); + this.range = getConfig().getDouble("Abilities.Air.AirSuction.Range"); + this.radius = getConfig().getDouble("Abilities.Air.AirSuction.Radius"); + this.pushFactor = getConfig().getDouble("Abilities.Air.AirSuction.Push"); + this.cooldown = GeneralMethods.getGlobalCooldown(); + this.random = new Random(); + + if (ORIGINS.containsKey(player)) { + origin = ORIGINS.get(player); + hasOtherOrigin = true; + ORIGINS.remove(player); } else { origin = player.getEyeLocation(); } - location = GeneralMethods.getTargetedLocation(player, range, GeneralMethods.nonOpaque); + + location = GeneralMethods.getTargetedLocation(player, range, GeneralMethods.NON_OPAQUE); direction = GeneralMethods.getDirection(location, origin).normalize(); - Entity entity = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); + Entity entity = GeneralMethods.getTargetedEntity(player, range); + if (entity != null) { direction = GeneralMethods.getDirection(entity.getLocation(), origin).normalize(); location = getLocation(origin, direction.clone().multiply(-1)); - // location = - // origin.clone().add(direction.clone().multiply(-range)); } - // } - instances.put(player, this); - bPlayer.addCooldown("AirSuction", GeneralMethods.getGlobalCooldown()); - // time = System.currentTimeMillis(); - // timers.put(player, System.currentTimeMillis()); - } - - public static String getDescription() { - return "To use, simply left-click in a direction. " + "A gust of wind will originate as far as it can in that direction" - + " and flow towards you, sucking anything in its path harmlessly with it." - + " Skilled benders can use this technique to pull items from precarious locations. " - + "Additionally, tapping sneak will change the origin of your next " + "AirSuction to your targeted location."; + bPlayer.addCooldown("AirSuction", cooldown); + start(); } private static void playOriginEffect(Player player) { - if (!origins.containsKey(player)) - return; - Location origin = origins.get(player); - if (player.isDead() || !player.isOnline()) - return; - - if (!origin.getWorld().equals(player.getWorld())) { - origins.remove(player); + if (!ORIGINS.containsKey(player)) { return; } - if (GeneralMethods.getBoundAbility(player) == null) { - origins.remove(player); + Location origin = ORIGINS.get(player); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null || player.isDead() || !player.isOnline()) { + return; + } else if (!origin.getWorld().equals(player.getWorld())) { + ORIGINS.remove(player); + return; + } else if (!bPlayer.canBendIgnoreCooldowns(getAbility("AirSuction"))) { + ORIGINS.remove(player); + return; + } else if (origin.distanceSquared(player.getEyeLocation()) > ORIGIN_SELECT_RANGE * ORIGIN_SELECT_RANGE) { + ORIGINS.remove(player); return; } - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirSuction") - || !GeneralMethods.canBend(player.getName(), "AirSuction")) { - origins.remove(player); - return; - } - - if (origin.distance(player.getEyeLocation()) > originselectrange) { - origins.remove(player); - return; - } - - AirMethods.playAirbendingParticles(origin, 6); - // - // origin.getWorld().playEffect(origin, Effect.SMOKE, 4, - // (int) originselectrange); + playAirbendingParticles(origin, ORIGIN_PARTICLE_COUNT); } - public static void progressAll() { - for (AirSuction ability : instances.values()) { - ability.progress(); - } - for (Player player : origins.keySet()) { + public static void progressOrigins() { + for (Player player : ORIGINS.keySet()) { playOriginEffect(player); } } public static void setOrigin(Player player) { - Location location = GeneralMethods.getTargetedLocation(player, originselectrange, GeneralMethods.nonOpaque); - if (location.getBlock().isLiquid() || GeneralMethods.isSolid(location.getBlock())) + Location location = GeneralMethods.getTargetedLocation(player, ORIGIN_SELECT_RANGE, GeneralMethods.NON_OPAQUE); + if (location.getBlock().isLiquid() || GeneralMethods.isSolid(location.getBlock())) { return; - - if (GeneralMethods.isRegionProtectedFromBuild(player, "AirSuction", location)) + } else if (GeneralMethods.isRegionProtectedFromBuild(player, "AirSuction", location)) { return; - - if (origins.containsKey(player)) { - origins.replace(player, location); + } else if (ORIGINS.containsKey(player)) { + ORIGINS.replace(player, location); } else { - origins.put(player, location); + ORIGINS.put(player, location); } } private void advanceLocation() { - AirMethods.playAirbendingParticles(location, 6, 0.275F, 0.275F, 0.275F); - if (GeneralMethods.rand.nextInt(4) == 0) { - AirMethods.playAirbendingSound(location); + playAirbendingParticles(location, particleCount, 0.275F, 0.275F, 0.275F); + if (random.nextInt(4) == 0) { + playAirbendingSound(location); } - // location.getWorld().playEffect(location, Effect.SMOKE, 4, - // (int) AirBlast.defaultrange); - location = location.add(direction.clone().multiply(speedfactor)); - } - - public double getAffectingradius() { - return affectingradius; + double speedFactor = speed * (ProjectKorra.time_step / 1000.); + location = location.add(direction.clone().multiply(speedFactor)); } private Location getLocation(Location origin, Vector direction) { Location location = origin.clone(); for (double i = 1; i <= range; i++) { location = origin.clone().add(direction.clone().multiply(i)); - if (!EarthMethods.isTransparentToEarthbending(player, location.getBlock()) - || GeneralMethods.isRegionProtectedFromBuild(player, "AirSuction", location)) { + if (!isTransparent(location.getBlock()) + || GeneralMethods.isRegionProtectedFromBuild(this, location)) { return origin.clone().add(direction.clone().multiply(i - 1)); } } return location; } - public Player getPlayer() { - return player; - } - - public double getPushfactor() { - return pushfactor; - } - - public double getRange() { - return range; - } - - public double getSpeed() { - return speed; - } - - public boolean progress() { + @Override + public void progress() { if (player.isDead() || !player.isOnline()) { remove(); - return false; - } - if (GeneralMethods.isRegionProtectedFromBuild(player, "AirSuction", location)) { + return; + } else if (GeneralMethods.isRegionProtectedFromBuild(player, "AirSuction", location)) { remove(); - return false; + return; } - speedfactor = speed * (ProjectKorra.time_step / 1000.); ticks++; - - if (ticks > maxticks) { + if (ticks > MAX_TICKS) { remove(); - return false; - } - // if (player.isSneaking() - // && Methods.getBendingAbility(player) == Abilities.AirSuction) { - // new AirSuction(player); - // } - - if ((location.distance(origin) > range) || (location.distance(origin) <= 1)) { + return; + } else if ((location.distanceSquared(origin) > range * range) || (location.distanceSquared(origin) <= 1)) { remove(); - return false; + return; } - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, affectingradius)) { - // if (affectedentities.contains(entity)) - // continue; - // affectedentities.add(entity); - if (entity.getEntityId() != player.getEntityId() || otherorigin) { + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, radius)) { + if (entity.getEntityId() != player.getEntityId() || hasOtherOrigin) { Vector velocity = entity.getVelocity(); - double max = maxspeed; - double factor = pushfactor; - if (AvatarState.isAvatarState(player)) { - max = AvatarState.getValue(maxspeed); + double max = speed; + double factor = pushFactor; + if (bPlayer.isAvatarState()) { + max = AvatarState.getValue(max); factor = AvatarState.getValue(factor); } Vector push = direction.clone(); if (Math.abs(push.getY()) > max && entity.getEntityId() != player.getEntityId()) { - if (push.getY() < 0) + if (push.getY() < 0) { push.setY(-max); - else + } else { push.setY(max); + } } factor *= 1 - location.distance(origin) / (2 * range); @@ -260,44 +199,37 @@ public class AirSuction implements ConfigLoadable { } if (entity instanceof Player) { - if (Commands.invincible.contains(((Player) entity).getName())) + if (Commands.invincible.contains(((Player) entity).getName())) { continue; + } } + GeneralMethods.setVelocity(entity, velocity); - new HorizontalVelocityTracker(entity, player, 200l, "AirSuction", Element.Air, null); + new HorizontalVelocityTracker(entity, player, 200l, "AirSuction", Element.AIR); entity.setFallDistance(0); if (entity.getEntityId() != player.getEntityId() && entity instanceof Player) { new Flight((Player) entity, player); } - if (entity.getFireTicks() > 0) - entity.getWorld().playEffect(entity.getLocation(), Effect.EXTINGUISH, 0); - entity.setFireTicks(0); - AirMethods.breakBreathbendingHold(entity); + if (entity.getFireTicks() > 0) { + entity.getWorld().playEffect(entity.getLocation(), Effect.EXTINGUISH, 0); + } + entity.setFireTicks(0); + breakBreathbendingHold(entity); } } advanceLocation(); - return true; - } - - public void remove() { - instances.remove(player); - } - - public static void removeAll() { - for (AirSuction ability : instances.values()) { - ability.remove(); - } } public static boolean removeAirSuctionsAroundPoint(Location location, double radius) { boolean removed = false; - for (AirSuction airSuction : instances.values()) { + for (AirSuction airSuction : CoreAbility.getAbilities(AirSuction.class)) { Location airSuctionlocation = airSuction.location; if (location.getWorld() == airSuctionlocation.getWorld()) { - if (location.distance(airSuctionlocation) <= radius) + if (location.distanceSquared(airSuctionlocation) <= radius * radius) { airSuction.remove(); + } removed = true; } } @@ -305,30 +237,108 @@ public class AirSuction implements ConfigLoadable { } @Override - public void reloadVariables() { - SPEED = config.get().getDouble("Abilities.Air.AirSuction.Speed"); - RANGE = config.get().getDouble("Abilities.Air.AirSuction.Range"); - RADIUS = config.get().getDouble("Abilities.Air.AirSuction.Radius"); - PUSH_FACTOR = config.get().getDouble("Abilities.Air.AirSuction.Push"); - speed = SPEED; - range = RANGE; - affectingradius = RADIUS; - pushfactor = PUSH_FACTOR; + public String getName() { + return "AirSuction"; } - public void setAffectingradius(double affectingradius) { - this.affectingradius = affectingradius; + @Override + public Location getLocation() { + return location; } - public void setPushfactor(double pushfactor) { - this.pushfactor = pushfactor; + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public boolean isHasOtherOrigin() { + return hasOtherOrigin; + } + + public void setHasOtherOrigin(boolean hasOtherOrigin) { + this.hasOtherOrigin = hasOtherOrigin; + } + + public int getTicks() { + return ticks; + } + + public void setTicks(int ticks) { + this.ticks = ticks; + } + + public int getParticleCount() { + return particleCount; + } + + public void setParticleCount(int particleCount) { + this.particleCount = particleCount; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public double getRange() { + return range; } public void setRange(double range) { this.range = range; } - public void setSpeed(double speed) { - this.speed = speed; + public double getRadius() { + return radius; } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getPushFactor() { + return pushFactor; + } + + public void setPushFactor(double pushFactor) { + this.pushFactor = pushFactor; + } + + public void setLocation(Location location) { + this.location = location; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/airbending/AirSwipe.java b/src/com/projectkorra/projectkorra/airbending/AirSwipe.java index 4ee880dc..53fa3b67 100644 --- a/src/com/projectkorra/projectkorra/airbending/AirSwipe.java +++ b/src/com/projectkorra/projectkorra/airbending/AirSwipe.java @@ -1,9 +1,18 @@ package com.projectkorra.projectkorra.airbending; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.command.Commands; +import com.projectkorra.projectkorra.earthbending.EarthBlast; +import com.projectkorra.projectkorra.firebending.Combustion; +import com.projectkorra.projectkorra.firebending.FireBlast; +import com.projectkorra.projectkorra.firebending.Illumination; +import com.projectkorra.projectkorra.util.Flight; +import com.projectkorra.projectkorra.waterbending.WaterManipulation; import org.bukkit.Location; import org.bukkit.Material; @@ -14,95 +23,78 @@ import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.command.Commands; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.earthbending.EarthBlast; -import com.projectkorra.projectkorra.firebending.Combustion; -import com.projectkorra.projectkorra.firebending.FireBlast; -import com.projectkorra.projectkorra.firebending.Illumination; -import com.projectkorra.projectkorra.util.Flight; -import com.projectkorra.projectkorra.waterbending.WaterManipulation; -import com.projectkorra.projectkorra.waterbending.WaterMethods; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; -public class AirSwipe implements ConfigLoadable { +public class AirSwipe extends AirAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static int stepsize = 4; - - private static int ARC = config.get().getInt("Abilities.Air.AirSwipe.Arc"); - private static int defaultdamage = config.get().getInt("Abilities.Air.AirSwipe.Damage"); - private static double PUSH_FACTOR = config.get().getDouble("Abilities.Air.AirSwipe.Push"); - private static double AFFECTING_RADIUS = config.get().getDouble("Abilities.Air.AirSwipe.Radius"); - private static double RANGE = config.get().getDouble("Abilities.Air.AirSwipe.Range"); - private static double SPEED = config.get().getDouble("Abilities.Air.AirSwipe.Speed"); - private static double MAX_FACTOR = config.get().getDouble("Abilities.Air.AirSwipe.ChargeFactor"); - private static byte full = AirBlast.full; - private static long MAX_CHARGE_TIME = config.get().getLong("Abilities.Air.AirSwipe.MaxChargeTime"); - private static Integer[] breakables = { 6, 31, 32, 37, 38, 39, 40, 59, 81, 83, 106, 175 }; - - private final int MAX_AFFECTABLE_ENTITIES = 10; - - private double speedfactor; + private static final Integer[] BREAKABLES = { 6, 31, 32, 37, 38, 39, 40, 59, 81, 83, 106, 175 }; + private static byte FULL_LIQUID_DATA = 0x0; + private static final int STEP_SIZE = 4; + // Limiting the entities reduces the risk of crashing + private static final int MAX_AFFECTABLE_ENTITIES = 10; + private boolean charging; + private int arc; + private int particleCount; + private long maxChargeTime; + private long cooldown; + private double damage; + private double pushFactor; + private double speed; + private double range; + private double radius; + private double maxChargeFactor; private Location origin; - private Player player; - private boolean charging = false; - private long time; - private double damage = defaultdamage; - private double pushfactor = PUSH_FACTOR; - private double speed = SPEED; - private double range = RANGE; - private double maxfactor = MAX_FACTOR; - private double affectingradius = AFFECTING_RADIUS; - private int arc = ARC; - private long maxchargetime = MAX_CHARGE_TIME; - private ConcurrentHashMap elements = new ConcurrentHashMap(); - private ArrayList affectedentities = new ArrayList(); - + private Random random; + private ConcurrentHashMap elements; + private ArrayList affectedEntities; + public AirSwipe(Player player) { this(player, false); } public AirSwipe(Player player, boolean charging) { - /* Initial Check */ - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("AirSwipe")) - return; - if (player.getEyeLocation().getBlock().isLiquid()) { + super(player); + + this.charging = charging; + this.origin = player.getEyeLocation(); + this.charging = false; + this.particleCount = 3; + this.arc = getConfig().getInt("Abilities.Air.AirSwipe.Arc"); + this.maxChargeTime = getConfig().getLong("Abilities.Air.AirSwipe.MaxChargeTime"); + this.cooldown = getConfig().getLong("Abilities.Air.AirSwipe.Cooldown"); + this.damage = getConfig().getDouble("Abilities.Air.AirSwipe.Damage"); + this.pushFactor = getConfig().getDouble("Abilities.Air.AirSwipe.Push"); + this.speed = getConfig().getDouble("Abilities.Air.AirSwipe.Speed") * (ProjectKorra.time_step / 1000.0); + this.range = getConfig().getDouble("Abilities.Air.AirSwipe.Range"); + this.radius = getConfig().getDouble("Abilities.Air.AirSwipe.Radius"); + this.maxChargeFactor = getConfig().getDouble("Abilities.Air.AirSwipe.chargeFactor"); + this.random = new Random(); + this.elements = new ConcurrentHashMap<>(); + this.affectedEntities = new ArrayList<>(); + + if (bPlayer.isOnCooldown(this) || player.getEyeLocation().getBlock().isLiquid()) { return; } - /* End Initial Check */ - // reloadVariables(); - this.player = player; - this.charging = charging; - origin = player.getEyeLocation(); - time = System.currentTimeMillis(); - - instances.put(player, this); - - bPlayer.addCooldown("AirSwipe", ProjectKorra.plugin.getConfig().getLong("Abilities.Air.AirSwipe.Cooldown")); - - if (!charging) + + if (!charging) { launch(); - } - - public static void charge(Player player) { - new AirSwipe(player, true); + } + start(); + bPlayer.addCooldown(this); } public static boolean removeSwipesAroundPoint(Location loc, double radius) { boolean removed = false; - for (AirSwipe aswipe : instances.values()) { + for (AirSwipe aswipe : CoreAbility.getAbilities(AirSwipe.class)) { for (Vector vec : aswipe.elements.keySet()) { Location vectorLoc = aswipe.elements.get(vec); if (vectorLoc != null && vectorLoc.getWorld().equals(loc.getWorld())) { - if (vectorLoc.distance(loc) <= radius) { - // instances.remove(aswipe.uuid); + if (vectorLoc.distanceSquared(loc) <= radius * radius) { aswipe.remove(); removed = true; } @@ -114,24 +106,23 @@ public class AirSwipe implements ConfigLoadable { @SuppressWarnings("deprecation") private void advanceSwipe() { - affectedentities.clear(); + affectedEntities.clear(); for (Vector direction : elements.keySet()) { Location location = elements.get(direction); if (direction != null && location != null) { - location = location.clone().add(direction.clone().multiply(speedfactor)); + location = location.clone().add(direction.clone().multiply(speed)); elements.replace(direction, location); - if (location.distance(origin) > range || GeneralMethods.isRegionProtectedFromBuild(player, "AirSwipe", location)) { + if (location.distanceSquared(origin) > range * range + || GeneralMethods.isRegionProtectedFromBuild(this, location)) { elements.remove(direction); } else { - AirMethods.removeAirSpouts(location, player); - WaterMethods.removeWaterSpouts(location, player); - - double radius = FireBlast.AFFECTING_RADIUS; - Player source = player; - if (EarthBlast.annihilateBlasts(location, radius, source) - || WaterManipulation.annihilateBlasts(location, radius, source) - || FireBlast.annihilateBlasts(location, radius, source) + removeAirSpouts(location, player); + WaterAbility.removeWaterSpouts(location, player); + + if (EarthBlast.annihilateBlasts(location, radius, player) + || WaterManipulation.annihilateBlasts(location, radius, player) + || FireBlast.annihilateBlasts(location, radius, player) || Combustion.removeAroundPoint(location, radius)) { elements.remove(direction); damage = 0; @@ -140,7 +131,7 @@ public class AirSwipe implements ConfigLoadable { } Block block = location.getBlock(); - for (Block testblock : GeneralMethods.getBlocksAroundPoint(location, affectingradius)) { + for (Block testblock : GeneralMethods.getBlocksAroundPoint(location, radius)) { if (testblock.getType() == Material.FIRE) { testblock.setType(Material.AIR); } @@ -155,74 +146,72 @@ public class AirSwipe implements ConfigLoadable { } else { elements.remove(direction); } - if (block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA) { - if (block.getData() == full) { + if (isLava(block)) { + if (block.getData() == FULL_LIQUID_DATA) { block.setType(Material.OBSIDIAN); } else { block.setType(Material.COBBLESTONE); } } } else { - AirMethods.playAirbendingParticles(location, 3, 0.2F, 0.2F, 0); - if (GeneralMethods.rand.nextInt(4) == 0) { - AirMethods.playAirbendingSound(location); + playAirbendingParticles(location, particleCount, 0.2F, 0.2F, 0); + if (random.nextInt(4) == 0) { + playAirbendingSound(location); } affectPeople(location, direction); } } - // } else { - // elements.remove(direction); } - } - if (elements.isEmpty()) { remove(); } } private void affectPeople(Location location, Vector direction) { - WaterMethods.removeWaterSpouts(location, player); - AirMethods.removeAirSpouts(location, player); - final List entities = GeneralMethods.getEntitiesAroundPoint(location, affectingradius); - final List surroundingEntities = GeneralMethods.getEntitiesAroundPoint(location, 4); + WaterAbility.removeWaterSpouts(location, player); + removeAirSpouts(location, player); + final List entities = GeneralMethods.getEntitiesAroundPoint(location, radius); final Vector fDirection = direction; for (int i = 0; i < entities.size(); i++) { final Entity entity = entities.get(i); new BukkitRunnable() { public void run() { - if (GeneralMethods.isRegionProtectedFromBuild(player, "AirSwipe", entity.getLocation())) + if (GeneralMethods.isRegionProtectedFromBuild(AirSwipe.this, entity.getLocation())) { return; + } if (entity.getEntityId() != player.getEntityId() && entity instanceof LivingEntity) { if (entity instanceof Player) { - if (Commands.invincible.contains(((Player) entity).getName())) + if (Commands.invincible.contains(((Player) entity).getName())) { return; - } - if (surroundingEntities.size() < MAX_AFFECTABLE_ENTITIES) { - if (AvatarState.isAvatarState(player)) { - GeneralMethods.setVelocity(entity, fDirection.multiply(AvatarState.getValue(pushfactor))); - } else { - GeneralMethods.setVelocity(entity, fDirection.multiply(pushfactor)); } } - if (entity instanceof LivingEntity && !affectedentities.contains(entity)) { - if (damage != 0) + if (entities.size() < MAX_AFFECTABLE_ENTITIES) { + if (bPlayer.isAvatarState()) { + GeneralMethods.setVelocity(entity, fDirection.multiply(AvatarState.getValue(pushFactor))); + } else { + GeneralMethods.setVelocity(entity, fDirection.multiply(pushFactor)); + } + } + if (entity instanceof LivingEntity && !affectedEntities.contains(entity)) { + if (damage != 0) { GeneralMethods.damageEntity(player, entity, damage, "AirSwipe"); - affectedentities.add(entity); + } + affectedEntities.add(entity); } if (entity instanceof Player) { new Flight((Player) entity, player); } - AirMethods.breakBreathbendingHold(entity); + breakBreathbendingHold(entity); if (elements.containsKey(fDirection)) { elements.remove(fDirection); } } else if (entity.getEntityId() != player.getEntityId() && !(entity instanceof LivingEntity)) { - if (AvatarState.isAvatarState(player)) { - GeneralMethods.setVelocity(entity, fDirection.multiply(AvatarState.getValue(pushfactor))); + if (bPlayer.isAvatarState()) { + GeneralMethods.setVelocity(entity, fDirection.multiply(AvatarState.getValue(pushFactor))); } else { - GeneralMethods.setVelocity(entity, fDirection.multiply(pushfactor)); + GeneralMethods.setVelocity(entity, fDirection.multiply(pushFactor)); } } } @@ -230,46 +219,10 @@ public class AirSwipe implements ConfigLoadable { } } - public double getAffectingradius() { - return affectingradius; - } - - public int getArc() { - return arc; - } - - public double getDamage() { - return damage; - } - - public long getMaxchargetime() { - return maxchargetime; - } - - public double getMaxfactor() { - return maxfactor; - } - - public Player getPlayer() { - return player; - } - - public double getPushfactor() { - return pushfactor; - } - - public double getRange() { - return range; - } - - public double getSpeed() { - return speed; - } - @SuppressWarnings("deprecation") private boolean isBlockBreakable(Block block) { Integer id = block.getTypeId(); - if (Arrays.asList(breakables).contains(id) && !Illumination.blocks.containsKey(block)) { + if (Arrays.asList(BREAKABLES).contains(id) && !Illumination.getBlocks().containsKey(block)) { return true; } return false; @@ -277,7 +230,7 @@ public class AirSwipe implements ConfigLoadable { private void launch() { origin = player.getEyeLocation(); - for (int i = -arc; i <= arc; i += stepsize) { + for (int i = -arc; i <= arc; i += STEP_SIZE) { double angle = Math.toRadians((double) i); Vector direction = player.getEyeLocation().getDirection().clone(); @@ -295,110 +248,169 @@ public class AirSwipe implements ConfigLoadable { } } - public boolean progress() { + public void progress() { if (player.isDead() || !player.isOnline()) { remove(); - return false; + return; } - speedfactor = speed * (ProjectKorra.time_step / 1000.); + if (!charging) { if (elements.isEmpty()) { remove(); - return false; + return; } - advanceSwipe(); } else { - if (GeneralMethods.getBoundAbility(player) == null) { + if (!bPlayer.canBend(this)) { remove(); - return false; - } - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirSwipe") - || !GeneralMethods.canBend(player.getName(), "AirSwipe")) { - remove(); - return false; + return; } if (!player.isSneaking()) { double factor = 1; - if (System.currentTimeMillis() >= time + maxchargetime) { - factor = maxfactor; - } else if (AvatarState.isAvatarState(player)) { + if (System.currentTimeMillis() >= startTime + maxChargeTime) { + factor = maxChargeFactor; + } else if (bPlayer.isAvatarState()) { factor = AvatarState.getValue(factor); } else { - factor = maxfactor * (double) (System.currentTimeMillis() - time) / (double) maxchargetime; + factor = maxChargeFactor * (double) (System.currentTimeMillis() - startTime) / (double) maxChargeTime; } + charging = false; launch(); - if (factor < 1) - factor = 1; + factor = Math.max(1, factor); damage *= factor; - pushfactor *= factor; - return true; - } else if (System.currentTimeMillis() >= time + maxchargetime) { - AirMethods.playAirbendingParticles(player.getEyeLocation(), 3); + pushFactor *= factor; + return; + } else if (System.currentTimeMillis() >= startTime + maxChargeTime) { + playAirbendingParticles(player.getEyeLocation(), particleCount); } } - return true; - } - - public static void progressAll() { - for (AirSwipe ability : instances.values()) { - ability.progress(); - } - } - - public void remove() { - instances.remove(player); - } - - public static void removeAll() { - for (AirSwipe ability : instances.values()) { - ability.remove(); - } } @Override - public void reloadVariables() { - ARC = config.get().getInt("Abilities.Air.AirSwipe.Arc"); - defaultdamage = config.get().getInt("Abilities.Air.AirSwipe.Damage"); - PUSH_FACTOR = config.get().getDouble("Abilities.Air.AirSwipe.Push"); - AFFECTING_RADIUS = config.get().getDouble("Abilities.Air.AirSwipe.Radius"); - RANGE = config.get().getDouble("Abilities.Air.AirSwipe.Range"); - SPEED = config.get().getDouble("Abilities.Air.AirSwipe.Speed"); - MAX_FACTOR = config.get().getDouble("Abilities.Air.AirSwipe.ChargeFactor"); - MAX_CHARGE_TIME = config.get().getLong("Abilities.Air.AirSwipe.MaxChargeTime"); + public String getName() { + return "AirSwipe"; } - public void setAffectingradius(double affectingradius) { - this.affectingradius = affectingradius; + @Override + public Location getLocation() { + return elements.size() != 0 ? elements.values().iterator().next() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public boolean isCharging() { + return charging; + } + + public void setCharging(boolean charging) { + this.charging = charging; + } + + public int getArc() { + return arc; } public void setArc(int arc) { this.arc = arc; } + public int getParticleCount() { + return particleCount; + } + + public void setParticleCount(int particleCount) { + this.particleCount = particleCount; + } + + public long getMaxChargeTime() { + return maxChargeTime; + } + + public void setMaxChargeTime(long maxChargeTime) { + this.maxChargeTime = maxChargeTime; + } + + public double getDamage() { + return damage; + } + public void setDamage(double damage) { this.damage = damage; } - public void setMaxchargetime(long maxchargetime) { - this.maxchargetime = maxchargetime; + public double getPushFactor() { + return pushFactor; } - public void setMaxfactor(double maxfactor) { - this.maxfactor = maxfactor; + public void setPushFactor(double pushFactor) { + this.pushFactor = pushFactor; } - public void setPushfactor(double pushfactor) { - this.pushfactor = pushfactor; + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public double getRange() { + return range; } public void setRange(double range) { this.range = range; } - public void setSpeed(double speed) { - this.speed = speed; + public double getRadius() { + return radius; } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getMaxChargeFactor() { + return maxChargeFactor; + } + + public void setMaxChargeFactor(double maxChargeFactor) { + this.maxChargeFactor = maxChargeFactor; + } + + public ConcurrentHashMap getElements() { + return elements; + } + + public ArrayList getAffectedEntities() { + return affectedEntities; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/airbending/AirbendingManager.java b/src/com/projectkorra/projectkorra/airbending/AirbendingManager.java index 70699b5e..3fc97ef7 100644 --- a/src/com/projectkorra/projectkorra/airbending/AirbendingManager.java +++ b/src/com/projectkorra/projectkorra/airbending/AirbendingManager.java @@ -2,8 +2,6 @@ package com.projectkorra.projectkorra.airbending; import com.projectkorra.projectkorra.ProjectKorra; -import org.bukkit.Bukkit; - public class AirbendingManager implements Runnable { public ProjectKorra plugin; @@ -14,19 +12,10 @@ public class AirbendingManager implements Runnable { @Override public void run() { - AirBlast.progressAll(); - AirPassive.handlePassive(Bukkit.getServer()); - AirBurst.progressAll(); - AirScooter.progressAll(); - Suffocate.progressAll(); - AirSpout.progressAll(); - AirBubble.handleBubbles(Bukkit.getServer()); - AirSuction.progressAll(); - AirSwipe.progressAll(); - Tornado.progressAll(); - AirShield.progressAll(); - AirCombo.progressAll(); - FlightAbility.progressAll(); + AirBlast.progressOrigins(); + AirPassive.handlePassive(); + AirBubble.handleBubbles(); + AirSuction.progressOrigins(); } } diff --git a/src/com/projectkorra/projectkorra/airbending/FlightAbility.java b/src/com/projectkorra/projectkorra/airbending/FlightAbility.java deleted file mode 100644 index aa349eab..00000000 --- a/src/com/projectkorra/projectkorra/airbending/FlightAbility.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.projectkorra.projectkorra.airbending; - -import java.util.concurrent.ConcurrentHashMap; - -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.util.Flight; - -public class FlightAbility implements ConfigLoadable { - - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static ConcurrentHashMap hits = new ConcurrentHashMap(); - private static ConcurrentHashMap hovering = new ConcurrentHashMap(); - private Player player; - private Flight flight; - - private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Air.Flight.Cooldown"); - - public FlightAbility(Player player) { - this.player = player; - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("Flight")) - return; - if (!AirMethods.canFly(player, true, false)) - return; - if (flight == null) - flight = new Flight(player); - player.setAllowFlight(true); - player.setVelocity(player.getEyeLocation().getDirection().normalize()); - bPlayer.addCooldown("Flight", cooldown); - instances.put(player, this); - } - - public static void addHit(Player player) { - if (contains(player)) { - if (hits.containsKey(player.getName())) { - if (hits.get(player.getName()) >= 4) { - hits.remove(player.getName()); - remove(player); - } - } else { - hits.put(player.getName(), 1); - } - } - } - - public static boolean contains(Player player) { - return instances.containsKey(player); - } - - public static boolean isHovering(Player player) { - return hovering.containsKey(player.getName()); - } - - public static void remove(Player player) { - if (contains(player)) - instances.get(player).remove(); - } - - public static void removeAll() { - for (FlightAbility ability : instances.values()) { - ability.remove(); - } - hits.clear(); - hovering.clear(); - } - - public static void setHovering(Player player, boolean bool) { - String playername = player.getName(); - - if (bool) { - if (!hovering.containsKey(playername)) { - hovering.put(playername, true); - player.setVelocity(new Vector(0, 0, 0)); - } - } else { - if (hovering.containsKey(playername)) { - hovering.remove(playername); - } - } - } - - public boolean progress() { - if (!AirMethods.canFly(player, false, isHovering(player))) { - remove(player); - return false; - } - - if (flight == null) - flight = new Flight(player); - - if (isHovering(player)) { - Vector vec = player.getVelocity().clone(); - vec.setY(0); - player.setVelocity(vec); - } else { - player.setVelocity(player.getEyeLocation().getDirection().normalize()); - } - return true; - } - - public static void progressAll() { - for (FlightAbility ability : instances.values()) { - ability.progress(); - } - } - - @Override - public void reloadVariables() { - } - - public void remove() { - String name = player.getName(); - instances.remove(player); - hits.remove(name); - hovering.remove(name); - if (flight != null) - flight.revert(); - } - -} diff --git a/src/com/projectkorra/projectkorra/airbending/Suffocate.java b/src/com/projectkorra/projectkorra/airbending/Suffocate.java index 32ba22a0..46917cf3 100644 --- a/src/com/projectkorra/projectkorra/airbending/Suffocate.java +++ b/src/com/projectkorra/projectkorra/airbending/Suffocate.java @@ -2,7 +2,6 @@ package com.projectkorra.projectkorra.airbending; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; import org.bukkit.Location; import org.bukkit.entity.Entity; @@ -12,11 +11,11 @@ import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.scheduler.BukkitRunnable; -import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; /** * Suffocate @@ -27,91 +26,68 @@ import com.projectkorra.projectkorra.configuration.ConfigLoadable; * used on multiple entities within a large radius. If the user is damaged while performing this * ability then the ability is removed. */ -public class Suffocate implements ConfigLoadable { +public class Suffocate extends AirAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); + public static enum SpiralType { + HORIZONTAL1, HORIZONTAL2, VERTICAL1, VERTICAL2, DIAGONAL1, DIAGONAL2 + }; - private static boolean CAN_SUFFOCATE_UNDEAD = config.get().getBoolean("Abilities.Air.Suffocate.CanBeUsedOnUndeadMobs"); - private static boolean REQUIRE_CONSTANT_AIM = config.get().getBoolean("Abilities.Air.Suffocate.RequireConstantAim"); - private static double ANIM_RADIUS = config.get().getDouble("Abilities.Air.Suffocate.AnimationRadius"); - private static int ANIM_PARTICLE_AMOUNT = config.get().getInt("Abilities.Air.Suffocate.AnimationParticleAmount"); - - private static double ANIM_SPEED = config.get().getDouble("Abilities.Air.Suffocate.AnimationSpeed"); - private static long CHARGE_TIME = config.get().getLong("Abilities.Air.Suffocate.ChargeTime"); - private static long COOLDOWN = config.get().getLong("Abilities.Air.Suffocate.Cooldown"); - private static double RANGE = config.get().getDouble("Abilities.Air.Suffocate.Range"); - private static double AIM_RADIUS = config.get().getDouble("Abilities.Air.Suffocate.RequireConstantAimRadius"); - private static double DAMAGE = config.get().getDouble("Abilities.Air.Suffocate.Damage"); - private static double DAMAGE_INITIAL_DELAY = config.get().getDouble("Abilities.Air.Suffocate.DamageInitialDelay"); - private static double DAMAGE_INTERVAL = config.get().getDouble("Abilities.Air.Suffocate.DamageInterval"); - private static int SLOW = config.get().getInt("Abilities.Air.Suffocate.SlowPotency"); - private static double SLOW_INTERVAL = config.get().getDouble("Abilities.Air.Suffocate.SlowInterval"); - private static double SLOW_DELAY = config.get().getDouble("Abilities.Air.Suffocate.SlowDelay"); - private static int BLIND = config.get().getInt("Abilities.Air.Suffocate.BlindPotentcy"); - private static double BLIND_DELAY = config.get().getDouble("Abilities.Air.Suffocate.BlindDelay"); - - private static double BLIND_INTERVAL = config.get().getDouble("Abilities.Air.Suffocate.BlindInterval"); - private Player player; - private BendingPlayer bplayer; - private boolean started = false; - private long time; + private boolean started; + private boolean requireConstantAim; + private boolean canSuffocateUndead; + private int particleCount; + private long chargeTime; + private long cooldown; + private double range; + private double radius; + private double damage; + private double damageDelay; + private double damageRepeat; + private double slow; + private double slowRepeat; + private double slowDelay; + private double constantAimRadius; + private double blind; + private double blindDelay; + private double blindRepeat; + private double animationSpeed; private ArrayList tasks; private ArrayList targets; - private boolean reqConstantAim; - private boolean canSuffUndead; - private long chargeTime, cooldown; - private int particleScale; - private double range, radius; - private double speedFactor; - private double aimRadius; - private double damage, damageDelay, damageRepeat; - private double slow, slowRepeat, slowDelay; - - private double blind, blindDelay, blindRepeat; - private Integer[] transparent = {0, 6, 8, 9, 10, 11, 27, 28, 30, 31, 32, - 37, 38, 39, 40, 50, 51, 55, 59, 63, 64, - 65, 66, 68, 69, 70, 71, 72, 75, 76, 77, - 78, 83, 93, 94, 104, 105, 111, 115, 117, - 132, 141, 142, 143, 147, 148, 149, 150, - 157, 175, 176, 177, 183, 184, 185, 187, - 193, 194, 195, 196, 197}; - public Suffocate(Player player) { - this.player = player; - bplayer = GeneralMethods.getBendingPlayer(player.getName()); - targets = new ArrayList(); - tasks = new ArrayList(); - time = System.currentTimeMillis(); - - // reloadVariables(); - reqConstantAim = REQUIRE_CONSTANT_AIM; - canSuffUndead = CAN_SUFFOCATE_UNDEAD; - chargeTime = CHARGE_TIME; - cooldown = COOLDOWN; - particleScale = ANIM_PARTICLE_AMOUNT; - range = RANGE; - radius = ANIM_RADIUS; - speedFactor = ANIM_SPEED; - aimRadius = AIM_RADIUS; - damage = DAMAGE; - damageDelay = DAMAGE_INITIAL_DELAY; - damageRepeat = DAMAGE_INTERVAL; - slow = SLOW; - slowRepeat = SLOW_INTERVAL; - slowDelay = SLOW_DELAY; - blind = BLIND; - blindDelay = BLIND_DELAY; - blindRepeat = BLIND_INTERVAL; - - if (instances.containsKey(player)) { + super(player); + if (bPlayer.isOnCooldown(this)) { + return; + } else if (CoreAbility.hasAbility(player, Suffocate.class)) { return; } - if (AvatarState.isAvatarState(player)) { + this.started = false; + this.requireConstantAim = getConfig().getBoolean("Abilities.Air.Suffocate.RequireConstantAim"); + this.canSuffocateUndead = getConfig().getBoolean("Abilities.Air.Suffocate.CanBeUsedOnUndeadMobs"); + this.particleCount = getConfig().getInt("Abilities.Air.Suffocate.AnimationParticleAmount"); + this.animationSpeed = getConfig().getDouble("Abilities.Air.Suffocate.AnimationSpeed"); + this.chargeTime = getConfig().getLong("Abilities.Air.Suffocate.ChargeTime"); + this.cooldown = getConfig().getLong("Abilities.Air.Suffocate.Cooldown"); + this.range = getConfig().getDouble("Abilities.Air.Suffocate.Range"); + this.radius = getConfig().getDouble("Abilities.Air.Suffocate.AnimationRadius"); + this.constantAimRadius = getConfig().getDouble("Abilities.Air.Suffocate.RequireConstantAimRadius"); + this.damage = getConfig().getDouble("Abilities.Air.Suffocate.Damage"); + this.damageDelay = getConfig().getDouble("Abilities.Air.Suffocate.DamageInitialDelay"); + this.damageRepeat = getConfig().getDouble("Abilities.Air.Suffocate.DamageInterval"); + this.slow = getConfig().getInt("Abilities.Air.Suffocate.SlowPotency"); + this.slowRepeat = getConfig().getDouble("Abilities.Air.Suffocate.SlowInterval"); + this.slowDelay = getConfig().getDouble("Abilities.Air.Suffocate.SlowDelay"); + this.blind = getConfig().getInt("Abilities.Air.Suffocate.BlindPotentcy"); + this.blindDelay = getConfig().getDouble("Abilities.Air.Suffocate.BlindDelay"); + this.blindRepeat = getConfig().getDouble("Abilities.Air.Suffocate.BlindInterval"); + this.targets = new ArrayList(); + this.tasks = new ArrayList(); + + if (bPlayer.isAvatarState()) { cooldown = 0; chargeTime = 0; - reqConstantAim = false; + requireConstantAim = false; damage = AvatarState.getValue(damage); range *= 2; slow = AvatarState.getValue(slow); @@ -119,36 +95,27 @@ public class Suffocate implements ConfigLoadable { blind = AvatarState.getValue(blind); blindRepeat = AvatarState.getValue(blindRepeat); } - if (particleScale < 1) - particleScale = 1; - else if (particleScale > 2) - particleScale = 2; - if (AvatarState.isAvatarState(player)) { - for (Entity ent : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), range)) - if (ent instanceof LivingEntity && !ent.equals(player)) - targets.add((LivingEntity) ent); - } else { - //Entity ent = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); - List entities = new ArrayList(); - for (int i = 0; i < 6; i++) { - Location location = GeneralMethods.getTargetedLocation(player, i, transparent); - entities = GeneralMethods.getEntitiesAroundPoint(location, 1.7); - if (entities.contains(player)) - entities.remove(player); - if (entities != null && !entities.isEmpty() && !entities.contains(player)) { - break; - } - } - if (entities == null || entities.isEmpty()) { - return; - } - Entity target = entities.get(0); - if (target != null && target instanceof LivingEntity) - targets.add((LivingEntity) target); + if (particleCount < 1) { + particleCount = 1; + } else if (particleCount > 2) { + particleCount = 2; } - if (!canSuffUndead) { + if (bPlayer.isAvatarState()) { + for (Entity ent : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), range)) { + if (ent instanceof LivingEntity && !ent.equals(player)) { + targets.add((LivingEntity) ent); + } + } + } else { + Entity ent = GeneralMethods.getTargetedEntity(player, range); + if (ent != null && ent instanceof LivingEntity) { + targets.add((LivingEntity) ent); + } + } + + if (!canSuffocateUndead) { for (int i = 0; i < targets.size(); i++) { LivingEntity target = targets.get(i); if (GeneralMethods.isUndead(target)) { @@ -158,242 +125,18 @@ public class Suffocate implements ConfigLoadable { } } - if (targets.size() == 0) - return; - else if (bplayer.isOnCooldown("suffocate")) - return; - bplayer.addCooldown("suffocate", cooldown); - instances.put(player, this); + bPlayer.addCooldown(this); + start(); } - /** Stops an entity from being suffocated **/ - public static void breakSuffocate(Entity entity) { - for (Suffocate suffocate : instances.values()) { - if (suffocate.targets.contains(entity)) { - suffocate.breakSuffocateLocal(entity); - } - } - } - - /** Checks if an entity is being suffocated **/ - public static boolean isBreathbent(Entity entity) { - for (Suffocate suffocate : instances.values()) { - if (suffocate.targets.contains(entity)) { - return suffocate.started; - } - } - return false; - } - - /** Determines if a player is Suffocating entities **/ - public static boolean isChannelingSphere(Player player) { - return instances.containsKey(player); - } - - /** - * Removes an instance of Suffocate if player is the one suffocating entities - **/ - public static void remove(Player player) { - if (instances.containsKey(player)) { - instances.get(player).remove(); - } - } - - public static void removeAll() { - for (Suffocate ability : instances.values()) { - ability.remove(); - } - } - - /** - * Removes all instances of Suffocate at loc within the radius threshold. The location of a - * Suffocate is defined at the benders location, not the location of the entities being - * suffocated. - * - * @param causer The player causing this instance to be removed - **/ - public static boolean removeAtLocation(Player causer, Location loc, double radius) { - for (Player player : instances.keySet()) { - Suffocate suff = instances.get(player); - if (causer == null || !player.equals(causer)) { - Location playerLoc = suff.getPlayer().getLocation(); - if (playerLoc.getWorld().equals(loc.getWorld()) && playerLoc.distance(loc) <= radius) { - suff.remove(); - return true; - } - } - } - return false; - } - - /** - * Animates this instance of the Suffocate ability. Depending on the specific time (dt) the - * ability will create a different set of SuffocationSpirals. - */ - public void animate() { - long curTime = System.currentTimeMillis(); - long dt = curTime - time - chargeTime; - int steps = 8 * particleScale; - long delay = 2 / particleScale; - long t1 = (long) (1500 * speedFactor); - long t2 = (long) (2500 * speedFactor); - long t3 = (long) (5000 * speedFactor); - long t4 = (long) (6000 * speedFactor); - for (LivingEntity lent : targets) { - final LivingEntity target = lent; - if (dt < t1) { - new SuffocateSpiral(target, steps, radius, delay, 0, 0.25 - (0.25 * (double) dt / (double) t1), 0, - SpiralType.HORIZONTAL1); - new SuffocateSpiral(target, steps, radius, delay, 0, 0.25 - (0.25 * (double) dt / (double) t1), 0, - SpiralType.HORIZONTAL2); - } else if (dt < t2) { - new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.HORIZONTAL1); - new SuffocateSpiral(target, steps * 2, radius, delay, 0, 0, 0, SpiralType.VERTICAL1); - new SuffocateSpiral(target, steps * 2, radius, delay, 0, 0, 0, SpiralType.VERTICAL2); - } else if (dt < t3) { - new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.HORIZONTAL1); - new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.VERTICAL1); - new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.VERTICAL2); - } else if (dt < t4) { - new SuffocateSpiral(target, steps, radius - - Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double) (dt - t3) / (double) (t4 - t3)))), delay, 0, 0, - 0, SpiralType.HORIZONTAL1); - new SuffocateSpiral(target, steps, radius - - Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double) (dt - t3) / (double) (t4 - t3)))), delay, 0, 0, - 0, SpiralType.VERTICAL1); - new SuffocateSpiral(target, steps, radius - - Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double) (dt - t3) / (double) (t4 - t3)))), delay, 0, 0, - 0, SpiralType.VERTICAL2); - } else { - new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.HORIZONTAL1); - new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.VERTICAL1); - new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.VERTICAL2); - } - } - } - - /** Stops an entity from being suffocated **/ - public void breakSuffocateLocal(Entity entity) { - if (targets.contains(entity)) - targets.remove(entity); - } - - public double getAimRadius() { - return aimRadius; - } - - public double getBlind() { - return blind; - } - - public double getBlindDelay() { - return blindDelay; - } - - public double getBlindRepeat() { - return blindRepeat; - } - - public long getChargeTime() { - return chargeTime; - } - - public long getCooldown() { - return cooldown; - } - - public double getDamage() { - return damage; - } - - public double getDamageDelay() { - return damageDelay; - } - - public double getDamageRepeat() { - return damageRepeat; - } - - public int getParticleScale() { - return particleScale; - } - - public Player getPlayer() { - return player; - } - - public double getRadius() { - return radius; - } - - public double getRange() { - return range; - } - - public double getSlow() { - return slow; - } - - public double getSlowDelay() { - return slowDelay; - } - - public double getslowRepeat() { - return slowRepeat; - } - - public double getSpeedFactor() { - return speedFactor; - } - - public ArrayList getTargets() { - return targets; - } - - public ArrayList getTasks() { - return tasks; - } - - public long getTime() { - return time; - } - - public boolean isCanSuffUndead() { - return canSuffUndead; - } - - public boolean isReqConstantAim() { - return reqConstantAim; - } - - public boolean isStarted() { - return started; - } - - /** - * Progresses this instance of Suffocate by 1 tick. - * - * @return true If progress does not stop, progresses succesfully - */ - public boolean progress() { - if (targets.size() == 0) { - remove(); - return false; - } - if (player.isDead() || !player.isOnline()) { - remove(); - return false; - } - String ability = GeneralMethods.getBoundAbility(player); - if (ability == null || !ability.equalsIgnoreCase("Suffocate") || !GeneralMethods.canBend(player.getName(), "Suffocate")) { - remove(); - return false; - } - + @Override + public void progress() { for (int i = 0; i < targets.size(); i++) { LivingEntity target = targets.get(i); - if (target.isDead() || !target.getWorld().equals(player.getWorld()) - || target.getLocation().distance(player.getEyeLocation()) > range) { + if (target.isDead() + || !target.getWorld().equals(player.getWorld()) + || target.getLocation().distanceSquared(player.getEyeLocation()) > range * range + || GeneralMethods.isRegionProtectedFromBuild(this, target.getLocation())) { breakSuffocateLocal(target); i--; } else if (target instanceof Player) { @@ -404,16 +147,16 @@ public class Suffocate implements ConfigLoadable { } } } - if (targets.size() == 0) { + if (targets.size() == 0 || !bPlayer.canBendIgnoreCooldowns(this)) { remove(); - return false; + return; } - if (reqConstantAim) { + if (requireConstantAim) { double dist = player.getEyeLocation().distance(targets.get(0).getEyeLocation()); Location targetLoc = player.getEyeLocation().clone() .add(player.getEyeLocation().getDirection().normalize().multiply(dist)); - List ents = GeneralMethods.getEntitiesAroundPoint(targetLoc, aimRadius); + List ents = GeneralMethods.getEntitiesAroundPoint(targetLoc, constantAimRadius); for (int i = 0; i < targets.size(); i++) { LivingEntity target = targets.get(i); @@ -424,12 +167,12 @@ public class Suffocate implements ConfigLoadable { } if (targets.size() == 0) { remove(); - return false; + return; } } - if (System.currentTimeMillis() - time < chargeTime) { - return false; + if (System.currentTimeMillis() - startTime < chargeTime) { + return; } else if (!started) { started = true; final Player fplayer = player; @@ -466,43 +209,124 @@ public class Suffocate implements ConfigLoadable { animate(); if (!player.isSneaking()) { remove(); + return; + } + } + + /** Stops an entity from being suffocated **/ + public static void breakSuffocate(Entity entity) { + for (Suffocate suffocate : CoreAbility.getAbilities(Suffocate.class)) { + if (suffocate.targets.contains(entity)) { + suffocate.breakSuffocateLocal(entity); + } + } + } + + /** Checks if an entity is being suffocated **/ + public static boolean isBreathbent(Entity entity) { + for (Suffocate suffocate : CoreAbility.getAbilities(Suffocate.class)) { + if (suffocate.targets.contains(entity)) { + return suffocate.started; + } + } + return false; + } + + /** Determines if a player is Suffocating entities **/ + public static boolean isChannelingSphere(Player player) { + return CoreAbility.hasAbility(player, Suffocate.class); + } + + /** + * Removes an instance of Suffocate if player is the one suffocating entities + **/ + public static void remove(Player player) { + Suffocate suff = CoreAbility.getAbility(player, Suffocate.class); + if (suff != null) { + suff.remove(); + } + } + + /** + * Removes all instances of Suffocate at loc within the radius threshold. The location of a + * Suffocate is defined at the benders location, not the location of the entities being + * suffocated. + * + * @param causer The player causing this instance to be removed + **/ + public static boolean removeAtLocation(Player causer, Location loc, double radius) { + if (causer == null) { return false; } - return true; + for (Suffocate suff : CoreAbility.getAbilities(Suffocate.class)) { + if (!suff.player.equals(causer)) { + Location playerLoc = suff.getPlayer().getLocation(); + if (playerLoc.getWorld().equals(loc.getWorld()) && playerLoc.distanceSquared(loc) <= radius * radius) { + suff.remove(); + return true; + } + } + } + return false; } - public static void progressAll() { - for (Suffocate ability : instances.values()) { - ability.progress(); + /** + * Animates this instance of the Suffocate ability. Depending on the specific time (dt) the + * ability will create a different set of SuffocationSpirals. + */ + public void animate() { + int steps = 8 * particleCount; + long curTime = System.currentTimeMillis(); + long dt = curTime - startTime - chargeTime; + long delay = 2 / particleCount; + long t1 = (long) (1500 * animationSpeed); + long t2 = (long) (2500 * animationSpeed); + long t3 = (long) (5000 * animationSpeed); + long t4 = (long) (6000 * animationSpeed); + for (LivingEntity lent : targets) { + final LivingEntity target = lent; + if (dt < t1) { + new SuffocateSpiral(target, steps, radius, delay, 0, 0.25 - (0.25 * (double) dt / (double) t1), 0, + SpiralType.HORIZONTAL1); + new SuffocateSpiral(target, steps, radius, delay, 0, 0.25 - (0.25 * (double) dt / (double) t1), 0, + SpiralType.HORIZONTAL2); + } else if (dt < t2) { + new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.HORIZONTAL1); + new SuffocateSpiral(target, steps * 2, radius, delay, 0, 0, 0, SpiralType.VERTICAL1); + new SuffocateSpiral(target, steps * 2, radius, delay, 0, 0, 0, SpiralType.VERTICAL2); + } else if (dt < t3) { + new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.HORIZONTAL1); + new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.VERTICAL1); + new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.VERTICAL2); + } else if (dt < t4) { + new SuffocateSpiral(target, steps, radius + - Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double) (dt - t3) / (double) (t4 - t3)))), delay, 0, 0, + 0, SpiralType.HORIZONTAL1); + new SuffocateSpiral(target, steps, radius + - Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double) (dt - t3) / (double) (t4 - t3)))), delay, 0, 0, + 0, SpiralType.VERTICAL1); + new SuffocateSpiral(target, steps, radius + - Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double) (dt - t3) / (double) (t4 - t3)))), delay, 0, 0, + 0, SpiralType.VERTICAL2); + } else { + new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.HORIZONTAL1); + new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.VERTICAL1); + new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.VERTICAL2); + } } } - @Override - public void reloadVariables() { - CAN_SUFFOCATE_UNDEAD = config.get().getBoolean("Abilities.Air.Suffocate.CanBeUsedOnUndeadMobs"); - REQUIRE_CONSTANT_AIM = config.get().getBoolean("Abilities.Air.Suffocate.RequireConstantAim"); - ANIM_RADIUS = config.get().getDouble("Abilities.Air.Suffocate.AnimationRadius"); - ANIM_PARTICLE_AMOUNT = config.get().getInt("Abilities.Air.Suffocate.AnimationParticleAmount"); - ANIM_SPEED = config.get().getDouble("Abilities.Air.Suffocate.AnimationSpeed"); - - CHARGE_TIME = config.get().getLong("Abilities.Air.Suffocate.ChargeTime"); - COOLDOWN = config.get().getLong("Abilities.Air.Suffocate.Cooldown"); - RANGE = config.get().getDouble("Abilities.Air.Suffocate.Range"); - AIM_RADIUS = config.get().getDouble("Abilities.Air.Suffocate.RequireConstantAimRadius"); - DAMAGE = config.get().getDouble("Abilities.Air.Suffocate.Damage"); - DAMAGE_INITIAL_DELAY = config.get().getDouble("Abilities.Air.Suffocate.DamageInitialDelay"); - DAMAGE_INTERVAL = config.get().getDouble("Abilities.Air.Suffocate.DamageInterval"); - SLOW = config.get().getInt("Abilities.Air.Suffocate.SlowPotency"); - SLOW_INTERVAL = config.get().getDouble("Abilities.Air.Suffocate.SlowInterval"); - SLOW_DELAY = config.get().getDouble("Abilities.Air.Suffocate.SlowDelay"); - BLIND = config.get().getInt("Abilities.Air.Suffocate.BlindPotentcy"); - BLIND_DELAY = config.get().getDouble("Abilities.Air.Suffocate.BlindDelay"); - BLIND_INTERVAL = config.get().getDouble("Abilities.Air.Suffocate.BlindInterval"); + /** Stops an entity from being suffocated **/ + public void breakSuffocateLocal(Entity entity) { + if (targets.contains(entity)) { + targets.remove(entity); + } } /** Removes this instance of the ability **/ + @Override public void remove() { - instances.remove(player); + super.remove(); for (int i = 0; i < tasks.size(); i++) { tasks.get(i).cancel(); tasks.remove(i); @@ -510,98 +334,6 @@ public class Suffocate implements ConfigLoadable { } } - public void setAimRadius(double aimRadius) { - this.aimRadius = aimRadius; - } - - public void setBlind(double blind) { - this.blind = blind; - } - - public void setBlindDelay(double blindDelay) { - this.blindDelay = blindDelay; - } - - public void setBlindRepeat(double blindRepeat) { - this.blindRepeat = blindRepeat; - } - - public void setCanSuffUndead(boolean canSuffUndead) { - this.canSuffUndead = canSuffUndead; - } - - public void setChargeTime(long chargeTime) { - this.chargeTime = chargeTime; - } - - public void setCooldown(long cooldown) { - this.cooldown = cooldown; - } - - public void setDamage(double damage) { - this.damage = damage; - } - - public void setDamageDelay(double damageDelay) { - this.damageDelay = damageDelay; - } - - public void setDamageRepeat(double damageRepeat) { - this.damageRepeat = damageRepeat; - } - - public void setParticleScale(int particleScale) { - this.particleScale = particleScale; - } - - public void setRadius(double radius) { - this.radius = radius; - } - - public void setRange(double range) { - this.range = range; - } - - public void setReqConstantAim(boolean reqConstantAim) { - this.reqConstantAim = reqConstantAim; - } - - public void setSlow(double slow) { - this.slow = slow; - } - - public void setSlowDelay(double slowDelay) { - this.slowDelay = slowDelay; - } - - public void setslowRepeat(double slowRepeat) { - this.slowRepeat = slowRepeat; - } - - public void setSpeedFactor(double speedFactor) { - this.speedFactor = speedFactor; - } - - public void setStarted(boolean started) { - this.started = started; - } - - public void setTargets(ArrayList targets) { - this.targets = targets; - } - - public void setTasks(ArrayList tasks) { - this.tasks = tasks; - } - - public void setTime(long time) { - this.time = time; - } - - public static enum SpiralType { - HORIZONTAL1, HORIZONTAL2, VERTICAL1, VERTICAL2, DIAGONAL1, DIAGONAL2 - }; - /** * ** Animates a Spiral of air particles around a location or a targetted entity. The direction * of the spiral is determined by SpiralType, and each type is calculated independently from one @@ -636,9 +368,8 @@ public class Suffocate implements ConfigLoadable { this.dy = dy; this.dz = dz; this.type = type; - - loc = target.getEyeLocation(); - i = 0; + this.loc = target.getEyeLocation(); + this.i = 0; this.runTaskTimer(ProjectKorra.plugin, 0L, interval); tasks.add(this); } @@ -662,9 +393,8 @@ public class Suffocate implements ConfigLoadable { this.dy = dy; this.dz = dz; this.type = type; - - loc = startLoc.clone(); - i = 0; + this.loc = startLoc.clone(); + this.i = 0; this.runTaskTimer(ProjectKorra.plugin, 0L, interval); tasks.add(this); } @@ -707,10 +437,197 @@ public class Suffocate implements ConfigLoadable { loc.setZ(tempLoc.getZ() + radius * Math.cos(Math.toRadians((double) i / (double) totalSteps * 360))); } - AirMethods.getAirbendingParticles().display(loc, (float) 0, (float) 0, (float) 0, 0, 1); - if (i == totalSteps + 1) + getAirbendingParticles().display(loc, (float) 0, (float) 0, (float) 0, 0, 1); + if (i == totalSteps + 1) { this.cancel(); + } i++; } } + + @Override + public String getName() { + return "Suffocate"; + } + + @Override + public Location getLocation() { + if (targets.size() > 0) { + return targets.get(0).getLocation(); + } else if (player != null) { + return player.getLocation(); + } + return null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isStarted() { + return started; + } + + public void setStarted(boolean started) { + this.started = started; + } + + public boolean isRequireConstantAim() { + return requireConstantAim; + } + + public void setRequireConstantAim(boolean requireConstantAim) { + this.requireConstantAim = requireConstantAim; + } + + public boolean isCanSuffocateUndead() { + return canSuffocateUndead; + } + + public void setCanSuffocateUndead(boolean canSuffocateUndead) { + this.canSuffocateUndead = canSuffocateUndead; + } + + public int getParticleCount() { + return particleCount; + } + + public void setParticleCount(int particleCount) { + this.particleCount = particleCount; + } + + public long getChargeTime() { + return chargeTime; + } + + public void setChargeTime(long chargeTime) { + this.chargeTime = chargeTime; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getDamage() { + return damage; + } + + public void setDamage(double damage) { + this.damage = damage; + } + + public double getDamageDelay() { + return damageDelay; + } + + public void setDamageDelay(double damageDelay) { + this.damageDelay = damageDelay; + } + + public double getDamageRepeat() { + return damageRepeat; + } + + public void setDamageRepeat(double damageRepeat) { + this.damageRepeat = damageRepeat; + } + + public double getSlow() { + return slow; + } + + public void setSlow(double slow) { + this.slow = slow; + } + + public double getSlowRepeat() { + return slowRepeat; + } + + public void setSlowRepeat(double slowRepeat) { + this.slowRepeat = slowRepeat; + } + + public double getSlowDelay() { + return slowDelay; + } + + public void setSlowDelay(double slowDelay) { + this.slowDelay = slowDelay; + } + + public double getConstantAimRadius() { + return constantAimRadius; + } + + public void setConstantAimRadius(double constantAimRadius) { + this.constantAimRadius = constantAimRadius; + } + + public double getBlind() { + return blind; + } + + public void setBlind(double blind) { + this.blind = blind; + } + + public double getBlindDelay() { + return blindDelay; + } + + public void setBlindDelay(double blindDelay) { + this.blindDelay = blindDelay; + } + + public double getBlindRepeat() { + return blindRepeat; + } + + public void setBlindRepeat(double blindRepeat) { + this.blindRepeat = blindRepeat; + } + + public double getAnimationSpeed() { + return animationSpeed; + } + + public void setAnimationSpeed(double animationSpeed) { + this.animationSpeed = animationSpeed; + } + + public ArrayList getTasks() { + return tasks; + } + + public ArrayList getTargets() { + return targets; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } } diff --git a/src/com/projectkorra/projectkorra/airbending/Tornado.java b/src/com/projectkorra/projectkorra/airbending/Tornado.java index f326ec00..53c494b2 100644 --- a/src/com/projectkorra/projectkorra/airbending/Tornado.java +++ b/src/com/projectkorra/projectkorra/airbending/Tornado.java @@ -1,8 +1,9 @@ package com.projectkorra.projectkorra.airbending; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.command.Commands; +import com.projectkorra.projectkorra.util.Flight; import org.bukkit.Location; import org.bukkit.Material; @@ -10,173 +11,98 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.command.Commands; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.util.Flight; +import java.util.HashSet; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; -public class Tornado implements ConfigLoadable { +public class Tornado extends AirAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static double MAX_HEIGHT = config.get().getDouble("Abilities.Air.Tornado.Height"); - private static double PLAYER_PUSH_FACTOR = config.get().getDouble("Abilities.Air.Tornado.PlayerPushFactor"); - private static double MAX_RADIUS = config.get().getDouble("Abilities.Air.Tornado.Radius"); - private static double RANGE = config.get().getDouble("Abilities.Air.Tornado.Range"); - private static double NPC_PUSH_FACTOR = config.get().getDouble("Abilities.Air.Tornado.MobPushFactor"); - private static int numberOfStreams = (int) (.3 * (double) MAX_HEIGHT); - // private static double speed = .75; - // private static double speedfactor = 1000 * speed - // * (Bending.time_step / 1000.); - private static double speedfactor = 1; - - private ConcurrentHashMap angles = new ConcurrentHashMap(); + private int numberOfStreams; + private int particleCount; + private double speed; + private double maxHeight; + private double playerPushFactor; + private double radius; + private double range; + private double npcPushFactor; + private double currentHeight; + private double currentRadius; + private Flight flight; private Location origin; - private Player player; - private double maxheight = MAX_HEIGHT; - private double PCpushfactor = PLAYER_PUSH_FACTOR; - private double maxradius = MAX_RADIUS; - private double range = RANGE; - private double NPCpushfactor = NPC_PUSH_FACTOR; - private double height = 2; - private double radius = height / maxheight * maxradius; - - // private boolean canfly; + private Random random; + private ConcurrentHashMap angles; public Tornado(Player player) { - // reloadVariables(); - this.player = player; - // canfly = player.getAllowFlight(); - // player.setAllowFlight(true); - origin = player.getTargetBlock((HashSet) null, (int) range).getLocation(); - origin.setY(origin.getY() - 1. / 10. * height); + super(player); + + this.origin = player.getTargetBlock((HashSet) null, (int) range).getLocation(); + this.origin.setY(origin.getY() - 1.0 / 10.0 * currentHeight); + this.maxHeight = getConfig().getDouble("Abilities.Air.Tornado.Height"); + this.playerPushFactor = getConfig().getDouble("Abilities.Air.Tornado.PlayerPushFactor"); + this.radius = getConfig().getDouble("Abilities.Air.Tornado.Radius"); + this.range = getConfig().getDouble("Abilities.Air.Tornado.Range"); + this.npcPushFactor = getConfig().getDouble("Abilities.Air.Tornado.MobPushFactor"); + this.speed = 1; + this.numberOfStreams = (int) (.3 * (double) maxHeight); + this.currentHeight = 2; + this.currentRadius = currentHeight / maxHeight * radius; + this.random = new Random(); + this.angles = new ConcurrentHashMap<>(); int angle = 0; - for (int i = 0; i <= maxheight; i += (int) maxheight / numberOfStreams) { + for (int i = 0; i <= maxHeight; i += (int) maxHeight / numberOfStreams) { angles.put(i, angle); angle += 90; - if (angle == 360) + if (angle == 360) { angle = 0; + } } - new Flight(player); + this.flight = new Flight(player); player.setAllowFlight(true); - instances.put(player, this); - } - - public static ArrayList getPlayers() { - ArrayList players = new ArrayList(); - for (Tornado tornado : instances.values()) { - players.add(tornado.getPlayer()); - } - return players; - } - - public double getMaxheight() { - return maxheight; - } - - public double getMaxradius() { - return maxradius; - } - - public double getNPCpushfactor() { - return NPCpushfactor; - } - - public double getPCpushfactor() { - return PCpushfactor; - } - - public Player getPlayer() { - return player; - } - - public double getRange() { - return range; - } - - public boolean progress() { - if (player.isDead() || !player.isOnline()) { - remove(); - return false; - } - if (!GeneralMethods.canBend(player.getName(), "Tornado") || player.getEyeLocation().getBlock().isLiquid()) { - remove(); - return false; - } - String abil = GeneralMethods.getBoundAbility(player); - if (abil == null) { - remove(); - return false; - } - if (!abil.equalsIgnoreCase("Tornado") || !player.isSneaking()) { - remove(); - return false; - } - - if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", origin)) { - remove(); - return false; - } - rotateTornado(); - return true; - } - - public static void progressAll() { - for (Tornado ability : instances.values()) { - ability.progress(); - } - } - - public void remove() { - instances.remove(player); - } - - public static void removeAll() { - for (Tornado ability : instances.values()) { - ability.remove(); - } + start(); } @Override - public void reloadVariables() { - MAX_HEIGHT = config.get().getDouble("Abilities.Air.Tornado.Height"); - PLAYER_PUSH_FACTOR = config.get().getDouble("Abilities.Air.Tornado.PlayerPushFactor"); - MAX_RADIUS = config.get().getDouble("Abilities.Air.Tornado.Radius"); - RANGE = config.get().getDouble("Abilities.Air.Tornado.Range"); - NPC_PUSH_FACTOR = config.get().getDouble("Abilities.Air.Tornado.MobPushFactor"); - numberOfStreams = (int) (.3 * (double) MAX_HEIGHT); - - maxheight = MAX_HEIGHT; - PCpushfactor = PLAYER_PUSH_FACTOR; - maxradius = MAX_RADIUS; - range = RANGE; - NPCpushfactor = NPC_PUSH_FACTOR; - radius = height / maxheight * maxradius; + public void progress() { + if (player.getEyeLocation().getBlock().isLiquid() || !player.isSneaking() || !bPlayer.canBendIgnoreCooldowns(this)) { + remove(); + return; + } else if (GeneralMethods.isRegionProtectedFromBuild(this, origin)) { + remove(); + return; + } + rotateTornado(); + } + + @Override + public void remove() { + super.remove(); + flight.remove(); + player.setAllowFlight(false); } private void rotateTornado() { origin = player.getTargetBlock((HashSet) null, (int) range).getLocation(); - - double timefactor = height / maxheight; - radius = timefactor * maxradius; + double timefactor = currentHeight / maxHeight; + currentRadius = timefactor * radius; if (origin.getBlock().getType() != Material.AIR) { - origin.setY(origin.getY() - 1. / 10. * height); + origin.setY(origin.getY() - 1. / 10. * currentHeight); - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(origin, height)) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", entity.getLocation())) + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(origin, currentHeight)) { + if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) { continue; + } double y = entity.getLocation().getY(); double factor; - if (y > origin.getY() && y < origin.getY() + height) { - factor = (y - origin.getY()) / height; + if (y > origin.getY() && y < origin.getY() + currentHeight) { + factor = (y - origin.getY()) / currentHeight; Location testloc = new Location(origin.getWorld(), origin.getX(), y, origin.getZ()); - if (testloc.distance(entity.getLocation()) < radius * factor) { + if (testloc.distance(entity.getLocation()) < currentRadius * factor) { double x, z, vx, vz, mag; double angle = 100; - double vy = 0.7 * NPCpushfactor; + double vy = 0.7 * npcPushFactor; angle = Math.toRadians(angle); x = entity.getLocation().getX() - origin.getX(); @@ -188,7 +114,7 @@ public class Tornado implements ConfigLoadable { vz = (x * Math.sin(angle) + z * Math.cos(angle)) / mag; if (entity instanceof Player) { - vy = 0.05 * PCpushfactor; + vy = 0.05 * playerPushFactor; } if (entity.getEntityId() == player.getEntityId()) { @@ -199,18 +125,20 @@ public class Tornado implements ConfigLoadable { double py = playerloc.getY(); double oy = origin.getY(); double dy = py - oy; - if (dy >= height * .95) { + + if (dy >= currentHeight * .95) { vy = 0; - } else if (dy >= height * .85) { - vy = 6.0 * (.95 - dy / height); + } else if (dy >= currentHeight * .85) { + vy = 6.0 * (.95 - dy / currentHeight); } else { vy = .6; } } if (entity instanceof Player) { - if (Commands.invincible.contains(((Player) entity).getName())) + if (Commands.invincible.contains(((Player) entity).getName())) { continue; + } } Vector velocity = entity.getVelocity(); @@ -221,7 +149,7 @@ public class Tornado implements ConfigLoadable { GeneralMethods.setVelocity(entity, velocity); entity.setFallDistance(0); - AirMethods.breakBreathbendingHold(entity); + breakBreathbendingHold(entity); if (entity instanceof Player) { new Flight((Player) entity); @@ -231,59 +159,143 @@ public class Tornado implements ConfigLoadable { } for (int i : angles.keySet()) { - double x, y, z; + double x, y, z, factor; double angle = (double) angles.get(i); angle = Math.toRadians(angle); - double factor; y = origin.getY() + timefactor * (double) i; - factor = (double) i / height; + factor = (double) i / currentHeight; - x = origin.getX() + timefactor * factor * radius * Math.cos(angle); - z = origin.getZ() + timefactor * factor * radius * Math.sin(angle); + x = origin.getX() + timefactor * factor * currentRadius * Math.cos(angle); + z = origin.getZ() + timefactor * factor * currentRadius * Math.sin(angle); Location effect = new Location(origin.getWorld(), x, y, z); - if (!GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", effect)) { - AirMethods.playAirbendingParticles(effect, 4); - if (GeneralMethods.rand.nextInt(20) == 0) { - AirMethods.playAirbendingSound(effect); + if (!GeneralMethods.isRegionProtectedFromBuild(this, effect)) { + playAirbendingParticles(effect, particleCount); + if (random.nextInt(20) == 0) { + playAirbendingSound(effect); } } - // origin.getWorld().playEffect(effect, Effect.SMOKE, 4, (int) - // AirBlast.defaultrange); - - angles.put(i, angles.get(i) + 25 * (int) speedfactor); + angles.put(i, angles.get(i) + 25 * (int) speed); } } - - if (height < maxheight) { - height += 1; - } - - if (height > maxheight) { - height = maxheight; - } - + currentHeight = currentHeight > maxHeight ? maxHeight : currentHeight + 1; } - public void setMaxheight(double maxheight) { - this.maxheight = maxheight; + @Override + public String getName() { + return "Tornado"; } - public void setMaxradius(double maxradius) { - this.maxradius = maxradius; + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; } - public void setNPCpushfactor(double nPCpushfactor) { - NPCpushfactor = nPCpushfactor; + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return true; } - public void setPCpushfactor(double pCpushfactor) { - PCpushfactor = pCpushfactor; + @Override + public boolean isHarmlessAbility() { + return false; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public int getNumberOfStreams() { + return numberOfStreams; + } + + public void setNumberOfStreams(int numberOfStreams) { + this.numberOfStreams = numberOfStreams; + } + + public int getParticleCount() { + return particleCount; + } + + public void setParticleCount(int particleCount) { + this.particleCount = particleCount; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public double getMaxHeight() { + return maxHeight; + } + + public void setMaxHeight(double maxHeight) { + this.maxHeight = maxHeight; + } + + public double getPlayerPushFactor() { + return playerPushFactor; + } + + public void setPlayerPushFactor(double playerPushFactor) { + this.playerPushFactor = playerPushFactor; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getRange() { + return range; } public void setRange(double range) { this.range = range; } + public double getNpcPushFactor() { + return npcPushFactor; + } + + public void setNpcPushFactor(double npcPushFactor) { + this.npcPushFactor = npcPushFactor; + } + + public double getCurrentHeight() { + return currentHeight; + } + + public void setCurrentHeight(double currentHeight) { + this.currentHeight = currentHeight; + } + + public double getCurrentRadius() { + return currentRadius; + } + + public void setCurrentRadius(double currentRadius) { + this.currentRadius = currentRadius; + } + + public ConcurrentHashMap getAngles() { + return angles; + } } diff --git a/src/com/projectkorra/projectkorra/avatar/AvatarState.java b/src/com/projectkorra/projectkorra/avatar/AvatarState.java new file mode 100644 index 00000000..f779f0a3 --- /dev/null +++ b/src/com/projectkorra/projectkorra/avatar/AvatarState.java @@ -0,0 +1,232 @@ +package com.projectkorra.projectkorra.avatar; + +import com.projectkorra.projectkorra.ability.AvatarAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.util.Flight; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.HashMap; + +public class AvatarState extends AvatarAbility { + + private static final HashMap START_TIMES = new HashMap<>(); + + private boolean regenEnabled; + private boolean speedEnabled; + private boolean resistanceEnabled; + private boolean fireResistanceEnabled; + private int regenPower; + private int speedPower; + private int resistancePower; + private int fireResistancePower; + private long duration; + private long cooldown; + private double factor; + + public AvatarState(Player player) { + super(player); + + AvatarState oldAbil = CoreAbility.getAbility(player, AvatarState.class); + if (oldAbil != null) { + oldAbil.remove(); + return; + } else if (bPlayer.isOnCooldown(this)) { + return; + } + + this.regenEnabled = getConfig().getBoolean("Abilities.AvatarState.PotionEffects.Regeneration.Enabled"); + this.speedEnabled = getConfig().getBoolean("Abilities.AvatarState.PotionEffects.Speed.Enabled"); + this.resistanceEnabled = getConfig().getBoolean("Abilities.AvatarState.PotionEffects.DamageResistance.Enabled"); + this.fireResistanceEnabled = getConfig().getBoolean("Abilities.AvatarState.PotionEffects.FireResistance.Enabled"); + this.regenPower = getConfig().getInt("Abilities.AvatarState.PotionEffects.Regeneration.Power") - 1; + this.speedPower = getConfig().getInt("Abilities.AvatarState.PotionEffects.Speed.Power") - 1; + this.resistancePower = getConfig().getInt("Abilities.AvatarState.PotionEffects.DamageResistance.Power") - 1; + this.fireResistancePower = getConfig().getInt("Abilities.AvatarState.PotionEffects.FireResistance.Power") - 1; + this.duration = getConfig().getLong("Abilities.AvatarState.Duration"); + this.cooldown = getConfig().getLong("Abilities.AvatarState.Cooldown"); + this.factor = getConfig().getDouble("Abilities.AvatarState.PowerMultiplier"); + + new Flight(player); + playAvatarSound(player.getLocation()); + + start(); + bPlayer.addCooldown(this); + if (duration != 0) { + START_TIMES.put(player.getName(), System.currentTimeMillis()); + } + } + + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { + if (player != null) { + if (bPlayer.isOnCooldown(this)) { + bPlayer.removeCooldown(this); + } + } + remove(); + return; + } + + if (START_TIMES.containsKey(player.getName())) { + if (START_TIMES.get(player.getName()) + duration < System.currentTimeMillis()) { + START_TIMES.remove(player.getName()); + remove(); + return; + } + } + + addPotionEffects(); + } + + private void addPotionEffects() { + int duration = 70; + if (regenEnabled) { + player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, duration, regenPower)); + } + if (speedEnabled) { + player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, duration, speedPower)); + } + if (resistanceEnabled) { + player.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, duration, resistancePower)); + } + if (fireResistanceEnabled) { + player.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, duration, fireResistancePower)); + } + } + + public static double getValue(double value) { + double factor = getConfig().getDouble("Abilities.AvatarState.PowerMultiplier"); + return factor * value; + } + + public static int getValue(int value) { + return (int) getValue((double) value); + } + + public static double getValue(double value, Player player) { + AvatarState astate = getAbility(player, AvatarState.class); + if (astate != null) { + return astate.getFactor() * value; + } + return value; + } + + @Override + public String getName() { + return "AvatarState"; + } + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return true; + } + + public boolean isRegenEnabled() { + return regenEnabled; + } + + public void setRegenEnabled(boolean regenEnabled) { + this.regenEnabled = regenEnabled; + } + + public boolean isSpeedEnabled() { + return speedEnabled; + } + + public void setSpeedEnabled(boolean speedEnabled) { + this.speedEnabled = speedEnabled; + } + + public boolean isResistanceEnabled() { + return resistanceEnabled; + } + + public void setResistanceEnabled(boolean resistanceEnabled) { + this.resistanceEnabled = resistanceEnabled; + } + + public boolean isFireResistanceEnabled() { + return fireResistanceEnabled; + } + + public void setFireResistanceEnabled(boolean fireResistanceEnabled) { + this.fireResistanceEnabled = fireResistanceEnabled; + } + + public int getRegenPower() { + return regenPower; + } + + public void setRegenPower(int regenPower) { + this.regenPower = regenPower; + } + + public int getSpeedPower() { + return speedPower; + } + + public void setSpeedPower(int speedPower) { + this.speedPower = speedPower; + } + + public int getResistancePower() { + return resistancePower; + } + + public void setResistancePower(int resistancePower) { + this.resistancePower = resistancePower; + } + + public int getFireResistancePower() { + return fireResistancePower; + } + + public void setFireResistancePower(int fireResistancePower) { + this.fireResistancePower = fireResistancePower; + } + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + public double getFactor() { + return factor; + } + + public void setFactor(double factor) { + this.factor = factor; + } + + public static HashMap getStartTimes() { + return START_TIMES; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + +} diff --git a/src/com/projectkorra/projectkorra/chiblocking/AcrobatStance.java b/src/com/projectkorra/projectkorra/chiblocking/AcrobatStance.java index d391e14b..c573db5a 100644 --- a/src/com/projectkorra/projectkorra/chiblocking/AcrobatStance.java +++ b/src/com/projectkorra/projectkorra/chiblocking/AcrobatStance.java @@ -1,105 +1,75 @@ package com.projectkorra.projectkorra.chiblocking; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.earthbending.MetalClips; -import com.projectkorra.projectkorra.waterbending.Bloodbending; +import com.projectkorra.projectkorra.ability.ChiAbility; +import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import java.util.concurrent.ConcurrentHashMap; - -public class AcrobatStance { - - public static double CHI_BLOCK_BOOST = ProjectKorra.plugin.getConfig().getDouble("Abilities.Chi.AcrobatStance.ChiBlockBoost"); - public static double PARA_DODGE_BOOST = ProjectKorra.plugin.getConfig().getDouble("Abilities.Chi.AcrobatStance.ParalyzeChanceDecrease"); - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - - private Player player; - public double chiBlockBost = CHI_BLOCK_BOOST; - public double paralyzeDodgeBoost = PARA_DODGE_BOOST; - public int speed = ChiPassive.speedPower + 1; - public int jump = ChiPassive.jumpPower + 1; - +public class AcrobatStance extends ChiAbility { + + private int speed; + private int jump; + private double chiBlockBoost; + private double paralyzeDodgeBoost; + public AcrobatStance(Player player) { - this.player = player; - if (instances.containsKey(player)) { - instances.remove(player); - return; + super(player); + + this.chiBlockBoost = getConfig().getDouble("Abilities.Chi.AcrobatStance.ChiBlockBoost"); + this.paralyzeDodgeBoost = getConfig().getDouble("Abilities.Chi.AcrobatStance.ParalyzeChanceDecrease"); + this.speed = ChiPassive.getSpeedPower() + 1; + this.jump = ChiPassive.getJumpPower() + 1; + + ChiAbility stance = bPlayer.getStance(); + if (stance != null && !(stance instanceof AcrobatStance)) { + stance.remove(); + bPlayer.setStance(this); } - - if (WarriorStance.isInWarriorStance(player)) { - WarriorStance.remove(player); - } - - instances.put(player, this); + start(); } + @Override public void progress() { - if (player.isDead() || !player.isOnline()) { + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { remove(); return; } - - if (!GeneralMethods.canBend(player.getName(), "AcrobatStance")) { - remove(); - return; - } - - if (MetalClips.isControlled(player) || Paralyze.isParalyzed(player) || Bloodbending.isBloodbended(player)) { - remove(); - return; - } - + if (!player.hasPotionEffect(PotionEffectType.SPEED)) { player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 60, speed)); } - if (!player.hasPotionEffect(PotionEffectType.JUMP)) { player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 60, jump)); } } - - public static void progressAll() { - for (Player player : instances.keySet()) { - instances.get(player).progress(); - } + + @Override + public String getName() { + return "AcrobatStance"; } - private void remove() { - instances.remove(player); + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; } - public static void remove(Player player) { - instances.remove(player); + @Override + public long getCooldown() { + return 0; } - public static boolean isInAcrobatStance(Player player) { - return instances.containsKey(player); + @Override + public boolean isSneakAbility() { + return false; } - public double getChiBlockBost() { - return chiBlockBost; + @Override + public boolean isHarmlessAbility() { + return true; } - - public void setChiBlockBost(double chiBlockBost) { - this.chiBlockBost = chiBlockBost; - } - - public double getParalyzeDodgeBoost() { - return paralyzeDodgeBoost; - } - - public void setParalyzeDodgeBoost(double paralyzeDodgeBoost) { - this.paralyzeDodgeBoost = paralyzeDodgeBoost; - } - - public Player getPlayer() { - return player; - } - + public int getSpeed() { return speed; } @@ -115,4 +85,21 @@ public class AcrobatStance { public void setJump(int jump) { this.jump = jump; } + + public double getChiBlockBoost() { + return chiBlockBoost; + } + + public void setChiBlockBoost(double chiBlockBoost) { + this.chiBlockBoost = chiBlockBoost; + } + + public double getParalyzeDodgeBoost() { + return paralyzeDodgeBoost; + } + + public void setParalyzeDodgeBoost(double paralyzeDodgeBoost) { + this.paralyzeDodgeBoost = paralyzeDodgeBoost; + } + } diff --git a/src/com/projectkorra/projectkorra/chiblocking/ChiCombo.java b/src/com/projectkorra/projectkorra/chiblocking/ChiCombo.java index 81a99f2b..e6992a04 100644 --- a/src/com/projectkorra/projectkorra/chiblocking/ChiCombo.java +++ b/src/com/projectkorra/projectkorra/chiblocking/ChiCombo.java @@ -1,51 +1,54 @@ package com.projectkorra.projectkorra.chiblocking; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.ChiAbility; +import com.projectkorra.projectkorra.ability.ComboAbility; +import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation; +import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; -/** - * A representation of all chi combo moves. - * @author kingbirdy - * +/* + * TODO: Combo classes should eventually be rewritten so that each combo is treated + * as an individual ability. In the mean time, we will just place "fake" + * classes so that CoreAbility will register each ability. */ -public class ChiCombo { +public class ChiCombo extends ChiAbility implements ComboAbility { - private static boolean enabled = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Chi.ChiCombo.Enabled"); - - public static long IMMOBILIZE_DURATION = ProjectKorra.plugin.getConfig().getLong("Abilities.Chi.ChiCombo.Immobilize.ParalyzeDuration"); - public static long IMMOBILIZE_COOLDOWN = ProjectKorra.plugin.getConfig().getLong("Abilities.Chi.ChiCombo.Immobilize.Cooldown"); - /** - * A List of every instance of an active {@link ChiCombo}. - */ - public static List instances = new ArrayList(); /** * a Map containing every entity which is paralyzed, and the time in milliseconds at which they will be unparalyzed. */ - public static Map paralyzedEntities = new HashMap(); + private static final ConcurrentHashMap PARALYZED_ENTITIES = new ConcurrentHashMap<>(); - //private Player player; + private boolean enabled; + private long duration; + private long cooldown; private Entity target; + private String name; public ChiCombo(Player player, String ability) { - if (!enabled) + super(player); + + this.name = ability; + this.enabled = getConfig().getBoolean("Abilities.Chi.ChiCombo.Enabled"); + + if (!enabled) { return; + } if (ability.equalsIgnoreCase("Immobilize")) { - if (!GeneralMethods.canBend(player.getName(), "Immobilize") || GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("Immobilize")) + this.cooldown = getConfig().getLong("Abilities.Chi.ChiCombo.Immobilize.Cooldown"); + this.duration = getConfig().getLong("Abilities.Chi.ChiCombo.Immobilize.ParalyzeDuration"); + if (!bPlayer.canBendIgnoreBinds(this)) { return; - else { - //this.player = player; - target = GeneralMethods.getTargetedEntity(player, 5, new ArrayList()); - paralyze(target, IMMOBILIZE_DURATION); - instances.add(this); - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("Immobilize", IMMOBILIZE_COOLDOWN); + } else { + target = GeneralMethods.getTargetedEntity(player, 5); + paralyze(target, duration); + start(); + bPlayer.addCooldown(this); } } } @@ -57,7 +60,7 @@ public class ChiCombo { * @param duration The time in milliseconds the target will be paralyzed */ private static void paralyze(Entity target, Long duration) { - paralyzedEntities.put(target, (System.currentTimeMillis() + duration)); + PARALYZED_ENTITIES.put(target, (System.currentTimeMillis() + duration)); } /** @@ -78,34 +81,124 @@ public class ChiCombo { * @return True if the entity is paralyzed, false otherwise */ public static boolean isParalyzed(Entity entity) { - return paralyzedEntities.containsKey(entity); + return PARALYZED_ENTITIES.containsKey(entity); } /** * Checks the status of all paralyzed entities. If their paralysis has expired, - * it removes them from {@link ChiCombo#paralyzedEntities paralyzedEntities} and + * it removes them from {@link ChiCombo#PARALYZED_ENTITIES paralyzedEntities} and * removes the instance of the combo from {@link ChiCombo#instances instances}. */ public static void handleParalysis() { - for (Entity e : paralyzedEntities.keySet()) { - if (paralyzedEntities.get(e) <= System.currentTimeMillis()) { - paralyzedEntities.remove(e); - List remove = new ArrayList(); - for (ChiCombo c : instances) { - if (e == null || c.target == null) { - remove.add(instances.indexOf(c)); - continue; + for (Entity entity : PARALYZED_ENTITIES.keySet()) { + if (PARALYZED_ENTITIES.get(entity) <= System.currentTimeMillis()) { + PARALYZED_ENTITIES.remove(entity); + + for (ChiCombo combo : getAbilities(ChiCombo.class)) { + if (combo.target.equals(entity)) { + combo.remove(); } - if (c.target.equals(e)) - remove.add(instances.indexOf(c)); - } - for (int i : remove) { - if (i >= instances.size()) { - continue; - } - instances.remove(i); } } } } + + @Override + public String getName() { + return name != null ? name : "ChiCombo"; + } + + @Override + public void progress() { + } + + @Override + public Location getLocation() { + return target != null ? target.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isHiddenAbility() { + return true; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + + @Override + public String getInstructions() { + return null; + } + + @Override + public Object createNewComboInstance(Player player) { + return null; + } + + @Override + public ArrayList getCombination() { + return null; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + public Entity getTarget() { + return target; + } + + public void setTarget(Entity target) { + this.target = target; + } + + public static ConcurrentHashMap getParalyzedEntities() { + return PARALYZED_ENTITIES; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setName(String name) { + this.name = name; + } + + public class Immobilize extends ChiCombo { + + public Immobilize(Player player, String name) { + super(player, "Immobilize"); + } + + @Override + public String getName() { + return "Immobilize"; + } + } + } diff --git a/src/com/projectkorra/projectkorra/chiblocking/ChiMethods.java b/src/com/projectkorra/projectkorra/chiblocking/ChiMethods.java deleted file mode 100644 index 03800539..00000000 --- a/src/com/projectkorra/projectkorra/chiblocking/ChiMethods.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.projectkorra.projectkorra.chiblocking; - -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AbilityModuleManager; - -import org.bukkit.ChatColor; -import org.bukkit.configuration.file.FileConfiguration; - -public class ChiMethods { - - static ProjectKorra plugin; - private static FileConfiguration config = ProjectKorra.plugin.getConfig(); - - public ChiMethods(ProjectKorra plugin) { - ChiMethods.plugin = plugin; - } - - /** - * Gets the ChiColor from the config. - * - * @return Config specified ChatColor - */ - public static ChatColor getChiColor() { - return ChatColor.valueOf(config.getString("Properties.Chat.Colors.Chi")); - } - - /** - * Checks whether an ability is a chi ability. - * - * @param ability The ability to check - * @return true If the ability is a chi ability. - */ - public static boolean isChiAbility(String ability) { - return AbilityModuleManager.chiabilities.contains(ability); - } - - /** - * Checks whether a player is chiblocked. - * - * @param player The player to check - * @return true If the player is chiblocked. - */ - public static boolean isChiBlocked(String player) { - if (GeneralMethods.getBendingPlayer(player) != null) { - return GeneralMethods.getBendingPlayer(player).isChiBlocked(); - } - return false; - } - - public static void stopBending() { - RapidPunch.instances.clear(); - WarriorStance.instances.clear(); - AcrobatStance.instances.clear(); - } -} diff --git a/src/com/projectkorra/projectkorra/chiblocking/ChiPassive.java b/src/com/projectkorra/projectkorra/chiblocking/ChiPassive.java index d716e496..154005a9 100644 --- a/src/com/projectkorra/projectkorra/chiblocking/ChiPassive.java +++ b/src/com/projectkorra/projectkorra/chiblocking/ChiPassive.java @@ -2,42 +2,43 @@ package com.projectkorra.projectkorra.chiblocking; import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.ChiAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; import com.projectkorra.projectkorra.airbending.Suffocate; +import com.projectkorra.projectkorra.configuration.ConfigManager; import org.bukkit.Bukkit; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; public class ChiPassive { - private static FileConfiguration config = ProjectKorra.plugin.getConfig(); - - public static double FallReductionFactor = config.getDouble("Abilities.Chi.Passive.FallReductionFactor"); - public static int jumpPower = config.getInt("Abilities.Chi.Passive.Jump"); - public static int speedPower = config.getInt("Abilities.Chi.Passive.Speed"); - public static double chance = config.getDouble("Abilities.Chi.Passive.BlockChi.Chance"); - public static int duration = config.getInt("Abilities.Chi.Passive.BlockChi.Duration"); - - static long ticks = (duration / 1000) * 20; - public static boolean willChiBlock(Player attacker, Player player) { - if (AcrobatStance.isInAcrobatStance(attacker)) { - chance = chance + AcrobatStance.CHI_BLOCK_BOOST; - } - if (GeneralMethods.getBoundAbility(player) == "QuickStrike") { - chance = chance + QuickStrike.blockChance; - } - if (GeneralMethods.getBoundAbility(player) == "SwiftKick") { - chance = chance + SwiftKick.blockChance; - } - if (Math.random() > chance/100) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { return false; } - if (ChiMethods.isChiBlocked(player.getName())) { + + ChiAbility stance = bPlayer.getStance(); + QuickStrike quickStrike = CoreAbility.getAbility(player, QuickStrike.class); + SwiftKick swiftKick = CoreAbility.getAbility(player, SwiftKick.class); + double newChance = 0; + + if (stance != null && stance instanceof AcrobatStance) { + newChance = getChance() + ((AcrobatStance) stance).getChiBlockBoost(); + } + + if (quickStrike != null) { + newChance = getChance() + quickStrike.getBlockChance(); + } else if (swiftKick != null) { + newChance = getChance() + swiftKick.getBlockChance(); + } + + if (Math.random() > newChance / 100.0) { + return false; + } else if (bPlayer.isChiBlocked()) { return false; } return true; @@ -47,30 +48,64 @@ public class ChiPassive { if (Suffocate.isChannelingSphere(player)) { Suffocate.remove(player); } - final BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer == null) + + final BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { return; + } bPlayer.blockChi(); Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(ProjectKorra.plugin, new Runnable() { + @Override public void run() { bPlayer.unblockChi(); } - }, ticks); + }, getTicks()); } public static void handlePassive() { for (Player player : Bukkit.getOnlinePlayers()) { - if (GeneralMethods.canBendPassive(player.getName(), Element.Chi) && !GeneralMethods.canBendPassive(player.getName(), Element.Air)) { // If they're an airbender and gets the boosts we want to give them that instead of the Chi. - if (player.isSprinting()) { - if (!player.hasPotionEffect(PotionEffectType.JUMP) && !AcrobatStance.isInAcrobatStance(player)) { - player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 60, jumpPower - 1)); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + continue; + } + + if (bPlayer.canBendPassive(Element.CHI) && !bPlayer.canBendPassive(Element.AIR)) { // If they're an airbender and gets the boosts we want to give them that instead of the Chi. + ChiAbility stance = bPlayer.getStance(); + if (player.isSprinting() && !(stance instanceof AcrobatStance)) { + if (!player.hasPotionEffect(PotionEffectType.JUMP)) { + player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 60, getJumpPower() - 1)); } - if (!player.hasPotionEffect(PotionEffectType.SPEED) && !AcrobatStance.isInAcrobatStance(player)) { - player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 60, speedPower - 1)); + if (!player.hasPotionEffect(PotionEffectType.SPEED)) { + player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 60, getSpeedPower() - 1)); } } } } } + + public static double getFallReductionFactor() { + return ConfigManager.getConfig().getDouble("Abilities.Chi.Passive.FallReductionFactor"); + } + + public static int getJumpPower() { + return ConfigManager.getConfig().getInt("Abilities.Chi.Passive.Jump"); + } + + public static int getSpeedPower() { + return ConfigManager.getConfig().getInt("Abilities.Chi.Passive.Speed"); + } + + public static double getChance() { + return ConfigManager.getConfig().getDouble("Abilities.Chi.Passive.BlockChi.Chance"); + } + + public static int getDuration() { + return ConfigManager.getConfig().getInt("Abilities.Chi.Passive.BlockChi.Duration"); + } + + public static long getTicks() { + return (getDuration() / 1000) * 20; + } + } diff --git a/src/com/projectkorra/projectkorra/chiblocking/ChiblockingManager.java b/src/com/projectkorra/projectkorra/chiblocking/ChiblockingManager.java index 4fc98544..4741754c 100644 --- a/src/com/projectkorra/projectkorra/chiblocking/ChiblockingManager.java +++ b/src/com/projectkorra/projectkorra/chiblocking/ChiblockingManager.java @@ -6,7 +6,6 @@ import org.bukkit.Bukkit; import org.bukkit.entity.Player; public class ChiblockingManager implements Runnable { - public ProjectKorra plugin; public ChiblockingManager(ProjectKorra plugin) { @@ -16,8 +15,6 @@ public class ChiblockingManager implements Runnable { @Override public void run() { ChiPassive.handlePassive(); - WarriorStance.progressAll(); - AcrobatStance.progressAll(); for (Player player : Bukkit.getOnlinePlayers()) { Smokescreen.removeFromHashMap(player); if (Paralyze.isParalyzed(player)) { diff --git a/src/com/projectkorra/projectkorra/chiblocking/HighJump.java b/src/com/projectkorra/projectkorra/chiblocking/HighJump.java index 78aecc1f..33d83b56 100644 --- a/src/com/projectkorra/projectkorra/chiblocking/HighJump.java +++ b/src/com/projectkorra/projectkorra/chiblocking/HighJump.java @@ -1,45 +1,87 @@ package com.projectkorra.projectkorra.chiblocking; -import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.ChiAbility; import com.projectkorra.projectkorra.waterbending.WaterArmsWhip; +import org.bukkit.Location; import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -public class HighJump { - - private int jumpheight = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.HighJump.Height"); - private long cooldown = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.HighJump.Cooldown"); - - public HighJump(Player p) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(p.getName()); - - if (bPlayer.isOnCooldown("HighJump")) - return; - if (WaterArmsWhip.grabbedEntities.containsKey(p)) { - WaterArmsWhip waw = WaterArmsWhip.instances.get(WaterArmsWhip.grabbedEntities.get(p)); - if (waw != null) { - waw.setGrabbed(false); - } - } - jump(p); - bPlayer.addCooldown("HighJump", cooldown); +public class HighJump extends ChiAbility { + private int height; + private long cooldown; + + public HighJump(Player player) { + super(player); + this.height = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.HighJump.Height"); + this.cooldown = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.HighJump.Cooldown"); + start(); } private void jump(Player p) { - if (!GeneralMethods.isSolid(p.getLocation().getBlock().getRelative(BlockFace.DOWN))) + if (!GeneralMethods.isSolid(p.getLocation().getBlock().getRelative(BlockFace.DOWN))) { return; + } Vector vec = p.getVelocity(); - vec.setY(jumpheight); + vec.setY(height); p.setVelocity(vec); return; } - public static String getDescription() { - return "To use this ability, simply click. You will jump quite high. This ability has a short cooldown."; + @Override + public void progress() { + if (bPlayer.isOnCooldown(this)) { + remove(); + return; + } + + jump(player); + WaterArmsWhip waw = WaterArmsWhip.getGrabbedEntities().get(player); + if (waw != null) { + waw.setGrabbed(false); + } + bPlayer.addCooldown(this); } + + @Override + public String getName() { + return "HighJump"; + } + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return true; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/chiblocking/Paralyze.java b/src/com/projectkorra/projectkorra/chiblocking/Paralyze.java index 8e421151..85468bbc 100644 --- a/src/com/projectkorra/projectkorra/chiblocking/Paralyze.java +++ b/src/com/projectkorra/projectkorra/chiblocking/Paralyze.java @@ -1,48 +1,58 @@ package com.projectkorra.projectkorra.chiblocking; -import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; +import com.projectkorra.projectkorra.BendingPlayer; +import com.projectkorra.projectkorra.ability.ChiAbility; import com.projectkorra.projectkorra.airbending.Suffocate; import com.projectkorra.projectkorra.command.Commands; +import org.bukkit.Location; import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import java.util.concurrent.ConcurrentHashMap; -public class Paralyze { +public class Paralyze extends ChiAbility { - private static ConcurrentHashMap entities = new ConcurrentHashMap(); - private static ConcurrentHashMap cooldowns = new ConcurrentHashMap(); + private static final String DURATION_STRING = "Abilities.Chi.Paralyze.Duration"; + private static final ConcurrentHashMap ENTITIES = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap COOLDOWNS = new ConcurrentHashMap<>(); - private static final long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Chi.Paralyze.Cooldown"); - private static final long duration = ProjectKorra.plugin.getConfig().getLong("Abilities.Chi.Paralyze.Duration"); + private long cooldown; + private Entity target; public Paralyze(Player sourceplayer, Entity targetentity) { - if (GeneralMethods.getBoundAbility(sourceplayer) == null) - return; - if (GeneralMethods.isBender(sourceplayer.getName(), Element.Chi) && GeneralMethods.getBoundAbility(sourceplayer).equalsIgnoreCase("Paralyze") && GeneralMethods.canBend(sourceplayer.getName(), "Paralyze")) { - if (cooldowns.containsKey(targetentity)) { - if (System.currentTimeMillis() < cooldowns.get(targetentity) + cooldown) { + super(sourceplayer); + this.target = targetentity; + this.cooldown = getConfig().getLong("Abilities.Chi.Paralyze.Cooldown"); + start(); + } + + @Override + public void progress() { + if (bPlayer.canBendIgnoreCooldowns(this)) { + if (COOLDOWNS.containsKey(target)) { + if (System.currentTimeMillis() < COOLDOWNS.get(target) + cooldown) { return; } else { - cooldowns.remove(targetentity); + COOLDOWNS.remove(target); } } - if (targetentity instanceof Player) { - if (Commands.invincible.contains(((Player) targetentity).getName())) + if (target instanceof Player) { + if (Commands.invincible.contains(((Player) target).getName())) { + remove(); return; + } } - paralyze(targetentity); - cooldowns.put(targetentity, System.currentTimeMillis()); + paralyze(target); + COOLDOWNS.put(target, System.currentTimeMillis()); + } else { + remove(); } } private static void paralyze(Entity entity) { - entities.put(entity, System.currentTimeMillis()); + ENTITIES.put(entity, System.currentTimeMillis()); if (entity instanceof Creature) { ((Creature) entity).setTarget(null); } @@ -54,19 +64,75 @@ public class Paralyze { } } + //TODO change paralyze to use Spigot metadata rather than checking this class public static boolean isParalyzed(Entity entity) { if (entity instanceof Player) { - if (AvatarState.isAvatarState((Player) entity)) + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer((Player) entity); + if (bPlayer != null && bPlayer.isAvatarState()) { return false; + } } - if (entities.containsKey(entity)) { - if (System.currentTimeMillis() < entities.get(entity) + duration) { + if (ENTITIES.containsKey(entity)) { + if (System.currentTimeMillis() < ENTITIES.get(entity) + getDuration()) { return true; } - entities.remove(entity); + ENTITIES.remove(entity); } return false; } + @Override + public String getName() { + return "Paralyze"; + } + + @Override + public Location getLocation() { + return target != null ? target.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public static long getDuration() { + return getConfig().getLong(DURATION_STRING); + } + + public Entity getTarget() { + return target; + } + + public void setTarget(Entity target) { + this.target = target; + } + + public static String getDurationString() { + return DURATION_STRING; + } + + public static ConcurrentHashMap getEntities() { + return ENTITIES; + } + + public static ConcurrentHashMap getCooldowns() { + return COOLDOWNS; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/chiblocking/QuickStrike.java b/src/com/projectkorra/projectkorra/chiblocking/QuickStrike.java index 0dc9aa5e..a2aa4fb9 100644 --- a/src/com/projectkorra/projectkorra/chiblocking/QuickStrike.java +++ b/src/com/projectkorra/projectkorra/chiblocking/QuickStrike.java @@ -1,46 +1,87 @@ package com.projectkorra.projectkorra.chiblocking; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.ChiAbility; +import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -import java.util.ArrayList; - -public class QuickStrike { - public static int damage = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.QuickStrike.Damage"); - public static int blockChance = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.QuickStrike.ChiBlockChance"); +public class QuickStrike extends ChiAbility { + private int damage; + private int blockChance; + private Entity target; + public QuickStrike(Player player) { - if (!isEligible(player)) + super(player); + this.damage = getConfig().getInt("Abilities.Chi.QuickStrike.Damage"); + this.blockChance = getConfig().getInt("Abilities.Chi.QuickStrike.ChiBlockChance"); + target = GeneralMethods.getTargetedEntity(player, 2); + start(); + } + + + @Override + public void progress() { + if (target == null) { return; - - Entity e = GeneralMethods.getTargetedEntity(player, 2, new ArrayList()); - - if (e == null) - return; - - GeneralMethods.damageEntity(player, e, damage, "QuickStrike"); - - if (e instanceof Player && ChiPassive.willChiBlock(player, (Player)e)) { - ChiPassive.blockChi((Player) e); } + + GeneralMethods.damageEntity(this, target, damage); + if (target instanceof Player && ChiPassive.willChiBlock(player, (Player) target)) { + ChiPassive.blockChi((Player) target); + } + remove(); } - public boolean isEligible(Player player) { - if (!GeneralMethods.canBend(player.getName(), "QuickStrike")) - return false; - - if (GeneralMethods.getBoundAbility(player) == null) - return false; - - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("QuickStrike")) - return false; - - if (GeneralMethods.isRegionProtectedFromBuild(player, "QuickStrike", player.getLocation())) - return false; - - return true; + @Override + public String getName() { + return "QuickStrike"; } + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public int getDamage() { + return damage; + } + + public void setDamage(int damage) { + this.damage = damage; + } + + public int getBlockChance() { + return blockChance; + } + + public void setBlockChance(int blockChance) { + this.blockChance = blockChance; + } + + public Entity getTarget() { + return target; + } + + public void setTarget(Entity target) { + this.target = target; + } + } diff --git a/src/com/projectkorra/projectkorra/chiblocking/RapidPunch.java b/src/com/projectkorra/projectkorra/chiblocking/RapidPunch.java index b0e29e29..f7356d7d 100644 --- a/src/com/projectkorra/projectkorra/chiblocking/RapidPunch.java +++ b/src/com/projectkorra/projectkorra/chiblocking/RapidPunch.java @@ -1,84 +1,80 @@ package com.projectkorra.projectkorra.chiblocking; -import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.ChiAbility; import com.projectkorra.projectkorra.airbending.Suffocate; +import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; +public class RapidPunch extends ChiAbility { -public class RapidPunch { - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - public static List punching = new ArrayList(); - - private int damage = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.RapidPunch.Damage"); - private int punches = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.RapidPunch.Punches"); - private int distance = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.RapidPunch.Distance"); - private long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Chi.RapidPunch.Cooldown"); - - private int numpunches; - // private long timers; + private int damage; + private int punches; + private int distance; + private long cooldown; + private int numPunches; private Entity target; - private Player player; - - public RapidPunch(Player p) { - this.player = p; - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(p.getName()); - if (instances.containsKey(p)) - return; - if (bPlayer.isOnCooldown("RapidPunch")) - return; - - Entity t = GeneralMethods.getTargetedEntity(p, distance, new ArrayList()); - - if (t == null) - return; - - this.target = t; - this.numpunches = 0; - instances.put(p, this); + + public RapidPunch(Player player) { + super(player); + this.damage = getConfig().getInt("Abilities.Chi.RapidPunch.Damage"); + this.punches = getConfig().getInt("Abilities.Chi.RapidPunch.Punches"); + this.distance = getConfig().getInt("Abilities.Chi.RapidPunch.Distance"); + this.cooldown = getConfig().getLong("Abilities.Chi.RapidPunch.Cooldown"); + this.target = GeneralMethods.getTargetedEntity(player, distance); + start(); } - public static void startPunchAll() { - for (Player player : instances.keySet()) { - if (player != null) - instances.get(player).startPunch(player); + @Override + public void progress() { + if (numPunches >= punches || target == null || !(target instanceof LivingEntity)) { + remove(); + return; } - } - - public void startPunch(Player p) { - if (numpunches >= punches) - instances.remove(p); - if (target instanceof LivingEntity && target != null) { - LivingEntity lt = (LivingEntity) target; - GeneralMethods.damageEntity(p, target, damage, "RapidPunch"); - if (target instanceof Player) { - if (ChiPassive.willChiBlock(p, (Player) target)) { - ChiPassive.blockChi((Player) target); - } - if (Suffocate.isChannelingSphere((Player) target)) { - Suffocate.remove((Player) target); - } + + LivingEntity lt = (LivingEntity) target; + GeneralMethods.damageEntity(this, target, damage); + + if (target instanceof Player) { + if (ChiPassive.willChiBlock(player, (Player) target)) { + ChiPassive.blockChi((Player) target); + } + if (Suffocate.isChannelingSphere((Player) target)) { + Suffocate.remove((Player) target); } - lt.setNoDamageTicks(0); } - GeneralMethods.getBendingPlayer(p.getName()).addCooldown("RapidPunch", cooldown); - swing(p); - numpunches++; + + lt.setNoDamageTicks(0); + bPlayer.addCooldown(this); + numPunches++; + } + + @Override + public String getName() { + return "RapidPunch"; } - private void swing(Player p) { + @Override + public Location getLocation() { + return target != null ? target.getLocation() : null; } - public static String getDescription() { - return "This ability allows the chiblocker to punch rapidly in a short period. To use, simply punch." + " This has a short cooldown."; + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return false; } public int getDamage() { @@ -89,28 +85,6 @@ public class RapidPunch { this.damage = damage; } - public int getDistance() { - return distance; - } - - public void setDistance(int distance) { - this.distance = distance; - } - - public long getCooldown() { - return cooldown; - } - - public void setCooldown(long cooldown) { - this.cooldown = cooldown; - if (player != null) - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("RapidPunch", cooldown); - } - - public Player getPlayer() { - return player; - } - public int getPunches() { return punches; } @@ -119,11 +93,32 @@ public class RapidPunch { this.punches = punches; } - public int getNumpunches() { - return numpunches; + public int getDistance() { + return distance; } - public void setNumpunches(int numpunches) { - this.numpunches = numpunches; + public void setDistance(int distance) { + this.distance = distance; } + + public int getNumPunches() { + return numPunches; + } + + public void setNumPunches(int numPunches) { + this.numPunches = numPunches; + } + + public Entity getTarget() { + return target; + } + + public void setTarget(Entity target) { + this.target = target; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/chiblocking/Smokescreen.java b/src/com/projectkorra/projectkorra/chiblocking/Smokescreen.java index 062c68ab..82473083 100644 --- a/src/com/projectkorra/projectkorra/chiblocking/Smokescreen.java +++ b/src/com/projectkorra/projectkorra/chiblocking/Smokescreen.java @@ -1,8 +1,7 @@ package com.projectkorra.projectkorra.chiblocking; -import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.ChiAbility; import com.projectkorra.projectkorra.command.Commands; import org.bukkit.Effect; @@ -13,34 +12,38 @@ import org.bukkit.entity.Snowball; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +import java.util.concurrent.ConcurrentHashMap; -public class Smokescreen { +public class Smokescreen extends ChiAbility { - public static HashMap cooldowns = new HashMap(); - public static List snowballs = new ArrayList(); - public static HashMap blinded = new HashMap(); - - 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"); + private static final ConcurrentHashMap SNOWBALLS = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap BLINDED_TIMES = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap BLINDED_TO_ABILITY = new ConcurrentHashMap<>(); + private int duration; + private long cooldown; + private double radius; + public Smokescreen(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (bPlayer.isOnCooldown("Smokescreen")) - return; - - snowballs.add(player.launchProjectile(Snowball.class).getEntityId()); - bPlayer.addCooldown("Smokescreen", cooldown); + super(player); + this.cooldown = getConfig().getLong("Abilities.Chi.Smokescreen.Cooldown"); + this.duration = getConfig().getInt("Abilities.Chi.Smokescreen.Duration"); + this.radius = getConfig().getDouble("Abilities.Chi.Smokescreen.Radius"); + start(); + } + + @Override + public void progress() { + SNOWBALLS.put(player.launchProjectile(Snowball.class).getEntityId(), this); + bPlayer.addCooldown(this); + remove(); } 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++) { @@ -48,7 +51,6 @@ public class Smokescreen { } if (z == 2) { z = -2; - // y++; } if (x == 2) { x = -2; @@ -58,24 +60,89 @@ public class Smokescreen { } } - public static void applyBlindness(Entity entity) { + public void applyBlindness(Entity entity) { if (entity instanceof Player) { - if (Commands.invincible.contains(((Player) entity).getName())) + if (Commands.invincible.contains(((Player) entity).getName())) { return; + } else if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) { + return; + } Player p = (Player) entity; p.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, duration * 20, 2)); - blinded.put(p.getName(), System.currentTimeMillis()); + BLINDED_TIMES.put(p.getName(), System.currentTimeMillis()); + BLINDED_TO_ABILITY.put(p.getName(), this); } } public static void removeFromHashMap(Entity entity) { if (entity instanceof Player) { Player p = (Player) entity; - if (blinded.containsKey(p.getName())) { - if (blinded.get(p.getName()) + duration >= System.currentTimeMillis()) { - blinded.remove(p.getName()); + if (BLINDED_TIMES.containsKey(p.getName())) { + Smokescreen smokescreen = BLINDED_TO_ABILITY.get(p.getName()); + if (BLINDED_TIMES.get(p.getName()) + smokescreen.duration >= System.currentTimeMillis()) { + BLINDED_TIMES.remove(p.getName()); + BLINDED_TO_ABILITY.remove(p.getName()); } } } } + + + @Override + public String getName() { + return "Smokescreen"; + } + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public int getDuration() { + return duration; + } + + public void setDuration(int duration) { + this.duration = duration; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public static ConcurrentHashMap getSnowballs() { + return SNOWBALLS; + } + + public static ConcurrentHashMap getBlindedTimes() { + return BLINDED_TIMES; + } + + public static ConcurrentHashMap getBlindedToAbility() { + return BLINDED_TO_ABILITY; + } + } diff --git a/src/com/projectkorra/projectkorra/chiblocking/SwiftKick.java b/src/com/projectkorra/projectkorra/chiblocking/SwiftKick.java index 56e9cf31..9bce3c9d 100644 --- a/src/com/projectkorra/projectkorra/chiblocking/SwiftKick.java +++ b/src/com/projectkorra/projectkorra/chiblocking/SwiftKick.java @@ -1,55 +1,93 @@ package com.projectkorra.projectkorra.chiblocking; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.ChiAbility; +import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -import java.util.ArrayList; - -public class SwiftKick { - public static int damage = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.SwiftKick.Damage"); - public static int blockChance = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.ChiCombo.ChiBlockChance"); - +public class SwiftKick extends ChiAbility { + + private int damage; + private int blockChance; + private long cooldown; + private Entity target; + public SwiftKick(Player player) { - if (!isEligible(player)) - return; - - Entity e = GeneralMethods.getTargetedEntity(player, 4, new ArrayList()); - - if (e == null) - return; - - GeneralMethods.damageEntity(player, e, damage, "SwiftKick"); - - if (e instanceof Player && ChiPassive.willChiBlock(player, (Player)e)) { - ChiPassive.blockChi((Player) e); - } - - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("SwiftKick", 4000); + super(player); + this.damage = getConfig().getInt("Abilities.Chi.SwiftKick.Damage"); + this.cooldown = getConfig().getInt("Abilities.Chi.ChiCombo.ChiBlockChance"); + this.cooldown = 4000; + this.target = GeneralMethods.getTargetedEntity(player, 4); + start(); } - @SuppressWarnings("deprecation") - public boolean isEligible(Player player) { - if (!GeneralMethods.canBend(player.getName(), "SwiftKick")) - return false; + @Override + public void progress() { + if (target == null) { + remove(); + return; + } + GeneralMethods.damageEntity(this, target, damage); + if (target instanceof Player && ChiPassive.willChiBlock(player, (Player) target)) { + ChiPassive.blockChi((Player) target); + } + bPlayer.addCooldown(this); + remove(); + } + + @Override + public String getName() { + return "SwiftKick"; + } - if (GeneralMethods.getBoundAbility(player) == null) - return false; - - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("SwiftKick")) - return false; - - if (GeneralMethods.isRegionProtectedFromBuild(player, "SwiftKick", player.getLocation())) - return false; - - if (GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("SwiftKick")) - return false; - - if (player.isOnGround()) - return false; + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { return true; } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public int getDamage() { + return damage; + } + + public void setDamage(int damage) { + this.damage = damage; + } + + public int getBlockChance() { + return blockChance; + } + + public void setBlockChance(int blockChance) { + this.blockChance = blockChance; + } + + public Entity getTarget() { + return target; + } + + public void setTarget(Entity target) { + this.target = target; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/chiblocking/WarriorStance.java b/src/com/projectkorra/projectkorra/chiblocking/WarriorStance.java index 89d07725..e6b29715 100644 --- a/src/com/projectkorra/projectkorra/chiblocking/WarriorStance.java +++ b/src/com/projectkorra/projectkorra/chiblocking/WarriorStance.java @@ -1,79 +1,68 @@ package com.projectkorra.projectkorra.chiblocking; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.StockAbility; -import com.projectkorra.projectkorra.waterbending.Bloodbending; +import com.projectkorra.projectkorra.ability.ChiAbility; +import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import java.util.concurrent.ConcurrentHashMap; - -public class WarriorStance { - - public int strength = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.WarriorStance.Strength") - 1; - public int resistance = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.WarriorStance.Resistance"); - - private Player player; - public static ConcurrentHashMap instances = new ConcurrentHashMap(); +public class WarriorStance extends ChiAbility { + private int strength; + private int resistance; + public WarriorStance(Player player) { - this.player = player; - if (instances.containsKey(player)) { - instances.remove(player); - return; + super(player); + this.strength = getConfig().getInt("Abilities.Chi.WarriorStance.Strength") - 1; + this.resistance = getConfig().getInt("Abilities.Chi.WarriorStance.Resistance"); + + ChiAbility stance = bPlayer.getStance(); + if (stance != null && !(stance instanceof WarriorStance)) { + stance.remove(); + bPlayer.setStance(this); } - - if (AcrobatStance.isInAcrobatStance(player)) { - AcrobatStance.remove(player); - } - - instances.put(player, this); + start(); } - private void progress() { - if (player.isDead() || !player.isOnline()) { - remove(); - return; - } - if (!GeneralMethods.canBend(player.getName(), StockAbility.WarriorStance.toString())) { - remove(); - return; - } - - if (Paralyze.isParalyzed(player) || Bloodbending.isBloodbended(player)) { + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { remove(); return; } + if (!player.hasPotionEffect(PotionEffectType.DAMAGE_RESISTANCE)) { player.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 60, resistance)); } - if (!player.hasPotionEffect(PotionEffectType.INCREASE_DAMAGE)) { player.addPotionEffect(new PotionEffect(PotionEffectType.INCREASE_DAMAGE, 60, strength)); } } - - public static void progressAll() { - for (Player player : instances.keySet()) { - instances.get(player).progress(); - } + + @Override + public String getName() { + return "WarriorStance"; } - private void remove() { - instances.remove(player); + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; } - public static boolean isInWarriorStance(Player player) { - if (instances.containsKey(player)) - return true; + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { return false; } - public static void remove(Player player) { - instances.remove(player); + @Override + public boolean isHarmlessAbility() { + return true; } public int getStrength() { @@ -91,8 +80,5 @@ public class WarriorStance { public void setResistance(int resistance) { this.resistance = resistance; } - - public Player getPlayer() { - return player; - } + } diff --git a/src/com/projectkorra/projectkorra/command/AddCommand.java b/src/com/projectkorra/projectkorra/command/AddCommand.java index 6d79d5af..73a9f5b3 100644 --- a/src/com/projectkorra/projectkorra/command/AddCommand.java +++ b/src/com/projectkorra/projectkorra/command/AddCommand.java @@ -52,10 +52,10 @@ public class AddCommand extends PKCommand { * @param element The element to add */ private void add(CommandSender sender, Player target, String element) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(target.getName()); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(target); if (bPlayer == null) { GeneralMethods.createBendingPlayer(target.getUniqueId(), target.getName()); - bPlayer = GeneralMethods.getBendingPlayer(target.getName()); + bPlayer = BendingPlayer.getBendingPlayer(target); } if (bPlayer.isPermaRemoved()) { sender.sendMessage(ChatColor.RED + "That player's bending was permanently removed."); @@ -63,9 +63,10 @@ public class AddCommand extends PKCommand { } if (Arrays.asList(Commands.elementaliases).contains(element.toLowerCase())) { element = getElement(element.toLowerCase()); - Element type = Element.getType(element); + Element type = Element.getElement(element); bPlayer.addElement(type); - ChatColor color = GeneralMethods.getElementColor(type); + ChatColor color = type.getColor(); + if (element.charAt(0) == 'w' || element.charAt(0) == 'f') { target.sendMessage(color + "You are also a " + Character.toString(element.charAt(0)).toUpperCase() + element.substring(1) + "bender."); } else if (element.charAt(0) == 'e' || element.charAt(0) == 'a') { diff --git a/src/com/projectkorra/projectkorra/command/BendingTabComplete.java b/src/com/projectkorra/projectkorra/command/BendingTabComplete.java index cfcbaf42..b77c5aae 100644 --- a/src/com/projectkorra/projectkorra/command/BendingTabComplete.java +++ b/src/com/projectkorra/projectkorra/command/BendingTabComplete.java @@ -1,9 +1,9 @@ package com.projectkorra.projectkorra.command; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import com.projectkorra.projectkorra.BendingPlayer; +import com.projectkorra.projectkorra.Element; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.object.Preset; import org.bukkit.Bukkit; import org.bukkit.command.Command; @@ -11,14 +11,10 @@ import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; import org.bukkit.entity.Player; -import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ability.AbilityModuleManager; -import com.projectkorra.projectkorra.ability.combo.ComboAbilityModule; -import com.projectkorra.projectkorra.ability.combo.ComboManager; -import com.projectkorra.projectkorra.ability.combo.ComboManager.ComboAbility; -import com.projectkorra.projectkorra.ability.combo.ComboModuleManager; -import com.projectkorra.projectkorra.object.Preset; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * Completes tabbing for the bending command/subcommands. @@ -30,15 +26,21 @@ public class BendingTabComplete implements TabCompleter { public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { if (args.length == 0 || args[0].equals("")) return getPossibleCompletionsForGivenArgs(args, getCommandsForUser(sender)); + if (args.length >= 2) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(sender.getName()); + if (args[0].equalsIgnoreCase("bind") || args[0].equalsIgnoreCase("b")) { if (args.length > 3 || !sender.hasPermission("bending.command.bind") || !(sender instanceof Player)) return new ArrayList(); + List abilities = new ArrayList(); if (args.length == 2) { - for (String abil : AbilityModuleManager.abilities) { - if (GeneralMethods.canBind(sender.getName(), abil)) { - abilities.add(abil); + if (bPlayer != null) { + for (CoreAbility coreAbil : CoreAbility.getAbilities()) { + if (!coreAbil.isHiddenAbility() && bPlayer.canBind(coreAbil)) { + abilities.add(coreAbil.getName()); + } } } } else { @@ -46,6 +48,7 @@ public class BendingTabComplete implements TabCompleter { abilities.add("" + i); } } + Collections.sort(abilities); return getPossibleCompletionsForGivenArgs(args, abilities); } else if (args[0].equalsIgnoreCase("display") || args[0].equalsIgnoreCase("d")) { @@ -79,13 +82,16 @@ public class BendingTabComplete implements TabCompleter { if (args.length > 3 || !sender.hasPermission("bending.command.add")) return new ArrayList(); List l = new ArrayList(); - if (args.length == 2) { + if (args.length == 2) + { l.add("Air"); l.add("Earth"); l.add("Fire"); l.add("Water"); l.add("Chi"); - } else { + } + else + { for (Player p : Bukkit.getOnlinePlayers()) { l.add(p.getName()); } @@ -103,25 +109,16 @@ public class BendingTabComplete implements TabCompleter { if (args.length > 2 || !sender.hasPermission("bending.command.help")) return new ArrayList(); List list = new ArrayList(); - for (Element e : Element.values()) { - list.add(e.toString()); + for (Element e : Element.getElements()) { + list.add(e.getName()); } List abils = new ArrayList(); - for (String abil : AbilityModuleManager.abilities) { - if (GeneralMethods.canBind(sender.getName(), abil)) { - abils.add(abil); - } - } - for (ComboAbility abil : ComboManager.comboAbilityList.values()) { - if (GeneralMethods.canBind(sender.getName(), abil.getName()) && (abil.getName() != "IceBulletRightClick" && abil.getName() != "IceBulletLeftClick")) { - abils.add(abil.getName()); - } - } - for (ComboAbilityModule abil : ComboModuleManager.combo) { - if (GeneralMethods.canBind(sender.getName(), abil.getName())) { - abils.add(abil.getName()); + for (CoreAbility coreAbil : CoreAbility.getAbilities()) { + if (bPlayer.canBind(coreAbil)) { + abils.add(coreAbil.getName()); } } + Collections.sort(abils); list.addAll(abils); return getPossibleCompletionsForGivenArgs(args, list); @@ -134,7 +131,7 @@ public class BendingTabComplete implements TabCompleter { } return getPossibleCompletionsForGivenArgs(args, players); } else if (args[0].equalsIgnoreCase("preset") || args[0].equalsIgnoreCase("presets") || args[0].equalsIgnoreCase("pre") || args[0].equalsIgnoreCase("set") || args[0].equalsIgnoreCase("p")) { - if (args.length > 4 || !sender.hasPermission("bending.command.preset") || !(sender instanceof Player)) + if (args.length > 3 || !sender.hasPermission("bending.command.preset") || !(sender instanceof Player)) return new ArrayList(); List l = new ArrayList(); if (args.length == 2) { @@ -150,28 +147,10 @@ public class BendingTabComplete implements TabCompleter { for (Preset preset : presets) { presetNames.add(preset.getName()); } - } - if (sender.hasPermission("bending.command.preset.bind.external")) { - if (Preset.externalPresets.keySet().size() > 0) { - for (String externalPreset : Preset.externalPresets.keySet()) { - presetNames.add(externalPreset); - } - } - } - if (presetNames.size() == 0) + } else return new ArrayList(); return getPossibleCompletionsForGivenArgs(args, presetNames); - } else if (args.length == 4 && Arrays.asList(new String[] {"bind", "b"}).contains(args[1].toLowerCase())) { - if (!sender.hasPermission("bending.command.preset.bind.assign") || (Preset.externalPresets.keySet().contains(args[2].toLowerCase())) && !sender.hasPermission("bending.command.preset.bind.external.other")) { - return new ArrayList(); - } - List players = new ArrayList(); - for (Player p : Bukkit.getOnlinePlayers()) { - players.add(p.getName()); - } - return getPossibleCompletionsForGivenArgs(args, players); } - return new ArrayList(); } else if (args[0].equalsIgnoreCase("remove") || args[0].equalsIgnoreCase("rm")) { if (args.length > 3 || !sender.hasPermission("bending.command.remove")) return new ArrayList(); @@ -196,17 +175,7 @@ public class BendingTabComplete implements TabCompleter { l.add(p.getName()); } return getPossibleCompletionsForGivenArgs(args, l); - } else if (args[0].equalsIgnoreCase("copy") || args[0].equalsIgnoreCase("co")) { - //If they can't use the command, have over 3 args (copy ), or if have over 2 args and can't assign to other players - if (!sender.hasPermission("bending.command.copy") || args.length > 4 || (args.length > 3 && !sender.hasPermission("bending.command.copy.assign"))) - return new ArrayList(); //Return nothing - List l = new ArrayList(); - for (Player p : Bukkit.getOnlinePlayers()) { - l.add(p.getName()); - } - return getPossibleCompletionsForGivenArgs(args, l); - } - else if (!PKCommand.instances.keySet().contains(args[0].toLowerCase())) { + } else if (!PKCommand.instances.keySet().contains(args[0].toLowerCase())) { return new ArrayList(); } } else { diff --git a/src/com/projectkorra/projectkorra/command/BindCommand.java b/src/com/projectkorra/projectkorra/command/BindCommand.java index 237dbabd..28d8935d 100644 --- a/src/com/projectkorra/projectkorra/command/BindCommand.java +++ b/src/com/projectkorra/projectkorra/command/BindCommand.java @@ -1,6 +1,8 @@ package com.projectkorra.projectkorra.command; +import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -23,36 +25,44 @@ public class BindCommand extends PKCommand { return; } - if (!GeneralMethods.abilityExists(args.get(0))) { + CoreAbility coreAbil = CoreAbility.getAbility(args.get(0)); + if (coreAbil == null || coreAbil.isHiddenAbility()) { sender.sendMessage(ChatColor.RED + "That ability doesn't exist."); return; } - String ability = GeneralMethods.getAbility(args.get(0)); // bending bind [Ability] if (args.size() == 1) { - bind(sender, ability, ((Player) sender).getInventory().getHeldItemSlot()+1); + bind(sender, args.get(0), ((Player) sender).getInventory().getHeldItemSlot()+1); } // bending bind [ability] [#] if (args.size() == 2) { - bind(sender, ability, Integer.parseInt(args.get(1))); + bind(sender, args.get(0), Integer.parseInt(args.get(1))); } } private void bind(CommandSender sender, String ability, int slot) { - if (slot < 1 || slot > 9) { + if (!(sender instanceof Player)) { + return; + } else if (slot < 1 || slot > 9) { sender.sendMessage(ChatColor.RED + "Slot must be an integer between 1 and 9."); return; } - if (!GeneralMethods.canBind(((Player) sender).getName(), ability)) { - sender.sendMessage(ChatColor.RED + "You don't have permission to bend this element."); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer((Player) sender); + CoreAbility coreAbil = CoreAbility.getAbility(ability); + if (bPlayer == null) { + sender.sendMessage(ChatColor.RED + "Please wait one moment while we load your bending information."); return; - } else if (!GeneralMethods.getBendingPlayer(sender.getName()).isElementToggled(GeneralMethods.getAbilityElement(ability))) { + } else if (coreAbil == null || !bPlayer.canBind(coreAbil)) { + sender.sendMessage(ChatColor.RED + "You don't have permission to bend this ability."); + return; + } else if (!bPlayer.isElementToggled(coreAbil.getElement())) { sender.sendMessage(ChatColor.RED + "You have that ability's element toggled off currently."); } - GeneralMethods.bindAbility((Player) sender, GeneralMethods.getAbility(ability), slot); + String name = coreAbil != null ? coreAbil.getName() : null; + GeneralMethods.bindAbility((Player) sender, name, slot); } } diff --git a/src/com/projectkorra/projectkorra/command/ChooseCommand.java b/src/com/projectkorra/projectkorra/command/ChooseCommand.java index 66b9f6ac..3f8fe240 100644 --- a/src/com/projectkorra/projectkorra/command/ChooseCommand.java +++ b/src/com/projectkorra/projectkorra/command/ChooseCommand.java @@ -33,10 +33,10 @@ public class ChooseCommand extends PKCommand { return; } - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(sender.getName()); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(sender.getName()); if (bPlayer == null) { GeneralMethods.createBendingPlayer(((Player) sender).getUniqueId(), sender.getName()); - bPlayer = GeneralMethods.getBendingPlayer(sender.getName()); + bPlayer = BendingPlayer.getBendingPlayer(sender.getName()); } if (bPlayer.isPermaRemoved()) { sender.sendMessage(ChatColor.RED + "Your bending was permanently removed."); @@ -83,32 +83,38 @@ public class ChooseCommand extends PKCommand { * * @param sender The CommandSender who issued the command * @param target The Player to add the element to - * @param element The element to add to the Player + * @param elementName The element to add to the Player */ - private void add(CommandSender sender, Player target, String element) { - element = getElement(element); - Element e = Element.getType(element); - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(target.getName()); - bPlayer.setElement(e); - ChatColor color = GeneralMethods.getElementColor(e); - if (element.charAt(0) == 'w' || element.charAt(0) == 'f') { - target.sendMessage(color + "You are now a " + Character.toString(element.charAt(0)).toUpperCase() + element.substring(1) + "bender."); - } else if (element.charAt(0) == 'e' || element.charAt(0) == 'a') { - target.sendMessage(color + "You are now an " + Character.toString(element.charAt(0)).toUpperCase() + element.substring(1) + "bender."); - } else if (element.equalsIgnoreCase("chi")) { + private void add(CommandSender sender, Player target, String elementName) { + elementName = getElement(elementName); + Element element = Element.getElement(elementName); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(target); + + if (bPlayer == null) { + return; + } + + bPlayer.setElement(element); + ChatColor color = element != null ? element.getColor() : null; + + if (elementName.charAt(0) == 'w' || elementName.charAt(0) == 'f') { + target.sendMessage(color + "You are now a " + Character.toString(elementName.charAt(0)).toUpperCase() + elementName.substring(1) + "bender."); + } else if (elementName.charAt(0) == 'e' || elementName.charAt(0) == 'a') { + target.sendMessage(color + "You are now an " + Character.toString(elementName.charAt(0)).toUpperCase() + elementName.substring(1) + "bender."); + } else if (elementName.equalsIgnoreCase("chi")) { target.sendMessage(color + "You are now a Chiblocker."); } if (!(sender instanceof Player) || !((Player) sender).equals(target)) { - if (element.charAt(0) == 'w' || element.charAt(0) == 'f') { - sender.sendMessage(ChatColor.DARK_AQUA + target.getName() + color + " is now a " + Character.toString(element.charAt(0)).toUpperCase() + element.substring(1) + "bender."); - } else if (element.charAt(0) == 'e' || element.charAt(0) == 'a') { - sender.sendMessage(ChatColor.DARK_AQUA + target.getName() + color + " is now an " + Character.toString(element.charAt(0)).toUpperCase() + element.substring(1) + "bender."); - } else if (element.equalsIgnoreCase("chi")) { + if (elementName.charAt(0) == 'w' || elementName.charAt(0) == 'f') { + sender.sendMessage(ChatColor.DARK_AQUA + target.getName() + color + " is now a " + Character.toString(elementName.charAt(0)).toUpperCase() + elementName.substring(1) + "bender."); + } else if (elementName.charAt(0) == 'e' || elementName.charAt(0) == 'a') { + sender.sendMessage(ChatColor.DARK_AQUA + target.getName() + color + " is now an " + Character.toString(elementName.charAt(0)).toUpperCase() + elementName.substring(1) + "bender."); + } else if (elementName.equalsIgnoreCase("chi")) { target.sendMessage(color + "You are now a Chiblocker."); } } GeneralMethods.removeUnusableAbilities(target.getName()); GeneralMethods.saveElements(bPlayer); - Bukkit.getServer().getPluginManager().callEvent(new PlayerChangeElementEvent(sender, target, e, Result.CHOOSE)); + Bukkit.getServer().getPluginManager().callEvent(new PlayerChangeElementEvent(sender, target, element, Result.CHOOSE)); } } diff --git a/src/com/projectkorra/projectkorra/command/ClearCommand.java b/src/com/projectkorra/projectkorra/command/ClearCommand.java index 1009b8bc..709d4588 100644 --- a/src/com/projectkorra/projectkorra/command/ClearCommand.java +++ b/src/com/projectkorra/projectkorra/command/ClearCommand.java @@ -2,7 +2,7 @@ package com.projectkorra.projectkorra.command; import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ability.multiability.MultiAbilityManager; +import com.projectkorra.projectkorra.ability.util.MultiAbilityManager; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -28,10 +28,10 @@ public class ClearCommand extends PKCommand { return; } - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(sender.getName()); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(sender.getName()); if (bPlayer == null) { GeneralMethods.createBendingPlayer(((Player) sender).getUniqueId(), sender.getName()); - bPlayer = GeneralMethods.getBendingPlayer(sender.getName()); + bPlayer = BendingPlayer.getBendingPlayer(sender.getName()); } if (args.size() == 0) { bPlayer.getAbilities().clear(); diff --git a/src/com/projectkorra/projectkorra/command/Commands.java b/src/com/projectkorra/projectkorra/command/Commands.java index bdfc83fd..1cb3c3af 100644 --- a/src/com/projectkorra/projectkorra/command/Commands.java +++ b/src/com/projectkorra/projectkorra/command/Commands.java @@ -80,7 +80,6 @@ public class Commands { PluginCommand projectkorra = plugin.getCommand("projectkorra"); new AddCommand(); new BindCommand(); - new CopyCommand(); new CheckCommand(); new ChooseCommand(); new ClearCommand(); diff --git a/src/com/projectkorra/projectkorra/command/CopyCommand.java b/src/com/projectkorra/projectkorra/command/CopyCommand.java deleted file mode 100644 index fc23a21e..00000000 --- a/src/com/projectkorra/projectkorra/command/CopyCommand.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.projectkorra.projectkorra.command; - -import java.util.HashMap; -import java.util.List; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; - -public class CopyCommand extends PKCommand { - - public CopyCommand() { - super("copy", "/bending copy [Player]", "This command will allow the user to copy the binds of another player either for himself or assign them to if specified.", new String[] { "copy", "co" }); - } - - @Override - public void execute(CommandSender sender, List args) { - if (!correctLength(sender, args.size(), 1, 2)) { - return; - } else if (args.size() == 1) { - if (!hasPermission(sender) || !isPlayer(sender)) { - return; - } - - Player orig = Bukkit.getPlayer(args.get(0)); - - if (orig == null || !orig.isOnline()) { - sender.sendMessage(ChatColor.RED + "Player not found."); - return; - } - - - boolean boundAll = assignAbilities(sender, orig, (Player) sender, true); - sender.sendMessage(ChatColor.GREEN + "Your bound abilities have been made the same as " + ChatColor.YELLOW + orig.getName()); - if (!boundAll) { - sender.sendMessage(ChatColor.RED + "Some abilities were not bound because you cannot bend the required element."); - } - } else if (args.size() == 2) { - if (!hasPermission(sender, "assign")) { - sender.sendMessage(ChatColor.RED + "You don't have permission to do that."); - return; - } - - Player orig = ProjectKorra.plugin.getServer().getPlayer(args.get(0)); - Player target = ProjectKorra.plugin.getServer().getPlayer(args.get(1)); - - if ((orig == null || !orig.isOnline()) || (target == null || !target.isOnline())) { - sender.sendMessage(ChatColor.RED + "That player is not online."); - return; - } - - boolean boundAll = assignAbilities(sender, orig, target, false); - sender.sendMessage(ChatColor.GREEN + "The bound abilities of " + ChatColor.YELLOW + target.getName() + ChatColor.GREEN + " have been been made the same as " + ChatColor.YELLOW + orig.getName()); - target.sendMessage(ChatColor.GREEN + "Your bound abilities have been made the same as " + ChatColor.YELLOW + orig.getName()); - if (!boundAll) { - sender.sendMessage(ChatColor.RED + "Some abilities were not bound because you cannot bend the required element."); - } - } - } - - @SuppressWarnings("unchecked") - private boolean assignAbilities(CommandSender sender, Player player, Player player2, boolean self) { - - BendingPlayer orig = GeneralMethods.getBendingPlayer(player.getName()); - BendingPlayer target = GeneralMethods.getBendingPlayer(player2.getName()); - - if (orig == null) { - GeneralMethods.createBendingPlayer(((Player) player).getUniqueId(), player.getName()); - orig = GeneralMethods.getBendingPlayer(player.getName()); - } - if (target == null) { - GeneralMethods.createBendingPlayer(((Player) player2).getUniqueId(), player2.getName()); - target = GeneralMethods.getBendingPlayer(player2.getName()); - } - if (orig.isPermaRemoved()) { - if (self) { - player.sendMessage(ChatColor.RED + "Your bending was permanently removed."); - } else { - sender.sendMessage(ChatColor.RED + "That players bending was permanently removed."); - } - return false; - } - - HashMap abilities = (HashMap) orig.getAbilities().clone(); - boolean boundAll = true; - for (int i = 1; i <= 9; i++) { - if (!GeneralMethods.canBend(player2.getName(), abilities.get(i))) { - abilities.remove(i); - boundAll = false; - } - } - target.setAbilities(abilities); - return boundAll; - } - -} diff --git a/src/com/projectkorra/projectkorra/command/DisplayCommand.java b/src/com/projectkorra/projectkorra/command/DisplayCommand.java index 46acf05b..d8076865 100644 --- a/src/com/projectkorra/projectkorra/command/DisplayCommand.java +++ b/src/com/projectkorra/projectkorra/command/DisplayCommand.java @@ -2,16 +2,11 @@ package com.projectkorra.projectkorra.command; import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.Element; +import com.projectkorra.projectkorra.Element.SubElement; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.SubElement; -import com.projectkorra.projectkorra.ability.AbilityModuleManager; -import com.projectkorra.projectkorra.ability.combo.ComboManager; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.chiblocking.ChiMethods; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.firebending.FireMethods; -import com.projectkorra.projectkorra.waterbending.WaterMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.SubAbility; +import com.projectkorra.projectkorra.ability.util.ComboManager; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -39,55 +34,61 @@ public class DisplayCommand extends PKCommand { //bending display [Element] if (args.size() == 1) { - String element = args.get(0).toLowerCase(); + String elementName = args.get(0).toLowerCase(); //combos - if (Arrays.asList(Commands.comboaliases).contains(element)) { - element = getElement(element); - Element e = Element.getType(element); - ArrayList combos = ComboManager.getCombosForElement(e); + if (Arrays.asList(Commands.comboaliases).contains(elementName)) { + elementName = this.getElement(elementName); + Element element = Element.getElement(elementName); + ChatColor color = element != null ? element.getColor() : null; + ArrayList combos = ComboManager.getCombosForElement(element); + if (combos.isEmpty()) { - sender.sendMessage(GeneralMethods.getElementColor(e) + "There are no " + element + " combos avaliable."); + sender.sendMessage(color + "There are no " + elementName + " combos avaliable."); return; } for (String combomove : combos) { if (!sender.hasPermission("bending.ability." + combomove)) continue; - ChatColor color = GeneralMethods.getComboColor(combomove); sender.sendMessage(color + combomove); } return; } //normal elements - else if (Arrays.asList(Commands.elementaliases).contains(element)) { - element = getElement(element); - displayElement(sender, element); + else if (Arrays.asList(Commands.elementaliases).contains(elementName)) { + elementName = getElement(elementName); + displayElement(sender, elementName); } //subelements - else if (Arrays.asList(Commands.subelementaliases).contains(element)) { - displaySubElement(sender, element); + else if (Arrays.asList(Commands.subelementaliases).contains(elementName)) { + displaySubElement(sender, elementName); } //avatar - else if (Arrays.asList(Commands.avataraliases).contains(element)) { + else if (Arrays.asList(Commands.avataraliases).contains(elementName)) { displayAvatar(sender); } else { ChatColor w = ChatColor.WHITE; - sender.sendMessage(ChatColor.RED + "Not a valid argument." + ChatColor.WHITE + "\nElements: " + AirMethods.getAirColor() + "Air" + ChatColor.WHITE + " | " + WaterMethods.getWaterColor() + "Water" + ChatColor.WHITE + " | " + EarthMethods.getEarthColor() + "Earth" + ChatColor.WHITE + " | " + FireMethods.getFireColor() + "Fire" + ChatColor.WHITE + " | " + ChiMethods.getChiColor() + "Chi"); + sender.sendMessage(ChatColor.RED + "Not a valid argument." + ChatColor.WHITE + "\nElements: " + + Element.AIR.getColor() + "Air" + ChatColor.WHITE + " | " + + Element.WATER.getColor() + "Water" + ChatColor.WHITE + " | " + + Element.EARTH.getColor() + "Earth" + ChatColor.WHITE + " | " + + Element.FIRE.getColor() + "Fire" + ChatColor.WHITE + " | " + + Element.CHI.getColor() + "Chi"); sender.sendMessage(w + "SubElements: " - + w + "\n-" + GeneralMethods.getSubBendingColor(Element.Air) + " Flight" - + w + "\n-" + GeneralMethods.getSubBendingColor(Element.Earth) + " Lavabending" - + w + "\n-" + GeneralMethods.getSubBendingColor(Element.Earth) + " Metalbending" - + w + "\n-" + GeneralMethods.getSubBendingColor(Element.Earth) + " Sandbending" - + w + "\n-" + GeneralMethods.getSubBendingColor(Element.Fire) + " Combustion" - + w + "\n-" + GeneralMethods.getSubBendingColor(Element.Fire) + " Lightning" - + w + "\n-" + GeneralMethods.getSubBendingColor(Element.Water) + " Bloodbending" - + w + "\n-" + GeneralMethods.getSubBendingColor(Element.Water) + " Healing" - + w + "\n-" + GeneralMethods.getSubBendingColor(Element.Water) + " Icebending" - + w + "\n-" + GeneralMethods.getSubBendingColor(Element.Water) + " Plantbending"); + + w + "\n-" + Element.AIR.getColor() + " Flight" + + w + "\n-" + Element.EARTH.getColor() + " Lavabending" + + w + "\n-" + Element.EARTH.getColor() + " Metalbending" + + w + "\n-" + Element.EARTH.getColor() + " Sandbending" + + w + "\n-" + Element.FIRE.getColor() + " Combustion" + + w + "\n-" + Element.FIRE.getColor() + " Lightning" + + w + "\n-" + Element.WATER.getColor() + " Bloodbending" + + w + "\n-" + Element.WATER.getColor() + " Healing" + + w + "\n-" + Element.WATER.getColor() + " Icebending" + + w + "\n-" + Element.WATER.getColor() + " Plantbending"); } } if (args.size() == 0) { @@ -101,23 +102,18 @@ public class DisplayCommand extends PKCommand { } private void displayAvatar(CommandSender sender) { - List abilities = new ArrayList<>(); - for (String ability : AbilityModuleManager.abilities) { - if (!AbilityModuleManager.airbendingabilities.contains(ability) && !AbilityModuleManager.earthbendingabilities.contains(ability) && !AbilityModuleManager.firebendingabilities.contains(ability) && !AbilityModuleManager.waterbendingabilities.contains(ability) && !AbilityModuleManager.chiabilities.contains(ability)) { - abilities.add(ability); - } - } + ArrayList abilities = CoreAbility.getAbilitiesByElement(Element.AVATAR); if (abilities.isEmpty()) { - sender.sendMessage(ChatColor.YELLOW + "There are no " + GeneralMethods.getAvatarColor() + "avatar" + ChatColor.YELLOW + " abilities on this server!"); + sender.sendMessage(ChatColor.YELLOW + "There are no " + Element.AVATAR.getColor() + "avatar" + ChatColor.YELLOW + " abilities on this server!"); return; } - for (String ability : abilities) { + for (CoreAbility ability : abilities) { if (sender instanceof Player) { - if (GeneralMethods.canView((Player) sender, ability)) { - sender.sendMessage(GeneralMethods.getAvatarColor() + ability); + if (GeneralMethods.canView((Player) sender, ability.getName())) { + sender.sendMessage(ability.getElement().getColor() + ability.getName()); } } else { - sender.sendMessage(GeneralMethods.getAvatarColor() + ability); + sender.sendMessage(ability.getElement().getColor() + ability.getName()); } } } @@ -129,22 +125,26 @@ public class DisplayCommand extends PKCommand { * @param element The element to show the moves for */ private void displayElement(CommandSender sender, String element) { - List abilities = ProjectKorra.plugin.abManager.getAbilities(element); - if (abilities == null) { + element = this.getElement(element); + ArrayList abilities = CoreAbility.getAbilitiesByElement(Element.getElement(element)); + + if (abilities.isEmpty()) { sender.sendMessage(ChatColor.RED + "You must select a valid element."); return; } else if (abilities.isEmpty()) { - sender.sendMessage(ChatColor.YELLOW + "There are no " + GeneralMethods.getElementColor(Element.valueOf(element)) + element + ChatColor.YELLOW + " abilities enabled on the server."); + sender.sendMessage(ChatColor.YELLOW + "There are no " + element + " abilities enabled on the server."); } - for (String ability : abilities) { - if (GeneralMethods.isSubAbility(ability)) + + for (CoreAbility ability : abilities) { + if (ability instanceof SubAbility || ability.isHiddenAbility()) { continue; - if (!(sender instanceof Player) || GeneralMethods.canView((Player) sender, ability)) { - sender.sendMessage(GeneralMethods.getElementColor(Element.getType(element)) + ability); + } + if (!(sender instanceof Player) || GeneralMethods.canView((Player) sender, ability.getName())) { + sender.sendMessage(ability.getElement().getColor() + ability.getName()); } } + if (element.equalsIgnoreCase("earth")) { - //sender.sendMessage(ChatColor.DARK_GREEN + "Combos: " + ChatColor.GREEN + "/bending display EarthCombos"); if (sender.hasPermission("bending.earth.lavabending")) { sender.sendMessage(ChatColor.DARK_GREEN + "Lavabending abilities: " + ChatColor.GREEN + "/bending display Lavabending"); } @@ -154,17 +154,12 @@ public class DisplayCommand extends PKCommand { if (sender.hasPermission("bending.earth.sandbending")) { sender.sendMessage(ChatColor.DARK_GREEN + "Sandbending abilities: " + ChatColor.GREEN + "/bending display Sandbending"); } - } - if (element.equalsIgnoreCase("air")) { + } else if (element.equalsIgnoreCase("air")) { sender.sendMessage(ChatColor.DARK_GRAY + "Combos: " + ChatColor.GRAY + "/bending display AirCombos"); if (sender.hasPermission("bending.air.flight")) { sender.sendMessage(ChatColor.DARK_GRAY + "Flight abilities: " + ChatColor.GRAY + "/bending display Flight"); } - //if (sender.hasPermission("bending.air.spiritualprojection")) { - // sender.sendMessage(ChatColor.DARK_GRAY + "SpiritualProjection abilities: " + ChatColor.GRAY + "/bending display spiritualprojection"); - //} - } - if (element.equalsIgnoreCase("fire")) { + } else if (element.equalsIgnoreCase("fire")) { sender.sendMessage(ChatColor.DARK_RED + "Combos: " + ChatColor.RED + "/bending display FireCombos"); if (sender.hasPermission("bending.fire.lightningbending")) { sender.sendMessage(ChatColor.DARK_RED + "Lightning abilities: " + ChatColor.RED + "/bending display Lightning"); @@ -172,8 +167,7 @@ public class DisplayCommand extends PKCommand { if (sender.hasPermission("bending.fire.combustionbending")) { sender.sendMessage(ChatColor.DARK_RED + "Combustion abilities: " + ChatColor.RED + "/bending display Combustion"); } - } - if (element.equalsIgnoreCase("water")) { + } else if (element.equalsIgnoreCase("water")) { sender.sendMessage(ChatColor.DARK_AQUA + "Combos: " + ChatColor.AQUA + "/bending display WaterCombos"); if (sender.hasPermission("bending.water.bloodbending")) { sender.sendMessage(ChatColor.DARK_AQUA + "Bloodbending abilities: " + ChatColor.AQUA + "/bending display Bloodbending"); @@ -187,8 +181,7 @@ public class DisplayCommand extends PKCommand { if (sender.hasPermission("bending.water.plantbending")) { sender.sendMessage(ChatColor.DARK_AQUA + "Plantbending abilities: " + ChatColor.AQUA + "/bending display Plantbending"); } - } - if (element.equalsIgnoreCase("chi")) { + } else if (element.equalsIgnoreCase("chi")) { sender.sendMessage(ChatColor.GOLD + "Combos: " + ChatColor.YELLOW + "/bending display ChiCombos"); } } @@ -200,16 +193,23 @@ public class DisplayCommand extends PKCommand { * @param element The subelement to show the moves for */ private void displaySubElement(CommandSender sender, String element) { - List abilities = ProjectKorra.plugin.abManager.getAbilities(element); - if (abilities.isEmpty() && element != null) { - Element e = SubElement.getType(element.toLowerCase()).getMainElement(); - ChatColor color = GeneralMethods.getSubBendingColor(e); + element = this.getElement(element); + Element mainElement = Element.getElement(element); + List abilities = CoreAbility.getAbilitiesByElement(mainElement); + + + if (mainElement instanceof SubElement) { + mainElement = ((SubElement) mainElement).getParentElement(); + } + ChatColor color = mainElement != null ? mainElement.getColor() : null; + + if (abilities.isEmpty() && mainElement != null) { sender.sendMessage(ChatColor.YELLOW + "There are no " + color + element + ChatColor.YELLOW + " abilities installed!"); return; } - for (String ability : abilities) { - if (!(sender instanceof Player) || GeneralMethods.canView((Player) sender, ability)) { - sender.sendMessage(GeneralMethods.getSubBendingColor(Element.getType(getElement(element))) + ability); + for (CoreAbility ability : abilities) { + if (!(sender instanceof Player) || GeneralMethods.canView((Player) sender, ability.getName())) { + sender.sendMessage(color + ability.getName()); } } } @@ -220,10 +220,10 @@ public class DisplayCommand extends PKCommand { * @param sender The CommandSender to output the bound abilities to */ private void displayBinds(CommandSender sender) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(sender.getName()); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(sender.getName()); if (bPlayer == null) { GeneralMethods.createBendingPlayer(((Player) sender).getUniqueId(), sender.getName()); - bPlayer = GeneralMethods.getBendingPlayer(sender.getName()); + bPlayer = BendingPlayer.getBendingPlayer(sender.getName()); } HashMap abilities = bPlayer.getAbilities(); @@ -235,8 +235,9 @@ public class DisplayCommand extends PKCommand { for (int i = 1; i <= 9; i++) { String ability = abilities.get(i); - if (ability != null && !ability.equalsIgnoreCase("null")) - sender.sendMessage(i + " - " + GeneralMethods.getAbilityColor(ability) + ability); + CoreAbility coreAbil = CoreAbility.getAbility(ability); + if (coreAbil != null && !ability.equalsIgnoreCase("null")) + sender.sendMessage(i + " - " + coreAbil.getElement().getColor() + ability); } } } diff --git a/src/com/projectkorra/projectkorra/command/HelpCommand.java b/src/com/projectkorra/projectkorra/command/HelpCommand.java index b25035ec..353f4ecd 100644 --- a/src/com/projectkorra/projectkorra/command/HelpCommand.java +++ b/src/com/projectkorra/projectkorra/command/HelpCommand.java @@ -1,20 +1,14 @@ package com.projectkorra.projectkorra.command; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ability.AbilityModuleManager; -import com.projectkorra.projectkorra.ability.combo.ComboManager; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.chiblocking.ChiMethods; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.firebending.FireMethods; -import com.projectkorra.projectkorra.waterbending.WaterMethods; +import com.projectkorra.projectkorra.Element; +import com.projectkorra.projectkorra.ability.ComboAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.util.ComboManager; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; -import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; /** @@ -22,7 +16,7 @@ import java.util.List; */ public class HelpCommand extends PKCommand { public HelpCommand() { - super("help", "/bending help [Topic/Page]", "This command provides information on how to use other commands in ProjectKorra.", new String[] { "help", "h" }); + super("help", "/bending help", "This command provides information on how to use other commands in ProjectKorra.", new String[] { "help", "h" }); } @Override @@ -30,75 +24,52 @@ public class HelpCommand extends PKCommand { if (!hasPermission(sender) || !correctLength(sender, args.size(), 0, 1)) return; else if (args.size() == 0) { - List strings = new ArrayList(); for (PKCommand command : instances.values()) { - if (!command.getName().equalsIgnoreCase("help") && sender.hasPermission("bending.command." + command.getName())) { - strings.add(command.getProperUse()); - } - } - Collections.sort(strings); - Collections.reverse(strings); - strings.add(instances.get("help").getProperUse()); - Collections.reverse(strings); - for (String s : getPage(strings, ChatColor.GOLD + "Commands: [optional]", 1, false)) { - sender.sendMessage(ChatColor.YELLOW + s); + sender.sendMessage(ChatColor.YELLOW + command.getProperUse()); } return; } - - String arg = args.get(0); - - if (isNumeric(arg)) { - List strings = new ArrayList(); - for (PKCommand command : instances.values()) { - if (!command.getName().equalsIgnoreCase("help") && sender.hasPermission("bending.command." + command.getName())) { - strings.add(command.getProperUse()); - } - } - Collections.sort(strings); - Collections.reverse(strings); - strings.add(instances.get("help").getProperUse()); - Collections.reverse(strings); - for (String s : getPage(strings, ChatColor.GOLD + "Commands: [optional]", Integer.valueOf(arg), false)) { - sender.sendMessage(ChatColor.YELLOW + s); - } - } else if (instances.keySet().contains(arg.toLowerCase())) {//bending help command + + String arg = args.get(0).toLowerCase(); + + if (instances.keySet().contains(arg.toLowerCase())) { //bending help command instances.get(arg).help(sender, true); } else if (Arrays.asList(Commands.comboaliases).contains(arg)) { //bending help elementcombo sender.sendMessage(ChatColor.GOLD + "Proper Usage: " + ChatColor.RED + "/bending display " + arg + ChatColor.GOLD + " or " + ChatColor.RED + "/bending help "); - } else if (GeneralMethods.abilityExists(arg)) { //bending help ability - String ability = GeneralMethods.getAbility(arg); - ChatColor color = GeneralMethods.getAbilityColor(ability); - sender.sendMessage(color + ability + " - "); - sender.sendMessage(color + AbilityModuleManager.descriptions.get(GeneralMethods.getAbility(ability))); + } else if (CoreAbility.getAbility(arg) != null && !(CoreAbility.getAbility(arg) instanceof ComboAbility)) { //bending help ability + CoreAbility ability = CoreAbility.getAbility(arg); + ChatColor color = ability.getElement().getColor(); + sender.sendMessage(color + ability.getName() + " - "); + sender.sendMessage(color + ability.getDescription()); } else if (Arrays.asList(Commands.airaliases).contains(args.get(0))) { - sender.sendMessage(AirMethods.getAirColor() + "Air is the element of freedom. Airbenders are natural pacifists and " + "great explorers. There is nothing stopping them from scaling the tallest of mountains and walls easily. They specialize in redirection, " + "from blasting things away with gusts of winds, to forming a shield around them to prevent damage. Easy to get across flat terrains, " + "such as oceans, there is practically no terrain off limits to Airbenders. They lack much raw damage output, but make up for it with " + "with their ridiculous amounts of utility and speed."); - sender.sendMessage(ChatColor.YELLOW + "Airbenders can chain their abilities into combos, type " + AirMethods.getAirColor() + "/b help AirCombos" + ChatColor.YELLOW + " for more information."); + sender.sendMessage(Element.AIR.getColor() + "Air is the element of freedom. Airbenders are natural pacifists and " + "great explorers. There is nothing stopping them from scaling the tallest of mountains and walls easily. They specialize in redirection, " + "from blasting things away with gusts of winds, to forming a shield around them to prevent damage. Easy to get across flat terrains, " + "such as oceans, there is practically no terrain off limits to Airbenders. They lack much raw damage output, but make up for it with " + "with their ridiculous amounts of utility and speed."); + sender.sendMessage(ChatColor.YELLOW + "Airbenders can chain their abilities into combos, type " + Element.AIR.getColor() + "/b help AirCombos" + ChatColor.YELLOW + " for more information."); sender.sendMessage(ChatColor.YELLOW + "Learn More: " + ChatColor.DARK_AQUA + "http://tinyurl.com/qffg9m3"); } else if (Arrays.asList(Commands.wateraliases).contains(args.get(0))) { - sender.sendMessage(WaterMethods.getWaterColor() + "Water is the element of change. Waterbending focuses on using your " + "opponents own force against them. Using redirection and various dodging tactics, you can be made " + "practically untouchable by an opponent. Waterbending provides agility, along with strong offensive " + "skills while in or near water."); - sender.sendMessage(ChatColor.YELLOW + "Waterbenders can chain their abilities into combos, type " + WaterMethods.getWaterColor() + "/b help WaterCombos" + ChatColor.YELLOW + " for more information."); + sender.sendMessage(Element.WATER.getColor() + "Water is the element of change. Waterbending focuses on using your " + "opponents own force against them. Using redirection and various dodging tactics, you can be made " + "practically untouchable by an opponent. Waterbending provides agility, along with strong offensive " + "skills while in or near water."); + sender.sendMessage(ChatColor.YELLOW + "Waterbenders can chain their abilities into combos, type " + Element.WATER.getColor() + "/b help WaterCombos" + ChatColor.YELLOW + " for more information."); sender.sendMessage(ChatColor.YELLOW + "Learn More: " + ChatColor.DARK_AQUA + "http://tinyurl.com/lod3plv"); } else if (Arrays.asList(Commands.earthaliases).contains(args.get(0))) { - sender.sendMessage(EarthMethods.getEarthColor() + "Earth is the element of substance. Earthbenders share many of the " + "same fundamental techniques as Waterbenders, but their domain is quite different and more readily " + "accessible. Earthbenders dominate the ground and subterranean, having abilities to pull columns " + "of rock straight up from the earth or drill their way through the mountain. They can also launch " + "themselves through the air using pillars of rock, and will not hurt themselves assuming they land " + "on something they can bend. The more skilled Earthbenders can even bend metal."); + sender.sendMessage(Element.EARTH.getColor() + "Earth is the element of substance. Earthbenders share many of the " + "same fundamental techniques as Waterbenders, but their domain is quite different and more readily " + "accessible. Earthbenders dominate the ground and subterranean, having abilities to pull columns " + "of rock straight up from the earth or drill their way through the mountain. They can also launch " + "themselves through the air using pillars of rock, and will not hurt themselves assuming they land " + "on something they can bend. The more skilled Earthbenders can even bend metal."); //sender.sendMessage(ChatColor.YELLOW + "Earthbenders can chain their abilities into combos, type " + EarthMethods.getEarthColor() + "/b help EarthCombos" + ChatColor.YELLOW + " for more information."); sender.sendMessage(ChatColor.YELLOW + "Learn More: " + ChatColor.DARK_AQUA + "http://tinyurl.com/qaudl42"); } else if (Arrays.asList(Commands.firealiases).contains(args.get(0))) { - sender.sendMessage(FireMethods.getFireColor() + "Fire is the element of power. Firebenders focus on destruction and " + "incineration. Their abilities are pretty straight forward: set things on fire. They do have a bit " + "of utility however, being able to make themselves un-ignitable, extinguish large areas, cook food " + "in their hands, extinguish large areas, small bursts of flight, and then comes the abilities to shoot " + "fire from your hands."); - sender.sendMessage(ChatColor.YELLOW + "Firebenders can chain their abilities into combos, type " + FireMethods.getFireColor() + "/b help FireCombos" + ChatColor.YELLOW + " for more information."); + sender.sendMessage(Element.FIRE.getColor() + "Fire is the element of power. Firebenders focus on destruction and " + "incineration. Their abilities are pretty straight forward: set things on fire. They do have a bit " + "of utility however, being able to make themselves un-ignitable, extinguish large areas, cook food " + "in their hands, extinguish large areas, small bursts of flight, and then comes the abilities to shoot " + "fire from your hands."); + sender.sendMessage(ChatColor.YELLOW + "Firebenders can chain their abilities into combos, type " + Element.FIRE.getColor() + "/b help FireCombos" + ChatColor.YELLOW + " for more information."); sender.sendMessage(ChatColor.YELLOW + "Learn More: " + ChatColor.DARK_AQUA + "http://tinyurl.com/k4fkjhb"); } else if (Arrays.asList(Commands.chialiases).contains(args.get(0))) { - sender.sendMessage(ChiMethods.getChiColor() + "Chiblockers focus on bare handed combat, utilizing their agility and " + "speed to stop any bender right in their path. Although they lack the ability to bend any of the " + "other elements, they are great in combat, and a serious threat to any bender. Chiblocking was " + "first shown to be used by Ty Lee in Avatar: The Last Airbender, then later by members of the " + "Equalists in The Legend of Korra."); - sender.sendMessage(ChatColor.YELLOW + "Chiblockers can chain their abilities into combos, type " + ChiMethods.getChiColor() + "/b help ChiCombos" + ChatColor.YELLOW + " for more information."); + sender.sendMessage(Element.CHI.getColor() + "Chiblockers focus on bare handed combat, utilizing their agility and " + "speed to stop any bender right in their path. Although they lack the ability to bend any of the " + "other elements, they are great in combat, and a serious threat to any bender. Chiblocking was " + "first shown to be used by Ty Lee in Avatar: The Last Airbender, then later by members of the " + "Equalists in The Legend of Korra."); + sender.sendMessage(ChatColor.YELLOW + "Chiblockers can chain their abilities into combos, type " + Element.CHI.getColor() + "/b help ChiCombos" + ChatColor.YELLOW + " for more information."); sender.sendMessage(ChatColor.YELLOW + "Learn More: " + ChatColor.DARK_AQUA + "http://tinyurl.com/mkp9n6y"); } else { //combos - handled differently because they're stored in CamelCase in ComboManager - for (String combo : ComboManager.descriptions.keySet()) { + for (String combo : ComboManager.getDescriptions().keySet()) { if (combo.equalsIgnoreCase(arg)) { - ChatColor color = GeneralMethods.getComboColor(combo); + CoreAbility coreAbility = CoreAbility.getAbility(combo); + ChatColor color = coreAbility != null ? coreAbility.getElement().getColor() : null; sender.sendMessage(color + combo + " (Combo) - "); - sender.sendMessage(color + ComboManager.descriptions.get(combo)); - sender.sendMessage(ChatColor.GOLD + "Usage: " + ComboManager.instructions.get(combo)); + sender.sendMessage(color + ComboManager.getDescriptions().get(combo)); + sender.sendMessage(ChatColor.GOLD + "Usage: " + ComboManager.getInstructions().get(combo)); return; } } diff --git a/src/com/projectkorra/projectkorra/command/ImportCommand.java b/src/com/projectkorra/projectkorra/command/ImportCommand.java index 89e572a9..d15123b9 100644 --- a/src/com/projectkorra/projectkorra/command/ImportCommand.java +++ b/src/com/projectkorra/projectkorra/command/ImportCommand.java @@ -4,7 +4,6 @@ import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.Element; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.StockAbility; import com.projectkorra.projectkorra.storage.DBConnection; import org.bukkit.Bukkit; @@ -56,30 +55,18 @@ public class ImportCommand extends PKCommand { String playername = string; @SuppressWarnings("deprecation") UUID uuid = ProjectKorra.plugin.getServer().getOfflinePlayer(playername).getUniqueId(); - ArrayList element = new ArrayList(); - List oe = bendingPlayers.getIntegerList(string + ".BendingTypes"); - HashMap abilities = new HashMap(); - List oa = bendingPlayers.getIntegerList(string + ".SlotAbilities"); + ArrayList elements = new ArrayList(); + List bendingTypes = bendingPlayers.getIntegerList(string + ".BendingTypes"); boolean permaremoved = bendingPlayers.getBoolean(string + ".Permaremoved"); - - int slot = 1; - for (int i : oa) { - if (StockAbility.getAbility(i) != null) { - abilities.put(slot, StockAbility.getAbility(i).toString()); - slot++; - } else { - abilities.put(slot, null); - slot++; + Element[] mainElements = Element.getMainElements(); + + for (int i : bendingTypes) { + if (i < mainElements.length) { + elements.add(mainElements[i]); } } - for (int i : oe) { - if (Element.getType(i) != null) { - element.add(Element.getType(i)); - } - } - - BendingPlayer bPlayer = new BendingPlayer(uuid, playername, element, abilities, permaremoved); + BendingPlayer bPlayer = new BendingPlayer(uuid, playername, elements, new HashMap(), permaremoved); bPlayers.add(bPlayer); } @@ -110,15 +97,15 @@ public class ImportCommand extends PKCommand { } StringBuilder elements = new StringBuilder(); BendingPlayer bPlayer = bPlayers.pop(); - if (bPlayer.hasElement(Element.Air)) + if (bPlayer.hasElement(Element.AIR)) elements.append("a"); - if (bPlayer.hasElement(Element.Water)) + if (bPlayer.hasElement(Element.WATER)) elements.append("w"); - if (bPlayer.hasElement(Element.Earth)) + if (bPlayer.hasElement(Element.EARTH)) elements.append("e"); - if (bPlayer.hasElement(Element.Fire)) + if (bPlayer.hasElement(Element.FIRE)) elements.append("f"); - if (bPlayer.hasElement(Element.Chi)) + if (bPlayer.hasElement(Element.CHI)) elements.append("c"); HashMap abilities = bPlayer.getAbilities(); diff --git a/src/com/projectkorra/projectkorra/command/PKCommand.java b/src/com/projectkorra/projectkorra/command/PKCommand.java index 08abf019..1686b392 100644 --- a/src/com/projectkorra/projectkorra/command/PKCommand.java +++ b/src/com/projectkorra/projectkorra/command/PKCommand.java @@ -4,13 +4,8 @@ import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import java.text.NumberFormat; -import java.text.ParsePosition; -import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -154,66 +149,39 @@ public abstract class PKCommand implements SubCommand { * otherwise */ public String getElement(String element) { - if (Arrays.asList(Commands.firealiases).contains(element) || Arrays.asList(Commands.firecomboaliases).contains(element) || Arrays.asList(Commands.combustionaliases).contains(element) || Arrays.asList(Commands.lightningaliases).contains(element)) + if (Arrays.asList(Commands.firealiases).contains(element) || Arrays.asList(Commands.firecomboaliases).contains(element)) return "fire"; - else if (Arrays.asList(Commands.earthaliases).contains(element) || Arrays.asList(Commands.earthcomboaliases).contains(element) || Arrays.asList(Commands.metalbendingaliases).contains(element) || Arrays.asList(Commands.sandbendingaliases).contains(element) || Arrays.asList(Commands.lavabendingaliases).contains(element)) - return "earth"; - else if (Arrays.asList(Commands.airaliases).contains(element) || Arrays.asList(Commands.aircomboaliases).contains(element) || Arrays.asList(Commands.spiritualprojectionaliases).contains(element) || Arrays.asList(Commands.flightaliases).contains(element)) - return "air"; - else if (Arrays.asList(Commands.wateraliases).contains(element) || Arrays.asList(Commands.watercomboaliases).contains(element) || Arrays.asList(Commands.healingaliases).contains(element) || Arrays.asList(Commands.bloodaliases).contains(element) || Arrays.asList(Commands.icealiases).contains(element) || Arrays.asList(Commands.plantaliases).contains(element)) - return "water"; + else if (Arrays.asList(Commands.combustionaliases).contains(element)) + return "combustion"; + else if (Arrays.asList(Commands.lightningaliases).contains(element)) + return "lightning"; + else if (Arrays.asList(Commands.earthaliases).contains(element) || Arrays.asList(Commands.earthcomboaliases).contains(element)) + return "earth"; + else if (Arrays.asList(Commands.metalbendingaliases).contains(element)) + return "metal"; + else if (Arrays.asList(Commands.sandbendingaliases).contains(element)) + return "sand"; + else if (Arrays.asList(Commands.lavabendingaliases).contains(element)) + return "lava"; + else if (Arrays.asList(Commands.airaliases).contains(element) || Arrays.asList(Commands.aircomboaliases).contains(element)) + return "air"; + else if (Arrays.asList(Commands.spiritualprojectionaliases).contains(element)) + return "spiritual"; + else if (Arrays.asList(Commands.flightaliases).contains(element)) + return "flight"; + else if (Arrays.asList(Commands.wateraliases).contains(element) || Arrays.asList(Commands.watercomboaliases).contains(element)) + return "water"; + else if (Arrays.asList(Commands.healingaliases).contains(element)) + return "healing"; + else if (Arrays.asList(Commands.bloodaliases).contains(element)) + return "blood"; + else if (Arrays.asList(Commands.icealiases).contains(element)) + return "ice"; + else if (Arrays.asList(Commands.plantaliases).contains(element)) + return "plant"; else if (Arrays.asList(Commands.chialiases).contains(element) || Arrays.asList(Commands.chicomboaliases).contains(element)) return "chi"; return null; } - /** - * Returns a boolean if the string provided is numerical. - * @param id - * @return boolean - */ - protected boolean isNumeric(String id) { - NumberFormat formatter = NumberFormat.getInstance(); - ParsePosition pos = new ParsePosition(0); - formatter.parse(id, pos); - return id.length() == pos.getIndex(); - } - - /** - * Returns a list for of commands for a page. - * @param entries - * @param title - * @param page - * @return - */ - protected List getPage(List entries, String title, int page, boolean alphabetical) { - List strings = new ArrayList(); - if (alphabetical) { - Collections.sort(entries); - } - - if (page < 1) { - page = 1; - } - if ((page * 8) - 8 >= entries.size()) { - page = Math.round(entries.size() / 8) + 1; - if (page < 1) { - page = 1; - } - } - strings.add(ChatColor.GOLD + "ProjectKorra " + ChatColor.DARK_GRAY + "- [" + ChatColor.GRAY + page + "/" + (int) Math.ceil((entries.size()+.0)/(8+.0)) + ChatColor.DARK_GRAY + "]"); - strings.add(title); - if (entries.size() > ((page * 8) - 8)) { - for (int i = ((page * 8) - 8); i < entries.size(); i++) { - if (entries.get(i) != null) { - strings.add(entries.get(i).toString()); - } - if (i >= (page * 8)-1) { - break; - } - } - } - - return strings; - } } diff --git a/src/com/projectkorra/projectkorra/command/PermaremoveCommand.java b/src/com/projectkorra/projectkorra/command/PermaremoveCommand.java index c13b6fd7..0ee64f5a 100644 --- a/src/com/projectkorra/projectkorra/command/PermaremoveCommand.java +++ b/src/com/projectkorra/projectkorra/command/PermaremoveCommand.java @@ -46,10 +46,10 @@ public class PermaremoveCommand extends PKCommand { return; } - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); if (bPlayer == null) { GeneralMethods.createBendingPlayer(player.getUniqueId(), player.getName()); - bPlayer = GeneralMethods.getBendingPlayer(player.getName()); + bPlayer = BendingPlayer.getBendingPlayer(player.getName()); } if (bPlayer.isPermaRemoved()) { diff --git a/src/com/projectkorra/projectkorra/command/PresetCommand.java b/src/com/projectkorra/projectkorra/command/PresetCommand.java index 7df9a229..59fc245a 100644 --- a/src/com/projectkorra/projectkorra/command/PresetCommand.java +++ b/src/com/projectkorra/projectkorra/command/PresetCommand.java @@ -2,10 +2,9 @@ package com.projectkorra.projectkorra.command; import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ability.multiability.MultiAbilityManager; +import com.projectkorra.projectkorra.ability.util.MultiAbilityManager; import com.projectkorra.projectkorra.object.Preset; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -29,10 +28,9 @@ public class PresetCommand extends PKCommand { super("preset", "/bending preset create|bind|list|delete [name]", "This command manages Presets, which are saved bindings. Use /bending preset list to view your existing presets, use /bending [create|delete] [name] to manage your presets, and use /bending bind [name] to bind an existing preset.", new String[] { "preset", "presets", "pre", "set", "p" }); } - @SuppressWarnings("unchecked") @Override public void execute(CommandSender sender, List args) { - if (!isPlayer(sender) || !correctLength(sender, args.size(), 1, 3)) { + if (!isPlayer(sender) || !correctLength(sender, args.size(), 1, 2)) { return; } else if (MultiAbilityManager.hasMultiAbilityBound((Player) sender)) { sender.sendMessage(ChatColor.RED + "You can't edit your binds right now!"); @@ -40,12 +38,6 @@ public class PresetCommand extends PKCommand { } Player player = (Player) sender; - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (bPlayer == null) { - GeneralMethods.createBendingPlayer(((Player) player).getUniqueId(), player.getName()); - bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - } //bending preset list if (args.size() == 1) { @@ -82,88 +74,16 @@ public class PresetCommand extends PKCommand { sender.sendMessage(ChatColor.GREEN + "You have deleted your preset named: " + ChatColor.YELLOW + name); return; } else if (Arrays.asList(bindaliases).contains(args.get(0)) && hasPermission(sender, "bind")) { //bending preset bind name - if (args.size() < 3) { - boolean boundAll = false; - if (Preset.presetExists(player, name)) { - Preset preset = Preset.getPreset(player, name); - boundAll = Preset.bindPreset(player, preset); - } else if (Preset.externalPresetExists(name) && hasPermission(sender, "bind.external")) { - boundAll = Preset.bindExternalPreset(player, name); - } else if (!Preset.externalPresetExists(name) && hasPermission(sender, "bind.external")) { - sender.sendMessage(ChatColor.RED + "No external preset with that name exists."); - return; - } else if (bPlayer.isPermaRemoved()) { - player.sendMessage(ChatColor.RED + "Your bending was permanently removed."); - return; - } else { - sender.sendMessage(ChatColor.RED + "You don't have a preset with that name."); - return; - } - - sender.sendMessage(ChatColor.GREEN + "Your bound slots have been set to match the " + ChatColor.YELLOW + name + ChatColor.GREEN + " preset."); - if (!boundAll) { - sender.sendMessage(ChatColor.RED + "Some abilities were not bound because you cannot bend the required element."); - } - } else if (hasPermission(sender, "bind.external.assign") && Preset.externalPresetExists(name)) { - if (!Preset.externalPresetExists(name)) { - sender.sendMessage(ChatColor.RED + "No external preset with that name exists."); - return; - } - - Player player2 = Bukkit.getPlayer(args.get(2)); - if (player2 != null && player2.isOnline()) { - BendingPlayer bPlayer2 = GeneralMethods.getBendingPlayer(player2.getName()); - - if (bPlayer2 == null) { - GeneralMethods.createBendingPlayer(((Player) player2).getUniqueId(), player2.getName()); - bPlayer = GeneralMethods.getBendingPlayer(player2.getName()); - } - if (bPlayer2.isPermaRemoved()) { - player.sendMessage(ChatColor.RED + "Your bending was permanently removed."); - return; - } - boolean boundAll = Preset.bindExternalPreset(player2, name); - - sender.sendMessage(ChatColor.GREEN + "The bound slots of " + ChatColor.YELLOW + player2.getName() + ChatColor.GREEN + " have been set to match the " + ChatColor.YELLOW + name + ChatColor.GREEN + " preset."); - player2.sendMessage(ChatColor.GREEN + "Your bound slots have been set to match the " + ChatColor.YELLOW + name + ChatColor.GREEN + " preset."); - if (!boundAll) { - player2.sendMessage(ChatColor.RED + "Some abilities were not bound, either the preset contains invalid abilities or you cannot bend the required elements."); - } - return; - } else { - sender.sendMessage(ChatColor.RED + "Player not found."); - } - } else if (hasPermission(sender, "bind.assign") && Preset.presetExists(player, name)) { - if (!Preset.presetExists(player, name)) { - sender.sendMessage(ChatColor.RED + "You don't have a preset with that name."); - return; - } - - Player player2 = Bukkit.getPlayer(args.get(2)); - if (player2 != null && player2.isOnline()) { - BendingPlayer bPlayer2 = GeneralMethods.getBendingPlayer(player2.getName()); - - if (bPlayer2 == null) { - GeneralMethods.createBendingPlayer(((Player) player2).getUniqueId(), player2.getName()); - bPlayer = GeneralMethods.getBendingPlayer(player2.getName()); - } - if (bPlayer2.isPermaRemoved()) { - player.sendMessage(ChatColor.RED + "Your bending was permanently removed."); - return; - } - Preset preset = Preset.getPreset(player, name); - boolean boundAll = Preset.bindPreset(player2, preset); - - sender.sendMessage(ChatColor.GREEN + "The bound slots of " + ChatColor.YELLOW + player2.getName() + ChatColor.GREEN + " have been set to match your " + ChatColor.YELLOW + name + ChatColor.GREEN + " preset."); - player2.sendMessage(ChatColor.GREEN + "Your bound slots have been set to match " + ChatColor.YELLOW + player.getName() + "'s " + name + ChatColor.GREEN + " preset."); - if (!boundAll) { - player2.sendMessage(ChatColor.RED + "Some abilities were not bound, either the preset contains invalid abilities or you cannot bend the required elements."); - } - return; - } else { - sender.sendMessage(ChatColor.RED + "Player not found."); - } + if (!Preset.presetExists(player, name)) { + sender.sendMessage(ChatColor.RED + "You don't have a preset with that name."); + return; } + boolean boundAll = Preset.bindPreset(player, name); + sender.sendMessage(ChatColor.GREEN + "Your bound slots have been set to match the " + ChatColor.YELLOW + name + ChatColor.GREEN + " preset."); + if (!boundAll) { + sender.sendMessage(ChatColor.RED + "Some abilities were not bound because you cannot bend the required element."); + } + return; } else if (Arrays.asList(createaliases).contains(args.get(0)) && hasPermission(sender, "create")) { //bending preset create name int limit = GeneralMethods.getMaxPresets(player); @@ -175,16 +95,16 @@ public class PresetCommand extends PKCommand { return; } - if (bPlayer == null) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) return; - } - HashMap abilities = (HashMap) bPlayer.getAbilities().clone(); - + HashMap abilities = bPlayer.getAbilities(); Preset preset = new Preset(player.getUniqueId(), name, abilities); - preset.save(player); + preset.save(); sender.sendMessage(ChatColor.GREEN + "Created preset with the name: " + ChatColor.YELLOW + name); } else { help(sender, false); } } + } diff --git a/src/com/projectkorra/projectkorra/command/RemoveCommand.java b/src/com/projectkorra/projectkorra/command/RemoveCommand.java index e5cdd457..f3e7f338 100644 --- a/src/com/projectkorra/projectkorra/command/RemoveCommand.java +++ b/src/com/projectkorra/projectkorra/command/RemoveCommand.java @@ -3,7 +3,6 @@ package com.projectkorra.projectkorra.command; import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.Element; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.chiblocking.ChiMethods; import com.projectkorra.projectkorra.event.PlayerChangeElementEvent; import com.projectkorra.projectkorra.event.PlayerChangeElementEvent.Result; @@ -32,18 +31,20 @@ public class RemoveCommand extends PKCommand { Player player = Bukkit.getPlayer(args.get(0)); if (player == null) { - Element e = Element.getType(getElement(args.get(0))); - if (e != null && sender instanceof Player) { - if (GeneralMethods.getBendingPlayer(sender.getName()).hasElement(e)) { - GeneralMethods.getBendingPlayer(sender.getName()).getElements().remove(e); - GeneralMethods.saveElements(GeneralMethods.getBendingPlayer(sender.getName())); + Element e = Element.getElement(getElement(args.get(0))); + BendingPlayer senderBPlayer = BendingPlayer.getBendingPlayer(sender.getName()); + + if (senderBPlayer != null && e != null && sender instanceof Player) { + if (senderBPlayer.hasElement(e)) { + senderBPlayer.getElements().remove(e); + GeneralMethods.saveElements(senderBPlayer); GeneralMethods.removeUnusableAbilities(sender.getName()); - if (e == Element.Chi) { - sender.sendMessage(ChiMethods.getChiColor() + "You have removed your chiblocking."); + + if (e == Element.CHI) { + sender.sendMessage(Element.CHI.getColor() + "You have removed your chiblocking."); return; } - sender.sendMessage(GeneralMethods.getElementColor(e) + "You have removed your " + e.toString().toLowerCase() + "bending."); - Bukkit.getServer().getPluginManager().callEvent(new PlayerChangeElementEvent(sender, (Player) sender, e, Result.REMOVE)); + sender.sendMessage(e.getColor() + "You have removed your " + e.toString().toLowerCase() + "bending."); return; } else { sender.sendMessage(ChatColor.RED + "You do not have that element!"); @@ -54,13 +55,13 @@ public class RemoveCommand extends PKCommand { return; } - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); if (bPlayer == null) { GeneralMethods.createBendingPlayer(player.getUniqueId(), player.getName()); - bPlayer = GeneralMethods.getBendingPlayer(player.getName()); + bPlayer = BendingPlayer.getBendingPlayer(player); } if (args.size() == 2) { - Element e = Element.getType(getElement(args.get(1))); + Element e = Element.getElement(getElement(args.get(1))); if (e != null) { if (!bPlayer.hasElement(e)) { sender.sendMessage(ChatColor.DARK_RED + "Targeted player does not have that element"); @@ -69,12 +70,12 @@ public class RemoveCommand extends PKCommand { bPlayer.getElements().remove(e); GeneralMethods.saveElements(bPlayer); GeneralMethods.removeUnusableAbilities(player.getName()); - if (e == Element.Chi) { - sender.sendMessage(ChiMethods.getChiColor() + "You have removed the chiblocking of " + ChatColor.DARK_AQUA + player.getName()); - player.sendMessage(ChiMethods.getChiColor() + "Your chiblocking has been removed by " + ChatColor.DARK_AQUA + sender.getName()); + if (e == Element.CHI) { + sender.sendMessage(Element.CHI.getColor() + "You have removed the chiblocking of " + ChatColor.DARK_AQUA + player.getName()); + player.sendMessage(Element.CHI.getColor() + "Your chiblocking has been removed by " + ChatColor.DARK_AQUA + sender.getName()); } else { - sender.sendMessage(GeneralMethods.getElementColor(e) + "You have removed the " + getElement(args.get(1)).toLowerCase() + "bending of " + ChatColor.DARK_AQUA + player.getName()); - player.sendMessage(GeneralMethods.getElementColor(e) + "Your " + getElement(args.get(1)).toLowerCase() + "bending has been removed by " + ChatColor.DARK_AQUA + sender.getName()); + sender.sendMessage(e.getColor() + "You have removed the " + getElement(args.get(1)).toLowerCase() + "bending of " + ChatColor.DARK_AQUA + player.getName()); + player.sendMessage(e.getColor() + "Your " + getElement(args.get(1)).toLowerCase() + "bending has been removed by " + ChatColor.DARK_AQUA + sender.getName()); } Bukkit.getServer().getPluginManager().callEvent(new PlayerChangeElementEvent(sender, player, e, Result.REMOVE)); return; diff --git a/src/com/projectkorra/projectkorra/command/ToggleCommand.java b/src/com/projectkorra/projectkorra/command/ToggleCommand.java index 2848d041..e1fb0ffe 100644 --- a/src/com/projectkorra/projectkorra/command/ToggleCommand.java +++ b/src/com/projectkorra/projectkorra/command/ToggleCommand.java @@ -3,7 +3,6 @@ package com.projectkorra.projectkorra.command; import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.Element; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.chiblocking.ChiMethods; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -34,10 +33,10 @@ public class ToggleCommand extends PKCommand { sender.sendMessage(ChatColor.RED + "Bending is currently toggled off for all players."); return; } - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(sender.getName()); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(sender.getName()); if (bPlayer == null) { GeneralMethods.createBendingPlayer(((Player) sender).getUniqueId(), sender.getName()); - bPlayer = GeneralMethods.getBendingPlayer(sender.getName()); + bPlayer = BendingPlayer.getBendingPlayer(sender.getName()); } if (bPlayer.isToggled()) { sender.sendMessage(ChatColor.RED + "Your bending has been toggled off. You will not be able to use most abilities until you toggle it back."); @@ -62,46 +61,54 @@ public class ToggleCommand extends PKCommand { if (!(sender instanceof Player)) sender.sendMessage(ChatColor.RED + "Bending has been toggled off for all players."); } - } else if (sender instanceof Player && args.size() == 1 && Element.getType(getElement(args.get(0))) != null && GeneralMethods.getBendingPlayer(sender.getName()).hasElement(Element.getType(getElement(args.get(0))))) { - Element e = Element.getType(getElement(args.get(0))); - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(sender.getName()); + } else if (sender instanceof Player && args.size() == 1 + && Element.getElement(getElement(args.get(0))) != null + && BendingPlayer.getBendingPlayer(sender.getName()).hasElement(Element.getElement(getElement(args.get(0))))) { + Element e = Element.getElement(getElement(args.get(0))); + ChatColor color = e != null ? e.getColor() : null; + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(sender.getName()); bPlayer.toggleElement(e); + if (bPlayer.isElementToggled(e) == false) { - if (e == Element.Chi) { - sender.sendMessage(ChiMethods.getChiColor() + "You have toggled off your chiblocking"); + if (e == Element.CHI) { + sender.sendMessage(color + "You have toggled off your chiblocking"); } else { - sender.sendMessage(GeneralMethods.getElementColor(e) + "You have toggled off your " + getElement(args.get(0)).toLowerCase() + "bending"); + sender.sendMessage(color + "You have toggled off your " + getElement(args.get(0)).toLowerCase() + "bending"); } } else { - if (e == Element.Chi) { - sender.sendMessage(ChiMethods.getChiColor() + "You have toggled on your chiblocking"); + if (e == Element.CHI) { + sender.sendMessage(color + "You have toggled on your chiblocking"); } else { - sender.sendMessage(GeneralMethods.getElementColor(e) + "You have toggled on your " + getElement(args.get(0)).toLowerCase() + "bending"); + sender.sendMessage(color + "You have toggled on your " + getElement(args.get(0)).toLowerCase() + "bending"); } } - } else if (sender instanceof Player && args.size() == 2 && Element.getType(getElement(args.get(0))) != null && GeneralMethods.getBendingPlayer(sender.getName()).hasElement(Element.getType(getElement(args.get(0))))) { + } else if (sender instanceof Player && args.size() == 2 + && Element.getElement(getElement(args.get(0))) != null + && BendingPlayer.getBendingPlayer(sender.getName()).hasElement(Element.getElement(getElement(args.get(0))))) { Player target = Bukkit.getPlayer(args.get(1)); if (!hasAdminPermission(sender)) return; if (target == null) { sender.sendMessage(ChatColor.RED + "Target is not found."); } - Element e = Element.getType(getElement(args.get(0))); - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(target.getName()); + Element e = Element.getElement(getElement(args.get(0))); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(target.getName()); + ChatColor color = e != null ? e.getColor() : null; + if (bPlayer.isElementToggled(e) == true) { - if (e == Element.Chi) { - sender.sendMessage(ChiMethods.getChiColor() + "You have toggled off " + ChatColor.DARK_AQUA + target.getName() + "'s chiblocking"); - target.sendMessage(ChiMethods.getChiColor() + "Your chiblocking has been toggled off by " + ChatColor.DARK_AQUA + sender.getName()); + if (e == Element.CHI) { + sender.sendMessage(color + "You have toggled off " + ChatColor.DARK_AQUA + target.getName() + "'s chiblocking"); + target.sendMessage(color + "Your chiblocking has been toggled off by " + ChatColor.DARK_AQUA + sender.getName()); } else { - sender.sendMessage(GeneralMethods.getElementColor(e) + "You have toggled off " + ChatColor.DARK_AQUA + target.getName() + "'s " + getElement(args.get(0)).toLowerCase() + "bending"); - target.sendMessage(GeneralMethods.getElementColor(e) + "Your " + getElement(args.get(0)).toLowerCase() + "bending has been toggled off by " + ChatColor.DARK_AQUA + sender.getName()); + sender.sendMessage(color + "You have toggled off " + ChatColor.DARK_AQUA + target.getName() + "'s " + getElement(args.get(0)).toLowerCase() + "bending"); + target.sendMessage(color + "Your " + getElement(args.get(0)).toLowerCase() + "bending has been toggled off by " + ChatColor.DARK_AQUA + sender.getName()); } } else { - if (e == Element.Chi) { - sender.sendMessage(ChiMethods.getChiColor() + "You have toggled on " + ChatColor.DARK_AQUA + target.getName() + "'s chiblocking"); - target.sendMessage(ChiMethods.getChiColor() + "Your chiblocking has been toggled on by " + ChatColor.DARK_AQUA + sender.getName()); + if (e == Element.CHI) { + sender.sendMessage(color + "You have toggled on " + ChatColor.DARK_AQUA + target.getName() + "'s chiblocking"); + target.sendMessage(color + "Your chiblocking has been toggled on by " + ChatColor.DARK_AQUA + sender.getName()); } else { - sender.sendMessage(GeneralMethods.getElementColor(e) + "You have toggled on " + ChatColor.DARK_AQUA + target.getName() + "'s " + getElement(args.get(0)).toLowerCase() + "bending"); - target.sendMessage(GeneralMethods.getElementColor(e) + "Your " + getElement(args.get(0)).toLowerCase() + "bending has been toggled on by " + ChatColor.DARK_AQUA + sender.getName()); + sender.sendMessage(color + "You have toggled on " + ChatColor.DARK_AQUA + target.getName() + "'s " + getElement(args.get(0)).toLowerCase() + "bending"); + target.sendMessage(color + "Your " + getElement(args.get(0)).toLowerCase() + "bending has been toggled on by " + ChatColor.DARK_AQUA + sender.getName()); } } bPlayer.toggleElement(e); diff --git a/src/com/projectkorra/projectkorra/command/WhoCommand.java b/src/com/projectkorra/projectkorra/command/WhoCommand.java index 33631a19..62385f8a 100644 --- a/src/com/projectkorra/projectkorra/command/WhoCommand.java +++ b/src/com/projectkorra/projectkorra/command/WhoCommand.java @@ -4,11 +4,7 @@ import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.Element; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.chiblocking.ChiMethods; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.firebending.FireMethods; -import com.projectkorra.projectkorra.waterbending.WaterMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; import com.projectkorra.rpg.RPGMethods; import org.bukkit.Bukkit; @@ -34,7 +30,7 @@ public class WhoCommand extends PKCommand { Map staff = new HashMap(); public WhoCommand() { - super("who", "/bending who [Player/Page]", "This command will tell you what element all players that are online are (If you don't specify a player) or give you information about the player that you specify.", new String[] { "who", "w" }); + super("who", "/bending who [Player]", "This command will tell you what element all players that are online are (If you don't specify a player) or give you information about the player that you specify.", new String[] { "who", "w" }); staff.put("8621211e-283b-46f5-87bc-95a66d68880e", ChatColor.RED + "ProjectKorra Founder"); // MistPhizzle @@ -70,73 +66,64 @@ public class WhoCommand extends PKCommand { public void execute(CommandSender sender, List args) { if (!hasPermission(sender) || !correctLength(sender, args.size(), 0, 1)) { return; - } else if (args.size() == 1 && args.get(0).length() > 2) { + } else if (args.size() == 1) { whoPlayer(sender, args.get(0)); - } else if (args.size() == 0 || args.size() == 1) { - int page = 1; - if (args.size() == 1 && isNumeric(args.get(0))) { - page = Integer.valueOf(args.get(0)); - } + } else if (args.size() == 0) { List players = new ArrayList(); for (Player player : Bukkit.getOnlinePlayers()) { String playerName = player.getName(); String result = ""; - BendingPlayer bp = GeneralMethods.getBendingPlayer(playerName); + BendingPlayer bp = BendingPlayer.getBendingPlayer(playerName); + if (bp == null) { GeneralMethods.createBendingPlayer(player.getUniqueId(), player.getName()); - bp = GeneralMethods.getBendingPlayer(player.getName()); + bp = BendingPlayer.getBendingPlayer(player.getName()); } - if (bp.hasElement(Element.Air)) { - result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.Air) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&7&mA") : AirMethods.getAirColor() + "A"); + if (bp.hasElement(Element.AIR)) { + result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.AIR) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&7&mA") : Element.AIR.getColor() + "A"); } - if (bp.hasElement(Element.Earth)) { + if (bp.hasElement(Element.EARTH)) { if (result == "") { - result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.Earth) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&a&mE") : EarthMethods.getEarthColor() + "E"); + result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.EARTH) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&a&mE") : Element.EARTH.getColor() + "E"); } else { - result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.Earth) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&a&mE") : EarthMethods.getEarthColor() + "E"); + result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.EARTH) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&a&mE") : Element.EARTH.getColor() + "E"); } } - if (bp.hasElement(Element.Fire)) { + if (bp.hasElement(Element.FIRE)) { if (result == "") { - result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.Fire) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&c&mF") : FireMethods.getFireColor() + "F"); + result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.FIRE) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&c&mF") : Element.FIRE.getColor() + "F"); } else { - result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.Fire) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&c&mF") : FireMethods.getFireColor() + "F"); + result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.FIRE) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&c&mF") : Element.FIRE.getColor() + "F"); } } - if (bp.hasElement(Element.Water)) { + if (bp.hasElement(Element.WATER)) { if (result == "") { - result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.Water) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&b&mW") : WaterMethods.getWaterColor() + "W"); + result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.WATER) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&b&mW") : Element.WATER.getColor() + "W"); } else { - result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.Water) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&b&mW") : WaterMethods.getWaterColor() + "W"); + result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.WATER) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&b&mW") : Element.WATER.getColor() + "W"); } } - if (bp.hasElement(Element.Chi)) { + if (bp.hasElement(Element.CHI)) { if (result == "") { - result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.Chi) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&6&mC") : ChiMethods.getChiColor() + "C"); + result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.CHI) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&6&mC") : Element.CHI.getColor() + "C"); } else { - result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.Chi) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&6&mC") : ChiMethods.getChiColor() + "C"); + result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.CHI) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&6&mC") : Element.CHI.getColor() + "C"); } } if (staff.containsKey(player.getUniqueId().toString())) { if (result == "") { - result = ChatColor.WHITE + playerName + " | " + staff.get(player.getUniqueId().toString()); + result = ChatColor.WHITE + playerName + staff.get(player.getUniqueId().toString()); } else { result = result + ChatColor.WHITE + " | " + staff.get(player.getUniqueId().toString()); } } - if (result == ""){ - result = ChatColor.WHITE + playerName; - } players.add(result); } if (players.isEmpty()) { sender.sendMessage(ChatColor.RED + "There is no one online."); } else { - //for (String st : players) { - // sender.sendMessage(st); - //} - for (String s : getPage(players, ChatColor.GOLD + "Players:", page, true)) { - sender.sendMessage(s); + for (String st : players) { + sender.sendMessage(st); } } } @@ -154,7 +141,6 @@ public class WhoCommand extends PKCommand { //Player player = Bukkit.getPlayer(playerName); @SuppressWarnings("deprecation") final OfflinePlayer player = Bukkit.getOfflinePlayer(playerName); - BendingPlayer bplayer = GeneralMethods.getBendingPlayer(player.getName()); if (player == null || !player.hasPlayedBefore()) { sender.sendMessage(ChatColor.RED + "Player not found!"); return; @@ -164,8 +150,9 @@ public class WhoCommand extends PKCommand { } Player player_ = (Player) (player.isOnline() ? player : null); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); - if (!BendingPlayer.getPlayers().containsKey(player.getUniqueId())) { + if (bPlayer == null) { GeneralMethods.createBendingPlayer(player.getUniqueId(), playerName); BukkitRunnable runnable = new BukkitRunnable() { @Override @@ -193,99 +180,82 @@ public class WhoCommand extends PKCommand { runnable.runTaskAsynchronously(ProjectKorra.plugin); return; } - if (BendingPlayer.getPlayers().containsKey(player.getUniqueId())) { + + bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer != null) { sender.sendMessage(player.getName() + (!player.isOnline() ? ChatColor.RESET + " (Offline)" : "") + " - "); - if (GeneralMethods.isBender(playerName, Element.Air)) { - if(bplayer.isElementToggled(Element.Air)) { - sender.sendMessage(AirMethods.getAirColor() + "- Airbender"); - } else { - sender.sendMessage(AirMethods.getAirColor() + "" + ChatColor.STRIKETHROUGH + "- Airbender"); + if (bPlayer.hasElement(Element.AIR)) { + sender.sendMessage(Element.AIR + "- Airbender"); + if (player_ != null && bPlayer.canUseFlight()) { + sender.sendMessage(Element.FLIGHT.getColor() + " Can Fly"); } - if (player_ != null && AirMethods.canAirFlight((Player) player)) { - sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Air) + " Can Fly"); - } - if (player_ != null && AirMethods.canUseSpiritualProjection((Player) player)) { - sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Air) + " Can use Spiritual Projection"); + if (player_ != null && bPlayer.canUseSpiritualProjection()) { + sender.sendMessage(Element.SPIRITUAL.getColor() + " Can use Spiritual Projection"); } } - if (GeneralMethods.isBender(playerName, Element.Water)) { - if(bplayer.isElementToggled(Element.Water)) { - sender.sendMessage(WaterMethods.getWaterColor() + "- Waterbender"); - } else { - sender.sendMessage(WaterMethods.getWaterColor() + "" + ChatColor.STRIKETHROUGH + "- Waterbender"); + if (bPlayer.hasElement(Element.WATER)) { + sender.sendMessage(Element.WATER.getColor() + "- Waterbender"); + if (player_ != null && bPlayer.canPlantbend()) { + sender.sendMessage(Element.PLANT.getColor() + " Can Plantbend"); } - if (player_ != null && WaterMethods.canPlantbend((Player) player)) { - sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Water) + " Can Plantbend"); - } - if (player_ != null && WaterMethods.canBloodbend((Player) player)) { - if (WaterMethods.canBloodbendAtAnytime((Player) player)) { - sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Water) + " Can Bloodbend anytime, on any day"); + if (player_ != null && bPlayer.canBloodbend()) { + if (bPlayer.canBloodbendAtAnytime()) { + sender.sendMessage(Element.BLOOD.getColor() + " Can Bloodbend anytime, on any day"); } else { - sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Water) + " Can Bloodbend"); + sender.sendMessage(Element.BLOOD.getColor() + " Can Bloodbend"); } } - if (player_ != null && WaterMethods.canIcebend((Player) player)) { - sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Water) + " Can Icebend"); + if (player_ != null && bPlayer.canIcebend()) { + sender.sendMessage(Element.ICE.getColor() + " Can Icebend"); } - if (player_ != null && WaterMethods.canWaterHeal((Player) player)) { - sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Water) + " Can Heal"); + if (player_ != null && bPlayer.canWaterHeal()) { + sender.sendMessage(Element.HEALING.getColor() + " Can Heal"); } } - if (GeneralMethods.isBender(playerName, Element.Earth)) { - if(bplayer.isElementToggled(Element.Earth)) { - sender.sendMessage(EarthMethods.getEarthColor() + "- Earthbender"); - } else { - sender.sendMessage(EarthMethods.getEarthColor() + "" + ChatColor.STRIKETHROUGH + "- Earthbender"); + if (bPlayer.hasElement(Element.EARTH)) { + sender.sendMessage(Element.EARTH.getColor() + "- Earthbender"); + if (player_ != null && bPlayer.canMetalbend()) { + sender.sendMessage(Element.METAL.getColor() + " Can Metalbend"); } - if (player_ != null && EarthMethods.canMetalbend((Player) player)) { - sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Earth) + " Can Metalbend"); + if (player_ != null && bPlayer.canLavabend()) { + sender.sendMessage(Element.LAVA.getColor() + " Can Lavabend"); } - if (player_ != null && EarthMethods.canLavabend((Player) player)) { - sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Earth) + " Can Lavabend"); - } - if (player_ != null && EarthMethods.canSandbend((Player) player)) { - sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Earth) + " Can Sandbend"); + if (player_ != null && bPlayer.canSandbend()) { + sender.sendMessage(Element.SAND.getColor() + " Can Sandbend"); } } - if (GeneralMethods.isBender(playerName, Element.Fire)) { - if(bplayer.isElementToggled(Element.Fire)) { - sender.sendMessage(FireMethods.getFireColor() + "- Firebender"); - } else { - sender.sendMessage(FireMethods.getFireColor() + "" + ChatColor.STRIKETHROUGH + "- Firebender"); + if (bPlayer.hasElement(Element.FIRE)) { + sender.sendMessage(Element.FIRE.getColor() + "- Firebender"); + if (player_ != null && bPlayer.canCombustionbend()) { + sender.sendMessage(Element.COMBUSTION.getColor() + " Can Combustionbend"); } - if (player_ != null && FireMethods.canCombustionbend((Player) player)) { - sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Fire) + " Can Combustionbend"); - } - if (player_ != null && FireMethods.canLightningbend((Player) player)) { - sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Fire) + " Can Lightningbend"); + if (player_ != null && bPlayer.canLightningbend()) { + sender.sendMessage(Element.LIGHTNING.getColor() + " Can Lightningbend"); } } - if (GeneralMethods.isBender(playerName, Element.Chi)) { - if(bplayer.isElementToggled(Element.Chi)) { - sender.sendMessage(ChiMethods.getChiColor() + "- Chiblocker"); - } else { - sender.sendMessage(ChiMethods.getChiColor() + "" + ChatColor.STRIKETHROUGH + "- Chiblocker"); - } + if (bPlayer.hasElement(Element.CHI)) { + sender.sendMessage(Element.CHI.getColor() + "- ChiBlocker"); } - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(playerName); + UUID uuid = player.getUniqueId(); if (bPlayer != null) { sender.sendMessage("Abilities: "); for (int i = 1; i <= 9; i++) { String ability = bPlayer.getAbilities().get(i); - if (ability == null || ability.equalsIgnoreCase("null")) { + CoreAbility coreAbil = CoreAbility.getAbility(ability); + if (coreAbil == null) { continue; } else { - sender.sendMessage(i + " - " + GeneralMethods.getAbilityColor(ability) + ability); + sender.sendMessage(i + " - " + coreAbil.getElement().getColor() + ability); } } } if (GeneralMethods.hasRPG()) { if (RPGMethods.isCurrentAvatar(player.getUniqueId())) { - sender.sendMessage(GeneralMethods.getAvatarColor() + "Current Avatar"); + sender.sendMessage(Element.AVATAR.getColor() + "Current Avatar"); } else if (RPGMethods.hasBeenAvatar(player.getUniqueId())) { - sender.sendMessage(GeneralMethods.getAvatarColor() + "Former Avatar"); + sender.sendMessage(Element.AVATAR.getColor() + "Former Avatar"); } } diff --git a/src/com/projectkorra/projectkorra/configuration/ConfigLoadable.java b/src/com/projectkorra/projectkorra/configuration/ConfigLoadable.java deleted file mode 100644 index a633fe59..00000000 --- a/src/com/projectkorra/projectkorra/configuration/ConfigLoadable.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.projectkorra.projectkorra.configuration; - -/** - * Represents something that loads values from configs. - * - * @author Jacklin213 - * @version 1.0.0 - */ -public interface ConfigLoadable { - - Config config = ConfigManager.defaultConfig; - - /** - * Reload/Loads variables from the configuration. - */ - public void reloadVariables(); - -} diff --git a/src/com/projectkorra/projectkorra/configuration/ConfigManager.java b/src/com/projectkorra/projectkorra/configuration/ConfigManager.java index 9b194329..776a55d1 100644 --- a/src/com/projectkorra/projectkorra/configuration/ConfigManager.java +++ b/src/com/projectkorra/projectkorra/configuration/ConfigManager.java @@ -7,41 +7,19 @@ import java.util.ArrayList; public class ConfigManager { - public static Config presetConfig; public static Config deathMsgConfig; public static Config defaultConfig; public ConfigManager() { - presetConfig = new Config(new File("presets.yml")); deathMsgConfig = new Config(new File("deathmessages.yml")); defaultConfig = new Config(new File("config.yml")); configCheck(ConfigType.DEFAULT); configCheck(ConfigType.DEATH_MESSAGE); - configCheck(ConfigType.PRESETS); } public static void configCheck(ConfigType type) { FileConfiguration config; switch (type) { - case PRESETS: - config = presetConfig.get(); - - ArrayList abilities = new ArrayList(); - abilities.add("FireBlast"); - abilities.add("AirBlast"); - abilities.add("WaterManipulation"); - abilities.add("EarthBlast"); - abilities.add("FireBurst"); - abilities.add("AirBurst"); - abilities.add("Torrent"); - abilities.add("Shockwave"); - abilities.add("AvatarState"); - - config.addDefault("Example", abilities); - - presetConfig.save(); - break; - case DEATH_MESSAGE: config = deathMsgConfig.get(); @@ -113,18 +91,15 @@ public class ConfigManager { earthbendable.add("NETHERRACK"); earthbendable.add("QUARTZ_ORE"); earthbendable.add("REDSTONE_ORE"); + earthbendable.add("SAND"); + earthbendable.add("SANDSTONE"); + earthbendable.add("RED_SANDSTONE"); earthbendable.add("MYCEL"); ArrayList metals = new ArrayList(); metals.add("IRON_BLOCK"); metals.add("GOLD_BLOCK"); metals.add("QUARTZ_BLOCK"); - - ArrayList sands = new ArrayList(); - sands.add("SAND"); - sands.add("SANDSTONE"); - sands.add("RED_SAND"); - sands.add("RED_SANDSTONE"); config.addDefault("Properties.Chat.Enable", true); config.addDefault("Properties.Chat.Format", ": "); @@ -178,13 +153,11 @@ public class ConfigManager { config.addDefault("Properties.Water.NightFactor", 1.5); config.addDefault("Properties.Water.FullMoonFactor", 2.0); config.addDefault("Properties.Water.CanBendPackedIce", true); - config.addDefault("Properties.Water.CanBendFromBentBlocks", false); config.addDefault("Properties.Water.PlaySound", true); config.addDefault("Properties.Water.NightMessage", "You feel the strength of the rising moon empowering your waterbending."); config.addDefault("Properties.Water.DayMessage", "You feel the empowering of your waterbending subside as the moon sets."); config.addDefault("Properties.Water.LunarEclipseMessage", "A lunar eclipse is out! Waterbendings are temporarily powerless."); config.addDefault("Properties.Water.FullMoonMessage", "A full moon is rising, empowering your waterbending like never before."); - config.addDefault("Properties.Water.Range", 4); config.addDefault("Properties.Earth.RevertEarthbending", true); config.addDefault("Properties.Earth.SafeRevert", true); @@ -192,10 +165,8 @@ public class ConfigManager { config.addDefault("Properties.Earth.CanBendWithWeapons", true); config.addDefault("Properties.Earth.EarthbendableBlocks", earthbendable); config.addDefault("Properties.Earth.MetalBlocks", metals); - config.addDefault("Properties.Earth.SandBlocks", sands); config.addDefault("Properties.Earth.MetalPowerFactor", 1.5); config.addDefault("Properties.Earth.PlaySound", true); - config.addDefault("Properties.Earth.Range", 4); config.addDefault("Properties.Fire.CanBendWithWeapons", true); config.addDefault("Properties.Fire.DayFactor", 1.25); @@ -248,12 +219,11 @@ public class ConfigManager { config.addDefault("Abilities.Air.AirBubble.Radius", 7); config.addDefault("Abilities.Air.AirBurst.Enabled", true); - config.addDefault("Abilities.Air.AirBurst.Description", "AirBurst is one of the most powerful abilities in the airbender's arsenal. " + "To use, press and hold sneak to charge your burst. " + "Once charged, you can either release sneak to release the burst in a sphere around you " + "or click to launch a cone-shaped burst of air in front of you. " + "Additionally, having this ability selected when you land on the ground from a " + "large enough fall will create a burst of air around you."); + config.addDefault("Abilities.Air.AirBurst.Description", "AirBurst is one of the most powerful abilities in the airbender's arsenal. " + "To use, press and hold sneak to charge your burst. " + "Once charged, you can either release sneak to launch a cone-shaped burst " + "of air in front of you, or click to release the burst in a sphere around you. " + "Additionally, having this ability selected when you land on the ground from a " + "large enough fall will create a burst of air around you."); config.addDefault("Abilities.Air.AirBurst.FallThreshold", 10); config.addDefault("Abilities.Air.AirBurst.PushFactor", 1.5); config.addDefault("Abilities.Air.AirBurst.ChargeTime", 1750); config.addDefault("Abilities.Air.AirBurst.Damage", 0); - config.addDefault("Abilities.Air.AirBurst.Cooldown", 0); config.addDefault("Abilities.Air.AirScooter.Enabled", true); config.addDefault("Abilities.Air.AirScooter.Description", "AirScooter is a fast means of transportation. To use, sprint, jump then click with " + "this ability selected. You will hop on a scooter of air and be propelled forward " + "in the direction you're looking (you don't need to press anything). " + "This ability can be used to levitate above liquids, but it cannot go up steep slopes. " + "Any other actions will deactivate this ability."); @@ -293,7 +263,6 @@ public class ConfigManager { config.addDefault("Abilities.Air.Flight.Enabled", true); config.addDefault("Abilities.Air.Flight.Description", "Jump in the air, crouch (default: shift) and hold with this ability bound and you will glide around in the direction you look. While flying, click to Hover. Click again to disable Hovering."); config.addDefault("Abilities.Air.Flight.HoverEnabled", true); - config.addDefault("Abilities.Air.Flight.Cooldown", 0); config.addDefault("Abilities.Air.Suffocate.Enabled", true); config.addDefault("Abilities.Air.Suffocate.Description", "This ability is one of the most dangerous abilities an Airbender possesses. To use, simply look at an entity and hold shift. The entity will begin taking damage as you extract the air from their lungs. Any bender caught in this sphere will only be able to use basic moves, such as AirSwipe, WaterManipulation, FireBlast, or EarthBlast. An entity can be knocked out of the sphere by certain bending arts, and your attention will be disrupted if you are hit by bending."); @@ -346,7 +315,7 @@ public class ConfigManager { config.addDefault("Abilities.Water.Bloodbending.Enabled", true); config.addDefault("Abilities.Water.Bloodbending.Description", "This ability was made illegal for a reason. With this ability selected, sneak while " + "targetting something and you will bloodbend that target. Bloodbent targets cannot move, " + "bend or attack. You are free to control their actions by looking elsewhere - they will " + "be forced to move in that direction. Additionally, clicking while bloodbending will " + "launch that target off in the direction you're looking. " + "People who are capable of bloodbending are immune to your technique, and you are immune to theirs."); - config.addDefault("Abilities.Water.Bloodbending.CanOnlyBeUsedAtNight", true); + config.addDefault("Abilities.Water.Bloodbending.CanOnlyBeUsedAtNight", false); config.addDefault("Abilities.Water.Bloodbending.CanBeUsedOnUndeadMobs", true); config.addDefault("Abilities.Water.Bloodbending.ThrowFactor", 2); config.addDefault("Abilities.Water.Bloodbending.Range", 10); @@ -357,7 +326,6 @@ public class ConfigManager { config.addDefault("Abilities.Water.HealingWaters.Enabled", true); config.addDefault("Abilities.Water.HealingWaters.Description", "To use, the bender must be at least partially submerged in water. " + "If the user is not sneaking, this ability will automatically begin " + "working provided the user has it selected. If the user is sneaking, " + "he/she is channeling the healing to their target in front of them. " + "In order for this channel to be successful, the user and the target must " + "be at least partially submerged in water."); - config.addDefault("Abilities.Water.HealingWaters.ShiftRequired", true); config.addDefault("Abilities.Water.HealingWaters.Radius", 5); config.addDefault("Abilities.Water.HealingWaters.Interval", 750); config.addDefault("Abilities.Water.HealingWaters.Power", 1); @@ -366,10 +334,8 @@ public class ConfigManager { config.addDefault("Abilities.Water.IceBlast.Damage", 3); config.addDefault("Abilities.Water.IceBlast.Range", 20); config.addDefault("Abilities.Water.IceBlast.Cooldown", 1500); - config.addDefault("Abilities.Water.IceBlast.SelectRange", 12); config.addDefault("Abilities.Water.IceBlast.Description", "This ability offers a powerful ice utility for Waterbenders. It can be used to fire an explosive burst of ice at an opponent, spraying ice and snow around it. To use, simply tap sneak (Default: Shift) while targeting a block of ice to select it as a source. From there, you can just left click to send the blast off at your opponent."); - config.addDefault("Abilities.Water.IceBlast.DynamicSourcing.Enabled", true); - + config.addDefault("Abilities.Water.IceSpike.Enabled", true); config.addDefault("Abilities.Water.IceSpike.Description", "This ability has many functions. Clicking while targetting ice, or an entity over some ice, " + "will raise a spike of ice up, damaging and slowing the target. Tapping sneak (shift) while" + " selecting a water source will select that source that can then be fired with a click. Firing" + " this will launch a spike of ice at your target, dealing a bit of damage and slowing the target. " + "If you sneak (shift) while not selecting a source, many ice spikes will erupt from around you, " + "damaging and slowing those targets."); config.addDefault("Abilities.Water.IceSpike.Cooldown", 2000); @@ -379,8 +345,6 @@ public class ConfigManager { config.addDefault("Abilities.Water.IceSpike.Height", 6); config.addDefault("Abilities.Water.IceSpike.Projectile.Range", 20); config.addDefault("Abilities.Water.IceSpike.Projectile.Damage", 1); - config.addDefault("Abilities.Water.IceSpike.Projectile.SelectRange", 12); - config.addDefault("Abilities.Water.IceSpike.DynamicSourcing.Enabled", true); config.addDefault("Abilities.Water.OctopusForm.Enabled", true); config.addDefault("Abilities.Water.OctopusForm.Description", "This ability allows the waterbender to manipulate a large quantity of water into a form resembling that of an octopus. " + "To use, click to select a water source. Then, hold sneak to channel this ability. " + "While channeling, the water will form itself around you and has a chance to block incoming attacks. " + "Additionally, you can click while channeling to attack things near you, dealing damage and knocking them back. " + "Releasing shift at any time will dissipate the form."); @@ -390,55 +354,36 @@ public class ConfigManager { config.addDefault("Abilities.Water.OctopusForm.Damage", 4); config.addDefault("Abilities.Water.OctopusForm.Knockback", 1.75); config.addDefault("Abilities.Water.OctopusForm.FormDelay", 40); - config.addDefault("Abilities.Water.OctopusForm.SelectRange", 12); - config.addDefault("Abilities.Water.OctopusForm.Cooldown", 0); - config.addDefault("Abilities.Water.OctopusForm.AutoSourcing.Enabled", true); - config.addDefault("Abilities.Water.OctopusForm.AutoSourcing.Cooldown", 1500); - config.addDefault("Abilities.Water.OctopusForm.AutoSourcing.SelectRange", 5); - config.addDefault("Abilities.Water.OctopusForm.DynamicSourcing.Enabled", true); config.addDefault("Abilities.Water.PhaseChange.Enabled", true); config.addDefault("Abilities.Water.PhaseChange.Description", "To use, simply left-click. " + "Any water you are looking at within range will instantly freeze over into solid ice. " + "Provided you stay within range of the ice and do not unbind FreezeMelt, " + "that ice will not thaw. If, however, you do either of those the ice will instantly thaw. " + "If you sneak (default: shift), anything around where you are looking at will instantly melt. " + "Since this is a more favorable state for these things, they will never re-freeze unless they " + "would otherwise by nature or some other bending ability. Additionally, if you tap sneak while " + "targetting water with FreezeMelt, it will evaporate water around that block that is above " + "sea level. "); - config.addDefault("Abilities.Water.PhaseChange.Range", 15); - config.addDefault("Abilities.Water.PhaseChange.Radius", 4); - config.addDefault("Abilities.Water.PhaseChange.Cooldown", 0); + config.addDefault("Abilities.Water.PhaseChange.Range", 20); + config.addDefault("Abilities.Water.PhaseChange.Radius", 5); config.addDefault("Abilities.Water.PlantArmor.Enabled", true); config.addDefault("Abilities.Water.PlantArmor.Description", "PlantArmor is a defensive ability in the arsenal of the plantbender. Clicking on leaves with this ability will temporarily clad you in strong armor made out of plants! You can use this defensively, but you can also use the armor as a source for other plantbending skills."); config.addDefault("Abilities.Water.PlantArmor.Duration", 7500); config.addDefault("Abilities.Water.PlantArmor.Resistance", 1); config.addDefault("Abilities.Water.PlantArmor.Cooldown", 10000); - config.addDefault("Abilities.Water.PlantArmor.SelectRange", 12); - config.addDefault("Abilities.Water.PlantArmor.AutoSourcing.Enabled", true); - config.addDefault("Abilities.Water.PlantArmor.AutoSourcing.Cooldown", 10000); - config.addDefault("Abilities.Water.PlantArmor.AutoSourcing.SelectRange", 5); + config.addDefault("Abilities.Water.PlantArmor.Range", 10); config.addDefault("Abilities.Water.Surge.Enabled", true); config.addDefault("Abilities.Water.Surge.Description", "This ability has two distinct features. If you sneak to select a source block, you can then click in a direction and a large wave will be launched in that direction. If you sneak again while the wave is en route, the wave will freeze the next target it hits. If, instead, you click to select a source block, you can hold sneak to form a wall of water at your cursor location. Click to shift between a water wall and an ice wall. Release sneak to dissipate it."); config.addDefault("Abilities.Water.Surge.Wave.Radius", 3); config.addDefault("Abilities.Water.Surge.Wave.Range", 20); - config.addDefault("Abilities.Water.Surge.Wave.SelectRange", 6); config.addDefault("Abilities.Water.Surge.Wave.HorizontalPush", 1); - config.addDefault("Abilities.Water.Surge.Wave.DynamicSourcing.Enabled", true); config.addDefault("Abilities.Water.Surge.VerticalPush", 0.2); + config.addDefault("Abilities.Water.Surge.Wall.Range", 5); config.addDefault("Abilities.Water.Surge.Wall.Radius", 2); - config.addDefault("Abilities.Water.Surge.Wall.SelectRange", 5); - config.addDefault("Abilities.Water.Surge.Wall.DynamicSourcing.Enabled", true); config.addDefault("Abilities.Water.Torrent.Enabled", true); config.addDefault("Abilities.Water.Torrent.Description", "Torrent is one of the strongest moves in a waterbender's arsenal. To use, first click a source block to select it; then hold shift to begin streaming the water around you. Water flowing around you this way will damage and knock back nearby enemies and projectiles. If you release shift during this, you will create a large wave that expands outwards from you, launching anything in its path back. Instead, if you click you release the water and channel it to flow towards your cursor. Anything caught in the blast will be tossed about violently and take damage. Finally, if you click again when the water is torrenting, it will freeze the area around it when it is obstructed."); config.addDefault("Abilities.Water.Torrent.Range", 25); config.addDefault("Abilities.Water.Torrent.DeflectDamage", 1); config.addDefault("Abilities.Water.Torrent.Damage", 3); - config.addDefault("Abilities.Water.Torrent.Cooldown", 1500); config.addDefault("Abilities.Water.Torrent.Wave.Radius", 15); config.addDefault("Abilities.Water.Torrent.Wave.Knockback", 1.5); config.addDefault("Abilities.Water.Torrent.Wave.Height", 1); - config.addDefault("Abilities.Water.Torrent.SelectRange", 12); - config.addDefault("Abilities.Water.Torrent.AutoSourcing.Enabled", true); - config.addDefault("Abilities.Water.Torrent.AutoSourcing.Cooldown", 1500); - config.addDefault("Abilities.Water.Torrent.AutoSourcing.SelectRange", 5); - config.addDefault("Abilities.Water.Torrent.DynamicSourcing.Enabled", true); config.addDefault("Abilities.Water.Plantbending.RegrowTime", 180000); @@ -505,13 +450,7 @@ public class ConfigManager { config.addDefault("Abilities.Water.WaterManipulation.Range", 30); config.addDefault("Abilities.Water.WaterManipulation.Speed", 35); config.addDefault("Abilities.Water.WaterManipulation.Push", 0.3); - config.addDefault("Abilities.Water.WaterManipulation.SelectRange", 12); - config.addDefault("Abilities.Water.WaterManipulation.AutoSourcing.Enabled", true); - config.addDefault("Abilities.Water.WaterManipulation.AutoSourcing.Cooldown", 1500); - config.addDefault("Abilities.Water.WaterManipulation.AutoSourcing.SelectRange", 5); - config.addDefault("Abilities.Water.WaterManipulation.DynamicSourcing.Enabled", true); - config.addDefault("Abilities.Water.WaterManipulation.Cooldown", 1500); - + config.addDefault("Abilities.Water.WaterManipulation.Cooldown", 1000); config.addDefault("Abilities.Water.WaterSpout.Enabled", true); config.addDefault("Abilities.Water.WaterSpout.Description", "This ability provides a Waterbender with a means of transportation. To use, simply left click while in or over water to spout water up beneath you, experiencing controlled levitation. Left clicking again while the spout is active will cause it to disappear. Alternatively, tapping a Waterbendable block while not in Water will select a water block as a source, from there, you can tap sneak (Default:Shift) to channel the Water around you. Releasing the sneak will create a wave allowing you a quick burst of controlled transportation. While riding the wave you may press sneak to cause the wave to disappear."); @@ -520,10 +459,11 @@ public class ConfigManager { config.addDefault("Abilities.Water.WaterSpout.Particles", false); config.addDefault("Abilities.Water.WaterSpout.Wave.Particles", false); config.addDefault("Abilities.Water.WaterSpout.Wave.Enabled", true); + config.addDefault("Abilities.Water.WaterSpout.Wave.Range", 6); config.addDefault("Abilities.Water.WaterSpout.Wave.ChargeTime", 500); config.addDefault("Abilities.Water.WaterSpout.Wave.FlightTime", 2500); config.addDefault("Abilities.Water.WaterSpout.Wave.Speed", 1.3); - config.addDefault("Abilities.Water.WaterSpout.Wave.SelectRange", 12); + config.addDefault("Abilities.Water.WaterSpout.Wave.Cooldown", 4500); config.addDefault("Abilities.Water.WaterCombo.Enabled", true); config.addDefault("Abilities.Water.WaterCombo.IceWave.Damage", 4); @@ -544,46 +484,32 @@ public class ConfigManager { config.addDefault("Abilities.Earth.Catapult.Length", 6); config.addDefault("Abilities.Earth.Catapult.Speed", 10); config.addDefault("Abilities.Earth.Catapult.Push", 4); - config.addDefault("Abilities.Earth.Catapult.ShiftModifier", 2); - config.addDefault("Abilities.Earth.Catapult.Cooldown", 0); config.addDefault("Abilities.Earth.Collapse.Enabled", true); config.addDefault("Abilities.Earth.Collapse.Description", " To use, simply left-click on an earthbendable block. " + "That block and the earthbendable blocks above it will be shoved " + "back into the earth below them, if they can. " + "This ability does have the capacity to trap something inside of it, " + "although it is incredibly difficult to do so. " + "Additionally, press sneak with this ability to affect an area around your targetted location - " + "all earth that can be moved downwards will be moved downwards. " + "This ability is especially risky or deadly in caves, depending on the " + "earthbender's goal and technique."); - config.addDefault("Abilities.Earth.Collapse.SelectRange", 20); + config.addDefault("Abilities.Earth.Collapse.Range", 20); config.addDefault("Abilities.Earth.Collapse.Radius", 7); config.addDefault("Abilities.Earth.Collapse.Speed", 8); - config.addDefault("Abilities.Earth.Collapse.Cooldown", 0); - config.addDefault("Abilities.Earth.Collapse.DynamicSourcing.Enabled", true); config.addDefault("Abilities.Earth.EarthArmor.Enabled", true); config.addDefault("Abilities.Earth.EarthArmor.Description", "This ability encases the earthbender in temporary armor. To use, click on a block that is earthbendable. If there is another block under it that is earthbendable, the block will fly to you and grant you temporary armor and damage reduction. This ability has a long cooldown."); config.addDefault("Abilities.Earth.EarthArmor.Duration", 10000); config.addDefault("Abilities.Earth.EarthArmor.Strength", 2); - config.addDefault("Abilities.Earth.EarthArmor.SelectRange", 20); config.addDefault("Abilities.Earth.EarthArmor.Cooldown", 17500); - config.addDefault("Abilities.Earth.EarthArmor.AutoSourcing.Enabled", true); - config.addDefault("Abilities.Earth.EarthArmor.AutoSourcing.SelectRange", 5); - config.addDefault("Abilities.Earth.EarthArmor.AutoSourcing.Cooldown", 17500); config.addDefault("Abilities.Earth.EarthBlast.Enabled", true); config.addDefault("Abilities.Earth.EarthBlast.Description", "To use, place your cursor over an earthbendable object (dirt, rock, ores, etc) " + "and tap sneak (default: shift). The object will temporarily turn to stone, " + "indicating that you have it focused as the source for your ability. " + "After you have selected an origin (you no longer need to be sneaking), " + "simply left-click in any direction and you will see your object launch " + "off in that direction, smashing into any creature in its path. If you look " + "towards a creature when you use this ability, it will target that creature. " + "A collision from Earth Blast both knocks the target back and deals some damage. " + "You cannot have multiple of these abilities flying at the same time."); config.addDefault("Abilities.Earth.EarthBlast.CanHitSelf", false); - config.addDefault("Abilities.Earth.EarthBlast.Radius", 30); + config.addDefault("Abilities.Earth.EarthBlast.PrepareRange", 10); + config.addDefault("Abilities.Earth.EarthBlast.Range", 30); config.addDefault("Abilities.Earth.EarthBlast.Speed", 35); - config.addDefault("Abilities.Earth.EarthBlast.SelectRange", 20); config.addDefault("Abilities.Earth.EarthBlast.Revert", true); config.addDefault("Abilities.Earth.EarthBlast.Damage", 3); config.addDefault("Abilities.Earth.EarthBlast.Push", 0.3); - config.addDefault("Abilities.Earth.EarthBlast.Cooldown", 1500); - config.addDefault("Abilities.Earth.EarthBlast.AutoSourcing.Enabled", true); - config.addDefault("Abilities.Earth.EarthBlast.AutoSourcing.Cooldown", 1500); - config.addDefault("Abilities.Earth.EarthBlast.AutoSourcing.SelectRange", 5); - config.addDefault("Abilities.Earth.EarthBlast.DynamicSourcing.Enabled", true); config.addDefault("Abilities.Earth.EarthGrab.Enabled", true); config.addDefault("Abilities.Earth.EarthGrab.Description", "To use, simply left-click while targeting a creature within range. " + "This ability will erect a circle of earth to trap the creature in."); config.addDefault("Abilities.Earth.EarthGrab.Range", 8); - config.addDefault("Abilities.Earth.EarthGrab.Cooldown", 0); config.addDefault("Abilities.Earth.EarthTunnel.Enabled", true); config.addDefault("Abilities.Earth.EarthTunnel.Description", "Earth Tunnel is a completely utility ability for earthbenders. To use, simply sneak (default: shift) in the direction you want to tunnel. You will slowly begin tunneling in the direction you're facing for as long as you sneak or if the tunnel has been dug long enough. This ability will be interrupted if it hits a block that cannot be earthbent."); @@ -607,7 +533,7 @@ public class ConfigManager { config.addDefault("Abilities.Earth.LavaFlow.ShiftCleanupDelay", 10000); config.addDefault("Abilities.Earth.LavaFlow.ClickLavaCleanupDelay", 7000); config.addDefault("Abilities.Earth.LavaFlow.ClickLandCleanupDelay", 20000); - config.addDefault("Abilities.Earth.LavaFlow.ClickRange", 10); + config.addDefault("Abilities.Earth.LavaFlow.ClickRange", 10.0); config.addDefault("Abilities.Earth.LavaFlow.ShiftRadius", 7.0); config.addDefault("Abilities.Earth.LavaFlow.ShiftPlatformRadius", 1.5); config.addDefault("Abilities.Earth.LavaFlow.ClickRadius", 5.0); @@ -621,15 +547,13 @@ public class ConfigManager { config.addDefault("Abilities.Earth.LavaFlow.DownwardFlow", 4); config.addDefault("Abilities.Earth.LavaFlow.AllowNaturalFlow", false); config.addDefault("Abilities.Earth.LavaFlow.ParticleDensity", 0.11); - config.addDefault("Abilities.Earth.LavaFlow.DynamicSourcing.Enabled", true); config.addDefault("Abilities.Earth.EarthSmash.Enabled", true); config.addDefault("Abilities.Earth.EarthSmash.Description", "To raise an EarthSmash hold sneak (default: shift) for approximately 1.5 seconds, " + "then release while aiming at dirt. To grab the EarthSmash aim at the center and hold sneak, " + "the EarthSmash will follow your mouse. You can shoot the EarthSmash by grabbing onto it and left clicking. " + "To ride the EarthSmash simply hop ontop of it and hold sneak while aiming in the direction that you wish to go. " + "Another way to ride an EarthSmash is to grab it with sneak and then right click it. " + "Use EarthSmash as a defensive shield, a powerful attack, or an advanced means of transportation."); config.addDefault("Abilities.Earth.EarthSmash.AllowGrab", true); config.addDefault("Abilities.Earth.EarthSmash.AllowShooting", true); config.addDefault("Abilities.Earth.EarthSmash.AllowFlight", true); - config.addDefault("Abilities.Earth.EarthSmash.SelectRange", 10); - config.addDefault("Abilities.Earth.EarthSmash.GrabRange", 3.0); + config.addDefault("Abilities.Earth.EarthSmash.GrabRange", 10); config.addDefault("Abilities.Earth.EarthSmash.ChargeTime", 1500); config.addDefault("Abilities.Earth.EarthSmash.Cooldown", 2500); config.addDefault("Abilities.Earth.EarthSmash.ShotRange", 30); @@ -640,6 +564,16 @@ public class ConfigManager { config.addDefault("Abilities.Earth.EarthSmash.FlightTimer", 3000); config.addDefault("Abilities.Earth.EarthSmash.RemoveTimer", 30000); + // config.addDefault("Abilities.Earth.LavaSurge.Enabled", true); + // config.addDefault("Abilities.Earth.LavaSurge.Description", "LavaSurge is a fundamental move for any Lavabender out there. To use, simply sneak (Default: Shift) while looking at a source of Earth or Lava, then click in a direction. A surge of lava will swiftly travel towards the target you were pointing at, dealing moderate damage, a large knockback, and setting them on fire."); + // config.addDefault("Abilities.Earth.LavaSurge.Damage", 4); + // config.addDefault("Abilities.Earth.LavaSurge.Cooldown", 1000); + // config.addDefault("Abilities.Earth.LavaSurge.FractureRadius", 1); + // config.addDefault("Abilities.Earth.LavaSurge.PrepareRange", 7); + // config.addDefault("Abilities.Earth.LavaSurge.TravelRange", 15); + // config.addDefault("Abilities.Earth.LavaSurge.MaxLavaWaves", 10); + // config.addDefault("Abilities.Earth.LavaSurge.SourceCanBeEarth", true); + config.addDefault("Abilities.Earth.MetalClips.Enabled", true); config.addDefault("Abilities.Earth.MetalClips.Description", "MetalClips has the potential to be both an offensive and a utility ability. To start, you must carry smelted Iron Ingots in your inventory. To apply the clips onto an entity, simply click at them. If the entity is a Zombie, a Skeleton, or a Player, the clips will form armor around the entity, giving you some control over them. Each additional clip will give you more control. If you have permission to do so, you may crush the entity against a wall with a 4th clip, hurting them. Without explicit permissions, you will only be able to strap three clips on your target. If the entity is not one of the above, the clip will simply do damage and fall to the ground, to be collected. Another permission requiring action is throwing entities. To do so, click while controlling a metalclipped entity"); config.addDefault("Abilities.Earth.MetalClips.Damage", 2); @@ -653,11 +587,9 @@ public class ConfigManager { config.addDefault("Abilities.Earth.RaiseEarth.Enabled", true); config.addDefault("Abilities.Earth.RaiseEarth.Description", "To use, simply left-click on an earthbendable block. " + "A column of earth will shoot upwards from that location. " + "Anything in the way of the column will be brought up with it, " + "leaving talented benders the ability to trap brainless entities up there. " + "Additionally, simply sneak (default shift) looking at an earthbendable block. " + "A wall of earth will shoot upwards from that location. " + "Anything in the way of the wall will be brought up with it. "); config.addDefault("Abilities.Earth.RaiseEarth.Column.Height", 6); - config.addDefault("Abilities.Earth.RaiseEarth.SelectRange", 15); + config.addDefault("Abilities.Earth.RaiseEarth.Wall.Range", 15); config.addDefault("Abilities.Earth.RaiseEarth.Wall.Height", 6); config.addDefault("Abilities.Earth.RaiseEarth.Wall.Width", 6); - config.addDefault("Abilities.Earth.RaiseEarth.Cooldown", 0); - config.addDefault("Abilities.Earth.RaiseEarth.DynamicSourcing.Enabled", true); config.addDefault("Abilities.Earth.Shockwave.Enabled", true); config.addDefault("Abilities.Earth.Shockwave.Description", "This is one of the most powerful moves in the earthbender's arsenal. " + "To use, you must first charge it by holding sneak (default: shift). " + "Once charged, you can release sneak to create an enormous shockwave of earth, " + "disturbing all earth around you and expanding radially outwards. " + "Anything caught in the shockwave will be blasted back and dealt damage. " + "If you instead click while charged, the disruption is focused in a cone in front of you. " + "Lastly, if you fall from a great enough height with this ability selected, you will automatically create a shockwave."); @@ -666,7 +598,6 @@ public class ConfigManager { config.addDefault("Abilities.Earth.Shockwave.Damage", 4); config.addDefault("Abilities.Earth.Shockwave.Knockback", 1.1); config.addDefault("Abilities.Earth.Shockwave.Range", 15); - config.addDefault("Abilities.Earth.Shockwave.Cooldown", 0); config.addDefault("Abilities.Earth.SandSpout.Enabled", true); config.addDefault("Abilities.Earth.SandSpout.Description", "SandSpout is a core move for travelling, evasion, and mobility for sandbenders. To use, simply left click while over sand or sandstone, and a column of sand will form at your feet, enabling you to levitate. Any mobs or players that touch your column will receive damage and be blinded. Beware, as the spout will stop working when no longer over sand!"); @@ -689,7 +620,6 @@ public class ConfigManager { config.addDefault("Abilities.Fire.Blaze.ArcOfFire.Arc", 16); config.addDefault("Abilities.Fire.Blaze.ArcOfFire.Range", 7); config.addDefault("Abilities.Fire.Blaze.RingOfFire.Range", 7); - config.addDefault("Abilities.Fire.Blaze.Cooldown", 0); config.addDefault("Abilities.Fire.Combustion.Enabled", true); config.addDefault("Abilities.Fire.Combustion.Description", "Combustion is a powerful ability only known by a few skilled Firebenders. It allows the bender to Firebend with their mind, concentrating energy to create a powerful blast. To use, simply tap sneak (Default: Shift) to launch the blast. This technique is highly destructive and very effective, it also comes with a long cooldown."); @@ -721,11 +651,10 @@ public class ConfigManager { config.addDefault("Abilities.Fire.FireBlast.Charged.FireTicks", 4); config.addDefault("Abilities.Fire.FireBurst.Enabled", true); - config.addDefault("Abilities.Fire.FireBurst.Description", "FireBurst is a very powerful firebending ability. " + "To use, press and hold sneak to charge your burst. " + "Once charged, you can either release sneak to release the burst in a sphere around you or " + "click to launch a cone-shaped burst of flames in front of you."); + config.addDefault("Abilities.Fire.FireBurst.Description", "FireBurst is a very powerful firebending ability. " + "To use, press and hold sneak to charge your burst. " + "Once charged, you can either release sneak to launch a cone-shaped burst " + "of flames in front of you, or click to release the burst in a sphere around you. "); config.addDefault("Abilities.Fire.FireBurst.Damage", 2); config.addDefault("Abilities.Fire.FireBurst.ChargeTime", 3500); config.addDefault("Abilities.Fire.FireBurst.Range", 15); - config.addDefault("Abilities.Fire.FireBurst.Cooldown", 0); config.addDefault("Abilities.Fire.FireJet.Enabled", true); config.addDefault("Abilities.Fire.FireJet.Description", "This ability is used for a limited burst of flight for firebenders. Clicking with this " + "ability selected will launch you in the direction you're looking, granting you " + "controlled flight for a short time. This ability can be used mid-air to prevent falling " + "to your death, but on the ground it can only be used if standing on a block that's " + "ignitable (e.g. not snow or water)."); diff --git a/src/com/projectkorra/projectkorra/configuration/ConfigType.java b/src/com/projectkorra/projectkorra/configuration/ConfigType.java index 471673e5..e44135e1 100644 --- a/src/com/projectkorra/projectkorra/configuration/ConfigType.java +++ b/src/com/projectkorra/projectkorra/configuration/ConfigType.java @@ -14,9 +14,5 @@ public enum ConfigType { /** * Death Message configuration represented by deathmessages.yml */ - DEATH_MESSAGE, - /** - * Preset configuration represented by presets.yml - */ - PRESETS; + DEATH_MESSAGE; } diff --git a/src/com/projectkorra/projectkorra/earthbending/Catapult.java b/src/com/projectkorra/projectkorra/earthbending/Catapult.java index 48fc97f1..3459cd5c 100644 --- a/src/com/projectkorra/projectkorra/earthbending/Catapult.java +++ b/src/com/projectkorra/projectkorra/earthbending/Catapult.java @@ -1,7 +1,7 @@ package com.projectkorra.projectkorra.earthbending; -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.EarthAbility; import org.bukkit.Location; import org.bukkit.block.Block; @@ -9,121 +9,94 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; +// TODO: Remove Catapult.Speed from the Configuration +public class Catapult extends EarthAbility { -public class Catapult implements ConfigLoadable { - - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static int LENGTH = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.Catapult.Length"); - private static double SPEED = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Catapult.Speed"); - private static double PUSH = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Catapult.Push"); - private static double SHIFT = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Catapult.ShiftModifier"); - private static long COOLDOWN = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.Catapult.Cooldown"); - - private int length = LENGTH; - private double speed = SPEED; - private double push = PUSH; - private double shift = SHIFT; - private long cooldown = COOLDOWN; - private Player player; + private boolean catapult; + private boolean moving; + private boolean flying; + private int length; + private int distance; + private long cooldown; + private double push; private Location origin; private Location location; private Vector direction; - private int distance; - private boolean catapult = false; - private boolean moving = false; - private boolean flying = false; - + public Catapult(Player player) { - /* Initial Checks */ - BendingPlayer bplayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bplayer.isOnCooldown("Catapult")) + super(player); + setFields(); + this.origin = player.getEyeLocation().clone(); + this.direction = origin.getDirection().clone().normalize(); + + if (!bPlayer.canBend(this)) { return; - /* End Initial Checks */ - // reloadVariables(); - this.player = player; - origin = player.getEyeLocation().clone(); - direction = origin.getDirection().clone().normalize(); + } Vector neg = direction.clone().multiply(-1); - Block block; distance = 0; + for (int i = 0; i <= length; i++) { location = origin.clone().add(neg.clone().multiply((double) i)); block = location.getBlock(); - if (EarthMethods.isEarthbendable(player, block)) { - distance = EarthMethods.getEarthbendableBlocksLength(player, block, neg, length - i); + if (isEarthbendable(block)) { + distance = getEarthbendableBlocksLength(block, neg, length - i); break; - } else if (!EarthMethods.isTransparentToEarthbending(player, block)) { + } else if (!isTransparent(block)) { break; } } if (distance != 0) { - if ((double) distance >= location.distance(origin)) { + if ((double) distance * distance >= location.distanceSquared(origin)) { catapult = true; } - if (player.isSneaking()) - distance = (int) (distance / shift); + if (player.isSneaking()) { + distance = distance / 2; + } moving = true; - instances.put(player, this); - bplayer.addCooldown("Catapult", cooldown); + start(); + bPlayer.addCooldown(this); } - } public Catapult(Player player, Catapult source) { - this.player = player; - // reloadVariables(); + super(player); flying = true; moving = false; - + setFields(); location = source.location.clone(); direction = source.direction.clone(); distance = source.distance; - instances.put(player, this); - EarthMethods.playEarthbendingSound(player.getLocation()); + start(); + playEarthbendingSound(player.getLocation()); fly(); } - - public static String getDescription() { - return "To use, left-click while looking in the direction you want to be launched. " - + "A pillar of earth will jut up from under you and launch you in that direction - " - + "if and only if there is enough earth behind where you're looking to launch you. " - + "Skillful use of this ability takes much time and work, and it does result in the " - + "death of certain gung-ho earthbenders. If you plan to use this ability, be sure " - + "you've read about your passive ability you innately have as an earthbender."; - } - - public static ArrayList getPlayers() { - ArrayList players = new ArrayList(); - for (Catapult cata : instances.values()) { - players.add(cata.getPlayer()); - } - return players; + + private void setFields() { + this.length = getConfig().getInt("Abilities.Earth.Catapult.Length"); + this.push = getConfig().getDouble("Abilities.Earth.Catapult.Push"); + this.distance = 0; + this.cooldown = 0; + this.catapult = false; + this.moving = false; + this.flying = false; } private void fly() { if (player.isDead() || !player.isOnline()) { remove(); return; - } - - if (!player.getWorld().equals(location.getWorld())) { + } else if (!player.getWorld().equals(location.getWorld())) { remove(); return; - } - - if (player.getLocation().distance(location) < 3) { - if (!moving) + } else if (player.getLocation().distanceSquared(location) < 9) { + if (!moving) { flying = false; + } return; } @@ -133,31 +106,16 @@ public class Catapult implements ConfigLoadable { return; } } + Vector vector = direction.clone().multiply(push * distance / length); vector.setY(player.getVelocity().getY()); player.setVelocity(vector); } - public int getLength() { - return length; - } - - public Player getPlayer() { - return player; - } - - public double getPush() { - return push; - } - - public double getSpeed() { - return speed; - } - private boolean moveEarth() { location = location.clone().add(direction); if (catapult) { - if (location.distance(origin) < .5) { + if (location.distance(origin) < 0.5) { for (Entity entity : GeneralMethods.getEntitiesAroundPoint(origin, 2)) { if (entity instanceof Player) { Player target = (Player) entity; @@ -168,69 +126,137 @@ public class Catapult implements ConfigLoadable { return false; } } else { - if (location.distance(origin) <= length - distance) { + double lengthSquared = (length - distance) * (length - distance); + if (location.distanceSquared(origin) <= lengthSquared) { for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2)) { entity.setVelocity(direction.clone().multiply(push * distance / length)); } return false; } } - EarthMethods.moveEarth(player, location.clone().subtract(direction), direction, distance, false); + moveEarth(location.clone().subtract(direction), direction, distance, false); return true; } - public boolean progress() { - if (player.isDead() || !player.isOnline()) { + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { remove(); - return false; + return; } - if (moving) + if (moving) { if (!moveEarth()) { moving = false; } - - if (flying) - fly(); - - if (!flying && !moving) - remove(); - return true; - } - - public static void progressAll() { - for (Catapult ability : instances.values()) { - ability.progress(); } - } - public static void removeAll() { - for (Catapult ability : instances.values()) { - ability.remove(); + if (flying) { + fly(); + } else if (!moving) { + remove(); + return; } } @Override - public void reloadVariables() { - LENGTH = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.Catapult.Length"); - SPEED = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Catapult.Speed"); - PUSH = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Catapult.Push"); + public String getName() { + return "Catapult"; } - public void remove() { - instances.remove(player); + @Override + public Location getLocation() { + if (player != null) { + return player.getLocation(); + } + return null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public boolean isCatapult() { + return catapult; + } + + public void setCatapult(boolean catapult) { + this.catapult = catapult; + } + + public boolean isMoving() { + return moving; + } + + public void setMoving(boolean moving) { + this.moving = moving; + } + + public boolean isFlying() { + return flying; + } + + public void setFlying(boolean flying) { + this.flying = flying; + } + + public int getLength() { + return length; } public void setLength(int length) { this.length = length; } + public int getDistance() { + return distance; + } + + public void setDistance(int distance) { + this.distance = distance; + } + + public double getPush() { + return push; + } + public void setPush(double push) { this.push = push; } - public void setSpeed(double speed) { - this.speed = speed; + public void setLocation(Location location) { + this.location = location; } + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/earthbending/Collapse.java b/src/com/projectkorra/projectkorra/earthbending/Collapse.java index f9e53b9e..16a42864 100644 --- a/src/com/projectkorra/projectkorra/earthbending/Collapse.java +++ b/src/com/projectkorra/projectkorra/earthbending/Collapse.java @@ -1,84 +1,235 @@ package com.projectkorra.projectkorra.earthbending; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.ClickType; +import java.util.concurrent.ConcurrentHashMap; import org.bukkit.Location; import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; +import org.bukkit.util.Vector; -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.EarthAbility; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.ClickType; -public class Collapse { +public class Collapse extends EarthAbility { - private static final double defaultradius = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Collapse.Radius"); - private static final int height = EarthColumn.standardheight; + private int distance; + private int height; + private long time; + private long cooldown; + private double range; + private double speed; + private Location origin; + private Location location; + private Vector direction; + private Block block; + private ConcurrentHashMap affectedBlocks; - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.Collapse.SelectRange"); - private static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.Collapse.DynamicSourcing.Enabled"); - - private ConcurrentHashMap blocks = new ConcurrentHashMap(); - private ConcurrentHashMap baseblocks = new ConcurrentHashMap(); - private double radius = defaultradius; - private Player player; - - @SuppressWarnings("deprecation") public Collapse(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("Collapse")) + super(player); + setFields(); + + if (!bPlayer.canBend(this)) { return; + } + + block = BlockSource.getEarthSourceBlock(player, range, ClickType.LEFT_CLICK); + if (block == null) { + return; + } - this.player = player; - Block sblock = BlockSource.getEarthSourceBlock(player, selectRange, selectRange, ClickType.SHIFT_DOWN, false, dynamic, true, EarthMethods.canSandbend(player), EarthMethods.canMetalbend(player)); - Location location; - if (sblock == null) { - location = player.getTargetBlock(EarthMethods.getTransparentEarthbending(), selectRange).getLocation(); + this.origin = block.getLocation(); + this.location = origin.clone(); + this.distance = getEarthbendableBlocksLength(block, direction.clone().multiply(-1), height); + loadAffectedBlocks(); + + if (distance != 0) { + start(); + bPlayer.addCooldown(this); + time = System.currentTimeMillis() - (long) (1000.0 / speed); } else { - location = sblock.getLocation(); - } - for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) { - if (EarthMethods.isEarthbendable(player, block) && !blocks.containsKey(block) && block.getY() >= location.getBlockY()) { - getAffectedBlocks(block); - } - } - - if (!baseblocks.isEmpty()) { - bPlayer.addCooldown("Collapse", GeneralMethods.getGlobalCooldown()); - } - - for (Block block : baseblocks.keySet()) { - new CompactColumn(player, block.getLocation()); + remove(); } } - private void getAffectedBlocks(Block block) { - Block baseblock = block; - int tall = 0; - ArrayList bendableblocks = new ArrayList(); - bendableblocks.add(block); - for (int i = 1; i <= height; i++) { - Block blocki = block.getRelative(BlockFace.DOWN, i); - if (EarthMethods.isEarthbendable(player, blocki)) { - baseblock = blocki; - bendableblocks.add(blocki); - tall++; - } else { - break; - } - } - baseblocks.put(baseblock, tall); - for (Block blocki : bendableblocks) { - blocks.put(blocki, baseblock); - } + public Collapse(Player player, Location origin) { + super(player); + setFields(); + this.origin = origin; + this.player = player; + this.block = origin.getBlock(); + this.location = origin.clone(); + this.distance = getEarthbendableBlocksLength(block, direction.clone().multiply(-1), height); + loadAffectedBlocks(); + if (distance != 0) { + start(); + time = System.currentTimeMillis() - (long) (1000.0 / speed); + } else { + remove(); + } } - public static String getDescription() { - return " To use, simply left-click on an earthbendable block. " + "That block and the earthbendable blocks above it will be shoved " + "back into the earth below them, if they can. " + "This ability does have the capacity to trap something inside of it, " + "although it is incredibly difficult to do so. " + "Additionally, press sneak with this ability to affect an area around your targetted location - " + "all earth that can be moved downwards will be moved downwards. " + "This ability is especially risky or deadly in caves, depending on the " + "earthbender's goal and technique."; + private void setFields() { + this.height = getConfig().getInt("Abilities.Earth.RaiseEarth.Column.Height"); + this.range = getConfig().getInt("Abilities.Earth.Collapse.Range"); + this.speed = getConfig().getDouble("Abilities.Earth.Collapse.Speed"); + this.cooldown = GeneralMethods.getGlobalCooldown(); + this.direction = new Vector(0, -1, 0); + this.affectedBlocks = new ConcurrentHashMap<>(); + } + + private void loadAffectedBlocks() { + affectedBlocks.clear(); + Block thisBlock; + + for (int i = 0; i <= distance; i++) { + thisBlock = block.getWorld().getBlockAt(location.clone().add(direction.clone().multiply(-i))); + affectedBlocks.put(thisBlock, thisBlock); + if (RaiseEarth.blockInAllAffectedBlocks(thisBlock)) { + RaiseEarth.revertBlock(thisBlock); + } + } + } + + public static boolean blockInAllAffectedBlocks(Block block) { + for (Collapse collapse : CoreAbility.getAbilities(Collapse.class)) { + if (collapse.affectedBlocks.containsKey(block)) { + return true; + } + } + return false; + } + + public static void revert(Block block) { + for (Collapse collapse : CoreAbility.getAbilities(Collapse.class)) { + collapse.affectedBlocks.remove(block); + } + } + + @Override + public void progress() { + if (System.currentTimeMillis() - time >= (long) (1000.0 / speed)) { + time = System.currentTimeMillis(); + if (!tryToMoveEarth()) { + remove(); + return; + } + } + } + + private boolean tryToMoveEarth() { + Block block = location.getBlock(); + location = location.add(direction); + if (distance == 0) { + return false; + } + + moveEarth(block, direction, distance); + loadAffectedBlocks(); + return location.distanceSquared(origin) < distance * distance; + } + + @Override + public String getName() { + return "Collapse"; + } + + @Override + public Location getLocation() { + return location; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public Block getBlock() { + return block; + } + + public void setBlock(Block block) { + this.block = block; + } + + public int getDistance() { + return distance; + } + + public void setDistance(int distance) { + this.distance = distance; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public ConcurrentHashMap getAffectedBlocks() { + return affectedBlocks; + } + + public void setLocation(Location location) { + this.location = location; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; } } diff --git a/src/com/projectkorra/projectkorra/earthbending/CollapseWall.java b/src/com/projectkorra/projectkorra/earthbending/CollapseWall.java new file mode 100644 index 00000000..409379b1 --- /dev/null +++ b/src/com/projectkorra/projectkorra/earthbending/CollapseWall.java @@ -0,0 +1,152 @@ +package com.projectkorra.projectkorra.earthbending; + +import java.util.ArrayList; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.EarthAbility; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.ClickType; + +// TODO: Merge this ability with Collapse +public class CollapseWall extends EarthAbility { + + private int range; + private int height; + private long cooldown; + private double radius; + private Location location; + private ConcurrentHashMap blocks; + private ConcurrentHashMap baseBlocks; + + public CollapseWall(Player player) { + super(player); + if (bPlayer.isOnCooldown(this)) { + return; + } + + this.range = getConfig().getInt("Abilities.Earth.Collapse.Range"); + this.height = getConfig().getInt("Abilities.Earth.RaiseEarth.Column.Height"); + this.radius = getConfig().getDouble("Abilities.Earth.Collapse.Radius"); + this.cooldown = GeneralMethods.getGlobalCooldown(); + this.blocks = new ConcurrentHashMap<>(); + this.baseBlocks = new ConcurrentHashMap<>(); + + Block sblock = BlockSource.getEarthSourceBlock(player, range, ClickType.SHIFT_DOWN); + if (sblock == null) { + location = getTargetEarthBlock(range).getLocation(); + } else { + location = sblock.getLocation(); + } + + for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) { + if (isEarthbendable(block) && !blocks.containsKey(block) && block.getY() >= location.getBlockY()) { + getAffectedBlocks(block); + } + } + + if (!baseBlocks.isEmpty()) { + bPlayer.addCooldown(this); + } + for (Block block : baseBlocks.keySet()) { + new Collapse(player, block.getLocation()); + } + } + + private void getAffectedBlocks(Block block) { + int tall = 0; + Block baseBlock = block; + ArrayList bendableBlocks = new ArrayList(); + bendableBlocks.add(block); + + for (int i = 1; i <= height; i++) { + Block blocki = block.getRelative(BlockFace.DOWN, i); + if (isEarthbendable(blocki)) { + baseBlock = blocki; + bendableBlocks.add(blocki); + tall++; + } else { + break; + } + } + + baseBlocks.put(baseBlock, tall); + for (Block blocki : bendableBlocks) { + blocks.put(blocki, baseBlock); + } + } + + @Override + public String getName() { + return "Collapse"; + } + + @Override + public void progress() {} + + @Override + public Location getLocation() { + return location; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public int getRange() { + return range; + } + + public void setRange(int range) { + this.range = range; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public ConcurrentHashMap getBlocks() { + return blocks; + } + + public ConcurrentHashMap getBaseBlocks() { + return baseBlocks; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/earthbending/CompactColumn.java b/src/com/projectkorra/projectkorra/earthbending/CompactColumn.java deleted file mode 100644 index c7a22cb6..00000000 --- a/src/com/projectkorra/projectkorra/earthbending/CompactColumn.java +++ /dev/null @@ -1,177 +0,0 @@ -package com.projectkorra.projectkorra.earthbending; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.ClickType; - -import org.bukkit.Location; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -import java.util.concurrent.ConcurrentHashMap; - -public class CompactColumn { - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - private static ConcurrentHashMap alreadydoneblocks = new ConcurrentHashMap(); - - private static int ID = Integer.MIN_VALUE; - private static int height = EarthColumn.standardheight; - private static double speed = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Collapse.Speed"); - private static final Vector direction = new Vector(0, -1, 0); - private static long interval = (long) (1000. / speed); - - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.Collapse.SelectRange"); - private static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.Collapse.DynamicSourcing.Enabled"); - - private Location origin; - private Location location; - private Block block; - private Player player; - private int distance; - private int id; - private long time; - private ConcurrentHashMap affectedblocks = new ConcurrentHashMap(); - - public CompactColumn(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("Collapse")) - return; - - block = BlockSource.getEarthSourceBlock(player, selectRange, selectRange, ClickType.LEFT_CLICK, false, dynamic, true, EarthMethods.canSandbend(player), EarthMethods.canMetalbend(player)); - if (block == null) - return; - origin = block.getLocation(); - location = origin.clone(); - this.player = player; - distance = EarthMethods.getEarthbendableBlocksLength(player, block, direction.clone().multiply(-1), height); - - loadAffectedBlocks(); - - if (distance != 0) { - if (canInstantiate()) { - id = ID; - instances.put(id, this); - bPlayer.addCooldown("Collapse", GeneralMethods.getGlobalCooldown()); - if (ID >= Integer.MAX_VALUE) { - ID = Integer.MIN_VALUE; - } - ID++; - time = System.currentTimeMillis() - interval; - } - } - } - - public CompactColumn(Player player, Location origin) { - // Methods.verbose("New compact column"); - this.origin = origin; - this.player = player; - block = origin.getBlock(); - // Methods.verbose(block); - // Methods.verbose(origin); - location = origin.clone(); - distance = EarthMethods.getEarthbendableBlocksLength(player, block, direction.clone().multiply(-1), height); - - loadAffectedBlocks(); - - if (distance != 0) { - if (canInstantiate()) { - id = ID; - instances.put(id, this); - if (ID >= Integer.MAX_VALUE) { - ID = Integer.MIN_VALUE; - } - ID++; - time = System.currentTimeMillis() - interval; - } - } - } - - private void loadAffectedBlocks() { - affectedblocks.clear(); - Block thisblock; - for (int i = 0; i <= distance; i++) { - thisblock = block.getWorld().getBlockAt(location.clone().add(direction.clone().multiply(-i))); - affectedblocks.put(thisblock, thisblock); - if (EarthColumn.blockInAllAffectedBlocks(thisblock)) - EarthColumn.revertBlock(thisblock); - } - } - - private boolean blockInAffectedBlocks(Block block) { - if (affectedblocks.containsKey(block)) { - return true; - } - return false; - } - - public static boolean blockInAllAffectedBlocks(Block block) { - for (int ID : instances.keySet()) { - if (instances.get(ID).blockInAffectedBlocks(block)) - return true; - } - return false; - } - - public static void revertBlock(Block block) { - for (int ID : instances.keySet()) { - if (instances.get(ID).blockInAffectedBlocks(block)) { - instances.get(ID).affectedblocks.remove(block); - } - } - } - - private boolean canInstantiate() { - for (Block block : affectedblocks.keySet()) { - if (blockInAllAffectedBlocks(block) || alreadydoneblocks.containsKey(block)) { - return false; - } - } - return true; - } - - public static void progressAll() { - for (int ID : instances.keySet()) { - instances.get(ID).progress(); - } - } - - private boolean progress() { - if (System.currentTimeMillis() - time >= interval) { - time = System.currentTimeMillis(); - if (!moveEarth()) { - instances.remove(id); - // for (Block block : affectedblocks.keySet()) { - // alreadydoneblocks.put(block, block); - // } - return false; - } - } - return true; - } - - private boolean moveEarth() { - Block block = location.getBlock(); - location = location.add(direction); - if (block == null || location == null || distance == 0) { - return false; - } - EarthMethods.moveEarth(player, block, direction, distance); - loadAffectedBlocks(); - - if (location.distance(origin) >= distance) { - return false; - } - - return true; - } - - public static void removeAll() { - for (int id : instances.keySet()) { - instances.remove(id); - } - } -} diff --git a/src/com/projectkorra/projectkorra/earthbending/EarthArmor.java b/src/com/projectkorra/projectkorra/earthbending/EarthArmor.java index a28b0e05..34032c8d 100644 --- a/src/com/projectkorra/projectkorra/earthbending/EarthArmor.java +++ b/src/com/projectkorra/projectkorra/earthbending/EarthArmor.java @@ -1,7 +1,5 @@ package com.projectkorra.projectkorra.earthbending; -import java.util.concurrent.ConcurrentHashMap; - import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; @@ -12,256 +10,257 @@ import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.ClickType; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.EarthAbility; import com.projectkorra.projectkorra.util.TempBlock; import com.projectkorra.projectkorra.util.TempPotionEffect; -public class EarthArmor { +public class EarthArmor extends EarthAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - - private static long interval = 2000; - private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.EarthArmor.Cooldown"); - private static long duration = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.EarthArmor.Duration"); - private static int STRENGTH = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.EarthArmor.Strength"); - - private static boolean auto = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.EarthArmor.AutoSourcing.Enabled"); - private static long autocooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.EarthArmor.AutoSourcing.Cooldown"); - private static int autoSelectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.EarthArmor.AutoSourcing.SelectRange"); - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.EarthArmor.SelectRange"); - - private Player player; - private static Block headblock; - - private Block legsblock; - private Location headblocklocation, legsblocklocation; - private Material headtype, legstype; - private byte headdata, legsdata; - private long time, starttime; - private boolean formed = false; - private boolean complete = false; - private int strength = STRENGTH; - public ItemStack[] oldarmor; + private boolean formed; + private boolean complete; + private byte headData; + private byte legsData; + private int strength; + private int range; + private long time; + private long cooldown; + private long interval; + private long duration; + private Block headBlock; + private Block legsBlock; + private Location headBlockLocation; + private Location legsBlockLocation; + private Material headType; + private Material legsType; + private ItemStack[] oldArmor; @SuppressWarnings("deprecation") public EarthArmor(Player player) { - if (instances.containsKey(player)) { + super(player); + if (CoreAbility.hasAbility(player, EarthArmor.class) || !bPlayer.canBend(this)) { return; } + + this.formed = false; + this.complete = false; + this.interval = 2000; + this.cooldown = getConfig().getLong("Abilities.Earth.EarthArmor.Cooldown"); + this.duration = getConfig().getLong("Abilities.Earth.EarthArmor.Duration"); + this.strength = getConfig().getInt("Abilities.Earth.EarthArmor.Strength"); + this.range = 7; - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); + headBlock = getTargetEarthBlock(range); + if (!GeneralMethods.isRegionProtectedFromBuild(this, headBlock.getLocation()) + && getEarthbendableBlocksLength(headBlock, new Vector(0, -1, 0), 2) >= 2) { + this.legsBlock = headBlock.getRelative(BlockFace.DOWN); + this.headType = headBlock.getType(); + this.legsType = legsBlock.getType(); + this.headData = headBlock.getData(); + this.legsData = legsBlock.getData(); + this.headBlockLocation = headBlock.getLocation(); + this.legsBlockLocation = legsBlock.getLocation(); - if (bPlayer.isOnCooldown("EarthArmor")) - return; + Block oldHeadBlock = headBlock; + Block oldLegsBlock = legsBlock; - this.player = player; - headblock = BlockSource.getEarthSourceBlock(player, autoSelectRange, selectRange, ClickType.LEFT_CLICK, auto, false, true, EarthMethods.canSandbend(player), false); - if (BlockSource.isAuto(headblock)) { - bPlayer.addCooldown("EarthArmor", autocooldown); - } else { - bPlayer.addCooldown("EarthArmor", cooldown); - } - if (EarthMethods.getEarthbendableBlocksLength(player, headblock, new Vector(0, -1, 0), 2) >= 2) { - legsblock = headblock.getRelative(BlockFace.DOWN); - headtype = headblock.getType(); - legstype = legsblock.getType(); - headdata = headblock.getData(); - legsdata = legsblock.getData(); - headblocklocation = headblock.getLocation(); - legsblocklocation = legsblock.getLocation(); - Block oldheadblock, oldlegsblock; - oldheadblock = headblock; - oldlegsblock = legsblock; - if (!moveBlocks()) + if (!moveBlocks()) { return; - if (ProjectKorra.plugin.getConfig().getBoolean("Properties.Earth.RevertEarthbending")) { - EarthMethods.addTempAirBlock(oldheadblock); - EarthMethods.addTempAirBlock(oldlegsblock); - } else { - GeneralMethods.removeBlock(oldheadblock); - GeneralMethods.removeBlock(oldlegsblock); } - instances.put(player, this); + if (isEarthRevertOn()) { + addTempAirBlock(oldHeadBlock); + addTempAirBlock(oldLegsBlock); + } else { + GeneralMethods.removeBlock(oldHeadBlock); + GeneralMethods.removeBlock(oldLegsBlock); + } + start(); } } - - public ItemStack getOriginalArmor(int i) { - return oldarmor[i]; - } - - private boolean moveBlocks() { - if (!player.getWorld().equals(headblock.getWorld())) { - cancel(); - return false; - } - - Location headlocation = player.getEyeLocation(); - Location legslocation = player.getLocation(); - Vector headdirection = headlocation.toVector().subtract(headblocklocation.toVector()).normalize().multiply(.5); - Vector legsdirection = legslocation.toVector().subtract(legsblocklocation.toVector()).normalize().multiply(.5); - - Block newheadblock = headblock; - Block newlegsblock = legsblock; - - if (!headlocation.getBlock().equals(headblock)) { - headblocklocation = headblocklocation.clone().add(headdirection); - newheadblock = headblocklocation.getBlock(); - } - if (!legslocation.getBlock().equals(legsblock)) { - legsblocklocation = legsblocklocation.clone().add(legsdirection); - newlegsblock = legsblocklocation.getBlock(); - } - - if (EarthMethods.isTransparentToEarthbending(player, newheadblock) && !newheadblock.isLiquid()) { - GeneralMethods.breakBlock(newheadblock); - } else if (!EarthMethods.isEarthbendable(player, newheadblock) && !newheadblock.isLiquid() && newheadblock.getType() != Material.AIR) { - cancel(); - return false; - } - - if (EarthMethods.isTransparentToEarthbending(player, newlegsblock) && !newlegsblock.isLiquid()) { - GeneralMethods.breakBlock(newlegsblock); - } else if (!EarthMethods.isEarthbendable(player, newlegsblock) && !newlegsblock.isLiquid() && newlegsblock.getType() != Material.AIR) { - cancel(); - return false; - } - - if (headblock.getLocation().distance(player.getEyeLocation()) > selectRange || legsblock.getLocation().distance(player.getLocation()) > selectRange) { - cancel(); - return false; - } - - if (!newheadblock.equals(headblock)) { - new TempBlock(newheadblock, headtype, headdata); - if (TempBlock.isTempBlock(headblock)) - TempBlock.revertBlock(headblock, Material.AIR); - } - - if (!newlegsblock.equals(legsblock)) { - new TempBlock(newlegsblock, legstype, legsdata); - if (TempBlock.isTempBlock(legsblock)) - TempBlock.revertBlock(legsblock, Material.AIR); - } - - headblock = newheadblock; - legsblock = newlegsblock; - - return true; - } - - private void cancel() { - if (ProjectKorra.plugin.getConfig().getBoolean("Properties.Earth.RevertEarthbending")) { - if (TempBlock.isTempBlock(headblock)) - TempBlock.revertBlock(headblock, Material.AIR); - if (TempBlock.isTempBlock(legsblock)) - TempBlock.revertBlock(legsblock, Material.AIR); - } else { - headblock.breakNaturally(); - legsblock.breakNaturally(); - } - if (instances.containsKey(player)) - instances.remove(player); - } - - private boolean inPosition() { - if (headblock.equals(player.getEyeLocation().getBlock()) && legsblock.equals(player.getLocation().getBlock())) { - return true; - } - return false; - } private void formArmor() { - if (TempBlock.isTempBlock(headblock)) - TempBlock.revertBlock(headblock, Material.AIR); - if (TempBlock.isTempBlock(legsblock)) - TempBlock.revertBlock(legsblock, Material.AIR); + if (TempBlock.isTempBlock(headBlock)) { + TempBlock.revertBlock(headBlock, Material.AIR); + } + if (TempBlock.isTempBlock(legsBlock)) { + TempBlock.revertBlock(legsBlock, Material.AIR); + } - oldarmor = player.getInventory().getArmorContents(); - ItemStack armors[] = { new ItemStack(Material.LEATHER_BOOTS, 1), new ItemStack(Material.LEATHER_LEGGINGS, 1), new ItemStack(Material.LEATHER_CHESTPLATE, 1), new ItemStack(Material.LEATHER_HELMET, 1) }; + this.oldArmor = player.getInventory().getArmorContents(); + ItemStack armors[] = { new ItemStack(Material.LEATHER_BOOTS, 1), + new ItemStack(Material.LEATHER_LEGGINGS, 1), + new ItemStack(Material.LEATHER_CHESTPLATE, 1), + new ItemStack(Material.LEATHER_HELMET, 1) }; player.getInventory().setArmorContents(armors); PotionEffect resistance = new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, (int) duration / 50, strength - 1); new TempPotionEffect(player, resistance); - // player.addPotionEffect(new PotionEffect( - // PotionEffectType.DAMAGE_RESISTANCE, (int) duration / 50, - // strength - 1)); formed = true; - starttime = System.currentTimeMillis(); + } + + private boolean inPosition() { + return headBlock.equals(player.getEyeLocation().getBlock()) && legsBlock.equals(player.getLocation().getBlock()); } - public static void moveArmorAll() { - for (Player player : instances.keySet()) { - moveArmor(player); + private boolean moveBlocks() { + if (!player.getWorld().equals(headBlock.getWorld())) { + remove(); + return false; } - } + + Location headLocation = player.getEyeLocation(); + Location legsLocation = player.getLocation(); + Vector headDirection = headLocation.toVector().subtract(headBlockLocation.toVector()).normalize().multiply(.5); + Vector legsDirection = legsLocation.toVector().subtract(legsBlockLocation.toVector()).normalize().multiply(.5); + Block newHeadBlock = headBlock; + Block newLegsBlock = legsBlock; - public static void moveArmor(Player player) { - if (!instances.containsKey(player)) - return; - EarthArmor eartharmor = instances.get(player); - - if (player.isDead() || !player.isOnline()) { - eartharmor.cancel(); - eartharmor.removeEffect(); - return; + if (!headLocation.getBlock().equals(headBlock)) { + headBlockLocation = headBlockLocation.clone().add(headDirection); + newHeadBlock = headBlockLocation.getBlock(); + } + if (!legsLocation.getBlock().equals(legsBlock)) { + legsBlockLocation = legsBlockLocation.clone().add(legsDirection); + newLegsBlock = legsBlockLocation.getBlock(); } - if (eartharmor.formed) { - if (System.currentTimeMillis() > eartharmor.starttime + duration && !eartharmor.complete) { - eartharmor.complete = true; - eartharmor.removeEffect(); - eartharmor.cancel(); - return; - } - } else if (System.currentTimeMillis() > eartharmor.time + interval) { - if (!eartharmor.moveBlocks()) - return; + if (isTransparent(newHeadBlock) && !newHeadBlock.isLiquid()) { + GeneralMethods.breakBlock(newHeadBlock); + } else if (!isEarthbendable(newHeadBlock) && !newHeadBlock.isLiquid() && newHeadBlock.getType() != Material.AIR) { + remove(); + return false; + } - if (eartharmor.inPosition()) { - eartharmor.formArmor(); + if (isTransparent(newLegsBlock) && !newLegsBlock.isLiquid()) { + GeneralMethods.breakBlock(newLegsBlock); + } else if (!isEarthbendable(newLegsBlock) && !newLegsBlock.isLiquid() && newLegsBlock.getType() != Material.AIR) { + remove(); + return false; + } + + if (headBlock.getLocation().distanceSquared(player.getEyeLocation()) > range * range + || legsBlock.getLocation().distanceSquared(player.getLocation()) > range * range) { + remove(); + return false; + } + + if (!newHeadBlock.equals(headBlock)) { + new TempBlock(newHeadBlock, headType, headData); + if (TempBlock.isTempBlock(headBlock)) { + TempBlock.revertBlock(headBlock, Material.AIR); } } - } - - private void removeEffect() { - player.getInventory().setArmorContents(oldarmor); - // player.removePotionEffect(PotionEffectType.DAMAGE_RESISTANCE); - // instances.remove(player); - } - - public static void removeEffect(Player player) { - if (!instances.containsKey(player)) - return; - instances.get(player).removeEffect(); - } - - public static void removeAll() { - for (Player player : instances.keySet()) { - EarthArmor eartharmor = instances.get(player); - eartharmor.cancel(); - eartharmor.removeEffect(); - } - } - - public static String getDescription() { - return "This ability encases the earthbender in temporary armor. To use, click on a block that is earthbendable. If there is another block under" + " it that is earthbendable, the block will fly to you and grant you temporary armor and damage reduction. This ability has a long cooldown."; - } - - public static boolean canRemoveArmor(Player player) { - if (instances.containsKey(player)) { - EarthArmor eartharmor = instances.get(player); - if (System.currentTimeMillis() < eartharmor.starttime + duration) - return false; + if (!newLegsBlock.equals(legsBlock)) { + new TempBlock(newLegsBlock, legsType, legsData); + if (TempBlock.isTempBlock(legsBlock)) { + TempBlock.revertBlock(legsBlock, Material.AIR); + } } + headBlock = newHeadBlock; + legsBlock = newLegsBlock; return true; } - public Player getPlayer() { - return player; + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { + return; + } + + if (formed) { + if (System.currentTimeMillis() > startTime + duration && !complete) { + complete = true; + bPlayer.addCooldown(this); + remove(); + return; + } + } else if (System.currentTimeMillis() > time + interval) { + if (!moveBlocks()) { + return; + } + if (inPosition()) { + formArmor(); + } + } + } + + @Override + public void remove() { + super.remove(); + if (isEarthRevertOn()) { + if (TempBlock.isTempBlock(headBlock)) { + TempBlock.revertBlock(headBlock, Material.AIR); + } + if (TempBlock.isTempBlock(legsBlock)) { + TempBlock.revertBlock(legsBlock, Material.AIR); + } + } else { + headBlock.breakNaturally(); + legsBlock.breakNaturally(); + } + + if (oldArmor != null) { + player.getInventory().setArmorContents(oldArmor); + } + player.removePotionEffect(PotionEffectType.DAMAGE_RESISTANCE); + } + + @Override + public String getName() { + return "EarthArmor"; + } + + @Override + public Location getLocation() { + return headBlockLocation; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isFormed() { + return formed; + } + + public void setFormed(boolean formed) { + this.formed = formed; + } + + public boolean isComplete() { + return complete; + } + + public void setComplete(boolean complete) { + this.complete = complete; + } + + public byte getHeadData() { + return headData; + } + + public void setHeadData(byte headData) { + this.headData = headData; + } + + public byte getLegsData() { + return legsData; + } + + public void setLegsData(byte legsData) { + this.legsData = legsData; } public int getStrength() { @@ -271,4 +270,97 @@ public class EarthArmor { public void setStrength(int strength) { this.strength = strength; } + + public int getRange() { + return range; + } + + public void setRange(int range) { + this.range = range; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + public Block getHeadBlock() { + return headBlock; + } + + public void setHeadBlock(Block headBlock) { + this.headBlock = headBlock; + } + + public Block getLegsBlock() { + return legsBlock; + } + + public void setLegsBlock(Block legsBlock) { + this.legsBlock = legsBlock; + } + + public Location getHeadBlockLocation() { + return headBlockLocation; + } + + public void setHeadBlockLocation(Location headBlockLocation) { + this.headBlockLocation = headBlockLocation; + } + + public Location getLegsBlockLocation() { + return legsBlockLocation; + } + + public void setLegsBlockLocation(Location legsBlockLocation) { + this.legsBlockLocation = legsBlockLocation; + } + + public Material getHeadType() { + return headType; + } + + public void setHeadType(Material headType) { + this.headType = headType; + } + + public Material getLegsType() { + return legsType; + } + + public void setLegsType(Material legsType) { + this.legsType = legsType; + } + + public ItemStack[] getOldArmor() { + return oldArmor; + } + + public void setOldArmor(ItemStack[] oldArmor) { + this.oldArmor = oldArmor; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/earthbending/EarthBlast.java b/src/com/projectkorra/projectkorra/earthbending/EarthBlast.java index 460cf6b2..f37321b1 100644 --- a/src/com/projectkorra/projectkorra/earthbending/EarthBlast.java +++ b/src/com/projectkorra/projectkorra/earthbending/EarthBlast.java @@ -1,7 +1,16 @@ package com.projectkorra.projectkorra.earthbending; -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.BendingPlayer; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.EarthAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.firebending.Combustion; +import com.projectkorra.projectkorra.firebending.FireBlast; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.ClickType; +import com.projectkorra.projectkorra.waterbending.WaterManipulation; import org.bukkit.Location; import org.bukkit.Material; @@ -11,534 +20,541 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.firebending.Combustion; -import com.projectkorra.projectkorra.firebending.FireBlast; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.ClickType; -import com.projectkorra.projectkorra.waterbending.WaterManipulation; -import com.projectkorra.projectkorra.waterbending.WaterMethods; +import java.util.ArrayList; -public class EarthBlast { +public class EarthBlast extends EarthAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - - private static boolean hitself = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.EarthBlast.CanHitSelf"); - private static double RANGE = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.EarthBlast.Radius"); - private static double DAMAGE = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.EarthBlast.Damage"); - private static double speed = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.EarthBlast.Speed"); - private static final double deflectrange = 3; - - private static boolean revert = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.EarthBlast.Revert"); - private static double PUSH_FACTOR = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.EarthBlast.Push"); - - private static boolean dynamic = ProjectKorra.plugin.getConfig() - .getBoolean("Abilities.Earth.EarthBlast.DynamicSourcing.Enabled"); - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.EarthBlast.SelectRange"); - private static int autoSelectRange = ProjectKorra.plugin.getConfig() - .getInt("Abilities.Earth.EarthBlast.AutoSourcing.SelectRange"); - private static boolean auto = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.EarthBlast.AutoSourcing.Enabled"); - private static long autocooldown = ProjectKorra.plugin.getConfig() - .getLong("Abilities.Earth.EarthBlast.AutoSourcing.Cooldown"); - private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.EarthBlast.Cooldown"); - - private static long interval = (long) (1000. / speed); - - private static int ID = Integer.MIN_VALUE; - - private Player player; - private int id; - private Location location = null; - private Block sourceblock = null; - private Material sourcetype = null; - private boolean progressing = false; - private Location destination = null; - private Location firstdestination = null; - // private Vector firstdirection = null; - // private Vector targetdirection = null; - private boolean falling = false; + private boolean isProgressing; + private boolean isAtDestination; + private boolean isSettingUp; + private boolean canHitSelf; private long time; - private boolean settingup = true; - private double range = RANGE; - private double damage = DAMAGE; - private double pushfactor = PUSH_FACTOR; + private long interval; + private long cooldown; + private double range; + private double damage; + private double speed; + private double pushFactor; + private double prepareRange; + private double deflectRange; + private double collisionRadius; + private Material sourceType; + private Location location; + private Location destination; + private Location firstDestination; + private Block sourceBlock; public EarthBlast(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("EarthBlast")) - return; - this.player = player; + super(player); + + this.isProgressing = false; + this.isAtDestination = false; + this.isSettingUp = true; + this.deflectRange = 3; + this.collisionRadius = 2; + this.cooldown = GeneralMethods.getGlobalCooldown(); + this.canHitSelf = getConfig().getBoolean("Abilities.Earth.EarthBlast.CanHitSelf"); + this.range = getConfig().getDouble("Abilities.Earth.EarthBlast.Range"); + this.damage = getConfig().getDouble("Abilities.Earth.EarthBlast.Damage"); + this.speed = getConfig().getDouble("Abilities.Earth.EarthBlast.Speed"); + this.pushFactor = getConfig().getDouble("Abilities.Earth.EarthBlast.Push"); + this.prepareRange = getConfig().getDouble("Abilities.Earth.EarthBlast.PrepareRange"); + this.time = System.currentTimeMillis(); + this.interval = (long) (1000.0 / speed); + if (prepare()) { - id = ID++; - if (ID >= Integer.MAX_VALUE) - ID = Integer.MIN_VALUE; - instances.put(id, this); + start(); time = System.currentTimeMillis(); } - } - public boolean prepare() { - cancelPrevious(); - Block block = BlockSource.getEarthSourceBlock(player, autoSelectRange, selectRange, ClickType.SHIFT_DOWN, auto, - dynamic, true, EarthMethods.canSandbend(player), EarthMethods.canMetalbend(player)); - block(player); - if (block != null) { - if (block.getLocation().distance(player.getLocation()) > selectRange) { - return false; + private void checkForCollision() { + for (EarthBlast blast : CoreAbility.getAbilities(EarthBlast.class)) { + if (blast.player.equals(player)) { + continue; + } else if (!blast.location.getWorld().equals(player.getWorld())) { + continue; + } else if (!blast.isProgressing) { + continue; + } else if (GeneralMethods.isRegionProtectedFromBuild(this, blast.location)) { + continue; } - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (BlockSource.isAuto(block)) { - bPlayer.addCooldown("EarthBlast", autocooldown); - } else { - bPlayer.addCooldown("EarthBlast", cooldown); + + Location location = player.getEyeLocation(); + Vector vector = location.getDirection(); + Location mloc = blast.location; + if (mloc.distanceSquared(location) <= range * range + && GeneralMethods.getDistanceFromLine(vector, location, blast.location) < deflectRange + && mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) { + blast.remove(); + remove(); + return; } - sourceblock = block; - focusBlock(); - return true; } - return false; } - private static Location getTargetLocation(Player player) { - Entity target = GeneralMethods.getTargetedEntity(player, RANGE, new ArrayList()); + @SuppressWarnings("deprecation") + private void focusBlock() { + if (EarthPassive.isPassiveSand(sourceBlock)) { + EarthPassive.revertSand(sourceBlock); + } + + if (sourceBlock.getType() == Material.SAND) { + sourceType = Material.SAND; + if (sourceBlock.getData() == (byte) 0x1) { + sourceBlock.setType(Material.RED_SANDSTONE); + } else { + sourceBlock.setType(Material.SANDSTONE); + } + } else if (sourceBlock.getType() == Material.STONE) { + sourceBlock.setType(Material.COBBLESTONE); + sourceType = Material.STONE; + } else { + sourceType = sourceBlock.getType(); + sourceBlock.setType(Material.STONE); + } + + location = sourceBlock.getLocation(); + } + + private Location getTargetLocation() { + Entity target = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); Location location; + if (target == null) { - location = GeneralMethods.getTargetedLocation(player, RANGE); + location = GeneralMethods.getTargetedLocation(player, range); } else { location = ((LivingEntity) target).getEyeLocation(); } return location; } - private void cancelPrevious() { - - for (int id : instances.keySet()) { - EarthBlast blast = instances.get(id); - if (blast.player == player && !blast.progressing) - blast.cancel(); - } - - } - - public void cancel() { - unfocusBlock(); - } - - @SuppressWarnings("deprecation") - private void focusBlock() { - if (EarthPassive.isPassiveSand(sourceblock)) - EarthPassive.revertSand(sourceblock); - if (sourceblock.getType() == Material.SAND) { - sourcetype = Material.SAND; - if (sourceblock.getData() == (byte) 0x1) { - sourceblock.setType(Material.RED_SANDSTONE); - } else { - sourceblock.setType(Material.SANDSTONE); - } - } else if (sourceblock.getType() == Material.STONE) { - sourceblock.setType(Material.COBBLESTONE); - sourcetype = Material.STONE; - } else { - sourcetype = sourceblock.getType(); - sourceblock.setType(Material.STONE); - } - location = sourceblock.getLocation(); - } - - @SuppressWarnings("deprecation") - private void unfocusBlock() { - if (destination != null) { - breakBlock(); - return; - } - if (sourceblock.getType() == Material.SAND) { - if (sourceblock.getData() == (byte) 0x1) { - sourceblock.setType(sourcetype); - sourceblock.setData((byte) 0x1); - } else { - sourceblock.setType(sourcetype); - } - } else { - sourceblock.setType(sourcetype); - } - instances.remove(id); - } - - @SuppressWarnings("deprecation") - public void throwEarth() { - if (sourceblock != null) { - if (sourceblock.getWorld().equals(player.getWorld())) { - if (EarthMethods.movedearth.containsKey(sourceblock)) { - if (!revert) - EarthMethods.removeRevertIndex(sourceblock); - } - Entity target = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); - // Methods.verbose(target); - if (target == null) { - destination = player.getTargetBlock(EarthMethods.getTransparentEarthbending(), (int) range).getLocation(); - firstdestination = sourceblock.getLocation().clone(); - firstdestination.setY(destination.getY()); - } else { - destination = ((LivingEntity) target).getEyeLocation(); - firstdestination = sourceblock.getLocation().clone(); - firstdestination.setY(destination.getY()); - destination = GeneralMethods.getPointOnLine(firstdestination, destination, range); - } - if (destination.distance(location) <= 1) { - progressing = false; - destination = null; - } else { - progressing = true; - EarthMethods.playEarthbendingSound(sourceblock.getLocation()); - // direction = getDirection().normalize(); - if (sourcetype != Material.SAND && sourcetype != Material.GRAVEL) { - sourceblock.setType(sourcetype); - } - } - } - - } - } - - public static EarthBlast getBlastFromSource(Block block) { - for (int id : instances.keySet()) { - EarthBlast blast = instances.get(id); - if (blast.sourceblock.equals(block)) - return blast; - } - return null; - } - - public static void progressAll() { - for (int ID : instances.keySet()) { - instances.get(ID).progress(); - } - } - - @SuppressWarnings("deprecation") - private boolean progress() { - if (player.isDead() || !player.isOnline() || !GeneralMethods.canBend(player.getName(), "EarthBlast")) { - breakBlock(); + public boolean prepare() { + Block block = BlockSource.getEarthSourceBlock(player, range, ClickType.SHIFT_DOWN); + if (block == null || !isEarthbendable(block)) { return false; } + + boolean selectedABlockInUse = false; + for (EarthBlast blast : CoreAbility.getAbilities(player, EarthBlast.class)) { + if (!blast.isProgressing) { + blast.remove(); + } else if (blast.isProgressing && block.equals(blast.sourceBlock)) { + selectedABlockInUse = true; + } + } + + if (selectedABlockInUse) { + return false; + } + + checkForCollision(); + if (block.getLocation().distanceSquared(player.getLocation()) > prepareRange * prepareRange) { + return false; + } + sourceBlock = block; + focusBlock(); + return true; + } + + @SuppressWarnings("deprecation") + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { + remove(); + return; + } + if (System.currentTimeMillis() - time >= interval) { time = System.currentTimeMillis(); - if (falling) { - breakBlock(); - return false; + if (isAtDestination) { + remove(); + return; + } else if (!isEarthbendable(sourceBlock) && sourceBlock.getType() != Material.COBBLESTONE) { + remove(); + return; } - if (!progressing && !falling) { - if (GeneralMethods.getBoundAbility(player) == null) { - unfocusBlock(); - return false; - } - - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("EarthBlast")) { - unfocusBlock(); - return false; - } - - if (sourceblock == null) { - instances.remove(id); - return false; - } - if (!player.getWorld().equals(sourceblock.getWorld())) { - unfocusBlock(); - return false; - } - if (sourceblock.getLocation().distance(player.getLocation()) > selectRange) { - unfocusBlock(); - return false; + if (!isProgressing && !isAtDestination) { + if (sourceBlock == null || !bPlayer.getBoundAbilityName().equals(getName())) { + remove(); + return; + } else if (!player.getWorld().equals(sourceBlock.getWorld())) { + remove(); + return; + } else if (sourceBlock.getLocation().distanceSquared(player.getLocation()) > prepareRange * prepareRange) { + remove(); + return; } } - if (falling) { - breakBlock(); - + if (isAtDestination) { + remove(); + return; } else { - if (!progressing) { - return false; + if (!isProgressing) { + return; + } + if (sourceBlock.getY() == firstDestination.getBlockY()) { + isSettingUp = false; } - - if (sourceblock.getY() == firstdestination.getBlockY()) - settingup = false; Vector direction; - if (settingup) { - direction = GeneralMethods.getDirection(location, firstdestination).normalize(); + if (isSettingUp) { + direction = GeneralMethods.getDirection(location, firstDestination).normalize(); } else { direction = GeneralMethods.getDirection(location, destination).normalize(); } location = location.clone().add(direction); - - WaterMethods.removeWaterSpouts(location, player); - AirMethods.removeAirSpouts(location, player); - Block block = location.getBlock(); - if (block.getLocation().equals(sourceblock.getLocation())) { + + WaterAbility.removeWaterSpouts(location, player); + AirAbility.removeAirSpouts(location, player); + + if (block.getLocation().equals(sourceBlock.getLocation())) { location = location.clone().add(direction); block = location.getBlock(); } - if (EarthMethods.isTransparentToEarthbending(player, block) && !block.isLiquid()) { + if (isTransparent(block) && !block.isLiquid()) { GeneralMethods.breakBlock(block); - } else if (!settingup) { - breakBlock(); - return false; + } else if (!isSettingUp) { + remove(); + return; } else { location = location.clone().subtract(direction); direction = GeneralMethods.getDirection(location, destination).normalize(); location = location.clone().add(direction); - WaterMethods.removeWaterSpouts(location, player); - AirMethods.removeAirSpouts(location, player); - double radius = FireBlast.AFFECTING_RADIUS; - Player source = player; - if (EarthBlast.annihilateBlasts(location, radius, source) - || WaterManipulation.annihilateBlasts(location, radius, source) - || FireBlast.annihilateBlasts(location, radius, source)) { - breakBlock(); - return false; + WaterAbility.removeWaterSpouts(location, player); + AirAbility.removeAirSpouts(location, player); + + if (EarthBlast.annihilateBlasts(location, collisionRadius, player) + || WaterManipulation.annihilateBlasts(location, collisionRadius, player) + || FireBlast.annihilateBlasts(location, collisionRadius, player)) { + remove(); + return; } - Combustion.removeAroundPoint(location, radius); + Combustion.removeAroundPoint(location, collisionRadius); Block block2 = location.getBlock(); - if (block2.getLocation().equals(sourceblock.getLocation())) { + if (block2.getLocation().equals(sourceBlock.getLocation())) { location = location.clone().add(direction); block2 = location.getBlock(); } - if (EarthMethods.isTransparentToEarthbending(player, block) && !block.isLiquid()) { + if (isTransparent(block) && !block.isLiquid()) { GeneralMethods.breakBlock(block); } else { - breakBlock(); - return false; + remove(); + return; } } - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, FireBlast.AFFECTING_RADIUS)) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "EarthBlast", entity.getLocation())) + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, collisionRadius)) { + if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) { continue; - if (entity instanceof LivingEntity && (entity.getEntityId() != player.getEntityId() || hitself)) { - - AirMethods.breakBreathbendingHold(entity); - + } + if (entity instanceof LivingEntity && (entity.getEntityId() != player.getEntityId() || canHitSelf)) { + AirAbility.breakBreathbendingHold(entity); + Location location = player.getEyeLocation(); Vector vector = location.getDirection(); - entity.setVelocity(vector.normalize().multiply(pushfactor)); - double damage = this.damage; - if (EarthMethods.isMetal(sourceblock) && EarthMethods.canMetalbend(player)) { - damage = EarthMethods.getMetalAugment(this.damage); + entity.setVelocity(vector.normalize().multiply(pushFactor)); + double damage = this.damage; + + if (isMetal(sourceBlock) && bPlayer.canMetalbend()) { + damage = getMetalAugment(damage); } - GeneralMethods.damageEntity(player, entity, damage, "EarthBlast"); - progressing = false; + GeneralMethods.damageEntity(this, entity, damage); + isProgressing = false; } } - if (!progressing) { - breakBlock(); - return false; + if (!isProgressing) { + remove(); + return; } - if (revert) { - // Methods.addTempEarthBlock(sourceblock, block); - if (sourceblock.getType() == Material.RED_SANDSTONE) { - sourceblock.setType(sourcetype); - if (sourcetype == Material.SAND) - sourceblock.setData((byte) 0x1); - } else { - sourceblock.setType(sourcetype); + if (isEarthRevertOn()) { + sourceBlock.setType(sourceType); + if (sourceBlock.getType() == Material.RED_SANDSTONE && sourceType == Material.SAND) { + sourceBlock.setData((byte) 0x1); } - EarthMethods.moveEarthBlock(sourceblock, block); - if (block.getType() == Material.SAND) + moveEarthBlock(sourceBlock, block); + + if (block.getType() == Material.SAND) { block.setType(Material.SANDSTONE); - if (block.getType() == Material.GRAVEL) + } + if (block.getType() == Material.GRAVEL) { block.setType(Material.STONE); + } } else { - block.setType(sourceblock.getType()); - sourceblock.setType(Material.AIR); + block.setType(sourceBlock.getType()); + sourceBlock.setType(Material.AIR); } - sourceblock = block; + sourceBlock = block; - if (location.distance(destination) < 1) { - if (sourcetype == Material.SAND || sourcetype == Material.GRAVEL) { - progressing = false; - if (sourceblock.getType() == Material.RED_SANDSTONE) { - sourcetype = Material.SAND; - sourceblock.setType(sourcetype); - sourceblock.setData((byte) 0x1); - } else { - sourceblock.setType(sourcetype); + if (location.distanceSquared(destination) < 1) { + if (sourceType == Material.SAND || sourceType == Material.GRAVEL) { + isProgressing = false; + if (sourceBlock.getType() == Material.RED_SANDSTONE) { + sourceType = Material.SAND; + sourceBlock.setType(sourceType); + sourceBlock.setData((byte) 0x1); + } + else { + sourceBlock.setType(sourceType); } } - falling = true; - progressing = false; + isAtDestination = true; + isProgressing = false; } - - return true; + return; } } - - return false; - - } - - private void breakBlock() { - sourceblock.setType(sourcetype); - if (revert) { - EarthMethods.addTempAirBlock(sourceblock); - } else { - sourceblock.breakNaturally(); - } - instances.remove(id); - } - - public static void throwEarth(Player player) { - ArrayList ignore = new ArrayList(); - - for (int id : instances.keySet()) { - EarthBlast blast = instances.get(id); - if (blast.player == player && !blast.progressing) { - blast.throwEarth(); - ignore.add(blast); - } - } - redirectTargettedBlasts(player, ignore); - } - - public static void removeAll() { - for (int id : instances.keySet()) { - instances.get(id).breakBlock(); - } - } - - private static void redirectTargettedBlasts(Player player, ArrayList ignore) { - for (int id : instances.keySet()) { - EarthBlast blast = instances.get(id); - - if (!blast.progressing || ignore.contains(blast)) - continue; - - if (!blast.location.getWorld().equals(player.getWorld())) - continue; - - if (GeneralMethods.isRegionProtectedFromBuild(player, "EarthBlast", blast.location)) - continue; - - if (blast.player.equals(player)) - blast.redirect(player, getTargetLocation(player)); - - Location location = player.getEyeLocation(); - Vector vector = location.getDirection(); - Location mloc = blast.location; - if (mloc.distance(location) <= RANGE - && GeneralMethods.getDistanceFromLine(vector, location, blast.location) < deflectrange - && mloc.distance(location.clone().add(vector)) < mloc - .distance(location.clone().add(vector.clone().multiply(-1)))) { - blast.redirect(player, getTargetLocation(player)); - } - - } } private void redirect(Player player, Location targetlocation) { - if (progressing) { - if (location.distance(player.getLocation()) <= range) { - // direction = Methods.getDirection(location, targetlocation) - // .normalize(); - settingup = false; + if (isProgressing) { + if (location.distanceSquared(player.getLocation()) <= range * range) { + isSettingUp = false; destination = targetlocation; } } } - private static void block(Player player) { - for (int id : instances.keySet()) { - EarthBlast blast = instances.get(id); + @SuppressWarnings("deprecation") + @Override + public void remove() { + super.remove(); + if(destination != null && sourceBlock != null) { + sourceBlock.setType(Material.AIR); + } else if (sourceBlock != null) { + if (sourceBlock.getType() == Material.SAND) { + if (sourceBlock.getData() == (byte) 0x1) { + sourceBlock.setType(sourceType); + sourceBlock.setData((byte) 0x1); + } else { + sourceBlock.setType(sourceType); + } + } else { + sourceBlock.setType(sourceType); + } + } + } - if (blast.player.equals(player)) - continue; + public void throwEarth() { + if (sourceBlock == null || !sourceBlock.getWorld().equals(player.getWorld())) { + return; + } + + if (getMovedEarth().containsKey(sourceBlock)) { + if (!isEarthRevertOn()) { + removeRevertIndex(sourceBlock); + } + } + + Entity target = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); + if (target == null) { + destination = getTargetEarthBlock((int) range).getLocation(); + firstDestination = sourceBlock.getLocation().clone(); + firstDestination.setY(destination.getY()); + } else { + destination = ((LivingEntity) target).getEyeLocation(); + firstDestination = sourceBlock.getLocation().clone(); + firstDestination.setY(destination.getY()); + destination = GeneralMethods.getPointOnLine(firstDestination, destination, range); + } + + if (destination.distanceSquared(location) <= 1) { + isProgressing = false; + destination = null; + } else { + isProgressing = true; + playEarthbendingSound(sourceBlock.getLocation()); - if (!blast.location.getWorld().equals(player.getWorld())) - continue; + Material currentType = sourceBlock.getType(); + sourceBlock.setType(sourceType); + if (isEarthRevertOn()) { + addTempAirBlock(sourceBlock); + } else { + sourceBlock.breakNaturally(); + } + sourceBlock.setType(currentType); + } + } + + public static boolean annihilateBlasts(Location location, double radius, Player source) { + boolean broke = false; + for (EarthBlast blast : CoreAbility.getAbilities(EarthBlast.class)) { + if (blast.location.getWorld().equals(location.getWorld()) && !source.equals(blast.player)) { + if (blast.location.distanceSquared(location) <= radius * radius) { + blast.remove(); + broke = true; + } + } + } + return broke; + } - if (!blast.progressing) - continue; + public static ArrayList getAroundPoint(Location location, double radius) { + ArrayList list = new ArrayList(); + for (EarthBlast blast : CoreAbility.getAbilities(EarthBlast.class)) { + if (blast.location.getWorld().equals(location.getWorld())) { + if (blast.location.distanceSquared(location) <= radius * radius) { + list.add(blast); + } + } + } + return list; + } - if (GeneralMethods.isRegionProtectedFromBuild(player, "EarthBlast", blast.location)) + public static EarthBlast getBlastFromSource(Block block) { + for (EarthBlast blast : CoreAbility.getAbilities(EarthBlast.class)) { + if (blast.sourceBlock.equals(block)) { + return blast; + } + } + return null; + } + + private static void redirectTargettedBlasts(Player player, ArrayList ignore) { + for (EarthBlast blast : CoreAbility.getAbilities(EarthBlast.class)) { + if (!blast.isProgressing || ignore.contains(blast)) { continue; + } else if (!blast.location.getWorld().equals(player.getWorld())) { + continue; + } else if (GeneralMethods.isRegionProtectedFromBuild(blast, blast.location)) { + continue; + } else if (blast.player.equals(player)) { + blast.redirect(player, blast.getTargetLocation()); + } Location location = player.getEyeLocation(); Vector vector = location.getDirection(); Location mloc = blast.location; - if (mloc.distance(location) <= RANGE - && GeneralMethods.getDistanceFromLine(vector, location, blast.location) < deflectrange - && mloc.distance(location.clone().add(vector)) < mloc - .distance(location.clone().add(vector.clone().multiply(-1)))) { - blast.breakBlock(); + + if (mloc.distanceSquared(location) <= blast.range * blast.range + && GeneralMethods.getDistanceFromLine(vector, location, blast.location) < blast.deflectRange + && mloc.distanceSquared(location.clone().add(vector)) + < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) { + blast.redirect(player, blast.getTargetLocation()); } } } - public static String getDescription() { - return "To use, place your cursor over an earthbendable object (dirt, rock, ores, etc) " - + "and tap sneak (default: shift). The object will temporarily turn to stone, " - + "indicating that you have it focused as the source for your ability. " - + "After you have selected an origin (you no longer need to be sneaking), " - + "simply left-click in any direction and you will see your object launch " - + "off in that direction, smashing into any creature in its path. If you look " - + "towards a creature when you use this ability, it will target that creature. " - + "A collision from Earth Blast both knocks the target back and deals some damage. " - + "You cannot have multiple of these abilities flying at the same time."; - } - public static void removeAroundPoint(Location location, double radius) { - for (int id : instances.keySet()) { - EarthBlast blast = instances.get(id); - if (blast.location.getWorld().equals(location.getWorld())) - if (blast.location.distance(location) <= radius) - blast.breakBlock(); - } - } - - public static ArrayList getAroundPoint(Location location, double radius) { - ArrayList list = new ArrayList(); - for (int id : instances.keySet()) { - EarthBlast blast = instances.get(id); - if (blast.location.getWorld().equals(location.getWorld())) - if (blast.location.distance(location) <= radius) - list.add(blast); - } - return list; - } - - public static boolean annihilateBlasts(Location location, double radius, Player source) { - boolean broke = false; - for (int id : instances.keySet()) { - EarthBlast blast = instances.get(id); - if (blast.location.getWorld().equals(location.getWorld()) && !source.equals(blast.player)) - if (blast.location.distance(location) <= radius) { - blast.breakBlock(); - broke = true; + for (EarthBlast blast : CoreAbility.getAbilities(EarthBlast.class)) { + if (blast.location.getWorld().equals(location.getWorld())) { + if (blast.location.distanceSquared(location) <= radius * radius) { + blast.remove(); } + } } - return broke; } - public Player getPlayer() { - return player; + public static void throwEarth(Player player) { + ArrayList ignore = new ArrayList(); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + EarthBlast earthBlast = null; + + if (bPlayer == null) { + return; + } + + for (EarthBlast blast : CoreAbility.getAbilities(player, EarthBlast.class)) { + if (!blast.isProgressing && bPlayer.canBend(blast)) { + blast.throwEarth(); + ignore.add(blast); + earthBlast = blast; + } + } + + if (earthBlast != null) { + bPlayer.addCooldown(earthBlast); + } + redirectTargettedBlasts(player, ignore); + } + + @Override + public String getName() { + return "EarthBlast"; + } + + @Override + public Location getLocation() { + return location; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isProgressing() { + return isProgressing; + } + + public void setProgressing(boolean isProgressing) { + this.isProgressing = isProgressing; + } + + public boolean isAtDestination() { + return isAtDestination; + } + + public void setAtDestination(boolean isAtDestination) { + this.isAtDestination = isAtDestination; + } + + public boolean isSettingUp() { + return isSettingUp; + } + + public void setSettingUp(boolean isSettingUp) { + this.isSettingUp = isSettingUp; + } + + public boolean isCanHitSelf() { + return canHitSelf; + } + + public void setCanHitSelf(boolean canHitSelf) { + this.canHitSelf = canHitSelf; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; } public double getRange() { @@ -557,12 +573,84 @@ public class EarthBlast { this.damage = damage; } - public double getPushfactor() { - return pushfactor; + public double getSpeed() { + return speed; } - public void setPushfactor(double pushfactor) { - this.pushfactor = pushfactor; + public void setSpeed(double speed) { + this.speed = speed; + } + + public double getPushFactor() { + return pushFactor; + } + + public void setPushFactor(double pushFactor) { + this.pushFactor = pushFactor; + } + + public double getPrepareRange() { + return prepareRange; + } + + public void setPrepareRange(double prepareRange) { + this.prepareRange = prepareRange; + } + + public double getDeflectRange() { + return deflectRange; + } + + public void setDeflectRange(double deflectRange) { + this.deflectRange = deflectRange; + } + + public double getCollisionRadius() { + return collisionRadius; + } + + public void setCollisionRadius(double collisionRadius) { + this.collisionRadius = collisionRadius; + } + + public Material getSourcetype() { + return sourceType; + } + + public void setSourcetype(Material sourcetype) { + this.sourceType = sourcetype; + } + + public Location getDestination() { + return destination; + } + + public void setDestination(Location destination) { + this.destination = destination; + } + + public Location getFirstDestination() { + return firstDestination; + } + + public void setFirstDestination(Location firstDestination) { + this.firstDestination = firstDestination; + } + + public Block getSourceBlock() { + return sourceBlock; + } + + public void setSourceBlock(Block sourceBlock) { + this.sourceBlock = sourceBlock; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; } } \ No newline at end of file diff --git a/src/com/projectkorra/projectkorra/earthbending/EarthColumn.java b/src/com/projectkorra/projectkorra/earthbending/EarthColumn.java deleted file mode 100644 index ba76e08d..00000000 --- a/src/com/projectkorra/projectkorra/earthbending/EarthColumn.java +++ /dev/null @@ -1,210 +0,0 @@ -package com.projectkorra.projectkorra.earthbending; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.ClickType; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -import java.util.concurrent.ConcurrentHashMap; - -public class EarthColumn { - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - - public static final int standardheight = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.RaiseEarth.Column.Height"); - private static int ID = Integer.MIN_VALUE; - private static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.RaiseEarth.DynamicSourcing.Enabled"); - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.RaiseEarth.SelectRange"); - - private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.RaiseEarth.Cooldown"); - private static double speed = 8; - private static final Vector direction = new Vector(0, 1, 0); - private static long interval = (long) (1000. / speed); - - private Location origin; - private Location location; - private Block block; - private int distance; - private Player player; - private int id; - private long time; - private int height = standardheight; - private ConcurrentHashMap affectedblocks = new ConcurrentHashMap(); - - public EarthColumn(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (bPlayer.isOnCooldown("RaiseEarth")) - return; - - try { - if (AvatarState.isAvatarState(player)) { - height = (int) (2. / 5. * (double) AvatarState.getValue(height)); - } - block = BlockSource.getEarthSourceBlock(player, selectRange, selectRange, ClickType.LEFT_CLICK, false, dynamic, true, EarthMethods.canSandbend(player), EarthMethods.canMetalbend(player)); - if (block == null) - return; - origin = block.getLocation(); - location = origin.clone(); - distance = EarthMethods.getEarthbendableBlocksLength(player, block, direction.clone().multiply(-1), height); - } - catch (IllegalStateException e) { - return; - } - - this.player = player; - - loadAffectedBlocks(); - - if (distance != 0) { - if (canInstantiate()) { - id = ID; - instances.put(id, this); - bPlayer.addCooldown("RaiseEarth", cooldown); - if (ID >= Integer.MAX_VALUE) { - ID = Integer.MIN_VALUE; - } - ID++; - time = System.currentTimeMillis() - interval; - } - } - } - - public EarthColumn(Player player, Location origin) { - this.origin = origin; - location = origin.clone(); - block = location.getBlock(); - this.player = player; - distance = EarthMethods.getEarthbendableBlocksLength(player, block, direction.clone().multiply(-1), height); - - loadAffectedBlocks(); - - if (distance != 0) { - if (canInstantiate()) { - id = ID; - instances.put(id, this); - if (ID >= Integer.MAX_VALUE) { - ID = Integer.MIN_VALUE; - } - ID++; - time = System.currentTimeMillis() - interval; - } - } - } - - public EarthColumn(Player player, Location origin, int height) { - this.height = height; - this.origin = origin; - location = origin.clone(); - block = location.getBlock(); - this.player = player; - distance = EarthMethods.getEarthbendableBlocksLength(player, block, direction.clone().multiply(-1), height); - - loadAffectedBlocks(); - - if (distance != 0) { - if (canInstantiate()) { - id = ID; - instances.put(id, this); - if (ID >= Integer.MAX_VALUE) { - ID = Integer.MIN_VALUE; - } - ID++; - time = System.currentTimeMillis() - interval; - } - } - } - - private void loadAffectedBlocks() { - affectedblocks.clear(); - Block thisblock; - for (int i = 0; i <= distance; i++) { - thisblock = block.getWorld().getBlockAt(location.clone().add(direction.clone().multiply(-i))); - affectedblocks.put(thisblock, thisblock); - if (CompactColumn.blockInAllAffectedBlocks(thisblock)) - CompactColumn.revertBlock(thisblock); - } - } - - private boolean blockInAffectedBlocks(Block block) { - if (affectedblocks.containsKey(block)) { - return true; - } - return false; - } - - public static boolean blockInAllAffectedBlocks(Block block) { - for (int ID : instances.keySet()) { - if (instances.get(ID).blockInAffectedBlocks(block)) - return true; - } - return false; - } - - public static void revertBlock(Block block) { - for (int ID : instances.keySet()) { - if (instances.get(ID).blockInAffectedBlocks(block)) { - instances.get(ID).affectedblocks.remove(block); - } - } - } - - private boolean canInstantiate() { - for (Block block : affectedblocks.keySet()) { - if (blockInAllAffectedBlocks(block) || block.getType()==Material.AIR) { - return false; - } - } - return true; - } - - public static void progressAll() { - for (int ID : instances.keySet()) { - instances.get(ID).progress(); - } - } - - private boolean progress() { - if (System.currentTimeMillis() - time >= interval) { - time = System.currentTimeMillis(); - if (!moveEarth()) { - instances.remove(id); - - return false; - } - } - return true; - } - - private boolean moveEarth() { - Block block = location.getBlock(); - location = location.add(direction); - EarthMethods.moveEarth(player, block, direction, distance); - loadAffectedBlocks(); - - if (location.distance(origin) >= distance) { - return false; - } - - return true; - } - - public static void removeAll() { - for (int id : instances.keySet()) { - instances.remove(id); - } - } - - public static String getDescription() { - return "To use, simply left-click on an earthbendable block. " + "A column of earth will shoot upwards from that location. " + "Anything in the way of the column will be brought up with it, " + "leaving talented benders the ability to trap brainless entities up there. " + "Additionally, simply sneak (default shift) looking at an earthbendable block. " + "A wall of earth will shoot upwards from that location. " + "Anything in the way of the wall will be brought up with it. "; - } - -} diff --git a/src/com/projectkorra/projectkorra/earthbending/EarthGrab.java b/src/com/projectkorra/projectkorra/earthbending/EarthGrab.java index 4a114bef..21eba78e 100644 --- a/src/com/projectkorra/projectkorra/earthbending/EarthGrab.java +++ b/src/com/projectkorra/projectkorra/earthbending/EarthGrab.java @@ -1,8 +1,7 @@ package com.projectkorra.projectkorra.earthbending; -import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.EarthAbility; import org.bukkit.Location; import org.bukkit.block.Block; @@ -13,62 +12,88 @@ import org.bukkit.util.Vector; import java.util.ArrayList; -public class EarthGrab { +public class EarthGrab extends EarthAbility { + + private long cooldown; + private double lowestDistance; + private double range; + private double height; + private Location origin; + private Vector direction; + private Entity closestEntity; - private static double range = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.EarthGrab.Range"); - private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.EarthGrab.Cooldown"); - - public EarthGrab(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (bPlayer.isOnCooldown("EarthGrab")) + public EarthGrab(Player player, boolean isOtherEntity) { + super(player); + + this.range = getConfig().getDouble("Abilities.Earth.EarthGrab.Range"); + this.height = 6; + this.cooldown = GeneralMethods.getGlobalCooldown(); + this.origin = player.getEyeLocation(); + this.direction = origin.getDirection(); + this.lowestDistance = range + 1; + this.closestEntity = null; + + if (!bPlayer.canBend(this)) { return; - - Location origin = player.getEyeLocation(); - Vector direction = origin.getDirection(); - double lowestdistance = range + 1; - Entity closestentity = null; + } + + start(); + if (isOtherEntity) { + earthGrabOtherEntity(); + } else { + earthGrabSelf(); + } + remove(); + } + + public void earthGrabOtherEntity() { for (Entity entity : GeneralMethods.getEntitiesAroundPoint(origin, range)) { if (GeneralMethods.getDistanceFromLine(direction, origin, entity.getLocation()) <= 3 - && (entity instanceof LivingEntity) && (entity.getEntityId() != player.getEntityId())) { + && (entity instanceof LivingEntity) + && (entity.getEntityId() != player.getEntityId())) { double distance = origin.distance(entity.getLocation()); - if (distance < lowestdistance) { - closestentity = entity; - lowestdistance = distance; + if (distance < lowestDistance) { + closestEntity = entity; + lowestDistance = distance; } } } - if (closestentity != null) { - // Methods.verbose("grabbing"); + if (closestEntity != null) { ArrayList blocks = new ArrayList(); - Location location = closestentity.getLocation(); + Location location = closestEntity.getLocation(); Location loc1 = location.clone(); Location loc2 = location.clone(); - Location testloc, testloc2; + Location testLoc, testloc2; double factor = 3; double factor2 = 4; int height1 = 3; int height2 = 2; + for (double angle = 0; angle <= 360; angle += 20) { - testloc = loc1.clone().add(factor * Math.cos(Math.toRadians(angle)), 1, factor * Math.sin(Math.toRadians(angle))); - testloc2 = loc2.clone().add(factor2 * Math.cos(Math.toRadians(angle)), 1, + testLoc = loc1.clone().add( + factor * Math.cos(Math.toRadians(angle)), 1, + factor * Math.sin(Math.toRadians(angle))); + testloc2 = loc2.clone().add( + factor2 * Math.cos(Math.toRadians(angle)), 1, factor2 * Math.sin(Math.toRadians(angle))); - for (int y = 0; y < EarthColumn.standardheight - height1; y++) { - testloc = testloc.clone().add(0, -1, 0); - if (EarthMethods.isEarthbendable(player, testloc.getBlock())) { - if (!blocks.contains(testloc.getBlock())) { - new EarthColumn(player, testloc, height1 + y - 1); + + for (int y = 0; y < height - height1; y++) { + testLoc = testLoc.clone().add(0, -1, 0); + if (isEarthbendable(testLoc.getBlock())) { + if (!blocks.contains(testLoc.getBlock())) { + new RaiseEarth(player, testLoc, height1 + y - 1); } - blocks.add(testloc.getBlock()); + blocks.add(testLoc.getBlock()); break; } } - for (int y = 0; y < EarthColumn.standardheight - height2; y++) { + + for (int y = 0; y < height - height2; y++) { testloc2 = testloc2.clone().add(0, -1, 0); - if (EarthMethods.isEarthbendable(player, testloc2.getBlock())) { + if (isEarthbendable(testloc2.getBlock())) { if (!blocks.contains(testloc2.getBlock())) { - new EarthColumn(player, testloc2, height2 + y - 1); + new RaiseEarth(player, testloc2, height2 + y - 1); } blocks.add(testloc2.getBlock()); break; @@ -76,58 +101,141 @@ public class EarthGrab { } } - if (!blocks.isEmpty()) - bPlayer.addCooldown("EarthGrab", cooldown); + if (!blocks.isEmpty()) { + bPlayer.addCooldown(this); + } } } - public static void EarthGrabSelf(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (bPlayer.isOnCooldown("EarthGrab")) - return; - - Entity closestentity = player; - - if (closestentity != null) { - // Methods.verbose("grabbing"); + public void earthGrabSelf() { + closestEntity = player; + if (closestEntity != null) { ArrayList blocks = new ArrayList(); - Location location = closestentity.getLocation(); + Location location = closestEntity.getLocation(); Location loc1 = location.clone(); Location loc2 = location.clone(); - Location testloc, testloc2; + Location testLoc, testLoc2; double factor = 3; double factor2 = 4; int height1 = 3; int height2 = 2; + for (double angle = 0; angle <= 360; angle += 20) { - testloc = loc1.clone().add(factor * Math.cos(Math.toRadians(angle)), 1, factor * Math.sin(Math.toRadians(angle))); - testloc2 = loc2.clone().add(factor2 * Math.cos(Math.toRadians(angle)), 1, + testLoc = loc1.clone().add( + factor * Math.cos(Math.toRadians(angle)), 1, + factor * Math.sin(Math.toRadians(angle))); + testLoc2 = loc2.clone().add( + factor2 * Math.cos(Math.toRadians(angle)), 1, factor2 * Math.sin(Math.toRadians(angle))); - for (int y = 0; y < EarthColumn.standardheight - height1; y++) { - testloc = testloc.clone().add(0, -1, 0); - if (EarthMethods.isEarthbendable(player, testloc.getBlock())) { - if (!blocks.contains(testloc.getBlock())) { - new EarthColumn(player, testloc, height1 + y - 1); + + for (int y = 0; y < height - height1; y++) { + testLoc = testLoc.clone().add(0, -1, 0); + if (isEarthbendable(testLoc.getBlock())) { + if (!blocks.contains(testLoc.getBlock())) { + new RaiseEarth(player, testLoc, height1 + y - 1); } - blocks.add(testloc.getBlock()); + blocks.add(testLoc.getBlock()); break; } } - for (int y = 0; y < EarthColumn.standardheight - height2; y++) { - testloc2 = testloc2.clone().add(0, -1, 0); - if (EarthMethods.isEarthbendable(player, testloc2.getBlock())) { - if (!blocks.contains(testloc2.getBlock())) { - new EarthColumn(player, testloc2, height2 + y - 1); + + for (int y = 0; y < height - height2; y++) { + testLoc2 = testLoc2.clone().add(0, -1, 0); + if (isEarthbendable(testLoc2.getBlock())) { + if (!blocks.contains(testLoc2.getBlock())) { + new RaiseEarth(player, testLoc2, height2 + y - 1); } - blocks.add(testloc2.getBlock()); + blocks.add(testLoc2.getBlock()); break; } } } - if (!blocks.isEmpty()) - bPlayer.addCooldown("EarthGrab", GeneralMethods.getGlobalCooldown()); + if (!blocks.isEmpty()) { + bPlayer.addCooldown(this); + } } } + + @Override + public String getName() { + return "EarthGrab"; + } + + @Override + public void progress() { + } + + @Override + public Location getLocation() { + return origin; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public double getLowestDistance() { + return lowestDistance; + } + + public void setLowestDistance(double lowestDistance) { + this.lowestDistance = lowestDistance; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getHeight() { + return height; + } + + public void setHeight(double height) { + this.height = height; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public Entity getClosestEntity() { + return closestEntity; + } + + public void setClosestEntity(Entity closestEntity) { + this.closestEntity = closestEntity; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } \ No newline at end of file diff --git a/src/com/projectkorra/projectkorra/earthbending/EarthMethods.java b/src/com/projectkorra/projectkorra/earthbending/EarthMethods.java deleted file mode 100644 index f95fe10e..00000000 --- a/src/com/projectkorra/projectkorra/earthbending/EarthMethods.java +++ /dev/null @@ -1,752 +0,0 @@ -package com.projectkorra.projectkorra.earthbending; - -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AbilityModuleManager; -import com.projectkorra.projectkorra.configuration.ConfigManager; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.Information; -import com.projectkorra.projectkorra.util.ParticleEffect; -import com.projectkorra.projectkorra.util.TempBlock; - -import org.bukkit.ChatColor; -import org.bukkit.Effect; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Entity; -import org.bukkit.entity.FallingBlock; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -public class EarthMethods { - - static ProjectKorra plugin; - private static FileConfiguration config = ConfigManager.defaultConfig.get(); - - public static ConcurrentHashMap movedearth = new ConcurrentHashMap(); - public static ConcurrentHashMap tempair = new ConcurrentHashMap(); - public static HashSet tempNoEarthbending = new HashSet(); - public static Integer[] transparentToEarthbending = { 0, 6, 8, 9, 10, 11, 30, 31, 32, 37, 38, 39, 40, 50, 51, 59, 78, 83, 106, - 175 }; - private static final ItemStack pickaxe = new ItemStack(Material.DIAMOND_PICKAXE); - public static ArrayList tempnophysics = new ArrayList(); - - public EarthMethods(ProjectKorra plugin) { - EarthMethods.plugin = plugin; - } - - /** - * Creates a temporary air block. - * - * @param block The block to use as a base - */ - public static void addTempAirBlock(Block block) { - if (movedearth.containsKey(block)) { - Information info = movedearth.get(block); - block.setType(Material.AIR); - info.setTime(System.currentTimeMillis()); - movedearth.remove(block); - tempair.put(info.getID(), info); - } else { - Information info = new Information(); - info.setBlock(block); - info.setState(block.getState()); - info.setTime(System.currentTimeMillis()); - block.setType(Material.AIR); - tempair.put(info.getID(), info); - } - - } - - /** - * Checks to see if a player can SandBend. - * - * @param player The player to check - * @return true If player has permission node "bending.earth.sandbending" - */ - public static boolean canSandbend(Player player) { - if (player.hasPermission("bending.earth.sandbending")) - return true; - return false; - } - - /** - * Checks to see if a player can MetalBend. - * - * @param player The player to check - * @return true If player has permission node "bending.earth.metalbending" - */ - public static boolean canMetalbend(Player player) { - if (player.hasPermission("bending.earth.metalbending")) - return true; - return false; - } - - /** - * Checks to see if a player can LavaBend. - * - * @param player The player to check - * @return true If player has permission node "bending.earth.lavabending" - */ - public static boolean canLavabend(Player player) { - return player.hasPermission("bending.earth.lavabending"); - } - - public static void displaySandParticle(Location loc, float xOffset, float yOffset, float zOffset, float amount, float speed, - boolean red) { - if (amount <= 0) - return; - - for (int x = 0; x < amount; x++) { - if (!red) { - ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.SAND, (byte) 0), - new Vector(((Math.random() - 0.5) * xOffset), ((Math.random() - 0.5) * yOffset), - ((Math.random() - 0.5) * zOffset)), - speed, loc, 257.0D); - ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.SANDSTONE, (byte) 0), - new Vector(((Math.random() - 0.5) * xOffset), ((Math.random() - 0.5) * yOffset), - ((Math.random() - 0.5) * zOffset)), - speed, loc, 257.0D); - } else if (red) { - ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.SAND, (byte) 1), - new Vector(((Math.random() - 0.5) * xOffset), ((Math.random() - 0.5) * yOffset), - ((Math.random() - 0.5) * zOffset)), - speed, loc, 257.0D); - ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.RED_SANDSTONE, (byte) 0), - new Vector(((Math.random() - 0.5) * xOffset), ((Math.random() - 0.5) * yOffset), - ((Math.random() - 0.5) * zOffset)), - speed, loc, 257.0D); - } - - } - } - - /** - * Gets the EarthColor from the config. - * - * @return Config specified ChatColor - */ - public static ChatColor getEarthColor() { - return ChatColor.valueOf(config.getString("Properties.Chat.Colors.Earth")); - } - - /** - * Gets the EarthSubColor from the config. - * - * @return Config specified ChatColor - */ - public static ChatColor getEarthSubColor() { - return ChatColor.valueOf(config.getString("Properties.Chat.Colors.EarthSub")); - } - - public static int getEarthbendableBlocksLength(Player player, Block block, Vector direction, int maxlength) { - Location location = block.getLocation(); - direction = direction.normalize(); - double j; - for (int i = 0; i <= maxlength; i++) { - j = (double) i; - if (!isEarthbendable(player, location.clone().add(direction.clone().multiply(j)).getBlock())) { - return i; - } - } - return maxlength; - } - - /** - * Finds a valid Earth source for a Player. To use dynamic source selection, use - * BlockSource.getEarthSourceBlock() instead of this method. Dynamic source selection saves the - * user's previous source for future use. - * {@link BlockSource#getEarthSourceBlock(Player, double, com.projectkorra.projectkorra.util.ClickType)} - * - * @param player the player that is attempting to Earthbend. - * @param range the maximum block selection range. - * @return a valid Earth source block, or null if one could not be found. - */ - @SuppressWarnings("deprecation") - public static Block getEarthSourceBlock(Player player, int range, boolean earth, boolean sand, boolean metal) { - Block testblock = player.getTargetBlock(getTransparentEarthbending(), range); - if (isEarthbendable(testblock) && earth == true) - return testblock; - if (isSand(testblock) && sand == true) - return testblock; - if (isMetal(testblock) && metal == true) - return testblock; - Location location = player.getEyeLocation(); - Vector vector = location.getDirection().clone().normalize(); - for (double i = 0; i <= range; i++) { - Block block = location.clone().add(vector.clone().multiply(i)).getBlock(); - if (GeneralMethods.isRegionProtectedFromBuild(player, "RaiseEarth", location)) - continue; - if (isEarthbendable(player, block)) { - return block; - } - } - return null; - } - - /** - * Returns a random block within a radius of a location. - * - * @param location - * @param radius - * @return random block - */ - public static Block getRandomEarthBlock(Player player, Location location, int radius, boolean earth, boolean sand, - boolean metal) { - List checked = new ArrayList(); - List blocks = GeneralMethods.getBlocksAroundPoint(location, radius); - for (int i = 0; i < blocks.size(); i++) { - int index = GeneralMethods.rand.nextInt(blocks.size()); - while (checked.contains(index)) { - index = GeneralMethods.rand.nextInt(blocks.size()); - } - checked.add(index); - Block block = blocks.get(index); - if (block == null || block.getLocation().distance(location) < 2) { - continue; - } - if (isTransparentToEarthbending(player, block.getRelative(BlockFace.UP))) { - if (isEarthbendable(block) && earth == true) { - BlockSource.randomBlocks.add(block); - return block; - } - if (isSand(block) && sand == true) { - BlockSource.randomBlocks.add(block); - return block; - } - - if (isMetal(block) && metal == true) { - BlockSource.randomBlocks.add(block); - return block; - } - } - } - return null; - } - - /** - * Attempts to find the closest earth block near a given location. - * - * @param loc the initial location to search from. - * @param radius the maximum radius to search for the earth block. - * @param maxVertical the maximum block height difference between the starting location and the - * earth bendable block. - * @return an earth bendable block, or null. - */ - public static Block getNearbyEarthBlock(Location loc, double radius, int maxVertical, boolean earth, boolean sand, - boolean metal) { - if (loc == null) { - return null; - } - int rotation = 30; - for (int i = 0; i < radius; i++) { - Vector tracer = new Vector(i, 0, 0); - for (int deg = 0; deg < 360; deg += rotation) { - Location searchLoc = loc.clone().add(tracer); - Block block = GeneralMethods.getTopBlock(searchLoc, maxVertical); - - if (block != null) { - if (isEarthbendable(block) && earth == true) - return block; - if (isSand(block) && sand == true) - return block; - if (isMetal(block) && metal == true) - return block; - } - tracer = GeneralMethods.rotateXZ(tracer, rotation); - } - } - return null; - } - - /** - * Gets the MetalBendingColor from the config. - * - * @return Config specified ChatColor - */ - @Deprecated - public static ChatColor getMetalbendingColor() { - return ChatColor.valueOf(config.getString("Properties.Chat.Colors.Metalbending")); - } - - public static HashSet getTransparentEarthbending() { - HashSet set = new HashSet(); - for (int i : transparentToEarthbending) { - set.add((byte) i); - } - return set; - } - - /** - * Finds a valid Lava source for a Player. To use dynamic source selection, use - * BlockSource.getLavaSourceBlock() instead of this method. Dynamic source selection saves the - * user's previous source for future use. - * {@link BlockSource#getLavaSourceBlock(Player, double, com.projectkorra.projectkorra.util.ClickType)} - * - * @param player the player that is attempting to Earthbend. - * @param range the maximum block selection range. - * @return a valid Lava source block, or null if one could not be found. - */ - @SuppressWarnings("deprecation") - public static Block getLavaSourceBlock(Player player, int range) { - Location location = player.getEyeLocation(); - Vector vector = location.getDirection().clone().normalize(); - for (double i = 0; i <= range; i++) { - Block block = location.clone().add(vector.clone().multiply(i)).getBlock(); - if (GeneralMethods.isRegionProtectedFromBuild(player, "LavaSurge", location)) - continue; - if (isLavabendable(block, player)) { - if (TempBlock.isTempBlock(block)) { - TempBlock tb = TempBlock.get(block); - byte full = 0x0; - if (tb.getState().getRawData() != full && (tb.getState().getType() != Material.LAVA - || tb.getState().getType() != Material.STATIONARY_LAVA)) { - continue; - } - } - return block; - } - } - return null; - } - - public static boolean isLavabendingAbility(String ability) { - return AbilityModuleManager.lavaabilities.contains(ability); - } - - public static boolean isMetalbendingAbility(String ability) { - return AbilityModuleManager.metalabilities.contains(ability); - } - - public static boolean isSandbendingAbility(String ability) { - return AbilityModuleManager.sandabilities.contains(ability); - } - - public static boolean isEarthAbility(String ability) { - return AbilityModuleManager.earthbendingabilities.contains(ability); - } - - public static boolean isEarthbendable(Player player, Block block) { - return isEarthbendable(player, "RaiseEarth", block); - } - - public static boolean isEarth(Block block) { - Material material = block.getType(); - return config.getStringList("Properties.Earth.EarthbendableBlocks").contains(material.toString()); - } - - public static boolean isMetal(Block block) { - Material material = block.getType(); - return config.getStringList("Properties.Earth.MetalBlocks").contains(material.toString()); - } - - public static boolean isSand(Block block) { - Material material = block.getType(); - return config.getStringList("Properties.Earth.SandBlocks").contains(material.toString()); - } - - public static double getMetalAugment(double value) { - return value * config.getDouble("Properties.Earth.MetalPowerFactor"); - } - - public static boolean isEarthbendable(Block block) { - if (isEarth(block)) { - return true; - } - if (isSand(block)) { - return true; - } - if (isMetal(block)) { - return true; - } - return false; - } - - public static boolean isEarthbendable(Player player, String ability, Block block) { - Material material = block.getType(); - boolean valid = false; - for (String s : config.getStringList("Properties.Earth.EarthbendableBlocks")) - if (material == Material.getMaterial(s)) { - valid = true; - break; - } - if (isSand(block) && canSandbend(player)) { - valid = true; - } - if (isMetal(block) && canMetalbend(player)) { - valid = true; - } - if (tempNoEarthbending.contains(block)) - valid = false; - - if (GeneralMethods.isRegionProtectedFromBuild(player, ability, block.getLocation())) - valid = false; - return valid; - } - - public static boolean isMetalbendable(Player player, Material mat) { - boolean valid = false; - for (String s : config.getStringList("Properties.Earth.MetalBlocks")) { - if (mat == Material.getMaterial(s)) { - valid = true; - break; - } - } - if (!player.hasPermission("bending.earth.metalbending")) - valid = false; - return valid; - } - - public static boolean isMetalBlock(Block block) { - if (block.getType() == Material.GOLD_BLOCK || block.getType() == Material.IRON_BLOCK - || block.getType() == Material.IRON_ORE || block.getType() == Material.GOLD_ORE - || block.getType() == Material.QUARTZ_BLOCK || block.getType() == Material.QUARTZ_ORE) - return true; - return false; - } - - public static boolean isTransparentToEarthbending(Player player, Block block) { - return isTransparentToEarthbending(player, "RaiseEarth", block); - } - - @SuppressWarnings("deprecation") - public static boolean isTransparentToEarthbending(Player player, String ability, Block block) { - if (!Arrays.asList(transparentToEarthbending).contains(block.getTypeId())) - return false; - if (!GeneralMethods.isRegionProtectedFromBuild(player, ability, block.getLocation())) - return true; - return false; - } - - public static boolean isLava(Block block) { - if (block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA) - return true; - return false; - } - - @SuppressWarnings("deprecation") - public static boolean isLavabendable(Block block, Player player) { - byte full = 0x0; - if (TempBlock.isTempBlock(block)) { - TempBlock tblock = TempBlock.instances.get(block); - if (tblock == null || !LavaFlow.TEMP_LAVA_BLOCKS.contains(tblock)) - return false; - } - if ((block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA) && block.getData() == full) - return true; - return false; - } - - public static void moveEarth(Player player, Block block, Vector direction, int chainlength) { - moveEarth(player, block, direction, chainlength, true); - } - - public static boolean moveEarth(Player player, Block block, Vector direction, int chainlength, boolean throwplayer) { - if (isEarthbendable(player, block) - && !GeneralMethods.isRegionProtectedFromBuild(player, "RaiseEarth", block.getLocation())) { - - boolean up = false; - boolean down = false; - Vector norm = direction.clone().normalize(); - if (norm.dot(new Vector(0, 1, 0)) == 1) { - up = true; - } else if (norm.dot(new Vector(0, -1, 0)) == 1) { - down = true; - } - Vector negnorm = norm.clone().multiply(-1); - - Location location = block.getLocation(); - - ArrayList blocks = new ArrayList(); - for (double j = -2; j <= chainlength; j++) { - Block checkblock = location.clone().add(negnorm.clone().multiply(j)).getBlock(); - if (!tempnophysics.contains(checkblock)) { - blocks.add(checkblock); - tempnophysics.add(checkblock); - } - } - - Block affectedblock = location.clone().add(norm).getBlock(); - if (EarthPassive.isPassiveSand(block)) { - EarthPassive.revertSand(block); - } - - if (affectedblock == null) - return false; - if (isTransparentToEarthbending(player, affectedblock)) { - if (throwplayer) { - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(affectedblock.getLocation(), 1.75)) { - if (entity instanceof LivingEntity) { - LivingEntity lentity = (LivingEntity) entity; - if (lentity.getEyeLocation().getBlockX() == affectedblock.getX() - && lentity.getEyeLocation().getBlockZ() == affectedblock.getZ()) - if (!(entity instanceof FallingBlock)) - entity.setVelocity(norm.clone().multiply(.75)); - } else { - if (entity.getLocation().getBlockX() == affectedblock.getX() - && entity.getLocation().getBlockZ() == affectedblock.getZ()) - if (!(entity instanceof FallingBlock)) - entity.setVelocity(norm.clone().multiply(.75)); - } - } - - } - - if (up) { - Block topblock = affectedblock.getRelative(BlockFace.UP); - if (topblock.getType() != Material.AIR) { - GeneralMethods.breakBlock(affectedblock); - } else if (!affectedblock.isLiquid() && affectedblock.getType() != Material.AIR) { - moveEarthBlock(affectedblock, topblock); - } - } else { - GeneralMethods.breakBlock(affectedblock); - } - - moveEarthBlock(block, affectedblock); - playEarthbendingSound(block.getLocation()); - - for (double i = 1; i < chainlength; i++) { - affectedblock = location.clone().add(negnorm.getX() * i, negnorm.getY() * i, negnorm.getZ() * i).getBlock(); - if (!isEarthbendable(player, affectedblock)) { - if (down) { - if (isTransparentToEarthbending(player, affectedblock) && !affectedblock.isLiquid() - && affectedblock.getType() != Material.AIR) { - moveEarthBlock(affectedblock, block); - } - } - break; - } - if (EarthPassive.isPassiveSand(affectedblock)) { - EarthPassive.revertSand(affectedblock); - } - if (block == null) { - for (Block checkblock : blocks) { - tempnophysics.remove(checkblock); - } - return false; - } - moveEarthBlock(affectedblock, block); - block = affectedblock; - } - - int i = chainlength; - affectedblock = location.clone().add(negnorm.getX() * i, negnorm.getY() * i, negnorm.getZ() * i).getBlock(); - if (!isEarthbendable(player, affectedblock)) { - if (down) { - if (isTransparentToEarthbending(player, affectedblock) && !affectedblock.isLiquid()) { - moveEarthBlock(affectedblock, block); - } - } - } - - } else { - for (Block checkblock : blocks) { - tempnophysics.remove(checkblock); - } - return false; - } - for (Block checkblock : blocks) { - tempnophysics.remove(checkblock); - } - return true; - } - return false; - } - - public static void moveEarth(Player player, Location location, Vector direction, int chainlength) { - moveEarth(player, location, direction, chainlength, true); - } - - public static void moveEarth(Player player, Location location, Vector direction, int chainlength, boolean throwplayer) { - Block block = location.getBlock(); - moveEarth(player, block, direction, chainlength, throwplayer); - } - - @SuppressWarnings("deprecation") - public static void moveEarthBlock(Block source, Block target) { - byte full = 0x0; - Information info; - if (movedearth.containsKey(source)) { - info = movedearth.get(source); - info.setTime(System.currentTimeMillis()); - movedearth.remove(source); - movedearth.put(target, info); - } else { - info = new Information(); - info.setBlock(source); - info.setTime(System.currentTimeMillis()); - info.setState(source.getState()); - movedearth.put(target, info); - } - - if (GeneralMethods.isAdjacentToThreeOrMoreSources(source)) { - source.setType(Material.WATER); - source.setData(full); - } else { - source.setType(Material.AIR); - } - if (info.getState().getType() == Material.SAND) { - if (info.getState().getRawData() == (byte) 0x1) { - target.setType(Material.RED_SANDSTONE); - } else { - target.setType(Material.SANDSTONE); - } - } else { - target.setType(info.getState().getType()); - target.setData(info.getState().getRawData()); - } - } - - public static void playSandBendingSound(Location loc) { - if (plugin.getConfig().getBoolean("Properties.Earth.PlaySound")) { - loc.getWorld().playSound(loc, Sound.DIG_SAND, 1.5f, 5); - } - } - - public static void removeAllEarthbendedBlocks() { - for (Block block : movedearth.keySet()) { - revertBlock(block); - } - - for (Integer i : tempair.keySet()) { - revertAirBlock(i, true); - } - } - - public static void removeRevertIndex(Block block) { - if (movedearth.containsKey(block)) { - Information info = movedearth.get(block); - if (block.getType() == Material.SANDSTONE && info.getType() == Material.SAND) - block.setType(Material.SAND); - if (EarthColumn.blockInAllAffectedBlocks(block)) - EarthColumn.revertBlock(block); - - movedearth.remove(block); - } - } - - public static void revertAirBlock(int i) { - revertAirBlock(i, false); - } - - public static void revertAirBlock(int i, boolean force) { - if (!tempair.containsKey(i)) - return; - Information info = tempair.get(i); - Block block = info.getState().getBlock(); - if (block.getType() != Material.AIR && !block.isLiquid()) { - if (force || !movedearth.containsKey(block)) { -// GeneralMethods.dropItems(block, -// GeneralMethods.getDrops(block, info.getState().getType(), info.getState().getRawData(), pickaxe)); - tempair.remove(i); - } else { - info.setTime(info.getTime() + 10000); - } - return; - } else { - info.getState().update(true); - tempair.remove(i); - } - } - - @SuppressWarnings("deprecation") - public static boolean revertBlock(Block block) { - byte full = 0x0; - if (!ProjectKorra.plugin.getConfig().getBoolean("Properties.Earth.RevertEarthbending")) { - movedearth.remove(block); - return false; - } - if (movedearth.containsKey(block)) { - Information info = movedearth.get(block); - Block sourceblock = info.getState().getBlock(); - - if (info.getState().getType() == Material.AIR) { - movedearth.remove(block); - return true; - } - - if (block.equals(sourceblock)) { - info.getState().update(true); - if (EarthColumn.blockInAllAffectedBlocks(sourceblock)) - EarthColumn.revertBlock(sourceblock); - if (EarthColumn.blockInAllAffectedBlocks(block)) - EarthColumn.revertBlock(block); - movedearth.remove(block); - return true; - } - - if (movedearth.containsKey(sourceblock)) { - addTempAirBlock(block); - movedearth.remove(block); - return true; - } - - if (sourceblock.getType() == Material.AIR || sourceblock.isLiquid()) { - info.getState().update(true); - } else { -// GeneralMethods.dropItems(block, -// GeneralMethods.getDrops(block, info.getState().getType(), info.getState().getRawData(), pickaxe)); - } - - if (GeneralMethods.isAdjacentToThreeOrMoreSources(block)) { - block.setType(Material.WATER); - block.setData(full); - } else { - block.setType(Material.AIR); - } - - if (EarthColumn.blockInAllAffectedBlocks(sourceblock)) - EarthColumn.revertBlock(sourceblock); - if (EarthColumn.blockInAllAffectedBlocks(block)) - EarthColumn.revertBlock(block); - movedearth.remove(block); - } - return true; - } - - public static void playEarthbendingSound(Location loc) { - if (plugin.getConfig().getBoolean("Properties.Earth.PlaySound")) { - loc.getWorld().playEffect(loc, Effect.GHAST_SHOOT, 0, 10); - } - } - - public static void playMetalbendingSound(Location loc) { - if (plugin.getConfig().getBoolean("Properties.Earth.PlaySound")) { - loc.getWorld().playSound(loc, Sound.IRONGOLEM_HIT, 1, 10); - } - } - - public static void stopBending() { - Catapult.removeAll(); - CompactColumn.removeAll(); - EarthBlast.removeAll(); - EarthColumn.removeAll(); - EarthPassive.removeAll(); - EarthArmor.removeAll(); - EarthTunnel.instances.clear(); - Shockwave.removeAll(); - Tremorsense.removeAll(); - LavaFlow.removeAll(); - EarthSmash.removeAll(); - - if (ProjectKorra.plugin.getConfig().getBoolean("Properties.Earth.RevertEarthbending")) { - EarthMethods.removeAllEarthbendedBlocks(); - } - - EarthPassive.removeAll(); - } - -} diff --git a/src/com/projectkorra/projectkorra/earthbending/EarthPassive.java b/src/com/projectkorra/projectkorra/earthbending/EarthPassive.java index fbed3ca9..3fddcc10 100644 --- a/src/com/projectkorra/projectkorra/earthbending/EarthPassive.java +++ b/src/com/projectkorra/projectkorra/earthbending/EarthPassive.java @@ -1,8 +1,11 @@ package com.projectkorra.projectkorra.earthbending; +import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.Element; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.EarthAbility; +import com.projectkorra.projectkorra.ability.ElementalAbility; import com.projectkorra.projectkorra.util.TempBlock; import org.bukkit.Bukkit; @@ -20,20 +23,24 @@ import java.util.concurrent.ConcurrentHashMap; public class EarthPassive { - public static ConcurrentHashMap sandblocks = new ConcurrentHashMap(); - public static ConcurrentHashMap sandidentities = new ConcurrentHashMap(); + public static ConcurrentHashMap sandBlocks = new ConcurrentHashMap(); + public static ConcurrentHashMap sandIdEntities = new ConcurrentHashMap(); private static final long duration = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.Passive.Duration"); - private static int sandspeed = ProjectKorra.plugin.getConfig().getInt("Properties.Earth.Passive.SandRunPower"); + private static final int sandSpeed = ProjectKorra.plugin.getConfig().getInt("Properties.Earth.Passive.SandRunPower"); @SuppressWarnings("deprecation") public static boolean softenLanding(Player player) { Block block = player.getLocation().getBlock().getRelative(BlockFace.DOWN); - if (EarthMethods.canMetalbend(player) && EarthMethods.isMetalBlock(block)) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + return false; + } else if (bPlayer.canMetalbend() && ElementalAbility.isMetalBlock(block)) { return true; } - if (EarthMethods.isEarthbendable(player, block) || EarthMethods.isTransparentToEarthbending(player, block)) { - if (!EarthMethods.isTransparentToEarthbending(player, block)) { + + if (EarthAbility.isEarthbendable(player, block) || ElementalAbility.isTransparentToEarthbending(player, block)) { + if (!ElementalAbility.isTransparentToEarthbending(player, block)) { MaterialData type = block.getState().getData(); if (GeneralMethods.isSolid(block.getRelative(BlockFace.DOWN))) { if (type.getItemType() == Material.RED_SANDSTONE) { @@ -43,15 +50,15 @@ public class EarthPassive { } else { block.setType(Material.SAND); } - if (!sandblocks.containsKey(block)) { - sandidentities.put(block, type); - sandblocks.put(block, System.currentTimeMillis()); + if (!sandBlocks.containsKey(block)) { + sandIdEntities.put(block, type); + sandBlocks.put(block, System.currentTimeMillis()); } } } for (Block affectedBlock : GeneralMethods.getBlocksAroundPoint(block.getLocation(), 2)) { - if (EarthMethods.isEarthbendable(player, affectedBlock)) { + if (EarthAbility.isEarthbendable(player, affectedBlock)) { if (GeneralMethods.isSolid(affectedBlock.getRelative(BlockFace.DOWN))) { MaterialData type = affectedBlock.getState().getData(); if (type.getItemType() == Material.RED_SANDSTONE) { @@ -61,9 +68,9 @@ public class EarthPassive { } else { affectedBlock.setType(Material.SAND); } - if (!sandblocks.containsKey(affectedBlock)) { - sandidentities.putIfAbsent(affectedBlock, type); - sandblocks.put(affectedBlock, System.currentTimeMillis()); + if (!sandBlocks.containsKey(affectedBlock)) { + sandIdEntities.putIfAbsent(affectedBlock, type); + sandBlocks.put(affectedBlock, System.currentTimeMillis()); } } } @@ -71,21 +78,19 @@ public class EarthPassive { return true; } - if (EarthMethods.isEarthbendable(player, block) || EarthMethods.isTransparentToEarthbending(player, block)) { - return true; - } - return false; + return EarthAbility.isEarthbendable(player, block) || EarthAbility.isTransparentToEarthbending(player, block); } public static boolean isPassiveSand(Block block) { - return (sandblocks.containsKey(block)); + return sandBlocks.containsKey(block); } @SuppressWarnings("deprecation") public static void revertSand(Block block) { - MaterialData materialdata = sandidentities.get(block); - sandidentities.remove(block); - sandblocks.remove(block); + MaterialData materialdata = sandIdEntities.get(block); + sandIdEntities.remove(block); + sandBlocks.remove(block); + if (block.getType() == Material.SAND) { block.setType(materialdata.getItemType()); block.setData(materialdata.getData()); @@ -93,11 +98,16 @@ public class EarthPassive { } public static void sandSpeed() { - for (Player p : Bukkit.getOnlinePlayers()) { - if (p != null && GeneralMethods.getBendingPlayer(p.getName()) != null) { - if (EarthMethods.canSandbend(p) && GeneralMethods.getBendingPlayer(p.getName()).hasElement(Element.Earth) && !GeneralMethods.canBendPassive(p.getName(), Element.Air) && !GeneralMethods.canBendPassive(p.getName(), Element.Chi)) { - if (p.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.SAND || p.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.SANDSTONE || p.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.RED_SANDSTONE) { - p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 60, sandspeed - 1)); + for (Player player : Bukkit.getOnlinePlayers()) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + + if (bPlayer != null) { + if (bPlayer.canSandbend() && bPlayer.hasElement(Element.EARTH) + && !bPlayer.canBendPassive(Element.AIR) && !bPlayer.canBendPassive(Element.CHI)) { + if (player.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.SAND + || player.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.SANDSTONE + || player.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.RED_SANDSTONE) { + player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 60, sandSpeed - 1)); } } } @@ -107,12 +117,16 @@ public class EarthPassive { @SuppressWarnings("deprecation") public static void handleMetalPassives() { for (Player player : Bukkit.getOnlinePlayers()) { - if (GeneralMethods.canBendPassive(player.getName(), Element.Earth) && EarthMethods.canMetalbend(player)) { - if (player.isSneaking() && !GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("MetalPassive")) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + + if (bPlayer != null && bPlayer.canBendPassive(Element.EARTH) && bPlayer.canMetalbend()) { + if (player.isSneaking() && !bPlayer.isOnCooldown("MetalPassive")) { Block block = player.getTargetBlock((HashSet) null, 5); - if (block == null) + if (block == null) { continue; - if (block.getType() == Material.IRON_DOOR_BLOCK && !GeneralMethods.isRegionProtectedFromBuild(player, null, block.getLocation())) { + } + + if (block.getType() == Material.IRON_DOOR_BLOCK && !GeneralMethods.isRegionProtectedFromBuild(player, block.getLocation())) { if (block.getData() >= 8) { block = block.getRelative(BlockFace.DOWN); } @@ -125,17 +139,7 @@ public class EarthPassive { block.getWorld().playSound(block.getLocation(), Sound.DOOR_OPEN, 10, 1); } - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("MetalPassive", 200); - - // Door door = (Door) block.getState().getData(); - // if (door.isTopHalf()) { - // block = block.getRelative(BlockFace.DOWN); - // if (door.isOpen()) { - // door.setOpen(false); - // } else { - // door.setOpen(true); - // } - // } + bPlayer.addCooldown("MetalPassive", 200); } } } @@ -143,15 +147,15 @@ public class EarthPassive { } public static void revertSands() { - for (Block block : sandblocks.keySet()) { - if (System.currentTimeMillis() >= sandblocks.get(block) + duration) { + for (Block block : sandBlocks.keySet()) { + if (System.currentTimeMillis() >= sandBlocks.get(block) + duration) { revertSand(block); } } } public static void revertAllSand() { - for (Block block : sandblocks.keySet()) { + for (Block block : sandBlocks.keySet()) { revertSand(block); } } @@ -161,44 +165,30 @@ public class EarthPassive { } public static boolean canPhysicsChange(Block block) { - if (LavaWall.affectedblocks.containsKey(block)) + if (LavaSurgeWall.getAffectedBlocks().containsKey(block)) { return false; - if (LavaWall.wallblocks.containsKey(block)) + } else if (LavaSurgeWall.getWallBlocks().containsKey(block)) { return false; - if (LavaWave.isBlockWave(block)) + } else if (LavaSurgeWave.isBlockWave(block)) { return false; - if (TempBlock.isTempBlock(block)) + } else if (TempBlock.isTempBlock(block)) { return false; - if (TempBlock.isTouchingTempBlock(block)) + } else if (TempBlock.isTouchingTempBlock(block)) { return false; + } return true; } public static boolean canFlowFromTo(Block from, Block to) { - // if (to.getType() == Material.TORCH) - // return true; - if (LavaWall.affectedblocks.containsKey(to) || LavaWall.affectedblocks.containsKey(from)) { - // Methods.verbose("waterwallaffectedblocks"); + if (LavaSurgeWall.getAffectedBlocks().containsKey(to) || LavaSurgeWall.getAffectedBlocks().containsKey(from)) { + return false; + } else if (LavaSurgeWall.getWallBlocks().containsKey(to) || LavaSurgeWall.getWallBlocks().containsKey(from)) { + return false; + } else if (LavaSurgeWave.isBlockWave(to) || LavaSurgeWave.isBlockWave(from)) { + return false; + } else if (TempBlock.isTempBlock(to) || TempBlock.isTempBlock(from)) { return false; } - if (LavaWall.wallblocks.containsKey(to) || LavaWall.wallblocks.containsKey(from)) { - // Methods.verbose("waterwallwall"); - return false; - } - if (LavaWave.isBlockWave(to) || LavaWave.isBlockWave(from)) { - // Methods.verbose("wave"); - return false; - } - if (TempBlock.isTempBlock(to) || TempBlock.isTempBlock(from)) { - // Methods.verbose("tempblock"); - return false; - } - // if (Methods.isAdjacentToFrozenBlock(to) - // || Methods.isAdjacentToFrozenBlock(from)) { - // // Methods.verbose("frozen"); - // return false; - // } - return true; } } diff --git a/src/com/projectkorra/projectkorra/earthbending/EarthSmash.java b/src/com/projectkorra/projectkorra/earthbending/EarthSmash.java index a3088261..679e848c 100644 --- a/src/com/projectkorra/projectkorra/earthbending/EarthSmash.java +++ b/src/com/projectkorra/projectkorra/earthbending/EarthSmash.java @@ -1,14 +1,14 @@ package com.projectkorra.projectkorra.earthbending; -import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.airbending.AirMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.EarthAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; import com.projectkorra.projectkorra.util.ClickType; import com.projectkorra.projectkorra.util.ParticleEffect; import com.projectkorra.projectkorra.util.TempBlock; -import com.projectkorra.projectkorra.waterbending.WaterMethods; import org.bukkit.Effect; import org.bukkit.Location; @@ -23,151 +23,145 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; -public class EarthSmash { +// TODO: remove allowShooting from config +public class EarthSmash extends EarthAbility { + public static enum State { START, LIFTING, LIFTED, GRABBED, SHOT, FLYING, REMOVED } - public static ArrayList instances = new ArrayList(); - public static boolean ALLOW_GRAB = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.EarthSmash.AllowGrab"); - public static boolean ALLOW_SHOOTING = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.EarthSmash.AllowShooting"); - public static boolean ALLOW_FLIGHT = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.EarthSmash.AllowFlight"); - public static int SELECT_RANGE = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.EarthSmash.SelectRange"); - public static double GRAB_RANGE = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.EarthSmash.GrabRange"); - public static double TRAVEL_RANGE = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.EarthSmash.ShotRange"); - public static double SHOOTING_DAMAGE = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.EarthSmash.Damage"); - - public static double KNOCKBACK_POWER = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.EarthSmash.Knockback"); - public static double KNOCKUP_POWER = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.EarthSmash.Knockup"); - public static double FLYING_PLAYER_SPEED = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.EarthSmash.FlightSpeed"); - public static long CHARGE_TIME = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.EarthSmash.ChargeTime"); - public static long MAIN_COOLDOWN = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.EarthSmash.Cooldown"); - public static long FLYING_REMOVE_TIMER = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.EarthSmash.FlightTimer"); - public static long REMOVE_TIMER = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.EarthSmash.RemoveTimer"); - - private static int REQUIRED_BENDABLE_BLOCKS = 11; - private static int MAX_BLOCKS_TO_PASS_THROUGH = 3; - private static double GRAB_DETECTION_RADIUS = GRAB_RANGE; - private static double FLIGHT_DETECTION_RADIUS = 3.8; - private static long SHOOTING_ANIMATION_COOLDOWN = 25; - private static long FLYING_ANIMATION_COOLDOWN = 0; - private static long LIFT_ANIMATION_COOLDOWN = 30; - - private Player player; - private BendingPlayer bplayer; + private boolean allowGrab; + private boolean allowFlight; + private int animationCounter; + private int progressCounter; + private int requiredBendableBlocks; + private int maxBlocksToPassThrough; + private long delay; + private long cooldown; + private long chargeTime; + private long removeTimer; + private long flightRemoveTimer; + private long flightStartTime; + private long shootAnimationCooldown; + private long flightAnimationCooldown; + private long liftAnimationCooldown; + private double grabRange; + private double shootRange; + private double damage; + private double knockback; + private double knockup; + private double flySpeed; + private double grabbedDistance; + private double grabDetectionRadius; + private double flightDetectionRadius; + private State state; private Block origin; - private Location loc, destination; - public State state = State.START; - private int animCounter, progressCounter; - private long time, delay, cooldown, flightRemove, flightStart; - private double grabbedRange; - private double chargeTime, damage, knockback, knockup, flySpeed, shootRange; - private int selectRange; - private ArrayList affectedEntities = new ArrayList(); - private ArrayList currentBlocks = new ArrayList(); - private ArrayList affectedBlocks = new ArrayList(); + private Location location; + private Location destination; + private ArrayList affectedEntities; + private ArrayList currentBlocks; + private ArrayList affectedBlocks; public EarthSmash(Player player, ClickType type) { - if (!GeneralMethods.hasPermission(player, "EarthSmash")) - return; - - this.player = player; - bplayer = GeneralMethods.getBendingPlayer(player.getName()); - this.time = System.currentTimeMillis(); - + super(player); + + this.requiredBendableBlocks = 11; + this.maxBlocksToPassThrough = 3; + this.shootAnimationCooldown = 25; + this.flightAnimationCooldown = 0; + this.liftAnimationCooldown = 30; + this.grabDetectionRadius = 2.5; + this.flightDetectionRadius = 3.8; + this.state = State.START; + this.allowGrab = getConfig().getBoolean("Abilities.Earth.EarthSmash.AllowGrab"); + this.allowFlight = getConfig().getBoolean("Abilities.Earth.EarthSmash.AllowFlight"); + this.grabRange = getConfig().getDouble("Abilities.Earth.EarthSmash.GrabRange"); + this.shootRange = getConfig().getDouble("Abilities.Earth.EarthSmash.ShotRange"); + this.damage = getConfig().getDouble("Abilities.Earth.EarthSmash.Damage"); + this.knockback = getConfig().getDouble("Abilities.Earth.EarthSmash.Knockback"); + this.knockup = getConfig().getDouble("Abilities.Earth.EarthSmash.Knockup"); + this.flySpeed = getConfig().getDouble("Abilities.Earth.EarthSmash.FlightSpeed"); + this.chargeTime = getConfig().getLong("Abilities.Earth.EarthSmash.ChargeTime"); + this.cooldown = getConfig().getLong("Abilities.Earth.EarthSmash.Cooldown"); + this.flightRemoveTimer = getConfig().getLong("Abilities.Earth.EarthSmash.FlightTimer"); + this.removeTimer = getConfig().getLong("Abilities.Earth.EarthSmash.RemoveTimer"); + this.affectedEntities = new ArrayList<>(); + this.currentBlocks = new ArrayList<>(); + this.affectedBlocks = new ArrayList<>(); + if (type == ClickType.SHIFT_DOWN || type == ClickType.SHIFT_UP && !player.isSneaking()) { - selectRange = SELECT_RANGE; - chargeTime = CHARGE_TIME; - cooldown = MAIN_COOLDOWN; - damage = SHOOTING_DAMAGE; - knockback = KNOCKBACK_POWER; - knockup = KNOCKUP_POWER; - flySpeed = FLYING_PLAYER_SPEED; - flightRemove = FLYING_REMOVE_TIMER; - shootRange = TRAVEL_RANGE; - if (AvatarState.isAvatarState(player)) { - selectRange = AvatarState.getValue(selectRange); + if (bPlayer.isAvatarState()) { + grabRange = AvatarState.getValue(grabRange); chargeTime = 0; cooldown = 0; damage = AvatarState.getValue(damage); knockback = AvatarState.getValue(knockback); knockup = AvatarState.getValue(knockup); flySpeed = AvatarState.getValue(flySpeed); - flightRemove = Integer.MAX_VALUE; + flightRemoveTimer = Integer.MAX_VALUE; shootRange = AvatarState.getValue(shootRange); - GRAB_DETECTION_RADIUS = AvatarState.getValue(shootRange); } EarthSmash flySmash = flyingInSmashCheck(player); if (flySmash != null) { flySmash.state = State.FLYING; flySmash.player = player; - flySmash.flightStart = System.currentTimeMillis(); + flySmash.flightStartTime = System.currentTimeMillis(); return; } - EarthSmash grabbedSmash = aimingAtSmashCheck(player, null); + EarthSmash grabbedSmash = aimingAtSmashCheck(player, State.LIFTED); if (grabbedSmash == null) { - + if (bPlayer.isOnCooldown(this)) { + return; + } grabbedSmash = aimingAtSmashCheck(player, State.SHOT); } - else if (grabbedSmash != null && grabbedSmash.state == State.LIFTED) { - + + if (grabbedSmash != null) { grabbedSmash.state = State.GRABBED; - grabbedSmash.grabbedRange = grabbedSmash.loc.distance(player.getEyeLocation()); - grabbedSmash.player = player; - return; - } - else if (grabbedSmash != null && grabbedSmash.state == State.SHOT && grabbedSmash.player != player && grabbedSmash == aimingAtSmashCheck(player, State.SHOT)) { - - grabbedSmash.state = State.GRABBED; - grabbedSmash.grabbedRange = grabbedSmash.loc.distance(player.getEyeLocation()); + grabbedSmash.grabbedDistance = grabbedSmash.location.distance(player.getEyeLocation()); grabbedSmash.player = player; return; } + + start(); } else if (type == ClickType.LEFT_CLICK && player.isSneaking()) { - for (EarthSmash smash : instances) { + for (EarthSmash smash : CoreAbility.getAbilities(EarthSmash.class)) { if (smash.state == State.GRABBED && smash.player == player) { smash.state = State.SHOT; smash.destination = player.getEyeLocation().clone().add(player.getEyeLocation().getDirection().normalize().multiply(smash.shootRange)); - smash.loc.getWorld().playEffect(smash.loc, Effect.GHAST_SHOOT, 0, 10); + smash.location.getWorld().playEffect(smash.location, Effect.GHAST_SHOOT, 0, 10); } } return; } else if (type == ClickType.RIGHT_CLICK && player.isSneaking()) { EarthSmash grabbedSmash = aimingAtSmashCheck(player, State.GRABBED); if (grabbedSmash != null) { - player.teleport(grabbedSmash.loc.clone().add(0, 2, 0)); + player.teleport(grabbedSmash.location.clone().add(0, 2, 0)); grabbedSmash.state = State.FLYING; grabbedSmash.player = player; - grabbedSmash.flightStart = System.currentTimeMillis(); + grabbedSmash.flightStartTime = System.currentTimeMillis(); } return; - } else { - return; } - instances.add(this); } + @Override public void progress() { progressCounter++; - if (state == State.LIFTED && REMOVE_TIMER > 0 && System.currentTimeMillis() - time > REMOVE_TIMER) { + if (state == State.LIFTED && removeTimer > 0 && System.currentTimeMillis() - startTime > removeTimer) { remove(); return; } - if (state == State.START || state == State.FLYING || state == State.GRABBED) { - if (player.isDead() || !player.isOnline()) { - remove(); - return; - } - } else if (state == State.START) { - String ability = GeneralMethods.getBoundAbility(player); - if (ability == null || !ability.equalsIgnoreCase("EarthSmash") || bplayer.isOnCooldown("EarthSmash")) { + + if (state == State.START) { + if (!bPlayer.canBend(this)) { remove(); return; } } else if (state == State.START || state == State.FLYING || state == State.GRABBED) { - if (!GeneralMethods.canBend(player.getName(), "EarthSmash")) { + if (!bPlayer.canBendIgnoreCooldowns(this)) { remove(); return; } @@ -175,46 +169,45 @@ public class EarthSmash { if (state == State.START && progressCounter > 1) { if (!player.isSneaking()) { - if (System.currentTimeMillis() - time > chargeTime) { - origin = EarthMethods.getEarthSourceBlock(player, selectRange, true, EarthMethods.canSandbend(player), EarthMethods.canMetalbend(player)); + if (System.currentTimeMillis() - startTime >= chargeTime) { + origin = getEarthSourceBlock(grabRange); if (origin == null) { remove(); return; } - loc = origin.getLocation(); + bPlayer.addCooldown(this); + location = origin.getLocation(); state = State.LIFTING; } else { remove(); return; } - } else if (System.currentTimeMillis() - time > chargeTime) { + } else if (System.currentTimeMillis() - startTime > chargeTime) { Location tempLoc = player.getEyeLocation().add(player.getEyeLocation().getDirection().normalize().multiply(1.2)); tempLoc.add(0, 0.3, 0); ParticleEffect.SMOKE.display(tempLoc, 0.3F, 0.1F, 0.3F, 0, 4); } - if (bplayer.isOnCooldown("EarthSmash")) { - return; - } } else if (state == State.LIFTING) { - if (System.currentTimeMillis() - delay >= LIFT_ANIMATION_COOLDOWN) { + if (System.currentTimeMillis() - delay >= liftAnimationCooldown) { delay = System.currentTimeMillis(); animateLift(); - bplayer.addCooldown("EarthSmash", cooldown); } } else if (state == State.GRABBED) { if (player.isSneaking()) { revert(); - Location oldLoc = loc.clone(); - loc = player.getEyeLocation().add(player.getEyeLocation().getDirection().normalize().multiply(grabbedRange)); + Location oldLoc = location.clone(); + location = player.getEyeLocation().add(player.getEyeLocation().getDirection().normalize().multiply(grabbedDistance)); - //Check to make sure the new location is available to move to - for (Block block : getBlocks()) - if (block.getType() != Material.AIR && !EarthMethods.isTransparentToEarthbending(player, block)) { - loc = oldLoc; + // Check to make sure the new location is available to move to + for (Block block : getBlocks()) { + if (block.getType() != Material.AIR && !isTransparent(block)) { + location = oldLoc; break; } - WaterMethods.removeWaterSpouts(loc, 2, player); - AirMethods.removeAirSpouts(loc, 2, player); + } + + WaterAbility.removeWaterSpouts(location, 2, player); + AirAbility.removeAirSpouts(location, 2, player); draw(); return; } else { @@ -222,31 +215,36 @@ public class EarthSmash { return; } } else if (state == State.SHOT) { - if (System.currentTimeMillis() - delay >= SHOOTING_ANIMATION_COOLDOWN) { - + if (System.currentTimeMillis() - delay >= shootAnimationCooldown) { delay = System.currentTimeMillis(); - if (GeneralMethods.isRegionProtectedFromBuild(player, "EarthSmash", loc)) { + if (GeneralMethods.isRegionProtectedFromBuild(this, location)) { remove(); return; } + revert(); - loc.add(GeneralMethods.getDirection(loc, destination).normalize().multiply(1)); - if (loc.distanceSquared(destination) < 4) { + location.add(GeneralMethods.getDirection(location, destination).normalize().multiply(1)); + if (location.distanceSquared(destination) < 4) { remove(); return; } + // If an earthsmash runs into too many blocks we should remove it int badBlocksFound = 0; - for (Block block : getBlocks()) - if (block.getType() != Material.AIR && (!EarthMethods.isTransparentToEarthbending(player, block) || block.getType() == Material.WATER || block.getType() == Material.STATIONARY_WATER)) + for (Block block : getBlocks()) { + if (block.getType() != Material.AIR && (!isTransparent(block) + || block.getType() == Material.WATER + || block.getType() == Material.STATIONARY_WATER)) { badBlocksFound++; + } + } - if (badBlocksFound > MAX_BLOCKS_TO_PASS_THROUGH) { + if (badBlocksFound > maxBlocksToPassThrough) { remove(); return; } - WaterMethods.removeWaterSpouts(loc, 2, player); - AirMethods.removeAirSpouts(loc, 2, player); + WaterAbility.removeWaterSpouts(location, 2, player); + AirAbility.removeAirSpouts(location, 2, player); shootingCollisionDetection(); draw(); smashToSmashCollisionDetection(); @@ -256,141 +254,151 @@ public class EarthSmash { if (!player.isSneaking()) { remove(); return; - } else if (System.currentTimeMillis() - delay >= FLYING_ANIMATION_COOLDOWN) { + } else if (System.currentTimeMillis() - delay >= flightAnimationCooldown) { delay = System.currentTimeMillis(); - if (GeneralMethods.isRegionProtectedFromBuild(player, "EarthSmash", loc)) { + if (GeneralMethods.isRegionProtectedFromBuild(this, location)) { remove(); return; } revert(); destination = player.getEyeLocation().clone().add(player.getEyeLocation().getDirection().normalize().multiply(shootRange)); - Vector direction = GeneralMethods.getDirection(loc, destination).normalize(); + Vector direction = GeneralMethods.getDirection(location, destination).normalize(); - List entities = GeneralMethods.getEntitiesAroundPoint(loc.clone().add(0, 2, 0), FLIGHT_DETECTION_RADIUS); + List entities = GeneralMethods.getEntitiesAroundPoint(location.clone().add(0, 2, 0), flightDetectionRadius); if (entities.size() == 0) { remove(); return; } - for (Entity entity : entities) + for (Entity entity : entities) { entity.setVelocity(direction.clone().multiply(flySpeed)); + } - //These values tend to work well when dealing with a person aiming upward or downward. - if (direction.getY() < -0.35) - loc = player.getLocation().clone().add(0, -3.2, 0); - else if (direction.getY() > 0.35) - loc = player.getLocation().clone().add(0, -1.7, 0); - else - loc = player.getLocation().clone().add(0, -2.2, 0); + // These values tend to work well when dealing with a person aiming upward or downward. + if (direction.getY() < -0.35) { + location = player.getLocation().clone().add(0, -3.2, 0); + } else if (direction.getY() > 0.35) { + location = player.getLocation().clone().add(0, -1.7, 0); + } else { + location = player.getLocation().clone().add(0, -2.2, 0); + } draw(); } - if (System.currentTimeMillis() - flightStart > flightRemove) { + if (System.currentTimeMillis() - flightStartTime > flightRemoveTimer) { remove(); return; } } } + /** + * Begins animating the EarthSmash from the ground. The lift animation + * consists of 3 steps, and each one has to design the shape in the + * ground that removes the Earthbendable material. We also need to make + * sure that there is a clear path for the EarthSmash to rise, and that + * there is enough Earthbendable material for it to be created. + */ @SuppressWarnings("deprecation") public void animateLift() { - /** - * Begins animating the EarthSmash from the ground. The lift animation - * consists of 3 steps, and each one has to design the shape in the - * ground that removes the earthbendable material. We also need to make - * sure that there is a clear path for the EarthSmash to rise, and that - * there is enough earthbendable material for it to be created. - */ - if (animCounter < 4) { + if (animationCounter < 4) { revert(); - loc.add(0, 1, 0); + location.add(0, 1, 0); //Remove the blocks underneath the rising smash - if (animCounter == 0) { + if (animationCounter == 0) { //Check all of the blocks and make sure that they can be removed AND make sure there is enough dirt int totalBendableBlocks = 0; - for (int x = -1; x <= 1; x++) - for (int y = -2; y <= -1; y++) + for (int x = -1; x <= 1; x++) { + for (int y = -2; y <= -1; y++) { for (int z = -1; z <= 1; z++) { - Block block = loc.clone().add(x, y, z).getBlock(); - if (GeneralMethods.isRegionProtectedFromBuild(player, "EarthSmash", block.getLocation())) { + Block block = location.clone().add(x, y, z).getBlock(); + if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { remove(); return; } - if (EarthMethods.isEarthbendable(player, block)) { + if (isEarthbendable(block)) { totalBendableBlocks++; } } - if (totalBendableBlocks < REQUIRED_BENDABLE_BLOCKS) { + } + } + if (totalBendableBlocks < requiredBendableBlocks) { remove(); return; } //Make sure there is a clear path upward otherwise remove for (int y = 0; y <= 3; y++) { - Block tempBlock = loc.clone().add(0, y, 0).getBlock(); - if (!EarthMethods.isTransparentToEarthbending(player, tempBlock) && tempBlock.getType() != Material.AIR) { + Block tempBlock = location.clone().add(0, y, 0).getBlock(); + if (!isTransparent(tempBlock) && tempBlock.getType() != Material.AIR) { remove(); return; } } //Design what this EarthSmash looks like by using BlockRepresenters - Location tempLoc = loc.clone().add(0, -2, 0); - for (int x = -1; x <= 1; x++) - for (int y = -1; y <= 1; y++) - for (int z = -1; z <= 1; z++) + Location tempLoc = location.clone().add(0, -2, 0); + for (int x = -1; x <= 1; x++) { + for (int y = -1; y <= 1; y++) { + for (int z = -1; z <= 1; z++) { if ((Math.abs(x) + Math.abs(y) + Math.abs(z)) % 2 == 0) { Block block = tempLoc.clone().add(x, y, z).getBlock(); - currentBlocks.add(new BlockRepresenter(x, y, z, selectMaterialForRepresenter(block), block.getData())); + currentBlocks.add(new BlockRepresenter(x, y, z, selectMaterialForRepresenter(block.getType()), block.getData())); } + } + } + } //Remove the design of the second level of removed dirt - for (int x = -1; x <= 1; x++) + for (int x = -1; x <= 1; x++) { for (int z = -1; z <= 1; z++) { if ((Math.abs(x) + Math.abs(z)) % 2 == 1) { - Block block = loc.clone().add(x, -2, z).getBlock(); - if (EarthMethods.isEarthbendable(player, block)) - EarthMethods.addTempAirBlock(block); + Block block = location.clone().add(x, -2, z).getBlock(); + if (isEarthbendable(block)) { + addTempAirBlock(block); + } } //Remove the first level of dirt - Block block = loc.clone().add(x, -1, z).getBlock(); - if (EarthMethods.isEarthbendable(player, block)) - EarthMethods.addTempAirBlock(block); - + Block block = location.clone().add(x, -1, z).getBlock(); + if (isEarthbendable(block)) { + addTempAirBlock(block); + } } + } + /* * We needed to calculate all of the blocks based on the * location being 1 above the initial bending block, however we * want to animate it starting from the original bending block. * We must readjust the location back to what it originally was. */ - loc.add(0, -1, 0); + location.add(0, -1, 0); } //Move any entities that are above the rock - List entities = GeneralMethods.getEntitiesAroundPoint(loc, 2.5); + List entities = GeneralMethods.getEntitiesAroundPoint(location, 2.5); for (Entity entity : entities) { org.bukkit.util.Vector velocity = entity.getVelocity(); entity.setVelocity(velocity.add(new Vector(0, 0.36, 0))); } - loc.getWorld().playEffect(loc, Effect.GHAST_SHOOT, 0, 7); + location.getWorld().playEffect(location, Effect.GHAST_SHOOT, 0, 7); draw(); } else { state = State.LIFTED; } - animCounter++; + animationCounter++; } + /** + * Redraws the blocks for this instance of EarthSmash. + */ public void draw() { - /** - * Redraws the blocks for this instance of EarthSmash. - */ if (currentBlocks.size() == 0) { remove(); return; } for (BlockRepresenter blockRep : currentBlocks) { - Block block = loc.clone().add(blockRep.getX(), blockRep.getY(), blockRep.getZ()).getBlock(); - if (player != null && EarthMethods.isTransparentToEarthbending(player, block)) { + Block block = location.clone().add(blockRep.getX(), blockRep.getY(), blockRep.getZ()).getBlock(); + if (player != null && isTransparent(block)) { affectedBlocks.add(new TempBlock(block, blockRep.getType(), blockRep.getData())); - EarthMethods.tempNoEarthbending.add(block); + getPreventEarthbendingBlocks().add(block); } } } @@ -399,27 +407,27 @@ public class EarthSmash { checkRemainingBlocks(); for (int i = 0; i < affectedBlocks.size(); i++) { TempBlock tblock = affectedBlocks.get(i); - EarthMethods.tempNoEarthbending.remove(tblock.getBlock()); + getPreventEarthbendingBlocks().remove(tblock.getBlock()); tblock.revertBlock(); affectedBlocks.remove(i); i--; } } + /** + * Checks to see which of the blocks are still attached to the + * EarthSmash, remember that blocks can be broken or used in other + * abilities so we need to double check and remove any that are not + * still attached. + * + * Also when we remove the blocks from instances, movedearth, or tempair + * we should do it on a delay because tempair takes a couple seconds + * before the block shows up in that map. + */ public void checkRemainingBlocks() { - /** - * Checks to see which of the blocks are still attached to the - * EarthSmash, remember that blocks can be broken or used in other - * abilities so we need to double check and remove any that are not - * still attached. - * - * Also when we remove the blocks from instances, movedearth, or tempair - * we should do it on a delay because tempair takes a couple seconds - * before the block shows up in that map. - */ for (int i = 0; i < currentBlocks.size(); i++) { BlockRepresenter brep = currentBlocks.get(i); - final Block block = loc.clone().add(brep.getX(), brep.getY(), brep.getZ()).getBlock(); + final Block block = location.clone().add(brep.getX(), brep.getY(), brep.getZ()).getBlock(); // Check for grass because sometimes the dirt turns into grass. if (block.getType() != brep.getType() && (block.getType() != Material.GRASS) && (block.getType() != Material.COBBLESTONE)) { currentBlocks.remove(i); @@ -429,140 +437,150 @@ public class EarthSmash { } public void remove() { + super.remove(); state = State.REMOVED; revert(); - instances.remove(this); } + /** + * Gets the blocks surrounding the EarthSmash's loc. This method ignores + * the blocks that should be Air, and only returns the ones that are + * dirt. + */ public List getBlocks() { - /** - * Gets the blocks surrounding the EarthSmash's loc. This method ignores - * the blocks that should be Air, and only returns the ones that are - * dirt. - */ List blocks = new ArrayList(); - for (int x = -1; x <= 1; x++) - for (int y = -1; y <= 1; y++) - for (int z = -1; z <= 1; z++) - if ((Math.abs(x) + Math.abs(y) + Math.abs(z)) % 2 == 0) //Give it the cool shape - if (loc != null) - blocks.add(loc.getWorld().getBlockAt(loc.clone().add(x, y, z))); + for (int x = -1; x <= 1; x++) { + for (int y = -1; y <= 1; y++) { + for (int z = -1; z <= 1; z++) { + if ((Math.abs(x) + Math.abs(y) + Math.abs(z)) % 2 == 0) { //Give it the cool shape + if (location != null) { + blocks.add(location.getWorld().getBlockAt(location.clone().add(x, y, z))); + } + } + } + } + } return blocks; } + /** + * Gets the blocks surrounding the EarthSmash's loc. This method returns + * all the blocks surrounding the loc, including dirt and air. + */ public List getBlocksIncludingInner() { - /** - * Gets the blocks surrounding the EarthSmash's loc. This method returns - * all the blocks surrounding the loc, including dirt and air. - */ List blocks = new ArrayList(); - for (int x = -1; x <= 1; x++) - for (int y = -1; y <= 1; y++) - for (int z = -1; z <= 1; z++) - if (loc != null) - blocks.add(loc.getWorld().getBlockAt(loc.clone().add(x, y, z))); + for (int x = -1; x <= 1; x++) { + for (int y = -1; y <= 1; y++) { + for (int z = -1; z <= 1; z++) { + if (location != null) { + blocks.add(location.getWorld().getBlockAt(location.clone().add(x, y, z))); + } + } + } + } return blocks; } - + + /** + * Switches the Sand Material and Gravel to SandStone and stone + * respectively, since gravel and sand cannot be bent due to gravity. + */ public static Material selectMaterial(Material mat) { - /** - * Switches the Sand Material and Gravel to SandStone and stone - * respectively, since gravel and sand cannot be bent due to gravity. - */ - if (mat == Material.SAND) + if (mat == Material.SAND) { return Material.SANDSTONE; - else if (mat == Material.GRAVEL) + } else if (mat == Material.GRAVEL) { return Material.STONE; - else + } else { return mat; + } } - public Material selectMaterialForRepresenter(Block block) { - Material tempMat = selectMaterial(block.getType()); + public Material selectMaterialForRepresenter(Material mat) { + Material tempMat = selectMaterial(mat); Random rand = new Random(); - if (!EarthMethods.isEarthbendable(player, block)) { + if (!isEarthbendable(tempMat) || !isMetalbendable(tempMat)) { if (currentBlocks.size() < 1) { return Material.DIRT; - } - else + } else { return currentBlocks.get(rand.nextInt(currentBlocks.size())).getType(); + } } return tempMat; } - + + /** + * Determines if a player is trying to grab an EarthSmash. A player is + * trying to grab an EarthSmash if they are staring at it and holding + * shift. + */ private EarthSmash aimingAtSmashCheck(Player player, State reqState) { - /** - * Determines if a player is trying to grab an EarthSmash. A player is - * trying to grab an EarthSmash if they are staring at it and holding - * shift. - */ - if (!ALLOW_GRAB) + if (!allowGrab) { return null; - - List blocks = GeneralMethods.getBlocksAroundPoint(GeneralMethods.getTargetedLocation(player, GRAB_DETECTION_RADIUS, GeneralMethods.nonOpaque), 1); - for (EarthSmash smash : instances) { - if (reqState == null || smash.state == reqState) + } + + List blocks = GeneralMethods.getBlocksAroundPoint(GeneralMethods.getTargetedLocation(player, grabRange, GeneralMethods.NON_OPAQUE), 1); + for (EarthSmash smash : CoreAbility.getAbilities(EarthSmash.class)) { + if (reqState == null || smash.state == reqState) { for (Block block : blocks) { - if (block == null || smash.loc == null) { - continue; - } - if (block.getLocation().getWorld() == smash.loc.getWorld() && block.getLocation().distanceSquared(smash.loc) <= Math.pow(2.5, 2)) + if (block.getLocation().getWorld() == smash.location.getWorld() + && block.getLocation().distanceSquared(smash.location) <= Math.pow(grabDetectionRadius, 2)) { return smash; + } } + } } return null; } + /** + * This method handles any collision between an EarthSmash and the + * surrounding entities, the method only applies to earthsmashes that + * have already been shot. + */ public void shootingCollisionDetection() { - /** - * This method handles any collision between an EarthSmash and the - * surrounding entities, the method only applies to earthsmashes that - * have already been shot. - */ - List entities = GeneralMethods.getEntitiesAroundPoint(loc, FLIGHT_DETECTION_RADIUS); - for (Entity entity : entities) + List entities = GeneralMethods.getEntitiesAroundPoint(location, flightDetectionRadius); + for (Entity entity : entities) { if (entity instanceof LivingEntity && entity != player && !affectedEntities.contains(entity)) { affectedEntities.add(entity); - double damage = (currentBlocks.size() / 13.0) * this.damage; + double damage = currentBlocks.size() / 13 * this.damage; GeneralMethods.damageEntity(player, entity, damage, "EarthSmash"); - Vector travelVec = GeneralMethods.getDirection(loc, entity.getLocation()); + Vector travelVec = GeneralMethods.getDirection(location, entity.getLocation()); entity.setVelocity(travelVec.setY(knockup).normalize().multiply(knockback)); } - } - - public void smashToSmashCollisionDetection() { - /** - * EarthSmash to EarthSmash collision can only happen when one of the - * Smashes have been shot by a player. If we find out that one of them - * have collided then we want to return since a smash can only remove 1 - * at a time. - */ - for (int i = 0; i < instances.size(); i++) { - EarthSmash smash = instances.get(i); - if (smash.loc != null) { - if (smash != this && smash.loc.getWorld() == loc.getWorld() && smash.loc.distanceSquared(loc) < Math.pow(FLIGHT_DETECTION_RADIUS, 2)) { - smash.remove(); - remove(); - i -= 2; - return; - } - } } } - + + /** + * EarthSmash to EarthSmash collision can only happen when one of the + * Smashes have been shot by a player. If we find out that one of them + * have collided then we want to return since a smash can only remove 1 + * at a time. + */ + public void smashToSmashCollisionDetection() { + for (EarthSmash smash : CoreAbility.getAbilities(EarthSmash.class)) { + if (smash.location != null && smash != this && smash.location.getWorld() == location.getWorld() + && smash.location.distanceSquared(location) < Math.pow(flightDetectionRadius, 2)) { + smash.remove(); + remove(); + return; + } + } + } + + /** + * Determines whether or not a player is trying to fly ontop of an + * EarthSmash. A player is considered "flying" if they are standing + * ontop of the earthsmash and holding shift. + */ private static EarthSmash flyingInSmashCheck(Player player) { - /** - * Determines whether or not a player is trying to fly ontop of an - * EarthSmash. A player is considered "flying" if they are standing - * ontop of the earthsmash and holding shift. - */ - if (!ALLOW_FLIGHT) - return null; - - for (EarthSmash smash : instances) { + for (EarthSmash smash : CoreAbility.getAbilities(EarthSmash.class)) { + if (!smash.allowFlight) { + continue; + } //Check to see if the player is standing on top of the smash. if (smash.state == State.LIFTED) { - if (smash.loc.getWorld().equals(player.getWorld()) && smash.loc.clone().add(0, 2, 0).distanceSquared(player.getLocation()) <= Math.pow(FLIGHT_DETECTION_RADIUS, 2)) { + if (smash.location.getWorld().equals(player.getWorld()) + && smash.location.clone().add(0, 2, 0).distanceSquared(player.getLocation()) <= Math.pow(smash.flightDetectionRadius, 2)) { return smash; } } @@ -570,27 +588,15 @@ public class EarthSmash { return null; } - public static void progressAll() { - for (int i = 0; i < instances.size(); i++) - instances.get(i).progress(); - } - - public static void removeAll() { - for (int i = 0; i < instances.size(); i++) { - instances.get(i).remove(); - i--; - } - } - + /** + * A BlockRepresenter is used to keep track of each of the individual + * types of blocks that are attached to an EarthSmash. Without the + * representer then an EarthSmash can only be made up of 1 material at a + * time. For example, an ESmash that is entirely dirt, coalore, or + * sandstone. Using the representer will allow all the materials to be + * mixed together. + */ public class BlockRepresenter { - /** - * A BlockRepresenter is used to keep track of each of the individual - * types of blocks that are attached to an EarthSmash. Without the - * representer then an EarthSmash can only be made up of 1 material at a - * time. For example, an ESmash that is entirely dirt, coalore, or - * sandstone. Using the representer will allow all the materials to be - * mixed together. - */ private int x, y, z; private Material type; private byte data; @@ -674,40 +680,119 @@ public class EarthSmash { } } - public Player getPlayer() { - return player; + @Override + public String getName() { + return "EarthSmash"; } - public void setPlayer(Player player) { - this.player = player; + @Override + public Location getLocation() { + return location; } + @Override public long getCooldown() { return cooldown; } - - public void setCooldown(long cooldown) { - this.cooldown = cooldown; - if (player != null) - bplayer.addCooldown("EarthSmash", cooldown); + + @Override + public boolean isSneakAbility() { + return true; } - public int getSelectRange() { - return selectRange; + @Override + public boolean isHarmlessAbility() { + return false; } - public void setSelectRange(int grabRange) { - this.selectRange = grabRange; + public boolean isAllowGrab() { + return allowGrab; } - public double getChargeTime() { + public void setAllowGrab(boolean allowGrab) { + this.allowGrab = allowGrab; + } + + public boolean isAllowFlight() { + return allowFlight; + } + + public void setAllowFlight(boolean allowFlight) { + this.allowFlight = allowFlight; + } + + public int getAnimationCounter() { + return animationCounter; + } + + public void setAnimationCounter(int animationCounter) { + this.animationCounter = animationCounter; + } + + public int getProgressCounter() { + return progressCounter; + } + + public void setProgressCounter(int progressCounter) { + this.progressCounter = progressCounter; + } + + public long getDelay() { + return delay; + } + + public void setDelay(long delay) { + this.delay = delay; + } + + public long getChargeTime() { return chargeTime; } - public void setChargeTime(double chargeTime) { + public void setChargeTime(long chargeTime) { this.chargeTime = chargeTime; } + public long getRemoveTimer() { + return removeTimer; + } + + public void setRemoveTimer(long removeTimer) { + this.removeTimer = removeTimer; + } + + public long getFlightRemoveTimer() { + return flightRemoveTimer; + } + + public void setFlightRemoveTimer(long flightRemoveTimer) { + this.flightRemoveTimer = flightRemoveTimer; + } + + public long getFlightStartTime() { + return flightStartTime; + } + + public void setFlightStartTime(long flightStartTime) { + this.flightStartTime = flightStartTime; + } + + public double getGrabRange() { + return grabRange; + } + + public void setGrabRange(double grabRange) { + this.grabRange = grabRange; + } + + public double getShootRange() { + return shootRange; + } + + public void setShootRange(double shootRange) { + this.shootRange = shootRange; + } + public double getDamage() { return damage; } @@ -740,19 +825,112 @@ public class EarthSmash { this.flySpeed = flySpeed; } - public double getShootRange() { - return shootRange; + public double getGrabbedDistance() { + return grabbedDistance; } - public void setShootRange(double shootRange) { - this.shootRange = shootRange; + public void setGrabbedDistance(double grabbedDistance) { + this.grabbedDistance = grabbedDistance; } - public long getFlightRemove() { - return flightRemove; + public State getState() { + return state; } - public void setFlightRemove(long flightRemove) { - this.flightRemove = flightRemove; + public void setState(State state) { + this.state = state; } + + public Block getOrigin() { + return origin; + } + + public void setOrigin(Block origin) { + this.origin = origin; + } + + public Location getDestination() { + return destination; + } + + public void setDestination(Location destination) { + this.destination = destination; + } + + public ArrayList getAffectedEntities() { + return affectedEntities; + } + + public ArrayList getCurrentBlocks() { + return currentBlocks; + } + + public ArrayList getAffectedBlocks() { + return affectedBlocks; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + + public int getRequiredBendableBlocks() { + return requiredBendableBlocks; + } + + public void setRequiredBendableBlocks(int requiredBendableBlocks) { + this.requiredBendableBlocks = requiredBendableBlocks; + } + + public int getMaxBlocksToPassThrough() { + return maxBlocksToPassThrough; + } + + public void setMaxBlocksToPassThrough(int maxBlocksToPassThrough) { + this.maxBlocksToPassThrough = maxBlocksToPassThrough; + } + + public long getShootAnimationCooldown() { + return shootAnimationCooldown; + } + + public void setShootAnimationCooldown(long shootAnimationCooldown) { + this.shootAnimationCooldown = shootAnimationCooldown; + } + + public long getFlightAnimationCooldown() { + return flightAnimationCooldown; + } + + public void setFlightAnimationCooldown(long flightAnimationCooldown) { + this.flightAnimationCooldown = flightAnimationCooldown; + } + + public long getLiftAnimationCooldown() { + return liftAnimationCooldown; + } + + public void setLiftAnimationCooldown(long liftAnimationCooldown) { + this.liftAnimationCooldown = liftAnimationCooldown; + } + + public double getGrabDetectionRadius() { + return grabDetectionRadius; + } + + public void setGrabDetectionRadius(double grabDetectionRadius) { + this.grabDetectionRadius = grabDetectionRadius; + } + + public double getFlightDetectionRadius() { + return flightDetectionRadius; + } + + public void setFlightDetectionRadius(double flightDetectionRadius) { + this.flightDetectionRadius = flightDetectionRadius; + } + } diff --git a/src/com/projectkorra/projectkorra/earthbending/EarthTunnel.java b/src/com/projectkorra/projectkorra/earthbending/EarthTunnel.java index 28aa8a7c..9d3f5ad8 100644 --- a/src/com/projectkorra/projectkorra/earthbending/EarthTunnel.java +++ b/src/com/projectkorra/projectkorra/earthbending/EarthTunnel.java @@ -1,7 +1,7 @@ package com.projectkorra.projectkorra.earthbending; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.EarthAbility; import org.bukkit.Location; import org.bukkit.Material; @@ -10,131 +10,122 @@ import org.bukkit.entity.Player; import org.bukkit.util.Vector; import java.util.HashSet; -import java.util.concurrent.ConcurrentHashMap; -public class EarthTunnel { - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - - private static final double MAX_RADIUS = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.EarthTunnel.MaxRadius"); - private static final double RANGE = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.EarthTunnel.Range"); - private static final double RADIUS = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.EarthTunnel.Radius"); - - private static boolean revert = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.EarthTunnel.Revert"); - private static final long INTERVAL = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.EarthTunnel.Interval"); - - private Player player; - private Block block; - private Location origin, location; - private Vector direction; - private double depth, radius, angle; - private double maxradius = MAX_RADIUS; - private double range = RANGE; - private double radiusinc = RADIUS; - private long interval = INTERVAL; +public class EarthTunnel extends EarthAbility { + + private long interval; private long time; + private long cooldown; + private double depth; + private double radius; + private double angle; + private double maxRadius; + private double range; + private double radiusIncrement; + private Block block; + private Location origin; + private Location location; + private Vector direction; public EarthTunnel(Player player) { - this.player = player; - location = player.getEyeLocation().clone(); - origin = player.getTargetBlock((HashSet) null, (int) range).getLocation(); - block = origin.getBlock(); - direction = location.getDirection().clone().normalize(); - depth = origin.distance(location) - 1; - if (depth < 0) - depth = 0; - angle = 0; - radius = radiusinc; - time = System.currentTimeMillis(); + super(player); + + this.maxRadius = getConfig().getDouble("Abilities.Earth.EarthTunnel.MaxRadius"); + this.range = getConfig().getDouble("Abilities.Earth.EarthTunnel.Range"); + this.radius = getConfig().getDouble("Abilities.Earth.EarthTunnel.Radius"); + this.interval = getConfig().getLong("Abilities.Earth.EarthTunnel.Interval"); + this.cooldown = 0; + this.radiusIncrement = radius; + this.time = System.currentTimeMillis(); + + this.location = player.getEyeLocation().clone(); + this.origin = player.getTargetBlock((HashSet) null, (int) range).getLocation(); + this.block = origin.getBlock(); + this.direction = location.getDirection().clone().normalize(); + this.depth = Math.max(0, origin.distance(location) - 1); + this.angle = 0; - instances.put(player, this); + if (!bPlayer.canBend(this)) { + return; + } + + start(); + bPlayer.addCooldown(this); } - private boolean progress() { - if (player.isDead() || !player.isOnline()) { - instances.remove(player); - return false; + @Override + public void progress() { + if (!bPlayer.canBendIgnoreCooldowns(this)) { + remove(); + return; } + if (System.currentTimeMillis() - time >= interval) { time = System.currentTimeMillis(); if (Math.abs(Math.toDegrees(player.getEyeLocation().getDirection().angle(direction))) > 20 || !player.isSneaking()) { - instances.remove(player); - return false; + remove(); + return; } else { - while (!EarthMethods.isEarthbendable(player, block)) { - if (!EarthMethods.isTransparentToEarthbending(player, block)) { - instances.remove(player); - return false; + while (!isEarthbendable(block)) { + if (!isTransparent(block)) { + remove(); + return; } + if (angle >= 360) { angle = 0; - if (radius >= maxradius) { - radius = radiusinc; + if (radius >= maxRadius) { + radius = radiusIncrement; if (depth >= range) { - instances.remove(player); - return false; + remove(); + return; } else { - depth += .5; + depth += 0.5; } } else { - radius += radiusinc; + radius += radiusIncrement; } } else { angle += 20; } + Vector vec = GeneralMethods.getOrthogonalVector(direction, angle, radius); block = location.clone().add(direction.clone().normalize().multiply(depth)).add(vec).getBlock(); } - if (revert) { - EarthMethods.addTempAirBlock(block); + if (isEarthRevertOn()) { + addTempAirBlock(block); } else { block.breakNaturally(); } - - return true; + return; } - } else { - return false; } } - public static void progressAll() { - for (Player player : instances.keySet()) { - instances.get(player).progress(); - } + @Override + public String getName() { + return "EarthTunnel"; } - public static String getDescription() { - return "Earth Tunnel is a completely utility ability for earthbenders. " + "To use, simply sneak (default: shift) in the direction you want to tunnel. " + "You will slowly begin tunneling in the direction you're facing for as long as you " + "sneak or if the tunnel has been dug long enough. This ability will be interupted " + "if it hits a block that cannot be earthbent."; + @Override + public Location getLocation() { + return location; } - public Player getPlayer() { - return player; + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; } - public double getMaxradius() { - return maxradius; - } - - public void setMaxradius(double maxradius) { - this.maxradius = maxradius; - } - - public double getRange() { - return range; - } - - public void setRange(double range) { - this.range = range; - } - - public double getRadiusinc() { - return radiusinc; - } - - public void setRadiusinc(double radiusinc) { - this.radiusinc = radiusinc; + @Override + public boolean isHarmlessAbility() { + return false; } public long getInterval() { @@ -145,4 +136,92 @@ public class EarthTunnel { this.interval = interval; } + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public double getDepth() { + return depth; + } + + public void setDepth(double depth) { + this.depth = depth; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getAngle() { + return angle; + } + + public void setAngle(double angle) { + this.angle = angle; + } + + public double getMaxRadius() { + return maxRadius; + } + + public void setMaxRadius(double maxRadius) { + this.maxRadius = maxRadius; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getRadiusIncrement() { + return radiusIncrement; + } + + public void setRadiusIncrement(double radiusIncrement) { + this.radiusIncrement = radiusIncrement; + } + + public Block getBlock() { + return block; + } + + public void setBlock(Block block) { + this.block = block; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + } diff --git a/src/com/projectkorra/projectkorra/earthbending/EarthWall.java b/src/com/projectkorra/projectkorra/earthbending/EarthWall.java deleted file mode 100644 index 132e0888..00000000 --- a/src/com/projectkorra/projectkorra/earthbending/EarthWall.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.projectkorra.projectkorra.earthbending; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.ClickType; - -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -public class EarthWall { - - private static final int defaultheight = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.RaiseEarth.Wall.Height"); - private static final int defaulthalfwidth = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.RaiseEarth.Wall.Width") / 2; - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.RaiseEarth.SelectRange"); - private static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.RaiseEarth.DynamicSourcing.Enabled"); - - private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.RaiseEarth.Cooldown"); - private int height = defaultheight; - private int halfwidth = defaulthalfwidth; - - public EarthWall(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (bPlayer.isOnCooldown("RaiseEarth")) - return; - - if (AvatarState.isAvatarState(player)) { - height = (int) (2. / 5. * (double) AvatarState.getValue(height)); - halfwidth = AvatarState.getValue(halfwidth); - } - - Vector direction = player.getEyeLocation().getDirection().normalize(); - - double ox, oy, oz; - ox = -direction.getZ(); - oy = 0; - oz = direction.getX(); - - Vector orth = new Vector(ox, oy, oz); - orth = orth.normalize(); - Block sblock = BlockSource.getEarthSourceBlock(player, selectRange, selectRange, ClickType.SHIFT_DOWN, false, dynamic, true, EarthMethods.canSandbend(player), EarthMethods.canMetalbend(player)); - if (sblock != null) { - Location origin = sblock.getLocation(); - World world = origin.getWorld(); - - boolean cd = false; - - for (int i = -halfwidth; i <= halfwidth; i++) { - Block block = world.getBlockAt(origin.clone().add(orth.clone().multiply((double) i))); - // if (block.getType() == Material.AIR || block.isLiquid()) { - if (EarthMethods.isTransparentToEarthbending(player, block)) { - for (int j = 1; j < height; j++) { - block = block.getRelative(BlockFace.DOWN); - if (EarthMethods.isEarthbendable(player, block)) { - cd = true; - new EarthColumn(player, block.getLocation(), height); - // } else if (block.getType() != Material.AIR - // && !block.isLiquid()) { - } else if (!EarthMethods.isTransparentToEarthbending(player, block)) { - break; - } - } - } else if (EarthMethods.isEarthbendable(player, block.getRelative(BlockFace.UP))) { - for (int j = 1; j < height; j++) { - block = block.getRelative(BlockFace.UP); - // if (block.getType() == Material.AIR || block.isLiquid()) - // { - if (EarthMethods.isTransparentToEarthbending(player, block)) { - cd = true; - new EarthColumn(player, block.getRelative(BlockFace.DOWN).getLocation(), height); - } else if (!EarthMethods.isEarthbendable(player, block)) { - break; - } - } - } else if (EarthMethods.isEarthbendable(player, block)) { - cd = true; - new EarthColumn(player, block.getLocation(), height); - } - } - - if (cd) - bPlayer.addCooldown("RaiseEarth", cooldown); - } else { - return; - } - } - -} diff --git a/src/com/projectkorra/projectkorra/earthbending/EarthbendingManager.java b/src/com/projectkorra/projectkorra/earthbending/EarthbendingManager.java index 2e423754..37b657e9 100644 --- a/src/com/projectkorra/projectkorra/earthbending/EarthbendingManager.java +++ b/src/com/projectkorra/projectkorra/earthbending/EarthbendingManager.java @@ -18,18 +18,6 @@ public class EarthbendingManager implements Runnable { EarthPassive.handleMetalPassives(); EarthPassive.sandSpeed(); RevertChecker.revertEarthBlocks(); - EarthTunnel.progressAll(); - EarthArmor.moveArmorAll(); - Catapult.progressAll(); Tremorsense.manage(Bukkit.getServer()); - EarthColumn.progressAll(); - CompactColumn.progressAll(); - Shockwave.progressAll(); - EarthBlast.progressAll(); - MetalClips.progressAll(); - LavaSurge.progressAll(); - LavaFlow.progressAll(); - EarthSmash.progressAll(); - SandSpout.spoutAll(); } } diff --git a/src/com/projectkorra/projectkorra/earthbending/Extraction.java b/src/com/projectkorra/projectkorra/earthbending/Extraction.java index 2fb251d5..a6f7dc6c 100644 --- a/src/com/projectkorra/projectkorra/earthbending/Extraction.java +++ b/src/com/projectkorra/projectkorra/earthbending/Extraction.java @@ -1,9 +1,9 @@ package com.projectkorra.projectkorra.earthbending; -import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.EarthAbility; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -12,43 +12,52 @@ import org.bukkit.inventory.ItemStack; import java.util.HashSet; import java.util.Random; -public class Extraction { - - private long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.Extraction.Cooldown"); - private static int doublechance = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.Extraction.DoubleLootChance"); - private static int triplechance = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.Extraction.TripleLootChance"); +public class Extraction extends EarthAbility { + private int doubleChance; + private int tripleChance; + private int range; + private long cooldown; + private Block originBlock; + public Extraction(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("Extraction")) - return; - - Block block = player.getTargetBlock((HashSet) null, 5); - if (block == null) { + super(player); + + this.doubleChance = getConfig().getInt("Abilities.Earth.Extraction.DoubleLootChance"); + this.tripleChance = getConfig().getInt("Abilities.Earth.Extraction.TripleLootChance"); + this.cooldown = getConfig().getLong("Abilities.Earth.Extraction.Cooldown"); + this.range = 5; + + if (!bPlayer.canBend(this)) { return; } - if (!GeneralMethods.isRegionProtectedFromBuild(player, "Extraction", block.getLocation())) { - if (EarthMethods.canMetalbend(player) && GeneralMethods.canBend(player.getName(), "Extraction")) { + + originBlock = player.getTargetBlock((HashSet) null, range); + if (originBlock == null) { + return; + } + if (!GeneralMethods.isRegionProtectedFromBuild(this, originBlock.getLocation())) { + if (bPlayer.canMetalbend() && bPlayer.canBend(this)) { Material type = null; - switch (block.getType()) { + switch (originBlock.getType()) { case IRON_ORE: - block.setType(Material.STONE); + originBlock.setType(Material.STONE); player.getWorld().dropItem(player.getLocation(), new ItemStack(Material.IRON_INGOT, getAmount())); type = Material.STONE; break; case GOLD_ORE: - block.setType(Material.STONE); + originBlock.setType(Material.STONE); player.getWorld().dropItem(player.getLocation(), new ItemStack(Material.GOLD_INGOT, getAmount())); type = Material.STONE; break; case QUARTZ_ORE: - block.setType(Material.NETHERRACK); + originBlock.setType(Material.NETHERRACK); player.getWorld().dropItem(player.getLocation(), new ItemStack(Material.QUARTZ, getAmount())); type = Material.NETHERRACK; break; default: - break; // shouldn't happen. + break; } if (type != null) { @@ -57,13 +66,15 @@ public class Extraction { * otherwise players can use RaiseEarth > Extraction > * Collapse to dupe the material from the block. */ - if (EarthMethods.movedearth.containsKey(block)) { - EarthMethods.movedearth.remove(block); + if (getMovedEarth().containsKey(originBlock)) { + getMovedEarth().remove(originBlock); } } - EarthMethods.playMetalbendingSound(block.getLocation()); - bPlayer.addCooldown("Extraction", cooldown); + playMetalbendingSound(originBlock.getLocation()); + start(); + bPlayer.addCooldown(this); + remove(); } } @@ -71,7 +82,76 @@ public class Extraction { private int getAmount() { Random rand = new Random(); - return rand.nextInt(99) + 1 <= triplechance ? 3 : rand.nextInt(99) + 1 <= doublechance ? 2 : 1; + return rand.nextInt(99) + 1 <= tripleChance ? 3 : rand.nextInt(99) + 1 <= doubleChance ? 2 : 1; } + @Override + public String getName() { + return "Extraction"; + } + + @Override + public void progress() {} + + @Override + public Location getLocation() { + if (originBlock != null) { + return originBlock.getLocation(); + } else if (player != null) { + return player.getLocation(); + } + return null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public int getDoubleChance() { + return doubleChance; + } + + public void setDoubleChance(int doubleChance) { + this.doubleChance = doubleChance; + } + + public int getTripleChance() { + return tripleChance; + } + + public void setTripleChance(int tripleChance) { + this.tripleChance = tripleChance; + } + + public int getRange() { + return range; + } + + public void setRange(int range) { + this.range = range; + } + + public Block getOriginBlock() { + return originBlock; + } + + public void setOriginBlock(Block originBlock) { + this.originBlock = originBlock; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/earthbending/LavaFlow.java b/src/com/projectkorra/projectkorra/earthbending/LavaFlow.java index 80a9cdb5..28593210 100644 --- a/src/com/projectkorra/projectkorra/earthbending/LavaFlow.java +++ b/src/com/projectkorra/projectkorra/earthbending/LavaFlow.java @@ -1,9 +1,10 @@ package com.projectkorra.projectkorra.earthbending; -import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.LavaAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; import com.projectkorra.projectkorra.util.BlockSource; import com.projectkorra.projectkorra.util.ClickType; import com.projectkorra.projectkorra.util.ParticleEffect; @@ -16,76 +17,52 @@ import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import java.util.ArrayList; +import java.util.Random; -public class LavaFlow { +public class LavaFlow extends LavaAbility { + public static enum AbilityType { SHIFT, CLICK } - /** The material that lava will be converted into **/ - public static final Material REVERT_MATERIAL = Material.STONE; - /** A list of every instance of this ability **/ - public static final ArrayList instances = new ArrayList(); - /** The temporary lava blocks that have been created by every LavaFlow **/ - public static final ArrayList TEMP_LAVA_BLOCKS = new ArrayList(); - /** The temporary land blocks that have been created by every LavaFlow **/ - public static final ArrayList TEMP_LAND_BLOCKS = new ArrayList(); + private static final Material REVERT_MATERIAL = Material.STONE; + private static final ArrayList TEMP_LAVA_BLOCKS = new ArrayList(); + private static final ArrayList TEMP_LAND_BLOCKS = new ArrayList(); - public static final long SHIFT_COOLDOWN = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.LavaFlow.ShiftCooldown"); - public static final long CLICK_LAVA_DELAY = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.LavaFlow.ClickLavaStartDelay"); - public static final long CLICK_LAND_DELAY = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.LavaFlow.ClickLandStartDelay"); - public static final long CLICK_LAVA_COOLDOWN = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.LavaFlow.ClickLavaCooldown"); - public static final long CLICK_LAND_COOLDOWN = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.LavaFlow.ClickLandCooldown"); - public static final long CLICK_LAVA_CLEANUP_DELAY = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.LavaFlow.ClickLavaCleanupDelay"); - public static final long CLICK_LAND_CLEANUP_DELAY = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.LavaFlow.ClickLandCleanupDelay"); - public static final long SHIFT_REMOVE_DELAY = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.LavaFlow.ShiftCleanupDelay"); - - public static final int CLICK_RANGE = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.LavaFlow.ClickRange"); - public static final double CLICK_LAVA_RADIUS = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.LavaFlow.ClickRadius"); - public static final double CLICK_LAND_RADIUS = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.LavaFlow.ClickRadius"); - public static final double SHIFT_PLATFORM_RADIUS = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.LavaFlow.ShiftPlatformRadius"); - public static final double SHIFT_MAX_RADIUS = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.LavaFlow.ShiftRadius"); - public static final double SHIFT_REMOVE_SPEED = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.LavaFlow.ShiftRemoveSpeed"); - public static final double LAVA_CREATE_SPEED = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.LavaFlow.ClickLavaCreateSpeed"); - public static final double LAND_CREATE_SPEED = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.LavaFlow.ClickLandCreateSpeed"); - public static final double SHIFT_FLOW_SPEED = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.LavaFlow.ShiftFlowSpeed"); - - private static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.LavaFlow.DynamicSourcing.Enabled"); - - public static final int UPWARD_FLOW = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.LavaFlow.UpwardFlow"); - public static final int DOWNWARD_FLOW = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.LavaFlow.DownwardFlow"); - public static final boolean ALLOW_NATURAL_FLOW = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.LavaFlow.AllowNaturalFlow"); - public static final double PARTICLE_DENSITY = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.LavaFlow.ParticleDensity"); - private static final double PARTICLE_OFFSET = 3; - - private Player player; - private BendingPlayer bplayer; - private long time; - private int shiftCounter; private boolean removing; private boolean makeLava; private boolean clickIsFinished; - private double currentRadius; - - private double shiftPlatformRadius, shiftMaxRadius; - private double shiftFlowSpeed, shiftRemoveSpeed, shiftRemoveDelay; - private double particleDensity; - private double clickLavaRadius, clickLandRadius; - private long clickLavaDelay, clickLandDelay, clickLavaCooldown, clickLandCooldown, - shiftCooldown; - private long clickLavaCleanupDelay, clickLandCleanupDelay; - private double lavaCreateSpeed, landCreateSpeed; - private int upwardFlow, downwardFlow; private boolean shiftIsFinished; private boolean allowNaturalFlow; - private int clickRange; + private int shiftCounter; + private int upwardFlow; + private int downwardFlow; + private long time; + private long clickLavaDelay; + private long clickLandDelay; + private long clickLavaCooldown; + private long clickLandCooldown; + private long shiftCooldown; + private long clickLavaCleanupDelay; + private long clickLandCleanupDelay; + private double particleDensity; + private double particleOffset; + private double currentRadius; + private double shiftPlatformRadius; + private double shiftMaxRadius; + private double shiftFlowSpeed; + private double shiftRemoveSpeed; + private double shiftRemoveDelay; + private double clickRange; + private double clickLavaRadius; + private double clickLandRadius; + private double lavaCreateSpeed; + private double landCreateSpeed; private AbilityType type; private Location origin; - - /** All of the blocks that have been modified by this ability **/ private ArrayList affectedBlocks; private ArrayList tasks; - + /** * Creates a new LavaFlow ability and initializes all of the variables and * cooldowns. The ability is not guaranteed to continue, it may be the case @@ -96,45 +73,45 @@ public class LavaFlow { * @param type either shift or sneak */ public LavaFlow(Player player, AbilityType type) { - if (!EarthMethods.canLavabend(player)) + super(player); + if (!bPlayer.canLavabend()) { return; + } - time = System.currentTimeMillis(); - this.player = player; + this.time = System.currentTimeMillis(); this.type = type; - bplayer = GeneralMethods.getBendingPlayer(player.getName()); + this.shiftCounter = 0; + this.currentRadius = 0; + this.particleOffset = 3; + this.removing = false; + this.makeLava = true; + this.clickIsFinished = false; + this.affectedBlocks = new ArrayList(); + this.tasks = new ArrayList(); - shiftCounter = 0; - currentRadius = 0; - removing = false; - makeLava = true; - clickIsFinished = false; - affectedBlocks = new ArrayList(); - tasks = new ArrayList(); + this.shiftCooldown = getConfig().getLong("Abilities.Earth.LavaFlow.ShiftCooldown"); + this.shiftPlatformRadius = getConfig().getDouble("Abilities.Earth.LavaFlow.ShiftPlatformRadius"); + this.shiftMaxRadius = getConfig().getDouble("Abilities.Earth.LavaFlow.ShiftRadius"); + this.shiftFlowSpeed = getConfig().getDouble("Abilities.Earth.LavaFlow.ShiftFlowSpeed"); + this.shiftRemoveSpeed = getConfig().getDouble("Abilities.Earth.LavaFlow.ShiftRemoveSpeed"); + this.shiftRemoveDelay = getConfig().getLong("Abilities.Earth.LavaFlow.ShiftCleanupDelay"); + this.particleDensity = getConfig().getDouble("Abilities.Earth.LavaFlow.ParticleDensity"); + this.clickRange = getConfig().getDouble("Abilities.Earth.LavaFlow.ClickRange"); + this.clickLavaRadius = getConfig().getDouble("Abilities.Earth.LavaFlow.ClickRadius"); + this.clickLandRadius = getConfig().getDouble("Abilities.Earth.LavaFlow.ClickRadius"); + this.clickLavaDelay = getConfig().getLong("Abilities.Earth.LavaFlow.ClickLavaStartDelay"); + this.clickLandDelay = getConfig().getLong("Abilities.Earth.LavaFlow.ClickLandStartDelay"); + this.clickLavaCooldown = getConfig().getLong("Abilities.Earth.LavaFlow.ClickLavaCooldown"); + this.clickLandCooldown = getConfig().getLong("Abilities.Earth.LavaFlow.ClickLandCooldown"); + this.clickLavaCleanupDelay = getConfig().getLong("Abilities.Earth.LavaFlow.ClickLavaCleanupDelay"); + this.clickLandCleanupDelay = getConfig().getLong("Abilities.Earth.LavaFlow.ClickLandCleanupDelay"); + this.lavaCreateSpeed = getConfig().getDouble("Abilities.Earth.LavaFlow.ClickLavaCreateSpeed"); + this.landCreateSpeed = getConfig().getDouble("Abilities.Earth.LavaFlow.ClickLandCreateSpeed"); + this.upwardFlow = getConfig().getInt("Abilities.Earth.LavaFlow.UpwardFlow"); + this.downwardFlow = getConfig().getInt("Abilities.Earth.LavaFlow.DownwardFlow"); + this.allowNaturalFlow = getConfig().getBoolean("Abilities.Earth.LavaFlow.AllowNaturalFlow"); - shiftCooldown = SHIFT_COOLDOWN; - shiftPlatformRadius = SHIFT_PLATFORM_RADIUS; - shiftMaxRadius = SHIFT_MAX_RADIUS; - shiftFlowSpeed = SHIFT_FLOW_SPEED; - shiftRemoveSpeed = SHIFT_REMOVE_SPEED; - shiftRemoveDelay = SHIFT_REMOVE_DELAY; - particleDensity = PARTICLE_DENSITY; - clickRange = CLICK_RANGE; - clickLavaRadius = CLICK_LAVA_RADIUS; - clickLandRadius = CLICK_LAND_RADIUS; - clickLavaDelay = CLICK_LAVA_DELAY; - clickLandDelay = CLICK_LAND_DELAY; - clickLavaCooldown = CLICK_LAVA_COOLDOWN; - clickLandCooldown = CLICK_LAND_COOLDOWN; - clickLavaCleanupDelay = CLICK_LAVA_CLEANUP_DELAY; - clickLandCleanupDelay = CLICK_LAND_CLEANUP_DELAY; - lavaCreateSpeed = LAVA_CREATE_SPEED; - landCreateSpeed = LAND_CREATE_SPEED; - upwardFlow = UPWARD_FLOW; - downwardFlow = DOWNWARD_FLOW; - allowNaturalFlow = ALLOW_NATURAL_FLOW; - - if (AvatarState.isAvatarState(player)) { + if (bPlayer.isAvatarState()) { shiftCooldown = 0; clickLavaCooldown = 0; clickLandCooldown = 0; @@ -157,42 +134,45 @@ public class LavaFlow { // Update the shift counter for all the player's LavaFlows ArrayList shiftFlows = LavaFlow.getLavaFlow(player, LavaFlow.AbilityType.SHIFT); if (shiftFlows.size() > 0 && !player.isSneaking()) { - for (LavaFlow lf : shiftFlows) { - lf.shiftCounter++; + for (LavaFlow lavaFlow : shiftFlows) { + lavaFlow.shiftCounter++; } } - if (bplayer.isOnCooldown("lavaflowshift")) { + if (bPlayer.isOnCooldown("lavaflowshift")) { remove(); return; } - instances.add(this); + start(); } else if (type == AbilityType.CLICK) { - Block sourceBlock = BlockSource.getEarthOrLavaSourceBlock(player, clickRange, clickRange, ClickType.CLICK, false, dynamic, true, EarthMethods.canSandbend(player), EarthMethods.canMetalbend(player)); + Block sourceBlock = BlockSource.getEarthOrLavaSourceBlock(player, clickRange, ClickType.LEFT_CLICK); if (sourceBlock == null) { remove(); return; } + + long cooldown = makeLava ? clickLavaCooldown : clickLandCooldown; origin = sourceBlock.getLocation(); makeLava = !isLava(sourceBlock); - long cooldown = makeLava ? clickLavaCooldown : clickLandCooldown; if (makeLava) { - if (bplayer.isOnCooldown("lavaflowmakelava")) { + if (bPlayer.isOnCooldown("lavaflowmakelava")) { remove(); return; - } else - bplayer.addCooldown("lavaflowmakelava", cooldown); + } else { + bPlayer.addCooldown("lavaflowmakelava", cooldown); + } } if (!makeLava) { - if (bplayer.isOnCooldown("lavaflowmakeland")) { + if (bPlayer.isOnCooldown("lavaflowmakeland")) { remove(); return; - } else - bplayer.addCooldown("lavaflowmakeland", cooldown); + } else { + bPlayer.addCooldown("lavaflowmakeland", cooldown); + } } - instances.add(this); + start(); } } @@ -201,17 +181,20 @@ public class LavaFlow { * determines whether or not the LavaFlow type is Click/Sneaking, and it * will remove the ability if any issues arise. */ + @Override public void progress() { if (shiftCounter > 0 && type == AbilityType.SHIFT) { remove(); return; - } else if (removing) + } else if (removing) { return; - else if (player.isDead() || !player.isOnline()) { + } else if (player.isDead() || !player.isOnline()) { remove(); return; } + Random random = new Random(); + if (type == AbilityType.SHIFT) { if (System.currentTimeMillis() - time > shiftRemoveDelay) { remove(); @@ -221,49 +204,49 @@ public class LavaFlow { if (affectedBlocks.size() > 0) { removeOnDelay(); removing = true; - bplayer.addCooldown("lavaflowshift", shiftCooldown); - } else + bPlayer.addCooldown("lavaflowshift", shiftCooldown); + } else { remove(); + } return; } - String ability = GeneralMethods.getBoundAbility(player); - if (ability == null) { - remove(); - return; - } else if (!ability.equalsIgnoreCase("LavaFlow") || !GeneralMethods.canBend(player.getName(), "LavaFlow")) { + if (!bPlayer.canBendIgnoreCooldowns(this)) { remove(); return; } else if (origin == null) { origin = player.getLocation().clone().add(0, -1, 0); - if (!EarthMethods.isEarthbendable(player, origin.getBlock()) && origin.getBlock().getType() != Material.GLOWSTONE) { + if (!isEarthbendable(origin.getBlock()) && origin.getBlock().getType() != Material.GLOWSTONE) { remove(); return; } } - for (double x = -currentRadius; x <= currentRadius + PARTICLE_OFFSET; x++) { - for (double z = -currentRadius; z < currentRadius + PARTICLE_OFFSET; z++) { + for (double x = -currentRadius; x <= currentRadius + particleOffset; x++) { + for (double z = -currentRadius; z < currentRadius + particleOffset; z++) { Location loc = origin.clone().add(x, 0, z); Block block = GeneralMethods.getTopBlock(loc, upwardFlow, downwardFlow); - if (block == null) + if (block == null) { continue; + } double dSquared = distanceSquaredXZ(block.getLocation(), origin); if (!isLava(block) && dSquared > Math.pow(shiftPlatformRadius, 2)) { - if (dSquared < Math.pow(currentRadius, 2) && !GeneralMethods.isRegionProtectedFromBuild(player, "LavaFlow", block.getLocation())) { - if (dSquared < shiftPlatformRadius * 4 || getAdjacentLavaBlocks(block.getLocation()).size() > 0) + if (dSquared < Math.pow(currentRadius, 2) && !GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + if (dSquared < shiftPlatformRadius * 4 || getAdjacentLavaBlocks(block.getLocation()).size() > 0) { createLava(block); - } else if (Math.random() < particleDensity && dSquared < Math.pow(currentRadius + particleDensity, 2) && currentRadius + particleDensity < shiftMaxRadius) { - if (GeneralMethods.rand.nextInt(3) == 0) { - ParticleEffect.LAVA.display(loc, (float) Math.random(), (float) Math.random(), (float) Math.random(), 0, 1); } + } else if (Math.random() < particleDensity + && dSquared < Math.pow(currentRadius + particleDensity, 2) + && currentRadius + particleDensity < shiftMaxRadius + && random.nextInt(3) == 0) { + ParticleEffect.LAVA.display(loc, (float) Math.random(), (float) Math.random(), (float) Math.random(), 0, 1); } } } if(!shiftIsFinished) { - if (GeneralMethods.rand.nextInt(10) == 0) { + if (random.nextInt(10) == 0) { ParticleEffect.LAVA.display(player.getLocation(), (float) Math.random(), (float) Math.random(), (float) Math.random(), 0, 1); } } @@ -274,38 +257,40 @@ public class LavaFlow { shiftIsFinished = true; } } - } - - /* - * The variable makeLava refers to whether or not the ability is trying - * to remove land in place of lava or if makeLava = false then lava is - * being replaced with land. - * - * Notice we have separate variables between both versions, because most - * of the time making lava will have longer delays and longer cooldowns. - */ - else if (type == AbilityType.CLICK) { + } else if (type == AbilityType.CLICK) { + /* + * The variable makeLava refers to whether or not the ability is trying + * to remove land in place of lava or if makeLava = false then lava is + * being replaced with land. + * + * Notice we have separate variables between both versions, because most + * of the time making lava will have longer delays and longer cooldowns. + */ long curTime = System.currentTimeMillis() - time; double delay = makeLava ? clickLavaDelay : clickLandDelay; + if (makeLava && curTime > clickLavaCleanupDelay) { remove(); return; } else if (!makeLava && curTime > clickLandCleanupDelay) { remove(); return; - } else if (!makeLava && curTime < delay) + } else if (!makeLava && curTime < delay) { return; - else if (makeLava && curTime < delay) { - for (double x = -clickLavaRadius; x <= clickLavaRadius; x++) + } else if (makeLava && curTime < delay) { + for (double x = -clickLavaRadius; x <= clickLavaRadius; x++) { for (double z = -clickLavaRadius; z <= clickLavaRadius; z++) { Location loc = origin.clone().add(x, 0, z); Block tempBlock = GeneralMethods.getTopBlock(loc, upwardFlow, downwardFlow); - if (tempBlock != null && !isLava(tempBlock) && Math.random() < PARTICLE_DENSITY && tempBlock.getLocation().distanceSquared(origin) <= Math.pow(clickLavaRadius, 2)) { - if (GeneralMethods.rand.nextInt(3) == 0) { + + if (tempBlock != null && !isLava(tempBlock) && Math.random() < particleDensity + && tempBlock.getLocation().distanceSquared(origin) <= Math.pow(clickLavaRadius, 2)) { + if (random.nextInt(3) == 0) { ParticleEffect.LAVA.display(loc, (float) Math.random(), (float) Math.random(), (float) Math.random(), 0, 1); } } } + } return; } @@ -317,34 +302,37 @@ public class LavaFlow { if (!clickIsFinished) { clickIsFinished = true; double radius = makeLava ? clickLavaRadius : clickLandRadius; - for (double x = -radius; x <= radius; x++) + + for (double x = -radius; x <= radius; x++) { for (double z = -radius; z <= radius; z++) { Location loc = origin.clone().add(x, 0, z); Block tempBlock = GeneralMethods.getTopBlock(loc, upwardFlow, downwardFlow); - if (tempBlock == null) + if (tempBlock == null) { continue; + } double dSquared = distanceSquaredXZ(tempBlock.getLocation(), origin); - if (dSquared < Math.pow(radius, 2) && !GeneralMethods.isRegionProtectedFromBuild(player, "LavaFlow", loc)) { + if (dSquared < Math.pow(radius, 2) && !GeneralMethods.isRegionProtectedFromBuild(this, loc)) { if (makeLava && !isLava(tempBlock)) { clickIsFinished = false; - if (Math.random() < lavaCreateSpeed) + if (Math.random() < lavaCreateSpeed) { createLava(tempBlock); - else { - if (GeneralMethods.rand.nextInt(4) == 0) { + } else { + if (random.nextInt(4) == 0) { ParticleEffect.LAVA.display(loc, (float) Math.random(), (float) Math.random(), (float) Math.random(), 0, 1); } } } else if (!makeLava && isLava(tempBlock)) { clickIsFinished = false; - if (Math.random() < landCreateSpeed) + if (Math.random() < landCreateSpeed) { removeLava(tempBlock); + } } } } + } return; } - } } @@ -358,12 +346,14 @@ public class LavaFlow { * @param block the block that will be turned to lava */ public void createLava(Block block) { - if (isEarthbendableMaterial(block.getType(), player)) { + if (isEarthbendable(block)) { TempBlock tblock = new TempBlock(block, Material.STATIONARY_LAVA, (byte) 0); TEMP_LAVA_BLOCKS.add(tblock); affectedBlocks.add(tblock); - if (allowNaturalFlow) + + if (allowNaturalFlow) { TempBlock.instances.remove(block); + } } } @@ -372,10 +362,12 @@ public class LavaFlow { * * @param testBlock the block to attempt to remove */ + @SuppressWarnings("deprecation") public void removeLava(Block testBlock) { for (int i = 0; i < TEMP_LAVA_BLOCKS.size(); i++) { TempBlock tblock = TEMP_LAVA_BLOCKS.get(i); Block block = tblock.getBlock(); + if (block.equals(testBlock)) { tblock.revertBlock(); TEMP_LAVA_BLOCKS.remove(i); @@ -383,8 +375,8 @@ public class LavaFlow { return; } } - - TempBlock tblock = new TempBlock(testBlock, REVERT_MATERIAL, (byte) 0); + + TempBlock tblock = new TempBlock(testBlock, REVERT_MATERIAL, testBlock.getData()); affectedBlocks.add(tblock); TEMP_LAND_BLOCKS.add(tblock); } @@ -396,6 +388,7 @@ public class LavaFlow { */ public void removeOnDelay() { BukkitRunnable br = new BukkitRunnable() { + @Override public void run() { remove(); } @@ -411,11 +404,13 @@ public class LavaFlow { * This version of remove will create tasks that remove each lava block with * an animation. */ + @Override public void remove() { - instances.remove(this); + super.remove(); for (int i = affectedBlocks.size() - 1; i > -1; i--) { final TempBlock tblock = affectedBlocks.get(i); new BukkitRunnable() { + @Override public void run() { tblock.revertBlock(); } @@ -431,8 +426,9 @@ public class LavaFlow { } } - for (BukkitRunnable task : tasks) + for (BukkitRunnable task : tasks) { task.cancel(); + } } /** @@ -440,7 +436,7 @@ public class LavaFlow { * block animation, it just removes everything. */ public void removeInstantly() { - instances.remove(this); + super.remove(); for (int i = affectedBlocks.size() - 1; i > -1; i--) { final TempBlock tblock = affectedBlocks.get(i); tblock.revertBlock(); @@ -454,45 +450,11 @@ public class LavaFlow { } } - for (BukkitRunnable task : tasks) + for (BukkitRunnable task : tasks) { task.cancel(); - } - - /** - * Progresses every instance of LavaFlow by 1 tick - */ - public static void progressAll() { - for (int i = instances.size() - 1; i >= 0; i--) - instances.get(i).progress(); - } - - /** - * Removes every instancce of LavaFlow without animating the block removing - * process. - */ - public static void removeAll() { - for (int i = instances.size() - 1; i >= 0; i--) { - instances.get(i).removeInstantly(); } } - - /** - * Returns an ArrayList of all the surrounding blocks for loc, but it - * excludes the block that is contained at Loc. - * - * @param loc the middle block location - * @return a list of adjacent blocks - */ - public static ArrayList getAdjacentBlocks(Location loc) { - ArrayList list = new ArrayList(); - Block block = loc.getBlock(); - for (int x = -1; x <= 1; x++) - for (int y = -1; y <= 1; y++) - for (int z = -1; z <= 1; z++) - if (!(x == 0 && y == 0 && z == 0)) - list.add(block.getLocation().add(x, y, z).getBlock()); - return list; - } + /** * Returns a list of all the Lava blocks that are adjacent to the block at @@ -501,7 +463,7 @@ public class LavaFlow { * @param loc the middle location of the adjacent blocks * @return a list of the adjacent blocks */ - public static ArrayList getAdjacentLavaBlocks(Location loc) { + public ArrayList getAdjacentLavaBlocks(Location loc) { ArrayList list = getAdjacentBlocks(loc); for (int i = 0; i < list.size(); i++) { Block block = list.get(i); @@ -514,29 +476,26 @@ public class LavaFlow { } /** - * A version of Methods.isEarthbendable that avoids using the - * isRegionProtected call since it isn't necessary in the case of just - * checking a specific material. + * Returns an ArrayList of all the surrounding blocks for loc, but it + * excludes the block that is contained at Loc. * - * @param mat The material to check - * @param player The player that is earthbending - * @return true if the material is earthbendable + * @param loc the middle block location + * @return a list of adjacent blocks */ - public static boolean isEarthbendableMaterial(Material mat, Player player) { - for (String s : ProjectKorra.plugin.getConfig().getStringList("Properties.Earth.EarthbendableBlocks")) - if (mat == Material.getMaterial(s)) - return true; - if (ProjectKorra.plugin.getConfig().getStringList("Properties.Earth.SandBlocks").contains(mat.toString()) && EarthMethods.canSandbend(player)) { - return true; + public static ArrayList getAdjacentBlocks(Location loc) { + ArrayList list = new ArrayList(); + Block block = loc.getBlock(); + + for (int x = -1; x <= 1; x++) { + for (int y = -1; y <= 1; y++) { + for (int z = -1; z <= 1; z++) { + if (!(x == 0 && y == 0 && z == 0)) { + list.add(block.getLocation().add(x, y, z).getBlock()); + } + } + } } - if (ProjectKorra.plugin.getConfig().getStringList("Properties.Earth.MetalBlocks").contains(mat.toString()) && EarthMethods.canMetalbend(player)) { - return true; - } - return false; - } - - public static boolean isLava(Block block) { - return block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA; + return list; } /** @@ -557,20 +516,6 @@ public class LavaFlow { return temp1.distanceSquared(temp2); } - /** - * Returns all the LavaFlows created by a specific player. - * - * @param player the player that created the ability instance - * @return a list of all the LavaFlows created by player - */ - public static ArrayList getLavaFlow(Player player) { - ArrayList list = new ArrayList(); - for (LavaFlow lf : instances) - if (lf.player != null && lf.player == player) - list.add(lf); - return list; - } - /** * Returns all of the LavaFlows created by a specific player but filters the * abilities based on shift or click. @@ -581,26 +526,54 @@ public class LavaFlow { */ public static ArrayList getLavaFlow(Player player, AbilityType type) { ArrayList list = new ArrayList(); - for (LavaFlow lf : instances) - if (lf.player != null && lf.player == player && lf.type != null && lf.type == type) + for (LavaFlow lf : CoreAbility.getAbilities(LavaFlow.class)) { + if (lf.player != null && lf.player == player && lf.type != null && lf.type == type) { list.add(lf); + } + } return list; } - - public Player getPlayer() { - return player; + + public static Material getRevertMaterial() { + return REVERT_MATERIAL; + } + + public static ArrayList getTempLandBlocks() { + return TEMP_LAND_BLOCKS; + } + + public static ArrayList getTempLavaBlocks() { + return TEMP_LAVA_BLOCKS; } - public void setPlayer(Player player) { - this.player = player; + @Override + public String getName() { + return "LavaFlow"; } - public long getTime() { - return time; + @Override + public Location getLocation() { + if (origin != null) { + return origin; + } else if (player != null) { + return player.getLocation(); + } + return null; } - public void setTime(long time) { - this.time = time; + @Override + public long getCooldown() { + return type == AbilityType.CLICK ? clickLandCooldown : shiftCooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; } public boolean isRemoving() { @@ -627,6 +600,126 @@ public class LavaFlow { this.clickIsFinished = clickIsFinished; } + public boolean isShiftIsFinished() { + return shiftIsFinished; + } + + public void setShiftIsFinished(boolean shiftIsFinished) { + this.shiftIsFinished = shiftIsFinished; + } + + public boolean isAllowNaturalFlow() { + return allowNaturalFlow; + } + + public void setAllowNaturalFlow(boolean allowNaturalFlow) { + this.allowNaturalFlow = allowNaturalFlow; + } + + public int getShiftCounter() { + return shiftCounter; + } + + public void setShiftCounter(int shiftCounter) { + this.shiftCounter = shiftCounter; + } + + public int getUpwardFlow() { + return upwardFlow; + } + + public void setUpwardFlow(int upwardFlow) { + this.upwardFlow = upwardFlow; + } + + public int getDownwardFlow() { + return downwardFlow; + } + + public void setDownwardFlow(int downwardFlow) { + this.downwardFlow = downwardFlow; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getClickLavaDelay() { + return clickLavaDelay; + } + + public void setClickLavaDelay(long clickLavaDelay) { + this.clickLavaDelay = clickLavaDelay; + } + + public long getClickLandDelay() { + return clickLandDelay; + } + + public void setClickLandDelay(long clickLandDelay) { + this.clickLandDelay = clickLandDelay; + } + + public long getClickLavaCooldown() { + return clickLavaCooldown; + } + + public void setClickLavaCooldown(long clickLavaCooldown) { + this.clickLavaCooldown = clickLavaCooldown; + } + + public long getClickLandCooldown() { + return clickLandCooldown; + } + + public void setClickLandCooldown(long clickLandCooldown) { + this.clickLandCooldown = clickLandCooldown; + } + + public long getShiftCooldown() { + return shiftCooldown; + } + + public void setShiftCooldown(long shiftCooldown) { + this.shiftCooldown = shiftCooldown; + } + + public long getClickLavaCleanupDelay() { + return clickLavaCleanupDelay; + } + + public void setClickLavaCleanupDelay(long clickLavaCleanupDelay) { + this.clickLavaCleanupDelay = clickLavaCleanupDelay; + } + + public long getClickLandCleanupDelay() { + return clickLandCleanupDelay; + } + + public void setClickLandCleanupDelay(long clickLandCleanupDelay) { + this.clickLandCleanupDelay = clickLandCleanupDelay; + } + + public double getParticleDensity() { + return particleDensity; + } + + public void setParticleDensity(double particleDensity) { + this.particleDensity = particleDensity; + } + + public double getParticleOffset() { + return particleOffset; + } + + public void setParticleOffset(double particleOffset) { + this.particleOffset = particleOffset; + } + public double getCurrentRadius() { return currentRadius; } @@ -675,19 +768,11 @@ public class LavaFlow { this.shiftRemoveDelay = shiftRemoveDelay; } - public double getParticleDensity() { - return particleDensity; - } - - public void setParticleDensity(double particleDensity) { - this.particleDensity = particleDensity; - } - - public int getClickRange() { + public double getClickRange() { return clickRange; } - public void setClickRange(int clickRange) { + public void setClickRange(double clickRange) { this.clickRange = clickRange; } @@ -707,68 +792,6 @@ public class LavaFlow { this.clickLandRadius = clickLandRadius; } - public long getClickLavaDelay() { - return clickLavaDelay; - } - - public void setClickLavaDelay(long clickLavaDelay) { - this.clickLavaDelay = clickLavaDelay; - } - - public long getClickLandDelay() { - return clickLandDelay; - } - - public void setClickLandDelay(long clickLandDelay) { - this.clickLandDelay = clickLandDelay; - } - - public long getClickLavaCooldown() { - return clickLavaCooldown; - } - - public void setClickLavaCooldown(long clickLavaCooldown) { - this.clickLavaCooldown = clickLavaCooldown; - if (player != null) - bplayer.addCooldown("lavaflowmakelava", clickLavaCooldown); - } - - public long getClickLandCooldown() { - return clickLandCooldown; - } - - public void setClickLandCooldown(long clickLandCooldown) { - this.clickLandCooldown = clickLandCooldown; - if (player != null) - bplayer.addCooldown("lavaflowmakeland", clickLandCooldown); - } - - public long getShiftCooldown() { - return shiftCooldown; - } - - public void setShiftCooldown(long shiftCooldown) { - this.shiftCooldown = shiftCooldown; - if (player != null) - bplayer.addCooldown("lavaflowshift", shiftCooldown); - } - - public long getClickLavaCleanupDelay() { - return clickLavaCleanupDelay; - } - - public void setClickLavaCleanupDelay(long clickLavaCleanupDelay) { - this.clickLavaCleanupDelay = clickLavaCleanupDelay; - } - - public long getClickLandCleanupDelay() { - return clickLandCleanupDelay; - } - - public void setClickLandCleanupDelay(long clickLandCleanupDelay) { - this.clickLandCleanupDelay = clickLandCleanupDelay; - } - public double getLavaCreateSpeed() { return lavaCreateSpeed; } @@ -785,30 +808,6 @@ public class LavaFlow { this.landCreateSpeed = landCreateSpeed; } - public int getUpwardFlow() { - return upwardFlow; - } - - public void setUpwardFlow(int upwardFlow) { - this.upwardFlow = upwardFlow; - } - - public int getDownwardFlow() { - return downwardFlow; - } - - public void setDownwardFlow(int downwardFlow) { - this.downwardFlow = downwardFlow; - } - - public boolean isAllowNaturalFlow() { - return allowNaturalFlow; - } - - public void setAllowNaturalFlow(boolean allowNaturalFlow) { - this.allowNaturalFlow = allowNaturalFlow; - } - public AbilityType getType() { return type; } @@ -829,23 +828,8 @@ public class LavaFlow { return affectedBlocks; } - public void setAffectedBlocks(ArrayList affectedBlocks) { - this.affectedBlocks = affectedBlocks; - } - public ArrayList getTasks() { return tasks; } - - public void setTasks(ArrayList tasks) { - this.tasks = tasks; - } - - public int getShiftCounter() { - return shiftCounter; - } - - public void setShiftCounter(int shiftCounter) { - this.shiftCounter = shiftCounter; - } + } diff --git a/src/com/projectkorra/projectkorra/earthbending/LavaSurge.java b/src/com/projectkorra/projectkorra/earthbending/LavaSurge.java index e2db54ba..e68a8817 100644 --- a/src/com/projectkorra/projectkorra/earthbending/LavaSurge.java +++ b/src/com/projectkorra/projectkorra/earthbending/LavaSurge.java @@ -1,8 +1,8 @@ package com.projectkorra.projectkorra.earthbending; -import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.LavaAbility; import com.projectkorra.projectkorra.util.BlockSource; import com.projectkorra.projectkorra.util.ClickType; import com.projectkorra.projectkorra.util.ParticleEffect; @@ -19,104 +19,94 @@ import org.bukkit.entity.Player; import org.bukkit.util.Vector; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.ListIterator; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; -public class LavaSurge { - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - public static int impactDamage = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.LavaSurge.Damage"); - public static int cooldown = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.LavaSurge.Cooldown"); - public static int fractureRadius = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.LavaSurge.FractureRadius"); - public static int prepareRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.LavaSurge.PrepareRange"); - public static int travelRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.LavaSurge.TravelRange"); - public static int maxBlocks = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.LavaSurge.MaxLavaWaves"); - public static boolean canSourceBeEarth = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.LavaSurge.SourceCanBeEarth"); - private static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.LavaSurge.DynamicSourcing.Enabled"); - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.LavaSurge.SelectRange"); - public static List falling = new ArrayList(); - public static int particleInterval = 100; - public static int fallingBlockInterval = 100; +public class LavaSurge extends LavaAbility { - private Player player; - private Block sourceBlock; - private long lastTime; + private static final HashSet ALL_FALLING_BLOCKS = new HashSet<>(); + + private boolean hasSurgeStarted; + private boolean isFractureOpen; + private boolean canSourceBeEarth; + private int fallingBlocksCount; + private int maxBlocks; + private int particleInterval; + private int fallingBlockInterval; private long time; - private int fallingBlocksCount = 0; - private boolean surgeStarted = false; - private boolean fractureOpen; - private Random randy = new Random(); + private long lastTime; + private long cooldown; + private double impactDamage; + private double fractureRadius; + private double prepareRange; + private double travelRange; + private Block sourceBlock; + private Random random; private Vector direction; private Location startLocation; - //private Location currentLocation; // Unused. - private List fblocks = new ArrayList(); - private List fracture = new ArrayList(); - private List fracturetb = new ArrayList(); - private List movingLava = new ArrayList(); - private ConcurrentHashMap lava = new ConcurrentHashMap(); - private ListIterator li; + private ArrayList fallingBlocks; + private ArrayList fracture; + private ArrayList fractureTempBlocks; + private ArrayList movingLava; + private ConcurrentHashMap lavaBlocks; + private ListIterator listIterator; - public LavaSurge(Player player) - { - this.player = player; + public LavaSurge(Player player) { + super(player); - if(!isEligible()) + this.impactDamage = getConfig().getInt("Abilities.Earth.LavaSurge.Damage"); + this.cooldown = getConfig().getLong("Abilities.Earth.LavaSurge.Cooldown"); + this.fractureRadius = getConfig().getDouble("Abilities.Earth.LavaSurge.FractureRadius"); + this.prepareRange = getConfig().getInt("Abilities.Earth.LavaSurge.PrepareRange"); + this.travelRange = getConfig().getInt("Abilities.Earth.LavaSurge.TravelRange"); + this.maxBlocks = getConfig().getInt("Abilities.Earth.LavaSurge.MaxLavaWaves"); + this.canSourceBeEarth = getConfig().getBoolean("Abilities.Earth.LavaSurge.SourceCanBeEarth"); + this.particleInterval = 100; + this.fallingBlockInterval = 100; + + this.random = new Random(); + this.fallingBlocks = new ArrayList<>(); + this.fracture = new ArrayList<>(); + this.fractureTempBlocks = new ArrayList<>(); + this.movingLava = new ArrayList<>(); + this.lavaBlocks = new ConcurrentHashMap<>(); + + if(!isEligible()) { return; - - if(GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("LavaSurge")) + } else if(bPlayer.isOnCooldown(this)) { return; + } lastTime = System.currentTimeMillis(); - if(prepare()) - { - instances.put(player, this); + if(prepare()) { + start(); } } - public boolean isEligible() - { - final BendingPlayer bplayer = GeneralMethods.getBendingPlayer(player.getName()); - - if(!GeneralMethods.canBend(player.getName(), "LavaSurge")) - return false; - - if(GeneralMethods.getBoundAbility(player) == null) - return false; - - if(!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("LavaSurge")) - return false; - - if(GeneralMethods.isRegionProtectedFromBuild(player, "LavaSurge", player.getLocation())) - return false; - - if(!EarthMethods.canLavabend(player)) - return false; - - if(bplayer.isOnCooldown("LavaSurge")) - return false; - - return true; + public boolean isEligible() { + return bPlayer.canBend(this) && bPlayer.canLavabend(); } - public boolean prepare() - { - Block targetBlock = BlockSource.getEarthSourceBlock(player, selectRange, selectRange, ClickType.SHIFT_DOWN, false, dynamic, true, EarthMethods.canSandbend(player), EarthMethods.canMetalbend(player)); + public boolean prepare() { + Block targetBlock = BlockSource.getEarthSourceBlock(player, prepareRange, ClickType.SHIFT_DOWN); - if(targetBlock == null || - !(targetBlock.getRelative(BlockFace.UP).getType() == Material.AIR) && - !isLava(targetBlock.getRelative(BlockFace.UP))) + if(targetBlock == null + || !(targetBlock.getRelative(BlockFace.UP).getType() == Material.AIR) + && !isLava(targetBlock.getRelative(BlockFace.UP))) { return false; + } - if(instances.containsKey(player)) - instances.get(player).revertFracture(); + LavaSurge otherSurge = CoreAbility.getAbility(player, this.getClass()); + if (otherSurge != null) { + otherSurge.revertFracture(); + } - if((canSourceBeEarth && EarthMethods.isEarthbendable(player, targetBlock)) || - EarthMethods.isLavabendable(targetBlock, player)) - { + if((canSourceBeEarth && isEarthbendable(targetBlock)) || isLavabendable(targetBlock)) { startLocation = targetBlock.getLocation().add(0, 1, 0); - //currentLocation = startLocation; // Not needed. sourceBlock = targetBlock; return true; } @@ -124,22 +114,14 @@ public class LavaSurge { return false; } - public boolean isLava(Block b) - { - if(b.getType() == Material.STATIONARY_LAVA || b.getType() == Material.LAVA) - return true; - return false; - } - - public void launch() - { + public void launch() { Location targetLocation = GeneralMethods.getTargetedLocation(player, travelRange*2); - try { targetLocation = GeneralMethods.getTargetedEntity(player, travelRange*2, null).getLocation(); } - catch(NullPointerException e) {}; + try { + targetLocation = GeneralMethods.getTargetedEntity(player, travelRange*2, null).getLocation(); + } catch(NullPointerException e) {} - if(targetLocation == null) - { + if(targetLocation == null) { remove(); return; } @@ -147,154 +129,124 @@ public class LavaSurge { time = System.currentTimeMillis(); direction = GeneralMethods.getDirection(startLocation, targetLocation).multiply(0.07); - if(direction.getY() < 0) + if(direction.getY() < 0) { direction.setY(0); + } - if(canSourceBeEarth) + if(canSourceBeEarth) { openFracture(); - else + } else { skipFracture(); + } } - public void openFracture() - { - + public void openFracture() { List affectedBlocks = GeneralMethods.getBlocksAroundPoint(sourceBlock.getLocation(), fractureRadius); - for(Block b : affectedBlocks) - { - if(EarthMethods.isEarthbendable(player, b)) - { + for(Block b : affectedBlocks) { + if(isEarthbendable(b)) { fracture.add(b); } } - - li = fracture.listIterator(); - - fractureOpen = true; - - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("LavaSurge", cooldown); + + listIterator = fracture.listIterator(); + isFractureOpen = true; + bPlayer.addCooldown(this); } - public void skipFracture() - { - li = fracture.listIterator(); - - fractureOpen = true; + public void skipFracture() { + listIterator = fracture.listIterator(); + isFractureOpen = true; } - public void revertFracture() - { - for(TempBlock tb : fracturetb) - { + public void revertFracture() { + for(TempBlock tb : fractureTempBlocks) { tb.revertBlock(); } - fracture.clear(); } - public void remove() - { + @Override + public void remove() { + super.remove(); revertFracture(); - instances.remove(player); } - public boolean canMoveThrough(Block block) - { - if(EarthMethods.isTransparentToEarthbending(player, startLocation.getBlock()) || - EarthMethods.isEarthbendable(player, startLocation.getBlock()) || - EarthMethods.isLavabendable(startLocation.getBlock(), player)) + public boolean canMoveThrough(Block block) { + if(isTransparent(startLocation.getBlock()) || + isEarthbendable(startLocation.getBlock()) || + isLavabendable(startLocation.getBlock())) { return true; + } return false; } - public void removeLava() - { - for(TempBlock tb : lava.values()) - { + public void removeLava() { + for(TempBlock tb : lavaBlocks.values()) { tb.revertBlock(); } - movingLava.clear(); } - public void progress() - { + @Override + public void progress() { long curTime = System.currentTimeMillis(); - if(!player.isOnline() || player.isDead()) - { + if(!player.isOnline() || player.isDead()) { + remove(); + return; + } else if(!hasSurgeStarted && !bPlayer.getBoundAbilityName().equals(getName())) { remove(); return; } - if(!surgeStarted && !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("LavaSurge")) - { - remove(); - return; - } - - if(!surgeStarted && sourceBlock != null && - curTime > lastTime + particleInterval) - { + if(!hasSurgeStarted && sourceBlock != null && curTime > lastTime + particleInterval) { lastTime = curTime; ParticleEffect.LAVA.display(sourceBlock.getLocation(), 0, 0, 0, 0, 1); - } - - else if(surgeStarted && curTime > lastTime + particleInterval) - { + } else if(hasSurgeStarted && curTime > lastTime + particleInterval) { lastTime = curTime; - for(FallingBlock fblock : fblocks) + for(FallingBlock fblock : fallingBlocks) { ParticleEffect.LAVA.display(fblock.getLocation(), 0, 0, 0, 0, 1); + } } - if(fractureOpen && !surgeStarted) - { - if(!li.hasNext()) - surgeStarted = true; - - else - { - Block b = li.next(); - - EarthMethods.playEarthbendingSound(b.getLocation()); + if(isFractureOpen && !hasSurgeStarted) { + if(!listIterator.hasNext()) { + hasSurgeStarted = true; + } else { + Block b = listIterator.next(); + playEarthbendingSound(b.getLocation()); - for(int i = 0; i < 2; i++) - { + for(int i = 0; i < 2; i++) { TempBlock tb = new TempBlock(b, Material.STATIONARY_LAVA, (byte) 0); - fracturetb.add(tb); + fractureTempBlocks.add(tb); } } } - if(surgeStarted) - { - if(fallingBlocksCount >= maxBlocks) - { + if(hasSurgeStarted) { + if(fallingBlocksCount >= maxBlocks) { return; } - if(curTime > time + (fallingBlockInterval * fallingBlocksCount)) - { + if(curTime > time + (fallingBlockInterval * fallingBlocksCount)) { FallingBlock fbs = GeneralMethods.spawnFallingBlock(sourceBlock.getLocation().add(0, 1, 0), 11, (byte) 0); - fblocks.add(fbs); - falling.add(fbs); - double x = randy.nextDouble()/5; - double z = randy.nextDouble()/5; + fallingBlocks.add(fbs); + ALL_FALLING_BLOCKS.add(fbs); + double x = random.nextDouble()/5; + double z = random.nextDouble()/5; - x = (randy.nextBoolean()) ? -x : x; - z = (randy.nextBoolean()) ? -z : z; + x = (random.nextBoolean()) ? -x : x; + z = (random.nextBoolean()) ? -z : z; fbs.setVelocity(direction.clone().add(new Vector(x, 0.2, z)).multiply(1.2)); fbs.setDropItem(false); - for(Block b : fracture) - { - if(randy.nextBoolean() && b != sourceBlock) - { + for(Block b : fracture) { + if(random.nextBoolean() && b != sourceBlock) { FallingBlock fb = GeneralMethods.spawnFallingBlock(b.getLocation().add(new Vector(0, 1, 0)), 11, (byte) 0); - falling.add(fb); - fblocks.add(fb); - fb.setVelocity(direction.clone().add(new Vector(randy.nextDouble()/10, 0.1, randy.nextDouble()/10)).multiply(1.2)); + ALL_FALLING_BLOCKS.add(fb); + fallingBlocks.add(fb); + fb.setVelocity(direction.clone().add(new Vector(random.nextDouble()/10, 0.1, random.nextDouble()/10)).multiply(1.2)); fb.setDropItem(false); } } @@ -302,14 +254,10 @@ public class LavaSurge { fallingBlocksCount++; } - for(FallingBlock fb : fblocks) - { - for(Entity e : GeneralMethods.getEntitiesAroundPoint(fb.getLocation(), 2)) - { - if(e instanceof LivingEntity) - { - if(e.getEntityId() != player.getEntityId()) - { + for(FallingBlock fb : fallingBlocks) { + for(Entity e : GeneralMethods.getEntitiesAroundPoint(fb.getLocation(), 2)) { + if(e instanceof LivingEntity) { + if(e.getEntityId() != player.getEntityId()) { GeneralMethods.damageEntity(player, e, impactDamage, "LavaSurge"); e.setFireTicks(100); GeneralMethods.setVelocity(e, direction.clone()); @@ -319,12 +267,202 @@ public class LavaSurge { } } } - - public static void progressAll() - { - for(Player p : instances.keySet()) - { - instances.get(p).progress(); - } + + @Override + public String getName() { + return null; // disabled } + + @Override + public Location getLocation() { + return startLocation; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public static HashSet getAllFallingBlocks() { + return ALL_FALLING_BLOCKS; + } + + public boolean isHasSurgeStarted() { + return hasSurgeStarted; + } + + public void setHasSurgeStarted(boolean hasSurgeStarted) { + this.hasSurgeStarted = hasSurgeStarted; + } + + public boolean isFractureOpen() { + return isFractureOpen; + } + + public void setFractureOpen(boolean isFractureOpen) { + this.isFractureOpen = isFractureOpen; + } + + public boolean isCanSourceBeEarth() { + return canSourceBeEarth; + } + + public void setCanSourceBeEarth(boolean canSourceBeEarth) { + this.canSourceBeEarth = canSourceBeEarth; + } + + public int getFallingBlocksCount() { + return fallingBlocksCount; + } + + public void setFallingBlocksCount(int fallingBlocksCount) { + this.fallingBlocksCount = fallingBlocksCount; + } + + public int getMaxBlocks() { + return maxBlocks; + } + + public void setMaxBlocks(int maxBlocks) { + this.maxBlocks = maxBlocks; + } + + public int getParticleInterval() { + return particleInterval; + } + + public void setParticleInterval(int particleInterval) { + this.particleInterval = particleInterval; + } + + public int getFallingBlockInterval() { + return fallingBlockInterval; + } + + public void setFallingBlockInterval(int fallingBlockInterval) { + this.fallingBlockInterval = fallingBlockInterval; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getLastTime() { + return lastTime; + } + + public void setLastTime(long lastTime) { + this.lastTime = lastTime; + } + + public double getImpactDamage() { + return impactDamage; + } + + public void setImpactDamage(double impactDamage) { + this.impactDamage = impactDamage; + } + + public double getFractureRadius() { + return fractureRadius; + } + + public void setFractureRadius(double fractureRadius) { + this.fractureRadius = fractureRadius; + } + + public double getPrepareRange() { + return prepareRange; + } + + public void setPrepareRange(double prepareRange) { + this.prepareRange = prepareRange; + } + + public double getTravelRange() { + return travelRange; + } + + public void setTravelRange(double travelRange) { + this.travelRange = travelRange; + } + + public Block getSourceBlock() { + return sourceBlock; + } + + public void setSourceBlock(Block sourceBlock) { + this.sourceBlock = sourceBlock; + } + + public Random getRandom() { + return random; + } + + public void setRandom(Random random) { + this.random = random; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public Location getStartLocation() { + return startLocation; + } + + public void setStartLocation(Location startLocation) { + this.startLocation = startLocation; + } + + public ListIterator getListIterator() { + return listIterator; + } + + public void setListIterator(ListIterator listIterator) { + this.listIterator = listIterator; + } + + public ArrayList getFallingBlocks() { + return fallingBlocks; + } + + public ArrayList getFracture() { + return fracture; + } + + public ArrayList getFractureTempBlocks() { + return fractureTempBlocks; + } + + public ArrayList getMovingLava() { + return movingLava; + } + + public ConcurrentHashMap getLavaBlocks() { + return lavaBlocks; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/earthbending/LavaSurgeWall.java b/src/com/projectkorra/projectkorra/earthbending/LavaSurgeWall.java new file mode 100644 index 00000000..6b5a0e27 --- /dev/null +++ b/src/com/projectkorra/projectkorra/earthbending/LavaSurgeWall.java @@ -0,0 +1,461 @@ +package com.projectkorra.projectkorra.earthbending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.LavaAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.firebending.FireBlast; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.BlockSource.BlockSourceType; +import com.projectkorra.projectkorra.util.ClickType; +import com.projectkorra.projectkorra.util.TempBlock; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.concurrent.ConcurrentHashMap; + +public class LavaSurgeWall extends LavaAbility { + + private static final ConcurrentHashMap AFFECTED_BLOCKS = new ConcurrentHashMap(); + private static final ConcurrentHashMap WALL_BLOCKS = new ConcurrentHashMap(); + private static final int SURGE_WAVE_RANGE = 20; // TODO: remove this + + private boolean progressing; + private boolean settingUp; + private boolean forming; + private long time; + private long interval; + private long cooldown; + private double radius; + private double range; + private Block sourceBlock; + private Location location; + private Location firstDestination; + private Location targetDestination; + private Vector firstDirection; + private Vector targetDirection; + + public LavaSurgeWall(Player player) { + super(player); + + this.interval = 30; + this.radius = getConfig().getDouble("Abilities.Water.Surge.Wall.Radius"); + this.range = getConfig().getDouble("Abilities.Water.Surge.Wall.Range"); + this.cooldown = GeneralMethods.getGlobalCooldown(); + + LavaSurgeWave wave = CoreAbility.getAbility(player, LavaSurgeWave.class); + if (wave != null && wave.isProgressing()) { + LavaSurgeWave.launch(player); + return; + } + + if (bPlayer.isAvatarState()) { + radius = AvatarState.getValue(radius); + range = AvatarState.getValue(range); + } + + if (!bPlayer.canBend(this)) { + return; + } + } + + public boolean prepare() { + cancelPrevious(); + Block block = BlockSource.getSourceBlock(player, range, BlockSourceType.LAVA, ClickType.LEFT_CLICK); + if (block != null) { + sourceBlock = block; + focusBlock(); + return true; + } + return false; + } + + private void cancelPrevious() { + LavaSurgeWall lavaWall = CoreAbility.getAbility(player, LavaSurgeWall.class); + if (lavaWall != null) { + if (lavaWall.progressing) { + lavaWall.removeLava(lavaWall.sourceBlock); + } else { + lavaWall.cancel(); + } + } + } + + public void cancel() { + remove(); + } + + private void focusBlock() { + location = sourceBlock.getLocation(); + } + + public void moveLava() { + if (sourceBlock != null) { + targetDestination = getTargetEarthBlock((int) range).getLocation(); + + if (targetDestination.distanceSquared(location) <= 1) { + progressing = false; + targetDestination = null; + } else { + progressing = true; + settingUp = true; + firstDestination = getToEyeLevel(); + firstDirection = getDirection(sourceBlock.getLocation(), firstDestination); + targetDirection = getDirection(firstDestination, targetDestination); + + if (!GeneralMethods.isAdjacentToThreeOrMoreSources(sourceBlock)) { + sourceBlock.setType(Material.AIR); + } + addLava(sourceBlock); + } + } + } + + private Location getToEyeLevel() { + Location loc = sourceBlock.getLocation().clone(); + loc.setY(targetDestination.getY()); + return loc; + } + + private Vector getDirection(Location location, Location destination) { + double x1, y1, z1; + double x0, y0, z0; + x1 = destination.getX(); + y1 = destination.getY(); + z1 = destination.getZ(); + x0 = location.getX(); + y0 = location.getY(); + z0 = location.getZ(); + return new Vector(x1 - x0, y1 - y0, z1 - z0); + } + + @Override + public void progress() { + if (!bPlayer.canBendIgnoreCooldowns(this)) { + if (!forming) { + breakBlock(); + } + remove(); + return; + } + + if (System.currentTimeMillis() - time >= interval) { + time = System.currentTimeMillis(); + if (progressing && !player.isSneaking()) { + remove(); + return; + } + + if (!progressing) { + sourceBlock.getWorld().playEffect(location, Effect.SMOKE, 4, (int) range); + return; + } + + if (forming) { + ArrayList blocks = new ArrayList(); + Location loc = GeneralMethods.getTargetedLocation(player, (int) range, 8, 9, 79); + location = loc.clone(); + Vector dir = player.getEyeLocation().getDirection(); + Vector vec; + Block block; + + for (double i = 0; i <= radius; i += 0.5) { + for (double angle = 0; angle < 360; angle += 10) { + vec = GeneralMethods.getOrthogonalVector(dir.clone(), angle, i); + block = loc.clone().add(vec).getBlock(); + + if (GeneralMethods.isRegionProtectedFromBuild(player, "LavaSurge", block.getLocation())) { + continue; + } + if (WALL_BLOCKS.containsKey(block)) { + blocks.add(block); + } else if (!blocks.contains(block) + && (block.getType() == Material.AIR || block.getType() == Material.FIRE || isLavabendable(block))) { + WALL_BLOCKS.put(block, player); + addWallBlock(block); + blocks.add(block); + FireBlast.removeFireBlastsAroundPoint(block.getLocation(), 2); + } + } + } + + for (Block blocki : WALL_BLOCKS.keySet()) { + if (WALL_BLOCKS.get(blocki) == player && !blocks.contains(blocki)) { + finalRemoveLava(blocki); + } + } + + return; + } + + if (sourceBlock.getLocation().distanceSquared(firstDestination) < 0.5 * 0.5 && settingUp) { + settingUp = false; + } + + Vector direction; + if (settingUp) { + direction = firstDirection; + } else { + direction = targetDirection; + } + + location = location.clone().add(direction); + Block block = location.getBlock(); + if (block.getLocation().equals(sourceBlock.getLocation())) { + location = location.clone().add(direction); + block = location.getBlock(); + } + + if (block.getType() != Material.AIR) { + breakBlock(); + return; + } else if (!progressing) { + breakBlock(); + return; + } + + addLava(block); + removeLava(sourceBlock); + sourceBlock = block; + if (location.distanceSquared(targetDestination) < 1) { + removeLava(sourceBlock); + forming = true; + } + return; + } + } + + private void addWallBlock(Block block) { + new TempBlock(block, Material.STATIONARY_LAVA, (byte) 8); + } + + private void breakBlock() { + finalRemoveLava(sourceBlock); + for (Block block : WALL_BLOCKS.keySet()) { + if (WALL_BLOCKS.get(block) == player) { + finalRemoveLava(block); + } + } + remove(); + } + + private void removeLava(Block block) { + if (block != null) { + if (AFFECTED_BLOCKS.containsKey(block)) { + if (!GeneralMethods.isAdjacentToThreeOrMoreSources(block)) { + TempBlock.revertBlock(block, Material.AIR); + } + AFFECTED_BLOCKS.remove(block); + } + } + } + + private static void finalRemoveLava(Block block) { + if (AFFECTED_BLOCKS.containsKey(block)) { + TempBlock.revertBlock(block, Material.AIR); + AFFECTED_BLOCKS.remove(block); + } + if (WALL_BLOCKS.containsKey(block)) { + TempBlock.revertBlock(block, Material.AIR); + WALL_BLOCKS.remove(block); + } + } + + private void addLava(Block block) { + if (GeneralMethods.isRegionProtectedFromBuild(player, "LavaSurge", block.getLocation())) + return; + if (!TempBlock.isTempBlock(block)) { + new TempBlock(block, Material.STATIONARY_LAVA, (byte) 8); + AFFECTED_BLOCKS.put(block, block); + } + } + + public static void moveLava(Player player) { + LavaSurgeWall wall = CoreAbility.getAbility(player, LavaSurgeWall.class); + if (wall != null) { + wall.moveLava(); + } + } + + @SuppressWarnings("deprecation") + public static void form(Player player) { + if (!CoreAbility.hasAbility(player, LavaSurgeWall.class)) { + new LavaSurgeWave(player); + return; + } else if (isLavabendable(player.getTargetBlock((HashSet) null, SURGE_WAVE_RANGE))) { + new LavaSurgeWave(player); + return; + } + moveLava(player); + } + + public static void cleanup() { + for (Block block : AFFECTED_BLOCKS.keySet()) { + TempBlock.revertBlock(block, Material.AIR); + AFFECTED_BLOCKS.remove(block); + WALL_BLOCKS.remove(block); + } + for (Block block : WALL_BLOCKS.keySet()) { + TempBlock.revertBlock(block, Material.AIR); + AFFECTED_BLOCKS.remove(block); + WALL_BLOCKS.remove(block); + } + } + + public static boolean wasBrokenFor(Player player, Block block) { + LavaSurgeWall wall = CoreAbility.getAbility(player, LavaSurgeWall.class); + if (wall != null) { + if (wall.sourceBlock == null) { + return false; + } else if (wall.sourceBlock.equals(block)) { + return true; + } + } + return false; + } + + public static ConcurrentHashMap getAffectedBlocks() { + return AFFECTED_BLOCKS; + } + + public static ConcurrentHashMap getWallBlocks() { + return WALL_BLOCKS; + } + + @Override + public String getName() { + return null; + } + + @Override + public Location getLocation() { + return location; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isProgressing() { + return progressing; + } + + public void setProgressing(boolean progressing) { + this.progressing = progressing; + } + + public boolean isSettingUp() { + return settingUp; + } + + public void setSettingUp(boolean settingUp) { + this.settingUp = settingUp; + } + + public boolean isForming() { + return forming; + } + + public void setForming(boolean forming) { + this.forming = forming; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public Block getSourceBlock() { + return sourceBlock; + } + + public void setSourceBlock(Block sourceBlock) { + this.sourceBlock = sourceBlock; + } + + public Location getFirstDestination() { + return firstDestination; + } + + public void setFirstDestination(Location firstDestination) { + this.firstDestination = firstDestination; + } + + public Location getTargetDestination() { + return targetDestination; + } + + public void setTargetDestination(Location targetDestination) { + this.targetDestination = targetDestination; + } + + public Vector getFirstDirection() { + return firstDirection; + } + + public void setFirstDirection(Vector firstDirection) { + this.firstDirection = firstDirection; + } + + public Vector getTargetDirection() { + return targetDirection; + } + + public void setTargetDirection(Vector targetDirection) { + this.targetDirection = targetDirection; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/earthbending/LavaSurgeWave.java b/src/com/projectkorra/projectkorra/earthbending/LavaSurgeWave.java new file mode 100644 index 00000000..5c985f76 --- /dev/null +++ b/src/com/projectkorra/projectkorra/earthbending/LavaSurgeWave.java @@ -0,0 +1,443 @@ +package com.projectkorra.projectkorra.earthbending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.LavaAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.firebending.FireBlast; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.BlockSource.BlockSourceType; +import com.projectkorra.projectkorra.util.ClickType; +import com.projectkorra.projectkorra.util.TempBlock; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.concurrent.ConcurrentHashMap; + +public class LavaSurgeWave extends LavaAbility { + + private boolean progressing; + private boolean canHitSelf; + private long time; + private long cooldown; + private double range; + private double radius; + private double maxRadius; + private double horizontalPush; + private double verticalPush; + private double interval; + private Location location; + private Block sourceBlock ; + private Location targetDestination; + private Vector targetDirection; + private ConcurrentHashMap waveBlocks; + private ConcurrentHashMap frozenBlocks; + + public LavaSurgeWave(Player player) { + super(player); + + this.progressing = false; + this.canHitSelf = true; + this.range = 20; + this.radius = 1; + this.interval = 30; + this.cooldown = GeneralMethods.getGlobalCooldown(); + this.maxRadius = getConfig().getDouble("Abilities.Earth.LavaSurge.Radius"); + this.horizontalPush = getConfig().getDouble("Abilities.Earth.LavaSurge.HorizontalPush"); + this.verticalPush = getConfig().getDouble("Abilities.Earth.LavaSurge.VerticalPush"); + this.waveBlocks = new ConcurrentHashMap(); + this.frozenBlocks = new ConcurrentHashMap(); + + if (bPlayer.isAvatarState()) { + range = AvatarState.getValue(range); + maxRadius = AvatarState.getValue(maxRadius); + horizontalPush = AvatarState.getValue(horizontalPush); + verticalPush = AvatarState.getValue(verticalPush); + } + + if (prepare()) { + LavaSurgeWave wave = CoreAbility.getAbility(player, LavaSurgeWave.class); + if (wave != null) { + wave.remove(); + } + start(); + time = System.currentTimeMillis(); + } + } + + public boolean prepare() { + cancelPrevious(); + Block block = BlockSource.getSourceBlock(player, range, BlockSourceType.LAVA, ClickType.SHIFT_DOWN); + + if (block != null) { + sourceBlock = block; + focusBlock(); + return true; + } + return false; + } + + private void cancelPrevious() { + LavaSurgeWave oldWave = CoreAbility.getAbility(player, LavaSurgeWave.class); + if (oldWave != null) { + if (oldWave.progressing) { + oldWave.breakBlock(); + } else { + oldWave.remove(); + } + } + } + + private void focusBlock() { + location = sourceBlock.getLocation(); + } + + public void moveLava() { + if (bPlayer.isOnCooldown(this)) { + return; + } + + bPlayer.addCooldown(this); + if (sourceBlock != null) { + if (!sourceBlock.getWorld().equals(player.getWorld())) { + return; + } + + Entity target = GeneralMethods.getTargetedEntity(player, range); + if (target == null) { + targetDestination = getTargetEarthBlock((int) range).getLocation(); + } else { + targetDestination = ((LivingEntity) target).getEyeLocation(); + } + + if (targetDestination.distanceSquared(location) <= 1) { + progressing = false; + targetDestination = null; + } else { + progressing = true; + targetDirection = getDirection(sourceBlock.getLocation(), targetDestination).normalize(); + targetDestination = location.clone().add(targetDirection.clone().multiply(range)); + + if (!GeneralMethods.isAdjacentToThreeOrMoreSources(sourceBlock)) { + sourceBlock.setType(Material.AIR); + } + addLava(sourceBlock); + } + } + } + + private Vector getDirection(Location location, Location destination) { + double x1, y1, z1; + double x0, y0, z0; + x1 = destination.getX(); + y1 = destination.getY(); + z1 = destination.getZ(); + x0 = location.getX(); + y0 = location.getY(); + z0 = location.getZ(); + return new Vector(x1 - x0, y1 - y0, z1 - z0); + } + + @Override + public void progress() { + if (!bPlayer.canBendIgnoreCooldowns(this)) { + breakBlock(); + return; + } + + if (System.currentTimeMillis() - time >= interval) { + time = System.currentTimeMillis(); + if (!progressing) { + sourceBlock.getWorld().playEffect(location, Effect.SMOKE, 4, (int) range); + return; + } + + Vector direction = targetDirection; + location = location.clone().add(direction); + Block blockl = location.getBlock(); + ArrayList blocks = new ArrayList(); + + if (!GeneralMethods.isRegionProtectedFromBuild(this, location) && blockl.getType() != Material.LEAVES + && (blockl.getType() == Material.AIR + || blockl.getType() == Material.FIRE + || WaterAbility.isPlant(blockl) + || isLava(blockl))) { + for (double i = 0; i <= radius; i += 0.5) { + for (double angle = 0; angle < 360; angle += 10) { + Vector vec = GeneralMethods.getOrthogonalVector(targetDirection, angle, i); + Block block = location.clone().add(vec).getBlock(); + + if (!blocks.contains(block) && (block.getType() == Material.AIR + || block.getType() == Material.FIRE) + || isLavabendable(block)) { + blocks.add(block); + FireBlast.removeFireBlastsAroundPoint(block.getLocation(), 2); + } + } + } + } + + for (Block block : waveBlocks.keySet()) { + if (!blocks.contains(block)) { + finalRemoveLava(block); + } + } + for (Block block : blocks) { + if (!waveBlocks.containsKey(block)) { + addLava(block); + } + } + if (waveBlocks.isEmpty()) { + breakBlock(); + progressing = false; + return; + } + + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2 * radius)) { + boolean knockback = false; + for (Block block : waveBlocks.keySet()) { + if (entity.getLocation().distanceSquared(block.getLocation()) <= 2 * 2) { + if (entity.getEntityId() != player.getEntityId() || canHitSelf) { + knockback = true; + } + } + } + if (knockback) { + Vector dir = direction.clone(); + dir.setY(dir.getY() * verticalPush); + entity.setVelocity(entity.getVelocity().clone().add(dir.clone().multiply(horizontalPush))); + entity.setFallDistance(0); + + if (entity.getFireTicks() > 0) { + entity.getWorld().playEffect(entity.getLocation(), Effect.EXTINGUISH, 0); + } + entity.setFireTicks(0); + } + } + + if (!progressing) { + breakBlock(); + return; + } + if (location.distanceSquared(targetDestination) < 1) { + progressing = false; + breakBlock(); + return; + } + if (radius < maxRadius) { + radius += .5; + } + return; + } + + return; + } + + private void breakBlock() { + for (Block block : waveBlocks.keySet()) { + finalRemoveLava(block); + } + remove(); + } + + private void finalRemoveLava(Block block) { + if (waveBlocks.containsKey(block)) { + TempBlock.revertBlock(block, Material.AIR); + waveBlocks.remove(block); + } + } + + private void addLava(Block block) { + if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + return; + } else if (!TempBlock.isTempBlock(block)) { + new TempBlock(block, Material.STATIONARY_LAVA, (byte) 8); + waveBlocks.put(block, block); + } + } + + public static boolean isBlockInWave(Block block) { + for (LavaSurgeWave lavaWave : CoreAbility.getAbilities(LavaSurgeWave.class)) { + if (block.getLocation().distance(lavaWave.location) <= 2 * lavaWave.radius) { + return true; + } + } + return false; + } + + public static boolean isBlockWave(Block block) { + for (LavaSurgeWave lavaWave : CoreAbility.getAbilities(LavaSurgeWave.class)) { + if (lavaWave.waveBlocks.containsKey(block)) { + return true; + } + } + return false; + } + + public static void launch(Player player) { + LavaSurgeWave lavaWave = CoreAbility.getAbility(player, LavaSurgeWave.class); + if (lavaWave != null) { + lavaWave.moveLava(); + } + } + + public static void cleanup() { + for (LavaSurgeWave lavaWave : CoreAbility.getAbilities(LavaSurgeWave.class)) { + for (Block block : lavaWave.waveBlocks.keySet()) { + block.setType(Material.AIR); + lavaWave.waveBlocks.remove(block); + } + for (Block block : lavaWave.frozenBlocks.keySet()) { + block.setType(Material.AIR); + lavaWave.frozenBlocks.remove(block); + } + } + } + + @Override + public String getName() { + return null; + } + + @Override + public Location getLocation() { + return location; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isProgressing() { + return progressing; + } + + public void setProgressing(boolean progressing) { + this.progressing = progressing; + } + + public boolean isCanHitSelf() { + return canHitSelf; + } + + public void setCanHitSelf(boolean canHitSelf) { + this.canHitSelf = canHitSelf; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getMaxRadius() { + return maxRadius; + } + + public void setMaxRadius(double maxRadius) { + this.maxRadius = maxRadius; + } + + public double getHorizontalPush() { + return horizontalPush; + } + + public void setHorizontalPush(double horizontalPush) { + this.horizontalPush = horizontalPush; + } + + public double getVerticalPush() { + return verticalPush; + } + + public void setVerticalPush(double verticalPush) { + this.verticalPush = verticalPush; + } + + public double getInterval() { + return interval; + } + + public void setInterval(double interval) { + this.interval = interval; + } + + public Block getSourceBlock() { + return sourceBlock; + } + + public void setSourceBlock(Block sourceBlock) { + this.sourceBlock = sourceBlock; + } + + public Location getTargetDestination() { + return targetDestination; + } + + public void setTargetDestination(Location targetDestination) { + this.targetDestination = targetDestination; + } + + public Vector getTargetDirection() { + return targetDirection; + } + + public void setTargetDirection(Vector targetDirection) { + this.targetDirection = targetDirection; + } + + public ConcurrentHashMap getWaveBlocks() { + return waveBlocks; + } + + public ConcurrentHashMap getFrozenBlocks() { + return frozenBlocks; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/earthbending/LavaWall.java b/src/com/projectkorra/projectkorra/earthbending/LavaWall.java deleted file mode 100644 index 8596f1cf..00000000 --- a/src/com/projectkorra/projectkorra/earthbending/LavaWall.java +++ /dev/null @@ -1,335 +0,0 @@ -package com.projectkorra.projectkorra.earthbending; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.concurrent.ConcurrentHashMap; - -import org.bukkit.Effect; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.firebending.FireBlast; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.ClickType; -import com.projectkorra.projectkorra.util.TempBlock; - -public class LavaWall { - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - public static ConcurrentHashMap affectedblocks = new ConcurrentHashMap(); - public static ConcurrentHashMap wallblocks = new ConcurrentHashMap(); - private static double range = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.Surge.Wall.Range"); - private static final double defaultradius = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.Surge.Wall.Radius"); - private static final long interval = 30; - private static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.LavaSurge.DynamicSourcing.Enabled"); - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.LavaSurge.SelectRange"); - - @SuppressWarnings("unused") - private static final byte full = 0x0; - Player player; - private Location location = null; - private Block sourceblock = null; - private Location firstdestination = null; - private Location targetdestination = null; - private Vector firstdirection = null; - private Vector targetdirection = null; - private boolean progressing = false; - private boolean settingup = false; - private boolean forming = false; - private long time; - private double radius = defaultradius; - - public LavaWall(Player player) { - this.player = player; - - if (LavaWave.instances.containsKey(player.getEntityId())) { - LavaWave wave = LavaWave.instances.get(player.getEntityId()); - if (!wave.progressing) { - LavaWave.launch(player); - return; - } - } - - if (AvatarState.isAvatarState(player)) { - radius = AvatarState.getValue(radius); - } - - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("LavaSurge")) - return; - - } - - public boolean prepare() { - cancelPrevious(); - Block block = BlockSource.getEarthOrLavaSourceBlock(player, selectRange, selectRange, ClickType.LEFT_CLICK, false, dynamic, true, EarthMethods.canSandbend(player), EarthMethods.canMetalbend(player)); - if (block != null) { - sourceblock = block; - focusBlock(); - return true; - } - return false; - } - - private void cancelPrevious() { - if (instances.containsKey(player.getEntityId())) { - LavaWall old = instances.get(player.getEntityId()); - if (old.progressing) { - old.removeLava(old.sourceblock); - } else { - old.cancel(); - } - } - } - - public void cancel() { - unfocusBlock(); - } - - private void focusBlock() { - location = sourceblock.getLocation(); - } - - private void unfocusBlock() { - instances.remove(player.getEntityId()); - } - - @SuppressWarnings("deprecation") - public void moveLava() { - if (sourceblock != null) { - targetdestination = player.getTargetBlock(EarthMethods.getTransparentEarthbending(), (int) range).getLocation(); - if (targetdestination.distance(location) <= 1) { - progressing = false; - targetdestination = null; - } else { - progressing = true; - settingup = true; - firstdestination = getToEyeLevel(); - firstdirection = getDirection(sourceblock.getLocation(), firstdestination); - targetdirection = getDirection(firstdestination, targetdestination); - - if (!GeneralMethods.isAdjacentToThreeOrMoreSources(sourceblock)) { - sourceblock.setType(Material.AIR); - } - addLava(sourceblock); - } - } - } - - private Location getToEyeLevel() { - Location loc = sourceblock.getLocation().clone(); - loc.setY(targetdestination.getY()); - return loc; - } - - private Vector getDirection(Location location, Location destination) { - double x1, y1, z1; - double x0, y0, z0; - x1 = destination.getX(); - y1 = destination.getY(); - z1 = destination.getZ(); - x0 = location.getX(); - y0 = location.getY(); - z0 = location.getZ(); - return new Vector(x1 - x0, y1 - y0, z1 - z0); - } - - public static void progressAll() { - for (int ID : instances.keySet()) { - instances.get(ID).progress(); - } - } - - private boolean progress() { - if (player.isDead() || !player.isOnline()) { - breakBlock(); - // instances.remove(player.getEntityId()); - return false; - } - if (!GeneralMethods.canBend(player.getName(), "LavaSurge")) { - if (!forming) - breakBlock(); - unfocusBlock(); - return false; - } - if (System.currentTimeMillis() - time >= interval) { - time = System.currentTimeMillis(); - if (!forming) { - } - if (GeneralMethods.getBoundAbility(player) == null) { - unfocusBlock(); - return false; - } - if (!progressing && !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("LavaSurge")) { - unfocusBlock(); - return false; - } - if (progressing && (!player.isSneaking() || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("LavaSurge"))) { - breakBlock(); - return false; - } - if (!progressing) { - sourceblock.getWorld().playEffect(location, Effect.SMOKE, 4, (int) range); - return false; - } - if (forming) { - ArrayList blocks = new ArrayList(); - Location loc = GeneralMethods.getTargetedLocation(player, (int) range, 8, 9, 79); - location = loc.clone(); - Vector dir = player.getEyeLocation().getDirection(); - Vector vec; - Block block; - for (double i = 0; i <= radius; i += 0.5) { - for (double angle = 0; angle < 360; angle += 10) { - vec = GeneralMethods.getOrthogonalVector(dir.clone(), angle, i); - block = loc.clone().add(vec).getBlock(); - if (GeneralMethods.isRegionProtectedFromBuild(player, "LavaSurge", block.getLocation())) - continue; - if (wallblocks.containsKey(block)) { - blocks.add(block); - } else if (!blocks.contains(block) && (block.getType() == Material.AIR || block.getType() == Material.FIRE || EarthMethods.isLavabendable(block, player))) { - wallblocks.put(block, player); - addWallBlock(block); - blocks.add(block); - FireBlast.removeFireBlastsAroundPoint(block.getLocation(), 2); - } - } - } - for (Block blocki : wallblocks.keySet()) { - if (wallblocks.get(blocki) == player && !blocks.contains(blocki)) { - finalRemoveLava(blocki); - } - } - return true; - } - if (sourceblock.getLocation().distance(firstdestination) < .5 && settingup) { - settingup = false; - } - Vector direction; - if (settingup) { - direction = firstdirection; - } else { - direction = targetdirection; - } - location = location.clone().add(direction); - Block block = location.getBlock(); - if (block.getLocation().equals(sourceblock.getLocation())) { - location = location.clone().add(direction); - block = location.getBlock(); - } - if (block.getType() != Material.AIR) { - breakBlock(); - return false; - } - if (!progressing) { - breakBlock(); - return false; - } - addLava(block); - removeLava(sourceblock); - sourceblock = block; - if (location.distance(targetdestination) < 1) { - removeLava(sourceblock); - forming = true; - } - return true; - } - return false; - } - - private void addWallBlock(Block block) { - new TempBlock(block, Material.STATIONARY_LAVA, (byte) 8); - } - - private void breakBlock() { - finalRemoveLava(sourceblock); - for (Block block : wallblocks.keySet()) { - if (wallblocks.get(block) == player) { - finalRemoveLava(block); - } - } - instances.remove(player.getEntityId()); - } - - private void removeLava(Block block) { - if (block != null) { - if (affectedblocks.containsKey(block)) { - if (!GeneralMethods.isAdjacentToThreeOrMoreSources(block)) { - TempBlock.revertBlock(block, Material.AIR); - } - affectedblocks.remove(block); - } - } - } - - private static void finalRemoveLava(Block block) { - if (affectedblocks.containsKey(block)) { - TempBlock.revertBlock(block, Material.AIR); - affectedblocks.remove(block); - } - if (wallblocks.containsKey(block)) { - TempBlock.revertBlock(block, Material.AIR); - wallblocks.remove(block); - } - } - - private void addLava(Block block) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "LavaSurge", block.getLocation())) - return; - if (!TempBlock.isTempBlock(block)) { - new TempBlock(block, Material.STATIONARY_LAVA, (byte) 8); - affectedblocks.put(block, block); - } - } - - public static void moveLava(Player player) { - if (instances.containsKey(player.getEntityId())) { - instances.get(player.getEntityId()).moveLava(); - } - } - - @SuppressWarnings("deprecation") - public static void form(Player player) { - if (!instances.containsKey(player.getEntityId())) { - new LavaWave(player); - return; - } else { - if (EarthMethods.isLavabendable(player.getTargetBlock((HashSet) null, (int) LavaWave.defaultrange), player)) { - new LavaWave(player); - return; - } - } - moveLava(player); - } - - public static void removeAll() { - for (Block block : affectedblocks.keySet()) { - TempBlock.revertBlock(block, Material.AIR); - affectedblocks.remove(block); - wallblocks.remove(block); - } - for (Block block : wallblocks.keySet()) { - TempBlock.revertBlock(block, Material.AIR); - affectedblocks.remove(block); - wallblocks.remove(block); - } - } - - public static boolean wasBrokenFor(Player player, Block block) { - if (instances.containsKey(player.getEntityId())) { - LavaWall wall = instances.get(player.getEntityId()); - if (wall.sourceblock == null) - return false; - if (wall.sourceblock.equals(block)) - return true; - } - return false; - } - -} diff --git a/src/com/projectkorra/projectkorra/earthbending/LavaWave.java b/src/com/projectkorra/projectkorra/earthbending/LavaWave.java deleted file mode 100644 index 620e89a0..00000000 --- a/src/com/projectkorra/projectkorra/earthbending/LavaWave.java +++ /dev/null @@ -1,313 +0,0 @@ -package com.projectkorra.projectkorra.earthbending; - -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; - -import org.bukkit.Effect; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.firebending.FireBlast; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.ClickType; -import com.projectkorra.projectkorra.util.TempBlock; -import com.projectkorra.projectkorra.waterbending.WaterMethods; - -public class LavaWave { - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - private static final double defaultmaxradius = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.LavaSurge.Radius"); - private static final double defaultfactor = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.LavaSurge.HorizontalPush"); - private static final double upfactor = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.LavaSurge.VerticalPush"); - private static final long interval = 30; - private static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.LavaSurge.DynamicSourcing.Enabled"); - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.LavaSurge.SelectRange"); - - @SuppressWarnings("unused") - private static final byte full = 0x0; - static double defaultrange = 20; - Player player; - private Location location = null; - private Block sourceblock = null; - private Location targetdestination = null; - private Vector targetdirection = null; - private ConcurrentHashMap wave = new ConcurrentHashMap(); - private ConcurrentHashMap frozenblocks = new ConcurrentHashMap(); - private long time; - private double radius = 1; - private double maxradius = defaultmaxradius; - private double factor = defaultfactor; - double range = defaultrange; - boolean progressing = false; - boolean canhitself = true; - - public LavaWave(Player player) { - this.player = player; - - if (AvatarState.isAvatarState(player)) { - maxradius = AvatarState.getValue(maxradius); - } - if (prepare()) { - if (instances.containsKey(player.getEntityId())) { - instances.get(player.getEntityId()).cancel(); - } - instances.put(player.getEntityId(), this); - time = System.currentTimeMillis(); - } - } - - public boolean prepare() { - cancelPrevious(); - // Block block = player.getTargetBlock(null, (int) range); - Block block = BlockSource.getEarthOrLavaSourceBlock(player, selectRange, selectRange, ClickType.SHIFT_DOWN, false, dynamic, true, EarthMethods.canSandbend(player), EarthMethods.canMetalbend(player)); - if (block != null) { - sourceblock = block; - focusBlock(); - return true; - } - return false; - } - - private void cancelPrevious() { - if (instances.containsKey(player.getEntityId())) { - LavaWave old = instances.get(player.getEntityId()); - if (old.progressing) { - old.breakBlock(); - } else { - old.cancel(); - } - } - } - - public void cancel() { - unfocusBlock(); - } - - private void focusBlock() { - location = sourceblock.getLocation(); - } - - private void unfocusBlock() { - instances.remove(player.getEntityId()); - } - - @SuppressWarnings("deprecation") - public void moveLava() { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("LavaSurge")) - return; - - bPlayer.addCooldown("LavaSurge", GeneralMethods.getGlobalCooldown()); - if (sourceblock != null) { - if (!sourceblock.getWorld().equals(player.getWorld())) { - return; - } - if (AvatarState.isAvatarState(player)) - factor = AvatarState.getValue(factor); - Entity target = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); - if (target == null) { - targetdestination = player.getTargetBlock(EarthMethods.getTransparentEarthbending(), (int) range).getLocation(); - } else { - targetdestination = ((LivingEntity) target).getEyeLocation(); - } - if (targetdestination.distance(location) <= 1) { - progressing = false; - targetdestination = null; - } else { - progressing = true; - targetdirection = getDirection(sourceblock.getLocation(), targetdestination).normalize(); - targetdestination = location.clone().add(targetdirection.clone().multiply(range)); - if (!GeneralMethods.isAdjacentToThreeOrMoreSources(sourceblock)) { - sourceblock.setType(Material.AIR); - } - addLava(sourceblock); - } - } - } - - private Vector getDirection(Location location, Location destination) { - double x1, y1, z1; - double x0, y0, z0; - x1 = destination.getX(); - y1 = destination.getY(); - z1 = destination.getZ(); - x0 = location.getX(); - y0 = location.getY(); - z0 = location.getZ(); - return new Vector(x1 - x0, y1 - y0, z1 - z0); - } - - public static void progressAll() { - for (int ID : instances.keySet()) { - instances.get(ID).progress(); - } - } - - private boolean progress() { - if (player.isDead() || !player.isOnline() || !GeneralMethods.canBend(player.getName(), "LavaSurge")) { - breakBlock(); - return false; - } - if (System.currentTimeMillis() - time >= interval) { - time = System.currentTimeMillis(); - if (GeneralMethods.getBoundAbility(player) == null) { - unfocusBlock(); - return false; - } - if (!progressing && !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("LavaSurge")) { - unfocusBlock(); - return false; - } - if (!progressing) { - sourceblock.getWorld().playEffect(location, Effect.SMOKE, 4, (int) range); - return false; - } - if (location.getWorld() != player.getWorld()) { - breakBlock(); - return false; - } - Vector direction = targetdirection; - location = location.clone().add(direction); - Block blockl = location.getBlock(); - ArrayList blocks = new ArrayList(); - if (!GeneralMethods.isRegionProtectedFromBuild(player, "LavaSurge", location) && (((blockl.getType() == Material.AIR || blockl.getType() == Material.FIRE || WaterMethods.isPlant(blockl) || EarthMethods.isLava(blockl) || EarthMethods.isLavabendable(blockl, player))) && blockl.getType() != Material.LEAVES)) { - for (double i = 0; i <= radius; i += .5) { - for (double angle = 0; angle < 360; angle += 10) { - Vector vec = GeneralMethods.getOrthogonalVector(targetdirection, angle, i); - Block block = location.clone().add(vec).getBlock(); - if (!blocks.contains(block) && (block.getType() == Material.AIR || block.getType() == Material.FIRE) || EarthMethods.isLavabendable(block, player)) { - blocks.add(block); - FireBlast.removeFireBlastsAroundPoint(block.getLocation(), 2); - } - } - - } - } - for (Block block : wave.keySet()) { - if (!blocks.contains(block)) - finalRemoveLava(block); - } - for (Block block : blocks) { - if (!wave.containsKey(block)) - addLava(block); - } - if (wave.isEmpty()) { - breakBlock(); - progressing = false; - return false; - } - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2 * radius)) { - boolean knockback = false; - for (Block block : wave.keySet()) { - if (entity.getLocation().distance(block.getLocation()) <= 2) { - if (entity.getEntityId() != player.getEntityId() || canhitself) - knockback = true; - } - } - if (knockback) { - Vector dir = direction.clone(); - dir.setY(dir.getY() * upfactor); - entity.setVelocity(entity.getVelocity().clone().add(dir.clone().multiply(factor))); - entity.setFallDistance(0); - if (entity.getFireTicks() > 0) - entity.getWorld().playEffect(entity.getLocation(), Effect.EXTINGUISH, 0); - entity.setFireTicks(0); - } - } - if (!progressing) { - breakBlock(); - return false; - } - if (location.distance(targetdestination) < 1) { - progressing = false; - breakBlock(); - return false; - } - if (radius < maxradius) - radius += .5; - return true; - } - - return false; - } - - private void breakBlock() { - for (Block block : wave.keySet()) { - finalRemoveLava(block); - } - instances.remove(player.getEntityId()); - } - - private void finalRemoveLava(Block block) { - if (wave.containsKey(block)) { - TempBlock.revertBlock(block, Material.AIR); - wave.remove(block); - } - } - - private void addLava(Block block) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "LavaSurge", block.getLocation())) - return; - if (!TempBlock.isTempBlock(block)) { - new TempBlock(block, Material.STATIONARY_LAVA, (byte) 8); - wave.put(block, block); - } - } - - @SuppressWarnings("unused") - private void clearWave() { - for (Block block : wave.keySet()) { - TempBlock.revertBlock(block, Material.AIR); - } - wave.clear(); - } - - public static void moveLava(Player player) { - if (instances.containsKey(player.getEntityId())) { - instances.get(player.getEntityId()).moveLava(); - } - } - - public static boolean isBlockInWave(Block block) { - for (int ID : instances.keySet()) { - if (block.getLocation().distance(instances.get(ID).location) <= 2 * instances.get(ID).radius) { - return true; - } - return false; - } - return false; - } - - public static boolean isBlockWave(Block block) { - for (int ID : instances.keySet()) { - if (instances.get(ID).wave.containsKey(block)) - return true; - } - return false; - } - - public static void launch(Player player) { - moveLava(player); - } - - public static void removeAll() { - for (int id : instances.keySet()) { - for (Block block : instances.get(id).wave.keySet()) { - block.setType(Material.AIR); - instances.get(id).wave.remove(block); - } - for (Block block : instances.get(id).frozenblocks.keySet()) { - block.setType(Material.AIR); - instances.get(id).frozenblocks.remove(block); - } - } - } -} diff --git a/src/com/projectkorra/projectkorra/earthbending/MetalClips.java b/src/com/projectkorra/projectkorra/earthbending/MetalClips.java index 604f1844..61108f30 100644 --- a/src/com/projectkorra/projectkorra/earthbending/MetalClips.java +++ b/src/com/projectkorra/projectkorra/earthbending/MetalClips.java @@ -1,8 +1,9 @@ package com.projectkorra.projectkorra.earthbending; -import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.MetalAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; import org.bukkit.Location; import org.bukkit.Material; @@ -20,241 +21,224 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.ConcurrentHashMap; -public class MetalClips { +public class MetalClips extends MetalAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - public static ConcurrentHashMap clipped = new ConcurrentHashMap(); - public static int armorTime = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.MetalClips.Duration"); - public static int crushInterval = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.MetalClips.DamageInterval");; - public static int cooldown = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.MetalClips.Cooldown"); - public static int crushDamage = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.MetalClips.Damage"); - public static int magnetRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.MetalClips.MagnetRange"); - public static double magnetPower = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.MetalClips.MagnetPower"); - public static Material[] metalItems = { + private static final ConcurrentHashMap ENTITY_CLIPS_COUNT = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap TARGET_TO_ABILITY = new ConcurrentHashMap<>(); + private static final Material[] METAL_ITEMS = { Material.IRON_INGOT, Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS, Material.IRON_BLOCK, Material.IRON_AXE, Material.IRON_PICKAXE, Material.IRON_SWORD, Material.IRON_HOE, Material.IRON_SPADE, Material.IRON_DOOR }; - - private static Player player; - private static LivingEntity targetent; - private boolean isBeingWorn = false; - private boolean isControlling = false; - private boolean canThrow = false; - private boolean magnetized = false; - public int metalclips = 0; - public int var; - private long startTime; + + private boolean isBeingWorn; + private boolean isControlling; + private boolean canThrow; + private boolean isMagnetized; + private boolean canUse4Clips; + private boolean canLoot; + private int metalClipsCount; + private int abilityType; + private int armorTime; + private int crushInterval; + private int crushDamage; + private int magnetRange; + private long armorStartTime; private long time; + private long cooldown; private double lastDistanceCheck; - - private static ItemStack[] oldarmor; - private List trackedIngots = new ArrayList(); - - public MetalClips(Player p, int var) { - if (instances.containsKey(p)) + private double magnetPower; + private double range; + private LivingEntity targetEntity; + private ItemStack[] oldArmor; + private List trackedIngots; + + public MetalClips(Player player, int abilityType) { + super(player); + if (CoreAbility.hasAbility(player, MetalClips.class)) { return; + } - player = p; - canThrow = ((ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.MetalClips.ThrowEnabled") && player.hasPermission("bending.ability.metalclips.throw")) ? true : false); - this.var = var; - - if (!isEligible()) + this.abilityType = abilityType; + this.range = 10; + this.canLoot = player.hasPermission("bending.ability.MetalClips.loot"); + this.canUse4Clips = player.hasPermission("bending.ability.MetalClips.4clips"); + this.armorTime = getConfig().getInt("Abilities.Earth.MetalClips.Duration"); + this.crushInterval = getConfig().getInt("Abilities.Earth.MetalClips.DamageInterval");; + this.cooldown = getConfig().getInt("Abilities.Earth.MetalClips.Cooldown"); + this.crushDamage = getConfig().getInt("Abilities.Earth.MetalClips.Damage"); + this.magnetRange = getConfig().getInt("Abilities.Earth.MetalClips.MagnetRange"); + this.magnetPower = getConfig().getDouble("Abilities.Earth.MetalClips.MagnetPower"); + this.canThrow = (getConfig().getBoolean("Abilities.Earth.MetalClips.ThrowEnabled") && player.hasPermission("bending.ability.metalclips.throw")); + this.trackedIngots = new ArrayList<>(); + + if (!bPlayer.canBend(this)) { return; + } + + if (bPlayer.isAvatarState()) { + cooldown = 0; + range = AvatarState.getValue(range); + crushDamage = AvatarState.getValue(crushDamage); + magnetRange = AvatarState.getValue(magnetRange); + magnetPower = AvatarState.getValue(magnetPower); + } - if (var == 0) + if (abilityType == 0) { shootMetal(); - else if (var == 1) - magnet(); + } else if (abilityType == 1) { + isMagnetized = true; + } - instances.put(p, this); + start(); } public static ItemStack getOriginalHelmet(LivingEntity ent) { - if (clipped.containsKey(ent)) { - return oldarmor[3]; + MetalClips clips = TARGET_TO_ABILITY.get(ent); + if (clips != null) { + return clips.oldArmor[3]; } return null; } public static ItemStack getOriginalChestplate(LivingEntity ent) { - if (clipped.containsKey(ent)) { - return oldarmor[2]; + MetalClips clips = TARGET_TO_ABILITY.get(ent); + if (clips != null) { + return clips.oldArmor[2]; } return null; } public static ItemStack getOriginalLeggings(LivingEntity ent) { - if (clipped.containsKey(ent)) { - return oldarmor[1]; + MetalClips clips = TARGET_TO_ABILITY.get(ent); + if (clips != null) { + return clips.oldArmor[1]; } return null; } public static ItemStack getOriginalBoots(LivingEntity ent) { - if (clipped.containsKey(ent)) { - return oldarmor[0]; + MetalClips clips = TARGET_TO_ABILITY.get(ent); + if (clips != null) { + return clips.oldArmor[0]; } return null; } - public boolean isEligible() { - final BendingPlayer bplayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (!GeneralMethods.canBend(player.getName(), "MetalClips")) - return false; - - if (GeneralMethods.getBoundAbility(player) == null) - return false; - - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("MetalClips")) - return false; - - if (GeneralMethods.isRegionProtectedFromBuild(player, "MetalClips", player.getLocation())) - return false; - - if (!EarthMethods.canMetalbend(player)) - return false; - - if (bplayer.isOnCooldown("MetalClips")) - return false; - - return true; - } - - public void magnet() { - magnetized = true; - } - public void shootMetal() { ItemStack is = new ItemStack(Material.IRON_INGOT, 1); - if (GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("MetalClips")) - return; - if (!player.getInventory().containsAtLeast(is, 1)) { - //ProjectKorra.log.info("Player doesn't have enough ingots!"); remove(); return; } - Item ii = player.getWorld().dropItemNaturally(player.getLocation().add(0, 1, 0), is); + Item item = player.getWorld().dropItemNaturally(player.getLocation().add(0, 1, 0), is); + Vector vector; - Vector v; + Entity targetedEntity = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); + if (targetedEntity != null) { + vector = GeneralMethods.getDirection(player.getLocation(), targetedEntity.getLocation()); + } else { + vector = GeneralMethods.getDirection(player.getLocation(), GeneralMethods.getTargetedLocation(player, range)); + } - if (GeneralMethods.getTargetedEntity(player, 10, new ArrayList()) != null) - v = GeneralMethods.getDirection(player.getLocation(), GeneralMethods.getTargetedEntity(player, 10, new ArrayList()).getLocation()); - else - v = GeneralMethods.getDirection(player.getLocation(), GeneralMethods.getTargetedLocation(player, 10)); - - ii.setVelocity(v.normalize().add(new Vector(0, 0.1, 0).multiply(1.2))); - trackedIngots.add(ii); + item.setVelocity(vector.normalize().add(new Vector(0, 0.1, 0).multiply(1.2))); + trackedIngots.add(item); player.getInventory().removeItem(is); - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("MetalClips", cooldown); + bPlayer.addCooldown(this); } public void formArmor() { - if (metalclips >= 4) + if (metalClipsCount >= 4) { return; - - if (metalclips == 3 && !player.hasPermission("bending.ability.MetalClips.4clips")) + } else if (metalClipsCount == 3 && !canUse4Clips) { return; + } else if (targetEntity != null && GeneralMethods.isRegionProtectedFromBuild(this, targetEntity.getLocation())) { + return; + } - metalclips = (metalclips < 4) ? metalclips + 1 : 4; + metalClipsCount = (metalClipsCount < 4) ? metalClipsCount + 1 : 4; - if (targetent instanceof Player) { - Player target = (Player) targetent; - if (oldarmor == null) - oldarmor = target.getInventory().getArmorContents(); + if (targetEntity instanceof Player) { + Player target = (Player) targetEntity; + if (oldArmor == null) { + oldArmor = target.getInventory().getArmorContents(); + } + + ItemStack[] metalArmor = new ItemStack[4]; + + metalArmor[2] = (metalClipsCount >= 1) ? new ItemStack(Material.IRON_CHESTPLATE, 1) : oldArmor[2]; + metalArmor[0] = (metalClipsCount >= 2) ? new ItemStack(Material.IRON_BOOTS, 1) : oldArmor[0]; + metalArmor[1] = (metalClipsCount >= 3) ? new ItemStack(Material.IRON_LEGGINGS, 1) : oldArmor[1]; + metalArmor[3] = (metalClipsCount >= 4) ? new ItemStack(Material.IRON_HELMET, 1) : oldArmor[3]; + ENTITY_CLIPS_COUNT.put(target, metalClipsCount); + target.getInventory().setArmorContents(metalArmor); + } else { + if (oldArmor == null) { + oldArmor = targetEntity.getEquipment().getArmorContents(); + } ItemStack[] metalarmor = new ItemStack[4]; - metalarmor[2] = (metalclips >= 1) ? new ItemStack(Material.IRON_CHESTPLATE, 1) : oldarmor[2]; - metalarmor[0] = (metalclips >= 2) ? new ItemStack(Material.IRON_BOOTS, 1) : oldarmor[0]; - metalarmor[1] = (metalclips >= 3) ? new ItemStack(Material.IRON_LEGGINGS, 1) : oldarmor[1]; - metalarmor[3] = (metalclips >= 4) ? new ItemStack(Material.IRON_HELMET, 1) : oldarmor[3]; - clipped.put(target, metalclips); - target.getInventory().setArmorContents(metalarmor); + metalarmor[2] = (metalClipsCount >= 1) ? new ItemStack(Material.IRON_CHESTPLATE, 1) : oldArmor[2]; + metalarmor[0] = (metalClipsCount >= 2) ? new ItemStack(Material.IRON_BOOTS, 1) : oldArmor[0]; + metalarmor[1] = (metalClipsCount >= 3) ? new ItemStack(Material.IRON_LEGGINGS, 1) : oldArmor[1]; + metalarmor[3] = (metalClipsCount >= 4) ? new ItemStack(Material.IRON_HELMET, 1) : oldArmor[3]; + ENTITY_CLIPS_COUNT.put(targetEntity, metalClipsCount); + targetEntity.getEquipment().setArmorContents(metalarmor); } - else { - if (oldarmor == null) - oldarmor = targetent.getEquipment().getArmorContents(); - - ItemStack[] metalarmor = new ItemStack[4]; - - metalarmor[2] = (metalclips >= 1) ? new ItemStack(Material.IRON_CHESTPLATE, 1) : oldarmor[2]; - metalarmor[0] = (metalclips >= 2) ? new ItemStack(Material.IRON_BOOTS, 1) : oldarmor[0]; - metalarmor[1] = (metalclips >= 3) ? new ItemStack(Material.IRON_LEGGINGS, 1) : oldarmor[1]; - metalarmor[3] = (metalclips >= 4) ? new ItemStack(Material.IRON_HELMET, 1) : oldarmor[3]; - clipped.put(targetent, metalclips); - targetent.getEquipment().setArmorContents(metalarmor); - } - - if (metalclips == 4) { + if (metalClipsCount == 4) { time = System.currentTimeMillis(); - lastDistanceCheck = player.getLocation().distance(targetent.getLocation()); + lastDistanceCheck = player.getLocation().distance(targetEntity.getLocation()); } - startTime = System.currentTimeMillis(); + armorStartTime = System.currentTimeMillis(); isBeingWorn = true; } public void resetArmor() { - if (targetent == null || oldarmor == null || targetent.isDead()) + if (targetEntity == null || oldArmor == null || targetEntity.isDead()) { return; + } - if (targetent instanceof Player) - ((Player) targetent).getInventory().setArmorContents(oldarmor); - else - targetent.getEquipment().setArmorContents(oldarmor); - - player.getWorld().dropItem(targetent.getLocation(), new ItemStack(Material.IRON_INGOT, metalclips)); + if (targetEntity instanceof Player) { + ((Player) targetEntity).getInventory().setArmorContents(oldArmor); + } else { + targetEntity.getEquipment().setArmorContents(oldArmor); + } + player.getWorld().dropItem(targetEntity.getLocation(), new ItemStack(Material.IRON_INGOT, metalClipsCount)); isBeingWorn = false; } - public void control() { - isControlling = true; - } - - public void ceaseControl() { - isControlling = false; - } - - public boolean controlling() { - return isControlling; - } - public void launch() { - if (!canThrow) + if (!canThrow) { return; + } Location location = player.getLocation(); double dx, dy, dz; - Location target = targetent.getLocation().clone(); + Location target = targetEntity.getLocation().clone(); dx = target.getX() - location.getX(); dy = target.getY() - location.getY(); dz = target.getZ() - location.getZ(); Vector vector = new Vector(dx, dy, dz); vector.normalize(); - targetent.setVelocity(vector.multiply(2)); + targetEntity.setVelocity(vector.multiply(2)); remove(); } + @Override public void progress() { - if (!player.isOnline() || player.isDead()) { + if (!bPlayer.canBendIgnoreCooldowns(this)) { remove(); return; } - if (GeneralMethods.getBoundAbility(player) == null || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("MetalClips")) { - remove(); - return; - } - - if (targetent != null) { - if ((targetent instanceof Player && !((Player) targetent).isOnline()) || targetent.isDead()) { + if (targetEntity != null) { + if ((targetEntity instanceof Player && !((Player) targetEntity).isOnline()) || targetEntity.isDead()) { remove(); return; } @@ -262,141 +246,143 @@ public class MetalClips { if (!player.isSneaking()) { isControlling = false; - magnetized = false; + isMagnetized = false; } - if (magnetized) { + if (isMagnetized) { if (GeneralMethods.getEntitiesAroundPoint(player.getLocation(), magnetRange).size() == 0) { remove(); return; } - for (Entity e : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), magnetRange)) { - Vector v = GeneralMethods.getDirection(e.getLocation(), player.getLocation()); + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), magnetRange)) { + Vector vector = GeneralMethods.getDirection(entity.getLocation(), player.getLocation()); + ItemStack itemInHand = player.getInventory().getItemInHand(); + + if (entity instanceof Player && canLoot && itemInHand.getType() == Material.IRON_INGOT && itemInHand.getItemMeta().getDisplayName().equalsIgnoreCase("Magnet")) { + Player targetPlayer = (Player) entity; - if (e instanceof Player && player.hasPermission("bending.ability.MetalClips.loot") && player.getInventory().getItemInHand().getType() == Material.IRON_INGOT && player.getInventory().getItemInHand().getItemMeta().getDisplayName().equalsIgnoreCase("Magnet")) { - Player p = (Player) e; - - if (p.getEntityId() == player.getEntityId()) + if (targetPlayer.getEntityId() == player.getEntityId()) { continue; + } - ItemStack[] inventory = p.getInventory().getContents(); + ItemStack[] inventory = targetPlayer.getInventory().getContents(); for (ItemStack is : inventory) { - if (is == null) + if (is == null) { continue; - - if (Arrays.asList(metalItems).contains(is.getType())) { - p.getWorld().dropItem(p.getLocation(), is); + } + if (Arrays.asList(METAL_ITEMS).contains(is.getType())) { + targetPlayer.getWorld().dropItem(targetPlayer.getLocation(), is); is.setType(Material.AIR); is.setAmount(0); } } - p.getInventory().setContents(inventory); - ItemStack[] armor = p.getInventory().getArmorContents(); + targetPlayer.getInventory().setContents(inventory); + ItemStack[] armor = targetPlayer.getInventory().getArmorContents(); for (ItemStack is : armor) { - if (Arrays.asList(metalItems).contains(is.getType())) { - p.getWorld().dropItem(p.getLocation(), is); - - is.setType(Material.AIR); - ; - } - } - - p.getInventory().setArmorContents(armor); - if (Arrays.asList(metalItems).contains(p.getInventory().getItemInHand().getType())) { - p.getWorld().dropItem(p.getLocation(), p.getEquipment().getItemInHand()); - p.getEquipment().setItemInHand(new ItemStack(Material.AIR, 1)); - } - } - - if ((e instanceof Zombie || e instanceof Skeleton) && player.hasPermission("bending.ability.MetalClips.loot") && player.getInventory().getItemInHand().getType() == Material.IRON_INGOT && player.getInventory().getItemInHand().getItemMeta().getDisplayName().equalsIgnoreCase("Magnet")) { - LivingEntity le = (LivingEntity) e; - - ItemStack[] armor = le.getEquipment().getArmorContents(); - - for (ItemStack is : armor) { - if (Arrays.asList(metalItems).contains(is.getType())) { - le.getWorld().dropItem(le.getLocation(), is); - + if (Arrays.asList(METAL_ITEMS).contains(is.getType())) { + targetPlayer.getWorld().dropItem(targetPlayer.getLocation(), is); is.setType(Material.AIR); } } - le.getEquipment().setArmorContents(armor); - - if (Arrays.asList(metalItems).contains(le.getEquipment().getItemInHand().getType())) { - le.getWorld().dropItem(le.getLocation(), le.getEquipment().getItemInHand()); - le.getEquipment().setItemInHand(new ItemStack(Material.AIR, 1)); + targetPlayer.getInventory().setArmorContents(armor); + if (Arrays.asList(METAL_ITEMS).contains(targetPlayer.getInventory().getItemInHand().getType())) { + targetPlayer.getWorld().dropItem(targetPlayer.getLocation(), targetPlayer.getEquipment().getItemInHand()); + targetPlayer.getEquipment().setItemInHand(new ItemStack(Material.AIR, 1)); } } - if (e instanceof Item) { - Item iron = (Item) e; + if ((entity instanceof Zombie || entity instanceof Skeleton) + && canLoot + && itemInHand.getType() == Material.IRON_INGOT + && itemInHand.getItemMeta().getDisplayName().equalsIgnoreCase("Magnet")) { + LivingEntity livingEntity = (LivingEntity) entity; - if (Arrays.asList(metalItems).contains(iron.getItemStack().getType())) { - iron.setVelocity(v.normalize().multiply(magnetPower)); + ItemStack[] armor = livingEntity.getEquipment().getArmorContents(); + + for (ItemStack istack : armor) { + if (Arrays.asList(METAL_ITEMS).contains(istack.getType())) { + livingEntity.getWorld().dropItem(livingEntity.getLocation(), istack); + istack.setType(Material.AIR); + } + } + + livingEntity.getEquipment().setArmorContents(armor); + + if (Arrays.asList(METAL_ITEMS).contains(livingEntity.getEquipment().getItemInHand().getType())) { + livingEntity.getWorld().dropItem(livingEntity.getLocation(), livingEntity.getEquipment().getItemInHand()); + livingEntity.getEquipment().setItemInHand(new ItemStack(Material.AIR, 1)); + } + } + + if (entity instanceof Item) { + Item iron = (Item) entity; + + if (Arrays.asList(METAL_ITEMS).contains(iron.getItemStack().getType())) { + iron.setVelocity(vector.normalize().multiply(magnetPower)); } } } } - if (isBeingWorn && System.currentTimeMillis() > startTime + armorTime) { + if (isBeingWorn && System.currentTimeMillis() > armorStartTime + armorTime) { remove(); return; } if (isControlling && player.isSneaking()) { - if (metalclips == 1) { - Location oldLocation = targetent.getLocation(); + if (metalClipsCount == 1) { + Location oldLocation = targetEntity.getLocation(); + Location loc = GeneralMethods.getTargetedLocation(player, (int) player.getLocation().distance(oldLocation)); + double distance = loc.distance(oldLocation); + Vector vector = GeneralMethods.getDirection(targetEntity.getLocation(), player.getLocation()); + + if (distance > 0.5) { + targetEntity.setVelocity(vector.normalize().multiply(0.2)); + } + } + + if (metalClipsCount == 2) { + Location oldLocation = targetEntity.getLocation(); Location loc = GeneralMethods.getTargetedLocation(player, (int) player.getLocation().distance(oldLocation)); double distance = loc.distance(oldLocation); - Vector v = GeneralMethods.getDirection(targetent.getLocation(), player.getLocation()); - - if (distance > .5) - targetent.setVelocity(v.normalize().multiply(0.2)); + Vector vector = GeneralMethods.getDirection(targetEntity.getLocation(), GeneralMethods.getTargetedLocation(player, 10)); + if (distance > 1.2) { + targetEntity.setVelocity(vector.normalize().multiply(0.2)); + } } - if (metalclips == 2) { - Location oldLocation = targetent.getLocation(); + if (metalClipsCount >= 3) { + Location oldLocation = targetEntity.getLocation(); Location loc = GeneralMethods.getTargetedLocation(player, (int) player.getLocation().distance(oldLocation)); double distance = loc.distance(oldLocation); + Vector vector = GeneralMethods.getDirection(oldLocation, GeneralMethods.getTargetedLocation(player, 10)); + + if (distance > 1.2) { + targetEntity.setVelocity(vector.normalize().multiply(.5)); + } else { + targetEntity.setVelocity(new Vector(0, 0, 0)); + } - Vector v = GeneralMethods.getDirection(targetent.getLocation(), GeneralMethods.getTargetedLocation(player, 10)); - - if (distance > 1.2) - targetent.setVelocity(v.normalize().multiply(0.2)); - + targetEntity.setFallDistance(0); } - if (metalclips >= 3) { - Location oldLocation = targetent.getLocation(); - Location loc = GeneralMethods.getTargetedLocation(player, (int) player.getLocation().distance(oldLocation)); - double distance = loc.distance(oldLocation); - - Vector v = GeneralMethods.getDirection(oldLocation, GeneralMethods.getTargetedLocation(player, 10)); - if (distance > 1.2) - targetent.setVelocity(v.normalize().multiply(.5)); - else - targetent.setVelocity(new Vector(0, 0, 0)); - - targetent.setFallDistance(0); - } - - if (metalclips == 4 && player.hasPermission("bending.ability.MetalClips.4clips")) { - double distance = player.getLocation().distance(targetent.getLocation()); + if (metalClipsCount == 4 && canUse4Clips) { + double distance = player.getLocation().distance(targetEntity.getLocation()); if (distance < lastDistanceCheck - 0.3) { - double height = targetent.getLocation().getY(); + double height = targetEntity.getLocation().getY(); if (height > player.getEyeLocation().getY()) { lastDistanceCheck = distance; if (System.currentTimeMillis() > time + crushInterval) { time = System.currentTimeMillis(); - GeneralMethods.damageEntity(player, targetent, (crushDamage + (crushDamage * 1.2)), "MetalClips"); + GeneralMethods.damageEntity(this, targetEntity, (crushDamage + (crushDamage * 1.2))); } } } @@ -419,13 +405,11 @@ public class MetalClips { for (Entity e : GeneralMethods.getEntitiesAroundPoint(ii.getLocation(), 2)) { if (e instanceof LivingEntity && e.getEntityId() != player.getEntityId()) { if (e instanceof Player || e instanceof Zombie || e instanceof Skeleton) { - targetent = (LivingEntity) e; - + targetEntity = (LivingEntity) e; + TARGET_TO_ABILITY.put(targetEntity, this); formArmor(); - } - - else { - GeneralMethods.damageEntity(player, e, 5, "MetalClips"); + } else { + GeneralMethods.damageEntity(this, e, 5); ii.getWorld().dropItem(ii.getLocation(), ii.getItemStack()); remove(); } @@ -448,46 +432,224 @@ public class MetalClips { } } - public LivingEntity getTarget() { - return targetent; - } - + @Override public void remove() { + super.remove(); for (Item i : trackedIngots) { i.remove(); } + resetArmor(); trackedIngots.clear(); - instances.remove(player); - metalclips = 0; - if (targetent != null) - clipped.remove(targetent); - } - - public static void removeAll() { - for (Player p : instances.keySet()) { - instances.get(p).remove(); - } - if (!clipped.isEmpty()) - clipped.clear(); - } - - public static void progressAll() { - for (Player p : instances.keySet()) { - instances.get(p).progress(); + metalClipsCount = 0; + + if (targetEntity != null) { + ENTITY_CLIPS_COUNT.remove(targetEntity); + TARGET_TO_ABILITY.remove(targetEntity); } } public static boolean isControlled(Player player) { - for (Player p : instances.keySet()) { - if (instances.get(p).getTarget() != null && instances.get(p).getTarget().getEntityId() == player.getEntityId()) { - return true; - } - } - return false; + return TARGET_TO_ABILITY.containsKey(player); } public static boolean isControllingEntity(Player player) { - return (instances.containsKey(player) && player.isSneaking() && targetent != null); + MetalClips clips = CoreAbility.getAbility(player, MetalClips.class); + return clips != null && player.isSneaking() && clips.targetEntity != null; } + + public static ConcurrentHashMap getEntityClipsCount() { + return ENTITY_CLIPS_COUNT; + } + + public static ConcurrentHashMap getTargetToAbility() { + return TARGET_TO_ABILITY; + } + + @Override + public String getName() { + return "MetalClips"; + } + + @Override + public Location getLocation() { + if (targetEntity != null) { + return targetEntity.getLocation(); + } else if (player != null) { + return player.getLocation(); + } + return null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isBeingWorn() { + return isBeingWorn; + } + + public void setBeingWorn(boolean isBeingWorn) { + this.isBeingWorn = isBeingWorn; + } + + public boolean isControlling() { + return isControlling; + } + + public void setControlling(boolean isControlling) { + this.isControlling = isControlling; + } + + public boolean isCanThrow() { + return canThrow; + } + + public void setCanThrow(boolean canThrow) { + this.canThrow = canThrow; + } + + public boolean isMagnetized() { + return isMagnetized; + } + + public void setMagnetized(boolean isMagnetized) { + this.isMagnetized = isMagnetized; + } + + public boolean isCanUse4Clips() { + return canUse4Clips; + } + + public void setCanUse4Clips(boolean canUse4Clips) { + this.canUse4Clips = canUse4Clips; + } + + public boolean isCanLoot() { + return canLoot; + } + + public void setCanLoot(boolean canLoot) { + this.canLoot = canLoot; + } + + public int getMetalClipsCount() { + return metalClipsCount; + } + + public void setMetalClipsCount(int metalClipsCount) { + this.metalClipsCount = metalClipsCount; + } + + public int getAbilityType() { + return abilityType; + } + + public void setAbilityType(int abilityType) { + this.abilityType = abilityType; + } + + public int getArmorTime() { + return armorTime; + } + + public void setArmorTime(int armorTime) { + this.armorTime = armorTime; + } + + public int getCrushInterval() { + return crushInterval; + } + + public void setCrushInterval(int crushInterval) { + this.crushInterval = crushInterval; + } + + public int getCrushDamage() { + return crushDamage; + } + + public void setCrushDamage(int crushDamage) { + this.crushDamage = crushDamage; + } + + public int getMagnetRange() { + return magnetRange; + } + + public void setMagnetRange(int magnetRange) { + this.magnetRange = magnetRange; + } + + public long getArmorStartTime() { + return armorStartTime; + } + + public void setArmorStartTime(long armorStartTime) { + this.armorStartTime = armorStartTime; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public double getLastDistanceCheck() { + return lastDistanceCheck; + } + + public void setLastDistanceCheck(double lastDistanceCheck) { + this.lastDistanceCheck = lastDistanceCheck; + } + + public double getMagnetPower() { + return magnetPower; + } + + public void setMagnetPower(double magnetPower) { + this.magnetPower = magnetPower; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public LivingEntity getTargetEntity() { + return targetEntity; + } + + public void setTargetEntity(LivingEntity targetEntity) { + this.targetEntity = targetEntity; + } + + public ItemStack[] getOldArmor() { + return oldArmor; + } + + public List getTrackedIngots() { + return trackedIngots; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/earthbending/RaiseEarth.java b/src/com/projectkorra/projectkorra/earthbending/RaiseEarth.java new file mode 100644 index 00000000..c0c4088c --- /dev/null +++ b/src/com/projectkorra/projectkorra/earthbending/RaiseEarth.java @@ -0,0 +1,259 @@ +package com.projectkorra.projectkorra.earthbending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.EarthAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.configuration.ConfigManager; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.ClickType; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.concurrent.ConcurrentHashMap; + +public class RaiseEarth extends EarthAbility { + + private static final ConcurrentHashMap ALL_AFFECTED_BLOCKS = new ConcurrentHashMap<>(); + + private int distance; + private int height; + private long time; + private long interval; + private long cooldown; + private double range; + private double speed; + private Block block; + private Vector direction; + private Location origin; + private Location location; + private ConcurrentHashMap affectedBlocks; + + public RaiseEarth(Player player) { + super(player); + setFields(); + + if (!bPlayer.canBend(this)) { + return; + } + + try { + if (bPlayer.isAvatarState()) { + height = (int) (2.0 / 5.0 * (double) AvatarState.getValue(height)); + } + block = BlockSource.getEarthSourceBlock(player, range, ClickType.LEFT_CLICK); + if (block == null) { + return; + } + + origin = block.getLocation(); + location = origin.clone(); + distance = getEarthbendableBlocksLength(block, direction.clone().multiply(-1), height); + } + catch (IllegalStateException e) { + return; + } + + loadAffectedBlocks(); + + if (distance != 0 && canInstantiate()) { + bPlayer.addCooldown(this); + time = System.currentTimeMillis() - interval; + start(); + } + } + + public RaiseEarth(Player player, Location origin) { + this(player, origin, ConfigManager.getConfig().getInt("Abilities.Earth.RaiseEarth.Column.Height")); + } + + public RaiseEarth(Player player, Location origin, int height) { + super(player); + setFields(); + + this.height = height; + this.origin = origin; + this.location = origin.clone(); + this.block = location.getBlock(); + this.distance = getEarthbendableBlocksLength(block, direction.clone().multiply(-1), height); + + loadAffectedBlocks(); + + if (distance != 0 && canInstantiate()) { + time = System.currentTimeMillis() - interval; + start(); + } + } + + private void setFields() { + this.height = getConfig().getInt("Abilities.Earth.RaiseEarth.Column.Height"); + this.range = 20; + this.speed = 8; + this.direction = new Vector(0, 1, 0); + this.interval = (long) (1000.0 / speed); + this.cooldown = GeneralMethods.getGlobalCooldown(); + this.affectedBlocks = new ConcurrentHashMap(); + } + + private boolean canInstantiate() { + for (Block block : affectedBlocks.keySet()) { + if (block.getType() == Material.AIR || ALL_AFFECTED_BLOCKS.containsKey(block)) { + return false; + } + } + return true; + } + + private void loadAffectedBlocks() { + affectedBlocks.clear(); + Block thisBlock; + for (int i = 0; i <= distance; i++) { + thisBlock = block.getWorld().getBlockAt(location.clone().add(direction.clone().multiply(-i))); + affectedBlocks.put(thisBlock, thisBlock); + if (Collapse.blockInAllAffectedBlocks(thisBlock)) { + Collapse.revert(thisBlock); + } + } + } + + @Override + public void progress() { + if (System.currentTimeMillis() - time >= interval) { + time = System.currentTimeMillis(); + Block block = location.getBlock(); + location = location.add(direction); + moveEarth(block, direction, distance); + loadAffectedBlocks(); + + if (location.distanceSquared(origin) >= distance * distance) { + remove(); + return; + } + } + } + + public static boolean blockInAllAffectedBlocks(Block block) { + return ALL_AFFECTED_BLOCKS.containsKey(block); + } + + public static void revertAffectedBlock(Block block) { + ALL_AFFECTED_BLOCKS.remove(block); + for (RaiseEarth raiseEarth : CoreAbility.getAbilities(RaiseEarth.class)) { + raiseEarth.affectedBlocks.remove(block); + } + } + + @Override + public String getName() { + return "RaiseEarth"; + } + + @Override + public Location getLocation() { + return location; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public int getDistance() { + return distance; + } + + public void setDistance(int distance) { + this.distance = distance; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public Block getBlock() { + return block; + } + + public void setBlock(Block block) { + this.block = block; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public ConcurrentHashMap getAffectedBlocks() { + return affectedBlocks; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/earthbending/RaiseEarthWall.java b/src/com/projectkorra/projectkorra/earthbending/RaiseEarthWall.java new file mode 100644 index 00000000..2df9f5e0 --- /dev/null +++ b/src/com/projectkorra/projectkorra/earthbending/RaiseEarthWall.java @@ -0,0 +1,154 @@ +package com.projectkorra.projectkorra.earthbending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.EarthAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.ClickType; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +public class RaiseEarthWall extends EarthAbility { + + private int range; + private int height; + private int width; + private long cooldown; + private Location location; + + public RaiseEarthWall(Player player) { + super(player); + this.range = getConfig().getInt("Abilities.Earth.RaiseEarth.Wall.Range"); + this.height = getConfig().getInt("Abilities.Earth.RaiseEarth.Wall.Height"); + this.width = getConfig().getInt("Abilities.Earth.RaiseEarth.Wall.Width"); + this.cooldown = GeneralMethods.getGlobalCooldown(); + + if (!bPlayer.canBend(this)) { + return; + } + + if (bPlayer.isAvatarState()) { + height = (int) (2.0 / 5.0 * (double) AvatarState.getValue(height)); + width = AvatarState.getValue(width); + } + + Vector direction = player.getEyeLocation().getDirection().normalize(); + double ox, oy, oz; + ox = -direction.getZ(); + oy = 0; + oz = direction.getX(); + + Vector orth = new Vector(ox, oy, oz); + orth = orth.normalize(); + + Block sblock = BlockSource.getEarthSourceBlock(player, range, ClickType.SHIFT_DOWN); + + if (sblock == null) { + location = getTargetEarthBlock(range).getLocation(); + } else { + location = sblock.getLocation(); + } + + World world = location.getWorld(); + boolean cooldown = false; + + for (int i = -width / 2; i <= width / 2; i++) { + Block block = world.getBlockAt(location.clone().add(orth.clone().multiply((double) i))); + + if (isTransparent(block)) { + for (int j = 1; j < height; j++) { + block = block.getRelative(BlockFace.DOWN); + if (isEarthbendable(block)) { + cooldown = true; + new RaiseEarth(player, block.getLocation(), height); + } else if (!isTransparent(block)) { + break; + } + } + } else if (isEarthbendable(block.getRelative(BlockFace.UP))) { + for (int j = 1; j < height; j++) { + block = block.getRelative(BlockFace.UP); + if (isTransparent(block)) { + cooldown = true; + new RaiseEarth(player, block.getRelative(BlockFace.DOWN).getLocation(), height); + } else if (!isEarthbendable(block)) { + break; + } + } + } else if (isEarthbendable(block)) { + cooldown = true; + new RaiseEarth(player, block.getLocation(), height); + } + } + + if (cooldown) { + bPlayer.addCooldown(this); + } + } + + @Override + public String getName() { + return "RaiseEarth"; + } + + @Override + public void progress() {} + + @Override + public Location getLocation() { + return location; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public int getRange() { + return range; + } + + public void setRange(int range) { + this.range = range; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/earthbending/Ripple.java b/src/com/projectkorra/projectkorra/earthbending/Ripple.java index f7421e79..386013de 100644 --- a/src/com/projectkorra/projectkorra/earthbending/Ripple.java +++ b/src/com/projectkorra/projectkorra/earthbending/Ripple.java @@ -1,9 +1,9 @@ package com.projectkorra.projectkorra.earthbending; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.airbending.AirMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.EarthAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; import org.bukkit.Location; import org.bukkit.block.Block; @@ -17,67 +17,79 @@ import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.concurrent.ConcurrentHashMap; -public class Ripple { +public class Ripple extends EarthAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - private static ConcurrentHashMap blocks = new ConcurrentHashMap(); + private static final ConcurrentHashMap BLOCKS = new ConcurrentHashMap(); - static final double RADIUS = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Shockwave.Range"); - private static final double DAMAGE = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Shockwave.Damage"); - private static int ID = Integer.MIN_VALUE; - private static double KNOCKBACK = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Shockwave.Knockback"); - - private Player player; + private int step; + private int maxStep; + private double range; + private double damage; + private double knockback; private Vector direction; - private Location origin, location; - private Block block1, block2, block3, block4; - private int id; - private int step = 0; - private int maxstep; - private double radius = RADIUS; - private double damage = DAMAGE; - private double knockback = KNOCKBACK; + private Location origin; + private Location location; + private Block block1; + private Block block2; + private Block block3; + private Block block4; private ArrayList locations = new ArrayList(); private ArrayList entities = new ArrayList(); public Ripple(Player player, Vector direction) { - this(player, getInitialLocation(player, direction), direction); + super(player); + initialize(player, getInitialLocation(player, direction), direction); } public Ripple(Player player, Location origin, Vector direction) { - this.player = player; - if (origin == null) + super(player); + initialize(player, origin, direction); + } + + private void initialize(Player player, Location origin, Vector direction) { + if (origin == null) { return; + } + + this.range = getConfig().getDouble("Abilities.Earth.Shockwave.Range"); + this.damage = getConfig().getDouble("Abilities.Earth.Shockwave.Damage"); + this.knockback = getConfig().getDouble("Abilities.Earth.Shockwave.Knockback"); this.direction = direction.clone().normalize(); this.origin = origin.clone(); this.location = origin.clone(); + this.locations = new ArrayList<>(); + this.entities = new ArrayList<>(); - initializeLocations(); - maxstep = locations.size(); - - if (EarthMethods.isEarthbendable(player, origin.getBlock())) { - id = ID++; - if (ID >= Integer.MAX_VALUE) - ID = Integer.MIN_VALUE; - instances.put(id, this); + if (bPlayer.isAvatarState()) { + range = AvatarState.getValue(range); + damage = AvatarState.getValue(damage); + knockback = AvatarState.getValue(knockback); } + initializeLocations(); + maxStep = locations.size(); + + if (isEarthbendable(origin.getBlock())) { + start(); + } } - private static Location getInitialLocation(Player player, Vector direction) { + private Location getInitialLocation(Player player, Vector direction) { Location location = player.getLocation().clone().add(0, -1, 0); direction = direction.normalize(); - Block block1 = location.getBlock(); - while (location.getBlock().equals(block1)) + while (location.getBlock().equals(block1)) { location = location.clone().add(direction); + } + for (int i : new int[] { 1, 2, 3, 0, -1 }) { Location loc; loc = location.clone().add(0, i, 0); - Block topblock = loc.getBlock(); - Block botblock = loc.clone().add(0, -1, 0).getBlock(); - if (EarthMethods.isTransparentToEarthbending(player, topblock) && EarthMethods.isEarthbendable(player, botblock)) { + Block topBlock = loc.getBlock(); + Block botBlock = loc.clone().add(0, -1, 0).getBlock(); + + if (isTransparent(topBlock) && isEarthbendable(botBlock)) { location = loc.clone().add(0, -1, 0); return location; } @@ -86,19 +98,14 @@ public class Ripple { return null; } - private void progress() { - - if (step < maxstep) { + @Override + public void progress() { + if (step < maxStep) { Location newlocation = locations.get(step); Block block = location.getBlock(); location = newlocation.clone(); + if (!newlocation.getBlock().equals(block)) { - // if (block2 != null) - // block1 = block2; - // if (block3 != null) - // block2 = block3; - // if (block4 != null) - // block3 = block4; block1 = block2; block2 = block3; block3 = block4; @@ -122,87 +129,85 @@ public class Ripple { } if (step == 0) { - - if (increase(block4)) + if (increase(block4)) { block4 = block4.getRelative(BlockFace.UP); - + } } else if (step == 1) { - - if (increase(block3)) + if (increase(block3)) { block3 = block3.getRelative(BlockFace.UP); - if (increase(block4)) + } + if (increase(block4)) { block4 = block4.getRelative(BlockFace.UP); - + } } else if (step == 2) { - - if (decrease(block2)) + if (decrease(block2)) { block2 = block2.getRelative(BlockFace.DOWN); - if (increase(block3)) + } + if (increase(block3)) { block3 = block3.getRelative(BlockFace.UP); - if (increase(block4)) + } + if (increase(block4)) { block4 = block4.getRelative(BlockFace.UP); - + } } else { - - if (decrease(block1)) + if (decrease(block1)) { block1 = block1.getRelative(BlockFace.DOWN); - if (decrease(block2)) + } + if (decrease(block2)) { block2 = block2.getRelative(BlockFace.DOWN); - if (increase(block3)) + } + if (increase(block3)) { block3 = block3.getRelative(BlockFace.UP); - if (increase(block4)) + } + if (increase(block4)) { block4 = block4.getRelative(BlockFace.UP); - + } } } - } else if (step == maxstep) { - - if (decrease(block2)) + } else if (step == maxStep) { + if (decrease(block2)) { block2 = block2.getRelative(BlockFace.DOWN); - if (decrease(block3)) + } + if (decrease(block3)) { block3 = block3.getRelative(BlockFace.DOWN); - if (increase(block4)) + } + if (increase(block4)) { block4 = block4.getRelative(BlockFace.UP); - - } else if (step == maxstep + 1) { - - if (decrease(block3)) + } + } else if (step == maxStep + 1) { + if (decrease(block3)) { block3 = block3.getRelative(BlockFace.DOWN); - if (decrease(block4)) + } + if (decrease(block4)) { block4 = block4.getRelative(BlockFace.DOWN); - - } else if (step == maxstep + 2) { - - if (decrease(block4)) + } + } else if (step == maxStep + 2) { + if (decrease(block4)) { block4 = block4.getRelative(BlockFace.DOWN); + } remove(); - } step += 1; - - for (Entity entity : entities) + for (Entity entity : entities) { affect(entity); + } entities.clear(); - - } - - private void remove() { - instances.remove(id); } private void initializeLocations() { Location location = origin.clone(); locations.add(location); - while (location.distance(origin) < radius) { + while (location.distanceSquared(origin) < range * range) { location = location.clone().add(direction); for (int i : new int[] { 1, 2, 3, 0, -1 }) { Location loc; loc = location.clone().add(0, i, 0); Block topblock = loc.getBlock(); Block botblock = loc.clone().add(0, -1, 0).getBlock(); - if (EarthMethods.isTransparentToEarthbending(player, topblock) && !topblock.isLiquid() && EarthMethods.isEarthbendable(player, botblock)) { + + if (isTransparent(topblock) && !topblock.isLiquid() && isEarthbendable(botblock)) { location = loc.clone().add(0, -1, 0); locations.add(location); break; @@ -214,36 +219,43 @@ public class Ripple { } private boolean decrease(Block block) { - if (block == null) + if (block == null) { return false; - if (hasAnyMoved(block)) + } else if (hasAnyMoved(block)) { return false; - setMoved(block); - Block botblock = block.getRelative(BlockFace.DOWN); - int length = 1; - if (EarthMethods.isEarthbendable(player, botblock)) { - length = 2; - block = botblock; } - return EarthMethods.moveEarth(player, block, new Vector(0, -1, 0), length, false); + + setMoved(block); + Block botBlock = block.getRelative(BlockFace.DOWN); + int length = 1; + + if (isEarthbendable(botBlock)) { + length = 2; + block = botBlock; + } + return moveEarth(block, new Vector(0, -1, 0), length, false); } private boolean increase(Block block) { - if (block == null) + if (block == null) { return false; - if (hasAnyMoved(block)) + } else if (hasAnyMoved(block)) { return false; + } + setMoved(block); Block botblock = block.getRelative(BlockFace.DOWN); int length = 1; - if (EarthMethods.isEarthbendable(player, botblock)) { + + if (isEarthbendable(botblock)) { length = 2; } - if (EarthMethods.moveEarth(player, block, new Vector(0, 1, 0), length, false)) { + if (moveEarth(block, new Vector(0, 1, 0), length, false)) { for (Entity entity : GeneralMethods.getEntitiesAroundPoint(block.getLocation().clone().add(0, 1, 0), 2)) { if (entity.getEntityId() != player.getEntityId() && !entities.contains(entity)) { - if (!(entity instanceof FallingBlock)) + if (!(entity instanceof FallingBlock)) { entities.add(entity); + } } } return true; @@ -252,57 +264,89 @@ public class Ripple { } private void affect(Entity entity) { - if (entity instanceof LivingEntity) { - GeneralMethods.damageEntity(player, entity, damage, "Shockwave"); + GeneralMethods.damageEntity(this, entity, damage); } Vector vector = direction.clone(); vector.setY(.5); - double knock = AvatarState.isAvatarState(player) ? AvatarState.getValue(knockback) : knockback; + double knock = bPlayer.isAvatarState() ? AvatarState.getValue(knockback) : knockback; entity.setVelocity(vector.clone().normalize().multiply(knock)); - - AirMethods.breakBreathbendingHold(entity); - + AirAbility.breakBreathbendingHold(entity); } private static void setMoved(Block block) { int x = block.getX(); int z = block.getZ(); Integer[] pair = new Integer[] { x, z }; - blocks.put(pair, block); + BLOCKS.put(pair, block); } private static boolean hasAnyMoved(Block block) { int x = block.getX(); int z = block.getZ(); Integer[] pair = new Integer[] { x, z }; - if (blocks.containsKey(pair)) + if (BLOCKS.containsKey(pair)) { return true; + } return false; } - public static void progressAll() { - blocks.clear(); - for (int id : instances.keySet()) - instances.get(id).progress(); + public static void progressAllCleanup() { + BLOCKS.clear(); } - public static void removeAll() { - instances.clear(); - + public static ConcurrentHashMap getBlocks() { + return BLOCKS; } - public Player getPlayer() { - return player; + @Override + public String getName() { + return "Shockwave"; } - public double getRadius() { - return radius; + @Override + public Location getLocation() { + return location; } - public void setRadius(double radius) { - this.radius = radius; + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public int getStep() { + return step; + } + + public void setStep(int step) { + this.step = step; + } + + public int getMaxStep() { + return maxStep; + } + + public void setMaxStep(int maxStep) { + this.maxStep = maxStep; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; } public double getDamage() { @@ -321,4 +365,64 @@ public class Ripple { this.knockback = knockback; } + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public Block getBlock1() { + return block1; + } + + public void setBlock1(Block block1) { + this.block1 = block1; + } + + public Block getBlock2() { + return block2; + } + + public void setBlock2(Block block2) { + this.block2 = block2; + } + + public Block getBlock3() { + return block3; + } + + public void setBlock3(Block block3) { + this.block3 = block3; + } + + public Block getBlock4() { + return block4; + } + + public void setBlock4(Block block4) { + this.block4 = block4; + } + + public ArrayList getLocations() { + return locations; + } + + public ArrayList getEntities() { + return entities; + } + + public void setLocation(Location location) { + this.location = location; + } + } diff --git a/src/com/projectkorra/projectkorra/earthbending/SandSpout.java b/src/com/projectkorra/projectkorra/earthbending/SandSpout.java index 7fbe1f1e..99662e38 100644 --- a/src/com/projectkorra/projectkorra/earthbending/SandSpout.java +++ b/src/com/projectkorra/projectkorra/earthbending/SandSpout.java @@ -1,7 +1,8 @@ package com.projectkorra.projectkorra.earthbending; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.SandAbility; import com.projectkorra.projectkorra.util.Flight; import org.bukkit.Location; @@ -12,71 +13,74 @@ import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import java.util.ArrayList; import java.util.Collection; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Random; -public class SandSpout { +public class SandSpout extends SandAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - - private static final double HEIGHT = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.SandSpout.Height"); - private static final int BTIME = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.SandSpout.BlindnessTime"); - private static final int SPOUTDAMAGE = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.SandSpout.SpoutDamage"); - private static final boolean SPIRAL = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth.SandSpout.Spiral"); - private static final long interval = 100; - - private Player player; + private boolean canSpiral; + private int angle; + private int blindnessTime; private long time; - private int angle = 0; - private double height = HEIGHT; - private int bTime = BTIME; - private double spoutDamage = SPOUTDAMAGE; - private double y = 0D; - + private long interval; + private long cooldown; + private double damage; + private double height; + private double currentHeight; + private Flight flight; + public SandSpout(Player player) { - - if (instances.containsKey(player)) { - instances.get(player).remove(); + super(player); + + this.currentHeight = 0; + this.angle = 0; + this.interval = 100; + this.cooldown = 0; + this.canSpiral = getConfig().getBoolean("Abilities.Earth.SandSpout.Spiral"); + this.height = getConfig().getDouble("Abilities.Earth.SandSpout.Height"); + this.blindnessTime = getConfig().getInt("Abilities.Earth.SandSpout.BlindnessTime"); + this.damage = getConfig().getInt("Abilities.Earth.SandSpout.SpoutDamage"); + + SandSpout oldSandSpout = CoreAbility.getAbility(player, SandSpout.class); + if (oldSandSpout != null) { + oldSandSpout.remove(); return; } - this.player = player; + + if (!bPlayer.canBend(this)) { + return; + } + time = System.currentTimeMillis(); Block topBlock = GeneralMethods.getTopBlock(player.getLocation(), 0, -50); - if (topBlock == null) + if (topBlock == null) { topBlock = player.getLocation().getBlock(); - Material mat = topBlock.getType(); - if (mat != Material.SAND && mat != Material.SANDSTONE && mat != Material.RED_SANDSTONE) - return; - new Flight(player); - instances.put(player, this); - spout(); - } - - public static void spoutAll() { - for (Player player : instances.keySet()) { - instances.get(player).spout(); } + + Material mat = topBlock.getType(); + if (mat != Material.SAND && mat != Material.SANDSTONE && mat != Material.RED_SANDSTONE) { + return; + } + + flight = new Flight(player); + start(); + bPlayer.addCooldown(this); } - public static ArrayList getPlayers() { - ArrayList players = new ArrayList(); - players.addAll(instances.keySet()); - return players; - } - - private void spout() { - if (!GeneralMethods.canBend(player.getName(), "SandSpout") - // || !Methods.hasAbility(player, Abilities.SandSpout) - || player.getEyeLocation().getBlock().isLiquid() || GeneralMethods.isSolid(player.getEyeLocation().getBlock()) || player.isDead() || !player.isOnline()) { + @Override + public void progress() { + Block eyeBlock = player.getEyeLocation().getBlock(); + if (!bPlayer.canBendIgnoreBindsCooldowns(this) || eyeBlock.isLiquid() || GeneralMethods.isSolid(eyeBlock)) { remove(); return; } + player.setFallDistance(0); player.setSprinting(false); - if (GeneralMethods.rand.nextInt(2) == 0) { - EarthMethods.playSandBendingSound(player.getLocation()); + if ((new Random()).nextInt(2) == 0) { + playSandBendingSound(player.getLocation()); } + Block block = getGround(); if (block != null && (block.getType() == Material.SAND || block.getType() == Material.SANDSTONE || block.getType() == Material.RED_SANDSTONE)) { double dy = player.getLocation().getY() - block.getY(); @@ -115,91 +119,95 @@ public class SandSpout { @SuppressWarnings("deprecation") private void rotateSandColumn(Block block) { - if (System.currentTimeMillis() >= time + interval) { time = System.currentTimeMillis(); Location location = block.getLocation(); - Location playerloc = player.getLocation(); - location = new Location(location.getWorld(), playerloc.getX(), location.getY(), playerloc.getZ()); + Location playerLoc = player.getLocation(); + location = new Location(location.getWorld(), playerLoc.getX(), location.getY(), playerLoc.getZ()); - double dy = playerloc.getY() - block.getY(); - if (dy > height) + double dy = playerLoc.getY() - block.getY(); + if (dy > height) { dy = height; + } + Integer[] directions = { 0, 1, 2, 3, 5, 6, 7, 8 }; int index = angle; angle++; - if (angle >= directions.length) + if (angle >= directions.length) { angle = 0; + } for (int i = 1; i <= dy; i++) { - index += 1; - if (index >= directions.length) + if (index >= directions.length) { index = 0; + } Location effectloc2 = new Location(location.getWorld(), location.getX(), block.getY() + i, location.getZ()); - if (SPIRAL) { + if (canSpiral) { displayHelix(block.getLocation(), this.player.getLocation(), block); } if (block != null && ((block.getType() == Material.SAND && block.getData() == (byte) 0) || block.getType() == Material.SANDSTONE)) { - EarthMethods.displaySandParticle(effectloc2, 1f, 3f, 1f, 20, .2f, false); + displaySandParticle(effectloc2, 1f, 3f, 1f, 20, .2f, false); } else if (block != null && ((block.getType() == Material.SAND && block.getData() == (byte) 1) || block.getType() == Material.RED_SANDSTONE)) { - EarthMethods.displaySandParticle(effectloc2, 1f, 3f, 1f, 20, .2f, true); + displaySandParticle(effectloc2, 1f, 3f, 1f, 20, .2f, true); } Collection players = GeneralMethods.getPlayersAroundPoint(effectloc2, 1.5f); - if (!players.isEmpty()) + if (!players.isEmpty()) { for (Player sPlayer : players) { if (!sPlayer.equals(player)) { - sPlayer.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, bTime * 20, 1)); - GeneralMethods.damageEntity(player, sPlayer, spoutDamage, "SandSpout"); + sPlayer.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, blindnessTime * 20, 1)); + GeneralMethods.damageEntity(this, sPlayer, damage); } } + } } } } @SuppressWarnings("deprecation") private void displayHelix(Location location, Location player, Block block) { - // TODO Auto-generated method stub - //double radius = 1.5; - this.y += 0.1; - if (this.y >= player.getY() - location.getY()) { - this.y = 0D; + this.currentHeight += 0.1; + if (this.currentHeight >= player.getY() - location.getY()) { + this.currentHeight = 0D; } + for (int points = 0; points <= 5; points++) { - double x = Math.cos(y); - double z = Math.sin(y); + double x = Math.cos(currentHeight); + double z = Math.sin(currentHeight); double nx = x * -1; double nz = z * -1; - Location newloc = new Location(player.getWorld(), location.getX() + x, location.getY() + y, location.getZ() + z); - Location secondloc = new Location(player.getWorld(), location.getX() + nx, location.getY() + y, location.getZ() + nz); + Location newLoc = new Location(player.getWorld(), location.getX() + x, location.getY() + currentHeight, location.getZ() + z); + Location secondLoc = new Location(player.getWorld(), location.getX() + nx, location.getY() + currentHeight, location.getZ() + nz); + if (block != null && ((block.getType() == Material.SAND && block.getData() == (byte) 0) || block.getType() == Material.SANDSTONE)) { - EarthMethods.displaySandParticle(newloc.add(0.5, 0.5, 0.5), 0.1F, 0.1F, 0.1F, 2, 1, false); - EarthMethods.displaySandParticle(secondloc.add(0.5, 0.5, 0.5), 0.1F, 0.1F, 0.1F, 2, 1, false); + displaySandParticle(newLoc.add(0.5, 0.5, 0.5), 0.1F, 0.1F, 0.1F, 2, 1, false); + displaySandParticle(secondLoc.add(0.5, 0.5, 0.5), 0.1F, 0.1F, 0.1F, 2, 1, false); } else if (block != null && ((block.getType() == Material.SAND && block.getData() == (byte) 1) || block.getType() == Material.RED_SANDSTONE)) { - EarthMethods.displaySandParticle(newloc.add(0.5, 0.5, 0.5), 0.1F, 0.1F, 0.1F, 2, 1, true); - EarthMethods.displaySandParticle(secondloc.add(0.5, 0.5, 0.5), 0.1F, 0.1F, 0.1F, 2, 1, true); + displaySandParticle(newLoc.add(0.5, 0.5, 0.5), 0.1F, 0.1F, 0.1F, 2, 1, true); + displaySandParticle(secondLoc.add(0.5, 0.5, 0.5), 0.1F, 0.1F, 0.1F, 2, 1, true); } } } - public static boolean removeSpouts(Location loc0, double radius, Player sourceplayer) { + public static boolean removeSpouts(Location location, double radius, Player sourcePlayer) { boolean removed = false; - for (Player player : instances.keySet()) { - if (!player.equals(sourceplayer)) { + for (SandSpout spout : CoreAbility.getAbilities(SandSpout.class)) { + Player player = spout.player; + if (!player.equals(sourcePlayer)) { Location loc1 = player.getLocation().getBlock().getLocation(); - loc0 = loc0.getBlock().getLocation(); - double dx = loc1.getX() - loc0.getX(); - double dy = loc1.getY() - loc0.getY(); - double dz = loc1.getZ() - loc0.getZ(); + location = location.getBlock().getLocation(); + double dx = loc1.getX() - location.getX(); + double dy = loc1.getY() - location.getY(); + double dz = loc1.getZ() - location.getZ(); double distance = Math.sqrt(dx * dx + dz * dz); - if (distance <= radius && dy > 0 && dy < HEIGHT) { - instances.get(player).remove(); + if (distance <= radius && dy > 0 && dy < spout.height) { + spout.remove(); removed = true; } } @@ -207,20 +215,84 @@ public class SandSpout { return removed; } - private void remove() { + @Override + public void remove() { + super.remove(); + flight.revert(); removeFlight(); - player.setFlySpeed(.1f); - instances.remove(player); } - public static void removeAll() { - for (Player player : instances.keySet()) { - instances.get(player).remove(); - } + @Override + public String getName() { + return "SandSpout"; } - public Player getPlayer() { - return player; + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isCanSpiral() { + return canSpiral; + } + + public void setCanSpiral(boolean canSpiral) { + this.canSpiral = canSpiral; + } + + public int getAngle() { + return angle; + } + + public void setAngle(int angle) { + this.angle = angle; + } + + public int getBlindnessTime() { + return blindnessTime; + } + + public void setBlindnessTime(int blindnessTime) { + this.blindnessTime = blindnessTime; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public double getDamage() { + return damage; + } + + public void setDamage(double damage) { + this.damage = damage; } public double getHeight() { @@ -231,4 +303,16 @@ public class SandSpout { this.height = height; } + public double getCurrentHeight() { + return currentHeight; + } + + public void setCurrentHeight(double currentHeight) { + this.currentHeight = currentHeight; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/earthbending/Shockwave.java b/src/com/projectkorra/projectkorra/earthbending/Shockwave.java index d87ec677..429cde3a 100644 --- a/src/com/projectkorra/projectkorra/earthbending/Shockwave.java +++ b/src/com/projectkorra/projectkorra/earthbending/Shockwave.java @@ -1,144 +1,180 @@ package com.projectkorra.projectkorra.earthbending; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.EarthAbility; import org.bukkit.Effect; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; - -public class Shockwave { - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - - private static final double angle = Math.toRadians(40); - private static final long defaultchargetime = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.Shockwave.ChargeTime"); - private static final double threshold = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Shockwave.FallThreshold"); - - private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.Shockwave.Cooldown"); - private Player player; - private long starttime; - private long chargetime = defaultchargetime; - private boolean charged = false; +public class Shockwave extends EarthAbility { + + private boolean charged; + private long chargeTime; + private long cooldown; + private double angle; + private double threshold; + private double range; public Shockwave(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("Shockwave")) - return; - if (instances.containsKey(player)) - return; - starttime = System.currentTimeMillis(); - if (AvatarState.isAvatarState(player)) - chargetime = 0; - this.player = player; - instances.put(player, this); - - } - - public static void fallShockwave(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (!GeneralMethods.canBend(player.getName(), "Shockwave")) { - return; + super(player); + + this.angle = Math.toRadians(40); + this.cooldown = 1500; + this.chargeTime = getConfig().getLong("Abilities.Earth.Shockwave.ChargeTime"); + this.threshold = getConfig().getDouble("Abilities.Earth.Shockwave.FallThreshold"); + this.range = getConfig().getDouble("Abilities.Earth.Shockwave.Range"); + + if (bPlayer.isAvatarState()) { + chargeTime = 0; + cooldown = 0; } - if (GeneralMethods.getBoundAbility(player) == null || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("Shockwave")) { - return; - } - - if (instances.containsKey(player) || player.getFallDistance() < threshold || !EarthMethods.isEarthbendable(player, player.getLocation().add(0, -1, 0).getBlock())) { - return; - } - if(bPlayer.isOnCooldown("Shockwave")) { + + if (!bPlayer.canBend(this)) { return; } - areaShockwave(player); + start(); + bPlayer.addCooldown(this); } - private void progress() { - if (GeneralMethods.getBoundAbility(player) == null) { - instances.remove(player); + public void fallShockwave() { + if (!bPlayer.canBendIgnoreCooldowns(this)) { return; - } - if (!GeneralMethods.canBend(player.getName(), "Shockwave") || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("Shockwave")) { - instances.remove(player); + } else if (player.getFallDistance() < threshold || !isEarthbendable(player.getLocation().add(0, -1, 0).getBlock())) { return; } - if (System.currentTimeMillis() > starttime + chargetime && !charged) { + areaShockwave(); + remove(); + } + + @Override + public void progress() { + if (!bPlayer.canBendIgnoreCooldowns(this)) { + remove(); + return; + } + + if (System.currentTimeMillis() > startTime + chargeTime && !charged) { charged = true; } if (!player.isSneaking()) { if (charged) { - areaShockwave(player); - instances.remove(player); + areaShockwave(); + remove(); + return; } else { - instances.remove(player); + remove(); + return; } } else if (charged) { Location location = player.getEyeLocation(); - // location = location.add(location.getDirection().normalize()); location.getWorld().playEffect(location, Effect.SMOKE, GeneralMethods.getIntCardinalDirection(player.getEyeLocation().getDirection()), 3); } } public static void progressAll() { - for (Player player : instances.keySet()) - instances.get(player).progress(); - Ripple.progressAll(); + Ripple.progressAllCleanup(); } - private static void areaShockwave(Player player) { - double dtheta = 360. / (2 * Math.PI * Ripple.RADIUS) - 1; + public void areaShockwave() { + double dtheta = 360.0 / (2 * Math.PI * this.range) - 1; for (double theta = 0; theta < 360; theta += dtheta) { double rtheta = Math.toRadians(theta); Vector vector = new Vector(Math.cos(rtheta), 0, Math.sin(rtheta)); new Ripple(player, vector.normalize()); } - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("Shockwave", cooldown); } public static void coneShockwave(Player player) { - if (instances.containsKey(player)) { - if (instances.get(player).charged) { - double dtheta = 360. / (2 * Math.PI * Ripple.RADIUS) - 1; + Shockwave shockWave = CoreAbility.getAbility(player, Shockwave.class); + if (shockWave != null) { + if (shockWave.charged) { + double dtheta = 360.0 / (2 * Math.PI * shockWave.range) - 1; + for (double theta = 0; theta < 360; theta += dtheta) { double rtheta = Math.toRadians(theta); Vector vector = new Vector(Math.cos(rtheta), 0, Math.sin(rtheta)); - if (vector.angle(player.getEyeLocation().getDirection()) < angle) + if (vector.angle(player.getEyeLocation().getDirection()) < shockWave.angle) { new Ripple(player, vector.normalize()); + } } - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("Shockwave", cooldown); - instances.remove(player); + shockWave.remove(); } } } - public static String getDescription() { - return "This is one of the most powerful moves in the earthbender's arsenal. " + "To use, you must first charge it by holding sneak (default: shift). " + "Once charged, you can release sneak to create an enormous shockwave of earth, " + "disturbing all earth around you and expanding radially outwards. " + "Anything caught in the shockwave will be blasted back and dealt damage. " + "If you instead click while charged, the disruption is focused in a cone in front of you. " + "Lastly, if you fall from a great enough height with this ability selected, you will automatically create a shockwave."; + @Override + public String getName() { // TODO: Shockwave getName() is being overridden by Ripple + return "Shockwave"; } - public static void removeAll() { - instances.clear(); - Ripple.removeAll(); - + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; } - public Player getPlayer() { - return player; + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; } - public long getChargetime() { - return chargetime; + @Override + public boolean isHarmlessAbility() { + return false; } - public void setChargetime(long chargetime) { - this.chargetime = chargetime; + public boolean isCharged() { + return charged; } + public void setCharged(boolean charged) { + this.charged = charged; + } + + public long getChargeTime() { + return chargeTime; + } + + public void setChargeTime(long chargeTime) { + this.chargeTime = chargeTime; + } + + public double getAngle() { + return angle; + } + + public void setAngle(double angle) { + this.angle = angle; + } + + public double getThreshold() { + return threshold; + } + + public void setThreshold(double threshold) { + this.threshold = threshold; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/earthbending/Tremorsense.java b/src/com/projectkorra/projectkorra/earthbending/Tremorsense.java index 44e62abf..11c5ab73 100644 --- a/src/com/projectkorra/projectkorra/earthbending/Tremorsense.java +++ b/src/com/projectkorra/projectkorra/earthbending/Tremorsense.java @@ -2,48 +2,48 @@ package com.projectkorra.projectkorra.earthbending; import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.EarthAbility; import org.bukkit.Effect; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Server; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import java.util.concurrent.ConcurrentHashMap; -public class Tremorsense { +public class Tremorsense extends EarthAbility { - private static FileConfiguration config = ProjectKorra.plugin.getConfig(); + private static final ConcurrentHashMap BLOCKS = new ConcurrentHashMap(); - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - public static ConcurrentHashMap blocks = new ConcurrentHashMap(); - - private static final int maxdepth = config.getInt("Abilities.Earth.Tremorsense.MaxDepth"); - private static final int radius = config.getInt("Abilities.Earth.Tremorsense.Radius"); - private static final byte lightthreshold = (byte) config.getInt("Abilities.Earth.Tremorsense.LightThreshold"); - private static long cooldown = config.getLong("Abilities.Earth.Tremorsense.Cooldown"); - - private Player player; + private byte lightThreshold; + private int maxDepth; + private int radius; + private long cooldown; private Block block; - + public Tremorsense(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("Tremorsense")) + super(player); + + this.maxDepth = getConfig().getInt("Abilities.Earth.Tremorsense.MaxDepth"); + this.radius = getConfig().getInt("Abilities.Earth.Tremorsense.Radius"); + this.lightThreshold = (byte) getConfig().getInt("Abilities.Earth.Tremorsense.LightThreshold"); + this.cooldown = getConfig().getLong("Abilities.Earth.Tremorsense.Cooldown"); + + if (!bPlayer.canBend(this)) { return; - - if (EarthMethods.isEarthbendable(player, player.getLocation().getBlock().getRelative(BlockFace.DOWN))) { - this.player = player; - bPlayer.addCooldown("Tremorsense", cooldown); - activate(); } - } + + byte lightLevel = player.getLocation().getBlock().getLightLevel(); - public Tremorsense(Player player, boolean value) { - this.player = player; - set(); + if (lightLevel < this.lightThreshold && isEarthbendable(player.getLocation().getBlock().getRelative(BlockFace.DOWN))) { + bPlayer.addCooldown(this); + activate(); + start(); + } } private void activate() { @@ -51,98 +51,158 @@ public class Tremorsense { for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) { boolean earth = false; - boolean foundair = false; - Block smokeblock = null; - for (int k = 0; k <= maxdepth; k++) { + boolean foundAir = false; + Block smokeBlock = null; + + for (int k = 0; k <= maxDepth; k++) { Block blocki = block.getRelative(BlockFace.EAST, i).getRelative(BlockFace.NORTH, j).getRelative(BlockFace.DOWN, k); - if (GeneralMethods.isRegionProtectedFromBuild(player, "RaiseEarth", blocki.getLocation())) + if (GeneralMethods.isRegionProtectedFromBuild(this, blocki.getLocation())) { continue; - if (EarthMethods.isEarthbendable(player, blocki) && !earth) { + } + if (isEarthbendable(blocki) && !earth) { earth = true; - smokeblock = blocki; - } else if (!EarthMethods.isEarthbendable(player, blocki) && earth) { - foundair = true; + smokeBlock = blocki; + } else if (!isEarthbendable(blocki) && earth) { + foundAir = true; break; - } else if (!EarthMethods.isEarthbendable(player, blocki) && !earth && blocki.getType() != Material.AIR) { + } else if (!isEarthbendable(blocki) && !earth && blocki.getType() != Material.AIR) { break; } } - if (foundair) { - smokeblock.getWorld().playEffect(smokeblock.getRelative(BlockFace.UP).getLocation(), Effect.SMOKE, 4, radius); + if (foundAir) { + smokeBlock.getWorld().playEffect(smokeBlock.getRelative(BlockFace.UP).getLocation(), Effect.SMOKE, 4, radius); } } } - } @SuppressWarnings("deprecation") - private void set() { - Block standblock = player.getLocation().getBlock().getRelative(BlockFace.DOWN); - - BendingPlayer bp = GeneralMethods.getBendingPlayer(player.getName()); - if (!bp.isTremorSensing()) { - if (block != null) - revert(); + private void tryToSetGlowBlock() { + Block standBlock = player.getLocation().getBlock().getRelative(BlockFace.DOWN); + if (!bPlayer.isTremorSensing()) { + if (block != null) { + remove(); + } return; } + + boolean isBendable = isEarthbendable(standBlock); - if (EarthMethods.isEarthbendable(player, standblock) && block == null) { - block = standblock; + if (isBendable && block == null) { + block = standBlock; player.sendBlockChange(block.getLocation(), 89, (byte) 1); - instances.put(player, this); - } else if (EarthMethods.isEarthbendable(player, standblock) && !block.equals(standblock)) { - revert(); - block = standblock; + } else if (isBendable && !block.equals(standBlock)) { + revertGlowBlock(); + block = standBlock; player.sendBlockChange(block.getLocation(), 89, (byte) 1); - instances.put(player, this); } else if (block == null) { return; } else if (!player.getWorld().equals(block.getWorld())) { - revert(); - } else if (!EarthMethods.isEarthbendable(player, standblock)) { - revert(); + remove(); + return; + } else if (!isBendable) { + revertGlowBlock(); + return; } - - // Block standblock = player.getLocation().getBlock() - // .getRelative(BlockFace.DOWN); - // - // if (Methods.isEarthbendable(player, Abilities.Tremorsense, standblock)) - // { - // PotionEffect potion = new PotionEffect( - // PotionEffectType.NIGHT_VISION, 70, 0); - // new TempPotionEffect(player, potion); - // } } @SuppressWarnings("deprecation") - private void revert() { + public void revertGlowBlock() { if (block != null) { player.sendBlockChange(block.getLocation(), block.getTypeId(), block.getData()); - instances.remove(player); + } + } + + @Override + public void remove() { + super.remove(); + revertGlowBlock(); + } + + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this) || player.getLocation().getBlock().getLightLevel() > lightThreshold) { + remove(); + return; + } else { + tryToSetGlowBlock(); } } public static void manage(Server server) { for (Player player : server.getOnlinePlayers()) { - if (instances.containsKey(player) && (!GeneralMethods.canBend(player.getName(), "Tremorsense") || player.getLocation().getBlock().getLightLevel() > lightthreshold)) { - instances.get(player).revert(); - } else if (instances.containsKey(player)) { - instances.get(player).set(); - } else if (GeneralMethods.canBend(player.getName(), "Tremorsense") && player.getLocation().getBlock().getLightLevel() < lightthreshold) { - new Tremorsense(player, false); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + + if (bPlayer != null && !CoreAbility.hasAbility(player, Tremorsense.class) + && bPlayer.canBend(CoreAbility.getAbility("Tremorsense"))) { + new Tremorsense(player); } } } - - public static void removeAll() { - for (Player player : instances.keySet()) { - instances.get(player).revert(); - } - + + public static ConcurrentHashMap getBlocks() { + return BLOCKS; } - public static String getDescription() { - return "This is a pure utility ability for earthbenders. If you have this ability bound to any " + "slot whatsoever, then you are able to 'see' using the earth. If you are in an area of low-light " + "and are standing on top of an earthbendable block, this ability will automatically turn that block into " + "glowstone, visible *only by you*. If you lose contact with a bendable block, the light will go out, " + "as you have lost contact with the earth and cannot 'see' until you can touch earth again. " + "Additionally, if you click with this ability selected, smoke will appear above nearby earth " + "with pockets of air beneath them."; + @Override + public String getName() { + return "Tremorsense"; } + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return true; + } + + public byte getLightThreshold() { + return lightThreshold; + } + + public void setLightThreshold(byte lightThreshold) { + this.lightThreshold = lightThreshold; + } + + public int getMaxDepth() { + return maxDepth; + } + + public void setMaxDepth(int maxDepth) { + this.maxDepth = maxDepth; + } + + public int getRadius() { + return radius; + } + + public void setRadius(int radius) { + this.radius = radius; + } + + public Block getBlock() { + return block; + } + + public void setBlock(Block block) { + this.block = block; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/event/HorizontalVelocityChangeEvent.java b/src/com/projectkorra/projectkorra/event/HorizontalVelocityChangeEvent.java index 1c519207..fbfc2666 100644 --- a/src/com/projectkorra/projectkorra/event/HorizontalVelocityChangeEvent.java +++ b/src/com/projectkorra/projectkorra/event/HorizontalVelocityChangeEvent.java @@ -1,7 +1,6 @@ package com.projectkorra.projectkorra.event; import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.SubElement; import org.bukkit.Location; import org.bukkit.entity.Entity; @@ -29,7 +28,6 @@ public class HorizontalVelocityChangeEvent extends Event implements Cancellable private Location end; private String abil; private Element element; - private SubElement sub; @Deprecated public HorizontalVelocityChangeEvent(Entity entity, Player instigator, Vector from, Vector to, Vector difference) { @@ -40,7 +38,7 @@ public class HorizontalVelocityChangeEvent extends Event implements Cancellable this.difference = difference; } - public HorizontalVelocityChangeEvent(Entity entity, Player instigator, Vector from, Vector to, Vector difference, Location start, Location end, String ability, Element element, SubElement sub) { + public HorizontalVelocityChangeEvent(Entity entity, Player instigator, Vector from, Vector to, Vector difference, Location start, Location end, String ability, Element element) { this.entity = entity; this.instigator = instigator; this.from = from; @@ -50,7 +48,6 @@ public class HorizontalVelocityChangeEvent extends Event implements Cancellable this.end = end; abil = ability; this.element = element; - this.sub = sub; } public Entity getEntity() { @@ -96,10 +93,6 @@ public class HorizontalVelocityChangeEvent extends Event implements Cancellable return element; } - public SubElement getSubElement() { - return sub; - } - @Override public HandlerList getHandlers() { return handlers; diff --git a/src/com/projectkorra/projectkorra/event/PlayerBendingDeathEvent.java b/src/com/projectkorra/projectkorra/event/PlayerBendingDeathEvent.java index 7fbeb0b3..d8bc95d9 100644 --- a/src/com/projectkorra/projectkorra/event/PlayerBendingDeathEvent.java +++ b/src/com/projectkorra/projectkorra/event/PlayerBendingDeathEvent.java @@ -1,9 +1,8 @@ package com.projectkorra.projectkorra.event; -import com.projectkorra.projectkorra.Element; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.SubElement; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; @@ -21,25 +20,19 @@ public class PlayerBendingDeathEvent extends Event { private Player attacker; private String ability; private double damage; - private Element element; - private SubElement sub; /** * * @param victim the player who died * @param attacker the player who killed the victim * @param damage the amount of damage done in the attack that killed the victim - * @param element the element of the ability - * @param sub the subelement of the ability * @param ability the ability used to kill the victim */ - public PlayerBendingDeathEvent(Player victim, Player attacker, double damage, Element element, SubElement sub, String ability) { + public PlayerBendingDeathEvent(Player victim, Player attacker, double damage, String ability) { this.victim = victim; this.attacker = attacker; this.ability = ability; this.damage = damage; - this.element = element; - this.sub = sub; } /** @@ -73,22 +66,6 @@ public class PlayerBendingDeathEvent extends Event { public double getDamage() { return damage; } - - /** - * - * @return the element of the ability used - */ - public Element getElement() { - return element; - } - - /** - * - * @return the subelement of the ability used - */ - public SubElement getSubElement() { - return sub; - } public HandlerList getHandlers() { return handlers; diff --git a/src/com/projectkorra/projectkorra/event/PlayerCooldownChangeEvent.java b/src/com/projectkorra/projectkorra/event/PlayerCooldownChangeEvent.java index 9fae5317..4cbd5171 100644 --- a/src/com/projectkorra/projectkorra/event/PlayerCooldownChangeEvent.java +++ b/src/com/projectkorra/projectkorra/event/PlayerCooldownChangeEvent.java @@ -11,14 +11,12 @@ public final class PlayerCooldownChangeEvent extends Event implements Cancellabl private String ability; private Result eventresult; private boolean cancelled; - private long cooldown; - public PlayerCooldownChangeEvent(Player player, String abilityname, long cooldown, Result result) { + public PlayerCooldownChangeEvent(Player player, String abilityname, Result result) { this.player = player; this.ability = abilityname; this.eventresult = result; this.cancelled = false; - this.cooldown = cooldown; } public Player getPlayer() { @@ -32,10 +30,6 @@ public final class PlayerCooldownChangeEvent extends Event implements Cancellabl public Result getResult() { return eventresult; } - - public long getCooldown() { - return cooldown; - } public boolean isCancelled() { return cancelled; @@ -44,10 +38,6 @@ public final class PlayerCooldownChangeEvent extends Event implements Cancellabl public void setCancelled(boolean cancel) { this.cancelled = cancel; } - - public void setCooldown(long cooldown) { - this.cooldown = cooldown; - } public HandlerList getHandlers() { return handlers; diff --git a/src/com/projectkorra/projectkorra/firebending/ArcOfFire.java b/src/com/projectkorra/projectkorra/firebending/ArcOfFire.java deleted file mode 100644 index ccacb08a..00000000 --- a/src/com/projectkorra/projectkorra/firebending/ArcOfFire.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.projectkorra.projectkorra.firebending; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; - -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -/** - * Used for the ability Blaze. - */ -public class ArcOfFire implements ConfigLoadable { - - private static int defaultarc = config.get().getInt("Abilities.Fire.Blaze.ArcOfFire.Arc"); - private static int defaultrange = config.get().getInt("Abilities.Fire.Blaze.ArcOfFire.Range"); - private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Fire.Blaze.Cooldown"); - private static int stepsize = 2; - - public ArcOfFire(Player player) { - /* Initial Checks */ - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("Blaze")) - return; - /* End Initial Checks */ - // reloadVariables(); - - Location location = player.getLocation(); - - int arc = (int) FireMethods.getFirebendingDayAugment(defaultarc, player.getWorld()); - - for (int i = -arc; i <= arc; i += stepsize) { - double angle = Math.toRadians((double) i); - Vector direction = player.getEyeLocation().getDirection().clone(); - - double x, z, vx, vz; - x = direction.getX(); - z = direction.getZ(); - - vx = x * Math.cos(angle) - z * Math.sin(angle); - vz = x * Math.sin(angle) + z * Math.cos(angle); - - direction.setX(vx); - direction.setZ(vz); - - int range = defaultrange; - if (AvatarState.isAvatarState(player)) - range = AvatarState.getValue(range); - - new FireStream(location, direction, player, range); - } - - bPlayer.addCooldown("Blaze", cooldown); - } - - public static String getDescription() { - return "To use, simply left-click in any direction. " + "An arc of fire will flow from your location, " - + "igniting anything in its path." + " Additionally, tap sneak to engulf the area around you " - + "in roaring flames."; - } - - @Override - public void reloadVariables() { - defaultarc = config.get().getInt("Abilities.Fire.Blaze.ArcOfFire.Arc"); - defaultrange = config.get().getInt("Abilities.Fire.Blaze.ArcOfFire.Range"); - } - -} diff --git a/src/com/projectkorra/projectkorra/firebending/Blaze.java b/src/com/projectkorra/projectkorra/firebending/Blaze.java new file mode 100644 index 00000000..27aacc51 --- /dev/null +++ b/src/com/projectkorra/projectkorra/firebending/Blaze.java @@ -0,0 +1,87 @@ +package com.projectkorra.projectkorra.firebending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + + +public class Blaze extends FireAbility { + + private int arc; + private long cooldown; + private double range; + private double speed; + + public Blaze(Player player) { + super(player); + + this.speed = 2; + this.cooldown = GeneralMethods.getGlobalCooldown(); + this.arc = getConfig().getInt("Abilities.Fire.Blaze.ArcOfFire.Arc"); + this.range = getConfig().getDouble("Abilities.Fire.Blaze.ArcOfFire.Range"); + + if (!bPlayer.canBend(this)) { + return; + } + + this.range = getDayFactor(range); + this.range = AvatarState.getValue(range, player); + this.arc = (int) getDayFactor(arc); + Location location = player.getLocation(); + + for (int i = -arc; i <= arc; i += speed) { + double angle = Math.toRadians(i); + Vector direction = player.getEyeLocation().getDirection().clone(); + double x, z, vx, vz; + + x = direction.getX(); + z = direction.getZ(); + + vx = x * Math.cos(angle) - z * Math.sin(angle); + vz = x * Math.sin(angle) + z * Math.cos(angle); + + direction.setX(vx); + direction.setZ(vz); + + new BlazeArc(player, location, direction, range); + } + + start(); + bPlayer.addCooldown(this); + remove(); + } + + @Override + public String getName() { + return "Blaze"; + } + + @Override + public void progress() { + } + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + +} diff --git a/src/com/projectkorra/projectkorra/firebending/BlazeArc.java b/src/com/projectkorra/projectkorra/firebending/BlazeArc.java new file mode 100644 index 00000000..d982563e --- /dev/null +++ b/src/com/projectkorra/projectkorra/firebending/BlazeArc.java @@ -0,0 +1,274 @@ +package com.projectkorra.projectkorra.firebending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.waterbending.PlantRegrowth; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.material.MaterialData; +import org.bukkit.util.Vector; + +import java.util.Arrays; +import java.util.concurrent.ConcurrentHashMap; + +public class BlazeArc extends FireAbility { + + private static final long DISSIPATE_REMOVE_TIME = 400; + private static final Material[] OVERWRITABLE_MATERIALS = { Material.SAPLING, Material.LONG_GRASS, Material.DEAD_BUSH, + Material.YELLOW_FLOWER, Material.RED_ROSE, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, + Material.FIRE, Material.SNOW, Material.TORCH }; + private static final ConcurrentHashMap IGNITED_BLOCKS = new ConcurrentHashMap(); + private static final ConcurrentHashMap IGNITED_TIMES = new ConcurrentHashMap(); + private static final ConcurrentHashMap REPLACED_BLOCKS = new ConcurrentHashMap(); + + private long time; + private long interval; + private double range; + private double speed; + private Location origin; + private Location location; + private Vector direction; + + public BlazeArc(Player player, Location location, Vector direction, double range) { + super(player); + this.range = getDayFactor(range); + this.speed = 15; + this.interval = (long) (1000. / speed); + this.origin = location.clone(); + this.location = origin.clone(); + + this.direction = direction.clone(); + this.direction.setY(0); + this.direction = this.direction.clone().normalize(); + this.location = this.location.clone().add(this.direction); + + this.time = System.currentTimeMillis(); + start(); + } + + private void ignite(Block block) { + if (block.getType() != Material.FIRE && block.getType() != Material.AIR) { + if (canFireGrief()) { + if (isPlant(block)) { + new PlantRegrowth(player, block); + } + } else if (block.getType() != Material.FIRE) { + REPLACED_BLOCKS.put(block.getLocation(), block.getState().getData()); + } + } + + block.setType(Material.FIRE); + IGNITED_BLOCKS.put(block, this.player); + IGNITED_TIMES.put(block, System.currentTimeMillis()); + } + + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { + remove(); + return; + } else if (System.currentTimeMillis() - time >= interval) { + location = location.clone().add(direction); + time = System.currentTimeMillis(); + + Block block = location.getBlock(); + if (block.getType() == Material.FIRE) { + return; + } + + if (location.distanceSquared(origin) > range * range) { + remove(); + return; + } else if (GeneralMethods.isRegionProtectedFromBuild(this, location)) { + return; + } + + if (isIgnitable(player, block)) { + ignite(block); + } else if (isIgnitable(player, block.getRelative(BlockFace.DOWN))) { + ignite(block.getRelative(BlockFace.DOWN)); + location = block.getRelative(BlockFace.DOWN).getLocation(); + } else if (isIgnitable(player, block.getRelative(BlockFace.UP))) { + ignite(block.getRelative(BlockFace.UP)); + location = block.getRelative(BlockFace.UP).getLocation(); + } else { + remove(); + return; + } + } + } + + public static void dissipateAll() { + if (DISSIPATE_REMOVE_TIME != 0) { + for (Block block : IGNITED_TIMES.keySet()) { + if (block.getType() != Material.FIRE) { + removeBlock(block); + } else { + long time = IGNITED_TIMES.get(block); + if (System.currentTimeMillis() > time + DISSIPATE_REMOVE_TIME) { + block.setType(Material.AIR); + removeBlock(block); + } + } + } + } + } + + public static void handleDissipation() { + for (Block block : IGNITED_BLOCKS.keySet()) { + if (block.getType() != Material.FIRE) { + IGNITED_BLOCKS.remove(block); + } + } + } + + public static boolean isIgnitable(Player player, Block block) { + if (block.getType() == Material.FIRE) { + return true; + } else if (Arrays.asList(OVERWRITABLE_MATERIALS).contains(block.getType())) { + return true; + } else if (block.getType() != Material.AIR) { + return false; + } + + Block belowBlock = block.getRelative(BlockFace.DOWN); + return isIgnitable(belowBlock); + } + + public static void removeAllCleanup() { + for (Block block : IGNITED_BLOCKS.keySet()) { + removeBlock(block); + } + } + + public static void removeAroundPoint(Location location, double radius) { + for (BlazeArc stream : CoreAbility.getAbilities(BlazeArc.class)) { + if (stream.location.getWorld().equals(location.getWorld())) { + if (stream.location.distanceSquared(location) <= radius * radius) { + stream.remove(); + } + } + } + } + + @SuppressWarnings("deprecation") + public static void removeBlock(Block block) { + if (IGNITED_BLOCKS.containsKey(block)) { + IGNITED_BLOCKS.remove(block); + } + if (IGNITED_TIMES.containsKey(block)) { + IGNITED_TIMES.remove(block); + } + if (REPLACED_BLOCKS.containsKey(block.getLocation())) { + block.setType(REPLACED_BLOCKS.get(block.getLocation()).getItemType()); + block.setData(REPLACED_BLOCKS.get(block.getLocation()).getData()); + REPLACED_BLOCKS.remove(block.getLocation()); + } + } + + @Override + public String getName() { + return "Blaze"; + } + + @Override + public Location getLocation() { + if (location != null) { + return location; + } + return origin; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public static long getDissipateRemoveTime() { + return DISSIPATE_REMOVE_TIME; + } + + public static Material[] getOverwritableMaterials() { + return OVERWRITABLE_MATERIALS; + } + + public static ConcurrentHashMap getIgnitedBlocks() { + return IGNITED_BLOCKS; + } + + public static ConcurrentHashMap getIgnitedTimes() { + return IGNITED_TIMES; + } + + public static ConcurrentHashMap getReplacedBlocks() { + return REPLACED_BLOCKS; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/firebending/BlazeRing.java b/src/com/projectkorra/projectkorra/firebending/BlazeRing.java new file mode 100644 index 00000000..855cbe66 --- /dev/null +++ b/src/com/projectkorra/projectkorra/firebending/BlazeRing.java @@ -0,0 +1,106 @@ +package com.projectkorra.projectkorra.firebending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +public class BlazeRing extends FireAbility { + + private int range; + private long cooldown; + private double angleIncrement; + private Location location; + + public BlazeRing(Player player) { + super(player); + + this.range = getConfig().getInt("Abilities.Fire.Blaze.RingOfFire.Range"); + this.angleIncrement = 10; + this.cooldown = GeneralMethods.getGlobalCooldown(); + this.location = player.getLocation(); + + this.range = (int) AvatarState.getValue(this.range, player); + + if (bPlayer.isOnCooldown(this)) { + return; + } + + for (double degrees = 0; degrees < 360; degrees += angleIncrement) { + double angle = Math.toRadians(degrees); + Vector direction = player.getEyeLocation().getDirection().clone(); + double x, z, vx, vz; + + x = direction.getX(); + z = direction.getZ(); + + vx = x * Math.cos(angle) - z * Math.sin(angle); + vz = x * Math.sin(angle) + z * Math.cos(angle); + + direction.setX(vx); + direction.setZ(vz); + + new BlazeArc(player, location, direction, range); + } + + start(); + bPlayer.addCooldown(this); + remove(); + } + + @Override + public String getName() { + return "Blaze"; + } + + @Override + public void progress() {} + + @Override + public Location getLocation() { + return location; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public int getRange() { + return range; + } + + public void setRange(int range) { + this.range = range; + } + + public double getAngleIncrement() { + return angleIncrement; + } + + public void setAngleIncrement(double angleIncrement) { + this.angleIncrement = angleIncrement; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + +} \ No newline at end of file diff --git a/src/com/projectkorra/projectkorra/firebending/Combustion.java b/src/com/projectkorra/projectkorra/firebending/Combustion.java index f6144f8c..bf5a42e5 100644 --- a/src/com/projectkorra/projectkorra/firebending/Combustion.java +++ b/src/com/projectkorra/projectkorra/firebending/Combustion.java @@ -1,6 +1,11 @@ package com.projectkorra.projectkorra.firebending; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CombustionAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.util.ParticleEffect; import org.bukkit.Location; import org.bukkit.Material; @@ -10,90 +15,73 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.util.ParticleEffect; +public class Combustion extends CombustionAbility { -public class Combustion implements ConfigLoadable { - - public static long chargeTime = config.get().getLong("Abilities.Fire.Combustion.ChargeTime"); - public static long cooldown = config.get().getLong("Abilities.Fire.Combustion.Cooldown"); - - public static double speed = config.get().getDouble("Abilities.Fire.Combustion.Speed"); - public static double defaultrange = config.get().getDouble("Abilities.Fire.Combustion.Range"); - public static double defaultpower = config.get().getDouble("Abilities.Fire.Combustion.Power"); - public static boolean breakblocks = config.get().getBoolean("Abilities.Fire.Combustion.BreakBlocks"); - public static double radius = config.get().getDouble("Abilities.Fire.Combustion.Radius"); - public static double defaultdamage = config.get().getDouble("Abilities.Fire.Combustion.Damage"); - - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static final int maxticks = 10000; - - private Location location; - private Location origin; - private Player player; - private Vector direction; - private double range = defaultrange; - private double speedfactor; - private int ticks = 0; + private static final int MAX_TICKS = 10000; + + private boolean breakBlocks; + private int ticks; + private long cooldown; + private long chargeTime; private float power; private double damage; - @SuppressWarnings("unused") - private long starttime; - @SuppressWarnings("unused") - private boolean charged = false; + private double radius; + private double speed; + private double range; + private double speedFactor; + private Location location; + private Location origin; + private Vector direction; public Combustion(Player player) { - /* Initial Checks */ - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (instances.containsKey(player)) + super(player); + + if (hasAbility(player, Combustion.class) || !bPlayer.canBend(this)) { return; - if (bPlayer.isOnCooldown("Combustion")) - return; - /* End Initial Checks */ - // reloadVariables(); - this.player = player; - starttime = System.currentTimeMillis(); - origin = player.getEyeLocation(); - direction = player.getEyeLocation().getDirection().normalize(); - location = origin.clone(); - if (AvatarState.isAvatarState(player)) { - range = AvatarState.getValue(defaultrange); - damage = AvatarState.getValue(defaultdamage); - } else if (FireMethods.isDay(player.getWorld())) { - range = FireMethods.getFirebendingDayAugment(defaultrange, player.getWorld()); - damage = FireMethods.getFirebendingDayAugment(defaultdamage, player.getWorld()); - } else { - range = defaultrange; - damage = defaultdamage; + } + + this.ticks = 0; + this.breakBlocks = getConfig().getBoolean("Abilities.Fire.Combustion.BreakBlocks"); + this.power = (float) getConfig().getDouble("Abilities.Fire.Combustion.Power"); + this.cooldown = getConfig().getLong("Abilities.Fire.Combustion.Cooldown"); + this.chargeTime = getConfig().getLong("Abilities.Fire.Combustion.ChargeTime"); + this.damage = getConfig().getDouble("Abilities.Fire.Combustion.Damage"); + this.radius = getConfig().getDouble("Abilities.Fire.Combustion.Radius"); + this.speed = getConfig().getDouble("Abilities.Fire.Combustion.Speed"); + this.range = getConfig().getDouble("Abilities.Fire.Combustion.Range"); + this.origin = player.getEyeLocation(); + this.direction = player.getEyeLocation().getDirection().normalize(); + this.location = origin.clone(); + + if (bPlayer.isAvatarState()) { + range = AvatarState.getValue(range); + damage = AvatarState.getValue(damage); + } else if (isDay(player.getWorld())) { + range = getDayFactor(range); + damage = getDayFactor(damage); } - if (GeneralMethods.isRegionProtectedFromBuild(player, "Combustion", GeneralMethods.getTargetedLocation(player, range))) { + if (GeneralMethods.isRegionProtectedFromBuild(this, GeneralMethods.getTargetedLocation(player, range))) { return; } - instances.put(player, this); - bPlayer.addCooldown("Combustion", cooldown); + start(); + bPlayer.addCooldown(this); } public static void explode(Player player) { - if (instances.containsKey(player)) { - Combustion combustion = instances.get(player); - combustion.createExplosion(combustion.location, combustion.power, breakblocks); + Combustion combustion = getAbility(player, Combustion.class); + if (combustion != null) { + combustion.createExplosion(combustion.location, combustion.power, combustion.breakBlocks); ParticleEffect.EXPLODE.display(combustion.location, (float) Math.random(), (float) Math.random(), (float) Math.random(), 0, 3); } } public static boolean removeAroundPoint(Location loc, double radius) { - for (Combustion combustion : instances.values()) { - if (combustion.location.getWorld() == loc.getWorld()) { - if (combustion.location.distance(loc) <= radius) { + for (Combustion combustion : getAbilities(Combustion.class)) { + if (combustion.location.getWorld().equals(loc.getWorld())) { + if (combustion.location.distanceSquared(loc) <= radius * radius) { explode(combustion.getPlayer()); combustion.remove(); return true; @@ -104,113 +92,188 @@ public class Combustion implements ConfigLoadable { } private void advanceLocation() { - ParticleEffect.FIREWORKS_SPARK.display(location, (float) Math.random() / 2, (float) Math.random() / 2, - (float) Math.random() / 2, 0, 5); - ParticleEffect.FLAME.display(location, (float) Math.random() / 2, (float) Math.random() / 2, (float) Math.random() / 2, - 0, 2); - // if (Methods.rand.nextInt(4) == 0) { - FireMethods.playCombustionSound(location); - // } - location = location.add(direction.clone().multiply(speedfactor)); + ParticleEffect.FIREWORKS_SPARK.display(location, (float) Math.random() / 2, (float) Math.random() / 2, (float) Math.random() / 2, 0, 5); + ParticleEffect.FLAME.display(location, (float) Math.random() / 2, (float) Math.random() / 2, (float) Math.random() / 2, 0, 2); + playCombustionSound(location); + location = location.add(direction.clone().multiply(speedFactor)); } - private void createExplosion(Location block, float power, boolean breakblocks) { - block.getWorld().createExplosion(block.getX(), block.getY(), block.getZ(), (float) defaultpower, true, breakblocks); + private void createExplosion(Location block, float power, boolean canBreakBlocks) { + block.getWorld().createExplosion(block.getX(), block.getY(), block.getZ(), power, true, canBreakBlocks); for (Entity entity : block.getWorld().getEntities()) { if (entity instanceof LivingEntity) { - if (entity.getLocation().distance(block) < radius) { // They are close enough to the - // explosion. - GeneralMethods.damageEntity(player, entity, damage, "Combustion"); - AirMethods.breakBreathbendingHold(entity); + if (entity.getLocation().distanceSquared(block) < radius * radius) { // They are close enough to the explosion. + GeneralMethods.damageEntity(this, entity, damage); + AirAbility.breakBreathbendingHold(entity); } } } remove(); - } - public boolean progress() { - if (!instances.containsKey(player)) { - return false; - } - - if (player.isDead() || !player.isOnline()) { + @Override + public void progress() { + if (!bPlayer.canBendIgnoreCooldowns(this)) { remove(); - return false; - } - - if (!GeneralMethods.canBend(player.getName(), "Combustion")) { + return; + } else if (GeneralMethods.isRegionProtectedFromBuild(this, location)) { remove(); - return false; + return; } - if (GeneralMethods.getBoundAbility(player) == null - || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("Combustion")) { - remove(); - return false; - } - - if (GeneralMethods.isRegionProtectedFromBuild(player, "Combustion", location)) { - remove(); - return false; - } - - speedfactor = speed * (ProjectKorra.time_step / 1000.); + speedFactor = speed * (ProjectKorra.time_step / 1000.0); ticks++; - if (ticks > maxticks) { + if (ticks > MAX_TICKS) { remove(); - return false; - } - - if (location.distance(origin) > range) { + return; + } else if (location.distanceSquared(origin) > range * range) { remove(); - return false; + return; } Block block = location.getBlock(); if (block != null) { - if (block.getType() != Material.AIR && block.getType() != Material.WATER - && block.getType() != Material.STATIONARY_WATER) { - createExplosion(block.getLocation(), power, breakblocks); + if (block.getType() != Material.AIR && !isWater(block)) { + createExplosion(block.getLocation(), power, breakBlocks); } } for (Entity entity : location.getWorld().getEntities()) { if (entity instanceof LivingEntity) { - if (entity.getLocation().distance(location) <= 2 && !entity.equals(player)) { - createExplosion(location, power, breakblocks); + if (entity.getLocation().distanceSquared(location) <= 4 && !entity.equals(player)) { + createExplosion(location, power, breakBlocks); } } } - advanceLocation(); - return true; - } - - public static void progressAll() { - for (Combustion ability : instances.values()) { - ability.progress(); - } } @Override - public void reloadVariables() { - chargeTime = config.get().getLong("Abilities.Fire.Combustion.ChargeTime"); - cooldown = config.get().getLong("Abilities.Fire.Combustion.Cooldown"); - - speed = config.get().getDouble("Abilities.Fire.Combustion.Speed"); - defaultrange = config.get().getDouble("Abilities.Fire.Combustion.Range"); - defaultpower = config.get().getDouble("Abilities.Fire.Combustion.Power"); - breakblocks = config.get().getBoolean("Abilities.Fire.Combustion.BreakBlocks"); - radius = config.get().getDouble("Abilities.Fire.Combustion.Radius"); - defaultdamage = config.get().getDouble("Abilities.Fire.Combustion.Damage"); + public String getName() { + return "Combustion"; } - public void remove() { - instances.remove(player); + @Override + public Location getLocation() { + if (location != null) { + return location; + } + return origin; } - public Player getPlayer() { - return player; + @Override + public long getCooldown() { + return cooldown; } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isBreakBlocks() { + return breakBlocks; + } + + public void setBreakBlocks(boolean breakBlocks) { + this.breakBlocks = breakBlocks; + } + + public int getTicks() { + return ticks; + } + + public void setTicks(int ticks) { + this.ticks = ticks; + } + + public long getChargeTime() { + return chargeTime; + } + + public void setChargeTime(long chargeTime) { + this.chargeTime = chargeTime; + } + + public float getPower() { + return power; + } + + public void setPower(float power) { + this.power = power; + } + + public double getDamage() { + return damage; + } + + public void setDamage(double damage) { + this.damage = damage; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getSpeedFactor() { + return speedFactor; + } + + public void setSpeedFactor(double speedFactor) { + this.speedFactor = speedFactor; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public static long getMaxTicks() { + return MAX_TICKS; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + } diff --git a/src/com/projectkorra/projectkorra/firebending/Cook.java b/src/com/projectkorra/projectkorra/firebending/Cook.java deleted file mode 100644 index 788b0ea2..00000000 --- a/src/com/projectkorra/projectkorra/firebending/Cook.java +++ /dev/null @@ -1,165 +0,0 @@ -package com.projectkorra.projectkorra.firebending; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.concurrent.ConcurrentHashMap; - -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.util.ParticleEffect; - -/** - * Used in {@link HeatControl}. - */ -public class Cook { - - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static final long COOK_TIME = 2000; - private static final Material[] cookables = { Material.RAW_BEEF, Material.RAW_CHICKEN, Material.RAW_FISH, Material.PORK, - Material.POTATO_ITEM, Material.RABBIT, Material.MUTTON }; - - private Player player; - private ItemStack items; - private long time; - private long cooktime = COOK_TIME; - - public Cook(Player player) { - // reloadVariables(); - this.player = player; - items = player.getItemInHand(); - time = System.currentTimeMillis(); - if (isCookable(items.getType())) { - instances.put(player, this); - } - } - - private static boolean isCookable(Material material) { - return Arrays.asList(cookables).contains(material); - } - - private void cook() { - ItemStack cooked = getCooked(items); - HashMap cantfit = player.getInventory().addItem(cooked); - for (int id : cantfit.keySet()) { - player.getWorld().dropItem(player.getEyeLocation(), cantfit.get(id)); - } - int amount = items.getAmount(); - if (amount == 1) { - player.getInventory().clear(player.getInventory().getHeldItemSlot()); - // items.setType(Material.AIR); - } else { - items.setAmount(amount - 1); - } - } - - private ItemStack getCooked(ItemStack is) { - ItemStack cooked = new ItemStack(Material.AIR); - Material material = is.getType(); - switch (material) { - case RAW_BEEF: - cooked = new ItemStack(Material.COOKED_BEEF, 1); - break; - case RAW_FISH: - ItemStack salmon = new ItemStack(Material.RAW_FISH, 1, (short) 1); - if (is.getDurability() == salmon.getDurability()) { - cooked = new ItemStack(Material.COOKED_FISH, 1, (short) 1); - } else { - cooked = new ItemStack(Material.COOKED_FISH, 1); - } - break; - case RAW_CHICKEN: - cooked = new ItemStack(Material.COOKED_CHICKEN, 1); - break; - case PORK: - cooked = new ItemStack(Material.GRILLED_PORK, 1); - break; - case POTATO_ITEM: - cooked = new ItemStack(Material.BAKED_POTATO, 1); - break; - case MUTTON: - cooked = new ItemStack(Material.COOKED_MUTTON); - break; - case RABBIT: - cooked = new ItemStack(Material.COOKED_RABBIT); - break; - default: - break; // Shouldn't happen - } - return cooked; - } - - public long getCooktime() { - return cooktime; - } - - public Player getPlayer() { - return player; - } - - public long getTime() { - return time; - } - - public boolean progress() { - if (player.isDead() || !player.isOnline()) { - remove(); - return false; - } - - if (GeneralMethods.getBoundAbility(player) == null) { - remove(); - return false; - } - if (!player.isSneaking() || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("HeatControl")) { - remove(); - return false; - } - - if (!items.equals(player.getItemInHand())) { - time = System.currentTimeMillis(); - items = player.getItemInHand(); - } - - if (!isCookable(items.getType())) { - remove(); - return false; - } - - if (System.currentTimeMillis() > time + cooktime) { - cook(); - time = System.currentTimeMillis(); - } - ParticleEffect.FLAME.display(player.getEyeLocation(), 0.6F, 0.6F, 0.6F, 0, 3); - ParticleEffect.SMOKE.display(player.getEyeLocation(), 0.6F, 0.6F, 0.6F, 0, 1); - return true; - } - - public static void progressAll() { - for (Cook ability : instances.values()) { - ability.progress(); - } - } - - public void remove() { - instances.remove(player); - } - - public static void removeAll() { - for (Cook ability : instances.values()) { - ability.remove(); - } - } - - public void setCooktime(long cooktime) { - this.cooktime = cooktime; - } - - public void setTime(long time) { - this.time = time; - } - -} \ No newline at end of file diff --git a/src/com/projectkorra/projectkorra/firebending/Enflamed.java b/src/com/projectkorra/projectkorra/firebending/Enflamed.java deleted file mode 100644 index f292aa5d..00000000 --- a/src/com/projectkorra/projectkorra/firebending/Enflamed.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.projectkorra.projectkorra.firebending; - -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; - -import java.util.concurrent.ConcurrentHashMap; - -public class Enflamed { - - private static ConcurrentHashMap instances = new ConcurrentHashMap(); - private static ConcurrentHashMap times = new ConcurrentHashMap(); - - private static final int damage = 1; - private static final int max = 90; - private static final long buffer = 30; - - public Enflamed(Entity entity, Player source) { - if (entity.getEntityId() == source.getEntityId()) - return; - if (instances.containsKey(entity)) { - instances.replace(entity, source); - } else { - instances.put(entity, source); - } - } - - public static boolean isEnflamed(Entity entity) { - // return false; - if (instances.containsKey(entity)) { - if (times.containsKey(entity)) { - long time = times.get(entity); - if (System.currentTimeMillis() < time + buffer) { - return false; - } - } - times.put(entity, System.currentTimeMillis()); - return true; - } else { - return false; - } - } - - public static void dealFlameDamage(Entity entity) { - if (instances.containsKey(entity) && entity instanceof LivingEntity) { - if (entity instanceof Player) { - if (!Extinguish.canBurn((Player) entity)) { - return; - } - } - LivingEntity Lentity = (LivingEntity) entity; - Player source = instances.get(entity); - Lentity.damage(damage, source); - if (entity.getFireTicks() > max) - entity.setFireTicks(max); - } - } - - public static void handleFlames() { - for (Entity entity : instances.keySet()) { - if (entity.getFireTicks() <= 0) { - instances.remove(entity); - } - } - } - -} diff --git a/src/com/projectkorra/projectkorra/firebending/Extinguish.java b/src/com/projectkorra/projectkorra/firebending/Extinguish.java deleted file mode 100644 index 749eb28e..00000000 --- a/src/com/projectkorra/projectkorra/firebending/Extinguish.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.projectkorra.projectkorra.firebending; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.airbending.AirBlast; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.waterbending.WaterMethods; - -import org.bukkit.Effect; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; - -import java.util.HashSet; - -/** - * Used in {@link Cook HeatControl}. - */ -public class Extinguish implements ConfigLoadable { - - private static double defaultrange = config.get().getDouble("Abilities.Fire.HeatControl.Extinguish.Range"); - private static double defaultradius = config.get().getDouble("Abilities.Fire.HeatControl.Extinguish.Radius"); - - @SuppressWarnings("unused") - private static byte full = AirBlast.full; - - public Extinguish(Player player) { - /* Initial Checks */ - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("HeatControl")) - return; - /* End Initial Checks */ - // reloadVariables(); - - double range = FireMethods.getFirebendingDayAugment(defaultrange, player.getWorld()); - if (WaterMethods.isMeltable(player.getTargetBlock((HashSet) null, (int) range))) { - new HeatMelt(player); - return; - } - double radius = FireMethods.getFirebendingDayAugment(defaultradius, player.getWorld()); - for (Block block : GeneralMethods.getBlocksAroundPoint(player.getTargetBlock((HashSet) null, (int) range) - .getLocation(), radius)) { - - Material mat = block.getType(); - if (mat != Material.FIRE - /* - * && mat != Material.STATIONARY_LAVA && mat != Material.LAVA - */) - continue; - if (GeneralMethods.isRegionProtectedFromBuild(player, "Blaze", block.getLocation())) - continue; - if (block.getType() == Material.FIRE) { - block.setType(Material.AIR); - block.getWorld().playEffect(block.getLocation(), Effect.EXTINGUISH, 0); - } /* - * else if (block.getType() == Material.STATIONARY_LAVA) { - * block.setType(Material.OBSIDIAN); block.getWorld().playEffect(block.getLocation(), - * Effect.EXTINGUISH, 0); } else if (block.getType() == Material.LAVA) { if - * (block.getData() == full) { block.setType(Material.OBSIDIAN); } else { - * block.setType(Material.COBBLESTONE); } - * block.getWorld().playEffect(block.getLocation(), Effect.EXTINGUISH, 0); } - */ - } - - bPlayer.addCooldown("HeatControl", GeneralMethods.getGlobalCooldown()); - } - - public static boolean canBurn(Player player) { - if (GeneralMethods.getBoundAbility(player) != null) { - if (GeneralMethods.getBoundAbility(player).equalsIgnoreCase("HeatControl") || FireJet.checkTemporaryImmunity(player)) { - player.setFireTicks(-1); - return false; - } - } - - if (player.getFireTicks() > 80 && GeneralMethods.canBendPassive(player.getName(), Element.Fire)) { - player.setFireTicks(80); - } - - // Methods.verbose(player.getFireTicks()); - - return true; - } - - public static String getDescription() { - return "While this ability is selected, the firebender becomes impervious " + "to fire damage and cannot be ignited. " - + "If the user left-clicks with this ability, the targeted area will be " - + "extinguished, although it will leave any creature burning engulfed in flames. " - + "This ability can also cool lava. If this ability is used while targetting ice or snow, it" - + " will instead melt blocks in that area. Finally, sneaking with this ability will cook any food in your hand."; - } - - @Override - public void reloadVariables() { - defaultrange = config.get().getDouble("Abilities.Fire.HeatControl.Extinguish.Range"); - defaultradius = config.get().getDouble("Abilities.Fire.HeatControl.Extinguish.Radius"); - } -} diff --git a/src/com/projectkorra/projectkorra/firebending/FireBlast.java b/src/com/projectkorra/projectkorra/firebending/FireBlast.java index 283de1f7..123163f6 100644 --- a/src/com/projectkorra/projectkorra/firebending/FireBlast.java +++ b/src/com/projectkorra/projectkorra/firebending/FireBlast.java @@ -1,9 +1,15 @@ package com.projectkorra.projectkorra.firebending; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.earthbending.EarthBlast; +import com.projectkorra.projectkorra.util.ParticleEffect; +import com.projectkorra.projectkorra.waterbending.PlantRegrowth; +import com.projectkorra.projectkorra.waterbending.WaterManipulation; import org.bukkit.Location; import org.bukkit.Material; @@ -15,372 +21,394 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.earthbending.EarthBlast; -import com.projectkorra.projectkorra.util.ParticleEffect; -import com.projectkorra.projectkorra.waterbending.Plantbending; -import com.projectkorra.projectkorra.waterbending.WaterManipulation; -import com.projectkorra.projectkorra.waterbending.WaterMethods; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; -public class FireBlast implements ConfigLoadable { +public class FireBlast extends FireAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static double SPEED = config.get().getDouble("Abilities.Fire.FireBlast.Speed"); - private static double PUSH_FACTOR = config.get().getDouble("Abilities.Fire.FireBlast.Push"); - private static double RANGE = config.get().getDouble("Abilities.Fire.FireBlast.Range"); - private static int DAMAGE = config.get().getInt("Abilities.Fire.FireBlast.Damage"); - private static double fireticks = config.get().getDouble("Abilities.Fire.FireBlast.FireTicks"); - private static int idCounter = 0; - - /* Package visible variables */ - static boolean dissipate = config.get().getBoolean("Abilities.Fire.FireBlast.Dissipate"); - /* End Package visible variables */ - - public static double AFFECTING_RADIUS = 2; - - // public static long interval = 2000; - public static byte full = 0x0; - private static boolean canPowerFurnace = true; - private static final int maxticks = 10000; - private long cooldown = config.get().getLong("Abilities.Fire.FireBlast.Cooldown"); - + private static final int MAX_TICKS = 10000; + + private boolean powerFurnace; + private boolean showParticles; + private boolean dissipate; + private int ticks; + private long cooldown; + private double speedFactor; + private double range; + private double damage; + private double speed; + private double radius; + private double fireTicks; + private double pushFactor; + private Random random; private Location location; - private List safe = new ArrayList(); private Location origin; private Vector direction; - private Player player; - private double speedfactor; - private int ticks = 0; - private int id = 0; - private double range = RANGE; - private double damage = DAMAGE; - private double speed = SPEED; - private double pushfactor = PUSH_FACTOR; - private double affectingradius = AFFECTING_RADIUS; - private boolean showParticles = true; - private Random rand = new Random(); + private List safeBlocks; - private FireBurst source = null; - - public FireBlast(Location location, Vector direction, Player player, int damage, List safeblocks, FireBurst burst) { - /* Initial Checks */ + public FireBlast(Location location, Vector direction, Player player, int damage, List safeBlocks) { + super(player); + if (location.getBlock().isLiquid()) { return; } - /* End Initial Checks */ - // reloadVariables(); - safe = safeblocks; - range = FireMethods.getFirebendingDayAugment(range, player.getWorld()); - // timers.put(player, System.currentTimeMillis()); - this.player = player; + + this.safeBlocks = safeBlocks; + this.damage = damage; + this.powerFurnace = true; + this.showParticles = true; + this.radius = 2; + this.dissipate = getConfig().getBoolean("Abilities.Fire.FireBlast.Dissipate"); + this.cooldown = getConfig().getLong("Abilities.Fire.FireBlast.Cooldown"); + this.range = getConfig().getDouble("Abilities.Fire.FireBlast.Range"); + this.speed = getConfig().getDouble("Abilities.Fire.FireBlast.Speed"); + this.fireTicks = getConfig().getDouble("Abilities.Fire.FireBlast.FireTicks"); + this.pushFactor = getConfig().getDouble("Abilities.Fire.FireBlast.Push"); + this.random = new Random(); + this.location = location.clone(); - origin = location.clone(); + this.origin = location.clone(); this.direction = direction.clone().normalize(); + + this.range = getDayFactor(range); this.damage *= 1.5; - source = burst; - instances.put(idCounter, this); - this.id = idCounter; - idCounter = (idCounter + 1) % Integer.MAX_VALUE; - } + start(); + } + public FireBlast(Player player) { - /* Initial Checks */ - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("FireBlast")) + super(player); + + if (bPlayer.isOnCooldown(this)) { return; - if (player.getEyeLocation().getBlock().isLiquid() || Fireball.isCharging(player)) { + } else if (player.getEyeLocation().getBlock().isLiquid() || FireBlastCharged.isCharging(player)) { return; } - /* End Initial Checks */ - // reloadVariables(); - range = FireMethods.getFirebendingDayAugment(range, player.getWorld()); - this.player = player; - location = player.getEyeLocation(); - origin = player.getEyeLocation(); - direction = player.getEyeLocation().getDirection().normalize(); - location = location.add(direction.clone()); - instances.put(idCounter, this); - this.id = idCounter; - idCounter = (idCounter + 1) % Integer.MAX_VALUE; - bPlayer.addCooldown("FireBlast", cooldown); - // time = System.currentTimeMillis(); - // timers.put(player, System.currentTimeMillis()); - } - - public static boolean annihilateBlasts(Location location, double radius, Player source) { - boolean broke = false; - for (FireBlast blast : instances.values()) { - Location fireblastlocation = blast.location; - if (location.getWorld() == fireblastlocation.getWorld() && !blast.player.equals(source)) { - if (location.distance(fireblastlocation) <= radius) { - blast.remove(); - broke = true; - } - } - } - if (Fireball.annihilateBlasts(location, radius, source)) - broke = true; - return broke; - } - - public static ArrayList getAroundPoint(Location location, double radius) { - ArrayList list = new ArrayList(); - for (FireBlast fireBlast : instances.values()) { - Location fireblastlocation = fireBlast.location; - if (location.getWorld() == fireblastlocation.getWorld()) { - if (location.distance(fireblastlocation) <= radius) - list.add(fireBlast); - } - } - return list; - } - - public static String getDescription() { - return "FireBlast is the most fundamental bending technique of a firebender. " - + "To use, simply left-click in a direction. A blast of fire will be created at your fingertips. " - + "If this blast contacts an enemy, it will dissipate and engulf them in flames, " - + "doing additional damage and knocking them back slightly. " - + "If the blast hits terrain, it will ignite the nearby area. " - + "Additionally, if you hold sneak, you will charge up the fireblast. " - + "If you release it when it's charged, it will instead launch a powerful " - + "fireball that explodes on contact."; - } - - public static void removeFireBlastsAroundPoint(Location location, double radius) { - for (FireBlast fireBlast : instances.values()) { - Location fireblastlocation = fireBlast.location; - if (location.getWorld() == fireblastlocation.getWorld()) { - if (location.distance(fireblastlocation) <= radius) - fireBlast.remove(); - } - } - Fireball.removeFireballsAroundPoint(location, radius); - } + + this.powerFurnace = true; + this.showParticles = true; + this.radius = 2; + this.dissipate = getConfig().getBoolean("Abilities.Fire.FireBlast.Dissipate"); + this.cooldown = getConfig().getLong("Abilities.Fire.FireBlast.Cooldown"); + this.range = getConfig().getDouble("Abilities.Fire.FireBlast.Range"); + this.damage = getConfig().getInt("Abilities.Fire.FireBlast.Damage"); + this.speed = getConfig().getDouble("Abilities.Fire.FireBlast.Speed"); + this.fireTicks = getConfig().getDouble("Abilities.Fire.FireBlast.FireTicks"); + this.pushFactor = getConfig().getDouble("Abilities.Fire.FireBlast.Push"); + this.random = new Random(); + this.safeBlocks = new ArrayList<>(); + + this.range = getDayFactor(this.range); + + this.location = player.getEyeLocation(); + this.origin = player.getEyeLocation(); + this.direction = player.getEyeLocation().getDirection().normalize(); + this.location = location.add(direction.clone()); + + start(); + bPlayer.addCooldown(this); + } private void advanceLocation() { if (showParticles) { - // ParticleEffect.RED_DUST.display((float) 16, (float) 111, (float) 227, 0.01F, 0, - // location, 256D); ParticleEffect.FLAME.display(location, 0.275F, 0.275F, 0.275F, 0, 6); ParticleEffect.SMOKE.display(location, 0.3F, 0.3F, 0.3F, 0, 3); } - location = location.add(direction.clone().multiply(speedfactor)); - if (rand.nextInt(4) == 0) { - FireMethods.playFirebendingSound(location); + location = location.add(direction.clone().multiply(speedFactor)); + if (random.nextInt(4) == 0) { + playFirebendingSound(location); } } private void affect(Entity entity) { if (entity.getUniqueId() != player.getUniqueId()) { - if (AvatarState.isAvatarState(player)) { - GeneralMethods.setVelocity(entity, direction.clone().multiply(AvatarState.getValue(pushfactor))); + if (bPlayer.isAvatarState()) { + GeneralMethods.setVelocity(entity, direction.clone().multiply(AvatarState.getValue(pushFactor))); } else { - GeneralMethods.setVelocity(entity, direction.clone().multiply(pushfactor)); + GeneralMethods.setVelocity(entity, direction.clone().multiply(pushFactor)); } if (entity instanceof LivingEntity) { - entity.setFireTicks((int) (fireticks * 20)); - if (source != null) { - GeneralMethods.damageEntity(player, entity, - (int) FireMethods.getFirebendingDayAugment((double) damage, entity.getWorld()), "FireBurst"); - } else { - GeneralMethods.damageEntity(player, entity, - (int) FireMethods.getFirebendingDayAugment((double) damage, entity.getWorld()), "FireBlast"); - } - AirMethods.breakBreathbendingHold(entity); - new Enflamed(entity, player); + entity.setFireTicks((int) (fireTicks * 20)); + GeneralMethods.damageEntity(this, entity, (int) getDayFactor(damage)); + AirAbility.breakBreathbendingHold(entity); + new FireDamageTimer(entity, player); remove(); } } } - public double getAffectingradius() { - return affectingradius; + private void ignite(Location location) { + for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) { + if (BlazeArc.isIgnitable(player, block) + && !safeBlocks.contains(block) + && !GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + if (canFireGrief()) { + if (WaterAbility.isPlantbendable(block)) { + new PlantRegrowth(player, block); + } + block.setType(Material.FIRE); + } else { + createTempFire(block.getLocation()); + } + + if (dissipate) { + BlazeArc.getIgnitedBlocks().put(block, player); + BlazeArc.getIgnitedTimes().put(block, System.currentTimeMillis()); + } + } + } } + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this) + || GeneralMethods.isRegionProtectedFromBuild(this, location)) { + remove(); + return; + } + + speedFactor = speed * (ProjectKorra.time_step / 1000.0); + ticks++; + + if (ticks > MAX_TICKS) { + remove(); + return; + } + + Block block = location.getBlock(); + if (GeneralMethods.isSolid(block) || block.isLiquid()) { + if (block.getType() == Material.FURNACE && powerFurnace) { + Furnace furnace = (Furnace) block.getState(); + furnace.setBurnTime((short) 800); + furnace.setCookTime((short) 800); + furnace.update(); + } else if (BlazeArc.isIgnitable(player, block.getRelative(BlockFace.UP))) { + ignite(location); + } + remove(); + return; + } + + if (location.distanceSquared(origin) > range * range) { + remove(); + return; + } + + WaterAbility.removeWaterSpouts(location, player); + AirAbility.removeAirSpouts(location, player); + + Player source = player; + if (EarthBlast.annihilateBlasts(location, radius, source) + || WaterManipulation.annihilateBlasts(location, radius, source) + || FireBlast.annihilateBlasts(location, radius, source)) { + remove(); + return; + } + + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, radius)) { + affect(entity); + if (entity instanceof LivingEntity) { + break; + } + } + + advanceLocation(); + } + + public static boolean annihilateBlasts(Location location, double radius, Player source) { + boolean broke = false; + for (FireBlast blast : getAbilities(FireBlast.class)) { + Location fireBlastLocation = blast.location; + if (location.getWorld().equals(fireBlastLocation.getWorld()) && !blast.player.equals(source)) { + if (location.distanceSquared(fireBlastLocation) <= radius * radius) { + blast.remove(); + broke = true; + } + } + } + if (FireBlastCharged.annihilateBlasts(location, radius, source)) { + broke = true; + } + return broke; + } + + public static ArrayList getAroundPoint(Location location, double radius) { + ArrayList list = new ArrayList(); + for (FireBlast fireBlast : getAbilities(FireBlast.class)) { + Location fireblastlocation = fireBlast.location; + if (location.getWorld().equals(fireblastlocation.getWorld())) { + if (location.distanceSquared(fireblastlocation) <= radius * radius) { + list.add(fireBlast); + } + } + } + return list; + } + + public static void removeFireBlastsAroundPoint(Location location, double radius) { + for (FireBlast fireBlast : getAbilities(FireBlast.class)) { + Location fireBlastLocation = fireBlast.location; + if (location.getWorld().equals(fireBlastLocation.getWorld())) { + if (location.distanceSquared(fireBlastLocation) <= radius * radius) { + fireBlast.remove(); + } + } + } + FireBlastCharged.removeFireballsAroundPoint(location, radius); + } + + @Override + public String getName() { + return "FireBlast"; + } + + @Override + public Location getLocation() { + return location != null ? location : origin; + } + + @Override public long getCooldown() { return cooldown; } - - public double getDamage() { - return damage; + + @Override + public boolean isSneakAbility() { + return true; } - public Player getPlayer() { - return player; + @Override + public boolean isHarmlessAbility() { + return false; } - public double getPushfactor() { - return pushfactor; + public boolean isPowerFurnace() { + return powerFurnace; + } + + public void setPowerFurnace(boolean powerFurnace) { + this.powerFurnace = powerFurnace; + } + + public boolean isShowParticles() { + return showParticles; + } + + public void setShowParticles(boolean showParticles) { + this.showParticles = showParticles; + } + + public boolean isDissipate() { + return dissipate; + } + + public void setDissipate(boolean dissipate) { + this.dissipate = dissipate; + } + + public int getTicks() { + return ticks; + } + + public void setTicks(int ticks) { + this.ticks = ticks; + } + + public double getSpeedFactor() { + return speedFactor; + } + + public void setSpeedFactor(double speedFactor) { + this.speedFactor = speedFactor; } public double getRange() { return range; } - public double getSpeed() { - return speed; - } - - private void ignite(Location location) { - for (Block block : GeneralMethods.getBlocksAroundPoint(location, affectingradius)) { - if (FireStream.isIgnitable(player, block) && !safe.contains(block)) { - /* - * if (WaterMethods.isPlantbendable(block)) { new Plantbending(block); } - */ - if (FireMethods.canFireGrief()) { - if (WaterMethods.isPlantbendable(block)) - new Plantbending(block); - block.setType(Material.FIRE); - } else - FireMethods.createTempFire(block.getLocation()); - // block.setType(Material.FIRE); - if (dissipate) { - FireStream.ignitedblocks.put(block, player); - FireStream.ignitedtimes.put(block, System.currentTimeMillis()); - } - } - } - } - - public boolean progress() { - if (player.isDead() || !player.isOnline()) { - remove(); - return false; - } - - if (GeneralMethods.isRegionProtectedFromBuild(player, "Blaze", location)) { - remove(); - return false; - } - - speedfactor = speed * (ProjectKorra.time_step / 1000.); - - ticks++; - - if (ticks > maxticks) { - remove(); - return false; - } - - Block block = location.getBlock(); - - if (GeneralMethods.isSolid(block) || block.isLiquid()) { - if (block.getType() == Material.FURNACE && canPowerFurnace) { - Furnace furnace = (Furnace) block.getState(); - furnace.setBurnTime((short) 800); - furnace.setCookTime((short) 800); - furnace.update(); - } else if (FireStream.isIgnitable(player, block.getRelative(BlockFace.UP))) { - ignite(location); - } - remove(); - return false; - } - - if (location.distance(origin) > range) { - remove(); - return false; - } - - WaterMethods.removeWaterSpouts(location, player); - AirMethods.removeAirSpouts(location, player); - - double radius = affectingradius; - Player source = player; - if (EarthBlast.annihilateBlasts(location, radius, source) || WaterManipulation.annihilateBlasts(location, radius, source) - || FireBlast.annihilateBlasts(location, radius, source)) { - remove(); - return false; - } - - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, affectingradius)) { - // Block bblock = location.getBlock(); - // Block block1 = entity.getLocation().getBlock(); - // if (bblock.equals(block1)) - affect(entity); - if (entity instanceof LivingEntity) { - // Block block2 = ((LivingEntity) entity).getEyeLocation() - // .getBlock(); - // if (bblock.equals(block1)) - // break; - // if (bblock.equals(block2)) { - // affect(entity); - break; - // } - } - } - - advanceLocation(); - - return true; - } - - public static void progressAll() { - for (FireBlast ability : instances.values()) { - ability.progress(); - } - } - - public void remove() { - instances.remove(id); - } - - public static void removeAll() { - for (FireBlast ability : instances.values()) { - ability.remove(); - } - } - - @Override - public void reloadVariables() { - SPEED = config.get().getDouble("Abilities.Fire.FireBlast.Speed"); - PUSH_FACTOR = config.get().getDouble("Abilities.Fire.FireBlast.Push"); - RANGE = config.get().getDouble("Abilities.Fire.FireBlast.Range"); - DAMAGE = config.get().getInt("Abilities.Fire.FireBlast.Damage"); - fireticks = config.get().getDouble("Abilities.Fire.FireBlast.FireTicks"); - dissipate = config.get().getBoolean("Abilities.Fire.FireBlast.Dissipate"); - cooldown = config.get().getLong("Abilities.Fire.FireBlast.Cooldown"); - range = RANGE; - damage = DAMAGE; - speed = SPEED; - pushfactor = PUSH_FACTOR; - affectingradius = AFFECTING_RADIUS; - } - - public void setAffectingradius(double affectingradius) { - this.affectingradius = affectingradius; - } - - public void setCooldown(long cooldown) { - this.cooldown = cooldown; - if (player != null) - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("FireBlast", cooldown); - } - - public void setDamage(double dmg) { - this.damage = dmg; - } - - public void setPushfactor(double pushfactor) { - this.pushfactor = pushfactor; - } - public void setRange(double range) { this.range = range; } - public void setShowParticles(boolean show) { - this.showParticles = show; + public double getDamage() { + return damage; + } + + public void setDamage(double damage) { + this.damage = damage; + } + + public double getSpeed() { + return speed; } public void setSpeed(double speed) { this.speed = speed; } + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getFireTicks() { + return fireTicks; + } + + public void setFireTicks(double fireTicks) { + this.fireTicks = fireTicks; + } + + public double getPushFactor() { + return pushFactor; + } + + public void setPushFactor(double pushFactor) { + this.pushFactor = pushFactor; + } + + public Random getRandom() { + return random; + } + + public void setRandom(Random random) { + this.random = random; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public static int getMaxTicks() { + return MAX_TICKS; + } + + public List getSafeBlocks() { + return safeBlocks; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + } diff --git a/src/com/projectkorra/projectkorra/firebending/FireBlastCharged.java b/src/com/projectkorra/projectkorra/firebending/FireBlastCharged.java new file mode 100644 index 00000000..2781093f --- /dev/null +++ b/src/com/projectkorra/projectkorra/firebending/FireBlastCharged.java @@ -0,0 +1,312 @@ +package com.projectkorra.projectkorra.firebending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.util.ParticleEffect; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.util.Vector; + +import java.util.List; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; + +public class FireBlastCharged extends FireAbility { + + private static ConcurrentHashMap EXPLOSIONS = new ConcurrentHashMap(); + + private boolean charged; + private boolean launched; + private boolean canDamageBlocks; + private boolean dissipate; + private long time; + private long chargeTime; + private long interval; + private double maxDamage; + private double range; + private double radius; + private double damageRadius; + private double explosionRadius; + private double innerRadius; + private double fireTicks; + private TNTPrimed explosion; + private Location origin; + private Location location; + private Vector direction; + + public FireBlastCharged(Player player) { + super(player); + + this.charged = false; + this.launched = false; + this.canDamageBlocks = getConfig().getBoolean("Abilities.Fire.FireBlast.Charged.DamageBlocks"); + this.dissipate = getConfig().getBoolean("Abilities.Fire.FireBlast.Dissipate"); + this.chargeTime = getConfig().getLong("Abilities.Fire.FireBlast.Charged.ChargeTime"); + this.time = System.currentTimeMillis(); + this.interval = 25; + this.radius = 2; + this.maxDamage = getConfig().getDouble("Abilities.Fire.FireBlast.Charged.Damage"); + this.range = getConfig().getDouble("Abilities.Fire.FireBlast.Charged.Range"); + this.damageRadius = getConfig().getDouble("Abilities.Fire.FireBlast.Charged.DamageRadius"); + this.explosionRadius = getConfig().getDouble("Abilities.Fire.FireBlast.Charged.ExplosionRadius"); + this.fireTicks = getConfig().getDouble("Abilities.Fire.FireBlast.Charged.FireTicks"); + this.innerRadius = damageRadius / 2; + + if (isDay(player.getWorld())) { + this.chargeTime = (long) (chargeTime / getDayFactor()); + } + if (bPlayer.isAvatarState()) { + this.chargeTime = 0; + this.maxDamage = AvatarState.getValue(maxDamage); + } + + this.range = getDayFactor(range); + if (!player.getEyeLocation().getBlock().isLiquid()) { + start(); + } + } + + public static boolean annihilateBlasts(Location location, double radius, Player source) { + boolean broke = false; + for (FireBlastCharged chargedBlast : getAbilities(FireBlastCharged.class)) { + if (!chargedBlast.launched) { + continue; + } + + Location fireBlastLocation = chargedBlast.location; + if (location.getWorld().equals(fireBlastLocation.getWorld()) && !source.equals(chargedBlast.player)) { + if (location.distanceSquared(fireBlastLocation) <= radius * radius) { + chargedBlast.explode(); + broke = true; + } + } + } + return broke; + } + + public static FireBlastCharged getFireball(Entity entity) { + return entity != null ? EXPLOSIONS.get(entity) : null; + } + + public static boolean isCharging(Player player) { + for (FireBlastCharged chargedBlast : getAbilities(player, FireBlastCharged.class)) { + if (!chargedBlast.launched) { + return true; + } + } + return false; + } + + public static void removeFireballsAroundPoint(Location location, double radius) { + for (FireBlastCharged fireball : getAbilities(FireBlastCharged.class)) { + if (!fireball.launched) { + continue; + } + Location fireblastlocation = fireball.location; + if (location.getWorld().equals(fireblastlocation.getWorld())) { + if (location.distanceSquared(fireblastlocation) <= radius * radius) { + fireball.remove(); + } + } + } + } + + public void dealDamage(Entity entity) { + if (explosion == null) { + return; + } + + double distance = entity.getLocation().distance(explosion.getLocation()); + if (distance > damageRadius) { + return; + } else if (distance < innerRadius) { + GeneralMethods.damageEntity(player, entity, maxDamage, "FireBlast"); + return; + } + + double slope = -(maxDamage * .5) / (damageRadius - innerRadius); + double damage = slope * (distance - innerRadius) + maxDamage; + GeneralMethods.damageEntity(this, entity, damage); + AirAbility.breakBreathbendingHold(entity); + } + + public void explode() { + boolean explode = true; + for (Block block : GeneralMethods.getBlocksAroundPoint(location, 3)) { + if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + explode = false; + break; + } + } + + if (explode) { + if (canDamageBlocks && explosionRadius > 0) { + explosion = player.getWorld().spawn(location, TNTPrimed.class); + explosion.setFuseTicks(0); + double yield = explosionRadius; + + if (!bPlayer.isAvatarState()) { + yield = getDayFactor(yield, player.getWorld()); + } else { + yield = AvatarState.getValue(yield); + } + + if (!bPlayer.isAvatarState()) { + if (isDay(player.getWorld())) { + yield = (float) getDayFactor(yield); + } + } else { + yield = AvatarState.getValue(yield); + } + explosion.setYield((float) yield); + EXPLOSIONS.put(explosion, this); + } else { + List entities = GeneralMethods.getEntitiesAroundPoint(location, damageRadius); + for (Entity entity : entities) { + if (entity instanceof LivingEntity) { + double slope = -(maxDamage * .5) / (damageRadius - innerRadius); + double damage = slope * (entity.getLocation().distance(location) - innerRadius) + maxDamage; + GeneralMethods.damageEntity(this, entity, damage); + } + } + location.getWorld().playSound(location, Sound.EXPLODE, 5, 1); + ParticleEffect.EXPLOSION_HUGE.display(new Vector(0, 0, 0), 0, location, 256); + } + } + + ignite(location); + remove(); + } + + private void executeFireball() { + for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) { + ParticleEffect.FLAME.display(block.getLocation(), 0.5F, 0.5F, 0.5F, 0, 5); + ParticleEffect.SMOKE.display(block.getLocation(), 0.5F, 0.5F, 0.5F, 0, 2); + if ((new Random()).nextInt(4) == 0) { + playFirebendingSound(location); + } + + } + + boolean exploded = false; + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2 * radius)) { + if (entity.getEntityId() == player.getEntityId() + || GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) { + continue; + } + entity.setFireTicks((int) (fireTicks * 20)); + if (entity instanceof LivingEntity) { + if (!exploded) { + explode(); + exploded = true; + } + dealDamage(entity); + } + } + } + + private void ignite(Location location) { + for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) { + if (BlazeArc.isIgnitable(player, block)) { + if (block.getType() != Material.FIRE) { + BlazeArc.getReplacedBlocks().put(block.getLocation(), block.getState().getData()); + } + block.setType(Material.FIRE); + if (dissipate) { + BlazeArc.getIgnitedBlocks().put(block, player); + BlazeArc.getIgnitedTimes().put(block, System.currentTimeMillis()); + } + } + } + } + + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this) && !launched) { + remove(); + return; + } else if (!player.isSneaking() && !charged) { + remove(); + return; + } + + if (System.currentTimeMillis() > startTime + chargeTime) { + charged = true; + } + if (!player.isSneaking() && !launched) { + launched = true; + location = player.getEyeLocation(); + origin = location.clone(); + direction = location.getDirection().normalize().multiply(radius); + } + + if (System.currentTimeMillis() > time + interval) { + if (launched) { + if (GeneralMethods.isRegionProtectedFromBuild(this, location)) { + remove(); + return; + } + } + + time = System.currentTimeMillis(); + + if (!launched && !charged) { + return; + } else if (!launched) { + player.getWorld().playEffect(player.getEyeLocation(), Effect.MOBSPAWNER_FLAMES, 0, 3); + return; + } + + location = location.clone().add(direction); + if (location.distanceSquared(origin) > range * range) { + remove(); + return; + } + + if (GeneralMethods.isSolid(location.getBlock())) { + explode(); + return; + } else if (location.getBlock().isLiquid()) { + remove(); + return; + } + executeFireball(); + } + } + + @Override + public String getName() { + return "FireBlast"; + } + + @Override + public Location getLocation() { + return location != null ? location : origin; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + +} diff --git a/src/com/projectkorra/projectkorra/firebending/FireBurst.java b/src/com/projectkorra/projectkorra/firebending/FireBurst.java index a2241bf2..e3b9c0fc 100644 --- a/src/com/projectkorra/projectkorra/firebending/FireBurst.java +++ b/src/com/projectkorra/projectkorra/firebending/FireBurst.java @@ -1,11 +1,8 @@ package com.projectkorra.projectkorra.firebending; -import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.rpg.event.EventManager; +import com.projectkorra.projectkorra.ability.FireAbility; import org.bukkit.Effect; import org.bukkit.Location; @@ -16,118 +13,85 @@ import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -public class FireBurst implements ConfigLoadable { +public class FireBurst extends FireAbility { - public static final ConcurrentHashMap instances = new ConcurrentHashMap<>(); + private boolean charged; + private int damage; + private long chargeTime; + private long range; + private long cooldown; + private double angleTheta; + private double anglePhi; + private double particlesPercentage; + private ArrayList blasts; - private static double PARTICLES_PERCENTAGE = 5; - - private Player player; - private long starttime; - private int damage = config.get().getInt("Abilities.Fire.FireBurst.Damage"); - private long chargetime = config.get().getLong("Abilities.Fire.FireBurst.ChargeTime"); - private long range = config.get().getLong("Abilities.Fire.FireBurst.Range"); - private static long cooldown = config.get().getLong("Abilities.Fire.FireBurst.Cooldown"); - private double deltheta = 10; - private double delphi = 10; - private boolean charged = false; - private ArrayList blasts = new ArrayList(); - public FireBurst(Player player) { - /* Initial Checks */ - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("FireBurst")) + super(player); + + this.charged = false; + this.damage = getConfig().getInt("Abilities.Fire.FireBurst.Damage"); + this.chargeTime = getConfig().getLong("Abilities.Fire.FireBurst.ChargeTime"); + this.range = getConfig().getLong("Abilities.Fire.FireBurst.Range"); + this.cooldown = 0; + this.angleTheta = 10; + this.anglePhi = 10; + this.particlesPercentage = 5; + this.blasts = new ArrayList<>(); + + if (!bPlayer.canBend(this) || hasAbility(player, FireBurst.class)) { return; - if (instances.containsKey(player)) - return; - /* End Initial Checks */ - // reloadVariables(); + } - starttime = System.currentTimeMillis(); - if (FireMethods.isDay(player.getWorld())) { - chargetime /= config.get().getDouble("Properties.Fire.DayFactor"); + if (isDay(player.getWorld())) { + chargeTime /= getDayFactor(); } - if (AvatarState.isAvatarState(player)) - chargetime = 0; - if (EventManager.marker.containsKey(player.getWorld())) { - if (EventManager.marker.get(player.getWorld()).equalsIgnoreCase("SozinsComet")) - chargetime = 0; + if (bPlayer.isAvatarState() || isSozinsComet(player.getWorld())) { + chargeTime = 0; } - this.player = player; - instances.put(player, this); + + start(); } public static void coneBurst(Player player) { - if (instances.containsKey(player)) { - ((FireBurst) instances.get(player)).coneBurst(); + FireBurst burst = getAbility(player, FireBurst.class); + if (burst != null) { + burst.coneBurst(); } } - public static String getDescription() { - return "FireBurst is a very powerful firebending ability. " + "To use, press and hold sneak to charge your burst. " - + "Once charged, you can either release sneak to launch a cone-shaped burst " - + "of flames in front of you, or click to release the burst in a sphere around you. "; - } - private void coneBurst() { if (charged) { Location location = player.getEyeLocation(); - List safeblocks = GeneralMethods.getBlocksAroundPoint(player.getLocation(), 2); + List safeBlocks = GeneralMethods.getBlocksAroundPoint(player.getLocation(), 2); Vector vector = location.getDirection(); + double angle = Math.toRadians(30); double x, y, z; double r = 1; - for (double theta = 0; theta <= 180; theta += deltheta) { - double dphi = delphi / Math.sin(Math.toRadians(theta)); + + for (double theta = 0; theta <= 180; theta += angleTheta) { + double dphi = anglePhi / Math.sin(Math.toRadians(theta)); for (double phi = 0; phi < 360; phi += dphi) { double rphi = Math.toRadians(phi); double rtheta = Math.toRadians(theta); + x = r * Math.cos(rphi) * Math.sin(rtheta); y = r * Math.sin(rphi) * Math.sin(rtheta); z = r * Math.cos(rtheta); Vector direction = new Vector(x, z, y); + if (direction.angle(vector) <= angle) { - // Methods.verbose(direction.angle(vector)); - // Methods.verbose(direction); - FireBlast fblast = new FireBlast(location, direction.normalize(), player, damage, safeblocks, this); + FireBlast fblast = new FireBlast(location, direction.normalize(), player, damage, safeBlocks); fblast.setRange(this.range); } } } - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("FireBurst", cooldown); } - // Methods.verbose("--" + AirBlast.instances.size() + "--"); + bPlayer.addCooldown(this); remove(); } - public long getChargetime() { - return chargetime; - } - - public int getDamage() { - return damage; - } - - public Player getPlayer() { - return player; - } - - public long getRange() { - return range; - } - - public void remove() { - instances.remove(player); - } - - public static void removeAll() { - for (FireBurst ability : instances.values()) { - ability.remove(); - } - } - /** * To combat the sphere FireBurst lag we are only going to show a certain percentage of * FireBurst particles at a time per tick. As the bursts spread out then we can show more at a @@ -136,8 +100,9 @@ public class FireBurst implements ConfigLoadable { public void handleSmoothParticles() { for (int i = 0; i < blasts.size(); i++) { final FireBlast fblast = blasts.get(i); - int toggleTime = (int) (i % (100 / PARTICLES_PERCENTAGE)); + int toggleTime = (int) (i % (100.0 / particlesPercentage)); new BukkitRunnable() { + @Override public void run() { fblast.setShowParticles(true); } @@ -145,26 +110,14 @@ public class FireBurst implements ConfigLoadable { } } - public boolean progress() { - if (player.isDead() || !player.isOnline()) { + @Override + public void progress() { + if (!bPlayer.canBendIgnoreCooldowns(this)) { remove(); - return false; - } - if (!GeneralMethods.canBend(player.getName(), "FireBurst")) { - remove(); - return false; - } - if (GeneralMethods.getBoundAbility(player) == null) { - remove(); - return false; + return; } - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("FireBurst")) { - remove(); - return false; - } - - if (System.currentTimeMillis() > starttime + chargetime && !charged) { + if (System.currentTimeMillis() > startTime + chargeTime && !charged) { charged = true; } @@ -176,34 +129,8 @@ public class FireBurst implements ConfigLoadable { } } else if (charged) { Location location = player.getEyeLocation(); - // location = location.add(location.getDirection().normalize()); location.getWorld().playEffect(location, Effect.MOBSPAWNER_FLAMES, 4, 3); } - return true; - } - - public static void progressAll() { - for (FireBurst ability : instances.values()) { - ability.progress(); - } - } - - @Override - public void reloadVariables() { - // No need for this because there are no static variables. - // All instance variables are gotten newly from config - } - - public void setChargetime(long chargetime) { - this.chargetime = chargetime; - } - - public void setDamage(int damage) { - this.damage = damage; - } - - public void setRange(long range) { - this.range = range; } private void sphereBurst() { @@ -212,25 +139,119 @@ public class FireBurst implements ConfigLoadable { List safeblocks = GeneralMethods.getBlocksAroundPoint(player.getLocation(), 2); double x, y, z; double r = 1; - for (double theta = 0; theta <= 180; theta += deltheta) { - double dphi = delphi / Math.sin(Math.toRadians(theta)); + + for (double theta = 0; theta <= 180; theta += angleTheta) { + double dphi = anglePhi / Math.sin(Math.toRadians(theta)); for (double phi = 0; phi < 360; phi += dphi) { double rphi = Math.toRadians(phi); double rtheta = Math.toRadians(theta); + x = r * Math.cos(rphi) * Math.sin(rtheta); y = r * Math.sin(rphi) * Math.sin(rtheta); z = r * Math.cos(rtheta); + Vector direction = new Vector(x, z, y); - FireBlast fblast = new FireBlast(location, direction.normalize(), player, damage, safeblocks, this); + FireBlast fblast = new FireBlast(location, direction.normalize(), player, damage, safeblocks); + fblast.setRange(this.range); fblast.setShowParticles(false); blasts.add(fblast); } } - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("FireBurst", cooldown); } - // Methods.verbose("--" + AirBlast.instances.size() + "--"); + + bPlayer.addCooldown(this); remove(); handleSmoothParticles(); } + + @Override + public String getName() { + return "FireBurst"; + } + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isCharged() { + return charged; + } + + public void setCharged(boolean charged) { + this.charged = charged; + } + + public int getDamage() { + return damage; + } + + public void setDamage(int damage) { + this.damage = damage; + } + + public long getChargeTime() { + return chargeTime; + } + + public void setChargeTime(long chargeTime) { + this.chargeTime = chargeTime; + } + + public long getRange() { + return range; + } + + public void setRange(long range) { + this.range = range; + } + + public double getAngleTheta() { + return angleTheta; + } + + public void setAngleTheta(double angleTheta) { + this.angleTheta = angleTheta; + } + + public double getAnglePhi() { + return anglePhi; + } + + public void setAnglePhi(double anglePhi) { + this.anglePhi = anglePhi; + } + + public double getParticlesPercentage() { + return particlesPercentage; + } + + public void setParticlesPercentage(double particlesPercentage) { + this.particlesPercentage = particlesPercentage; + } + + public ArrayList getBlasts() { + return blasts; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/firebending/FireCombo.java b/src/com/projectkorra/projectkorra/firebending/FireCombo.java index 5483dacc..2dacf831 100644 --- a/src/com/projectkorra/projectkorra/firebending/FireCombo.java +++ b/src/com/projectkorra/projectkorra/firebending/FireCombo.java @@ -1,17 +1,19 @@ package com.projectkorra.projectkorra.firebending; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.Element; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.airbending.AirMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.ComboAbility; +import com.projectkorra.projectkorra.ability.ElementalAbility; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation; +import com.projectkorra.projectkorra.avatar.AvatarState; import com.projectkorra.projectkorra.command.Commands; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; import com.projectkorra.projectkorra.util.ClickType; import com.projectkorra.projectkorra.util.ParticleEffect; -import com.projectkorra.projectkorra.waterbending.WaterMethods; +import org.bukkit.Bukkit; import org.bukkit.Effect; import org.bukkit.Location; import org.bukkit.Material; @@ -25,12 +27,16 @@ import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; import java.util.ArrayList; -import java.util.List; -public class FireCombo implements ConfigLoadable { - public static final List abilitiesToBlock = new ArrayList() { - private static final long serialVersionUID = 5395690551860441647L; - { +/* + * TODO: Combo classes should eventually be rewritten so that each combo is treated + * as an individual ability. In the mean time, we will just place "fake" + * classes so that CoreAbility will register each ability. + */ +public class FireCombo extends FireAbility implements ComboAbility { + + private static final ArrayList BLOCKABLE_ABILITIES = new ArrayList() { + private static final long serialVersionUID = 0; { add("AirShield"); add("FireShield"); add("AirSwipe"); @@ -43,112 +49,81 @@ public class FireCombo implements ConfigLoadable { add("AirSweep"); } }; - private static boolean enabled = config.get().getBoolean("Abilities.Fire.FireCombo.Enabled"); - private static final double FIRE_WHEEL_STARTING_HEIGHT = 2; - private static final double FIRE_WHEEL_RADIUS = 1; - public static double fireticksFireWheel = config.get().getDouble("Abilities.Fire.FireCombo.FireWheel.FireTicks"); - public static double fireticksJetBlaze = config.get().getDouble("Abilities.Fire.FireCombo.JetBlaze.FireTicks"); - public static double FIRE_KICK_RANGE = config.get().getDouble("Abilities.Fire.FireCombo.FireKick.Range"); - public static double FIRE_KICK_DAMAGE = config.get().getDouble("Abilities.Fire.FireCombo.FireKick.Damage"); - public static double FIRE_SPIN_RANGE = config.get().getDouble("Abilities.Fire.FireCombo.FireSpin.Range"); - public static double FIRE_SPIN_DAMAGE = config.get().getDouble("Abilities.Fire.FireCombo.FireSpin.Damage"); - public static double FIRE_SPIN_KNOCKBACK = config.get().getDouble("Abilities.Fire.FireCombo.FireSpin.Knockback"); - public static double FIRE_WHEEL_DAMAGE = config.get().getDouble("Abilities.Fire.FireCombo.FireWheel.Damage"); - public static double FIRE_WHEEL_RANGE = config.get().getDouble("Abilities.Fire.FireCombo.FireWheel.Range"); - public static double FIRE_WHEEL_SPEED = config.get().getDouble("Abilities.Fire.FireCombo.FireWheel.Speed"); - public static double JET_BLAST_SPEED = config.get().getDouble("Abilities.Fire.FireCombo.JetBlast.Speed"); - public static double JET_BLAZE_SPEED = config.get().getDouble("Abilities.Fire.FireCombo.JetBlaze.Speed"); - public static double JET_BLAZE_DAMAGE = config.get().getDouble("Abilities.Fire.FireCombo.JetBlaze.Damage"); - - public static long FIRE_KICK_COOLDOWN = config.get().getLong("Abilities.Fire.FireCombo.FireKick.Cooldown"); - public static long FIRE_SPIN_COOLDOWN = config.get().getLong("Abilities.Fire.FireCombo.FireSpin.Cooldown"); - public static long FIRE_WHEEL_COOLDOWN = config.get().getLong("Abilities.Fire.FireCombo.FireWheel.Cooldown"); - public static long JET_BLAST_COOLDOWN = config.get().getLong("Abilities.Fire.FireCombo.JetBlast.Cooldown"); - public static long JET_BLAZE_COOLDOWN = config.get().getLong("Abilities.Fire.FireCombo.JetBlaze.Cooldown"); - - public static ArrayList instances = new ArrayList(); - - private Player player; - private BendingPlayer bplayer; - private ClickType type; - private String ability; + private boolean firstTime; + private boolean enabled; + private int progressCounter; private long time; + private long cooldown; + private double damage; + private double speed; + private double range; + private double knockback; + private double fireTicks; + private double height; + private double radius; + private ClickType clickType; + private String ability; private Location origin; - private Location currentLoc; + private Location location; private Location destination; private Vector direction; - private boolean firstTime = true; - private ArrayList affectedEntities = new ArrayList(); - private ArrayList tasks = new ArrayList(); - private int progressCounter = 0; - private double damage = 0, speed = 0, range = 0; - private long cooldown = 0; - + private ArrayList affectedEntities; + private ArrayList tasks; + public FireCombo(Player player, String ability) { - // Dont' call Methods.canBind directly, it doesn't let you combo as fast - /* Initial Checks */ - if (!enabled) - return; - if (!GeneralMethods.getBendingPlayer(player.getName()).hasElement(Element.Fire)) - return; - if (Commands.isToggledForAll) - return; - if (GeneralMethods.isRegionProtectedFromBuild(player, "Blaze", player.getLocation())) - return; - if (!GeneralMethods.getBendingPlayer(player.getName()).isToggled()) - return; - if (!GeneralMethods.canBend(player.getName(), ability)) { - return; - } - /* End Initial Checks */ - // reloadVariables(); - time = System.currentTimeMillis(); - this.player = player; + super(player); + Bukkit.broadcastMessage("Here 0"); + this.ability = ability; - this.bplayer = GeneralMethods.getBendingPlayer(player.getName()); - + this.enabled = getConfig().getBoolean("Abilities.Fire.FireCombo.Enabled"); + + if (!this.enabled || !bPlayer.canBendIgnoreBindsCooldowns(this)) { + return; + } + + this.firstTime = true; + this.time = System.currentTimeMillis(); + this.affectedEntities = new ArrayList<>(); + this.tasks = new ArrayList<>(); + if (ability.equalsIgnoreCase("FireKick")) { - damage = FIRE_KICK_DAMAGE; - range = FIRE_KICK_RANGE; - speed = 1; - cooldown = FIRE_KICK_COOLDOWN; + this.damage = getConfig().getDouble("Abilities.Fire.FireCombo.FireKick.Damage"); + this.range = getConfig().getDouble("Abilities.Fire.FireCombo.FireKick.Range"); + this.cooldown = getConfig().getLong("Abilities.Fire.FireCombo.FireKick.Cooldown"); + this.speed = 1; } else if (ability.equalsIgnoreCase("FireSpin")) { - damage = FIRE_SPIN_DAMAGE; - range = FIRE_SPIN_RANGE; - speed = 0.3; - cooldown = FIRE_SPIN_COOLDOWN; + this.damage = getConfig().getDouble("Abilities.Fire.FireCombo.FireSpin.Damage"); + this.range = getConfig().getDouble("Abilities.Fire.FireCombo.FireSpin.Range"); + this.cooldown = getConfig().getLong("Abilities.Fire.FireCombo.FireSpin.Cooldown"); + this.knockback = getConfig().getDouble("Abilities.Fire.FireCombo.FireSpin.Knockback"); + this.speed = 0.3; } else if (ability.equalsIgnoreCase("FireWheel")) { - damage = FIRE_WHEEL_DAMAGE; - range = FIRE_WHEEL_RANGE; - speed = FIRE_WHEEL_SPEED; - cooldown = FIRE_WHEEL_COOLDOWN; + this.damage = getConfig().getDouble("Abilities.Fire.FireCombo.FireWheel.Damage"); + this.range = getConfig().getDouble("Abilities.Fire.FireCombo.FireWheel.Range"); + this.speed = getConfig().getDouble("Abilities.Fire.FireCombo.FireWheel.Speed"); + this.cooldown = getConfig().getLong("Abilities.Fire.FireCombo.FireWheel.Cooldown"); + this.fireTicks = getConfig().getDouble("Abilities.Fire.FireCombo.FireWheel.FireTicks"); + this.height = 2; + this.radius = 1; } else if (ability.equalsIgnoreCase("JetBlast")) { - speed = JET_BLAST_SPEED; - cooldown = JET_BLAST_COOLDOWN; + this.speed = getConfig().getDouble("Abilities.Fire.FireCombo.JetBlast.Speed"); + this.cooldown = getConfig().getLong("Abilities.Fire.FireCombo.JetBlast.Cooldown"); } else if (ability.equalsIgnoreCase("JetBlaze")) { - damage = JET_BLAZE_DAMAGE; - speed = JET_BLAZE_SPEED; - cooldown = JET_BLAZE_COOLDOWN; + this.damage = getConfig().getDouble("Abilities.Fire.FireCombo.JetBlaze.Damage"); + this.speed = getConfig().getDouble("Abilities.Fire.FireCombo.JetBlaze.Speed"); + this.cooldown = getConfig().getLong("Abilities.Fire.FireCombo.JetBlaze.Cooldown"); + this.fireTicks = getConfig().getDouble("Abilities.Fire.FireCombo.JetBlaze.FireTicks"); } - if (AvatarState.isAvatarState(player)) { - cooldown = 0; - damage = AvatarState.getValue(damage); - range = AvatarState.getValue(range); + + if (bPlayer.isAvatarState()) { + this.cooldown = 0; + this.damage = AvatarState.getValue(damage); + this.range = AvatarState.getValue(range); } - instances.add(this); + start(); } - /** - * Returns all the FireCombos created by a specific player. - */ - public static ArrayList getFireCombo(Player player) { - ArrayList list = new ArrayList(); - for (FireCombo lf : instances) - if (lf.player != null && lf.player == player) - list.add(lf); - return list; - } /** * Returns all of the FireCombos created by a specific player but filters the abilities based on @@ -156,44 +131,33 @@ public class FireCombo implements ConfigLoadable { */ public static ArrayList getFireCombo(Player player, ClickType type) { ArrayList list = new ArrayList(); - for (FireCombo lf : instances) - if (lf.player != null && lf.player == player && lf.type != null && lf.type == type) + for (FireCombo lf : getAbilities(player, FireCombo.class)) { + if (lf.clickType == type) { list.add(lf); - return list; - } - - public static void progressAll() { - for (int i = instances.size() - 1; i >= 0; i--) - instances.get(i).progress(); - } - - public static void removeAll() { - for (int i = instances.size() - 1; i >= 0; i--) { - instances.get(i).remove(); + } } + return list; } public static boolean removeAroundPoint(Player player, String ability, Location loc, double radius) { boolean removed = false; - for (int i = 0; i < instances.size(); i++) { - FireCombo combo = instances.get(i); - if (combo.getPlayer().equals(player)) + for (FireCombo combo : getAbilities(FireCombo.class)) { + if (combo.getPlayer().equals(player)) { continue; + } if (ability.equalsIgnoreCase("FireKick") && combo.ability.equalsIgnoreCase("FireKick")) { for (FireComboStream fs : combo.tasks) { if (fs.getLocation() != null && fs.getLocation().getWorld() == loc.getWorld() - && Math.abs(fs.getLocation().distance(loc)) <= radius) { + && Math.abs(fs.getLocation().distanceSquared(loc)) <= radius * radius) { fs.remove(); removed = true; } } - } - - else if (ability.equalsIgnoreCase("FireSpin") && combo.ability.equalsIgnoreCase("FireSpin")) { + } else if (ability.equalsIgnoreCase("FireSpin") && combo.ability.equalsIgnoreCase("FireSpin")) { for (FireComboStream fs : combo.tasks) { if (fs.getLocation() != null && fs.getLocation().getWorld().equals(loc.getWorld())) { - if (Math.abs(fs.getLocation().distance(loc)) <= radius) { + if (Math.abs(fs.getLocation().distanceSquared(loc)) <= radius * radius) { fs.remove(); removed = true; } @@ -202,8 +166,8 @@ public class FireCombo implements ConfigLoadable { } else if (ability.equalsIgnoreCase("FireWheel") && combo.ability.equalsIgnoreCase("FireWheel")) { - if (combo.currentLoc != null && Math.abs(combo.currentLoc.distance(loc)) <= radius) { - instances.remove(combo); + if (combo.location != null && Math.abs(combo.location.distanceSquared(loc)) <= radius * radius) { + combo.remove(); removed = true; } } @@ -211,70 +175,69 @@ public class FireCombo implements ConfigLoadable { return removed; } - public void checkSafeZone() { - if (currentLoc != null && GeneralMethods.isRegionProtectedFromBuild(player, "Blaze", currentLoc)) - remove(); - } - public void collision(LivingEntity entity, Vector direction, FireComboStream fstream) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "Blaze", entity.getLocation())) + if (GeneralMethods.isRegionProtectedFromBuild(player, "Blaze", entity.getLocation())) { return; + } entity.getLocation().getWorld().playSound(entity.getLocation(), Sound.VILLAGER_HIT, 0.3f, 0.3f); if (ability.equalsIgnoreCase("FireKick")) { - GeneralMethods.damageEntity(player, entity, damage, Element.Fire, "FireKick"); + GeneralMethods.damageEntity(this, entity, damage); fstream.remove(); } else if (ability.equalsIgnoreCase("FireSpin")) { if (entity instanceof Player) { - if (Commands.invincible.contains(((Player) entity).getName())) + if (Commands.invincible.contains(((Player) entity).getName())) { return; + } } - double knockback = AvatarState.isAvatarState(player) ? FIRE_SPIN_KNOCKBACK + 0.5 : FIRE_SPIN_KNOCKBACK; - GeneralMethods.damageEntity(player, entity, damage, Element.Fire, "FireSpin"); - entity.setVelocity(direction.normalize().multiply(knockback)); + + double newKnockback = bPlayer.isAvatarState() ? knockback + 0.5 : knockback; + GeneralMethods.damageEntity(this, entity, damage); + entity.setVelocity(direction.normalize().multiply(newKnockback)); fstream.remove(); } else if (ability.equalsIgnoreCase("JetBlaze")) { if (!affectedEntities.contains(entity)) { affectedEntities.add(entity); - GeneralMethods.damageEntity(player, entity, damage, Element.Fire, "JetBlaze"); - entity.setFireTicks((int) (fireticksJetBlaze * 20)); + GeneralMethods.damageEntity(this, entity, damage); + entity.setFireTicks((int) (fireTicks * 20)); } } else if (ability.equalsIgnoreCase("FireWheel")) { if (!affectedEntities.contains(entity)) { affectedEntities.add(entity); - GeneralMethods.damageEntity(player, entity, damage, Element.Fire, "FireWheel"); - entity.setFireTicks((int) (fireticksFireWheel * 20)); + GeneralMethods.damageEntity(this, entity, damage); + entity.setFireTicks((int) (fireTicks * 20)); this.remove(); } } } - public Player getPlayer() { - return player; - } - + @Override public void progress() { + Bukkit.broadcastMessage("Progressing"); progressCounter++; for (int i = 0; i < tasks.size(); i++) { BukkitRunnable br = tasks.get(i); if (br instanceof FireComboStream) { FireComboStream fs = (FireComboStream) br; - if (fs.isCancelled()) + if (fs.isCancelled()) { tasks.remove(fs); + } } } - if (player.isDead() || !player.isOnline()) { + + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { remove(); return; } if (ability.equalsIgnoreCase("FireKick")) { if (destination == null) { - if (bplayer.isOnCooldown("FireKick") && !AvatarState.isAvatarState(player)) { + if (bPlayer.isOnCooldown("FireKick") && !bPlayer.isAvatarState()) { remove(); return; } - bplayer.addCooldown("FireKick", cooldown); + + bPlayer.addCooldown("FireKick", cooldown); Vector eyeDir = player.getEyeLocation().getDirection().normalize().multiply(range); destination = player.getEyeLocation().add(eyeDir); @@ -288,27 +251,30 @@ public class FireCombo implements ConfigLoadable { fs.setSpread(0.2F); fs.setDensity(5); fs.setUseNewParticles(true); - if (tasks.size() % 3 != 0) + if (tasks.size() % 3 != 0) { fs.setCollides(false); + } fs.runTaskTimer(ProjectKorra.plugin, 0, 1L); tasks.add(fs); player.getWorld().playSound(player.getLocation(), Sound.FIRE_IGNITE, 0.5f, 1f); } - currentLoc = ((FireComboStream) tasks.get(0)).getLocation(); - for (FireComboStream stream : tasks) - if (GeneralMethods.blockAbilities(player, abilitiesToBlock, stream.currentLoc, 2)) + location = tasks.get(0).getLocation(); + for (FireComboStream stream : tasks) { + if (GeneralMethods.blockAbilities(player, BLOCKABLE_ABILITIES, stream.location, 2)) { stream.remove(); + } + } } else if (tasks.size() == 0) { remove(); return; } } else if (ability.equalsIgnoreCase("FireSpin")) { if (destination == null) { - if (bplayer.isOnCooldown("FireSpin") && !AvatarState.isAvatarState(player)) { + if (bPlayer.isOnCooldown("FireSpin") && !bPlayer.isAvatarState()) { remove(); return; } - bplayer.addCooldown("FireSpin", cooldown); + bPlayer.addCooldown("FireSpin", cooldown); destination = player.getEyeLocation().add(range, 0, range); player.getWorld().playSound(player.getLocation(), Sound.FIZZ, 0.5f, 0.5f); @@ -317,47 +283,52 @@ public class FireCombo implements ConfigLoadable { vec = GeneralMethods.rotateXZ(vec, i - 180); vec.setY(0); - FireComboStream fs = new FireComboStream(this, vec, player.getLocation().clone().add(0, 1, 0), range, speed, - "FireSpin"); + FireComboStream fs = new FireComboStream(this, vec, player.getLocation().clone().add(0, 1, 0), range, speed, "FireSpin"); fs.setSpread(0.0F); fs.setDensity(1); fs.setUseNewParticles(true); - if (tasks.size() % 10 != 0) + if (tasks.size() % 10 != 0) { fs.setCollides(false); + } fs.runTaskTimer(ProjectKorra.plugin, 0, 1L); tasks.add(fs); } } + if (tasks.size() == 0) { remove(); return; } + for (FireComboStream stream : tasks) { - if (FireMethods.isWithinFireShield(stream.getLocation())) + if (isWithinFireShield(stream.getLocation())) { stream.remove(); - if (AirMethods.isWithinAirShield(stream.getLocation())) + } + if (AirAbility.isWithinAirShield(stream.getLocation())) { stream.remove(); + } } } else if (ability.equalsIgnoreCase("JetBlast")) { if (System.currentTimeMillis() - time > 5000) { remove(); return; - } else if (FireJet.checkTemporaryImmunity(player)) { + } else if (hasAbility(player, FireJet.class)) { if (firstTime) { - if (bplayer.isOnCooldown("JetBlast") && !AvatarState.isAvatarState(player)) { + if (bPlayer.isOnCooldown("JetBlast") && !bPlayer.isAvatarState()) { remove(); return; } - bplayer.addCooldown("JetBlast", cooldown); + + bPlayer.addCooldown("JetBlast", cooldown); firstTime = false; float spread = 0F; ParticleEffect.LARGE_EXPLODE.display(player.getLocation(), spread, spread, spread, 0, 1); player.getWorld().playSound(player.getLocation(), Sound.EXPLODE, 15, 0F); } player.setVelocity(player.getVelocity().normalize().multiply(speed)); - - FireComboStream fs = new FireComboStream(this, player.getVelocity().clone().multiply(-1), player.getLocation(), - 3, 0.5, "JetBlast"); + FireComboStream fs = new FireComboStream(this, + player.getVelocity().clone().multiply(-1), player.getLocation(), 3, 0.5, "JetBlast"); + fs.setDensity(1); fs.setSpread(0.9F); fs.setUseNewParticles(true); @@ -365,20 +336,18 @@ public class FireCombo implements ConfigLoadable { fs.runTaskTimer(ProjectKorra.plugin, 0, 1L); tasks.add(fs); } - } - - else if (ability.equalsIgnoreCase("JetBlaze")) { + } else if (ability.equalsIgnoreCase("JetBlaze")) { if (firstTime) { - if (bplayer.isOnCooldown("JetBlaze") && !AvatarState.isAvatarState(player)) { + if (bPlayer.isOnCooldown("JetBlaze") && !bPlayer.isAvatarState()) { remove(); return; } - bplayer.addCooldown("JetBlaze", cooldown); + bPlayer.addCooldown("JetBlaze", cooldown); firstTime = false; } else if (System.currentTimeMillis() - time > 5000) { remove(); return; - } else if (FireJet.checkTemporaryImmunity(player)) { + } else if (hasAbility(player, FireJet.class)) { direction = player.getVelocity().clone().multiply(-1); player.setVelocity(player.getVelocity().normalize().multiply(speed)); @@ -388,20 +357,22 @@ public class FireCombo implements ConfigLoadable { fs.setUseNewParticles(true); fs.setCollisionRadius(3); fs.setParticleEffect(ParticleEffect.LARGE_SMOKE); - if (progressCounter % 5 != 0) + if (progressCounter % 5 != 0) { fs.setCollides(false); + } fs.runTaskTimer(ProjectKorra.plugin, 0, 1L); tasks.add(fs); - if (progressCounter % 4 == 0) + if (progressCounter % 4 == 0) { player.getWorld().playSound(player.getLocation(), Sound.FIZZ, 1, 0F); + } } } else if (ability.equalsIgnoreCase("FireWheel")) { - if (currentLoc == null) { - if (bplayer.isOnCooldown("FireWheel") && !AvatarState.isAvatarState(player)) { + if (location == null) { + if (bPlayer.isOnCooldown("FireWheel") && !bPlayer.isAvatarState()) { remove(); return; } - bplayer.addCooldown("FireWheel", cooldown); + bPlayer.addCooldown("FireWheel", cooldown); origin = player.getLocation(); if (GeneralMethods.getTopBlock(player.getLocation(), 3, 3) == null) { @@ -409,24 +380,24 @@ public class FireCombo implements ConfigLoadable { return; } - currentLoc = player.getLocation(); + location = player.getLocation(); direction = player.getEyeLocation().getDirection().clone().normalize(); direction.setY(0); - } else if (currentLoc.distance(origin) > range) { + } else if (location.distanceSquared(origin) > range * range) { remove(); return; } - Block topBlock = GeneralMethods.getTopBlock(currentLoc, 2, -4); - if (topBlock == null || (WaterMethods.isWaterbendable(topBlock, player) && !WaterMethods.isPlant(topBlock))) { + Block topBlock = GeneralMethods.getTopBlock(location, 2, -4); + if (topBlock == null || (WaterAbility.isWaterbendable(topBlock, player) && !isPlant(topBlock))) { remove(); return; - } - if (topBlock.getType() == Material.FIRE || WaterMethods.isPlant(topBlock)) + } else if (topBlock.getType() == Material.FIRE || ElementalAbility.isPlant(topBlock)) { topBlock = topBlock.getLocation().add(0, -1, 0).getBlock(); - currentLoc.setY(topBlock.getY() + FIRE_WHEEL_STARTING_HEIGHT); - - FireComboStream fs = new FireComboStream(this, direction, currentLoc.clone().add(0, -1, 0), 5, 1, "FireWheel"); + } + location.setY(topBlock.getY() + height); + FireComboStream fs = new FireComboStream(this, direction, location.clone().add(0, -1, 0), 5, 1, "FireWheel"); + fs.setDensity(0); fs.setSinglePoint(true); fs.setCollisionRadius(1.5); @@ -435,89 +406,107 @@ public class FireCombo implements ConfigLoadable { tasks.add(fs); for (double i = -180; i <= 180; i += 3) { - Location tempLoc = currentLoc.clone(); - Vector newDir = direction.clone().multiply(FIRE_WHEEL_RADIUS * Math.cos(Math.toRadians(i))); + Location tempLoc = location.clone(); + Vector newDir = direction.clone().multiply(radius * Math.cos(Math.toRadians(i))); tempLoc.add(newDir); - tempLoc.setY(tempLoc.getY() + (FIRE_WHEEL_RADIUS * Math.sin(Math.toRadians(i)))); + tempLoc.setY(tempLoc.getY() + (radius * Math.sin(Math.toRadians(i)))); ParticleEffect.FLAME.display(tempLoc, 0, 0, 0, 0, 1); } - currentLoc = currentLoc.add(direction.clone().multiply(speed)); - currentLoc.getWorld().playSound(currentLoc, Sound.FIRE, 1, 1); - if (GeneralMethods.blockAbilities(player, abilitiesToBlock, currentLoc, 2)) { + location = location.add(direction.clone().multiply(speed)); + location.getWorld().playSound(location, Sound.FIRE, 1, 1); + if (GeneralMethods.blockAbilities(player, BLOCKABLE_ABILITIES, location, 2)) { remove(); return; } - ; } - - if (progressCounter % 3 == 0) - checkSafeZone(); - } - - @Override - public void reloadVariables() { - enabled = config.get().getBoolean("Abilities.Fire.FireCombo.Enabled"); - fireticksFireWheel = config.get().getDouble("Abilities.Fire.FireCombo.FireWheel.FireTicks"); - fireticksJetBlaze = config.get().getDouble("Abilities.Fire.FireCombo.JetBlaze.FireTicks"); - FIRE_KICK_RANGE = config.get().getDouble("Abilities.Fire.FireCombo.FireKick.Range"); - FIRE_KICK_DAMAGE = config.get().getDouble("Abilities.Fire.FireCombo.FireKick.Damage"); - FIRE_SPIN_RANGE = config.get().getDouble("Abilities.Fire.FireCombo.FireSpin.Range"); - FIRE_SPIN_DAMAGE = config.get().getDouble("Abilities.Fire.FireCombo.FireSpin.Damage"); - FIRE_SPIN_KNOCKBACK = config.get().getDouble("Abilities.Fire.FireCombo.FireSpin.Knockback"); - FIRE_WHEEL_DAMAGE = config.get().getDouble("Abilities.Fire.FireCombo.FireWheel.Damage"); - FIRE_WHEEL_RANGE = config.get().getDouble("Abilities.Fire.FireCombo.FireWheel.Range"); - FIRE_WHEEL_SPEED = config.get().getDouble("Abilities.Fire.FireCombo.FireWheel.Speed"); - JET_BLAST_SPEED = config.get().getDouble("Abilities.Fire.FireCombo.JetBlast.Speed"); - JET_BLAZE_SPEED = config.get().getDouble("Abilities.Fire.FireCombo.JetBlaze.Speed"); - JET_BLAZE_DAMAGE = config.get().getDouble("Abilities.Fire.FireCombo.JetBlaze.Damage"); - - FIRE_KICK_COOLDOWN = config.get().getLong("Abilities.Fire.FireCombo.FireKick.Cooldown"); - FIRE_SPIN_COOLDOWN = config.get().getLong("Abilities.Fire.FireCombo.FireSpin.Cooldown"); - FIRE_WHEEL_COOLDOWN = config.get().getLong("Abilities.Fire.FireCombo.FireWheel.Cooldown"); - JET_BLAST_COOLDOWN = config.get().getLong("Abilities.Fire.FireCombo.JetBlast.Cooldown"); - JET_BLAZE_COOLDOWN = config.get().getLong("Abilities.Fire.FireCombo.JetBlaze.Cooldown"); } /** * Removes this instance of FireCombo, cleans up any blocks that are remaining in totalBlocks, * and cancels any remaining tasks. */ + @Override public void remove() { - instances.remove(this); - for (BukkitRunnable task : tasks) + super.remove(); + for (BukkitRunnable task : tasks) { task.cancel(); + } } public static class FireComboStream extends BukkitRunnable { - private Vector direction; + private boolean useNewParticles; + private boolean cancelled; + private boolean collides; + private boolean singlePoint; + private int density; + private int checkCollisionDelay; + private int checkCollisionCounter; + private float spread; + private double collisionRadius; private double speed; - private Location initialLoc, currentLoc; private double distance; + ParticleEffect particleEffect; + private FireCombo fireCombo; + private Vector direction; + private Location initialLocation; + private Location location; private String ability; - ParticleEffect particleEffect = ParticleEffect.FLAME; - private FireCombo fireCombo; - private float spread = 0; - private int density = 1; - private boolean useNewParticles = false; - private boolean cancelled = false; - private boolean collides = true; - private boolean singlePoint = false; - private double collisionRadius = 2; - private int checkCollisionDelay = 1; - private int checkCollisionCounter = 0; - - public FireComboStream(FireCombo fireCombo, Vector direction, Location loc, double distance, double speed, String ability) { + public FireComboStream(FireCombo fireCombo, Vector direction, Location location, double distance, double speed, String ability) { + this.useNewParticles = false; + this.cancelled = false; + this.collides = true; + this.singlePoint = false; + this.density = 1; + this.checkCollisionDelay = 1; + this.checkCollisionCounter = 0; + this.spread = 0; + this.collisionRadius = 2; + this.particleEffect = ParticleEffect.FLAME; this.fireCombo = fireCombo; this.direction = direction; this.speed = speed; - this.initialLoc = loc.clone(); - this.currentLoc = loc.clone(); + this.initialLocation = location.clone(); + this.location = location.clone(); this.distance = distance; this.ability = ability; } + + @Override + public void run() { + Block block = location.getBlock(); + if (block.getRelative(BlockFace.UP).getType() != Material.AIR && !ElementalAbility.isPlant(block)) { + remove(); + return; + } + for (int i = 0; i < density; i++) { + if (useNewParticles) { + particleEffect.display(location, spread, spread, spread, 0, 1); + } else { + location.getWorld().playEffect(location, Effect.MOBSPAWNER_FLAMES, 0, 15); + } + } + location.add(direction.normalize().multiply(speed)); + if (initialLocation.distanceSquared(location) > distance * distance) { + remove(); + return; + } else if (collides && checkCollisionCounter % checkCollisionDelay == 0) { + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, collisionRadius)) { + if (entity instanceof LivingEntity && !entity.equals(fireCombo.getPlayer())) { + fireCombo.collision((LivingEntity) entity, direction, this); + } + } + } + + checkCollisionCounter++; + if (singlePoint) { + remove(); + } + } + + @Override public void cancel() { remove(); } @@ -527,7 +516,7 @@ public class FireCombo implements ConfigLoadable { } public Location getLocation() { - return this.currentLoc; + return this.location; } public String getAbility() { @@ -543,34 +532,6 @@ public class FireCombo implements ConfigLoadable { this.cancelled = true; } - public void run() { - Block block = currentLoc.getBlock(); - if (block.getRelative(BlockFace.UP).getType() != Material.AIR && !WaterMethods.isPlant(block)) { - remove(); - return; - } - for (int i = 0; i < density; i++) { - if (useNewParticles) - particleEffect.display(currentLoc, spread, spread, spread, 0, 1); - else - currentLoc.getWorld().playEffect(currentLoc, Effect.MOBSPAWNER_FLAMES, 0, 15); - } - - currentLoc.add(direction.normalize().multiply(speed)); - if (initialLoc.distance(currentLoc) > distance) { - remove(); - return; - } else if (collides && checkCollisionCounter % checkCollisionDelay == 0) { - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(currentLoc, collisionRadius)) { - if (entity instanceof LivingEntity && !entity.equals(fireCombo.getPlayer())) - fireCombo.collision((LivingEntity) entity, direction, this); - } - } - checkCollisionCounter++; - if (singlePoint) - remove(); - } - public void setCheckCollisionDelay(int delay) { this.checkCollisionDelay = delay; } @@ -604,4 +565,261 @@ public class FireCombo implements ConfigLoadable { } } + @Override + public String getName() { + return ability != null ? ability : "FireCombo"; + } + + @Override + public Location getLocation() { + return location != null ? location : origin; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + @Override + public String getInstructions() { + return null; + } + + @Override + public Object createNewComboInstance(Player player) { + return null; + } + + @Override + public ArrayList getCombination() { + return null; + } + + public boolean isHiddenAbility() { + return true; + } + + public boolean isFirstTime() { + return firstTime; + } + + public void setFirstTime(boolean firstTime) { + this.firstTime = firstTime; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public int getProgressCounter() { + return progressCounter; + } + + public void setProgressCounter(int progressCounter) { + this.progressCounter = progressCounter; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public double getDamage() { + return damage; + } + + public void setDamage(double damage) { + this.damage = damage; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getKnockback() { + return knockback; + } + + public void setKnockback(double knockback) { + this.knockback = knockback; + } + + public double getFireTicks() { + return fireTicks; + } + + public void setFireTicks(double fireTicks) { + this.fireTicks = fireTicks; + } + + public double getHeight() { + return height; + } + + public void setHeight(double height) { + this.height = height; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public ClickType getClickType() { + return clickType; + } + + public void setClickType(ClickType clickType) { + this.clickType = clickType; + } + + public String getAbility() { + return ability; + } + + public void setAbility(String ability) { + this.ability = ability; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public Location getDestination() { + return destination; + } + + public void setDestination(Location destination) { + this.destination = destination; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public static ArrayList getBlockableAbilities() { + return BLOCKABLE_ABILITIES; + } + + public ArrayList getAffectedEntities() { + return affectedEntities; + } + + public ArrayList getTasks() { + return tasks; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + + public class FireKick extends FireCombo { + + public FireKick(Player player, String name) { + super(player, "FireKick"); + } + + @Override + public String getName() { + return "FireKick"; + } + + } + + public class FireSpin extends FireCombo { + + public FireSpin(Player player, String name) { + super(player, "FireSpin"); + } + + @Override + public String getName() { + return "FireSpin"; + } + + } + + public class FireWheel extends FireCombo { + + public FireWheel(Player player, String name) { + super(player, "FireWheel"); + } + + @Override + public String getName() { + return "FireWheel"; + } + + } + + public class JetBlast extends FireCombo { + + public JetBlast(Player player, String name) { + super(player, "JetBlast"); + } + + @Override + public String getName() { + return "JetBlast"; + } + + } + + public class JetBlaze extends FireCombo { + + public JetBlaze(Player player, String name) { + super(player, "JetBlaze"); + } + + @Override + public String getName() { + return "JetBlaze"; + } + + } + } diff --git a/src/com/projectkorra/projectkorra/firebending/FireDamageTimer.java b/src/com/projectkorra/projectkorra/firebending/FireDamageTimer.java new file mode 100644 index 00000000..301f6d75 --- /dev/null +++ b/src/com/projectkorra/projectkorra/firebending/FireDamageTimer.java @@ -0,0 +1,67 @@ +package com.projectkorra.projectkorra.firebending; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; + +import java.util.concurrent.ConcurrentHashMap; + +public class FireDamageTimer { + + private static final int MAX_TICKS = 90; + private static final int DAMAGE = 1; + private static final long BUFFER = 30; + private static final ConcurrentHashMap INSTANCES = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap TIMES = new ConcurrentHashMap<>(); + + public FireDamageTimer(Entity entity, Player source) { + if (entity.getEntityId() == source.getEntityId()) { + return; + } + if (INSTANCES.containsKey(entity)) { + INSTANCES.replace(entity, source); + } else { + INSTANCES.put(entity, source); + } + } + + public static boolean isEnflamed(Entity entity) { + if (INSTANCES.containsKey(entity)) { + if (TIMES.containsKey(entity)) { + long time = TIMES.get(entity); + if (System.currentTimeMillis() < time + BUFFER) { + return false; + } + } + TIMES.put(entity, System.currentTimeMillis()); + return true; + } else { + return false; + } + } + + public static void dealFlameDamage(Entity entity) { + if (INSTANCES.containsKey(entity) && entity instanceof LivingEntity) { + if (entity instanceof Player) { + if (!HeatControlExtinguish.canBurn((Player) entity)) { + return; + } + } + LivingEntity Lentity = (LivingEntity) entity; + Player source = INSTANCES.get(entity); + Lentity.damage(DAMAGE, source); + if (entity.getFireTicks() > MAX_TICKS) { + entity.setFireTicks(MAX_TICKS); + } + } + } + + public static void handleFlames() { + for (Entity entity : INSTANCES.keySet()) { + if (entity.getFireTicks() <= 0) { + INSTANCES.remove(entity); + } + } + } + +} diff --git a/src/com/projectkorra/projectkorra/firebending/FireJet.java b/src/com/projectkorra/projectkorra/firebending/FireJet.java index 40576bf5..71d8e39a 100644 --- a/src/com/projectkorra/projectkorra/firebending/FireJet.java +++ b/src/com/projectkorra/projectkorra/firebending/FireJet.java @@ -1,154 +1,152 @@ package com.projectkorra.projectkorra.firebending; -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.util.Flight; +import com.projectkorra.projectkorra.util.ParticleEffect; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.util.Flight; -import com.projectkorra.projectkorra.util.ParticleEffect; -import com.projectkorra.projectkorra.waterbending.WaterMethods; +import java.util.Random; -public class FireJet implements ConfigLoadable { - - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static double defaultfactor = config.get().getDouble("Abilities.Fire.FireJet.Speed"); - private static long defaultduration = config.get().getLong("Abilities.Fire.FireJet.Duration"); - private static boolean isToggle = config.get().getBoolean("Abilities.Fire.FireJet.IsAvatarStateToggle"); +public class FireJet extends FireAbility { - private Player player; + private boolean avatarStateToggled; private long time; - private long duration = defaultduration; - private double factor = defaultfactor; - + private long duration; + private long cooldown; + private double speed; + private Random random; + public FireJet(Player player) { - /* Initial Checks */ - if (instances.containsKey(player)) { - instances.get(player).remove(); + super(player); + + FireJet oldJet = getAbility(player, FireJet.class); + if (oldJet != null) { + oldJet.remove(); + return; + } else if (bPlayer.isOnCooldown(this)) { return; } - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("FireJet")) - return; - /* End Initial Checks */ - // reloadVariables(); + + this.avatarStateToggled = getConfig().getBoolean("Abilities.Fire.FireJet.IsAvatarStateToggle"); + this.duration = getConfig().getLong("Abilities.Fire.FireJet.Duration"); + this.speed = getConfig().getDouble("Abilities.Fire.FireJet.Speed"); + this.cooldown = getConfig().getLong("Abilities.Fire.FireJet.Cooldown"); + this.random = new Random(); - factor = FireMethods.getFirebendingDayAugment(defaultfactor, player.getWorld()); + this.speed = getDayFactor(speed); Block block = player.getLocation().getBlock(); - if (FireStream.isIgnitable(player, block) || block.getType() == Material.AIR || AvatarState.isAvatarState(player)) { - player.setVelocity(player.getEyeLocation().getDirection().clone().normalize().multiply(factor)); - if (FireMethods.canFireGrief()) { - FireMethods.createTempFire(block.getLocation()); - } else + + if (BlazeArc.isIgnitable(player, block) || block.getType() == Material.AIR || bPlayer.isAvatarState()) { + player.setVelocity(player.getEyeLocation().getDirection().clone().normalize().multiply(speed)); + if (canFireGrief()) { + createTempFire(block.getLocation()); + } else { block.setType(Material.FIRE); - this.player = player; - // canfly = player.getAllowFlight(); + } + new Flight(player); player.setAllowFlight(true); time = System.currentTimeMillis(); - // timers.put(player, time); - instances.put(player, this); - bPlayer.addCooldown("FireJet", config.get().getLong("Abilities.Fire.FireJet.Cooldown")); + + start(); + bPlayer.addCooldown(this); } - } - public static boolean checkTemporaryImmunity(Player player) { - if (instances.containsKey(player)) { - return true; + @Override + public void progress() { + if (player.isDead() || !player.isOnline()) { + remove(); + return; + } else if ((isWater(player.getLocation().getBlock()) || System.currentTimeMillis() > time + duration) + && (!bPlayer.isAvatarState() || !avatarStateToggled)) { + remove(); + return; + } else { + if (random.nextInt(2) == 0) { + playFirebendingSound(player.getLocation()); + } + + ParticleEffect.FLAME.display(player.getLocation(), 0.6F, 0.6F, 0.6F, 0, 20); + ParticleEffect.SMOKE.display(player.getLocation(), 0.6F, 0.6F, 0.6F, 0, 20); + double timefactor; + + if (bPlayer.isAvatarState() && avatarStateToggled) { + timefactor = 1; + } else { + timefactor = 1 - (System.currentTimeMillis() - time) / (2.0 * duration); + } + + Vector velocity = player.getEyeLocation().getDirection().clone().normalize().multiply(speed * timefactor); + player.setVelocity(velocity); + player.setFallDistance(0); } + } + + @Override + public String getName() { + return "FireJet"; + } + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { return false; } - public static ArrayList getPlayers() { - ArrayList players = new ArrayList(); - for (FireJet jet : instances.values()) { - players.add(jet.getPlayer()); - } - return players; + @Override + public boolean isHarmlessAbility() { + return true; + } + + public boolean isAvatarStateToggled() { + return avatarStateToggled; + } + + public void setAvatarStateToggled(boolean avatarStateToggled) { + this.avatarStateToggled = avatarStateToggled; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; } public long getDuration() { return duration; } - public double getFactor() { - return factor; - } - - public Player getPlayer() { - return player; - } - - public boolean progress() { - if (player.isDead() || !player.isOnline()) { - // player.setAllowFlight(canfly); - remove(); - return false; - } - if ((WaterMethods.isWater(player.getLocation().getBlock()) || System.currentTimeMillis() > time + duration) - && (!AvatarState.isAvatarState(player) || !isToggle)) { - // player.setAllowFlight(canfly); - remove(); - } else { - if (GeneralMethods.rand.nextInt(2) == 0) { - FireMethods.playFirebendingSound(player.getLocation()); - } - ParticleEffect.FLAME.display(player.getLocation(), 0.6F, 0.6F, 0.6F, 0, 20); - ParticleEffect.SMOKE.display(player.getLocation(), 0.6F, 0.6F, 0.6F, 0, 20); - double timefactor; - if (AvatarState.isAvatarState(player) && isToggle) { - timefactor = 1; - } else { - timefactor = 1 - ((double) (System.currentTimeMillis() - time)) / (2.0 * duration); - } - Vector velocity = player.getEyeLocation().getDirection().clone().normalize().multiply(factor * timefactor); - // Vector velocity = player.getVelocity().clone(); - // velocity.add(player.getEyeLocation().getDirection().clone() - // .normalize().multiply(factor * timefactor)); - player.setVelocity(velocity); - player.setFallDistance(0); - } - return true; - } - - public static void progressAll() { - for (FireJet ability : instances.values()) { - ability.progress(); - } - } - - @Override - public void reloadVariables() { - defaultfactor = config.get().getDouble("Abilities.Fire.FireJet.Speed"); - defaultduration = config.get().getLong("Abilities.Fire.FireJet.Duration"); - isToggle = config.get().getBoolean("Abilities.Fire.FireJet.IsAvatarStateToggle"); - } - - public void remove() { - instances.remove(player); - } - - public static void removeAll() { - for (FireJet ability : instances.values()) { - ability.remove(); - } - } - public void setDuration(long duration) { this.duration = duration; } - public void setFactor(double factor) { - this.factor = factor; + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; } } diff --git a/src/com/projectkorra/projectkorra/firebending/FirePassive.java b/src/com/projectkorra/projectkorra/firebending/FirePassive.java index b6df442d..eff1dba4 100644 --- a/src/com/projectkorra/projectkorra/firebending/FirePassive.java +++ b/src/com/projectkorra/projectkorra/firebending/FirePassive.java @@ -1,7 +1,7 @@ package com.projectkorra.projectkorra.firebending; +import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.GeneralMethods; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -10,12 +10,12 @@ public class FirePassive { public static void handlePassive() { for (Player player : Bukkit.getOnlinePlayers()) { - if (GeneralMethods.canBendPassive(player.getName(), Element.Fire)) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer != null && bPlayer.canBendPassive(Element.FIRE)) { if (player.getFireTicks() > 80) { player.setFireTicks(80); } } } } - } diff --git a/src/com/projectkorra/projectkorra/firebending/FireShield.java b/src/com/projectkorra/projectkorra/firebending/FireShield.java index 86839f39..77e051b3 100644 --- a/src/com/projectkorra/projectkorra/firebending/FireShield.java +++ b/src/com/projectkorra/projectkorra/firebending/FireShield.java @@ -1,7 +1,10 @@ package com.projectkorra.projectkorra.firebending; -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.earthbending.EarthBlast; +import com.projectkorra.projectkorra.util.ParticleEffect; +import com.projectkorra.projectkorra.waterbending.WaterManipulation; import org.bukkit.Effect; import org.bukkit.Location; @@ -13,159 +16,113 @@ import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ability.StockAbility; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.earthbending.EarthBlast; -import com.projectkorra.projectkorra.util.ParticleEffect; -import com.projectkorra.projectkorra.waterbending.WaterManipulation; +import java.util.ArrayList; +import java.util.Random; -public class FireShield implements ConfigLoadable { +public class FireShield extends FireAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static long interval = 100; - private static long DURATION = config.get().getLong("Abilities.Fire.FireShield.Duration"); - private static double RADIUS = config.get().getDouble("Abilities.Fire.FireShield.Radius"); - private static double DISC_RADIUS = config.get().getDouble("Abilities.Fire.FireShield.DiscRadius"); - private static double fireticks = config.get().getDouble("Abilities.Fire.FireShield.FireTicks"); - private static boolean ignite = true; - - private Player player; + private boolean shield; + private boolean ignite; private long time; - private long starttime; - private boolean shield = false; - private long duration = DURATION; - private double radius = RADIUS; - private double discradius = DISC_RADIUS; + private long duration; + private long interval; + private long cooldown; + private double radius; + private double discRadius; + private double fireTicks; + private Random random; public FireShield(Player player) { this(player, false); } public FireShield(Player player, boolean shield) { - /* Initial Checks */ - if (instances.containsKey(player)) - return; - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("FireShield")) - return; - /* End Initial Checks */ - // reloadVariables(); - this.player = player; + super(player); + this.shield = shield; - - if (!player.getEyeLocation().getBlock().isLiquid()) { + this.ignite = true; + this.interval = 100; + this.cooldown = shield ? 0 : GeneralMethods.getGlobalCooldown(); + this.duration = getConfig().getLong("Abilities.Fire.FireShield.Duration"); + this.radius = getConfig().getDouble("Abilities.Fire.FireShield.Radius"); + this.discRadius = getConfig().getDouble("Abilities.Fire.FireShield.DiscRadius"); + this.fireTicks = getConfig().getDouble("Abilities.Fire.FireShield.FireTicks"); + this.random = new Random(); + + if (hasAbility(player, FireShield.class) || bPlayer.isOnCooldown("FireShield")) { + return; + } else if (!player.getEyeLocation().getBlock().isLiquid()) { time = System.currentTimeMillis(); - starttime = time; - instances.put(player, this); - if (!shield) - bPlayer.addCooldown("FireShield", GeneralMethods.getGlobalCooldown()); + start(); + if (!shield) { + bPlayer.addCooldown(this); + } } } - public static String getDescription() { - return "FireShield is a basic defensive ability. " + "Clicking with this ability selected will create a " - + "small disc of fire in front of you, which will block most " - + "attacks and bending. Alternatively, pressing and holding " - + "sneak creates a very small shield of fire, blocking most attacks. " - + "Creatures that contact this fire are ignited."; - } - public static boolean isWithinShield(Location loc) { - for (FireShield fshield : instances.values()) { + for (FireShield fshield : getAbilities(FireShield.class)) { Location playerLoc = fshield.player.getLocation(); if (fshield.shield) { - if (!playerLoc.getWorld().equals(loc.getWorld())) + if (!playerLoc.getWorld().equals(loc.getWorld())) { return false; - if (playerLoc.distance(loc) <= fshield.radius) + } else if (playerLoc.distanceSquared(loc) <= fshield.radius * fshield.radius) { return true; + } } else { - Location tempLoc = playerLoc.clone().add(playerLoc.multiply(fshield.discradius)); - if (!tempLoc.getWorld().equals(loc.getWorld())) + Location tempLoc = playerLoc.clone().add(playerLoc.multiply(fshield.discRadius)); + if (!tempLoc.getWorld().equals(loc.getWorld())) { return false; - if (tempLoc.distance(loc) <= fshield.discradius) + } else if (tempLoc.distance(loc) <= fshield.discRadius * fshield.discRadius) { return true; + } } } return false; } - public static void shield(Player player) { - new FireShield(player, true); - } - - public double getDiscradius() { - return discradius; - } - - public long getDuration() { - return duration; - } - - public Player getPlayer() { - return player; - } - - public double getRadius() { - return radius; - } - - public StockAbility getStockAbility() { - return StockAbility.FireShield; - } - - public boolean isShield() { - return shield; - } - - public boolean progress() { - if (((!player.isSneaking()) && shield) || !GeneralMethods.canBend(player.getName(), "FireShield")) { + @Override + public void progress() { + if (!bPlayer.canBendIgnoreCooldowns(this)) { remove(); - return false; - } - - if (!player.isOnline() || player.isDead()) { + return; + } else if (!player.isSneaking() && shield) { remove(); - return false; - } - - if (System.currentTimeMillis() > starttime + duration && !shield) { + return; + } else if (System.currentTimeMillis() > startTime + duration && !shield) { remove(); - return false; + return; } if (System.currentTimeMillis() > time + interval) { time = System.currentTimeMillis(); if (shield) { - - ArrayList blocks = new ArrayList(); + ArrayList blocks = new ArrayList<>(); Location location = player.getEyeLocation().clone(); for (double theta = 0; theta < 180; theta += 20) { for (double phi = 0; phi < 360; phi += 20) { double rphi = Math.toRadians(phi); double rtheta = Math.toRadians(theta); - Block block = location - .clone() - .add(radius * Math.cos(rphi) * Math.sin(rtheta), radius * Math.cos(rtheta), + + Block block = location .clone() .add(radius * Math.cos(rphi) * Math.sin(rtheta), radius * Math.cos(rtheta), radius * Math.sin(rphi) * Math.sin(rtheta)).getBlock(); - if (!blocks.contains(block) && !GeneralMethods.isSolid(block) && !block.isLiquid()) + if (!blocks.contains(block) && !GeneralMethods.isSolid(block) && !block.isLiquid()) { blocks.add(block); + } } } for (Block block : blocks) { - if (!GeneralMethods.isRegionProtectedFromBuild(player, "FireShield", block.getLocation())) { - if (GeneralMethods.rand.nextInt(3) == 0) { + if (!GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + if (random.nextInt(3) == 0) { ParticleEffect.SMOKE.display(block.getLocation(), 0.6F, 0.6F, 0.6F, 0, 1); } ParticleEffect.FLAME.display(block.getLocation(), 0.6F, 0.6F, 0.6F, 0, 1); - if (GeneralMethods.rand.nextInt(7) == 0) { - FireMethods.playFirebendingSound(block.getLocation()); + if (random.nextInt(7) == 0) { + playFirebendingSound(block.getLocation()); } } } @@ -178,114 +135,160 @@ public class FireShield implements ConfigLoadable { } for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, radius)) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "FireShield", entity.getLocation())) + if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) { continue; - if (player.getEntityId() != entity.getEntityId() && ignite) { + } else if (player.getEntityId() != entity.getEntityId() && ignite) { entity.setFireTicks(120); - new Enflamed(entity, player); + new FireDamageTimer(entity, player); } } FireBlast.removeFireBlastsAroundPoint(location, radius + 1); - FireStream.removeAroundPoint(location, radius + 1); + BlazeArc.removeAroundPoint(location, radius + 1); Combustion.removeAroundPoint(location, radius + 1); - } else { - ArrayList blocks = new ArrayList(); + ArrayList blocks = new ArrayList<>(); Location location = player.getEyeLocation().clone(); Vector direction = location.getDirection(); location = location.clone().add(direction.multiply(radius)); - if (GeneralMethods.isRegionProtectedFromBuild(player, "FireShield", location)) { - remove(); - return false; - } - for (double theta = 0; theta < 360; theta += 20) { - Vector vector = GeneralMethods.getOrthogonalVector(direction, theta, discradius); + Vector vector = GeneralMethods.getOrthogonalVector(direction, theta, discRadius); Block block = location.clone().add(vector).getBlock(); - if (!blocks.contains(block) && !GeneralMethods.isSolid(block) && !block.isLiquid()) + if (!blocks.contains(block) && !GeneralMethods.isSolid(block) && !block.isLiquid()) { blocks.add(block); + } } for (Block block : blocks) { - if (!GeneralMethods.isRegionProtectedFromBuild(player, "FireShield", block.getLocation())) { - if (GeneralMethods.rand.nextInt(1) == 0) { + if (!GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + if (random.nextInt(1) == 0) { ParticleEffect.SMOKE.display(block.getLocation(), 0.6F, 0.6F, 0.6F, 0, 1); } ParticleEffect.FLAME.display(block.getLocation(), 0.6F, 0.6F, 0.6F, 0, 3); - if (GeneralMethods.rand.nextInt(4) == 0) { - FireMethods.playFirebendingSound(block.getLocation()); + if (random.nextInt(4) == 0) { + playFirebendingSound(block.getLocation()); } } } - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, discradius)) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "FireShield", entity.getLocation())) + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, discRadius)) { + if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) { continue; + } if (player.getEntityId() != entity.getEntityId() && ignite) { - entity.setFireTicks((int) (fireticks * 20)); + entity.setFireTicks((int) (fireTicks * 20)); if (!(entity instanceof LivingEntity)) { entity.remove(); } } } - FireBlast.removeFireBlastsAroundPoint(location, discradius); - WaterManipulation.removeAroundPoint(location, discradius); - EarthBlast.removeAroundPoint(location, discradius); - FireStream.removeAroundPoint(location, discradius); - Combustion.removeAroundPoint(location, discradius); - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, discradius)) { + FireBlast.removeFireBlastsAroundPoint(location, discRadius); + WaterManipulation.removeAroundPoint(location, discRadius); + EarthBlast.removeAroundPoint(location, discRadius); + BlazeArc.removeAroundPoint(location, discRadius); + Combustion.removeAroundPoint(location, discRadius); + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, discRadius)) { if (entity instanceof Projectile) { entity.remove(); } } } } - return true; - } - - public static void progressAll() { - for (FireShield ability : instances.values()) { - ability.progress(); - } - } - - public void remove() { - instances.remove(player); - } - - public static void removeAll() { - for (FireShield ability : instances.values()) { - ability.remove(); - } } @Override - public void reloadVariables() { - DURATION = config.get().getLong("Abilities.Fire.FireShield.Duration"); - RADIUS = config.get().getDouble("Abilities.Fire.FireShield.Radius"); - DISC_RADIUS = config.get().getDouble("Abilities.Fire.FireShield.DiscRadius"); - fireticks = config.get().getDouble("Abilities.Fire.FireShield.FireTicks"); - duration = DURATION; - radius = RADIUS; - discradius = DISC_RADIUS; + public String getName() { + return "FireShield"; } - public void setDiscradius(double discradius) { - this.discradius = discradius; + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isShield() { + return shield; + } + + public void setShield(boolean shield) { + this.shield = shield; + } + + public boolean isIgnite() { + return ignite; + } + + public void setIgnite(boolean ignite) { + this.ignite = ignite; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getDuration() { + return duration; } public void setDuration(long duration) { this.duration = duration; } + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public double getRadius() { + return radius; + } + public void setRadius(double radius) { this.radius = radius; } - public void setShield(boolean shield) { - this.shield = shield; + public double getDiscRadius() { + return discRadius; } + + public void setDiscRadius(double discRadius) { + this.discRadius = discRadius; + } + + public double getFireTicks() { + return fireTicks; + } + + public void setFireTicks(double fireTicks) { + this.fireTicks = fireTicks; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/firebending/FireStream.java b/src/com/projectkorra/projectkorra/firebending/FireStream.java deleted file mode 100644 index 930549a3..00000000 --- a/src/com/projectkorra/projectkorra/firebending/FireStream.java +++ /dev/null @@ -1,234 +0,0 @@ -package com.projectkorra.projectkorra.firebending; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.concurrent.ConcurrentHashMap; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.material.MaterialData; -import org.bukkit.util.Vector; - -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.waterbending.Plantbending; -import com.projectkorra.projectkorra.waterbending.WaterMethods; - -public class FireStream implements ConfigLoadable { - - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - public static ConcurrentHashMap ignitedblocks = new ConcurrentHashMap(); - public static ConcurrentHashMap ignitedtimes = new ConcurrentHashMap(); - public static ConcurrentHashMap replacedBlocks = new ConcurrentHashMap(); - public static ConcurrentHashMap ignitedentities = new ConcurrentHashMap(); - - @SuppressWarnings("unused") - private static long soonesttime = config.get().getLong("Properties.GlobalCooldown"); - @SuppressWarnings("unused") - private static int firedamage = 3; - @SuppressWarnings("unused") - private static int tickdamage = 2; - - private static int idCounter = 0; - private static double speed = 15; - private static long interval = (long) (1000. / speed); - private static long dissipateAfter = 400; - - private Player player; - private Location origin; - private Location location; - private Vector direction; - private long time; - private double range; - private int id; - - public FireStream(Location location, Vector direction, Player player, int range) { - this.range = FireMethods.getFirebendingDayAugment(range, player.getWorld()); - this.player = player; - origin = location.clone(); - this.location = origin.clone(); - this.direction = direction.clone(); - this.direction.setY(0); - this.direction = this.direction.clone().normalize(); - this.location = this.location.clone().add(this.direction); - time = System.currentTimeMillis(); - instances.put(idCounter, this); - this.id = idCounter; - idCounter = (idCounter + 1) % Integer.MAX_VALUE; - } - - public static void dissipateAll() { - if (dissipateAfter != 0) - for (Block block : ignitedtimes.keySet()) { - if (block.getType() != Material.FIRE) { - remove(block); - } else { - long time = ignitedtimes.get(block); - if (System.currentTimeMillis() > time + dissipateAfter) { - block.setType(Material.AIR); - remove(block); - } - } - } - } - - public static String getDescription() { - return "This ability no longer exists."; - } - - public static void handleDissipation() { - for (Block block : ignitedblocks.keySet()) { - if (block.getType() != Material.FIRE) { - ignitedblocks.remove(block); - } - } - } - - public static boolean isIgnitable(Player player, Block block) { - - Material[] overwriteable = { Material.SAPLING, Material.LONG_GRASS, Material.DEAD_BUSH, Material.YELLOW_FLOWER, - Material.RED_ROSE, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.FIRE, Material.SNOW, Material.TORCH }; - - if (Arrays.asList(overwriteable).contains(block.getType())) { - return true; - } else if (block.getType() != Material.AIR) { - return false; - } - - Material[] ignitable = { Material.BEDROCK, Material.BOOKSHELF, Material.BRICK, Material.CLAY, Material.CLAY_BRICK, - Material.COAL_ORE, Material.COBBLESTONE, Material.DIAMOND_ORE, Material.DIAMOND_BLOCK, Material.DIRT, - Material.ENDER_STONE, Material.GLOWING_REDSTONE_ORE, Material.GOLD_BLOCK, Material.GRAVEL, Material.GRASS, - Material.HUGE_MUSHROOM_1, Material.HUGE_MUSHROOM_2, Material.LAPIS_BLOCK, Material.LAPIS_ORE, Material.LOG, - Material.MOSSY_COBBLESTONE, Material.MYCEL, Material.NETHER_BRICK, Material.NETHERRACK, Material.OBSIDIAN, - Material.REDSTONE_ORE, - Material.SAND, - Material.SANDSTONE, - Material.SMOOTH_BRICK, - Material.STONE, - Material.SOUL_SAND, - Material.WOOD, // Material.SNOW_BLOCK, - Material.WOOL, Material.LEAVES, Material.LEAVES_2, Material.MELON_BLOCK, Material.PUMPKIN, - Material.JACK_O_LANTERN, Material.NOTE_BLOCK, Material.GLOWSTONE, Material.IRON_BLOCK, Material.DISPENSER, - Material.SPONGE, Material.IRON_ORE, Material.GOLD_ORE, Material.COAL_BLOCK, Material.WORKBENCH, - Material.HAY_BLOCK, Material.REDSTONE_LAMP_OFF, Material.REDSTONE_LAMP_ON, Material.EMERALD_ORE, - Material.EMERALD_BLOCK, Material.REDSTONE_BLOCK, Material.QUARTZ_BLOCK, Material.QUARTZ_ORE, - Material.STAINED_CLAY, Material.HARD_CLAY }; - - Block belowblock = block.getRelative(BlockFace.DOWN); - if (Arrays.asList(ignitable).contains(belowblock.getType())) { - return true; - } - - return false; - } - - @SuppressWarnings("deprecation") - public static void remove(Block block) { - if (ignitedblocks.containsKey(block)) { - ignitedblocks.remove(block); - } - if (ignitedtimes.containsKey(block)) { - ignitedtimes.remove(block); - } - if (replacedBlocks.containsKey(block.getLocation())) { - block.setType(replacedBlocks.get(block.getLocation()).getItemType()); - block.setData(replacedBlocks.get(block.getLocation()).getData()); - replacedBlocks.remove(block.getLocation()); - } - } - - public static void removeAll() { - for (Block block : ignitedblocks.keySet()) - remove(block); - - Iterator iter = instances.keySet().iterator(); - while (iter.hasNext()) { - Integer key = iter.next(); - instances.get(key).remove(); - } - } - - public static void removeAroundPoint(Location location, double radius) { - for (FireStream stream : instances.values()) { - if (stream.location.getWorld().equals(location.getWorld())) - if (stream.location.distance(location) <= radius) - stream.remove(); - } - - } - - public Player getPlayer() { - return player; - } - - public double getRange() { - return range; - } - - private void ignite(Block block) { - if (block.getType() != Material.AIR) { - if (FireMethods.canFireGrief()) { - if (WaterMethods.isPlant(block)) - new Plantbending(block); - } else if (block.getType() != Material.FIRE) { - replacedBlocks.put(block.getLocation(), block.getState().getData()); - } - } - block.setType(Material.FIRE); - - ignitedblocks.put(block, this.player); - ignitedtimes.put(block, System.currentTimeMillis()); - } - - public boolean progress() { - if (System.currentTimeMillis() - time >= interval) { - location = location.clone().add(direction); - time = System.currentTimeMillis(); - if (location.distance(origin) > range) { - remove(); - return false; - } - Block block = location.getBlock(); - if (isIgnitable(player, block)) { - ignite(block); - return true; - } else if (isIgnitable(player, block.getRelative(BlockFace.DOWN))) { - ignite(block.getRelative(BlockFace.DOWN)); - location = block.getRelative(BlockFace.DOWN).getLocation(); - return true; - } else if (isIgnitable(player, block.getRelative(BlockFace.UP))) { - ignite(block.getRelative(BlockFace.UP)); - location = block.getRelative(BlockFace.UP).getLocation(); - return true; - } else { - remove(); - return false; - } - - } - return false; - } - - public static void progressAll() { - for (FireStream ability : instances.values()) { - ability.progress(); - } - } - - public void remove() { - instances.remove(id); - } - - @Override - public void reloadVariables() { - soonesttime = config.get().getLong("Properties.GlobalCooldown"); - } - - public void setRange(double range) { - this.range = range; - } - -} diff --git a/src/com/projectkorra/projectkorra/firebending/Fireball.java b/src/com/projectkorra/projectkorra/firebending/Fireball.java deleted file mode 100644 index 78e3b76e..00000000 --- a/src/com/projectkorra/projectkorra/firebending/Fireball.java +++ /dev/null @@ -1,405 +0,0 @@ -package com.projectkorra.projectkorra.firebending; - -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -import org.bukkit.Effect; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.block.Block; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.entity.TNTPrimed; -import org.bukkit.util.Vector; - -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.util.ParticleEffect; - -/** - * Ability charged FireBlast - */ -public class Fireball implements ConfigLoadable { - - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static ConcurrentHashMap explosions = new ConcurrentHashMap(); - - private static long defaultchargetime = config.get().getLong("Abilities.Fire.FireBlast.Charged.ChargeTime"); - private static long interval = 25; - private static double radius = 1.5; - private static int idCounter = 0; - - private static double MAX_DAMAGE = config.get().getDouble("Abilities.Fire.FireBlast.Charged.Damage"); - private static double DAMAGE_RADIUS = config.get().getDouble("Abilities.Fire.FireBlast.Charged.DamageRadius"); - private static double RANGE = config.get().getDouble("Abilities.Fire.FireBlast.Charged.Range"); - private static double EXPLOSIONRADIUS = config.get().getDouble("Abilities.Fire.FireBlast.Charged.ExplosionRadius"); - private static boolean DAMAGEBLOCKS = config.get().getBoolean("Abilities.Fire.FireBlast.Charged.DamageBlocks"); - private static double fireticks = config.get().getDouble("Abilities.Fire.FireBlast.Charged.FireTicks"); - - private int id; - private double maxdamage = MAX_DAMAGE; - private double range = RANGE; - private double damageradius = DAMAGE_RADIUS; - private double explosionradius = EXPLOSIONRADIUS; - private double innerradius = damageradius / 2; - private long starttime; - private long time; - private long chargetime = defaultchargetime; - private boolean charged = false; - private boolean launched = false; - private Player player; - private Location origin; - private Location location; - private Vector direction; - private TNTPrimed explosion = null; - private boolean damage_blocks; - - public Fireball(Player player) { - this.player = player; - time = System.currentTimeMillis(); - starttime = time; - if (FireMethods.isDay(player.getWorld())) { - chargetime = (long) (chargetime / config.get().getDouble("Properties.Fire.DayFactor")); - } - if (AvatarState.isAvatarState(player)) { - chargetime = 0; - maxdamage = AvatarState.getValue(maxdamage); - } - range = FireMethods.getFirebendingDayAugment(range, player.getWorld()); - if (!player.getEyeLocation().getBlock().isLiquid()) { - instances.put(idCounter, this); - this.id = idCounter; - idCounter = (idCounter + 1) % Integer.MAX_VALUE; - } - } - - public static boolean annihilateBlasts(Location location, double radius, Player source) { - boolean broke = false; - for (Fireball fireball : instances.values()) { - if (!fireball.launched) - continue; - Location fireblastlocation = fireball.location; - if (location.getWorld() == fireblastlocation.getWorld() && !source.equals(fireball.player)) { - if (location.distance(fireblastlocation) <= radius) { - fireball.explode(); - broke = true; - } - } - } - - return broke; - - } - - public static Fireball getFireball(Entity entity) { - if (explosions.containsKey(entity)) - return explosions.get(entity); - return null; - } - - public static boolean isCharging(Player player) { - for (Fireball fireball : instances.values()) { - if (fireball.player == player && !fireball.launched) - return true; - } - return false; - } - - public static void removeFireballsAroundPoint(Location location, double radius) { - for (Fireball fireball : instances.values()) { - if (!fireball.launched) - continue; - Location fireblastlocation = fireball.location; - if (location.getWorld() == fireblastlocation.getWorld()) { - if (location.distance(fireblastlocation) <= radius) - fireball.remove(); - } - } - - } - - public void dealDamage(Entity entity) { - if (explosion == null) - return; - // if (Methods.isObstructed(explosion.getLocation(), - // entity.getLocation())) { - // return 0; - // } - double distance = entity.getLocation().distance(explosion.getLocation()); - if (distance > damageradius) - return; - if (distance < innerradius) { - GeneralMethods.damageEntity(player, entity, maxdamage, "FireBlast"); - return; - } - double slope = -(maxdamage * .5) / (damageradius - innerradius); - double damage = slope * (distance - innerradius) + maxdamage; - // Methods.verbose(damage); - GeneralMethods.damageEntity(player, entity, damage, "FireBlast"); - AirMethods.breakBreathbendingHold(entity); - } - - public void explode() { - // List blocks = Methods.getBlocksAroundPoint(location, 3); - // List blocks2 = new ArrayList(); - - // Methods.verbose("Fireball Explode!"); - boolean explode = true; - for (Block block : GeneralMethods.getBlocksAroundPoint(location, 3)) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "FireBlast", block.getLocation())) { - explode = false; - break; - } - } - if (explode) { - if (damage_blocks && explosionradius > 0) { - explosion = player.getWorld().spawn(location, TNTPrimed.class); - explosion.setFuseTicks(0); - float yield = (float) explosionradius; - if (!AvatarState.isAvatarState(player)) { - if (FireMethods.isDay(player.getWorld())) { - yield = (float) FireMethods.getFirebendingDayAugment(yield, player.getWorld()); - } - } else { - yield *= AvatarState.factor; - } - explosion.setYield(yield); - explosions.put(explosion, this); - } else { - List l = GeneralMethods.getEntitiesAroundPoint(location, damageradius); - for (Entity e : l) { - if (e instanceof LivingEntity) { - double slope = -(maxdamage * .5) / (damageradius - innerradius); - double damage = slope * (e.getLocation().distance(location) - innerradius) + maxdamage; - GeneralMethods.damageEntity(getPlayer(), e, damage, "FireBlast"); - } - } - location.getWorld().playSound(location, Sound.EXPLODE, 5, 1); - ParticleEffect.EXPLOSION_HUGE.display(new Vector(0, 0, 0), 0, location, 256); - } - } - - ignite(location); - remove(); - } - - private void fireball() { - for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) { - ParticleEffect.FLAME.display(block.getLocation(), 0.5F, 0.5F, 0.5F, 0, 5); - ParticleEffect.SMOKE.display(block.getLocation(), 0.5F, 0.5F, 0.5F, 0, 2); - if (GeneralMethods.rand.nextInt(4) == 0) { - FireMethods.playFirebendingSound(location); - } - - } - - boolean exploded = false; - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2 * radius)) { - if (entity.getEntityId() == player.getEntityId()) - continue; - entity.setFireTicks((int) (fireticks * 20)); - if (entity instanceof LivingEntity) { - if (!exploded) { - explode(); - exploded = true; - } - dealDamage(entity); - } - } - } - - public long getChargetime() { - return chargetime; - } - - public double getDamageRadius() { - return damageradius; - } - - public double getExplosionRadius() { - return explosionradius; - } - - public boolean getDamageBlocks() { - return this.damage_blocks; - } - - public double getInnerradius() { - return innerradius; - } - - public double getMaxdamage() { - return maxdamage; - } - - public Player getPlayer() { - return player; - } - - public double getRange() { - return range; - } - - private void ignite(Location location) { - for (Block block : GeneralMethods.getBlocksAroundPoint(location, FireBlast.AFFECTING_RADIUS)) { - if (FireStream.isIgnitable(player, block)) { - if (block.getType() != Material.FIRE) { - FireStream.replacedBlocks.put(block.getLocation(), block.getState().getData()); - } - block.setType(Material.FIRE); - if (FireBlast.dissipate) { - FireStream.ignitedblocks.put(block, player); - FireStream.ignitedtimes.put(block, System.currentTimeMillis()); - } - } - } - } - - public boolean progress() { - if (player.isDead() || !player.isOnline()) { - remove(); - return false; - } - - if (location != null && !player.getWorld().equals(location.getWorld())) { - remove(); - return false; - } - - if (GeneralMethods.getBoundAbility(player) == null) { - remove(); - return false; - } - - if (!GeneralMethods.canBend(player.getName(), "FireBlast") && !launched) { - remove(); - return false; - } - - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("FireBlast") && !launched) { - remove(); - return false; - } - - if (System.currentTimeMillis() > starttime + chargetime) { - charged = true; - } - - if (!player.isSneaking() && !charged) { - remove(); - return false; - } - - if (!player.isSneaking() && !launched) { - launched = true; - location = player.getEyeLocation(); - origin = location.clone(); - direction = location.getDirection().normalize().multiply(radius); - } - - if (System.currentTimeMillis() > time + interval) { - if (launched) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "Blaze", location)) { - remove(); - return false; - } - } - - time = System.currentTimeMillis(); - - if (!launched && !charged) - return true; - if (!launched) { - player.getWorld().playEffect(player.getEyeLocation(), Effect.MOBSPAWNER_FLAMES, 0, 3); - return true; - } - - location = location.clone().add(direction); - if (location.distance(origin) > range) { - remove(); - return false; - } - - if (GeneralMethods.isSolid(location.getBlock())) { - explode(); - return false; - } else if (location.getBlock().isLiquid()) { - remove(); - return false; - } - - fireball(); - } - return true; - } - - public static void progressAll() { - for (Fireball ability : instances.values()) { - ability.progress(); - } - } - - public void remove() { - instances.remove(id); - } - - public static void removeAll() { - for (Fireball ability : instances.values()) { - ability.remove(); - } - } - - @Override - public void reloadVariables() { - defaultchargetime = config.get().getLong("Abilities.Fire.FireBlast.Charged.ChargeTime"); - interval = 25; - radius = 1.5; - - MAX_DAMAGE = config.get().getDouble("Abilities.Fire.FireBlast.Charged.Damage"); - DAMAGE_RADIUS = config.get().getDouble("Abilities.Fire.FireBlast.Charged.DamageRadius"); - RANGE = config.get().getDouble("Abilities.Fire.FireBlast.Charged.Range"); - DAMAGEBLOCKS = config.get().getBoolean("Abilities.Fire.FireBlast.Charged.DamageBlocks"); - EXPLOSIONRADIUS = config.get().getDouble("Abilities.Fire.FireBlast.Charged.ExplosionRadius"); - fireticks = config.get().getDouble("Abilities.Fire.FireBlast.Charged.FireTicks"); - - maxdamage = MAX_DAMAGE; - range = RANGE; - damageradius = DAMAGE_RADIUS; - explosionradius = EXPLOSIONRADIUS; - damage_blocks = DAMAGEBLOCKS; - chargetime = defaultchargetime; - } - - public void setChargetime(long chargetime) { - this.chargetime = chargetime; - } - - public void setDamageBlocks(boolean damageblocks) { - this.damage_blocks = damageblocks; - } - - public void setExplosionRadius(double radius) { - this.explosionradius = radius; - } - - public void setDamageRadius(double radius) { - this.damageradius = radius; - } - - public void setInnerradius(double innerradius) { - this.innerradius = innerradius; - } - - public void setMaxdamage(double maxdamage) { - this.maxdamage = maxdamage; - } - - public void setRange(double range) { - this.range = range; - } -} diff --git a/src/com/projectkorra/projectkorra/firebending/FirebendingManager.java b/src/com/projectkorra/projectkorra/firebending/FirebendingManager.java index ac8714ae..80be973e 100644 --- a/src/com/projectkorra/projectkorra/firebending/FirebendingManager.java +++ b/src/com/projectkorra/projectkorra/firebending/FirebendingManager.java @@ -1,6 +1,7 @@ package com.projectkorra.projectkorra.firebending; import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.FireAbility; public class FirebendingManager implements Runnable { @@ -11,23 +12,10 @@ public class FirebendingManager implements Runnable { } public void run() { - FireStream.handleDissipation(); - Enflamed.handleFlames(); + BlazeArc.handleDissipation(); + FireDamageTimer.handleFlames(); FirePassive.handlePassive(); - FireJet.progressAll(); - Cook.progressAll(); - Illumination.progressAll(); - FireBlast.progressAll(); - Fireball.progressAll(); - FireBurst.progressAll(); - FireShield.progressAll(); - Lightning.progressAll(); - WallOfFire.progressAll(); - Combustion.progressAll(); - FireMethods.removeFire(); - HeatControl.progressAll(); - FireStream.dissipateAll(); - FireStream.progressAll(); - FireCombo.progressAll(); + BlazeArc.dissipateAll(); + FireAbility.removeFire(); } } diff --git a/src/com/projectkorra/projectkorra/firebending/HeatControl.java b/src/com/projectkorra/projectkorra/firebending/HeatControl.java deleted file mode 100644 index 8ce6383a..00000000 --- a/src/com/projectkorra/projectkorra/firebending/HeatControl.java +++ /dev/null @@ -1,215 +0,0 @@ -package com.projectkorra.projectkorra.firebending; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; - -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.util.ParticleEffect; -import com.projectkorra.projectkorra.util.TempBlock; - -/** - * Created by Carbogen on 11/02/15. Ability HeatControl - */ -public class HeatControl implements ConfigLoadable { - - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - public static int RANGE = config.get().getInt("Abilities.Fire.HeatControl.Solidify.Range"); - public static int RADIUS = config.get().getInt("Abilities.Fire.HeatControl.Solidify.Radius"); - public static int REVERT_TIME = config.get().getInt("Abilities.Fire.HeatControl.Solidify.RevertTime"); - - private Player player; - private int currentRadius = 1; - private long delay = 50; - private long lastBlockTime = 0; - private long lastParticleTime = 0; - private Location center; - private List tblocks = new ArrayList(); - - public int range = RANGE; - public int radius = RADIUS; - public long revertTime = REVERT_TIME; - - public HeatControl(Player player) { - /* Initial Checks */ - if (!isEligible(player)) - return; - - if (EarthMethods.getLavaSourceBlock(player, getRange()) == null) { - new Cook(player); - return; - } - - /* End Initial Checks */ - - this.player = player; - - lastBlockTime = System.currentTimeMillis(); - - instances.put(player, this); - } - - @SuppressWarnings("deprecation") - public void freeze(List area) { - if (System.currentTimeMillis() < lastBlockTime + delay) - return; - - List lava = new ArrayList(); - - for (Location l : area) - if (EarthMethods.isLava(l.getBlock())) - lava.add(l.getBlock()); - - lastBlockTime = System.currentTimeMillis(); - - if (lava.size() == 0) { - currentRadius++; - return; - } - - Block b = lava.get(GeneralMethods.rand.nextInt(lava.size())); - - TempBlock tb; - - if (TempBlock.isTempBlock(b)) { - tb = TempBlock.get(b); - tb.setType(Material.STONE); - } - - else - tb = new TempBlock(b, Material.STONE, b.getData()); - - if (!tblocks.contains(tb)) - tblocks.add(tb); - - } - - public Player getPlayer() { - return player; - } - - public int getRadius() { - return radius; - } - - public int getRange() { - return range; - } - - public long getRevertTime() { - return revertTime; - } - - public boolean isEligible(Player player) { - if (!GeneralMethods.canBend(player.getName(), "HeatControl")) - return false; - - if (GeneralMethods.getBoundAbility(player) == null) - return false; - - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("HeatControl")) - return false; - - return true; - } - - public void particles(List area) { - if (System.currentTimeMillis() < lastParticleTime + 300) - return; - - lastParticleTime = System.currentTimeMillis(); - - for (Location l : area) { - if (EarthMethods.isLava(l.getBlock())) - ParticleEffect.SMOKE.display(l, 0, 0, 0, 0.1f, 2); - } - } - - public boolean progress() { - if (!player.isOnline() || player.isDead() || !isEligible(player) || !player.isSneaking()) { - remove(); - return false; - } - - if (currentRadius >= getRadius()) { - remove(); - return false; - } - - Location targetlocation = GeneralMethods.getTargetedLocation(player, range); - - resetLocation(targetlocation); - - List area = GeneralMethods.getCircle(center, currentRadius, 3, true, true, 0); - - particles(area); - freeze(area); - return true; - } - - public static void progressAll() { - for (HeatControl ability : instances.values()) { - ability.progress(); - } - } - - @Override - public void reloadVariables() { - RANGE = config.get().getInt("Abilities.Fire.HeatControl.Solidify.Range"); - RADIUS = config.get().getInt("Abilities.Fire.HeatControl.Solidify.Radius"); - REVERT_TIME = config.get().getInt("Abilities.Fire.HeatControl.Solidify.RevertTime"); - range = RANGE; - radius = RADIUS; - revertTime = REVERT_TIME; - } - - public void remove() { - final HeatControl ability = this; - ProjectKorra.plugin.getServer().getScheduler().scheduleSyncDelayedTask(ProjectKorra.plugin, new Runnable() { - public void run() { - revertAll(); - instances.remove(ability); - } - }, getRevertTime()); - } - - public void resetLocation(Location loc) { - if (center == null) { - center = loc; - return; - } - - if (!loc.equals(center)) { - currentRadius = 1; - center = loc; - } - } - - public void revertAll() { - for (TempBlock tb : tblocks) { - tb.revertBlock(); - } - tblocks.clear(); - } - - public void setRadius(int value) { - radius = value; - } - - public void setRange(int value) { - range = value; - } - - public void setRevertTime(long value) { - revertTime = value; - } -} diff --git a/src/com/projectkorra/projectkorra/firebending/HeatControlCook.java b/src/com/projectkorra/projectkorra/firebending/HeatControlCook.java new file mode 100644 index 00000000..4b085c09 --- /dev/null +++ b/src/com/projectkorra/projectkorra/firebending/HeatControlCook.java @@ -0,0 +1,139 @@ +package com.projectkorra.projectkorra.firebending; + +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.util.ParticleEffect; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.Arrays; +import java.util.HashMap; + +public class HeatControlCook extends FireAbility { + + private static final Material[] COOKABLE_MATERIALS = { Material.RAW_BEEF, Material.RAW_CHICKEN, + Material.RAW_FISH, Material.PORK, Material.POTATO_ITEM, Material.RABBIT, Material.MUTTON }; + + private long time; + private long cookTime; + private ItemStack item; + + public HeatControlCook(Player player) { + super(player); + + + this.time = System.currentTimeMillis(); + this.cookTime = 2000; + this.item = player.getItemInHand(); + + if (isCookable(item.getType())) { + start(); + } + } + + private void cook() { + ItemStack cooked = getCooked(item); + HashMap cantFit = player.getInventory().addItem(cooked); + for (int id : cantFit.keySet()) { + player.getWorld().dropItem(player.getEyeLocation(), cantFit.get(id)); + } + + int amount = item.getAmount(); + if (amount == 1) { + player.getInventory().clear(player.getInventory().getHeldItemSlot()); + } else { + item.setAmount(amount - 1); + } + } + + private ItemStack getCooked(ItemStack is) { + ItemStack cooked = new ItemStack(Material.AIR); + Material material = is.getType(); + + switch (material) { + case RAW_BEEF: + cooked = new ItemStack(Material.COOKED_BEEF, 1); + break; + case RAW_FISH: + ItemStack salmon = new ItemStack(Material.RAW_FISH, 1, (short) 1); + if (is.getDurability() == salmon.getDurability()) { + cooked = new ItemStack(Material.COOKED_FISH, 1, (short) 1); + } else { + cooked = new ItemStack(Material.COOKED_FISH, 1); + } + break; + case RAW_CHICKEN: + cooked = new ItemStack(Material.COOKED_CHICKEN, 1); + break; + case PORK: + cooked = new ItemStack(Material.GRILLED_PORK, 1); + break; + case POTATO_ITEM: + cooked = new ItemStack(Material.BAKED_POTATO, 1); + break; + case MUTTON: + cooked = new ItemStack(Material.COOKED_MUTTON); + break; + case RABBIT: + cooked = new ItemStack(Material.COOKED_RABBIT); + break; + default: + break; + } + return cooked; + } + + @Override + public void progress() { + if (!bPlayer.canBendIgnoreCooldowns(this)) { + remove(); + return; + } else if (!item.equals(player.getItemInHand())) { + time = System.currentTimeMillis(); + item = player.getItemInHand(); + } + + if (!isCookable(item.getType())) { + remove(); + return; + } else if (System.currentTimeMillis() > time + cookTime) { + cook(); + time = System.currentTimeMillis(); + } + + ParticleEffect.FLAME.display(player.getEyeLocation(), 0.6F, 0.6F, 0.6F, 0, 3); + ParticleEffect.SMOKE.display(player.getEyeLocation(), 0.6F, 0.6F, 0.6F, 0, 1); + } + + public static boolean isCookable(Material material) { + return Arrays.asList(COOKABLE_MATERIALS).contains(material); + } + + @Override + public String getName() { + return "HeatControl"; + } + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return true; + } + +} \ No newline at end of file diff --git a/src/com/projectkorra/projectkorra/firebending/HeatControlExtinguish.java b/src/com/projectkorra/projectkorra/firebending/HeatControlExtinguish.java new file mode 100644 index 00000000..940fd30a --- /dev/null +++ b/src/com/projectkorra/projectkorra/firebending/HeatControlExtinguish.java @@ -0,0 +1,99 @@ +package com.projectkorra.projectkorra.firebending; + +import com.projectkorra.projectkorra.BendingPlayer; +import com.projectkorra.projectkorra.Element; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.FireAbility; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +import java.util.HashSet; + +public class HeatControlExtinguish extends FireAbility { + + private double range; + private double radius; + private long cooldown; + private Location location; + + public HeatControlExtinguish(Player player) { + super(player); + + if (bPlayer.isOnCooldown(this)) { + return; + } + + this.range = getConfig().getDouble("Abilities.Fire.HeatControl.Extinguish.Range"); + this.radius = getConfig().getDouble("Abilities.Fire.HeatControl.Extinguish.Radius"); + this.cooldown = GeneralMethods.getGlobalCooldown(); + + this.range = getDayFactor(this.range); + this.radius = getDayFactor(this.radius); + if (isMeltable(player.getTargetBlock((HashSet) null, (int) range))) { + new HeatControlMelt(player); + return; + } + + location = player.getTargetBlock((HashSet) null, (int) range).getLocation(); + for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) { + Material mat = block.getType(); + if (mat != Material.FIRE) { + continue; + } else if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + continue; + } else if (block.getType() == Material.FIRE) { + block.setType(Material.AIR); + block.getWorld().playEffect(block.getLocation(), Effect.EXTINGUISH, 0); + } + } + + bPlayer.addCooldown(this); + } + + public static boolean canBurn(Player player) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + return true; + } else if (bPlayer.getBoundAbilityName().equals("HeatControl") || hasAbility(player, FireJet.class)) { + player.setFireTicks(-1); + return false; + } else if (player.getFireTicks() > 80 && bPlayer.canBendPassive(Element.FIRE)) { + player.setFireTicks(80); + } + return true; + } + + @Override + public String getName() { + return "HeatControl"; + } + + @Override + public void progress() { + } + + @Override + public Location getLocation() { + return location; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return true; + } + +} diff --git a/src/com/projectkorra/projectkorra/firebending/HeatControlMelt.java b/src/com/projectkorra/projectkorra/firebending/HeatControlMelt.java new file mode 100644 index 00000000..1659d355 --- /dev/null +++ b/src/com/projectkorra/projectkorra/firebending/HeatControlMelt.java @@ -0,0 +1,98 @@ +package com.projectkorra.projectkorra.firebending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.waterbending.PhaseChangeMelt; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +public class HeatControlMelt extends FireAbility { + + private double range = getConfig().getDouble("Abilities.Fire.HeatControl.Melt.Range"); + private double radius = getConfig().getDouble("Abilities.Fire.HeatControl.Melt.Radius"); + private Location location; + + public HeatControlMelt(Player player) { + super(player); + + this.range = getConfig().getDouble("Abilities.Fire.HeatControl.Melt.Range"); + this.radius = getConfig().getDouble("Abilities.Fire.HeatControl.Melt.Radius"); + + this.range = getDayFactor(range); + this.radius = getDayFactor(radius); + + location = GeneralMethods.getTargetedLocation(player, range); + for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) { + if (isMeltable(block)) { + PhaseChangeMelt.melt(player, block); + } else if (isHeatable(block)) { + heat(block); + } + } + } + + @SuppressWarnings("deprecation") + private static void heat(Block block) { + if (block.getType() == Material.OBSIDIAN) { + block.setType(Material.LAVA); + block.setData((byte) 0x0); + } + } + + private static boolean isHeatable(Block block) { + return false; + } + + @Override + public String getName() { + return "HeatControl"; + } + + @Override + public void progress() { + } + + @Override + public Location getLocation() { + return location; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return true; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/firebending/HeatControlSolidify.java b/src/com/projectkorra/projectkorra/firebending/HeatControlSolidify.java new file mode 100644 index 00000000..06f83a6b --- /dev/null +++ b/src/com/projectkorra/projectkorra/firebending/HeatControlSolidify.java @@ -0,0 +1,239 @@ +package com.projectkorra.projectkorra.firebending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.EarthAbility; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.util.ParticleEffect; +import com.projectkorra.projectkorra.util.TempBlock; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class HeatControlSolidify extends FireAbility { + + private int radius; + private long delay; + private long lastBlockTime; + private long lastParticleTime; + private long revertTime; + private double maxRadius; + private double range; + private Location location; + private Random random; + private ArrayList tempBlocks; + + public HeatControlSolidify(Player player) { + super(player); + + this.radius = 1; + this.delay = 50; + this.lastBlockTime = 0; + this.lastParticleTime = 0; + this.revertTime = getConfig().getLong("Abilities.Fire.HeatControl.Solidify.RevertTime"); + this.maxRadius = getConfig().getDouble("Abilities.Fire.HeatControl.Solidify.Radius"); + this.range = getConfig().getDouble("Abilities.Fire.HeatControl.Solidify.Range"); + this.random = new Random(); + this.tempBlocks = new ArrayList<>(); + + if (!bPlayer.canBend(this)) { + return; + } else if (EarthAbility.getLavaSourceBlock(player, range) == null) { + new HeatControlCook(player); + return; + } + + lastBlockTime = System.currentTimeMillis(); + start(); + } + + @SuppressWarnings("deprecation") + public void freeze(List area) { + if (System.currentTimeMillis() < lastBlockTime + delay) { + return; + } + + List lava = new ArrayList(); + for (Location l : area) { + if (isLava(l.getBlock())) { + lava.add(l.getBlock()); + } + } + + lastBlockTime = System.currentTimeMillis(); + if (lava.size() == 0) { + radius++; + return; + } + + Block b = lava.get(random.nextInt(lava.size())); + TempBlock tb; + + if (TempBlock.isTempBlock(b)) { + tb = TempBlock.get(b); + tb.setType(Material.STONE); + } else { + tb = new TempBlock(b, Material.STONE, b.getData()); + } + + if (!tempBlocks.contains(tb)) { + tempBlocks.add(tb); + } + } + + public void particles(List area) { + if (System.currentTimeMillis() < lastParticleTime + 300) { + return; + } + + lastParticleTime = System.currentTimeMillis(); + for (Location l : area) { + if (isLava(l.getBlock())) { + ParticleEffect.SMOKE.display(l, 0, 0, 0, 0.1f, 2); + } + } + } + + @Override + public void progress() { + if (!bPlayer.canBendIgnoreCooldowns(this)) { + remove(); + return; + } else if (radius >= maxRadius) { + remove(); + return; + } + + Location targetlocation = GeneralMethods.getTargetedLocation(player, range); + resetLocation(targetlocation); + List area = GeneralMethods.getCircle(location, radius, 3, true, true, 0); + particles(area); + freeze(area); + } + + @Override + public void remove() { + ProjectKorra.plugin.getServer().getScheduler().scheduleSyncDelayedTask(ProjectKorra.plugin, new Runnable() { + @Override + public void run() { + revertAll(); + HeatControlSolidify.super.remove(); + } + }, revertTime); + } + + public void resetLocation(Location loc) { + if (location == null) { + location = loc; + return; + } + + if (!loc.equals(location)) { + radius = 1; + location = loc; + } + } + + public void revertAll() { + for (TempBlock tb : tempBlocks) { + tb.revertBlock(); + } + tempBlocks.clear(); + } + + @Override + public String getName() { + return "HeatControl"; + } + + @Override + public Location getLocation() { + return location; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return true; + } + + public int getRadius() { + return radius; + } + + public void setRadius(int radius) { + this.radius = radius; + } + + public long getDelay() { + return delay; + } + + public void setDelay(long delay) { + this.delay = delay; + } + + public long getLastBlockTime() { + return lastBlockTime; + } + + public void setLastBlockTime(long lastBlockTime) { + this.lastBlockTime = lastBlockTime; + } + + public long getLastParticleTime() { + return lastParticleTime; + } + + public void setLastParticleTime(long lastParticleTime) { + this.lastParticleTime = lastParticleTime; + } + + public long getRevertTime() { + return revertTime; + } + + public void setRevertTime(long revertTime) { + this.revertTime = revertTime; + } + + public double getMaxRadius() { + return maxRadius; + } + + public void setMaxRadius(double maxRadius) { + this.maxRadius = maxRadius; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public ArrayList getTempBlocks() { + return tempBlocks; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/firebending/HeatMelt.java b/src/com/projectkorra/projectkorra/firebending/HeatMelt.java deleted file mode 100644 index b7a78324..00000000 --- a/src/com/projectkorra/projectkorra/firebending/HeatMelt.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.projectkorra.projectkorra.firebending; - -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.waterbending.Melt; -import com.projectkorra.projectkorra.waterbending.WaterMethods; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; - -public class HeatMelt implements ConfigLoadable { - - private static int range = config.get().getInt("Abilities.Fire.HeatControl.Melt.Range"); - private static int radius = config.get().getInt("Abilities.Fire.HeatControl.Melt.Radius"); - - public HeatMelt(Player player) { - // reloadVariables(); - Location location = GeneralMethods.getTargetedLocation(player, - (int) FireMethods.getFirebendingDayAugment(range, player.getWorld())); - for (Block block : GeneralMethods.getBlocksAroundPoint(location, - (int) FireMethods.getFirebendingDayAugment(radius, player.getWorld()))) { - if (WaterMethods.isMeltable(block)) { - Melt.melt(player, block); - } else if (isHeatable(block)) { - heat(block); - } - } - } - - @SuppressWarnings("deprecation") - private static void heat(Block block) { - if (block.getType() == Material.OBSIDIAN) { - block.setType(Material.LAVA); - block.setData((byte) 0x0); - } - } - - private static boolean isHeatable(Block block) { - return false; - } - - @Override - public void reloadVariables() { - config.get().getInt("Abilities.Fire.HeatControl.Melt.Range"); - radius = config.get().getInt("Abilities.Fire.HeatControl.Melt.Radius"); - } -} diff --git a/src/com/projectkorra/projectkorra/firebending/Illumination.java b/src/com/projectkorra/projectkorra/firebending/Illumination.java index b2dd755e..ca9987da 100644 --- a/src/com/projectkorra/projectkorra/firebending/Illumination.java +++ b/src/com/projectkorra/projectkorra/firebending/Illumination.java @@ -1,156 +1,173 @@ package com.projectkorra.projectkorra.firebending; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.FireAbility; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; +import java.util.concurrent.ConcurrentHashMap; -public class Illumination implements ConfigLoadable { +public class Illumination extends FireAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - public static ConcurrentHashMap blocks = new ConcurrentHashMap(); + private static final ConcurrentHashMap BLOCKS = new ConcurrentHashMap<>(); - private static int range = config.get().getInt("Abilities.Fire.Illumination.Range"); - - private Player player; + private byte normalData; + private long cooldown; + private double range; + private Material normalType; private Block block; - private Material normaltype; - private byte normaldata; - + public Illumination(Player player) { - /* Initial Checks */ - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("Illumination")) + super(player); + + Illumination oldIllum = getAbility(player, Illumination.class); + if (oldIllum != null) { + oldIllum.remove(); return; - /* End Initial Checks */ - - if (instances.containsKey(player)) { - instances.get(player).remove(); - } else { - // reloadVariables(); - this.player = player; - set(); - instances.put(player, this); - bPlayer.addCooldown("Illumination", GeneralMethods.getGlobalCooldown()); } - } - - public static String getDescription() { - return "This ability gives firebenders a means of illuminating the area. It is a toggle - clicking " - + "will create a torch that follows you around. The torch will only appear on objects that are " - + "ignitable and can hold a torch (e.g. not leaves or ice). If you get too far away from the torch, " - + "it will disappear, but will reappear when you get on another ignitable block. Clicking again " - + "dismisses this torch."; - } - - public static void revert(Block block) { - Player player = blocks.get(block); - instances.get(player).revert(); - } - - // public static void manage(Server server) { - // for (Player player : server.getOnlinePlayers()) { - // if (instances.containsKey(player)) { - // if (!GeneralMethods.canBend(player.getName(), "Illumination")) { - // instances.get(player).revert(); - // instances.remove(player); - // } else { - // instances.get(player).set(); - // } - // } - // } - // - // for (Player player : instances.keySet()) { - // if (!player.isOnline() || player.isDead()) { - // instances.get(player).revert(); - // instances.remove(player); - // } - // } - // } - - public boolean progress() { - if (!player.isOnline() || player.isDead()) { - remove(); - return false; + + this.range = getConfig().getDouble("Abilities.Fire.Illumination.Range"); + this.cooldown = GeneralMethods.getGlobalCooldown(); + + this.range = getDayFactor(this.range); + + if (bPlayer.isOnCooldown(this)) { + return; } - if (!GeneralMethods.canBend(player.getName(), "Illumination")) { - remove(); - return false; - } else { - set(); - } - return true; - } - public static void progressAll() { - for (Illumination ability : instances.values()) { - ability.progress(); - } + set(); + start(); + bPlayer.addCooldown(this); } @Override - public void reloadVariables() { - range = config.get().getInt("Abilities.Fire.Illumination.Range"); - } - - public void remove() { - revert(); - instances.remove(player); - } - - public static void removeAll() { - for (Illumination ability : instances.values()) { - ability.remove(); + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { + remove(); + return; } + set(); } + @Override + public void remove() { + super.remove(); + revert(); + } + @SuppressWarnings("deprecation") private void revert() { if (block != null) { - blocks.remove(block); - block.setType(normaltype); - block.setData(normaldata); + BLOCKS.remove(block); + block.setType(normalType); + block.setData(normalData); } } @SuppressWarnings("deprecation") private void set() { - Block standingblock = player.getLocation().getBlock(); - Block standblock = standingblock.getRelative(BlockFace.DOWN); - if (standblock.getType() == Material.GLOWSTONE) { + Block standingBlock = player.getLocation().getBlock(); + Block standBlock = standingBlock.getRelative(BlockFace.DOWN); + + if (standBlock.getType() == Material.GLOWSTONE) { revert(); - } else if ((FireStream.isIgnitable(player, standingblock) && standblock.getType() != Material.LEAVES && standblock - .getType() != Material.LEAVES_2) && block == null && !blocks.containsKey(standblock)) { - block = standingblock; - normaltype = block.getType(); - normaldata = block.getData(); + } else if ((BlazeArc.isIgnitable(player, standingBlock) + && standBlock.getType() != Material.LEAVES && standBlock .getType() != Material.LEAVES_2) + && block == null && !BLOCKS.containsKey(standBlock)) { + block = standingBlock; + normalType = block.getType(); + normalData = block.getData(); + block.setType(Material.TORCH); - blocks.put(block, player); - } else if ((FireStream.isIgnitable(player, standingblock) && standblock.getType() != Material.LEAVES && standblock - .getType() != Material.LEAVES_2) - && !block.equals(standblock) - && !blocks.containsKey(standblock) - && GeneralMethods.isSolid(standblock)) { + BLOCKS.put(block, player); + } else if ((BlazeArc.isIgnitable(player, standingBlock) + && standBlock.getType() != Material.LEAVES && standBlock .getType() != Material.LEAVES_2) + && !block.equals(standBlock) + && !BLOCKS.containsKey(standBlock) + && GeneralMethods.isSolid(standBlock)) { revert(); - block = standingblock; - normaltype = block.getType(); - normaldata = block.getData(); + block = standingBlock; + normalType = block.getType(); + normalData = block.getData(); + block.setType(Material.TORCH); - blocks.put(block, player); + BLOCKS.put(block, player); } else if (block == null) { return; } else if (!player.getWorld().equals(block.getWorld())) { revert(); - } else if (player.getLocation().distance(block.getLocation()) > FireMethods.getFirebendingDayAugment(range, - player.getWorld())) { + } else if (player.getLocation().distanceSquared(block.getLocation()) > range * range) { revert(); } } + @Override + public String getName() { + return "Illumination"; + } + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return true; + } + + public byte getNormalData() { + return normalData; + } + + public void setNormalData(byte normalData) { + this.normalData = normalData; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public Material getNormalType() { + return normalType; + } + + public void setNormalType(Material normalType) { + this.normalType = normalType; + } + + public Block getBlock() { + return block; + } + + public void setBlock(Block block) { + this.block = block; + } + + public static ConcurrentHashMap getBlocks() { + return BLOCKS; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/firebending/Lightning.java b/src/com/projectkorra/projectkorra/firebending/Lightning.java index 7dcaf8e7..14d02f03 100644 --- a/src/com/projectkorra/projectkorra/firebending/Lightning.java +++ b/src/com/projectkorra/projectkorra/firebending/Lightning.java @@ -1,14 +1,11 @@ package com.projectkorra.projectkorra.firebending; -import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.earthbending.EarthMethods; +import com.projectkorra.projectkorra.ability.LightningAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; import org.bukkit.Location; -import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.entity.Entity; @@ -18,140 +15,95 @@ import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; import java.util.ArrayList; -import java.util.Arrays; -import java.util.concurrent.ConcurrentHashMap; -public class Lightning implements ConfigLoadable { - - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); +public class Lightning extends LightningAbility { + + public static enum State { + START, STRIKE, MAINBOLT + } - public static boolean SELF_HIT_WATER = config.get().getBoolean("Abilities.Fire.Lightning.SelfHitWater"); - public static boolean SELF_HIT_CLOSE = config.get().getBoolean("Abilities.Fire.Lightning.SelfHitClose"); - public static boolean ARC_ON_ICE = config.get().getBoolean("Abilities.Fire.Lightning.ArcOnIce"); - public static double RANGE = config.get().getDouble("Abilities.Fire.Lightning.Range"); - public static double DAMAGE = config.get().getDouble("Abilities.Fire.Lightning.Damage"); - public static double MAX_ARC_ANGLE = config.get().getDouble("Abilities.Fire.Lightning.MaxArcAngle"); - public static double SUB_ARC_CHANCE = config.get().getDouble("Abilities.Fire.Lightning.SubArcChance"); - public static double CHAIN_ARC_RANGE = config.get().getDouble("Abilities.Fire.Lightning.ChainArcRange"); - public static double CHAIN_ARC_CHANCE = config.get().getDouble("Abilities.Fire.Lightning.ChainArcChance"); - public static double WATER_ARC_RANGE = config.get().getDouble("Abilities.Fire.Lightning.WaterArcRange"); - public static double STUN_CHANCE = config.get().getDouble("Abilities.Fire.Lightning.StunChance"); - public static double STUN_DURATION = config.get().getDouble("Abilities.Fire.Lightning.StunDuration"); - public static int MAX_CHAIN_ARCS = (int) config.get().getDouble("Abilities.Fire.Lightning.MaxChainArcs"); - public static int WATER_ARCS = (int) config.get().getDouble("Abilities.Fire.Lightning.WaterArcs"); - public static long CHARGETIME = (long) config.get().getDouble("Abilities.Fire.Lightning.ChargeTime"); - public static long COOLDOWN = (long) config.get().getDouble("Abilities.Fire.Lightning.Cooldown"); private static final int POINT_GENERATION = 5; - private static int idCounter = 0; - - private Player player; - - private BendingPlayer bplayer; - private Location origin, destination; - private int id; - private double range, chargeTime, cooldown, subArcChance, damage, chainArcs, chainRange, waterRange; - private double chainArcChance, stunChance, stunDuration; + + private boolean charged; + private boolean hitWater; + private boolean hitIce; + private boolean selfHitWater; + private boolean selfHitClose; + private boolean arcOnIce; + private int waterArcs; + private double range; + private double chargeTime; + private double subArcChance; + private double damage; + private double maxChainArcs; + private double chainRange; + private double waterArcRange; + private double chainArcChance; + private double stunChance; + private double stunDuration; + private double maxArcAngle; + private double particleRotation; private long time; - private boolean charged, hitWater, hitIce; - private State state = State.START; - private ArrayList affectedEntities = new ArrayList(); - private ArrayList arcs = new ArrayList(); - private ArrayList tasks = new ArrayList(); - private double i = 0.0D; - private double newY; - + private long cooldown; + private State state; + private Location origin; + private Location destination; + private ArrayList affectedEntities; + private ArrayList arcs; + private ArrayList tasks; + public Lightning(Player player) { - // reloadVariables(); - this.player = player; - bplayer = GeneralMethods.getBendingPlayer(player.getName()); - charged = false; - hitWater = false; - hitIce = false; - time = System.currentTimeMillis(); - range = FireMethods.getFirebendingDayAugment(RANGE, player.getWorld()); - subArcChance = FireMethods.getFirebendingDayAugment(SUB_ARC_CHANCE, player.getWorld()); - damage = FireMethods.getFirebendingDayAugment(DAMAGE, player.getWorld()); - chainArcs = FireMethods.getFirebendingDayAugment(MAX_CHAIN_ARCS, player.getWorld()); - chainArcChance = FireMethods.getFirebendingDayAugment(CHAIN_ARC_CHANCE, player.getWorld()); - chainRange = FireMethods.getFirebendingDayAugment(CHAIN_ARC_RANGE, player.getWorld()); - waterRange = FireMethods.getFirebendingDayAugment(WATER_ARC_RANGE, player.getWorld()); - stunChance = FireMethods.getFirebendingDayAugment(STUN_CHANCE, player.getWorld()); - stunDuration = FireMethods.getFirebendingDayAugment(STUN_DURATION, player.getWorld()); - chargeTime = CHARGETIME; - cooldown = COOLDOWN; + super(player); + + this.charged = false; + this.hitWater = false; + this.hitIce = false; + this.time = System.currentTimeMillis(); + this.state = State.START; + this.affectedEntities = new ArrayList<>(); + this.arcs = new ArrayList<>(); + this.tasks = new ArrayList<>(); + + this.selfHitWater = getConfig().getBoolean("Abilities.Fire.Lightning.SelfHitWater"); + this.selfHitClose = getConfig().getBoolean("Abilities.Fire.Lightning.SelfHitClose"); + this.arcOnIce = getConfig().getBoolean("Abilities.Fire.Lightning.ArcOnIce"); + this.range = getConfig().getDouble("Abilities.Fire.Lightning.Range"); + this.damage = getConfig().getDouble("Abilities.Fire.Lightning.Damage"); + this.maxArcAngle = getConfig().getDouble("Abilities.Fire.Lightning.MaxArcAngle"); + this.subArcChance = getConfig().getDouble("Abilities.Fire.Lightning.SubArcChance"); + this.chainRange = getConfig().getDouble("Abilities.Fire.Lightning.ChainArcRange"); + this.chainArcChance = getConfig().getDouble("Abilities.Fire.Lightning.ChainArcChance"); + this.waterArcRange = getConfig().getDouble("Abilities.Fire.Lightning.WaterArcRange"); + this.stunChance = getConfig().getDouble("Abilities.Fire.Lightning.StunChance"); + this.stunDuration = getConfig().getDouble("Abilities.Fire.Lightning.StunDuration"); + this.maxChainArcs = getConfig().getInt("Abilities.Fire.Lightning.MaxChainArcs"); + this.waterArcs = getConfig().getInt("Abilities.Fire.Lightning.WaterArcs"); + this.chargeTime = getConfig().getLong("Abilities.Fire.Lightning.ChargeTime"); + this.cooldown = getConfig().getLong("Abilities.Fire.Lightning.Cooldown"); + + this.range = getDayFactor(this.range); + this.subArcChance = getDayFactor(this.subArcChance); + this.damage = getDayFactor(this.damage); + this.maxChainArcs = getDayFactor(this.maxChainArcs); + this.chainArcChance = getDayFactor(this.chainArcChance); + this.chainRange = getDayFactor(this.chainRange); + this.waterArcRange = getDayFactor(this.waterArcRange); + this.stunChance = getDayFactor(this.stunChance); + this.stunDuration = getDayFactor(this.stunDuration); - if (AvatarState.isAvatarState(player)) { - /* - * Some variables aren't considered here because it makes AS too overpowered and causes - * crashing. - */ - chargeTime = 0; - cooldown = 0; - damage = AvatarState.getValue(damage); - chainArcs = AvatarState.getValue(chainArcs); - chainArcChance = AvatarState.getValue(chainArcChance); - chainRange = AvatarState.getValue(chainRange); - stunChance = AvatarState.getValue(stunChance); + if (bPlayer.isAvatarState()) { + this.chargeTime = 0; + this.cooldown = 0; + this.damage = AvatarState.getValue(damage); + this.maxChainArcs = AvatarState.getValue(maxChainArcs); + this.chainArcChance = AvatarState.getValue(chainArcChance); + this.chainRange = AvatarState.getValue(chainRange); + this.stunChance = AvatarState.getValue(stunChance); + } else if (isSozinsComet(player.getWorld())) { + this.chargeTime = 0; + this.cooldown = 0; } - instances.put(idCounter, this); - this.id = idCounter; - idCounter = (idCounter + 1) % Integer.MAX_VALUE; - } - - public static ArrayList getAllArcs() { - ArrayList a = new ArrayList(); - for (Lightning light : instances.values()) { - for (Arc arcs : light.getArcs()) { - a.add(arcs); - } - } - return a; - } - - /** - * Returns an instance of this ability if it was initialized by player - * - * @param player that created the instance - * @return the ability - */ - public static Lightning getLightning(Player player) { - for (Lightning light : instances.values()) { - if (light.player == player) - return light; - } - return null; - } - - /** - * Checks if a location contains an ice block - * - * @param loc the location to check - * @return true if it is ice - */ - public static boolean isIce(Location loc) { - Material mat = loc.getBlock().getType(); - return mat == Material.ICE || mat == Material.PACKED_ICE; - } - - /** - * Checks if a location contains a water block - * - * @param loc the location to check - * @return true if it is water - */ - public static boolean isWater(Location loc) { - Material mat = loc.getBlock().getType(); - return mat == Material.WATER || mat == Material.STATIONARY_WATER; - } - - /** - * Checks if a location is ice or water - * - * @param loc the location to check - * @return true if it is water or ice - */ - public static boolean isWaterOrIce(Location loc) { - return isIce(loc) || isWater(loc); + start(); } /** @@ -162,13 +114,15 @@ public class Lightning implements ConfigLoadable { public void electrocute(LivingEntity lent) { lent.getWorld().playSound(lent.getLocation(), Sound.CREEPER_HISS, 1, 0); player.getWorld().playSound(player.getLocation(), Sound.CREEPER_HISS, 1, 0); - GeneralMethods.damageEntity(player, lent, damage, "Lightning"); + GeneralMethods.damageEntity(this, lent, damage); + if (Math.random() < stunChance) { final Location lentLoc = lent.getLocation(); final LivingEntity flent = lent; + new BukkitRunnable() { int count = 0; - + @Override public void run() { if (flent.isDead() || (flent instanceof Player && !((Player) flent).isOnline())) { cancel(); @@ -182,78 +136,14 @@ public class Lightning implements ConfigLoadable { flent.teleport(tempLoc); flent.setVelocity(tempVel); count++; - if (count > stunDuration) + if (count > stunDuration) { cancel(); + } } }.runTaskTimer(ProjectKorra.plugin, 0, 1); } } - public ArrayList getArcs() { - return this.arcs; - } - - public double getChainArcChance() { - return chainArcChance; - } - - public double getChainArcs() { - return chainArcs; - } - - public double getChainRange() { - return chainRange; - } - - public double getChargeTime() { - return chargeTime; - } - - public double getCooldown() { - return cooldown; - } - - public double getDamage() { - return damage; - } - - /** Below are all of the accessor/mutator methods **/ - public Player getPlayer() { - return player; - } - - public double getRange() { - return range; - } - - public double getStunChance() { - return stunChance; - } - - public double getStunDuration() { - return stunDuration; - } - - public double getSubArcChance() { - return subArcChance; - } - - public double getWaterRange() { - return waterRange; - } - - public boolean isCharged() { - return charged; - } - - public boolean isHitIce() { - return hitIce; - } - - public boolean isHitWater() { - return hitWater; - } - /** * Checks if a block is transparent, also considers the ARC_ON_ICE config option. * @@ -261,15 +151,15 @@ public class Lightning implements ConfigLoadable { * @param block the block * @return true if the block is transparent */ - @SuppressWarnings("deprecation") - public boolean isTransparent(Player player, Block block) { - if (Arrays.asList(EarthMethods.transparentToEarthbending).contains(block.getTypeId())) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "Lightning", block.getLocation())) + private boolean isTransparent(Player player, Block block) { + if (isTransparent(block)) { + if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { return false; - else if (isIce(block.getLocation())) - return ARC_ON_ICE; - else + } else if (isIce(block)) { + return arcOnIce; + } else { return true; + } } return false; } @@ -281,82 +171,86 @@ public class Lightning implements ConfigLoadable { * Once all of the arcs have been created then this ability instance gets removed, but the * BukkitRunnables continue until they remove themselves. **/ - public boolean progress() { + @Override + public void progress() { if (player.isDead() || !player.isOnline()) { removeWithTasks(); - return false; - } else if (GeneralMethods.getBoundAbility(player) == null - || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("Lightning")) { + return; + } else if (!bPlayer.canBendIgnoreCooldowns(this)) { remove(); - return false; + return; } + if (state == State.START) { - if (bplayer.isOnCooldown("Lightning")) { + if (bPlayer.isOnCooldown(this)) { remove(); - return false; - } - if (System.currentTimeMillis() - time > chargeTime) + return; + } else if (System.currentTimeMillis() - time > chargeTime) { charged = true; + } + if (charged) { if (player.isSneaking()) { Location loc = player.getEyeLocation().add(player.getEyeLocation().getDirection().normalize().multiply(1.2)); loc.add(0, 0.3, 0); - FireMethods.playLightningbendingParticle(loc, 0.2F, 0.2F, 0.2F); + playLightningbendingParticle(loc, 0.2F, 0.2F, 0.2F); } else { state = State.MAINBOLT; - bplayer.addCooldown("Lightning", (long) cooldown); - Entity target = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); + bPlayer.addCooldown(this); + Entity target = GeneralMethods.getTargetedEntity(player, range); origin = player.getEyeLocation(); - if (target != null) + + if (target != null) { destination = target.getLocation(); - else - destination = player.getEyeLocation().add( - player.getEyeLocation().getDirection().normalize().multiply(range)); + } else { + destination = player.getEyeLocation().add( player.getEyeLocation().getDirection().normalize().multiply(range)); + } } } else { if (!player.isSneaking()) { remove(); - return false; + return; } + + Location localLocation1 = player.getLocation(); double d1 = 0.1570796326794897D; double d2 = 0.06283185307179587D; double d3 = 1.0D; double d4 = 1.0D; - Location localLocation1 = player.getLocation(); - double d5 = d1 * i; - double d6 = d2 * i; - newY = (localLocation1.getY() + 1.0D + d4 * Math.cos(d6)); + double d5 = d1 * particleRotation; + double d6 = d2 * particleRotation; double d7 = localLocation1.getX() + d4 * Math.cos(d5); double d8 = localLocation1.getZ() + d4 * Math.sin(d5); + double newY = (localLocation1.getY() + 1.0D + d4 * Math.cos(d6)); Location localLocation2 = new Location(player.getWorld(), d7, newY, d8); - - FireMethods.playLightningbendingParticle(localLocation2); - - i += 1.0D / d3; + playLightningbendingParticle(localLocation2); + particleRotation += 1.0D / d3; } } else if (state == State.MAINBOLT) { Arc mainArc = new Arc(origin, destination); mainArc.generatePoints(POINT_GENERATION); arcs.add(mainArc); - ArrayList subArcs = mainArc.generateArcs(subArcChance, range / 2.0); + ArrayList subArcs = mainArc.generateArcs(subArcChance, range / 2.0, maxArcAngle); arcs.addAll(subArcs); state = State.STRIKE; } else if (state == State.STRIKE) { for (int i = 0; i < arcs.size(); i++) { Arc arc = arcs.get(i); - for (int j = 0; j < arc.getAnimLocs().size() - 1; j++) { - final Location iterLoc = arc.getAnimLocs().get(j).getLoc().clone(); - final Location dest = arc.getAnimLocs().get(j + 1).getLoc().clone(); - if (SELF_HIT_CLOSE && player.getLocation().distance(iterLoc) < 3 - && !isTransparent(player, iterLoc.getBlock()) && !affectedEntities.contains(player)) { + for (int j = 0; j < arc.getAnimationLocations().size() - 1; j++) { + final Location iterLoc = arc.getAnimationLocations().get(j).getLocation().clone(); + final Location dest = arc.getAnimationLocations().get(j + 1).getLocation().clone(); + if (selfHitClose + && player.getLocation().distanceSquared(iterLoc) < 9 + && !isTransparent(player, iterLoc.getBlock()) + && !affectedEntities.contains(player)) { affectedEntities.add(player); electrocute(player); } - while (iterLoc.distance(dest) > 0.15) { - BukkitRunnable task = new LightningParticle(arc, iterLoc.clone()); - double timer = arc.getAnimLocs().get(j).getAnimCounter() / 2; + while (iterLoc.distanceSquared(dest) > 0.15 * 0.15) { + BukkitRunnable task = new LightningParticle(arc, iterLoc.clone(), selfHitWater, waterArcs); + double timer = arc.getAnimationLocations().get(j).getAnimCounter() / 2; task.runTaskTimer(ProjectKorra.plugin, (long) timer, 1); tasks.add(task); iterLoc.add(GeneralMethods.getDirection(iterLoc, dest).normalize().multiply(0.15)); @@ -367,46 +261,9 @@ public class Lightning implements ConfigLoadable { } if (tasks.size() == 0) { remove(); - return false; + return; } } - return true; - } - - public static void progressAll() { - for (Lightning ability : instances.values()) { - ability.progress(); - } - } - - public void remove() { - instances.remove(id); - } - - public static void removeAll() { - for (Lightning ability : instances.values()) { - ability.remove(); - } - } - - @Override - public void reloadVariables() { - SELF_HIT_WATER = config.get().getBoolean("Abilities.Fire.Lightning.SelfHitWater"); - SELF_HIT_CLOSE = config.get().getBoolean("Abilities.Fire.Lightning.SelfHitClose"); - ARC_ON_ICE = config.get().getBoolean("Abilities.Fire.Lightning.ArcOnIce"); - RANGE = config.get().getDouble("Abilities.Fire.Lightning.Range"); - DAMAGE = config.get().getDouble("Abilities.Fire.Lightning.Damage"); - MAX_ARC_ANGLE = config.get().getDouble("Abilities.Fire.Lightning.MaxArcAngle"); - SUB_ARC_CHANCE = config.get().getDouble("Abilities.Fire.Lightning.SubArcChance"); - CHAIN_ARC_RANGE = config.get().getDouble("Abilities.Fire.Lightning.ChainArcRange"); - CHAIN_ARC_CHANCE = config.get().getDouble("Abilities.Fire.Lightning.ChainArcChance"); - WATER_ARC_RANGE = config.get().getDouble("Abilities.Fire.Lightning.WaterArcRange"); - STUN_CHANCE = config.get().getDouble("Abilities.Fire.Lightning.StunChance"); - STUN_DURATION = config.get().getDouble("Abilities.Fire.Lightning.StunDuration"); - MAX_CHAIN_ARCS = (int) config.get().getDouble("Abilities.Fire.Lightning.MaxChainArcs"); - WATER_ARCS = (int) config.get().getDouble("Abilities.Fire.Lightning.WaterArcs"); - CHARGETIME = (long) config.get().getDouble("Abilities.Fire.Lightning.ChargeTime"); - COOLDOWN = (long) config.get().getDouble("Abilities.Fire.Lightning.Cooldown"); } /** @@ -420,95 +277,33 @@ public class Lightning implements ConfigLoadable { remove(); } - public void setChainArcChance(double chainArcChance) { - this.chainArcChance = chainArcChance; - } - - public void setChainArcs(double chainArcs) { - this.chainArcs = chainArcs; - } - - public void setChainRange(double chainRange) { - this.chainRange = chainRange; - } - - public void setCharged(boolean charged) { - this.charged = charged; - } - - public void setChargeTime(double chargeTime) { - this.chargeTime = chargeTime; - } - - public void setCooldown(double cooldown) { - this.cooldown = cooldown; - if (player != null) - bplayer.addCooldown("Lightning", (long) cooldown); - } - - public void setDamage(double damage) { - this.damage = damage; - } - - public void setHitIce(boolean hitIce) { - this.hitIce = hitIce; - } - - public void setHitWater(boolean hitWater) { - this.hitWater = hitWater; - } - - public void setPlayer(Player player) { - this.player = player; - } - - public void setRange(double range) { - this.range = range; - } - - public void setStunChance(double stunChance) { - this.stunChance = stunChance; - } - - public void setStunDuration(double stunDuration) { - this.stunDuration = stunDuration; - } - - public void setSubArcChance(double subArcChance) { - this.subArcChance = subArcChance; - } - - public void setWaterRange(double waterRange) { - this.waterRange = waterRange; - } - /** * Represents a Lightning Arc Point particle animation. This basically just holds a location and * counts the amount of times that a particle has been animated. * **/ - public class AnimLocation { - private Location loc; - private int animCounter; + public class AnimationLocation { + private Location location; + private int animationCounter; - public AnimLocation(Location loc, int animCounter) { - this.loc = loc; - this.animCounter = animCounter; + public AnimationLocation(Location loc, int animationCounter) { + this.location = loc; + this.animationCounter = animationCounter; } public int getAnimCounter() { - return animCounter; + return animationCounter; } - public Location getLoc() { - return loc; + public Location getLocation() { + return location; } - public void setAnimCounter(int animCounter) { - this.animCounter = animCounter; + public void setAnimationCounter(int animationCounter) { + this.animationCounter = animationCounter; } - public void setLoc(Location loc) { - this.loc = loc; + public void setLocation(Location location) { + this.location = location; } } @@ -518,22 +313,22 @@ public class Lightning implements ConfigLoadable { * that chain off of their own instance. **/ public class Arc { + private int animationCounter; + private Vector direction; private ArrayList points; - private ArrayList animLocs; + private ArrayList animationLocations; private ArrayList particles; private ArrayList subArcs; - private Vector direction; - private int animCounter; public Arc(Location startPoint, Location endPoint) { - points = new ArrayList(); + points = new ArrayList<>(); points.add(startPoint.clone()); points.add(endPoint.clone()); direction = GeneralMethods.getDirection(startPoint, endPoint); - particles = new ArrayList(); - subArcs = new ArrayList(); - animLocs = new ArrayList(); - animCounter = 0; + particles = new ArrayList<>(); + subArcs = new ArrayList<>(); + animationLocations = new ArrayList<>(); + animationCounter = 0; } /** @@ -558,21 +353,24 @@ public class Lightning implements ConfigLoadable { * @param range The length of each subarc. * **/ - public ArrayList generateArcs(double chance, double range) { - ArrayList arcs = new ArrayList(); - for (int i = 0; i < animLocs.size(); i++) { + public ArrayList generateArcs(double chance, double range, double maxArcAngle) { + ArrayList arcs = new ArrayList<>(); + + for (int i = 0; i < animationLocations.size(); i++) { if (Math.random() < chance) { - Location loc = animLocs.get(i).getLoc(); - double angle = (Math.random() - 0.5) * MAX_ARC_ANGLE * 2; + Location loc = animationLocations.get(i).getLocation(); + double angle = (Math.random() - 0.5) * maxArcAngle * 2; Vector dir = GeneralMethods.rotateXZ(direction.clone(), angle); double randRange = (Math.random() * range) + (range / 3.0); + Location loc2 = loc.clone().add(dir.normalize().multiply(randRange)); Arc arc = new Arc(loc, loc2); + subArcs.add(arc); - arc.setAnimCounter(animLocs.get(i).getAnimCounter()); + arc.setAnimationCounter(animationLocations.get(i).getAnimCounter()); arc.generatePoints(POINT_GENERATION); arcs.add(arc); - arcs.addAll(arc.generateArcs(chance / 2.0, range / 2.0)); + arcs.addAll(arc.generateArcs(chance / 2.0, range / 2.0, maxArcAngle)); } } return arcs; @@ -594,61 +392,56 @@ public class Lightning implements ConfigLoadable { Location loc1 = points.get(j); Location loc2 = points.get(j + 1); double adjac = loc1.distance(loc2) / 2; - double angle = (Math.random() - 0.5) * MAX_ARC_ANGLE; + double angle = (Math.random() - 0.5) * maxArcAngle; + angle += angle >= 0 ? 10 : -10; + double radians = Math.toRadians(angle); double hypot = adjac / Math.cos(radians); Vector dir = GeneralMethods.rotateXZ(direction.clone(), angle); Location newLoc = loc1.clone().add(dir.normalize().multiply(hypot)); + newLoc.add(0, (Math.random() - 0.5) / 2.0, 0); points.add(j + 1, newLoc); } } for (int i = 0; i < points.size(); i++) { - animLocs.add(new AnimLocation(points.get(i), animCounter)); - animCounter++; + animationLocations.add(new AnimationLocation(points.get(i), animationCounter)); + animationCounter++; } } - public int getAnimCounter() { - return animCounter; + public int getAnimationCounter() { + return animationCounter; } - public ArrayList getAnimLocs() { - return animLocs; + public void setAnimationCounter(int animationCounter) { + this.animationCounter = animationCounter; } public Vector getDirection() { return direction; } - public ArrayList getParticles() { - return particles; + public void setDirection(Vector direction) { + this.direction = direction; } public ArrayList getPoints() { return points; } - public void setAnimCounter(int animCounter) { - this.animCounter = animCounter; + public ArrayList getAnimationLocations() { + return animationLocations; } - public void setAnimLocs(ArrayList animLocs) { - this.animLocs = animLocs; + public ArrayList getParticles() { + return particles; } - public void setDirection(Vector direction) { - this.direction = direction; - } - - public void setParticles(ArrayList particles) { - this.particles = particles; - } - - public void setPoints(ArrayList points) { - this.points = points; - } + public ArrayList getSubArcs() { + return subArcs; + } } @@ -660,17 +453,22 @@ public class Lightning implements ConfigLoadable { * generate subarcs to branch out. * **/ public class LightningParticle extends BukkitRunnable { - private Arc arc; - private Location loc; + private boolean selfHitWater; private int count = 0; + private int waterArcs; + private Arc arc; + private Location location; - public LightningParticle(Arc arc, Location loc) { + public LightningParticle(Arc arc, Location location, boolean selfHitWater, int waterArcs) { this.arc = arc; - this.loc = loc; + this.location = location; + this.selfHitWater = selfHitWater; + this.waterArcs = waterArcs; arc.particles.add(this); } /** Cancels this Runnable **/ + @Override public void cancel() { super.cancel(); tasks.remove(this); @@ -680,42 +478,45 @@ public class Lightning implements ConfigLoadable { * Animates the Location, checks for water/player collision and also deals with any chain * subarcs. */ + @Override public void run() { - FireMethods.playLightningbendingParticle(loc, 0F, 0F, 0F); + playLightningbendingParticle(location, 0F, 0F, 0F); count++; - if (count > 5) + if (count > 5) { this.cancel(); - else if (count == 1) { - if (!isTransparent(player, loc.getBlock())) { + } else if (count == 1) { + if (!isTransparent(player, location.getBlock())) { arc.cancel(); return; } - + Block block = location.getBlock(); // Handle Water electrocution - if (!hitWater && (isWater(loc) || (ARC_ON_ICE && isIce(loc)))) { + if (!hitWater && (isWater(block) || (arcOnIce && isIce(block)))) { hitWater = true; - if (isIce(loc)) + if (isIce(block)) { hitIce = true; - for (int i = 0; i < WATER_ARCS; i++) { - Location origin = loc.clone(); + } + + for (int i = 0; i < waterArcs; i++) { + Location origin = location.clone(); origin.add(new Vector((Math.random() - 0.5) * 2, 0, (Math.random() - 0.5) * 2)); - destination = origin.clone().add( - new Vector((Math.random() - 0.5) * waterRange, Math.random() - 0.7, (Math.random() - 0.5) - * waterRange)); + destination = origin.clone().add(new Vector((Math.random() - 0.5) * waterArcRange, Math.random() - 0.7, (Math.random() - 0.5)* waterArcRange)); Arc newArc = new Arc(origin, destination); newArc.generatePoints(POINT_GENERATION); arcs.add(newArc); } } - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(loc, 2.5)) { + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2.5)) { /* * If the player is in water we will electrocute them only if they are standing * in water. If the lightning hit ice we can electrocute them all the time. */ - if (entity.equals(player) && !(SELF_HIT_WATER && hitWater && isWater(player.getLocation())) - && !(SELF_HIT_WATER && hitIce)) + if (entity.equals(player) + && !(selfHitWater && hitWater && isWater(player.getLocation().getBlock())) + && !(selfHitWater && hitIce)) { continue; + } if (entity instanceof LivingEntity && !affectedEntities.contains(entity)) { affectedEntities.add(entity); @@ -724,18 +525,19 @@ public class Lightning implements ConfigLoadable { lent.getWorld().playSound(lent.getLocation(), Sound.CREEPER_HISS, 1, 0); player.getWorld().playSound(player.getLocation(), Sound.CREEPER_HISS, 1, 0); Player p = (Player) lent; - Lightning light = getLightning(p); + Lightning light = getAbility(p, Lightning.class); if (light != null && light.state == State.START) { light.charged = true; remove(); return; } } + electrocute(lent); // Handle Chain Lightning - if (chainArcs >= 1 && Math.random() <= chainArcChance) { - chainArcs--; + if (maxChainArcs >= 1 && Math.random() <= chainArcChance) { + maxChainArcs--; for (Entity ent : GeneralMethods.getEntitiesAroundPoint(lent.getLocation(), chainRange)) { if (!ent.equals(player) && !ent.equals(lent) && ent instanceof LivingEntity && !affectedEntities.contains(ent)) { @@ -753,9 +555,275 @@ public class Lightning implements ConfigLoadable { } } } + + public boolean isSelfHitWater() { + return selfHitWater; + } + + public void setSelfHitWater(boolean selfHitWater) { + this.selfHitWater = selfHitWater; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public int getWaterArcs() { + return waterArcs; + } + + public void setWaterArcs(int waterArcs) { + this.waterArcs = waterArcs; + } + + public Arc getArc() { + return arc; + } + + public void setArc(Arc arc) { + this.arc = arc; + } + + public Location getLocation() { + return location; + } + + public void setLocation(Location location) { + this.location = location; + } } - public static enum State { - START, STRIKE, MAINBOLT + @Override + public String getName() { + return "Lightning"; } + + @Override + public Location getLocation() { + return origin; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isCharged() { + return charged; + } + + public void setCharged(boolean charged) { + this.charged = charged; + } + + public boolean isHitWater() { + return hitWater; + } + + public void setHitWater(boolean hitWater) { + this.hitWater = hitWater; + } + + public boolean isHitIce() { + return hitIce; + } + + public void setHitIce(boolean hitIce) { + this.hitIce = hitIce; + } + + public boolean isSelfHitWater() { + return selfHitWater; + } + + public void setSelfHitWater(boolean selfHitWater) { + this.selfHitWater = selfHitWater; + } + + public boolean isSelfHitClose() { + return selfHitClose; + } + + public void setSelfHitClose(boolean selfHitClose) { + this.selfHitClose = selfHitClose; + } + + public boolean isArcOnIce() { + return arcOnIce; + } + + public void setArcOnIce(boolean arcOnIce) { + this.arcOnIce = arcOnIce; + } + + public int getWaterArcs() { + return waterArcs; + } + + public void setWaterArcs(int waterArcs) { + this.waterArcs = waterArcs; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getChargeTime() { + return chargeTime; + } + + public void setChargeTime(double chargeTime) { + this.chargeTime = chargeTime; + } + + public double getSubArcChance() { + return subArcChance; + } + + public void setSubArcChance(double subArcChance) { + this.subArcChance = subArcChance; + } + + public double getDamage() { + return damage; + } + + public void setDamage(double damage) { + this.damage = damage; + } + + public double getMaxChainArcs() { + return maxChainArcs; + } + + public void setMaxChainArcs(double maxChainArcs) { + this.maxChainArcs = maxChainArcs; + } + + public double getChainRange() { + return chainRange; + } + + public void setChainRange(double chainRange) { + this.chainRange = chainRange; + } + + public double getWaterArcRange() { + return waterArcRange; + } + + public void setWaterArcRange(double waterArcRange) { + this.waterArcRange = waterArcRange; + } + + public double getChainArcChance() { + return chainArcChance; + } + + public void setChainArcChance(double chainArcChance) { + this.chainArcChance = chainArcChance; + } + + public double getStunChance() { + return stunChance; + } + + public void setStunChance(double stunChance) { + this.stunChance = stunChance; + } + + public double getStunDuration() { + return stunDuration; + } + + public void setStunDuration(double stunDuration) { + this.stunDuration = stunDuration; + } + + public double getMaxArcAngle() { + return maxArcAngle; + } + + public void setMaxArcAngle(double maxArcAngle) { + this.maxArcAngle = maxArcAngle; + } + + public double getParticleRotation() { + return particleRotation; + } + + public void setParticleRotation(double particleRotation) { + this.particleRotation = particleRotation; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public Location getDestination() { + return destination; + } + + public void setDestination(Location destination) { + this.destination = destination; + } + + public static int getPointGeneration() { + return POINT_GENERATION; + } + + public ArrayList getAffectedEntities() { + return affectedEntities; + } + + public ArrayList getArcs() { + return arcs; + } + + public ArrayList getTasks() { + return tasks; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/firebending/RingOfFire.java b/src/com/projectkorra/projectkorra/firebending/RingOfFire.java deleted file mode 100644 index 09c8f6f1..00000000 --- a/src/com/projectkorra/projectkorra/firebending/RingOfFire.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.projectkorra.projectkorra.firebending; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; - -import org.bukkit.Location; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -public class RingOfFire implements ConfigLoadable { - - static int defaultrange = config.get().getInt("Abilities.Fire.Blaze.RingOfFire.Range"); - - public RingOfFire(Player player) { - /* Initial Checks */ - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("Blaze")) - return; - /* End Initial Checks */ - // reloadVariables(); - Location location = player.getLocation(); - - for (double degrees = 0; degrees < 360; degrees += 10) { - double angle = Math.toRadians(degrees); - Vector direction = player.getEyeLocation().getDirection().clone(); - - double x, z, vx, vz; - x = direction.getX(); - z = direction.getZ(); - - vx = x * Math.cos(angle) - z * Math.sin(angle); - vz = x * Math.sin(angle) + z * Math.cos(angle); - - direction.setX(vx); - direction.setZ(vz); - - int range = defaultrange; - if (AvatarState.isAvatarState(player)) - range = AvatarState.getValue(range); - - new FireStream(location, direction, player, range); - } - - bPlayer.addCooldown("Blaze", GeneralMethods.getGlobalCooldown()); - } - - public static String getDescription() { - return "To use, simply left-click. " + "A circle of fire will emanate from you, " - + "engulfing everything around you. Use with extreme caution."; - } - - @Override - public void reloadVariables() { - defaultrange = config.get().getInt("Abilities.Fire.Blaze.RingOfFire.Range"); - } - -} \ No newline at end of file diff --git a/src/com/projectkorra/projectkorra/firebending/WallOfFire.java b/src/com/projectkorra/projectkorra/firebending/WallOfFire.java index 302befbb..74f7dcb3 100644 --- a/src/com/projectkorra/projectkorra/firebending/WallOfFire.java +++ b/src/com/projectkorra/projectkorra/firebending/WallOfFire.java @@ -1,86 +1,75 @@ package com.projectkorra.projectkorra.firebending; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.util.ParticleEffect; import org.bukkit.Location; -import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.configuration.ConfigLoadable; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.util.ParticleEffect; -import com.projectkorra.projectkorra.util.TempBlock; -import com.projectkorra.projectkorra.waterbending.WaterMethods; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; -public class WallOfFire implements ConfigLoadable { - - public static ConcurrentHashMap instances = new ConcurrentHashMap<>(); - - private static double maxangle = 50; - - private static int RANGE = config.get().getInt("Abilities.Fire.WallOfFire.Range"); - - private static int HEIGHT = config.get().getInt("Abilities.Fire.WallOfFire.Height"); - private static int WIDTH = config.get().getInt("Abilities.Fire.WallOfFire.Width"); - private static long DURATION = config.get().getLong("Abilities.Fire.WallOfFire.Duration"); - private static int DAMAGE = config.get().getInt("Abilities.Fire.WallOfFire.Damage"); - private static long interval = 250; - private static long COOLDOWN = config.get().getLong("Abilities.Fire.WallOfFire.Cooldown"); - private static long DAMAGE_INTERVAL = config.get().getLong("Abilities.Fire.WallOfFire.Interval"); - private static double FIRETICKS = config.get().getDouble("Abilities.Fire.WallOfFire.FireTicks"); - private Player player; +public class WallOfFire extends FireAbility { + private boolean active; + private int damageTick; + private int intervalTick; + private int range; + private int height; + private int width; + private int damage; + private long cooldown; + private long damageInterval; + private long duration; + private long time; + private long interval; + private double fireTicks; + private double maxAngle; + private Random random; private Location origin; - private long time, starttime; - private boolean active = true; - private int damagetick = 0, intervaltick = 0; - private int range = RANGE; - private int height = HEIGHT; - private int width = WIDTH; - private long duration = DURATION; - private int damage = DAMAGE; - private long cooldown = COOLDOWN; - private long damageinterval = DAMAGE_INTERVAL; - private List blocks = new ArrayList(); - + private List blocks; + public WallOfFire(Player player) { - /* Initial Checks */ - if (instances.containsKey(player) && !AvatarState.isAvatarState(player)) { + super(player); + + this.active = true; + this.maxAngle = 50; + this.interval = 250; + this.range = getConfig().getInt("Abilities.Fire.WallOfFire.Range"); + this.height = getConfig().getInt("Abilities.Fire.WallOfFire.Height"); + this.width = getConfig().getInt("Abilities.Fire.WallOfFire.Width"); + this.damage = getConfig().getInt("Abilities.Fire.WallOfFire.Damage"); + this.cooldown = getConfig().getLong("Abilities.Fire.WallOfFire.Cooldown"); + this.damageInterval = getConfig().getLong("Abilities.Fire.WallOfFire.Interval"); + this.duration = getConfig().getLong("Abilities.Fire.WallOfFire.Duration"); + this.fireTicks = getConfig().getDouble("Abilities.Fire.WallOfFire.FireTicks"); + this.random = new Random(); + this.blocks = new ArrayList<>(); + + if (hasAbility(player, WallOfFire.class) && !bPlayer.isAvatarState()) { + return; + } else if (bPlayer.isOnCooldown(this)) { return; } - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("WallOfFire")) - return; - /* End Initial Checks */ - - this.player = player; - + origin = GeneralMethods.getTargetedLocation(player, range); - World world = player.getWorld(); - - if (FireMethods.isDay(player.getWorld())) { - width = (int) FireMethods.getFirebendingDayAugment((double) width, world); - height = (int) FireMethods.getFirebendingDayAugment((double) height, world); - duration = (long) FireMethods.getFirebendingDayAugment((double) duration, world); - damage = (int) FireMethods.getFirebendingDayAugment((double) damage, world); + if (isDay(player.getWorld())) { + width = (int) getDayFactor(width); + height = (int) getDayFactor(height); + duration = (long) getDayFactor(duration); + damage = (int) getDayFactor(damage); } time = System.currentTimeMillis(); - starttime = time; - Block block = origin.getBlock(); - if (block.isLiquid() || GeneralMethods.isSolid(block)) { return; } @@ -88,45 +77,42 @@ public class WallOfFire implements ConfigLoadable { Vector direction = player.getEyeLocation().getDirection(); Vector compare = direction.clone(); compare.setY(0); - - if (Math.abs(direction.angle(compare)) > Math.toRadians(maxangle)) { + if (Math.abs(direction.angle(compare)) > Math.toRadians(maxAngle)) { return; } initializeBlocks(); - - instances.put(player, this); - bPlayer.addCooldown("WallOfFire", cooldown); + start(); + bPlayer.addCooldown(this); } private void affect(Entity entity) { - if (entity instanceof LivingEntity) { - LivingEntity e = (LivingEntity) entity; - Block block = e.getEyeLocation().getBlock(); - if (TempBlock.isTempBlock(block) && WaterMethods.isIcebendable(block)) { - return; - } - GeneralMethods.damageEntity(player, entity, damage, "WallOfFire"); - new Enflamed(entity, player); - AirMethods.breakBreathbendingHold(entity); - } - entity.setFireTicks((int) (FIRETICKS * 20)); + entity.setFireTicks((int) (fireTicks * 20)); GeneralMethods.setVelocity(entity, new Vector(0, 0, 0)); + if (entity instanceof LivingEntity) { + GeneralMethods.damageEntity(this, entity, damage); + new FireDamageTimer(entity, player); + AirAbility.breakBreathbendingHold(entity); + } } private void damage() { double radius = height; - if (radius < width) + if (radius < width) { radius = width; + } + radius = radius + 1; List entities = GeneralMethods.getEntitiesAroundPoint(origin, radius); - if (entities.contains(player)) + if (entities.contains(player)) { entities.remove(player); + } for (Entity entity : entities) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "WallOfFire", entity.getLocation())) + if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) { continue; + } for (Block block : blocks) { - if (entity.getLocation().distance(block.getLocation()) <= 1.5) { + if (entity.getLocation().distanceSquared(block.getLocation()) <= 1.5 * 1.5) { affect(entity); break; } @@ -136,49 +122,15 @@ public class WallOfFire implements ConfigLoadable { private void display() { for (Block block : blocks) { - if (!EarthMethods.isTransparentToEarthbending(player, block)) { - continue; - } ParticleEffect.FLAME.display(block.getLocation(), 0.6F, 0.6F, 0.6F, 0, 3); ParticleEffect.SMOKE.display(block.getLocation(), 0.6F, 0.6F, 0.6F, 0, 1); - if (GeneralMethods.rand.nextInt(7) == 0) { - FireMethods.playFirebendingSound(block.getLocation()); + if (random.nextInt(7) == 0) { + playFirebendingSound(block.getLocation()); } } } - public long getCooldown() { - return cooldown; - } - - public int getDamage() { - return damage; - } - - public long getDamageinterval() { - return damageinterval; - } - - public long getDuration() { - return duration; - } - - public int getHeight() { - return height; - } - - public Player getPlayer() { - return player; - } - - public int getRange() { - return range; - } - - public int getWidth() { - return width; - } private void initializeBlocks() { Vector direction = player.getEyeLocation().getDirection(); @@ -190,113 +142,192 @@ public class WallOfFire implements ConfigLoadable { Vector orthoud = GeneralMethods.getOrthogonalVector(direction, 90, 1); orthoud = orthoud.normalize(); - double w = (double) width; - double h = (double) height; + double w = width; + double h = height; for (double i = -w; i <= w; i++) { for (double j = -h; j <= h; j++) { Location location = origin.clone().add(orthoud.clone().multiply(j)); location = location.add(ortholr.clone().multiply(i)); - if (GeneralMethods.isRegionProtectedFromBuild(player, "WallOfFire", location)) + if (GeneralMethods.isRegionProtectedFromBuild(this, location)) { continue; + } Block block = location.getBlock(); - if (!blocks.contains(block)) + if (!blocks.contains(block)) { blocks.add(block); + } } } - - } - - public boolean progress() { - time = System.currentTimeMillis(); - - if (time - starttime > cooldown) { - remove(); - return false; - } - - if (!active) - return false; - - if (time - starttime > duration) { - active = false; - return false; - } - - if (time - starttime > intervaltick * interval) { - intervaltick++; - display(); - } - - if (time - starttime > damagetick * damageinterval) { - damagetick++; - damage(); - } - return true; - } - - public static void progressAll() { - for (WallOfFire ability : instances.values()) { - ability.progress(); - } - } - - public void remove() { - instances.remove(player); - } - - public static void removeAll() { - for (WallOfFire ability : instances.values()) { - ability.remove(); - } } @Override - public void reloadVariables() { - RANGE = config.get().getInt("Abilities.Fire.WallOfFire.Range"); - HEIGHT = config.get().getInt("Abilities.Fire.WallOfFire.Height"); - WIDTH = config.get().getInt("Abilities.Fire.WallOfFire.Width"); - DURATION = config.get().getLong("Abilities.Fire.WallOfFire.Duration"); - DAMAGE = config.get().getInt("Abilities.Fire.WallOfFire.Damage"); - COOLDOWN = config.get().getLong("Abilities.Fire.WallOfFire.Cooldown"); - DAMAGE_INTERVAL = config.get().getLong("Abilities.Fire.WallOfFire.Interval"); - FIRETICKS = config.get().getDouble("Abilities.Fire.WallOfFire.FireTicks"); - range = RANGE; - height = HEIGHT; - width = WIDTH; - duration = DURATION; - damage = DAMAGE; - cooldown = COOLDOWN; - damageinterval = DAMAGE_INTERVAL; + public void progress() { + time = System.currentTimeMillis(); + + if (time - startTime > cooldown) { + remove(); + return; + } else if (!active) { + return; + } else if (time - startTime > duration) { + active = false; + return; + } + + if (time - startTime > intervalTick * interval) { + intervalTick++; + display(); + } + + if (time - startTime > damageTick * damageInterval) { + damageTick++; + damage(); + } } - public void setCooldown(long cooldown) { - this.cooldown = cooldown; - if (player != null) - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("WallOfFire", cooldown); + @Override + public String getName() { + return "WallOfFire"; } - public void setDamage(int damage) { - this.damage = damage; + @Override + public Location getLocation() { + return origin; } - public void setDamageinterval(long damageinterval) { - this.damageinterval = damageinterval; + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return false; } - public void setDuration(long duration) { - this.duration = duration; + @Override + public boolean isHarmlessAbility() { + return false; } - public void setHeight(int height) { - this.height = height; + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public int getDamageTick() { + return damageTick; + } + + public void setDamageTick(int damageTick) { + this.damageTick = damageTick; + } + + public int getIntervalTick() { + return intervalTick; + } + + public void setIntervalTick(int intervalTick) { + this.intervalTick = intervalTick; + } + + public int getRange() { + return range; } public void setRange(int range) { this.range = range; } + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + public void setWidth(int width) { this.width = width; } + + public int getDamage() { + return damage; + } + + public void setDamage(int damage) { + this.damage = damage; + } + + public long getDamageInterval() { + return damageInterval; + } + + public void setDamageInterval(long damageInterval) { + this.damageInterval = damageInterval; + } + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public double getFireTicks() { + return fireTicks; + } + + public void setFireTicks(double fireTicks) { + this.fireTicks = fireTicks; + } + + public double getMaxAngle() { + return maxAngle; + } + + public void setMaxAngle(double maxAngle) { + this.maxAngle = maxAngle; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public List getBlocks() { + return blocks; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/object/HorizontalVelocityTracker.java b/src/com/projectkorra/projectkorra/object/HorizontalVelocityTracker.java index fbef8570..5a43a6d1 100644 --- a/src/com/projectkorra/projectkorra/object/HorizontalVelocityTracker.java +++ b/src/com/projectkorra/projectkorra/object/HorizontalVelocityTracker.java @@ -3,10 +3,9 @@ package com.projectkorra.projectkorra.object; import com.projectkorra.projectkorra.Element; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.SubElement; -import com.projectkorra.projectkorra.earthbending.EarthMethods; +import com.projectkorra.projectkorra.ability.ElementalAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; import com.projectkorra.projectkorra.event.HorizontalVelocityChangeEvent; -import com.projectkorra.projectkorra.waterbending.WaterMethods; import org.bukkit.Location; import org.bukkit.block.Block; @@ -35,11 +34,10 @@ public class HorizontalVelocityTracker { private Location impactLocation; private String abil; private Element e; - private SubElement sub; public static String[] abils = {"AirBlast", "AirBurst", "AirSuction", "Bloodbending"}; - public HorizontalVelocityTracker(Entity e, Player instigator, long delay, String ability, Element element, SubElement se) { + public HorizontalVelocityTracker(Entity e, Player instigator, long delay, String ability, Element element) { if (!ProjectKorra.plugin.getConfig().getBoolean("Properties.HorizontalCollisionPhysics.Enabled")) return; @@ -54,7 +52,6 @@ public class HorizontalVelocityTracker { this.delay = delay; abil = ability; this.e = element; - sub = se; update(); instances.put(entity, this); } @@ -77,7 +74,7 @@ public class HorizontalVelocityTracker { List blocks = GeneralMethods.getBlocksAroundPoint(entity.getLocation(), 1.5); for (Block b : blocks) { - if (WaterMethods.isWater(b)) { + if (WaterAbility.isWater(b)) { remove(); return; } @@ -88,9 +85,9 @@ public class HorizontalVelocityTracker { impactLocation = entity.getLocation(); for (Block b : blocks) { if (GeneralMethods.isSolid(b) && (entity.getLocation().getBlock().getRelative(BlockFace.EAST, 1).equals(b) || entity.getLocation().getBlock().getRelative(BlockFace.NORTH, 1).equals(b) || entity.getLocation().getBlock().getRelative(BlockFace.WEST, 1).equals(b) || entity.getLocation().getBlock().getRelative(BlockFace.SOUTH, 1).equals(b))) { - if (!EarthMethods.isTransparentToEarthbending(instigator, b)) { + if (!ElementalAbility.isTransparentToEarthbending(instigator, b)) { hasBeenDamaged = true; - ProjectKorra.plugin.getServer().getPluginManager().callEvent(new HorizontalVelocityChangeEvent(entity, instigator, lastVelocity, thisVelocity, diff, launchLocation, impactLocation, abil, e, sub)); + ProjectKorra.plugin.getServer().getPluginManager().callEvent(new HorizontalVelocityChangeEvent(entity, instigator, lastVelocity, thisVelocity, diff, launchLocation, impactLocation, abil, e)); remove(); return; } diff --git a/src/com/projectkorra/projectkorra/object/Preset.java b/src/com/projectkorra/projectkorra/object/Preset.java index ba2d46c2..b6f55094 100644 --- a/src/com/projectkorra/projectkorra/object/Preset.java +++ b/src/com/projectkorra/projectkorra/object/Preset.java @@ -1,17 +1,10 @@ package com.projectkorra.projectkorra.object; import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.configuration.ConfigManager; +import com.projectkorra.projectkorra.ability.CoreAbility; import com.projectkorra.projectkorra.storage.DBConnection; - - - - - -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; @@ -37,8 +30,6 @@ public class Preset { * presets}, keyed to their UUID */ public static ConcurrentHashMap> presets = new ConcurrentHashMap>(); - public static FileConfiguration config = ConfigManager.presetConfig.get(); - public static HashMap> externalPresets = new HashMap>(); static String loadQuery = "SELECT * FROM pk_presets WHERE uuid = ?"; static String loadNameQuery = "SELECT * FROM pk_presets WHERE uuid = ? AND name = ?"; static String deleteQuery = "DELETE FROM pk_presets WHERE uuid = ? AND name = ?"; @@ -46,9 +37,9 @@ public class Preset { static String updateQuery1 = "UPDATE pk_presets SET slot"; static String updateQuery2 = " = ? WHERE uuid = ? AND name = ?"; - private UUID uuid; - private HashMap abilities; - private String name; + UUID uuid; + HashMap abilities; + String name; /** * Creates a new {@link Preset} @@ -85,7 +76,6 @@ public class Preset { */ public static void loadPresets(final Player player) { new BukkitRunnable() { - @SuppressWarnings("unchecked") @Override public void run() { UUID uuid = player.getUniqueId(); @@ -98,13 +88,13 @@ public class Preset { if (rs.next()) { // Presets exist. int i = 0; do { - HashMap abilities = (HashMap) new HashMap().clone(); + HashMap moves = new HashMap(); for (int total = 1; total <= 9; total++) { String slot = rs.getString("slot" + total); if (slot != null) - abilities.put(total, slot); + moves.put(total, slot); } - new Preset(uuid, rs.getString("name"), abilities); + new Preset(uuid, rs.getString("name"), moves); i++; } while (rs.next()); @@ -117,16 +107,6 @@ public class Preset { } }.runTaskAsynchronously(ProjectKorra.plugin); } - - /** - * Reload a Player's Presets from those stored in memory. - * - * @param player The Player who's Presets should be unloaded - */ - public static void reloadPreset(Player player) { - unloadPreset(player); - loadPresets(player); - } /** * Binds the abilities from a Preset for the given Player. @@ -135,19 +115,28 @@ public class Preset { * @param name The name of the Preset that should be bound * @return True if all abilities were successfully bound, or false otherwise */ - public static boolean bindPreset(Player player, Preset preset) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer == null) { + @SuppressWarnings("unchecked") + public static boolean bindPreset(Player player, String name) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) return false; - } - if (!presets.containsKey(player.getUniqueId())) { + if (!presets.containsKey(player.getUniqueId())) return false; + HashMap abilities = null; + for (Preset preset : presets.get(player.getUniqueId())) { + if (preset.name.equalsIgnoreCase(name)) { // We found it + abilities = (HashMap) preset.abilities.clone(); + } } - @SuppressWarnings("unchecked") - HashMap abilities = (HashMap) preset.abilities.clone(); + if (abilities == null) { + + } + boolean boundAll = true; for (int i = 1; i <= 9; i++) { - if (!GeneralMethods.canBind(player.getName(), abilities.get(i))) { + String abilName = abilities.get(i); + CoreAbility coreAbil = CoreAbility.getAbility(abilName); + if (coreAbil != null && !bPlayer.canBind(coreAbil)) { abilities.remove(i); boundAll = false; } @@ -164,14 +153,12 @@ public class Preset { * @return true if the Preset exists, false otherwise */ public static boolean presetExists(Player player, String name) { - if (!presets.containsKey(player.getUniqueId())) { + if (!presets.containsKey(player.getUniqueId())) return false; - } boolean exists = false; for (Preset preset : presets.get(player.getUniqueId())) { - if (preset.name.equalsIgnoreCase(name)) { + if (preset.name.equalsIgnoreCase(name)) exists = true; - } } return exists; } @@ -184,37 +171,14 @@ public class Preset { * @return The Preset, if it exists, or null otherwise */ public static Preset getPreset(Player player, String name) { - if (!presets.containsKey(player.getUniqueId())) { + if (!presets.containsKey(player.getUniqueId())) return null; - } for (Preset preset : presets.get(player.getUniqueId())) { - if (preset.name.equalsIgnoreCase(name)) { + if (preset.name.equalsIgnoreCase(name)) return preset; - } } return null; - } - - public static void loadExternalPresets() { - HashMap> presets = new HashMap>(); - for(String name : config.getKeys(false)) { - if (!presets.containsKey(name)) if (!config.getStringList(name).isEmpty() && config.getStringList(name).size() <= 9) { - presets.put(name.toLowerCase(), (ArrayList) config.getStringList(name)); - } - } - externalPresets = presets; - } - - public static boolean externalPresetExists(String name) { - for (String preset : externalPresets.keySet()) { - if (name.equalsIgnoreCase(preset)) { - return true; - } - } - return false; - } - /** * Gets the contents of a Preset for the specified Player. @@ -234,34 +198,6 @@ public class Preset { } return null; } - - @SuppressWarnings("unchecked") - public static boolean bindExternalPreset(Player player, String name) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - boolean boundAll = true; - int slot = 0; - - HashMap abilities = (HashMap) new HashMap().clone(); - - if (externalPresetExists(name.toLowerCase())) { - for (String ability : externalPresets.get(name.toLowerCase())) { - slot++; - if (GeneralMethods.abilityExists(ability)) { - abilities.put(slot, GeneralMethods.getAbility(ability)); - } - } - - for (int i = 1; i <= 9; i++) { - if (!GeneralMethods.canBend(player.getName(), abilities.get(i))) { - abilities.remove(i); - boundAll = false; - } - } - bPlayer.setAbilities(abilities); - return boundAll; - } - return false; - } /** * Deletes the Preset from the database. @@ -291,7 +227,7 @@ public class Preset { /** * Saves the Preset to the database. */ - public void save(final Player player) { + public void save() { try { PreparedStatement ps = DBConnection.sql.getConnection().prepareStatement(loadNameQuery); ps.setString(1, uuid.toString()); @@ -326,19 +262,5 @@ public class Preset { } }.runTaskAsynchronously(ProjectKorra.plugin); } - - new BukkitRunnable() { - - @Override - public void run() { - try { - Thread.sleep(1500); - reloadPreset(player); - } - catch (InterruptedException e) { - e.printStackTrace(); - } - } - }.runTaskAsynchronously(ProjectKorra.plugin); } } diff --git a/src/com/projectkorra/projectkorra/util/AbilityLoadable.java b/src/com/projectkorra/projectkorra/util/AbilityLoadable.java deleted file mode 100644 index 90bed431..00000000 --- a/src/com/projectkorra/projectkorra/util/AbilityLoadable.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.projectkorra.projectkorra.util; - -public class AbilityLoadable implements Cloneable { - - private final String name; - - public AbilityLoadable(String name) { - this.name = name; - } - - @Override - public AbilityLoadable clone() { - try { - return (AbilityLoadable) super.clone(); - } - catch (CloneNotSupportedException e) { - e.printStackTrace(); - } - return null; - } - - public LoadResult init() { - return new LoadResult(); - } - - public boolean isInternal() { - return false; - } - - public final String getName() { - return name; - } - - public static final class LoadResult { - private final Result result; - private final String reason; - - public LoadResult() { - this(Result.SUCCESS, ""); - } - - public LoadResult(String failReason) { - this(Result.FAILURE, failReason); - } - - public LoadResult(Result result, String reason) { - this.result = result; - this.reason = reason; - } - - public String getReason() { - return reason; - } - - public Result getResult() { - return result; - } - - public enum Result { - FAILURE, SUCCESS - } - } -} diff --git a/src/com/projectkorra/projectkorra/util/AbilityLoader.java b/src/com/projectkorra/projectkorra/util/AbilityLoader.java deleted file mode 100644 index 7b64e878..00000000 --- a/src/com/projectkorra/projectkorra/util/AbilityLoader.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.projectkorra.projectkorra.util; - -import com.projectkorra.projectkorra.event.AbilityLoadEvent; -import com.projectkorra.projectkorra.util.AbilityLoadable.LoadResult; -import com.projectkorra.projectkorra.util.AbilityLoadable.LoadResult.Result; - -import org.bukkit.event.Listener; -import org.bukkit.plugin.Plugin; - -import java.io.BufferedReader; -import java.io.File; -import java.io.InputStreamReader; -import java.lang.reflect.Constructor; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.List; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class AbilityLoader implements Listener { - - private final Plugin plugin; - - private final File dir; - private ClassLoader loader; - private final Object[] paramTypes; - private final Class[] ctorParams; - - private final ArrayList files; - private final List loadables; - - public AbilityLoader(Plugin plugin, File dir, Object... paramTypes) { - this.plugin = plugin; - this.dir = dir; - this.paramTypes = paramTypes; - this.files = new ArrayList(); - this.loadables = new ArrayList(0); - - for (File f : dir.listFiles(new FileExtensionFilter(".jar"))) { - files.add(f); - } - - List> constructorParams = new ArrayList>(); - - for (Object paramType : paramTypes) - constructorParams.add(paramType.getClass()); - - this.ctorParams = constructorParams.toArray(new Class[0]); - - List urls = new ArrayList(); - - for (File file : files) { - try { - urls.add(file.toURI().toURL()); - } - catch (MalformedURLException e) { - e.printStackTrace(); - } - } - - this.loader = URLClassLoader.newInstance(urls.toArray(new URL[0]), plugin.getClass().getClassLoader()); - } - - public Logger getLogger() { - return plugin.getLogger(); - } - - @SuppressWarnings("unchecked") - public final List load(Class classType) { - for (File file : files) { - try (final JarFile jarFile = new JarFile(file)) { - String mainClass = null; - - if (jarFile.getEntry("path.yml") != null) { - JarEntry element = jarFile.getJarEntry("path.yml"); - BufferedReader reader = new BufferedReader(new InputStreamReader(jarFile.getInputStream(element))); - mainClass = reader.readLine().substring(12); - } - - if (mainClass != null) { - Class clazz = Class.forName(mainClass, true, loader); - - if (clazz != null) { - Class loadableClass = clazz.asSubclass(classType); - Constructor ctor = loadableClass.getConstructor(ctorParams); - T loadable = (T) ctor.newInstance(paramTypes); - - LoadResult result = loadable.init(); - - if (result.getResult().equals(Result.SUCCESS)) { - loadables.add(loadable); - AbilityLoadEvent event = new AbilityLoadEvent(plugin, loadable, jarFile); - plugin.getServer().getPluginManager().callEvent(event); - continue; - } - - String reason = result.getReason(); - - if (reason != null && !reason.isEmpty()) { - getLogger().log(Level.INFO, "The JAR file " + file.getName() + " was unable to load because: " + reason); - } - } else { - jarFile.close(); - throw new ClassNotFoundException(); - } - } else { - jarFile.close(); - throw new ClassNotFoundException(); - } - } - catch (ClassCastException e) { - e.printStackTrace(); - getLogger().log(Level.WARNING, "The JAR file " + file.getPath() + " is in the wrong directory"); - getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load"); - } - catch (ClassNotFoundException e) { - e.printStackTrace(); - getLogger().log(Level.WARNING, "Invalid path.yml"); - getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load."); - } - catch (Exception e) { - e.printStackTrace(); - getLogger().log(Level.WARNING, "Unknown cause"); - getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load"); - } - } - - return loadables; - } - - public List reload(Class classType) { - unload(); - - List urls = new ArrayList(); - files.clear(); - for (String loadableFile : dir.list()) { - if (loadableFile.endsWith(".jar")) { - File file = new File(dir, loadableFile); - files.add(file); - try { - urls.add(file.toURI().toURL()); - } - catch (MalformedURLException e) { - e.printStackTrace(); - } - } - } - - this.loader = URLClassLoader.newInstance(urls.toArray(new URL[urls.size()]), plugin.getClass().getClassLoader()); - - return load(classType); - } - - public void unload() { - loadables.clear(); - } -} diff --git a/src/com/projectkorra/projectkorra/util/ActionBar.java b/src/com/projectkorra/projectkorra/util/ActionBar.java deleted file mode 100644 index e985c21e..00000000 --- a/src/com/projectkorra/projectkorra/util/ActionBar.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.projectkorra.projectkorra.util; - -import org.bukkit.entity.Player; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -import com.projectkorra.projectkorra.util.ReflectionHandler.PackageType; - -public class ActionBar { - - private static boolean initialised = false; - private static Constructor chatSer; - private static Constructor packetChat; - private static Method getHandle; - private static Field playerConnection; - private static Method sendPacket; - - static { - try { - chatSer = ReflectionHandler.getConstructor(PackageType.MINECRAFT_SERVER.getClass("ChatComponentText"), String.class); - packetChat = PackageType.MINECRAFT_SERVER.getClass("PacketPlayOutChat").getConstructor(PackageType.MINECRAFT_SERVER.getClass("IChatBaseComponent"), byte.class); - getHandle = ReflectionHandler.getMethod("CraftPlayer", PackageType.CRAFTBUKKIT_ENTITY, "getHandle"); - playerConnection = ReflectionHandler.getField("EntityPlayer", PackageType.MINECRAFT_SERVER, false, "playerConnection"); - sendPacket = ReflectionHandler.getMethod(playerConnection.getType(), "sendPacket", PackageType.MINECRAFT_SERVER.getClass("Packet")); - initialised = true; - } - catch (ReflectiveOperationException e) { - initialised = false; - } - } - - public static boolean isInitialised() { - return initialised; - } - - public static boolean sendActionBar(String message, Player... player) { - if (!initialised) { - return false; - } - try { - Object o = chatSer.newInstance(message); - Object packet = packetChat.newInstance(o, (byte) 2); - sendTo(packet, player); - } - catch (ReflectiveOperationException e) { - e.printStackTrace(); - initialised = false; - } - return initialised; - } - - private static void sendTo(Object packet, Player... player) throws ReflectiveOperationException { - for (Player p : player) { - Object entityplayer = getHandle.invoke(p); - Object PlayerConnection = playerConnection.get(entityplayer); - sendPacket.invoke(PlayerConnection, packet); - } - } -} diff --git a/src/com/projectkorra/projectkorra/util/BlockCacheElement.java b/src/com/projectkorra/projectkorra/util/BlockCacheElement.java new file mode 100644 index 00000000..d8066ca8 --- /dev/null +++ b/src/com/projectkorra/projectkorra/util/BlockCacheElement.java @@ -0,0 +1,61 @@ +package com.projectkorra.projectkorra.util; + +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +public class BlockCacheElement { + private Player player; + private Block block; + private String ability; + private boolean allowed; + private long time; + + public BlockCacheElement(Player player, Block block, String ability, boolean allowed, long time) { + this.player = player; + this.block = block; + this.ability = ability; + this.allowed = allowed; + this.time = time; + } + + public String getAbility() { + return ability; + } + + public Block getBlock() { + return block; + } + + public Player getPlayer() { + return player; + } + + public long getTime() { + return time; + } + + public boolean isAllowed() { + return allowed; + } + + public void setAbility(String ability) { + this.ability = ability; + } + + public void setAllowed(boolean allowed) { + this.allowed = allowed; + } + + public void setBlock(Block block) { + this.block = block; + } + + public void setPlayer(Player player) { + this.player = player; + } + + public void setTime(long time) { + this.time = time; + } + +} \ No newline at end of file diff --git a/src/com/projectkorra/projectkorra/util/BlockSource.java b/src/com/projectkorra/projectkorra/util/BlockSource.java index 143a119f..0f96ed7c 100644 --- a/src/com/projectkorra/projectkorra/util/BlockSource.java +++ b/src/com/projectkorra/projectkorra/util/BlockSource.java @@ -1,17 +1,17 @@ package com.projectkorra.projectkorra.util; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.waterbending.WaterMethods; +import com.projectkorra.projectkorra.BendingPlayer; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.EarthAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.configuration.ConfigManager; import org.bukkit.Location; import org.bukkit.block.Block; +import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; /** * BlockSource is a class that handles water and earth bending sources. When a @@ -29,13 +29,13 @@ public class BlockSource { * @author kingbirdy */ public static enum BlockSourceType { - WATER, ICE, PLANT, EARTH, METAL, LAVA, SAND + WATER, ICE, PLANT, EARTH, METAL, LAVA } - public static List randomBlocks = new ArrayList(); private static HashMap>> playerSources = new HashMap>>(); - private static final boolean tempblock = ProjectKorra.plugin.getConfig().getBoolean("Properties.Water.CanBendFromBentBlocks"); + private static FileConfiguration config = ConfigManager.defaultConfig.get(); // The player should never need to grab source blocks from farther than this. + private static double MAX_RANGE = config.getDouble("Abilities.Water.WaterManipulation.Range"); /** * Updates all of the player's sources. @@ -43,37 +43,40 @@ public class BlockSource { * @param player the player performing the bending. * @param clickType either {@link ClickType}.SHIFT_DOWN or ClickType.LEFT_CLICK */ - public static void update(Player player, int selectRange, ClickType clickType) { - String boundAbil = GeneralMethods.getBoundAbility(player); - if (boundAbil == null) { + public static void update(Player player, ClickType clickType) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { return; } - if (WaterMethods.isWaterAbility(boundAbil)) { - Block waterBlock = WaterMethods.getWaterSourceBlock(player, selectRange, true, true, true); + + CoreAbility coreAbil = bPlayer.getBoundAbility(); + if (coreAbil == null) { + return; + } + + if (coreAbil instanceof WaterAbility) { + Block waterBlock = WaterAbility.getWaterSourceBlock(player, MAX_RANGE, true); if (waterBlock != null) { putSource(player, waterBlock, BlockSourceType.WATER, clickType); - if (WaterMethods.isPlant(waterBlock)) { + if (WaterAbility.isPlant(waterBlock)) { putSource(player, waterBlock, BlockSourceType.PLANT, clickType); } - if (WaterMethods.isIcebendable(waterBlock)) { + if (WaterAbility.isIcebendable(waterBlock)) { putSource(player, waterBlock, BlockSourceType.ICE, clickType); } } - } else if (EarthMethods.isEarthAbility(boundAbil)) { - Block earthBlock = EarthMethods.getEarthSourceBlock(player, selectRange, true, true, true); + } else if (coreAbil instanceof EarthAbility) { + Block earthBlock = EarthAbility.getEarthSourceBlock(player, null, MAX_RANGE); if (earthBlock != null) { putSource(player, earthBlock, BlockSourceType.EARTH, clickType); - if (EarthMethods.isSand(earthBlock)) { - putSource(player, earthBlock, BlockSourceType.SAND, clickType); - } - if (EarthMethods.isMetal(earthBlock)) { + if (EarthAbility.isMetal(earthBlock)) { putSource(player, earthBlock, BlockSourceType.METAL, clickType); } } // We need to handle lava differently, since getEarthSourceBlock doesn't account for // lava. We should only select the lava source if it is closer than the earth. - Block lavaBlock = EarthMethods.getLavaSourceBlock(player, selectRange); + Block lavaBlock = EarthAbility.getLavaSourceBlock(player, MAX_RANGE); double earthDist = earthBlock != null ? earthBlock.getLocation().distanceSquared(player.getLocation()) : Double.MAX_VALUE; double lavaDist = lavaBlock != null ? lavaBlock.getLocation().distanceSquared(player.getLocation()) : Double.MAX_VALUE; if (lavaBlock != null && lavaDist <= earthDist) { @@ -131,7 +134,7 @@ public class BlockSource { * either ClickType.SHIFT_DOWN or ClickType.LEFT_CLICK. * @return a valid bendable block, or null if none was found. */ - public static BlockSourceInformation getValidBlockSourceInformation(Player player, int range, BlockSourceType sourceType, ClickType clickType) { + public static BlockSourceInformation getValidBlockSourceInformation(Player player, double range, BlockSourceType sourceType, ClickType clickType) { BlockSourceInformation blockInfo = getBlockSourceInformation(player, sourceType, clickType); return isStillAValidSource(blockInfo, range, clickType) ? blockInfo : null; } @@ -146,55 +149,67 @@ public class BlockSource { * either ClickType.SHIFT_DOWN or ClickType.LEFT_CLICK. * @return a valid bendable block, or null if none was found. */ - public static Block getDynamicEarthSourceBlock(Player player, int autoRange, int selectRange, BlockSourceType sourceType, ClickType clickType, boolean auto, boolean dynamic, boolean earth, boolean sand, boolean metal) { - update(player, selectRange, clickType); - BlockSourceInformation info = getValidBlockSourceInformation(player, selectRange, sourceType, clickType); - if (info != null) { - Block tempBlock = info.getBlock(); - if (EarthMethods.isEarth(tempBlock) && earth) { - return tempBlock; - } - if (EarthMethods.isSand(tempBlock) && sand) { - return tempBlock; - } - if (EarthMethods.isMetal(tempBlock) && metal) { - return tempBlock; - } - } - if (info == null && dynamic) { - return null; - } - return EarthMethods.getEarthSourceBlock(player, selectRange, earth, sand, metal); + public static Block getSourceBlock(Player player, double range, BlockSourceType sourceType, ClickType clickType) { + BlockSourceInformation info = getValidBlockSourceInformation(player, range, sourceType, clickType); + return info != null ? info.getBlock() : null; } - + /** - * Access a specific type of source block depending on a range and {@link ClickType}. + * Attempts to access a Water bendable block that was recently shifted or + * clicked on by the player. * * @param player the player that is trying to bend. * @param range the maximum range to access the block. - * @param sourceType the elemental type of block to find. - * @param clickType the action that was performed to access the source, - * either ClickType.SHIFT_DOWN or ClickType.LEFT_CLICK. - * @return a valid bendable block, or null if none was found. + * @return a valid Water bendable block, or null if none was found. */ - - @SuppressWarnings("deprecation") - public static Block getDynamicWaterSourceBlock(Player player, int autoRange, int selectRange, BlockSourceType sourceType, ClickType clickType, boolean auto, boolean dynamic, boolean water, boolean ice, boolean plant) { - update(player, selectRange, clickType); - BlockSourceInformation info = getValidBlockSourceInformation(player, selectRange, sourceType, clickType); - if (info != null && dynamic) { - if (WaterMethods.isWater(info.getBlock()) && info.getBlock().getState().getRawData() == 0x0 && water) { - return info.getBlock(); - } else if (WaterMethods.isIcebendable(info.getBlock()) && ice) { - return info.getBlock(); - } else if (WaterMethods.isPlant(info.getBlock()) && plant) { - return info.getBlock(); - } - } - if (info == null && dynamic) { - return null; - } - return WaterMethods.getWaterSourceBlock(player, selectRange, water, ice, plant); + public static Block getWaterSourceBlock(Player player, double range) { + return getWaterSourceBlock(player, range, ClickType.LEFT_CLICK); + } + + /** + * Attempts to access a Water bendable block that was recently shifted or + * clicked on by the player. + * + * @param player the player that is trying to bend. + * @param range the maximum range to access the block. + * @param clickType the action that was performed to access the source, + * either {@link ClickType}.SHIFT_DOWN or ClickType.LEFT_CLICK. + * @return a valid Water bendable block, or null if none was found. + */ + public static Block getWaterSourceBlock(Player player, double range, ClickType clickType) { + return getWaterSourceBlock(player, range, clickType, true, true, true); + } + + /** + * Attempts to access a Water bendable block that was recently shifted or + * clicked on by the player. + * + * @param player the player that is trying to bend. + * @param range the maximum range to access the block. + * @param allowWater true if water blocks are allowed. + * @param allowIce true if ice blocks are allowed. + * @param allowPlant true if plant blocks are allowed. + * @return a valid Water bendable block, or null if none was found. + */ + public static Block getWaterSourceBlock(Player player, double range, boolean allowWater, boolean allowIce, boolean allowPlant) { + return getWaterSourceBlock(player, range, ClickType.LEFT_CLICK, allowWater, allowIce, allowPlant); + } + + /** + * Attempts to access a Water bendable block that was recently shifted or + * clicked on by the player. + * + * @param player the player that is trying to bend. + * @param range the maximum range to access the block. + * @param clickType the action that was performed to access the source, + * either {@link ClickType}.SHIFT_DOWN or ClickType.LEFT_CLICK. + * @param allowWater true if water blocks are allowed. + * @param allowIce true if ice blocks are allowed. + * @param allowPlant true if plant blocks are allowed. + * @return a valid Water bendable block, or null if none was found. + */ + public static Block getWaterSourceBlock(Player player, double range, ClickType clickType, boolean allowWater, boolean allowIce, boolean allowPlant) { + return getWaterSourceBlock(player, range, clickType, allowWater, allowIce, allowPlant, true); } /** @@ -212,28 +227,42 @@ public class BlockSource { * that may have been created by a WaterBottle. * @return a valid Water bendable block, or null if none was found. */ - public static Block getWaterSourceBlock(Player player, int autoRange, int selectRange, ClickType clickType, boolean auto, boolean dynamic, boolean bottles, boolean water, boolean ice, boolean plant) { + public static Block getWaterSourceBlock(Player player, double range, ClickType clickType, boolean allowWater, boolean allowIce, boolean allowPlant, boolean allowWaterBottles) { Block sourceBlock = null; - if(dynamic) - sourceBlock = BlockSource.getDynamicWaterSourceBlock(player, autoRange, selectRange, BlockSourceType.WATER, clickType, auto, dynamic, water, ice, plant); - else - sourceBlock = WaterMethods.getWaterSourceBlock(player, selectRange, water, ice, plant); - if (sourceBlock == null) { - if(bottles) { + if (allowWaterBottles) { // Check the block in front of the player's eyes, it may have been created by a // WaterBottle. - sourceBlock = WaterMethods.getWaterSourceBlock(player, selectRange, water, ice, plant); - } - if (auto && (sourceBlock == null || sourceBlock.getLocation().distance(player.getEyeLocation()) > autoRange)) { - sourceBlock = WaterMethods.getRandomWaterBlock(player, player.getLocation(), autoRange, water, ice, plant); + sourceBlock = WaterAbility.getWaterSourceBlock(player, range, allowPlant); + if (sourceBlock == null || sourceBlock.getLocation().distance(player.getEyeLocation()) > 3) { + sourceBlock = null; } } - if(sourceBlock != null && TempBlock.isTempBlock(sourceBlock) && !tempblock) { - return null; + if (allowWater && sourceBlock == null) { + sourceBlock = getSourceBlock(player, range, BlockSourceType.WATER, clickType); + } + if (allowIce && sourceBlock == null) { + sourceBlock = getSourceBlock(player, range, BlockSourceType.ICE, clickType); + } + if (allowPlant && sourceBlock == null) { + sourceBlock = getSourceBlock(player, range, BlockSourceType.PLANT, clickType); } return sourceBlock; } + /** + * Attempts to access a Earth bendable block that was recently shifted or + * clicked on by the player. + * + * @param player the player that is trying to bend. + * @param range the maximum range to access the block. + * @param clickType the action that was performed to access the source, + * either {@link ClickType}.SHIFT_DOWN or ClickType.LEFT_CLICK. + * @return a valid Earth bendable block, or null if none was found. + */ + public static Block getEarthSourceBlock(Player player, double range, ClickType clickType) { + return getEarthSourceBlock(player, range, clickType, true); + } + /** * Attempts to access a Earth bendable block that was recently shifted or * clicked on by the player. @@ -247,32 +276,42 @@ public class BlockSource { * block. * @return a valid Earth bendable block, or null if none was found. */ - public static Block getEarthSourceBlock(Player player, int autoRange, int selectRange, ClickType clickType, boolean auto, boolean dynamic, boolean earth, boolean sand, boolean metal) { - Block sourceBlock = null; - if(dynamic) - sourceBlock = getDynamicEarthSourceBlock(player, autoRange, selectRange, BlockSourceType.EARTH, clickType, auto, dynamic, earth, sand, metal); - else - sourceBlock = EarthMethods.getEarthSourceBlock(player, selectRange, earth, sand, metal); - if (sourceBlock == null) { + public static Block getEarthSourceBlock(Player player, double range, ClickType clickType, boolean allowNearbySubstitute) { + Block sourceBlock = getSourceBlock(player, range, BlockSourceType.EARTH, clickType); + if (sourceBlock == null && allowNearbySubstitute) { BlockSourceInformation blockInfo = getBlockSourceInformation(player, BlockSourceType.EARTH, clickType); - if (dynamic) { - if (blockInfo != null) { - Block tempBlock = blockInfo.getBlock(); - if (tempBlock == null) { - return null; - } - Location loc = tempBlock.getLocation(); - sourceBlock = EarthMethods.getNearbyEarthBlock(loc, autoRange, 2, earth, sand, metal); - } + if (blockInfo == null) { + return null; } - if (auto && (sourceBlock == null || !sourceBlock.getLocation().getWorld().equals(player.getWorld()) || Math.abs(sourceBlock.getLocation().distance(player.getEyeLocation())) > selectRange)) { - return EarthMethods.getRandomEarthBlock(player, player.getLocation(), autoRange, earth, sand, metal); + Block tempBlock = blockInfo.getBlock(); + if (tempBlock == null) { + return null; + } + + Location loc = tempBlock.getLocation(); + sourceBlock = EarthAbility.getNearbyEarthBlock(loc, 3, 3); + if (sourceBlock == null || !sourceBlock.getLocation().getWorld().equals(player.getWorld()) || Math.abs(sourceBlock.getLocation().distance(player.getEyeLocation())) > range || !EarthAbility.isEarthbendable(player, sourceBlock)) { + return null; } } return sourceBlock; } + /** + * Attempts to access a Lava bendable block that was recently shifted or + * clicked on by the player. + * + * @param player the player that is trying to bend. + * @param range the maximum range to access the block. + * @param clickType the action that was performed to access the source, + * either {@link ClickType}.SHIFT_DOWN or ClickType.LEFT_CLICK. + * @return a valid Lava bendable block, or null if none was found. + */ + public static Block getLavaSourceBlock(Player player, double range, ClickType clickType) { + return getSourceBlock(player, range, BlockSourceType.LAVA, clickType); + } + /** * Attempts to access a Lava bendable block or an Earth block that was * recently shifted or clicked on by the player. @@ -283,14 +322,14 @@ public class BlockSource { * either {@link ClickType}.SHIFT_DOWN or ClickType.LEFT_CLICK. * @return a valid Earth or Lava bendable block, or null if none was found. */ - public static Block getEarthOrLavaSourceBlock(Player player, int autoRange, int selectRange, ClickType clickType, boolean auto, boolean dynamic, boolean earth, boolean sand, boolean metal) { + public static Block getEarthOrLavaSourceBlock(Player player, double range, ClickType clickType) { /* * When Lava is selected as a source it automatically overrides the * previous Earth based source. Only one of these types can exist, so if * Lava exists then we know Earth is null. */ - Block earthBlock = getEarthSourceBlock(player, autoRange, selectRange, clickType, auto, dynamic, earth, sand, metal); - BlockSourceInformation lavaBlockInfo = getValidBlockSourceInformation(player, selectRange, BlockSourceType.LAVA, clickType); + Block earthBlock = getEarthSourceBlock(player, range, clickType); + BlockSourceInformation lavaBlockInfo = getValidBlockSourceInformation(player, range, BlockSourceType.LAVA, clickType); if (earthBlock != null) { return earthBlock; } else if (lavaBlockInfo != null) { @@ -308,7 +347,7 @@ public class BlockSource { * @param range the maximum bending range. * @return true if it is valid. */ - private static boolean isStillAValidSource(BlockSourceInformation info, int range, ClickType clickType) { + private static boolean isStillAValidSource(BlockSourceInformation info, double range, ClickType clickType) { if (info == null || info.getBlock() == null) { return false; } else if (info.getClickType() != clickType) { @@ -317,28 +356,19 @@ public class BlockSource { return false; } else if (Math.abs(info.getPlayer().getLocation().distance(info.getBlock().getLocation())) > range) { return false; - } else if (info.getSourceType() == BlockSourceType.WATER && !WaterMethods.isWaterbendable(info.getBlock(), info.getPlayer())) { + } else if (info.getSourceType() == BlockSourceType.WATER && !WaterAbility.isWaterbendable(info.getBlock(), info.getPlayer())) { return false; - } else if (info.getSourceType() == BlockSourceType.ICE && !WaterMethods.isIcebendable(info.getBlock())) { + } else if (info.getSourceType() == BlockSourceType.ICE && !WaterAbility.isIcebendable(info.getBlock())) { return false; - } else if (info.getSourceType() == BlockSourceType.PLANT && (!WaterMethods.isPlant(info.getBlock()) || !WaterMethods.isWaterbendable(info.getBlock(), info.getPlayer()))) { + } else if (info.getSourceType() == BlockSourceType.PLANT && (!WaterAbility.isPlant(info.getBlock()) || !WaterAbility.isWaterbendable(info.getBlock(), info.getPlayer()))) { return false; - } else if (info.getSourceType() == BlockSourceType.EARTH && !EarthMethods.isEarthbendable(info.getPlayer(), info.getBlock())) { + } else if (info.getSourceType() == BlockSourceType.EARTH && !EarthAbility.isEarthbendable(info.getPlayer(), info.getBlock())) { return false; - } else if (info.getSourceType() == BlockSourceType.SAND && !EarthMethods.isSand(info.getBlock())) { + } else if (info.getSourceType() == BlockSourceType.METAL && (!EarthAbility.isMetal(info.getBlock()) || !EarthAbility.isEarthbendable(info.getPlayer(), info.getBlock()))) { return false; - } else if (info.getSourceType() == BlockSourceType.METAL && (!EarthMethods.isMetal(info.getBlock()) || !EarthMethods.isEarthbendable(info.getPlayer(), info.getBlock()))) { - return false; - } else if (info.getSourceType() == BlockSourceType.LAVA && (!EarthMethods.isLava(info.getBlock()) || !EarthMethods.isLavabendable(info.getBlock(), info.getPlayer()))) { + } else if (info.getSourceType() == BlockSourceType.LAVA && (!EarthAbility.isLava(info.getBlock()) || !EarthAbility.isLavabendable(info.getBlock()))) { return false; } return true; } - - public static boolean isAuto(Block block) { - if (randomBlocks.contains(block)) { - return true; - } - return false; - } } diff --git a/src/com/projectkorra/projectkorra/util/Flight.java b/src/com/projectkorra/projectkorra/util/Flight.java index 7cf4c208..e37dfc3c 100644 --- a/src/com/projectkorra/projectkorra/util/Flight.java +++ b/src/com/projectkorra/projectkorra/util/Flight.java @@ -1,5 +1,6 @@ package com.projectkorra.projectkorra.util; +import com.projectkorra.projectkorra.ability.CoreAbility; import com.projectkorra.projectkorra.airbending.AirScooter; import com.projectkorra.projectkorra.airbending.AirSpout; import com.projectkorra.projectkorra.airbending.Tornado; @@ -13,6 +14,7 @@ import org.bukkit.GameMode; import org.bukkit.entity.Player; import java.util.ArrayList; +import java.util.HashSet; import java.util.concurrent.ConcurrentHashMap; public class Flight { @@ -61,28 +63,21 @@ public class Flight { } public static void handle() { - ArrayList players = new ArrayList(); - ArrayList newflyingplayers = new ArrayList(); - //ArrayList avatarstateplayers = new ArrayList(); - ArrayList airscooterplayers = new ArrayList(); - ArrayList waterspoutplayers = new ArrayList(); - ArrayList airspoutplayers = new ArrayList(); - ArrayList sandspoutplayers = new ArrayList(); + ArrayList players = new ArrayList<>(); + ArrayList newFlyingPlayers = new ArrayList(); + HashSet airScooterPlayers = CoreAbility.getPlayers(AirScooter.class); + HashSet waterSpoutPlayers = CoreAbility.getPlayers(WaterSpout.class); + HashSet airSpoutPlayers = CoreAbility.getPlayers(AirSpout.class); + HashSet sandSpoutPlayers = CoreAbility.getPlayers(SandSpout.class); - players.addAll(Tornado.getPlayers()); - // players.addAll(Speed.getPlayers()); - players.addAll(FireJet.getPlayers()); - players.addAll(Catapult.getPlayers()); - //avatarstateplayers = AvatarState.getPlayers(); - airscooterplayers = AirScooter.getPlayers(); - waterspoutplayers = WaterSpout.getPlayers(); - airspoutplayers = AirSpout.getPlayers(); - sandspoutplayers = SandSpout.getPlayers(); + players.addAll(CoreAbility.getPlayers(Tornado.class)); + players.addAll(CoreAbility.getPlayers(FireJet.class)); + players.addAll(CoreAbility.getPlayers(Catapult.class)); for (Player player : instances.keySet()) { Flight flight = instances.get(player); if (System.currentTimeMillis() <= flight.time + duration) { - if (airscooterplayers.contains(player) || waterspoutplayers.contains(player) || airspoutplayers.contains(player) || sandspoutplayers.contains(player)) { + if (airScooterPlayers.contains(player) || waterSpoutPlayers.contains(player) || airSpoutPlayers.contains(player) || sandSpoutPlayers.contains(player)) { continue; } if (Bloodbending.isBloodbended(player)) { @@ -96,7 +91,7 @@ public class Flight { player.setAllowFlight(true); if (player.getGameMode() != GameMode.CREATIVE) player.setFlying(false); - newflyingplayers.add(player); + newFlyingPlayers.add(player); continue; } if (flight.source == null) { diff --git a/src/com/projectkorra/projectkorra/util/RevertChecker.java b/src/com/projectkorra/projectkorra/util/RevertChecker.java index 68ed4846..11408593 100644 --- a/src/com/projectkorra/projectkorra/util/RevertChecker.java +++ b/src/com/projectkorra/projectkorra/util/RevertChecker.java @@ -1,8 +1,8 @@ package com.projectkorra.projectkorra.util; import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.EarthAbility; import com.projectkorra.projectkorra.configuration.ConfigManager; -import com.projectkorra.projectkorra.earthbending.EarthMethods; import org.bukkit.Chunk; import org.bukkit.Server; @@ -36,14 +36,14 @@ public class RevertChecker implements Runnable { public static void revertAirBlocks() { for (int ID : airRevertQueue.keySet()) { - EarthMethods.revertAirBlock(ID); + EarthAbility.revertAirBlock(ID); RevertChecker.airRevertQueue.remove(ID); } } public static void revertEarthBlocks() { for (Block block : earthRevertQueue.keySet()) { - EarthMethods.revertBlock(block); + EarthAbility.revertBlock(block); earthRevertQueue.remove(block); } } @@ -73,12 +73,11 @@ public class RevertChecker implements Runnable { if (config.getBoolean("Properties.Earth.RevertEarthbending")) { try { - if(plugin.isEnabled()) { returnFuture = plugin.getServer().getScheduler().callSyncMethod(plugin, new getOccupiedChunks(plugin.getServer())); ArrayList chunks = returnFuture.get(); Map earth = new HashMap(); - earth.putAll(EarthMethods.movedearth); + earth.putAll(EarthAbility.getMovedEarth()); for (Block block : earth.keySet()) { if (earthRevertQueue.containsKey(block)) @@ -94,7 +93,7 @@ public class RevertChecker implements Runnable { } Map air = new HashMap(); - air.putAll(EarthMethods.tempair); + air.putAll(EarthAbility.getTempAirLocations()); for (Integer i : air.keySet()) { if (airRevertQueue.containsKey(i)) @@ -109,7 +108,6 @@ public class RevertChecker implements Runnable { addToAirRevertQueue(i); } } - } } catch (Exception e) { e.printStackTrace(); diff --git a/src/com/projectkorra/projectkorra/util/Updater.java b/src/com/projectkorra/projectkorra/util/Updater.java index 02deed17..0cf84cbf 100644 --- a/src/com/projectkorra/projectkorra/util/Updater.java +++ b/src/com/projectkorra/projectkorra/util/Updater.java @@ -7,10 +7,8 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import java.io.IOException; -import java.net.SocketTimeoutException; import java.net.URL; import java.net.URLConnection; -import java.net.UnknownHostException; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -60,9 +58,9 @@ public class Updater { urlc.setRequestProperty("User-Agent", ""); // Must be used or face 403 urlc.setConnectTimeout(30000); // 30 second time out, throws SocketTimeoutException document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(urlc.getInputStream()); - } catch (UnknownHostException | SocketTimeoutException e) { + } catch (IOException e) { plugin.getLogger().info("Could not connect to ProjectKorra.com to check for updates"); - } catch (IOException | SAXException | ParserConfigurationException e) { + } catch (SAXException | ParserConfigurationException e) { e.printStackTrace(); } this.currentVersion = plugin.getDescription().getVersion(); diff --git a/src/com/projectkorra/projectkorra/waterbending/Bloodbending.java b/src/com/projectkorra/projectkorra/waterbending/Bloodbending.java index 6424cc75..f249a13c 100644 --- a/src/com/projectkorra/projectkorra/waterbending/Bloodbending.java +++ b/src/com/projectkorra/projectkorra/waterbending/Bloodbending.java @@ -3,18 +3,16 @@ package com.projectkorra.projectkorra.waterbending; import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.Element; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.SubElement; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.firebending.FireMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.BloodAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; import com.projectkorra.projectkorra.object.HorizontalVelocityTracker; import com.projectkorra.projectkorra.util.TempPotionEffect; import org.bukkit.Location; import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffect; @@ -22,302 +20,309 @@ import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; import java.util.ArrayList; -import java.util.List; import java.util.concurrent.ConcurrentHashMap; -public class Bloodbending { +public class Bloodbending extends BloodAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - - ConcurrentHashMap targetentities = new ConcurrentHashMap(); - - private static final double FACTOR = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.Bloodbending.ThrowFactor"); - private static final boolean onlyUsableAtNight = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.Bloodbending.CanOnlyBeUsedAtNight"); - private static boolean canBeUsedOnUndead = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.Bloodbending.CanBeUsedOnUndeadMobs"); - private static final boolean onlyUsableDuringMoon = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.Bloodbending.CanOnlyBeUsedDuringFullMoon"); - private boolean canBloodbendBloodbenders = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.Bloodbending.CanBloodbendOtherBloodbenders"); + private static final ConcurrentHashMap TARGETED_ENTITIES = new ConcurrentHashMap(); - private int RANGE = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.Bloodbending.Range"); - private long HOLD_TIME = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.Bloodbending.HoldTime"); - private long COOLDOWN = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.Bloodbending.Cooldown"); - - private Player player; + private boolean canOnlyBeUsedAtNight; + private boolean canBeUsedOnUndeadMobs; + private boolean onlyUsableDuringMoon; + private boolean canBloodbendOtherBloodbenders; + private int range; private long time; - private double factor = FACTOR; - private int range = RANGE; - private long holdTime = HOLD_TIME; - private long cooldown = COOLDOWN; - - private Integer[] transparent = {0, 6, 8, 9, 10, 11, 27, 28, 30, 31, 32, - 37, 38, 39, 40, 50, 51, 55, 59, 63, 64, - 65, 66, 68, 69, 70, 71, 72, 75, 76, 77, - 78, 83, 93, 94, 104, 105, 111, 115, 117, - 132, 141, 142, 143, 147, 148, 149, 150, - 157, 175, 176, 177, 183, 184, 185, 187, - 193, 194, 195, 196, 197}; + private long holdTime; + private long cooldown; + private double throwFactor; public Bloodbending(Player player) { - if (instances.containsKey(player)) { - remove(player); + super(player); + + Bloodbending ability = CoreAbility.getAbility(player, getClass()); + if (ability != null) { + ability.remove(); return; } - if (onlyUsableAtNight && !WaterMethods.isNight(player.getWorld()) && !WaterMethods.canBloodbendAtAnytime(player)) { + + this.canOnlyBeUsedAtNight = getConfig().getBoolean("Abilities.Water.Bloodbending.CanOnlyBeUsedAtNight"); + this.canBeUsedOnUndeadMobs = getConfig().getBoolean("Abilities.Water.Bloodbending.CanBeUsedOnUndeadMobs"); + this.onlyUsableDuringMoon = getConfig().getBoolean("Abilities.Water.Bloodbending.CanOnlyBeUsedDuringFullMoon"); + this.canBloodbendOtherBloodbenders = getConfig().getBoolean("Abilities.Water.Bloodbending.CanBloodbendOtherBloodbenders"); + this.range = getConfig().getInt("Abilities.Water.Bloodbending.Range"); + this.holdTime = getConfig().getInt("Abilities.Water.Bloodbending.HoldTime"); + this.cooldown = getConfig().getInt("Abilities.Water.Bloodbending.Cooldown"); + this.throwFactor = getConfig().getDouble("Abilities.Water.Bloodbending.ThrowFactor"); + + if (canOnlyBeUsedAtNight && !isNight(player.getWorld()) && !bPlayer.canBloodbendAtAnytime()) { + return; + } else if (onlyUsableDuringMoon && !isFullMoon(player.getWorld()) && !bPlayer.canBloodbendAtAnytime()) { + return; + } else if (!bPlayer.canBend(this) && !bPlayer.isAvatarState()) { return; } - if (onlyUsableDuringMoon && !WaterMethods.isFullMoon(player.getWorld()) && !WaterMethods.canBloodbendAtAnytime(player)) { - return; - } - - BendingPlayer bplayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bplayer.isOnCooldown("Bloodbending") && !AvatarState.isAvatarState(player)) { - return; - } - - range = (int) WaterMethods.waterbendingNightAugment(range, player.getWorld()); - if (AvatarState.isAvatarState(player)) { + range = (int) getNightFactor(range, player.getWorld()); + if (bPlayer.isAvatarState()) { range += AvatarState.getValue(1.5); for (Entity entity : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), range)) { if (entity instanceof LivingEntity) { if (entity instanceof Player) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "Bloodbending", entity.getLocation()) || (AvatarState.isAvatarState((Player) entity) || entity.getEntityId() == player.getEntityId() || GeneralMethods.canBend(((Player) entity).getName(), "Bloodbending"))) + Player enemyPlayer = (Player) entity; + BendingPlayer enemyBPlayer = BendingPlayer.getBendingPlayer(enemyPlayer); + if (enemyBPlayer == null + || GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation()) + || (enemyBPlayer.isAvatarState() + || entity.getEntityId() == player.getEntityId() + || enemyBPlayer.canBend(this))) { continue; + } } - GeneralMethods.damageEntity(player, entity, 0, "Bloodbending"); - AirMethods.breakBreathbendingHold(entity); - targetentities.put(entity, entity.getLocation().clone()); + GeneralMethods.damageEntity(this, entity, 0); + AirAbility.breakBreathbendingHold(entity); + TARGETED_ENTITIES.put(entity, entity.getLocation().clone()); } } } else { - List entities = new ArrayList(); - for (int i = 0; i < 6; i++) { - Location location = GeneralMethods.getTargetedLocation(player, i, transparent); - entities = GeneralMethods.getEntitiesAroundPoint(location, 1.7); - if (entities.contains(player)) - entities.remove(player); - if (entities != null && !entities.isEmpty() && !entities.contains(player)) { - break; + Entity target = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); + if (target == null || !(target instanceof LivingEntity) || GeneralMethods.isRegionProtectedFromBuild(this, target.getLocation())) { + return; + } else if (target instanceof Player) { + BendingPlayer targetBPlayer = BendingPlayer.getBendingPlayer(player); + if (targetBPlayer != null) { + if ((targetBPlayer.canBend(ability) && !canBloodbendOtherBloodbenders) || targetBPlayer.isAvatarState()) { + if (!isDay(target.getWorld()) || targetBPlayer.canBloodbendAtAnytime()) { + return; + } + } } - } - if (entities == null || entities.isEmpty()) { + } else if (!canBeUsedOnUndeadMobs && isUndead(target)) { return; } - Entity target = entities.get(0); - //Entity target = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); - if (target == null) - return; - if (!(target instanceof LivingEntity) || GeneralMethods.isRegionProtectedFromBuild(player, "Bloodbending", target.getLocation())) - return; - if (target instanceof Player) { - if ((GeneralMethods.canBend(((Player) target).getName(), "Bloodbending") && !canBloodbendBloodbenders) || AvatarState.isAvatarState((Player) target)) - if (!FireMethods.isDay(target.getWorld()) || WaterMethods.canBloodbendAtAnytime((Player) target)) - return; - } - if (!canBeUsedOnUndead && isUndead(target)) { - return; - } - GeneralMethods.damageEntity(player, target, 0, "Bloodbending"); + + GeneralMethods.damageEntity(this, target, 0); HorizontalVelocityTracker.remove(target); - AirMethods.breakBreathbendingHold(target); - targetentities.put(target, target.getLocation().clone()); + AirAbility.breakBreathbendingHold(target); + TARGETED_ENTITIES.put(target, target.getLocation().clone()); } - if (targetentities.size() > 0) { - bplayer.addCooldown("Bloodbending", cooldown); + + if (TARGETED_ENTITIES.size() > 0) { + bPlayer.addCooldown(this); } - this.player = player; + this.time = System.currentTimeMillis(); - instances.put(player, this); + start(); } public static void launch(Player player) { - if (instances.containsKey(player)) - instances.get(player).launch(); + Bloodbending bloodbending = CoreAbility.getAbility(player, Bloodbending.class); + if (bloodbending != null) { + bloodbending.launch(); + } } private void launch() { Location location = player.getLocation(); - for (Entity entity : targetentities.keySet()) { + for (Entity entity : TARGETED_ENTITIES.keySet()) { Location target = entity.getLocation().clone(); Vector vector = GeneralMethods.getDirection(location, GeneralMethods.getTargetedLocation(player, location.distance(target))); vector.normalize(); - entity.setVelocity(vector.multiply(factor)); - new HorizontalVelocityTracker(entity, player, 200, "Bloodbending", Element.Water, SubElement.Bloodbending); + entity.setVelocity(vector.multiply(throwFactor)); + new HorizontalVelocityTracker(entity, player, 200, "Bloodbending", Element.AIR); } - remove(player); + remove(); } - private void progress() { + @Override + public void progress() { PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, 60, 1); if (!player.isSneaking()) { - remove(player); + remove(); + return; + } else if (holdTime > 0 && System.currentTimeMillis() - this.time > holdTime) { + remove(); return; } - if (holdTime > 0 && System.currentTimeMillis() - this.time > holdTime) { - remove(player); - return; - } - - if (!canBeUsedOnUndead) { - for (Entity entity : targetentities.keySet()) { + if (!canBeUsedOnUndeadMobs) { + for (Entity entity : TARGETED_ENTITIES.keySet()) { if (isUndead(entity)) { - targetentities.remove(entity); + TARGETED_ENTITIES.remove(entity); } } } - if (onlyUsableDuringMoon && !WaterMethods.isFullMoon(player.getWorld()) && !WaterMethods.canBloodbendAtAnytime(player)) { - remove(player); + if (onlyUsableDuringMoon && !isFullMoon(player.getWorld())) { + remove(); + return; + } else if (canOnlyBeUsedAtNight && !isNight(player.getWorld())) { + remove(); + return; + } else if (!bPlayer.canBendIgnoreCooldowns(this)) { + remove(); return; } - if (onlyUsableAtNight && !WaterMethods.isNight(player.getWorld()) && !WaterMethods.canBloodbendAtAnytime(player)) { - remove(player); - return; - } - - if (!GeneralMethods.canBend(player.getName(), "Bloodbending")) { - remove(player); - return; - } - if (GeneralMethods.getBoundAbility(player) == null) { - remove(player); - return; - } - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("Bloodbending")) { - remove(player); - return; - } - - if (AvatarState.isAvatarState(player)) { + if (bPlayer.isAvatarState()) { ArrayList entities = new ArrayList(); + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), range)) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "Bloodbending", entity.getLocation())) + if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) { continue; - if (entity instanceof Player) { - if (!WaterMethods.canBeBloodbent((Player) entity) || entity.getEntityId() == player.getEntityId()) - continue; + } else if (entity instanceof Player) { + BendingPlayer targetBPlayer = BendingPlayer.getBendingPlayer((Player) entity); + if (targetBPlayer != null) { + if (!targetBPlayer.canBeBloodbent() || entity.getEntityId() == player.getEntityId()) { + continue; + } + } } + entities.add(entity); - if (!targetentities.containsKey(entity) && entity instanceof LivingEntity) { - GeneralMethods.damageEntity(player, entity, 0, "Bloodbending"); - targetentities.put(entity, entity.getLocation().clone()); + if (!TARGETED_ENTITIES.containsKey(entity) && entity instanceof LivingEntity) { + GeneralMethods.damageEntity(this, entity, 0); + TARGETED_ENTITIES.put(entity, entity.getLocation().clone()); } + if (entity instanceof LivingEntity) { - Location newlocation = entity.getLocation(); - if (player.getWorld() != newlocation.getWorld()) { - targetentities.remove(entity); + Location newLocation = entity.getLocation(); + if (player.getWorld() != newLocation.getWorld()) { + TARGETED_ENTITIES.remove(entity); continue; } - Location location = targetentities.get(entity); - double distance = location.distance(newlocation); + + Location location = TARGETED_ENTITIES.get(entity); + double distance = location.distance(newLocation); double dx, dy, dz; - dx = location.getX() - newlocation.getX(); - dy = location.getY() - newlocation.getY(); - dz = location.getZ() - newlocation.getZ(); + dx = location.getX() - newLocation.getX(); + dy = location.getY() - newLocation.getY(); + dz = location.getZ() - newLocation.getZ(); Vector vector = new Vector(dx, dy, dz); + if (distance > .5) { entity.setVelocity(vector.normalize().multiply(.5)); } else { entity.setVelocity(new Vector(0, 0, 0)); } + new TempPotionEffect((LivingEntity) entity, effect); entity.setFallDistance(0); if (entity instanceof Creature) { ((Creature) entity).setTarget(null); } - AirMethods.breakBreathbendingHold(entity); + AirAbility.breakBreathbendingHold(entity); } } - for (Entity entity : targetentities.keySet()) { - if (!entities.contains(entity)) - targetentities.remove(entity); + + for (Entity entity : TARGETED_ENTITIES.keySet()) { + if (!entities.contains(entity)) { + TARGETED_ENTITIES.remove(entity); + } } } else { - for (Entity entity : targetentities.keySet()) { + for (Entity entity : TARGETED_ENTITIES.keySet()) { if (entity instanceof Player) { - if (!WaterMethods.canBeBloodbent((Player) entity)) { - targetentities.remove(entity); + BendingPlayer targetBPlayer = BendingPlayer.getBendingPlayer((Player) entity); + if (targetBPlayer != null && !targetBPlayer.canBeBloodbent()) { + TARGETED_ENTITIES.remove(entity); continue; } } - Location newlocation = entity.getLocation(); - if (player.getWorld() != newlocation.getWorld()) { - targetentities.remove(entity); + + Location newLocation = entity.getLocation(); + if (player.getWorld() != newLocation.getWorld()) { + TARGETED_ENTITIES.remove(entity); continue; } - Location location = GeneralMethods.getTargetedLocation(player, 6, transparent); - double distance = location.distance(newlocation); + + Location location = GeneralMethods.getTargetedLocation(player, 6, getTransparentMaterial()); + double distance = location.distance(newLocation); double dx, dy, dz; - dx = location.getX() - newlocation.getX(); - dy = location.getY() - newlocation.getY(); - dz = location.getZ() - newlocation.getZ(); + dx = location.getX() - newLocation.getX(); + dy = location.getY() - newLocation.getY(); + dz = location.getZ() - newLocation.getZ(); Vector vector = new Vector(dx, dy, dz); + if (distance > .5) { entity.setVelocity(vector.normalize().multiply(.5)); } else { entity.setVelocity(new Vector(0, 0, 0)); } + new TempPotionEffect((LivingEntity) entity, effect); entity.setFallDistance(0); if (entity instanceof Creature) { ((Creature) entity).setTarget(null); } - AirMethods.breakBreathbendingHold(entity); + AirAbility.breakBreathbendingHold(entity); } } } - public static void progressAll() { - for (Player player : instances.keySet()) { - instances.get(player).progress(); - } - } - - public static void remove(Player player) { - if (instances.containsKey(player)) { - instances.remove(player); - } - } - public static boolean isBloodbended(Entity entity) { - for (Player player : instances.keySet()) { - if (instances.get(player).targetentities.containsKey(entity)) { - return true; - } - } - return false; + return entity != null ? TARGETED_ENTITIES.containsKey(entity) : null; } - - public static boolean isUndead(Entity entity) { - if (entity == null) - return false; - if (entity.getType() == EntityType.ZOMBIE || entity.getType() == EntityType.BLAZE || entity.getType() == EntityType.GIANT || entity.getType() == EntityType.IRON_GOLEM || entity.getType() == EntityType.MAGMA_CUBE || entity.getType() == EntityType.PIG_ZOMBIE || entity.getType() == EntityType.SKELETON || entity.getType() == EntityType.SLIME || entity.getType() == EntityType.SNOWMAN || entity.getType() == EntityType.ZOMBIE) { - return true; - } - return false; - } - + public static Location getBloodbendingLocation(Entity entity) { - for (Player player : instances.keySet()) { - if (instances.get(player).targetentities.containsKey(entity)) { - return instances.get(player).targetentities.get(entity); - } - } - return null; + return entity != null ? TARGETED_ENTITIES.get(entity) : null; } - public Player getPlayer() { - return player; + @Override + public String getName() { + return "Bloodbending"; } - public double getFactor() { - return factor; + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; } - public void setFactor(double factor) { - this.factor = factor; + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isCanOnlyBeUsedAtNight() { + return canOnlyBeUsedAtNight; + } + + public void setCanOnlyBeUsedAtNight(boolean canOnlyBeUsedAtNight) { + this.canOnlyBeUsedAtNight = canOnlyBeUsedAtNight; + } + + public boolean isCanBeUsedOnUndeadMobs() { + return canBeUsedOnUndeadMobs; + } + + public void setCanBeUsedOnUndeadMobs(boolean canBeUsedOnUndeadMobs) { + this.canBeUsedOnUndeadMobs = canBeUsedOnUndeadMobs; + } + + public boolean isOnlyUsableDuringMoon() { + return onlyUsableDuringMoon; + } + + public void setOnlyUsableDuringMoon(boolean onlyUsableDuringMoon) { + this.onlyUsableDuringMoon = onlyUsableDuringMoon; + } + + public boolean isCanBloodbendOtherBloodbenders() { + return canBloodbendOtherBloodbenders; + } + + public void setCanBloodbendOtherBloodbenders(boolean canBloodbendOtherBloodbenders) { + this.canBloodbendOtherBloodbenders = canBloodbendOtherBloodbenders; } public int getRange() { @@ -328,6 +333,14 @@ public class Bloodbending { this.range = range; } + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + public long getHoldTime() { return holdTime; } @@ -336,14 +349,16 @@ public class Bloodbending { this.holdTime = holdTime; } - public long getCooldown() { - return cooldown; + public double getThrowFactor() { + return throwFactor; + } + + public void setThrowFactor(double throwFactor) { + this.throwFactor = throwFactor; } public void setCooldown(long cooldown) { this.cooldown = cooldown; - if (player != null) - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("Bloodbending", cooldown); } - + } diff --git a/src/com/projectkorra/projectkorra/waterbending/FreezeMelt.java b/src/com/projectkorra/projectkorra/waterbending/FreezeMelt.java deleted file mode 100644 index d544f9ac..00000000 --- a/src/com/projectkorra/projectkorra/waterbending/FreezeMelt.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.projectkorra.projectkorra.waterbending; - -import java.util.concurrent.ConcurrentHashMap; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.util.TempBlock; - -public class FreezeMelt { - - public static ConcurrentHashMap frozenblocks = new ConcurrentHashMap(); - - public static final int defaultrange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.PhaseChange.Range"); - public static final int defaultradius = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.PhaseChange.Radius"); - - private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.PhaseChange.Cooldown"); - - public FreezeMelt(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (!WaterMethods.canIcebend(player)) { - return; - } - if (bPlayer.isOnCooldown("PhaseChange")) { - return; - } - bPlayer.addCooldown("PhaseChange", cooldown); - - int range = (int) WaterMethods.waterbendingNightAugment(defaultrange, player.getWorld()); - int radius = (int) WaterMethods.waterbendingNightAugment(defaultradius, player.getWorld()); - if (AvatarState.isAvatarState(player)) { - range = AvatarState.getValue(range); - } - - Location location = GeneralMethods.getTargetedLocation(player, range); - for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) { - if (isFreezable(player, block)) { - freeze(player, block); - } - } - } - - private static boolean isFreezable(Player player, Block block) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "PhaseChange", block.getLocation())) { - return false; - } - if (block.getType() == Material.WATER || block.getType() == Material.STATIONARY_WATER) { - if (WaterManipulation.canPhysicsChange(block) && !TempBlock.isTempBlock(block)) { - return true; - } - } - return false; - } - - @SuppressWarnings("deprecation") - static void freeze(Player player, Block block) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "PhaseChange", block.getLocation())) { - return; - } - if (TempBlock.isTempBlock(block)) { - return; - } - byte data = block.getData(); - block.setType(Material.ICE); - if(frozenblocks.size() % 50 == 0) { - WaterMethods.playIcebendingSound(block.getLocation()); - } - frozenblocks.put(block, data); - } - - @SuppressWarnings("deprecation") - public static void thaw(Block block) { - if (frozenblocks.containsKey(block)) { - byte data = frozenblocks.get(block); - frozenblocks.remove(block); - block.setType(Material.WATER); - block.setData(data); - } - } - - public static void handleFrozenBlocks() { - new BukkitRunnable() { - public void run() { - canThaw(); - } - }.runTaskLater(ProjectKorra.plugin, 100); - } - - public static void canThaw() { - for (Block block : frozenblocks.keySet()) { - int canThaw = 0; - for (Player player : block.getWorld().getPlayers()) { - double range = WaterMethods.waterbendingNightAugment(defaultrange, player.getWorld()); - if (AvatarState.isAvatarState(player)) { - range = AvatarState.getValue(range); - } - - if (player == null || !player.isOnline()) { - canThaw++; - } - else if (!GeneralMethods.canBend(player.getName(), "PhaseChange")) { - canThaw++; - } - else if (block.getLocation().distance(player.getLocation()) > range) { - canThaw++; - } - } - if(canThaw >= block.getWorld().getPlayers().size()) { - thaw(block); - } - } - } - - @SuppressWarnings("deprecation") - private static void thawAll() { - for (Block block : frozenblocks.keySet()) { - if (block.getType() == Material.ICE) { - byte data = frozenblocks.get(block); - block.setType(Material.WATER); - block.setData(data); - frozenblocks.remove(block); - } - } - } - - public static void removeAll() { - thawAll(); - } - - public static String getDescription() { - return "To use, simply left-click. " + "Any water you are looking at within range will instantly freeze over into solid ice. " + "Provided you stay within range of the ice and do not unbind PhaseChange, " + "that ice will not thaw. If, however, you do either of those the ice will instantly thaw. " + "If you sneak (default: shift), anything around where you are looking at will instantly melt. " + "Since this is a more favorable state for these things, they will never re-freeze unless they " + "would otherwise by nature or some other bending ability. Additionally, if you tap sneak while " + "targetting water with PhaseChange, it will evaporate water around that block that is above " + "sea level. "; - } - -} diff --git a/src/com/projectkorra/projectkorra/waterbending/HealingWaters.java b/src/com/projectkorra/projectkorra/waterbending/HealingWaters.java index b98552e2..481c52c0 100644 --- a/src/com/projectkorra/projectkorra/waterbending/HealingWaters.java +++ b/src/com/projectkorra/projectkorra/waterbending/HealingWaters.java @@ -1,12 +1,16 @@ - package com.projectkorra.projectkorra.waterbending; +package com.projectkorra.projectkorra.waterbending; +import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.airbending.AirMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.HealingAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; import com.projectkorra.projectkorra.chiblocking.Smokescreen; import com.projectkorra.projectkorra.util.TempBlock; -import org.bukkit.Server; +import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; @@ -14,25 +18,21 @@ import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import java.util.ArrayList; - -public class HealingWaters { - - private static final boolean shift = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.HealingWaters.ShiftRequired"); - private static final double range = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.HealingWaters.Radius"); - private static final long interval = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.HealingWaters.Interval"); - private static final int power = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.HealingWaters.Power"); +public class HealingWaters extends HealingAbility { private static long time = 0; - - public static void heal(Server server) { - if (System.currentTimeMillis() - time >= interval) { + + public HealingWaters(Player player) { + super(player); + } + + public static void heal() { + if (System.currentTimeMillis() - time >= getInterval()) { time = System.currentTimeMillis(); - for (Player player : server.getOnlinePlayers()) { - if (GeneralMethods.getBoundAbility(player) != null) { - if (GeneralMethods.getBoundAbility(player).equalsIgnoreCase("HealingWaters") && GeneralMethods.canBend(player.getName(), "HealingWaters")) { - heal(player); - } + for (Player player : Bukkit.getServer().getOnlinePlayers()) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer != null && bPlayer.canBend(CoreAbility.getAbility("HealingWaters"))) { + heal(player); } } } @@ -40,22 +40,23 @@ public class HealingWaters { private static void heal(Player player) { if (inWater(player)) { - Entity entity = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); - if (entity instanceof LivingEntity && inWater(entity) && player.isSneaking()) { - giveHPToEntity((LivingEntity) entity); - } else if ((player.isSneaking() && shift) || !shift){ + if (player.isSneaking()) { + Entity entity = GeneralMethods.getTargetedEntity(player, getRadius()); + if (entity instanceof LivingEntity && inWater(entity)) { + giveHPToEntity((LivingEntity) entity); + } + } else { giveHP(player); } } } - private static void giveHPToEntity(LivingEntity le) { if (!le.isDead() && le.getHealth() < le.getMaxHealth()) { applyHealingToEntity(le); } for (PotionEffect effect : le.getActivePotionEffects()) { - if (WaterMethods.isNegativeEffect(effect.getType())) { + if (WaterAbility.isNegativeEffect(effect.getType())) { le.removePotionEffect(effect.getType()); } } @@ -65,9 +66,10 @@ public class HealingWaters { if (!player.isDead() && player.getHealth() < 20) { applyHealing(player); } + for (PotionEffect effect : player.getActivePotionEffects()) { - if (WaterMethods.isNegativeEffect(effect.getType())) { - if ((effect.getType() == PotionEffectType.BLINDNESS) && Smokescreen.blinded.containsKey(player.getName())) { + if (isNegativeEffect(effect.getType())) { + if ((effect.getType() == PotionEffectType.BLINDNESS) && Smokescreen.getBlindedTimes().containsKey(player.getName())) { return; } player.removePotionEffect(effect.getType()); @@ -77,37 +79,77 @@ public class HealingWaters { private static boolean inWater(Entity entity) { Block block = entity.getLocation().getBlock(); - if (WaterMethods.isWater(block) && !TempBlock.isTempBlock(block)) - return true; - return false; + return isWater(block) && !TempBlock.isTempBlock(block); } private static void applyHealing(Player player) { - if (!GeneralMethods.isRegionProtectedFromBuild(player, "HealingWaters", player.getLocation())) + if (!GeneralMethods.isRegionProtectedFromBuild(player, "HealingWaters", player.getLocation())) { if (player.getHealth() < player.getMaxHealth()) { - player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 70, power)); - AirMethods.breakBreathbendingHold(player); + player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, getDuration(), getPower())); + AirAbility.breakBreathbendingHold(player); } - // for(PotionEffect effect : player.getActivePotionEffects()) { - // if(Methods.isNegativeEffect(effect.getType())) { - // player.removePotionEffect(effect.getType()); - // } - // } + } } private static void applyHealingToEntity(LivingEntity le) { if (le.getHealth() < le.getMaxHealth()) { - le.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 70, 1)); - AirMethods.breakBreathbendingHold(le); + le.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, getDuration(), 1)); + AirAbility.breakBreathbendingHold(le); } - // for(PotionEffect effect : le.getActivePotionEffects()) { - // if(Methods.isNegativeEffect(effect.getType())) { - // le.removePotionEffect(effect.getType()); - // } - // } } - public static String getDescription() { - return "To use, the bender must be at least partially submerged in water. " + "If the user is not sneaking, this ability will automatically begin " + "working provided the user has it selected. If the user is sneaking, " + "he/she is channeling the healing to their target in front of them. " + "In order for this channel to be successful, the user and the target must " + "be at least partially submerged in water. This ability will heal the user or target, and it will also remove any negative potion effects the user or target has."; + public static long getTime() { + return time; } + + public static void setTime(long time) { + HealingWaters.time = time; + } + + public static double getRadius() { + return getConfig().getDouble("Abilities.Water.HealingWaters.Radius"); + } + + public static long getInterval() { + return getConfig().getLong("Abilities.Water.HealingWaters.Interval"); + } + + public static int getPower() { + return getConfig().getInt("Abilities.Water.HealingWaters.Power"); + } + + public static int getDuration() { + // TODO: add a duration config option + return 70; + } + + @Override + public String getName() { + return "HealingWaters"; + } + + @Override + public void progress() { + } + + @Override + public Location getLocation() { + return null; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return true; + } + } diff --git a/src/com/projectkorra/projectkorra/waterbending/IceBlast.java b/src/com/projectkorra/projectkorra/waterbending/IceBlast.java index ef3fc9e8..c433382f 100644 --- a/src/com/projectkorra/projectkorra/waterbending/IceBlast.java +++ b/src/com/projectkorra/projectkorra/waterbending/IceBlast.java @@ -2,9 +2,9 @@ package com.projectkorra.projectkorra.waterbending; import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.earthbending.EarthMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.IceAbility; import com.projectkorra.projectkorra.util.BlockSource; import com.projectkorra.projectkorra.util.ClickType; import com.projectkorra.projectkorra.util.ParticleEffect; @@ -23,305 +23,254 @@ import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Random; -public class IceBlast { - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - private static double defaultrange = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.IceBlast.Range"); - private static int DAMAGE = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.IceBlast.Damage"); - private static int COOLDOWN = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.IceBlast.Cooldown"); - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.IceBlast.SelectRange"); - private static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.IceBlast.DynamicSourcing.Enabled"); +public class IceBlast extends IceAbility { - private static int ID = Integer.MIN_VALUE; - - private static final long interval = 20; - private static final byte data = 0; - private static final double affectingradius = 2; - private static final double deflectrange = 3; - - private int id; - private double range; - private boolean prepared = false; - private boolean settingup = false; - private boolean progressing = false; + private boolean prepared; + private boolean settingUp; + private boolean progressing; + private byte data; private long time; + private long cooldown; + private long interval; + private double range; + private double damage; + private double radius; + private double deflectRange; + private Block sourceBlock; private Location location; - private Location firstdestination; + private Location firstDestination; private Location destination; - private Block sourceblock; - private Player player; public TempBlock source; - private double defaultdamage = DAMAGE; - private long cooldown = COOLDOWN; - + public IceBlast(Player player) { - if (!WaterMethods.canIcebend(player)) - return; - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("IceBlast")) { + super(player); + + this.data = 0; + this.interval = 20; + this.radius = 2; + this.deflectRange = 3; + this.range = getConfig().getDouble("Abilities.Water.IceBlast.Range"); + this.damage = getConfig().getInt("Abilities.Water.IceBlast.Damage"); + this.cooldown = getConfig().getInt("Abilities.Water.IceBlast.Cooldown"); + + this.damage = getNightFactor(damage, player.getWorld()); + + if (!bPlayer.canBend(this) || !bPlayer.canIcebend()) { return; } block(player); - range = WaterMethods.waterbendingNightAugment(defaultrange, player.getWorld()); - this.player = player; - Block sourceblock = BlockSource.getWaterSourceBlock(player, selectRange, selectRange, ClickType.SHIFT_DOWN, false, dynamic, false, false, - WaterMethods.canIcebend(player), false); + range = getNightFactor(range, player.getWorld()); + Block sourceBlock = BlockSource.getWaterSourceBlock(player, range, ClickType.SHIFT_DOWN, false, true, false); - if (sourceblock == null) { + if (sourceBlock == null) { return; - } else if (TempBlock.isTempBlock(sourceblock)) { + } else if (TempBlock.isTempBlock(sourceBlock) || GeneralMethods.isRegionProtectedFromBuild(this, sourceBlock.getLocation())) { return; } else { - prepare(sourceblock); + prepare(sourceBlock); } } private void prepare(Block block) { - for (IceBlast ice : getInstances(player)) { - if (ice.prepared) { - ice.cancel(); + for (IceBlast iceBlast : CoreAbility.getAbilities(player, IceBlast.class)) { + if (iceBlast.prepared) { + iceBlast.remove(); } } - sourceblock = block; - location = sourceblock.getLocation(); + sourceBlock = block; + location = sourceBlock.getLocation(); prepared = true; - if (getInstances(player).isEmpty()) - createInstance(); - } - - private void createInstance() { - id = ID++; - instances.put(id, this); - if (ID >= Integer.MAX_VALUE) { - ID = Integer.MIN_VALUE; + + if (CoreAbility.getAbilities(player, IceBlast.class).isEmpty()) { + start(); } } - private static ArrayList getInstances(Player player) { - ArrayList list = new ArrayList(); - for (int id : instances.keySet()) { - IceBlast ice = instances.get(id); - if (ice.player.equals(player)) { - list.add(ice); - } - } - - return list; - } - private static void block(Player player) { - for (int id : instances.keySet()) { - IceBlast ice = instances.get(id); - - if (ice.player.equals(player)) + for (IceBlast iceBlast : CoreAbility.getAbilities(player, IceBlast.class)) { + if (!iceBlast.location.getWorld().equals(player.getWorld())) { continue; - - if (!ice.location.getWorld().equals(player.getWorld())) + } else if (!iceBlast.progressing) { continue; - - if (!ice.progressing) - continue; - - if (GeneralMethods.isRegionProtectedFromBuild(player, "IceBlast", ice.location)) + } else if (GeneralMethods.isRegionProtectedFromBuild(iceBlast, iceBlast.location)) { continue; + } Location location = player.getEyeLocation(); Vector vector = location.getDirection(); - Location mloc = ice.location; - if (mloc.distance(location) <= defaultrange - && GeneralMethods.getDistanceFromLine(vector, location, ice.location) < deflectrange - && mloc.distance(location.clone().add(vector)) < mloc - .distance(location.clone().add(vector.clone().multiply(-1)))) { - ice.cancel(); + Location mloc = iceBlast.location; + + if (mloc.distanceSquared(location) <= iceBlast.range * iceBlast.range + && GeneralMethods.getDistanceFromLine(vector, location, iceBlast.location) < iceBlast.deflectRange + && mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) { + iceBlast.remove(); } - } } public static void activate(Player player) { - - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (bPlayer.isOnCooldown("IceBlast")) + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer != null && bPlayer.isOnCooldown("IceBlast")) { return; + } - for (IceBlast ice : getInstances(player)) { + for (IceBlast ice : CoreAbility.getAbilities(IceBlast.class)) { if (ice.prepared) { ice.throwIce(); } } } - private void cancel() { + @Override + public void remove() { + super.remove(); if (progressing) { - if (source != null) + if (source != null) { source.revertBlock(); + } progressing = false; } + if (player.isOnline()) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); if (bPlayer != null) { - bPlayer.addCooldown("IceBlast", cooldown); + bPlayer.addCooldown(this); } } - instances.remove(id); } private void returnWater() { - new WaterReturn(player, sourceblock); - } - - public static void removeAll() { - for (int id : instances.keySet()) { - instances.get(id).cancel(); - } - - instances.clear(); + new WaterReturn(player, sourceBlock); } private void affect(LivingEntity entity) { - int damage = (int) WaterMethods.waterbendingNightAugment(defaultdamage, player.getWorld()); if (entity instanceof Player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); if (bPlayer.canBeSlowed()) { PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, 70, 2); new TempPotionEffect(entity, effect); bPlayer.slow(10); - // entity.damage(damage, player); - GeneralMethods.damageEntity(player, entity, damage, "IceBlast"); + GeneralMethods.damageEntity(this, entity, damage); } } else { PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, 70, 2); new TempPotionEffect(entity, effect); - // entity.damage(damage, player); - GeneralMethods.damageEntity(player, entity, damage, "IceBlast"); + GeneralMethods.damageEntity(this, entity, damage); } - AirMethods.breakBreathbendingHold(entity); + AirAbility.breakBreathbendingHold(entity); for (int x = 0; x < 30; x++) { - ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.ICE, (byte) 0), - new Vector(((Math.random() - 0.5) * .5), ((Math.random() - 0.5) * .5), ((Math.random() - 0.5) * .5)), .3f, - location, 257.0D); + ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.ICE, (byte) 0), new Vector(((Math.random() - 0.5) * .5), ((Math.random() - 0.5) * .5), ((Math.random() - 0.5) * .5)), .3f, location, 257.0D); } } private void throwIce() { - if (!prepared) + if (!prepared) { return; + } + LivingEntity target = (LivingEntity) GeneralMethods.getTargetedEntity(player, range, new ArrayList()); if (target == null) { - destination = GeneralMethods.getTargetedLocation(player, range, EarthMethods.transparentToEarthbending); + destination = GeneralMethods.getTargetedLocation(player, range, getTransparentMaterial()); } else { destination = target.getEyeLocation(); } - location = sourceblock.getLocation(); - if (destination.distance(location) < 1) + location = sourceBlock.getLocation(); + if (destination.distanceSquared(location) < 1) { return; - firstdestination = location.clone(); - if (destination.getY() - location.getY() > 2) { - firstdestination.setY(destination.getY() - 1); - } else { - firstdestination.add(0, 2, 0); } - destination = GeneralMethods.getPointOnLine(firstdestination, destination, range); + + firstDestination = location.clone(); + if (destination.getY() - location.getY() > 2) { + firstDestination.setY(destination.getY() - 1); + } else { + firstDestination.add(0, 2, 0); + } + + destination = GeneralMethods.getPointOnLine(firstDestination, destination, range); progressing = true; - settingup = true; + settingUp = true; prepared = false; - new TempBlock(sourceblock, Material.AIR, (byte) 0); - - source = new TempBlock(sourceblock, Material.PACKED_ICE, data); + new TempBlock(sourceBlock, Material.AIR, (byte) 0); + source = new TempBlock(sourceBlock, Material.PACKED_ICE, data); } - private void progress() { - if (player.isDead() || !player.isOnline()) { - cancel(); - return; - } - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (!GeneralMethods.canBend(player.getName(), "IceBlast") || bPlayer.isOnCooldown("IceBlast")) { - cancel(); + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBinds(this)) { + remove(); return; } - if (!player.getWorld().equals(location.getWorld())) { - cancel(); - return; - } - - if (player.getEyeLocation().distance(location) >= range) { + if (player.getEyeLocation().distanceSquared(location) >= range * range) { if (progressing) { breakParticles(20); - cancel(); + remove(); returnWater(); } else { breakParticles(20); - cancel(); + remove(); } return; } - if ((GeneralMethods.getBoundAbility(player) == null - || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("IceBlast")) && prepared) { - cancel(); + if (!bPlayer.getBoundAbilityName().equalsIgnoreCase(getName()) && prepared) { + remove(); return; } - if (System.currentTimeMillis() < time + interval) + if (System.currentTimeMillis() < time + interval) { return; + } time = System.currentTimeMillis(); - if (progressing) { - Vector direction; + if (location.getBlockY() == firstDestination.getBlockY()) { + settingUp = false; + } - if (location.getBlockY() == firstdestination.getBlockY()) - settingup = false; - - if (location.distance(destination) <= 2) { - cancel(); + if (location.distanceSquared(destination) <= 4) { + remove(); returnWater(); return; } - if (settingup) { - direction = GeneralMethods.getDirection(location, firstdestination).normalize(); + if (settingUp) { + direction = GeneralMethods.getDirection(location, firstDestination).normalize(); } else { direction = GeneralMethods.getDirection(location, destination).normalize(); } location.add(direction); - Block block = location.getBlock(); - - if (block.equals(sourceblock)) + if (block.equals(sourceBlock)) { return; + } source.revertBlock(); source = null; - if (EarthMethods.isTransparentToEarthbending(player, block) && !block.isLiquid()) { + if (isTransparentToEarthbending(player, block) && !block.isLiquid()) { GeneralMethods.breakBlock(block); - } else if (!WaterMethods.isWater(block)) { + } else if (!isWater(block)) { breakParticles(20); - cancel(); + remove(); returnWater(); return; } - if (GeneralMethods.isRegionProtectedFromBuild(player, "IceBlast", location)) { - cancel(); + if (GeneralMethods.isRegionProtectedFromBuild(this, location)) { + remove(); returnWater(); return; } - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, affectingradius)) { + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, radius)) { if (entity.getEntityId() != player.getEntityId() && entity instanceof LivingEntity) { affect((LivingEntity) entity); progressing = false; @@ -330,46 +279,110 @@ public class IceBlast { } if (!progressing) { - cancel(); + remove(); return; } - sourceblock = block; - source = new TempBlock(sourceblock, Material.PACKED_ICE, data); + sourceBlock = block; + source = new TempBlock(sourceBlock, Material.PACKED_ICE, data); for (int x = 0; x < 10; x++) { - ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.ICE, (byte) 0), - new Vector(((Math.random() - 0.5) * .5), ((Math.random() - 0.5) * .5), ((Math.random() - 0.5) * .5)), .5f, - location, 257.0D); - ParticleEffect.SNOW_SHOVEL.display(location, (float) (Math.random() - 0.5), (float) (Math.random() - 0.5), - (float) (Math.random() - 0.5), 0, 5); + ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.ICE, (byte) 0), new Vector(((Math.random() - 0.5) * .5), ((Math.random() - 0.5) * .5), ((Math.random() - 0.5) * .5)), .5f, location, 257.0D); + ParticleEffect.SNOW_SHOVEL.display(location, (float) (Math.random() - 0.5), (float) (Math.random() - 0.5), (float) (Math.random() - 0.5), 0, 5); } - if (GeneralMethods.rand.nextInt(4) == 0) { - WaterMethods.playIcebendingSound(location); + if ((new Random()).nextInt(4) == 0) { + playIcebendingSound(location); } location = location.add(direction.clone()); - } else if (prepared) { - WaterMethods.playFocusWaterEffect(sourceblock); + playFocusWaterEffect(sourceBlock); } } - public static void progressAll() { - for (int id : instances.keySet()) { - instances.get(id).progress(); + public void breakParticles(int amount) { + for (int x = 0; x < amount; x++) { + ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.ICE, (byte) 0), new Vector(((Math.random() - 0.5) * .5), ((Math.random() - 0.5) * .5), ((Math.random() - 0.5) * .5)), 2f, location, 257.0D); + ParticleEffect.SNOW_SHOVEL.display(location, (float) Math.random(), (float) Math.random(), (float) Math.random(), 0, 2); } + location.getWorld().playSound(location, Sound.GLASS, 5, 1.3f); } - public Player getPlayer() { - return player; + @Override + public String getName() { + return "IceBlast"; } - public double getDefaultdamage() { - return defaultdamage; + @Override + public Location getLocation() { + if (location != null) { + return location; + } else if (sourceBlock != null) { + return sourceBlock.getLocation(); + } + return player != null ? player.getLocation() : null; } - public void setDefaultdamage(double defaultdamage) { - this.defaultdamage = defaultdamage; + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isPrepared() { + return prepared; + } + + public void setPrepared(boolean prepared) { + this.prepared = prepared; + } + + public boolean isSettingUp() { + return settingUp; + } + + public void setSettingUp(boolean settingUp) { + this.settingUp = settingUp; + } + + public boolean isProgressing() { + return progressing; + } + + public void setProgressing(boolean progressing) { + this.progressing = progressing; + } + + public byte getData() { + return data; + } + + public void setData(byte data) { + this.data = data; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; } public double getRange() { @@ -378,18 +391,70 @@ public class IceBlast { public void setRange(double range) { this.range = range; - } - public void breakParticles(int amount) { - for (int x = 0; x < amount; x++) { - ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.ICE, (byte) 0), - new Vector(((Math.random() - 0.5) * .5), ((Math.random() - 0.5) * .5), ((Math.random() - 0.5) * .5)), 2f, - location, 257.0D); - ParticleEffect.SNOW_SHOVEL.display(location, (float) Math.random(), (float) Math.random(), (float) Math.random(), 0, - 2); - } - location.getWorld().playSound(location, Sound.GLASS, 5, 1.3f); + public double getDamage() { + return damage; } + public void setDamage(double damage) { + this.damage = damage; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getDeflectRange() { + return deflectRange; + } + + public void setDeflectRange(double deflectRange) { + this.deflectRange = deflectRange; + } + + public Block getSourceBlock() { + return sourceBlock; + } + + public void setSourceBlock(Block sourceBlock) { + this.sourceBlock = sourceBlock; + } + + public Location getFirstDestination() { + return firstDestination; + } + + public void setFirstDestination(Location firstDestination) { + this.firstDestination = firstDestination; + } + + public Location getDestination() { + return destination; + } + + public void setDestination(Location destination) { + this.destination = destination; + } + + public TempBlock getSource() { + return source; + } + + public void setSource(TempBlock source) { + this.source = source; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + } diff --git a/src/com/projectkorra/projectkorra/waterbending/IceSpike.java b/src/com/projectkorra/projectkorra/waterbending/IceSpike.java deleted file mode 100644 index cdc42764..00000000 --- a/src/com/projectkorra/projectkorra/waterbending/IceSpike.java +++ /dev/null @@ -1,320 +0,0 @@ -package com.projectkorra.projectkorra.waterbending; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.util.TempPotionEffect; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -public class IceSpike { - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - public ConcurrentHashMap removeTimers = new ConcurrentHashMap(); - private static ConcurrentHashMap alreadydoneblocks = new ConcurrentHashMap(); - private static ConcurrentHashMap baseblocks = new ConcurrentHashMap(); - - public static long removeTimer = 500; - public static long COOLDOWN = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.IceSpike.Cooldown"); - public static final int HEIGHT = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.IceSpike.Height"); - private static double RANGE = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.IceSpike.Range"); - private static double DAMAGE = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.IceSpike.Damage"); - - private static int ID = Integer.MIN_VALUE; - private static double speed = 25; - private static long interval = (long) (1000. / speed); - private static final Vector direction = new Vector(0, 1, 0); - - private Location origin; - private Location location; - private Block block; - private Player player; - private int progress = 0; - private double damage = DAMAGE; - private double range = RANGE; - private long cooldown = COOLDOWN; - //TODO Fix height so that it actually does something - //private double standardheight = HEIGHT; - private long time; - int id; - int height = 2; - private Vector thrown = new Vector(0, ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.IceSpike.ThrowingMult"), 0); - private ConcurrentHashMap affectedblocks = new ConcurrentHashMap(); - private List damaged = new ArrayList(); - - public IceSpike(Player player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("IceSpike")) - return; - try { - this.player = player; - - double lowestdistance = range + 1; - Entity closestentity = null; - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), range)) { - if (GeneralMethods.getDistanceFromLine(player.getLocation().getDirection(), player.getLocation(), entity.getLocation()) <= 2 && (entity instanceof LivingEntity) && (entity.getEntityId() != player.getEntityId())) { - double distance = player.getLocation().distance(entity.getLocation()); - if (distance < lowestdistance) { - closestentity = entity; - lowestdistance = distance; - } - } - } - if (closestentity != null) { - Block temptestingblock = closestentity.getLocation().getBlock().getRelative(BlockFace.DOWN, 1); - // if (temptestingblock.getType() == Material.ICE){ - this.block = temptestingblock; - // } - } else { - this.block = player.getTargetBlock((HashSet) null, (int) range); - } - for(IceSpike2 icespike : IceSpike2.instances.values()) { - if(icespike.getBlock().equals(block)) { - return; - } - } - origin = block.getLocation(); - location = origin.clone(); - - } - catch (IllegalStateException e) { - return; - } - - loadAffectedBlocks(); - - if (height != 0) { - if (canInstantiate()) { - id = ID; - instances.put(id, this); - if (ID >= Integer.MAX_VALUE) { - ID = Integer.MIN_VALUE; - } - ID++; - time = System.currentTimeMillis() - interval; - bPlayer.addCooldown("IceSpike", cooldown); - } - } - } - - public IceSpike(Player player, Location origin, int damage, Vector throwing, long aoecooldown) { - cooldown = aoecooldown; - this.player = player; - this.origin = origin; - this.damage = damage; - this.thrown = throwing; - location = origin.clone(); - block = location.getBlock(); - - loadAffectedBlocks(); - - if (block.getType() == Material.ICE) { - if (canInstantiate()) { - id = ID; - instances.put(id, this); - if (ID >= Integer.MAX_VALUE) { - ID = Integer.MIN_VALUE; - } - ID++; - time = System.currentTimeMillis() - interval; - } - } - } - - private void loadAffectedBlocks() { - affectedblocks.clear(); - Block thisblock; - for (int i = 1; i <= height; i++) { - thisblock = block.getWorld().getBlockAt(location.clone().add(direction.clone().multiply(i))); - affectedblocks.put(thisblock, thisblock); - } - } - - private boolean blockInAffectedBlocks(Block block) { - if (affectedblocks.containsKey(block)) { - return true; - } - return false; - } - - public static boolean blockInAllAffectedBlocks(Block block) { - for (int ID : instances.keySet()) { - if (instances.get(ID).blockInAffectedBlocks(block)) - return true; - } - return false; - } - - public static void revertBlock(Block block) { - for (int ID : instances.keySet()) { - if (instances.get(ID).blockInAffectedBlocks(block)) { - instances.get(ID).affectedblocks.remove(block); - } - } - } - - private boolean canInstantiate() { - if (block.getType() != Material.ICE) - return false; - for (Block block : affectedblocks.keySet()) { - if (blockInAllAffectedBlocks(block) || alreadydoneblocks.containsKey(block) || block.getType() != Material.AIR || (block.getX() == player.getEyeLocation().getBlock().getX() && block.getZ() == player.getEyeLocation().getBlock().getZ())) { - return false; - } - } - return true; - } - - public static void progressAll() { - for (int ID : instances.keySet()) { - instances.get(ID).progress(); - } - } - - private boolean progress() { - if (System.currentTimeMillis() - time >= interval) { - time = System.currentTimeMillis(); - if (progress < height) { - moveEarth(); - removeTimers.put(player, System.currentTimeMillis()); - } else { - if (removeTimers.containsKey(player)) { - if (removeTimers.get(player) + removeTimer <= System.currentTimeMillis()) { - baseblocks.put(location.clone().add(direction.clone().multiply(-1 * (height))).getBlock(), (height - 1)); - if (!revertblocks()) { - instances.remove(id); - } - } - } - return false; - } - } - return true; - } - - private boolean moveEarth() { - progress++; - Block affectedblock = location.clone().add(direction).getBlock(); - location = location.add(direction); - if (GeneralMethods.isRegionProtectedFromBuild(player, "IceSpike", location)) - return false; - for (Entity en : GeneralMethods.getEntitiesAroundPoint(location, 1.4)) { - if (en instanceof LivingEntity && en != player && !damaged.contains(((LivingEntity) en))) { - LivingEntity le = (LivingEntity) en; - affect(le); - // le.setVelocity(thrown); - // le.damage(damage); - // damaged.add(le); - // Methods.verbose(damage + " Hp:" + le.getHealth()); - } - } - affectedblock.setType(Material.ICE); - WaterMethods.playIcebendingSound(block.getLocation()); - loadAffectedBlocks(); - - if (location.distance(origin) >= height) { - return false; - } - - return true; - } - - private void affect(LivingEntity entity) { - entity.setVelocity(thrown); - GeneralMethods.damageEntity(player, entity, damage, "IceSpike"); - damaged.add(entity); - long slowCooldown = IceSpike2.slowCooldown; - int mod = 2; - if (entity instanceof Player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.canBeSlowed()) { - PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, 70, mod); - new TempPotionEffect(entity, effect); - bPlayer.slow(slowCooldown); - } - } else { - PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, 70, mod); - new TempPotionEffect(entity, effect); - } - AirMethods.breakBreathbendingHold(entity); - - } - - public static boolean blockIsBase(Block block) { - if (baseblocks.containsKey(block)) { - return true; - } - return false; - } - - public static void removeBlockBase(Block block) { - if (baseblocks.containsKey(block)) { - baseblocks.remove(block); - } - - } - - public static void removeAll() { - for (int ID : instances.keySet()) { - instances.remove(ID); - } - } - - public boolean revertblocks() { - Vector direction = new Vector(0, -1, 0); - location.getBlock().setType(Material.AIR);// .clone().add(direction).getBlock().setType(Material.AIR); - location.add(direction); - if (blockIsBase(location.getBlock())) - return false; - return true; - } - - public Player getPlayer() { - return player; - } - - public double getDamage() { - return damage; - } - - public void setDamage(double damage) { - this.damage = damage; - } - - public double getRange() { - return range; - } - - public void setRange(double range) { - this.range = range; - } - - public long getCooldown() { - return cooldown; - } - - public void setCooldown(long cooldown) { - this.cooldown = cooldown; - if (player != null) - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("IceSpike", cooldown); - } - - public static String getDescription() { - return "This ability has many functions. Clicking while targetting ice, or an entity over some ice, " + "will raise a spike of ice up, damaging and slowing the target. Tapping sneak (shift) while" + " selecting a water source will select that source that can then be fired with a click. Firing" + " this will launch a spike of ice at your target, dealing a bit of damage and slowing the target. " + "If you sneak (shift) while not selecting a source, many ice spikes will erupt from around you, " + "damaging and slowing those targets."; - } - -} diff --git a/src/com/projectkorra/projectkorra/waterbending/IceSpike2.java b/src/com/projectkorra/projectkorra/waterbending/IceSpike2.java deleted file mode 100644 index df679262..00000000 --- a/src/com/projectkorra/projectkorra/waterbending/IceSpike2.java +++ /dev/null @@ -1,458 +0,0 @@ -package com.projectkorra.projectkorra.waterbending; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.ClickType; -import com.projectkorra.projectkorra.util.TempBlock; -import com.projectkorra.projectkorra.util.TempPotionEffect; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; - -public class IceSpike2 { - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - - private static double RANGE = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.IceSpike.Projectile.Range"); - private static double DAMAGE = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.IceSpike.Projectile.Damage"); - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.IceSpike.Projectile.SelectRange"); - private static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.IceSpike.Projectile.DynamicSourcing.Enabled"); - private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.IceSpike.Cooldown"); - - private static int defaultmod = 2; - private static int ID = Integer.MIN_VALUE; - static long slowCooldown = 5000; - - private static final long interval = 20; - private static final byte data = 0; - private static final double affectingradius = 2; - private static final double deflectrange = 3; - - private int id; - private double range; - private boolean prepared = false; - private boolean settingup = false; - private boolean progressing = false; - private long time; - private Location location; - private Location firstdestination; - private Location destination; - private Block sourceblock; - private Player player; - private TempBlock source; - private double defaultrange = RANGE; - private double defaultdamage = DAMAGE; - - public IceSpike2(Player player) { - if (!WaterMethods.canIcebend(player)) - return; - - block(player); - range = WaterMethods.waterbendingNightAugment(defaultrange, player.getWorld()); - this.player = player; - Block sourceblock = BlockSource.getWaterSourceBlock(player, selectRange, selectRange, ClickType.SHIFT_DOWN, false, dynamic, false, true, WaterMethods.canIcebend(player), WaterMethods.canPlantbend(player)); - - if (sourceblock == null) { - new SpikeField(player); - } else { - prepare(sourceblock); - } - - } - - private void prepare(Block block) { - for (IceSpike2 ice : getInstances(player)) { - if (ice.prepared) { - ice.cancel(); - } - } - sourceblock = block; - location = sourceblock.getLocation(); - prepared = true; - createInstance(); - } - - private void createInstance() { - id = ID++; - instances.put(id, this); - if (ID >= Integer.MAX_VALUE) { - ID = Integer.MIN_VALUE; - } - } - - private static ArrayList getInstances(Player player) { - ArrayList list = new ArrayList(); - for (int id : instances.keySet()) { - IceSpike2 ice = instances.get(id); - if (ice.player.equals(player)) { - list.add(ice); - } - } - - return list; - } - - public static void activate(Player player) { - redirect(player); - boolean activate = false; - - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (bPlayer.isOnCooldown("IceSpike")) - return; - - for (IceSpike2 ice : getInstances(player)) { - if (ice.prepared) { - ice.throwIce(); - activate = true; - } - } - - if (!activate) { - IceSpike spike = new IceSpike(player); - if (spike.id == 0) { - waterBottle(player); - } - } - } - - @SuppressWarnings("deprecation") - private static void waterBottle(Player player) { - if (WaterReturn.hasWaterBottle(player)) { - Location eyeloc = player.getEyeLocation(); - Block block = eyeloc.add(eyeloc.getDirection().normalize()).getBlock(); - if (EarthMethods.isTransparentToEarthbending(player, block) && EarthMethods.isTransparentToEarthbending(player, eyeloc.getBlock())) { - - LivingEntity target = (LivingEntity) GeneralMethods.getTargetedEntity(player, RANGE, new ArrayList()); - Location destination; - if (target == null) { - destination = GeneralMethods.getTargetedLocation(player, RANGE, EarthMethods.transparentToEarthbending); - } else { - destination = GeneralMethods.getPointOnLine(player.getEyeLocation(), target.getEyeLocation(), RANGE); - } - - if (destination.distance(block.getLocation()) < 1) - return; - - block.setType(Material.WATER); - block.setData((byte) 0x0); - IceSpike2 ice = new IceSpike2(player); - ice.throwIce(); - - if (ice.progressing) { - WaterReturn.emptyWaterBottle(player); - } else { - block.setType(Material.AIR); - } - - } - } - } - - private void throwIce() { - if (!prepared) - return; - LivingEntity target = (LivingEntity) GeneralMethods.getTargetedEntity(player, range, new ArrayList()); - if (target == null) { - destination = GeneralMethods.getTargetedLocation(player, range, EarthMethods.transparentToEarthbending); - } else { - destination = target.getEyeLocation(); - } - - location = sourceblock.getLocation(); - if (destination.distance(location) < 1) - return; - firstdestination = location.clone(); - if (destination.getY() - location.getY() > 2) { - firstdestination.setY(destination.getY() - 1); - } else { - firstdestination.add(0, 2, 0); - } - destination = GeneralMethods.getPointOnLine(firstdestination, destination, range); - progressing = true; - settingup = true; - prepared = false; - - if (WaterMethods.isPlant(sourceblock)) { - new Plantbending(sourceblock); - sourceblock.setType(Material.AIR); - } else if (!GeneralMethods.isAdjacentToThreeOrMoreSources(sourceblock)) { - sourceblock.setType(Material.AIR); - } - - source = new TempBlock(sourceblock, Material.ICE, data); - } - - public static void progressAll() { - for (int id : instances.keySet()) { - instances.get(id).progress(); - } - } - - private void progress() { - if (player.isDead() || !player.isOnline() || !GeneralMethods.canBend(player.getName(), "IceSpike")) { - cancel(); - return; - } - - if (!player.getWorld().equals(location.getWorld())) { - cancel(); - return; - } - - if (player.getEyeLocation().distance(location) >= range) { - if (progressing) { - cancel(); - returnWater(); - } else { - cancel(); - } - return; - } - - if ((GeneralMethods.getBoundAbility(player) == null || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("IceSpike")) && prepared) { - cancel(); - return; - } - - if (System.currentTimeMillis() < time + interval) - return; - - time = System.currentTimeMillis(); - - if (progressing) { - - Vector direction; - - if (location.getBlockY() == firstdestination.getBlockY()) - settingup = false; - - if (location.distance(destination) <= 2) { - cancel(); - returnWater(); - return; - } - - if (settingup) { - direction = GeneralMethods.getDirection(location, firstdestination).normalize(); - } else { - direction = GeneralMethods.getDirection(location, destination).normalize(); - } - - location.add(direction); - - Block block = location.getBlock(); - - if (block.equals(sourceblock)) - return; - - source.revertBlock(); - source = null; - - if (EarthMethods.isTransparentToEarthbending(player, block) && !block.isLiquid()) { - GeneralMethods.breakBlock(block); - } else if (!WaterMethods.isWater(block)) { - cancel(); - returnWater(); - return; - } - - if (GeneralMethods.isRegionProtectedFromBuild(player, "IceSpike", location)) { - cancel(); - returnWater(); - return; - } - - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, affectingradius)) { - if (entity.getEntityId() != player.getEntityId() && entity instanceof LivingEntity) { - affect((LivingEntity) entity); - progressing = false; - returnWater(); - } - } - - if (GeneralMethods.rand.nextInt(4) == 0) { - WaterMethods.playIcebendingSound(location); - } - - if (!progressing) { - cancel(); - return; - } - - sourceblock = block; - source = new TempBlock(sourceblock, Material.ICE, data); - - } else if (prepared) { - WaterMethods.playFocusWaterEffect(sourceblock); - } - } - - private void affect(LivingEntity entity) { - int mod = (int) WaterMethods.waterbendingNightAugment(defaultmod, player.getWorld()); - int damage = (int) WaterMethods.waterbendingNightAugment(defaultdamage, player.getWorld()); - if (entity instanceof Player) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.canBeSlowed()) { - PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, 70, mod); - new TempPotionEffect(entity, effect); - bPlayer.slow(slowCooldown); - GeneralMethods.damageEntity(player, entity, damage, "IceSpike"); - } - } else { - PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, 70, mod); - new TempPotionEffect(entity, effect); - GeneralMethods.damageEntity(player, entity, damage, "IceSpike"); - } - AirMethods.breakBreathbendingHold(entity); - - } - - private static void redirect(Player player) { - - for (int id : instances.keySet()) { - IceSpike2 ice = instances.get(id); - - if (!ice.progressing) - continue; - - if (!ice.location.getWorld().equals(player.getWorld())) - continue; - - if (ice.player.equals(player)) { - Location location; - Entity target = GeneralMethods.getTargetedEntity(player, ice.defaultrange, new ArrayList()); - if (target == null) { - location = GeneralMethods.getTargetedLocation(player, ice.defaultrange); - } else { - location = ((LivingEntity) target).getEyeLocation(); - } - location = GeneralMethods.getPointOnLine(ice.location, location, ice.defaultrange * 2); - ice.redirect(location, player); - } - - Location location = player.getEyeLocation(); - Vector vector = location.getDirection(); - Location mloc = ice.location; - if (GeneralMethods.isRegionProtectedFromBuild(player, "IceSpike", mloc)) - continue; - if (mloc.distance(location) <= ice.defaultrange && GeneralMethods.getDistanceFromLine(vector, location, ice.location) < deflectrange && mloc.distance(location.clone().add(vector)) < mloc.distance(location.clone().add(vector.clone().multiply(-1)))) { - Location loc; - Entity target = GeneralMethods.getTargetedEntity(player, ice.defaultrange, new ArrayList()); - if (target == null) { - loc = GeneralMethods.getTargetedLocation(player, ice.defaultrange); - } else { - loc = ((LivingEntity) target).getEyeLocation(); - } - loc = GeneralMethods.getPointOnLine(ice.location, loc, ice.defaultrange * 2); - ice.redirect(loc, player); - } - - } - } - - private static void block(Player player) { - for (int id : instances.keySet()) { - IceSpike2 ice = instances.get(id); - - if (ice.player.equals(player)) - continue; - - if (!ice.location.getWorld().equals(player.getWorld())) - continue; - - if (!ice.progressing) - continue; - - if (GeneralMethods.isRegionProtectedFromBuild(player, "IceSpike", ice.location)) - continue; - - Location location = player.getEyeLocation(); - Vector vector = location.getDirection(); - Location mloc = ice.location; - if (mloc.distance(location) <= ice.defaultrange && GeneralMethods.getDistanceFromLine(vector, location, ice.location) < deflectrange && mloc.distance(location.clone().add(vector)) < mloc.distance(location.clone().add(vector.clone().multiply(-1)))) { - ice.cancel(); - } - - } - } - - private void redirect(Location destination, Player player) { - this.destination = destination; - this.player = player; - } - - private void cancel() { - if (progressing) { - if (source != null) - source.revertBlock(); - progressing = false; - } - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - bPlayer.addCooldown("IceSpike", cooldown); - - instances.remove(id); - } - - private void returnWater() { - new WaterReturn(player, sourceblock); - } - - public static void removeAll() { - for (int id : instances.keySet()) { - instances.get(id).cancel(); - } - - instances.clear(); - } - - public static boolean isBending(Player player) { - for (int id : instances.keySet()) { - if (instances.get(id).player.equals(player)) - return true; - } - return false; - } - - public Player getPlayer() { - return player; - } - - public double getDefaultrange() { - return defaultrange; - } - - public void setDefaultrange(double defaultrange) { - this.defaultrange = defaultrange; - } - - public double getDefaultdamage() { - return defaultdamage; - } - - public void setDefaultdamage(double defaultdamage) { - this.defaultdamage = defaultdamage; - } - - public Block getBlock() { - return sourceblock; - } - - public void setBlock(Block block) { - this.sourceblock = block; - } -} \ No newline at end of file diff --git a/src/com/projectkorra/projectkorra/waterbending/IceSpikeBlast.java b/src/com/projectkorra/projectkorra/waterbending/IceSpikeBlast.java new file mode 100644 index 00000000..7e624eda --- /dev/null +++ b/src/com/projectkorra/projectkorra/waterbending/IceSpikeBlast.java @@ -0,0 +1,564 @@ +package com.projectkorra.projectkorra.waterbending; + +import com.projectkorra.projectkorra.BendingPlayer; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.IceAbility; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.ClickType; +import com.projectkorra.projectkorra.util.TempBlock; +import com.projectkorra.projectkorra.util.TempPotionEffect; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +import java.util.Random; + +public class IceSpikeBlast extends IceAbility { + + private boolean prepared; + private boolean settingUp; + private boolean progressing; + private byte data; + private int slowPower; + private int slowDuration; + private long time; + private long interval; + private long cooldown; + private long slowCooldown; + private double range; + private double damage; + private double affectingRadius; + private double deflectRange; + private Block sourceBlock; + private Location location; + private Location firstDestination; + private Location destination; + private TempBlock source; + + public IceSpikeBlast(Player player) { + super(player); + + this.data = 0; + this.interval = 20; + this.slowCooldown = 5000; + this.affectingRadius = 2; + this.deflectRange = 3; + this.range = getConfig().getDouble("Abilities.Water.IceSpike.Projectile.Range"); + this.damage = getConfig().getDouble("Abilities.Water.IceSpike.Projectile.Damage"); + this.cooldown = GeneralMethods.getGlobalCooldown(); + this.slowPower = 2; + this.slowDuration = 70; + + if (!bPlayer.canBend(this) || !bPlayer.canIcebend()) { + return; + } + + block(player); + this.range = getNightFactor(range); + this.damage = getNightFactor(damage); + this.slowPower = (int) getNightFactor(slowPower); + sourceBlock = BlockSource.getWaterSourceBlock(player, range, ClickType.SHIFT_DOWN, true, true, bPlayer.canPlantbend()); + + if (sourceBlock == null) { + new IceSpikePillarField(player); + } else if (GeneralMethods.isRegionProtectedFromBuild(this, sourceBlock.getLocation())) { + return; + } else { + prepare(sourceBlock); + } + } + + private void affect(LivingEntity entity) { + if (entity instanceof Player) { + BendingPlayer targetBPlayer = BendingPlayer.getBendingPlayer((Player) entity); + if (targetBPlayer == null) { + return; + } + if (targetBPlayer.canBeSlowed()) { + PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, slowDuration, slowPower); + new TempPotionEffect(entity, effect); + targetBPlayer.slow(slowCooldown); + GeneralMethods.damageEntity(this, entity, damage); + } + } else { + PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, slowDuration, slowPower); + new TempPotionEffect(entity, effect); + GeneralMethods.damageEntity(this, entity, damage); + } + AirAbility.breakBreathbendingHold(entity); + } + + private void prepare(Block block) { + for (IceSpikeBlast iceSpike : CoreAbility.getAbilities(player, IceSpikeBlast.class)) { + if (iceSpike.prepared) { + iceSpike.remove(); + } + } + + sourceBlock = block; + location = sourceBlock.getLocation(); + prepared = true; + start(); + } + + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { + remove(); + return; + } else if (player.getEyeLocation().distanceSquared(location) >= range * range) { + if (progressing) { + remove(); + returnWater(); + } else { + remove(); + } + return; + } else if (!bPlayer.getBoundAbilityName().equals(getName()) && prepared) { + remove(); + return; + } + + if (System.currentTimeMillis() < time + interval) { + return; + } + + time = System.currentTimeMillis(); + + if (progressing) { + Vector direction; + if (location.getBlockY() == firstDestination.getBlockY()) { + settingUp = false; + } + + if (location.distanceSquared(destination) <= 4) { + remove(); + returnWater(); + return; + } + + if (settingUp) { + direction = GeneralMethods.getDirection(location, firstDestination).normalize(); + } else { + direction = GeneralMethods.getDirection(location, destination).normalize(); + } + + location.add(direction); + Block block = location.getBlock(); + if (block.equals(sourceBlock)) { + return; + } + + if (source != null) { + source.revertBlock(); + } + source = null; + + if (isTransparentToEarthbending(player, block) && !block.isLiquid()) { + GeneralMethods.breakBlock(block); + } else if (!isWater(block)) { + remove(); + returnWater(); + return; + } + + if (GeneralMethods.isRegionProtectedFromBuild(this, location)) { + remove(); + returnWater(); + return; + } + + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, affectingRadius)) { + if (entity.getEntityId() != player.getEntityId() && entity instanceof LivingEntity) { + affect((LivingEntity) entity); + progressing = false; + returnWater(); + } + } + + if ((new Random()).nextInt(4) == 0) { + playIcebendingSound(location); + } + + if (!progressing) { + remove(); + return; + } + + sourceBlock = block; + source = new TempBlock(sourceBlock, Material.ICE, data); + } else if (prepared) { + playFocusWaterEffect(sourceBlock); + } + } + + private void redirect(Location destination, Player player) { + this.destination = destination; + this.player = player; + } + + @Override + public void remove() { + super.remove(); + if (progressing) { + if (source != null) { + source.revertBlock(); + } + progressing = false; + } + bPlayer.addCooldown(this); + } + + private void returnWater() { + new WaterReturn(player, sourceBlock); + } + + private void throwIce() { + if (!prepared) { + return; + } + + LivingEntity target = (LivingEntity) GeneralMethods.getTargetedEntity(player, range); + if (target == null) { + destination = GeneralMethods.getTargetedLocation(player, range, getTransparentMaterial()); + } else { + destination = target.getEyeLocation(); + } + + location = sourceBlock.getLocation(); + if (destination.distanceSquared(location) < 1) { + return; + } + + firstDestination = location.clone(); + if (destination.getY() - location.getY() > 2) { + firstDestination.setY(destination.getY() - 1); + } else { + firstDestination.add(0, 2, 0); + } + + destination = GeneralMethods.getPointOnLine(firstDestination, destination, range); + progressing = true; + settingUp = true; + prepared = false; + + if (isPlant(sourceBlock)) { + new PlantRegrowth(player, sourceBlock); + sourceBlock.setType(Material.AIR); + } + + new TempBlock(sourceBlock, Material.AIR, data); + } + + public static void activate(Player player) { + redirect(player); + boolean activate = false; + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + + if (bPlayer == null) { + return; + } else if (bPlayer.isOnCooldown("IceSpike")) { + return; + } + + for (IceSpikeBlast ice : CoreAbility.getAbilities(player, IceSpikeBlast.class)) { + if (ice.prepared) { + ice.throwIce(); + activate = true; + } + } + + if (!activate) { + IceSpikePillar spike = new IceSpikePillar(player); + if (!spike.isStarted()) { + waterBottle(player); + } + } + } + + private static void block(Player player) { + for (IceSpikeBlast iceSpike : CoreAbility.getAbilities(IceSpikeBlast.class)) { + if (iceSpike.player.equals(player)) { + continue; + } else if (!iceSpike.location.getWorld().equals(player.getWorld())) { + continue; + } else if (!iceSpike.progressing) { + continue; + } if (GeneralMethods.isRegionProtectedFromBuild(iceSpike, iceSpike.location)) { + continue; + } + + Location location = player.getEyeLocation(); + Vector vector = location.getDirection(); + Location mloc = iceSpike.location; + if (mloc.distanceSquared(location) <= iceSpike.range * iceSpike.range + && GeneralMethods.getDistanceFromLine(vector, location, iceSpike.location) < iceSpike.deflectRange + && mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) { + iceSpike.remove(); + } + } + } + + private static void redirect(Player player) { + for (IceSpikeBlast iceSpike : CoreAbility.getAbilities(IceSpikeBlast.class)) { + if (!iceSpike.progressing) { + continue; + } else if (!iceSpike.location.getWorld().equals(player.getWorld())) { + continue; + } + + if (iceSpike.player.equals(player)) { + Location location; + Entity target = GeneralMethods.getTargetedEntity(player, iceSpike.range); + if (target == null) { + location = GeneralMethods.getTargetedLocation(player, iceSpike.range); + } else { + location = ((LivingEntity) target).getEyeLocation(); + } + location = GeneralMethods.getPointOnLine(iceSpike.location, location, iceSpike.range * 2); + iceSpike.redirect(location, player); + } + + Location location = player.getEyeLocation(); + Vector vector = location.getDirection(); + Location mloc = iceSpike.location; + + if (GeneralMethods.isRegionProtectedFromBuild(iceSpike, mloc)) { + continue; + } else if (mloc.distanceSquared(location) <= iceSpike.range * iceSpike.range + && GeneralMethods.getDistanceFromLine(vector, location, iceSpike.location) < iceSpike.deflectRange + && mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) { + Location loc; + Entity target = GeneralMethods.getTargetedEntity(player, iceSpike.range); + if (target == null) { + loc = GeneralMethods.getTargetedLocation(player, iceSpike.range); + } else { + loc = ((LivingEntity) target).getEyeLocation(); + } + loc = GeneralMethods.getPointOnLine(iceSpike.location, loc, iceSpike.range * 2); + iceSpike.redirect(loc, player); + } + + } + } + + @SuppressWarnings("deprecation") + private static void waterBottle(Player player) { + long range = getConfig().getLong("Abilities.Water.IceSpike.Projectile.Range"); + + if (WaterReturn.hasWaterBottle(player)) { + Location eyeLoc = player.getEyeLocation(); + Block block = eyeLoc.add(eyeLoc.getDirection().normalize()).getBlock(); + + if (isTransparentToEarthbending(player, block) && isTransparentToEarthbending(player, eyeLoc.getBlock())) { + LivingEntity target = (LivingEntity) GeneralMethods.getTargetedEntity(player, range); + Location destination; + + if (target == null) { + destination = GeneralMethods.getTargetedLocation(player, range, getTransparentMaterial()); + } else { + destination = GeneralMethods.getPointOnLine(player.getEyeLocation(), target.getEyeLocation(), range); + } + + if (destination.distanceSquared(block.getLocation()) < 1) { + return; + } + + block.setType(Material.WATER); + block.setData((byte) 0x0); + IceSpikeBlast iceSpike = new IceSpikeBlast(player); + iceSpike.throwIce(); + + if (iceSpike.progressing) { + WaterReturn.emptyWaterBottle(player); + } else { + block.setType(Material.AIR); + } + } + } + } + + @Override + public String getName() { + return "IceSpike"; + } + + @Override + public Location getLocation() { + if (location != null) { + return location; + } else if (sourceBlock != null) { + return sourceBlock.getLocation(); + } + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isPrepared() { + return prepared; + } + + public void setPrepared(boolean prepared) { + this.prepared = prepared; + } + + public boolean isSettingUp() { + return settingUp; + } + + public void setSettingUp(boolean settingUp) { + this.settingUp = settingUp; + } + + public boolean isProgressing() { + return progressing; + } + + public void setProgressing(boolean progressing) { + this.progressing = progressing; + } + + public byte getData() { + return data; + } + + public void setData(byte data) { + this.data = data; + } + + public int getSlowPower() { + return slowPower; + } + + public void setSlowPower(int slowPower) { + this.slowPower = slowPower; + } + + public int getSlowDuration() { + return slowDuration; + } + + public void setSlowDuration(int slowDuration) { + this.slowDuration = slowDuration; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public long getSlowCooldown() { + return slowCooldown; + } + + public void setSlowCooldown(long slowCooldown) { + this.slowCooldown = slowCooldown; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getDamage() { + return damage; + } + + public void setDamage(double damage) { + this.damage = damage; + } + + public double getAffectingRadius() { + return affectingRadius; + } + + public void setAffectingRadius(double affectingRadius) { + this.affectingRadius = affectingRadius; + } + + public double getDeflectRange() { + return deflectRange; + } + + public void setDeflectRange(double deflectRange) { + this.deflectRange = deflectRange; + } + + public Block getSourceBlock() { + return sourceBlock; + } + + public void setSourceBlock(Block sourceBlock) { + this.sourceBlock = sourceBlock; + } + + public Location getFirstDestination() { + return firstDestination; + } + + public void setFirstDestination(Location firstDestination) { + this.firstDestination = firstDestination; + } + + public Location getDestination() { + return destination; + } + + public void setDestination(Location destination) { + this.destination = destination; + } + + public TempBlock getSource() { + return source; + } + + public void setSource(TempBlock source) { + this.source = source; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/waterbending/IceSpikePillar.java b/src/com/projectkorra/projectkorra/waterbending/IceSpikePillar.java new file mode 100644 index 00000000..35e13fd9 --- /dev/null +++ b/src/com/projectkorra/projectkorra/waterbending/IceSpikePillar.java @@ -0,0 +1,431 @@ +package com.projectkorra.projectkorra.waterbending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.IceAbility; +import com.projectkorra.projectkorra.util.TempPotionEffect; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.concurrent.ConcurrentHashMap; + +public class IceSpikePillar extends IceAbility { + + private static final ConcurrentHashMap ALREADY_DONE_BLOCKS = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap BASE_BLOCKS = new ConcurrentHashMap<>(); + + private int height; + private int progress; + private int slowPower; + private int slowDuration; + private long cooldown; + private long time; + private long removeTimestamp; + private long removeTimer; + private long interval; + private long slowCooldown; + private double damage; + private double range; + private double speed; + private Block block; + private Location origin; + private Location location; + private Vector thrownForce; + private Vector direction; + private ConcurrentHashMap affectedBlocks; + private ArrayList damaged; + + public IceSpikePillar(Player player) { + super(player); + setFields(); + + if (bPlayer.isOnCooldown(this)) { + return; + } + + try { + double lowestDistance = range + 1; + Entity closestEntity = null; + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), range)) { + if (GeneralMethods.getDistanceFromLine(player.getLocation().getDirection(), player.getLocation(), entity.getLocation()) <= 2 + && (entity instanceof LivingEntity) + && (entity.getEntityId() != player.getEntityId())) { + double distance = player.getLocation().distance(entity.getLocation()); + if (distance < lowestDistance) { + closestEntity = entity; + lowestDistance = distance; + } + } + } + + if (closestEntity != null) { + Block tempTestingBlock = closestEntity.getLocation().getBlock().getRelative(BlockFace.DOWN, 1); + this.block = tempTestingBlock; + } else { + this.block = player.getTargetBlock((HashSet) null, (int) range); + } + origin = block.getLocation(); + location = origin.clone(); + } catch (IllegalStateException e) { + return; + } + + loadAffectedBlocks(); + + if (height != 0) { + if (canInstantiate()) { + start(); + time = System.currentTimeMillis() - interval; + bPlayer.addCooldown(this); + } + } + } + + public IceSpikePillar(Player player, Location origin, int damage, Vector throwing, long aoecooldown) { + super(player); + setFields(); + + this.cooldown = aoecooldown; + this.player = player; + this.origin = origin; + this.damage = damage; + this.thrownForce = throwing; + this.location = origin.clone(); + this.block = location.getBlock(); + + loadAffectedBlocks(); + + if (block.getType() == Material.ICE) { + if (canInstantiate()) { + start(); + time = System.currentTimeMillis() - interval; + } + } + } + + private void setFields() { + this.height = 2; + this.direction = new Vector(0, 1, 0); + this.speed = 25; + this.interval = (long) (1000. / speed); + this.slowCooldown = 5000; + this.slowPower = 2; + this.slowDuration = 70; + this.damage = getConfig().getDouble("Abilities.Water.IceSpike.Damage"); + this.range = getConfig().getDouble("Abilities.Water.IceSpike.Range"); + this.cooldown = getConfig().getLong("Abilities.Water.IceSpike.Cooldown"); + this.height = getConfig().getInt("Abilities.Water.IceSpike.Height"); + this.thrownForce = new Vector(0, ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.IceSpike.ThrowingMult"), 0); + this.affectedBlocks = new ConcurrentHashMap<>(); + this.damaged = new ArrayList<>(); + } + + private void loadAffectedBlocks() { + affectedBlocks.clear(); + Block thisBlock; + for (int i = 1; i <= height; i++) { + thisBlock = block.getWorld().getBlockAt(location.clone().add(direction.clone().multiply(i))); + affectedBlocks.put(thisBlock, thisBlock); + } + } + + private boolean blockInAffectedBlocks(Block block) { + return affectedBlocks.containsKey(block); + } + + public static boolean blockInAllAffectedBlocks(Block block) { + for (IceSpikePillar iceSpike : CoreAbility.getAbilities(IceSpikePillar.class)) { + if (iceSpike.blockInAffectedBlocks(block)) { + return true; + } + } + return false; + } + + public static void revertBlock(Block block) { + for (IceSpikePillar iceSpike : CoreAbility.getAbilities(IceSpikePillar.class)) { + iceSpike.affectedBlocks.remove(block); + } + } + + private boolean canInstantiate() { + if (block.getType() != Material.ICE) { + return false; + } + for (Block block : affectedBlocks.keySet()) { + if (blockInAllAffectedBlocks(block) || ALREADY_DONE_BLOCKS.containsKey(block) + || block.getType() != Material.AIR + || (block.getX() == player.getEyeLocation().getBlock().getX() && block.getZ() == player.getEyeLocation().getBlock().getZ())) { + return false; + } + } + return true; + } + + @Override + public void progress() { + if (System.currentTimeMillis() - time >= interval) { + time = System.currentTimeMillis(); + if (progress < height) { + moveEarth(); + removeTimestamp = System.currentTimeMillis(); + } else { + if (removeTimestamp != 0 && removeTimestamp + removeTimer <= System.currentTimeMillis()) { + BASE_BLOCKS.put(location.clone().add(direction.clone().multiply(-1 * (height))).getBlock(), (height - 1)); + if (!revertblocks()) { + remove(); + return; + } + } + } + } + } + + private boolean moveEarth() { + progress++; + Block affectedBlock = location.clone().add(direction).getBlock(); + location = location.add(direction); + + if (GeneralMethods.isRegionProtectedFromBuild(this, location)) { + return false; + } + + for (Entity en : GeneralMethods.getEntitiesAroundPoint(location, 1.4)) { + if (en instanceof LivingEntity && en != player && !damaged.contains((en))) { + LivingEntity le = (LivingEntity) en; + affect(le); + } + } + + affectedBlock.setType(Material.ICE); + playIcebendingSound(block.getLocation()); + loadAffectedBlocks(); + + if (location.distanceSquared(origin) >= height * height) { + return false; + } + return true; + } + + private void affect(LivingEntity entity) { + entity.setVelocity(thrownForce); + GeneralMethods.damageEntity(this, entity, damage); + damaged.add(entity); + + if (entity instanceof Player) { + if (bPlayer.canBeSlowed()) { + PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, slowDuration, slowPower); + new TempPotionEffect(entity, effect); + bPlayer.slow(slowCooldown); + } + } else { + PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, slowDuration, slowPower); + new TempPotionEffect(entity, effect); + } + AirAbility.breakBreathbendingHold(entity); + } + + public static boolean blockIsBase(Block block) { + return block != null ? BASE_BLOCKS.containsKey(block) : null; + } + + public static void removeBlockBase(Block block) { + if (block != null) { + BASE_BLOCKS.remove(block); + } + } + + public boolean revertblocks() { + Vector direction = new Vector(0, -1, 0); + location.getBlock().setType(Material.AIR); + location.add(direction); + + if (blockIsBase(location.getBlock())) { + return false; + } + return true; + } + + @Override + public String getName() { + return "IceSpike"; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getProgress() { + return progress; + } + + public void setProgress(int progress) { + this.progress = progress; + } + + public int getSlowPower() { + return slowPower; + } + + public void setSlowPower(int slowPower) { + this.slowPower = slowPower; + } + + public int getSlowDuration() { + return slowDuration; + } + + public void setSlowDuration(int slowDuration) { + this.slowDuration = slowDuration; + } + + @Override + public long getCooldown() { + return cooldown; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getRemoveTimestamp() { + return removeTimestamp; + } + + public void setRemoveTimestamp(long removeTimestamp) { + this.removeTimestamp = removeTimestamp; + } + + public long getRemoveTimer() { + return removeTimer; + } + + public void setRemoveTimer(long removeTimer) { + this.removeTimer = removeTimer; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public long getSlowCooldown() { + return slowCooldown; + } + + public void setSlowCooldown(long slowCooldown) { + this.slowCooldown = slowCooldown; + } + + public double getDamage() { + return damage; + } + + public void setDamage(double damage) { + this.damage = damage; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public Block getBlock() { + return block; + } + + public void setBlock(Block block) { + this.block = block; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + @Override + public Location getLocation() { + return location; + } + + public void setLocation(Location location) { + this.location = location; + } + + public Vector getThrownForce() { + return thrownForce; + } + + public void setThrownForce(Vector thrownForce) { + this.thrownForce = thrownForce; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public static ConcurrentHashMap getAlreadyDoneBlocks() { + return ALREADY_DONE_BLOCKS; + } + + public static ConcurrentHashMap getBaseBlocks() { + return BASE_BLOCKS; + } + +} diff --git a/src/com/projectkorra/projectkorra/waterbending/IceSpikePillarField.java b/src/com/projectkorra/projectkorra/waterbending/IceSpikePillarField.java new file mode 100644 index 00000000..38bc1366 --- /dev/null +++ b/src/com/projectkorra/projectkorra/waterbending/IceSpikePillarField.java @@ -0,0 +1,164 @@ +package com.projectkorra.projectkorra.waterbending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.IceAbility; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class IceSpikePillarField extends IceAbility { + + private int damage; + private int radius; + private int numberOfSpikes; + private long cooldown; + private Vector thrownForce; + + public IceSpikePillarField(Player player) { + super(player); + + this.damage = 2; + this.radius = 6; + this.numberOfSpikes = ((radius * 2) * (radius * 2)) / 16; + this.cooldown = getConfig().getLong("Abilities.Water.IceSpike.Cooldown"); + this.thrownForce = new Vector(0, 1, 0); + + if (bPlayer.isOnCooldown(this)) { + return; + } + + Random random = new Random(); + int locX = player.getLocation().getBlockX(); + int locY = player.getLocation().getBlockY(); + int locZ = player.getLocation().getBlockZ(); + List iceBlocks = new ArrayList(); + + for (int x = -(radius - 1); x <= (radius - 1); x++) { + for (int z = -(radius - 1); z <= (radius - 1); z++) { + for (int y = -1; y <= 1; y++) { + Block testBlock = player.getWorld().getBlockAt(locX + x, locY + y, locZ + z); + + if (testBlock.getType() == Material.ICE + && testBlock.getRelative(BlockFace.UP).getType() == Material.AIR + && !(testBlock.getX() == player.getEyeLocation().getBlock().getX() + && testBlock.getZ() == player.getEyeLocation().getBlock().getZ())) { + iceBlocks.add(testBlock); + for(Block iceBlockForSound : iceBlocks) { + playIcebendingSound(iceBlockForSound.getLocation()); + } + } + } + } + } + + List entities = GeneralMethods.getEntitiesAroundPoint(player.getLocation(), radius); + for (int i = 0; i < numberOfSpikes; i++) { + if (iceBlocks.isEmpty()) { + return; + } + + Entity target = null; + Block targetBlock = null; + for (Entity entity : entities) { + if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId()) { + for (Block block : iceBlocks) { + if (block.getX() == entity.getLocation().getBlockX() && block.getZ() == entity.getLocation().getBlockZ()) { + target = entity; + targetBlock = block; + break; + } + } + } else { + continue; + } + } + + if (target != null) { + entities.remove(target); + } else { + targetBlock = iceBlocks.get(random.nextInt(iceBlocks.size())); + } + + if (targetBlock.getRelative(BlockFace.UP).getType() != Material.ICE) { + new IceSpikePillar(player, targetBlock.getLocation(), damage, thrownForce, cooldown); + bPlayer.addCooldown(this); + iceBlocks.remove(targetBlock); + } + } + } + + @Override + public String getName() { + return "IceSpike"; + } + + @Override + public void progress() {} + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public int getDamage() { + return damage; + } + + public void setDamage(int damage) { + this.damage = damage; + } + + public int getRadius() { + return radius; + } + + public void setRadius(int radius) { + this.radius = radius; + } + + public int getNumberOfSpikes() { + return numberOfSpikes; + } + + public void setNumberOfSpikes(int numberOfSpikes) { + this.numberOfSpikes = numberOfSpikes; + } + + public Vector getThrownForce() { + return thrownForce; + } + + public void setThrownForce(Vector thrownForce) { + this.thrownForce = thrownForce; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + +} \ No newline at end of file diff --git a/src/com/projectkorra/projectkorra/waterbending/Melt.java b/src/com/projectkorra/projectkorra/waterbending/Melt.java deleted file mode 100644 index ce40e76e..00000000 --- a/src/com/projectkorra/projectkorra/waterbending/Melt.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.projectkorra.projectkorra.waterbending; - -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.util.TempBlock; - -import org.bukkit.Effect; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; - -import java.util.HashSet; - -public class Melt { - - private static final int seaLevel = ProjectKorra.plugin.getConfig().getInt("Properties.SeaLevel"); - - private static final int defaultrange = FreezeMelt.defaultrange; - private static final int defaultradius = FreezeMelt.defaultradius; - private static final int defaultevaporateradius = 3; - - private static final byte full = 0x0; - - public Melt(Player player) { - if (!WaterMethods.canIcebend(player)) - return; - - int range = (int) WaterMethods.waterbendingNightAugment(defaultrange, player.getWorld()); - int radius = (int) WaterMethods.waterbendingNightAugment(defaultradius, player.getWorld()); - - if (AvatarState.isAvatarState(player)) { - range = AvatarState.getValue(range); - radius = AvatarState.getValue(radius); - } - boolean evaporate = false; - Location location = GeneralMethods.getTargetedLocation(player, range); - if (WaterMethods.isWater(player.getTargetBlock((HashSet) null, range)) && !(player.getEyeLocation().getBlockY() <= 62)) { - evaporate = true; - radius = (int) WaterMethods.waterbendingNightAugment(defaultevaporateradius, player.getWorld()); - } - for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) { - if (evaporate) { - if (block.getY() > seaLevel) - evaporate(player, block); - } else { - melt(player, block); - } - } - - } - - @SuppressWarnings("deprecation") - public static void melt(Player player, Block block) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "PhaseChange", block.getLocation())) - return; - if (!Wave.canThaw(block)) { - Wave.thaw(block); - return; - } - if (!Torrent.canThaw(block)) { - Torrent.thaw(block); - return; - } - WaterWave.thaw(block); - WaterCombo.thaw(block); - if (WaterMethods.isMeltable(block) && !TempBlock.isTempBlock(block) && WaterManipulation.canPhysicsChange(block)) { - if (block.getType() == Material.SNOW) { - block.setType(Material.AIR); - return; - } - if (FreezeMelt.frozenblocks.containsKey(block)) { - FreezeMelt.thaw(block); - } else { - block.setType(Material.WATER); - block.setData(full); - } - } - } - - public static void evaporate(Player player, Block block) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "PhaseChange", block.getLocation())) - return; - if (WaterMethods.isWater(block) && !TempBlock.isTempBlock(block) && WaterManipulation.canPhysicsChange(block)) { - block.setType(Material.AIR); - block.getWorld().playEffect(block.getLocation(), Effect.SMOKE, 1); - } - } - -} diff --git a/src/com/projectkorra/projectkorra/waterbending/OctopusForm.java b/src/com/projectkorra/projectkorra/waterbending/OctopusForm.java index 100d98ac..56c5560f 100644 --- a/src/com/projectkorra/projectkorra/waterbending/OctopusForm.java +++ b/src/com/projectkorra/projectkorra/waterbending/OctopusForm.java @@ -1,7 +1,13 @@ package com.projectkorra.projectkorra.waterbending; -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.ClickType; +import com.projectkorra.projectkorra.util.TempBlock; import org.bukkit.Location; import org.bukkit.Material; @@ -12,92 +18,86 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.ClickType; -import com.projectkorra.projectkorra.util.TempBlock; +import java.util.ArrayList; +import java.util.Random; -public class OctopusForm { +public class OctopusForm extends WaterAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap(); + private static final byte FULL = 0; - private static double ATTACK_RANGE = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.OctopusForm.AttackRange"); - private static int DAMAGE = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.OctopusForm.Damage"); - private static long INTERVAL = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.OctopusForm.FormDelay"); - private static double KNOCKBACK = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.OctopusForm.Knockback"); - static double RADIUS = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.OctopusForm.Radius"); - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.OctopusForm.SelectRange"); - private static boolean auto = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.OctopusForm.AutoSourcing.Enabled"); - private static long autocooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.OctopusForm.AutoSourcing.Cooldown"); - private static int autoSelectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.OctopusForm.AutoSourcing.SelectRange"); - private static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.OctopusForm.DynamicSourcing.Enabled"); - - private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.OctopusForm.Cooldown"); - - private static final byte full = 0x0; - - private boolean isAuto; - - private Player player; - private Block sourceblock; - private Location sourcelocation; - private TempBlock source; + private boolean sourceSelected; + private boolean settingUp; + private boolean forming; + private boolean formed; + private int range; + private int damage; + private int currentAnimationStep; + private int stepCounter; + private int totalStepCount; private long time; - private double startangle; + private long interval; + private long cooldown; + private double attackRange; + private double knockback; + private double radius; + private double startAngle; private double angle; - private double y = 0; - private double dta = 45; - private int animstep = 1, step = 1, inc = 3; - private ArrayList blocks = new ArrayList(); - private ArrayList newblocks = new ArrayList(); - // private static ArrayList water = new ArrayList(); - private boolean sourceselected = false; - private boolean settingup = false; - private boolean forming = false; - private boolean formed = false; - private double attackRange = ATTACK_RANGE; - private int damage = DAMAGE; - private long interval = INTERVAL; - private double knockback = KNOCKBACK; - private double radius = RADIUS; - + private double currentFormHeight; + private double angleIncrement; + private Block sourceBlock; + private TempBlock source; + private Location sourceLocation; + private ArrayList blocks; + private ArrayList newBlocks; + public OctopusForm(Player player) { - if (instances.containsKey(player)) { - if (instances.get(player).formed) { - instances.get(player).attack(); + super(player); + + OctopusForm oldOctopus = CoreAbility.getAbility(player, OctopusForm.class); + if (oldOctopus != null) { + if (oldOctopus.formed) { + oldOctopus.attack(); return; - } else if (!instances.get(player).sourceselected) { + } else if (!oldOctopus.sourceSelected) { return; } } - this.player = player; - if (GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("OctopusForm")) - return; - time = System.currentTimeMillis(); - sourceblock = BlockSource.getWaterSourceBlock(player, autoSelectRange, selectRange, ClickType.SHIFT_DOWN, auto, dynamic, true, true, WaterMethods.canIcebend(player), WaterMethods.canPlantbend(player)); - if (BlockSource.isAuto(sourceblock)) { - isAuto = true; - } else { - isAuto = false; - } - if (sourceblock != null) { - sourcelocation = sourceblock.getLocation(); - sourceselected = true; - instances.put(player, this); + + this.sourceSelected = false; + this.settingUp = false; + this.forming = false; + this.formed = false; + this.currentAnimationStep = 1; + this.stepCounter = 1; + this.totalStepCount = 3; + this.range = getConfig().getInt("Abilities.Water.OctopusForm.Range"); + this.damage = getConfig().getInt("Abilities.Water.OctopusForm.Damage"); + this.interval = getConfig().getLong("Abilities.Water.OctopusForm.FormDelay"); + this.attackRange = getConfig().getInt("Abilities.Water.OctopusForm.AttackRange"); + this.knockback = getConfig().getDouble("Abilities.Water.OctopusForm.Knockback"); + this.radius = getConfig().getDouble("Abilities.Water.OctopusForm.Radius"); + this.cooldown = 0; + this.currentFormHeight = 0; + this.angleIncrement = 45; + this.blocks = new ArrayList(); + this.newBlocks = new ArrayList(); + this.time = System.currentTimeMillis(); + this.sourceBlock = BlockSource.getWaterSourceBlock(player, range, ClickType.LEFT_CLICK, true, true, bPlayer.canPlantbend()); + + if (sourceBlock != null) { + sourceLocation = sourceBlock.getLocation(); + sourceSelected = true; + start(); + bPlayer.addCooldown(this); } } private void incrementStep() { - if (sourceselected) { - sourceselected = false; - settingup = true; - } else if (settingup) { - settingup = false; + if (sourceSelected) { + sourceSelected = false; + settingUp = true; + } else if (settingUp) { + settingUp = false; forming = true; } else if (forming) { forming = false; @@ -107,17 +107,21 @@ public class OctopusForm { @SuppressWarnings("deprecation") public static void form(Player player) { - if (instances.containsKey(player)) { - instances.get(player).form(); + OctopusForm oldForm = CoreAbility.getAbility(player, OctopusForm.class); + + if (oldForm != null) { + oldForm.form(); } else if (WaterReturn.hasWaterBottle(player)) { - Location eyeloc = player.getEyeLocation(); - Block block = eyeloc.add(eyeloc.getDirection().normalize()).getBlock(); - if (EarthMethods.isTransparentToEarthbending(player, block) && EarthMethods.isTransparentToEarthbending(player, eyeloc.getBlock())) { + Location eyeLoc = player.getEyeLocation(); + Block block = eyeLoc.add(eyeLoc.getDirection().normalize()).getBlock(); + + if (isTransparentToEarthbending(player, block) && isTransparentToEarthbending(player, eyeLoc.getBlock())) { block.setType(Material.WATER); - block.setData(full); + block.setData(FULL); OctopusForm form = new OctopusForm(player); form.form(); - if (form.formed || form.forming || form.settingup) { + + if (form.formed || form.forming || form.settingUp) { WaterReturn.emptyWaterBottle(player); } else { block.setType(Material.AIR); @@ -128,21 +132,22 @@ public class OctopusForm { private void form() { incrementStep(); - if (WaterMethods.isPlant(sourceblock)) { - new Plantbending(sourceblock); - sourceblock.setType(Material.AIR); - } else if (!GeneralMethods.isAdjacentToThreeOrMoreSources(sourceblock)) { - sourceblock.setType(Material.AIR); + if (isPlant(sourceBlock)) { + new PlantRegrowth(player, sourceBlock); + sourceBlock.setType(Material.AIR); + } else if (!GeneralMethods.isAdjacentToThreeOrMoreSources(sourceBlock)) { + sourceBlock.setType(Material.AIR); } - source = new TempBlock(sourceblock, Material.STATIONARY_WATER, (byte) 8); + source = new TempBlock(sourceBlock, Material.STATIONARY_WATER, (byte) 8); } private void attack() { - if (!formed) + if (!formed) { return; - double tentacleangle = (new Vector(1, 0, 0)).angle(player.getEyeLocation().getDirection()) + dta / 2; + } + double tentacleAngle = (new Vector(1, 0, 0)).angle(player.getEyeLocation().getDirection()) + angleIncrement / 2; - for (double tangle = tentacleangle; tangle < tentacleangle + 360; tangle += dta) { + for (double tangle = tentacleAngle; tangle < tentacleAngle + 360; tangle += angleIncrement) { double phi = Math.toRadians(tangle); affect(player.getLocation().clone().add(new Vector(radius * Math.cos(phi), 1, radius * Math.sin(phi)))); } @@ -150,192 +155,177 @@ public class OctopusForm { private void affect(Location location) { for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, attackRange)) { - if (entity.getEntityId() == player.getEntityId()) + if (entity.getEntityId() == player.getEntityId()) { continue; - if (GeneralMethods.isRegionProtectedFromBuild(player, "OctopusForm", entity.getLocation())) + } else if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) { continue; - // if (Torrent.canThaw(entity.getLocation().getBlock()) - // || Wave.canThaw(entity.getLocation().getBlock())) - // continue; - if (GeneralMethods.isObstructed(location, entity.getLocation())) + } else if (GeneralMethods.isObstructed(location, entity.getLocation())) { continue; - double knock = AvatarState.isAvatarState(player) ? AvatarState.getValue(knockback) : knockback; + } + + double knock = bPlayer.isAvatarState() ? AvatarState.getValue(knockback) : knockback; entity.setVelocity(GeneralMethods.getDirection(player.getLocation(), location).normalize().multiply(knock)); - if (entity instanceof LivingEntity) - GeneralMethods.damageEntity(player, entity, damage, "OctopusForm"); - AirMethods.breakBreathbendingHold(entity); + + if (entity instanceof LivingEntity) { + GeneralMethods.damageEntity(this, entity, damage); + } + AirAbility.breakBreathbendingHold(entity); } } - public static void progressAll() { - for (Player player : instances.keySet()) { - instances.get(player).progress(); - } - // replaceWater(); - } - - private void progress() { - if (player.isDead() || !player.isOnline()) { + @Override + public void progress() { + if (!bPlayer.canBendIgnoreCooldowns(this)) { + remove(); + return; + } else if (!player.isSneaking() && !sourceSelected) { + remove(); + return; + } else if (sourceBlock.getLocation().distanceSquared(player.getLocation()) > range * range && sourceSelected) { remove(); return; } - if (!GeneralMethods.canBend(player.getName(), "OctopusForm")) { - remove(); - returnWater(); - return; - } - - if (GeneralMethods.getBoundAbility(player) == null) { - remove(); - returnWater(); - return; - } - - if ((!player.isSneaking() && !sourceselected) || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("OctopusForm")) { - remove(); - returnWater(); - return; - } - - if (!sourceblock.getWorld().equals(player.getWorld())) { - remove(); - return; - } - - if (sourceblock.getLocation().distance(player.getLocation()) > selectRange && sourceselected) { - remove(); - return; - } + Random random = new Random(); if (System.currentTimeMillis() > time + interval) { time = System.currentTimeMillis(); - Location location = player.getLocation(); - if (sourceselected) { - WaterMethods.playFocusWaterEffect(sourceblock); - } else if (settingup) { - if (sourceblock.getY() < location.getBlockY()) { + if (sourceSelected) { + playFocusWaterEffect(sourceBlock); + } else if (settingUp) { + if (sourceBlock.getY() < location.getBlockY()) { source.revertBlock(); source = null; - Block newblock = sourceblock.getRelative(BlockFace.UP); - sourcelocation = newblock.getLocation(); - if (!GeneralMethods.isSolid(newblock)) { - source = new TempBlock(newblock, Material.STATIONARY_WATER, (byte) 8); - sourceblock = newblock; + Block newBlock = sourceBlock.getRelative(BlockFace.UP); + sourceLocation = newBlock.getLocation(); + + if (!GeneralMethods.isSolid(newBlock)) { + source = new TempBlock(newBlock, Material.STATIONARY_WATER, (byte) 8); + sourceBlock = newBlock; } else { remove(); - returnWater(); + return; } - } else if (sourceblock.getY() > location.getBlockY()) { + } else if (sourceBlock.getY() > location.getBlockY()) { source.revertBlock(); source = null; - Block newblock = sourceblock.getRelative(BlockFace.DOWN); - sourcelocation = newblock.getLocation(); - if (!GeneralMethods.isSolid(newblock)) { - source = new TempBlock(newblock, Material.STATIONARY_WATER, (byte) 8); - sourceblock = newblock; + Block newBlock = sourceBlock.getRelative(BlockFace.DOWN); + sourceLocation = newBlock.getLocation(); + + if (!GeneralMethods.isSolid(newBlock)) { + source = new TempBlock(newBlock, Material.STATIONARY_WATER, (byte) 8); + sourceBlock = newBlock; } else { remove(); - returnWater(); + return; } - } else if (sourcelocation.distance(location) > radius) { - Vector vector = GeneralMethods.getDirection(sourcelocation, location.getBlock().getLocation()).normalize(); - sourcelocation.add(vector); - Block newblock = sourcelocation.getBlock(); - if (!newblock.equals(sourceblock)) { + } else if (sourceLocation.distanceSquared(location) > radius * radius) { + Vector vector = GeneralMethods.getDirection(sourceLocation, location.getBlock().getLocation()).normalize(); + sourceLocation.add(vector); + Block newBlock = sourceLocation.getBlock(); + + if (!newBlock.equals(sourceBlock)) { if (source != null) { source.revertBlock(); } - if (!GeneralMethods.isSolid(newblock)) { - source = new TempBlock(newblock, Material.STATIONARY_WATER, (byte) 8); - sourceblock = newblock; + if (!GeneralMethods.isSolid(newBlock)) { + source = new TempBlock(newBlock, Material.STATIONARY_WATER, (byte) 8); + sourceBlock = newBlock; } } } else { incrementStep(); - if (source != null) + if (source != null) { source.revertBlock(); + } + source = null; Vector vector = new Vector(1, 0, 0); - startangle = vector.angle(GeneralMethods.getDirection(sourceblock.getLocation(), location)); - angle = startangle; + startAngle = vector.angle(GeneralMethods.getDirection(sourceBlock.getLocation(), location)); + angle = startAngle; } } else if (forming) { - - if (angle - startangle >= 360) { - y += 1; + if (angle - startAngle >= 360) { + currentFormHeight += 1; } else { angle += 20; } - if (GeneralMethods.rand.nextInt(4) == 0) { - WaterMethods.playWaterbendingSound(player.getLocation()); + + if (random.nextInt(4) == 0) { + playWaterbendingSound(player.getLocation()); } + formOctopus(); - if (y == 2) { + if (currentFormHeight == 2) { incrementStep(); } } else if (formed) { - if (GeneralMethods.rand.nextInt(7) == 0) { - WaterMethods.playWaterbendingSound(player.getLocation()); + if (random.nextInt(7) == 0) { + playWaterbendingSound(player.getLocation()); + } + + stepCounter += 1; + if (stepCounter % totalStepCount == 0) { + currentAnimationStep += 1; + } + if (currentAnimationStep > 8) { + currentAnimationStep = 1; } - step += 1; - if (step % inc == 0) - animstep += 1; - if (animstep > 8) - animstep = 1; formOctopus(); } else { remove(); + return; } } } private void formOctopus() { Location location = player.getLocation(); - newblocks.clear(); + newBlocks.clear(); + ArrayList doneBlocks = new ArrayList(); - ArrayList doneblocks = new ArrayList(); - - for (double theta = startangle; theta < startangle + angle; theta += 10) { + for (double theta = startAngle; theta < startAngle + angle; theta += 10) { double rtheta = Math.toRadians(theta); Block block = location.clone().add(new Vector(radius * Math.cos(rtheta), 0, radius * Math.sin(rtheta))).getBlock(); - if (!doneblocks.contains(block)) { + if (!doneBlocks.contains(block)) { addWater(block); - doneblocks.add(block); + doneBlocks.add(block); } } - Vector eyedir = player.getEyeLocation().getDirection(); - eyedir.setY(0); + Vector eyeDir = player.getEyeLocation().getDirection(); + eyeDir.setY(0); - double tentacleangle = Math.toDegrees((new Vector(1, 0, 0)).angle(eyedir)) + dta / 2; - int astep = animstep; - for (double tangle = tentacleangle; tangle < tentacleangle + 360; tangle += dta) { + double tentacleAngle = Math.toDegrees((new Vector(1, 0, 0)).angle(eyeDir)) + angleIncrement / 2; + int astep = currentAnimationStep; + for (double tangle = tentacleAngle; tangle < tentacleAngle + 360; tangle += angleIncrement) { astep += 1; double phi = Math.toRadians(tangle); tentacle(location.clone().add(new Vector(radius * Math.cos(phi), 0, radius * Math.sin(phi))), astep); } for (TempBlock block : blocks) { - if (!newblocks.contains(block)) + if (!newBlocks.contains(block)) { block.revertBlock(); + } } blocks.clear(); + blocks.addAll(newBlocks); - blocks.addAll(newblocks); - - if (blocks.isEmpty()) + if (blocks.isEmpty()) { remove(); + } } private void tentacle(Location base, int animationstep) { - if (!TempBlock.isTempBlock(base.getBlock())) + if (!TempBlock.isTempBlock(base.getBlock())) { return; - if (!blocks.contains(TempBlock.get(base.getBlock()))) + } else if (!blocks.contains(TempBlock.get(base.getBlock()))) { return; + } Vector direction = GeneralMethods.getDirection(player.getLocation(), base); direction.setY(0); @@ -345,28 +335,23 @@ public class OctopusForm { animationstep = animationstep % 8; } - if (y >= 1) { - - Block baseblock = base.clone().add(0, 1, 0).getBlock(); - + if (currentFormHeight >= 1) { + Block baseBlock = base.clone().add(0, 1, 0).getBlock(); if (animationstep == 1) { - addWater(baseblock); + addWater(baseBlock); } else if (animationstep == 2 || animationstep == 8) { - addWater(baseblock); + addWater(baseBlock); } else { addWater(base.clone().add(direction.getX(), 1, direction.getZ()).getBlock()); } - } - if (y == 2) { - - Block baseblock = base.clone().add(0, 2, 0).getBlock(); - + if (currentFormHeight == 2) { + Block baseBlock = base.clone().add(0, 2, 0).getBlock(); if (animationstep == 1) { addWater(base.clone().add(-direction.getX(), 2, -direction.getZ()).getBlock()); } else if (animationstep == 3 || animationstep == 7 || animationstep == 2 || animationstep == 8) { - addWater(baseblock); + addWater(baseBlock); } else if (animationstep == 4 || animationstep == 6) { addWater(base.clone().add(direction.getX(), 2, direction.getZ()).getBlock()); } else { @@ -378,85 +363,56 @@ public class OctopusForm { private void addWater(Block block) { clearNearbyWater(block); - if (GeneralMethods.isRegionProtectedFromBuild(player, "OctopusForm", block.getLocation())) + if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { return; + } + if (TempBlock.isTempBlock(block)) { TempBlock tblock = TempBlock.get(block); - if (!newblocks.contains(tblock)) { - if (!blocks.contains(tblock)) - tblock.setType(Material.WATER, full); - newblocks.add(tblock); + if (!newBlocks.contains(tblock)) { + if (!blocks.contains(tblock)) { + tblock.setType(Material.WATER, FULL); + } + newBlocks.add(tblock); } - } else if (WaterMethods.isWaterbendable(block, player) || block.getType() == Material.FIRE || block.getType() == Material.AIR) { - newblocks.add(new TempBlock(block, Material.STATIONARY_WATER, (byte) 8)); + } else if (isWaterbendable(block, player) || block.getType() == Material.FIRE || block.getType() == Material.AIR) { + newBlocks.add(new TempBlock(block, Material.STATIONARY_WATER, (byte) 8)); } } - // private static void replaceWater() { - // boolean replace = true; - // ArrayList newwater = new ArrayList(); - // for (TempBlock block : water) { - // for (Player player : instances.keySet()) { - // if (block.getLocation().distance(player.getLocation()) < 5) { - // replace = false; - // break; - // } - // } - // if (replace) { - // block.revertBlock(); - // } else { - // newwater.add(block); - // } - // } - // water.clear(); - // water.addAll(newwater); - // } - private void clearNearbyWater(Block block) { BlockFace[] faces = { BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST, BlockFace.DOWN }; for (BlockFace face : faces) { - Block rel = block.getRelative(face); - if (WaterMethods.isWater(rel) && !TempBlock.isTempBlock(rel)) { - FreezeMelt.freeze(player, rel); - // water.add(new TempBlock(rel, Material.AIR, (byte) 0)); + Block relBlock = block.getRelative(face); + if (isWater(relBlock) && !TempBlock.isTempBlock(relBlock)) { + PhaseChangeFreeze.freeze(player, relBlock); } } } - // private static boolean blockIsTouchingWater(Block block) { - // BlockFace[] faces = { BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, - // BlockFace.WEST, BlockFace.DOWN }; - // for (BlockFace face : faces) { - // Block rel = block.getRelative(face); - // if (Methods.isWater(rel) && !TempBlock.isTempBlock(rel)) - // return true; - // } - // return false; - // } - public static boolean wasBrokenFor(Player player, Block block) { - if (instances.containsKey(player)) { - OctopusForm form = instances.get(player); - if (form.sourceblock == null) + OctopusForm form = CoreAbility.getAbility(player, OctopusForm.class); + if (form != null) { + if (form.sourceBlock == null) { return false; - if (form.sourceblock.equals(block)) + } else if (form.sourceBlock.equals(block)) { return true; + } } return false; } - private void remove() { - if (source != null) + @Override + public void remove() { + super.remove(); + returnWater(); + + if (source != null) { source.revertBlock(); - for (TempBlock block : blocks) - block.revertBlock(); - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (isAuto) { - bPlayer.addCooldown("OctopusForm", autocooldown); - } else { - bPlayer.addCooldown("OctopusForm", cooldown); } - instances.remove(player); + for (TempBlock block : blocks) { + block.revertBlock(); + } } private void returnWater() { @@ -466,27 +422,80 @@ public class OctopusForm { source = null; } else { Location location = player.getLocation(); - double rtheta = Math.toRadians(startangle); + double rtheta = Math.toRadians(startAngle); Block block = location.clone().add(new Vector(radius * Math.cos(rtheta), 0, radius * Math.sin(rtheta))).getBlock(); new WaterReturn(player, block); } } - public static void removeAll() { - for (Player player : instances.keySet()) { - instances.get(player).remove(); + @Override + public Location getLocation() { + if (sourceBlock != null) { + return sourceBlock.getLocation(); + } else if (sourceLocation != null) { + return sourceLocation; } - - // for (TempBlock block : water) - // block.revertBlock(); + return player != null ? player.getLocation() : null; } - public static String getDescription() { - return "This ability allows the waterbender to manipulate a large quantity of water into a form resembling that of an octopus. " + "To use, click to select a water source. Then, hold sneak to channel this ability. " + "While channeling, the water will form itself around you and has a chance to block incoming attacks. " + "Additionally, you can click while channeling to attack things near you, dealing damage and knocking them back. " + "Releasing shift at any time will dissipate the form."; + @Override + public String getName() { + return "OctopusForm"; } - public Player getPlayer() { - return player; + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isSourceSelected() { + return sourceSelected; + } + + public void setSourceSelected(boolean sourceSelected) { + this.sourceSelected = sourceSelected; + } + + public boolean isSettingUp() { + return settingUp; + } + + public void setSettingUp(boolean settingUp) { + this.settingUp = settingUp; + } + + public boolean isForming() { + return forming; + } + + public void setForming(boolean forming) { + this.forming = forming; + } + + public boolean isFormed() { + return formed; + } + + public void setFormed(boolean formed) { + this.formed = formed; + } + + public int getRange() { + return range; + } + + public void setRange(int range) { + this.range = range; } public int getDamage() { @@ -497,6 +506,38 @@ public class OctopusForm { this.damage = damage; } + public int getCurrentAnimationStep() { + return currentAnimationStep; + } + + public void setCurrentAnimationStep(int currentAnimationStep) { + this.currentAnimationStep = currentAnimationStep; + } + + public int getStepCounter() { + return stepCounter; + } + + public void setStepCounter(int stepCounter) { + this.stepCounter = stepCounter; + } + + public int getTotalStepCount() { + return totalStepCount; + } + + public void setTotalStepCount(int totalStepCount) { + this.totalStepCount = totalStepCount; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + public long getInterval() { return interval; } @@ -505,6 +546,14 @@ public class OctopusForm { this.interval = interval; } + public double getAttackRange() { + return attackRange; + } + + public void setAttackRange(double attackRange) { + this.attackRange = attackRange; + } + public double getKnockback() { return knockback; } @@ -521,12 +570,72 @@ public class OctopusForm { this.radius = radius; } - public double getAttackRange() { - return attackRange; + public double getStartAngle() { + return startAngle; } - public void setAttackRange(double attackRange) { - this.attackRange = attackRange; + public void setStartAngle(double startAngle) { + this.startAngle = startAngle; } + public double getAngle() { + return angle; + } + + public void setAngle(double angle) { + this.angle = angle; + } + + public double getCurrentFormHeight() { + return currentFormHeight; + } + + public void setCurrentFormHeight(double currentFormHeight) { + this.currentFormHeight = currentFormHeight; + } + + public double getAngleIncrement() { + return angleIncrement; + } + + public void setAngleIncrement(double angleIncrement) { + this.angleIncrement = angleIncrement; + } + + public Block getSourceBlock() { + return sourceBlock; + } + + public void setSourceBlock(Block sourceBlock) { + this.sourceBlock = sourceBlock; + } + + public TempBlock getSource() { + return source; + } + + public void setSource(TempBlock source) { + this.source = source; + } + + public Location getSourceLocation() { + return sourceLocation; + } + + public void setSourceLocation(Location sourceLocation) { + this.sourceLocation = sourceLocation; + } + + public ArrayList getBlocks() { + return blocks; + } + + public ArrayList getNewBlocks() { + return newBlocks; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + } diff --git a/src/com/projectkorra/projectkorra/waterbending/PhaseChangeFreeze.java b/src/com/projectkorra/projectkorra/waterbending/PhaseChangeFreeze.java new file mode 100644 index 00000000..d3c73b67 --- /dev/null +++ b/src/com/projectkorra/projectkorra/waterbending/PhaseChangeFreeze.java @@ -0,0 +1,261 @@ +package com.projectkorra.projectkorra.waterbending; + +import com.projectkorra.projectkorra.BendingPlayer; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.IceAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.util.TempBlock; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.concurrent.ConcurrentHashMap; + +public class PhaseChangeFreeze extends IceAbility { + + private static final ConcurrentHashMap FROZEN_BLOCKS = new ConcurrentHashMap<>(); + private static final double REMOVE_RANGE = 50; // TODO: Make the remove range non static + + private static boolean overloading = false; + private static int overloadingLimit = 0; + private static int overloadCounter = 200; + + private double range; + private double radius; + private long cooldown; + private Location location; + + public PhaseChangeFreeze(Player player) { + super(player); + + this.range = getConfig().getDouble("Abilities.Water.PhaseChange.Range"); + this.radius = getConfig().getDouble("Abilities.Water.PhaseChange.Radius"); + this.cooldown = 0; + + this.range = getNightFactor(range); + this.radius = getNightFactor(radius); + + if (!bPlayer.canBend(this) || !bPlayer.canIcebend()) { + return; + } + + if (bPlayer.isAvatarState()) { + range = AvatarState.getValue(range); + } + + location = GeneralMethods.getTargetedLocation(player, range); + start(); + + for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) { + if (isFreezable(player, block)) { + freeze(player, block); + } + } + + bPlayer.addCooldown(this); + remove(); + } + + private static boolean isFreezable(Player player, Block block) { + if (GeneralMethods.isRegionProtectedFromBuild(player, "PhaseChange", block.getLocation())) { + return false; + } + return isWater(block) && WaterManipulation.canPhysicsChange(block) && !TempBlock.isTempBlock(block); + } + + @SuppressWarnings("deprecation") + public static void freeze(Player player, Block block) { + if (GeneralMethods.isRegionProtectedFromBuild(player, "PhaseChange", block.getLocation())) { + return; + } else if (TempBlock.isTempBlock(block)) { + return; + } + + byte data = block.getData(); + block.setType(Material.ICE); + + if(FROZEN_BLOCKS.size() % 50 == 0) { + playIcebendingSound(block.getLocation()); + } + FROZEN_BLOCKS.put(block, data); + } + + @SuppressWarnings("deprecation") + public static void thaw(Block block) { + if (FROZEN_BLOCKS.containsKey(block)) { + byte data = FROZEN_BLOCKS.get(block); + FROZEN_BLOCKS.remove(block); + block.setType(Material.WATER); + block.setData(data); + } + } + + public static void handleFrozenBlocks() { + int size = FROZEN_BLOCKS.keySet().size(); + overloadCounter++; + overloadCounter %= 10; + if (overloadCounter == 0) { + overloading = size > overloadingLimit ? true : false; + } + + // We only want to run this method once every 10 ticks if we are overloading. + if (overloading && overloadCounter != 0) { + return; + } + + if (overloading) { + int i = 0; + for (Block block : FROZEN_BLOCKS.keySet()) { + final Block fblock = block; + new BukkitRunnable() { + @Override + public void run() { + if (canThaw(fblock)) { + thaw(fblock); + } + } + }.runTaskLater(ProjectKorra.plugin, i % 10); + i++; + } + } else { + for (Block block : FROZEN_BLOCKS.keySet()) { + if (canThaw(block)) { + thaw(block); + } + } + } + } + + public static boolean canThaw(Block block) { + if (FROZEN_BLOCKS.containsKey(block)) { + for (Player player : block.getWorld().getPlayers()) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null || !player.isOnline()) { + continue; + } + + if (bPlayer.getBoundAbilityName().equalsIgnoreCase("OctopusForm")) { + if (block.getLocation().distance(player.getLocation()) <= REMOVE_RANGE + 2) { + return false; + } + } + + if (bPlayer.canBendIgnoreBindsCooldowns(getAbility("PhaseChange"))) { + double range = getNightFactor(REMOVE_RANGE, player.getWorld()); + if (bPlayer.isAvatarState()) { + range = AvatarState.getValue(range); + } + if (block.getLocation().distanceSquared(player.getLocation()) <= range * range) { + return false; + } + } + } + } + + if (!WaterManipulation.canPhysicsChange(block)) { + return false; + } + return true; + } + + @SuppressWarnings("deprecation") + public static void removeAllCleanup() { + for (Block block : FROZEN_BLOCKS.keySet()) { + if (block.getType() == Material.ICE) { + byte data = FROZEN_BLOCKS.get(block); + block.setType(Material.WATER); + block.setData(data); + FROZEN_BLOCKS.remove(block); + } + } + } + + @Override + public String getName() { + return "PhaseChange"; + } + + @Override + public void progress() {} + + @Override + public Location getLocation() { + return location; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public static boolean isOverloading() { + return overloading; + } + + public static void setOverloading(boolean overloading) { + PhaseChangeFreeze.overloading = overloading; + } + + public static int getOverloadingLimit() { + return overloadingLimit; + } + + public static void setOverloadingLimit(int overloadingLimit) { + PhaseChangeFreeze.overloadingLimit = overloadingLimit; + } + + public static int getOverloadCounter() { + return overloadCounter; + } + + public static void setOverloadCounter(int overloadCounter) { + PhaseChangeFreeze.overloadCounter = overloadCounter; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public static ConcurrentHashMap getFrozenBlocks() { + return FROZEN_BLOCKS; + } + + public static double getRemoveRange() { + return REMOVE_RANGE; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/waterbending/PhaseChangeMelt.java b/src/com/projectkorra/projectkorra/waterbending/PhaseChangeMelt.java new file mode 100644 index 00000000..b0276bf6 --- /dev/null +++ b/src/com/projectkorra/projectkorra/waterbending/PhaseChangeMelt.java @@ -0,0 +1,168 @@ +package com.projectkorra.projectkorra.waterbending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.IceAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.util.TempBlock; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +import java.util.HashSet; + +public class PhaseChangeMelt extends IceAbility { + + private static final byte FULL = 0x0; + + private int seaLevel; + private double range; + private double radius; + private double evaporateRadius; + private Location location; + + public PhaseChangeMelt(Player player) { + super(player); + + this.seaLevel = getConfig().getInt("Properties.SeaLevel"); + this.range = getConfig().getDouble("Abilities.Water.PhaseChange.Range"); + this.radius = getConfig().getDouble("Abilities.Water.PhaseChange.Radius"); + this.evaporateRadius = 3; + + this.range = getNightFactor(range); + this.radius = getNightFactor(radius); + + if (!bPlayer.canIcebend() || !bPlayer.canIcebend()) { + return; + } + + if (bPlayer.isAvatarState()) { + range = AvatarState.getValue(range); + radius = AvatarState.getValue(radius); + } + + boolean evaporate = false; + location = GeneralMethods.getTargetedLocation(player, range); + if (isWater(player.getTargetBlock((HashSet) null, (int) range)) && !(player.getEyeLocation().getBlockY() <= 62)) { + evaporate = true; + radius = (int) getNightFactor(evaporateRadius); + } + + start(); + for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) { + if (evaporate) { + if (block.getY() > seaLevel) { + evaporate(player, block); + } + } else { + melt(player, block); + } + } + remove(); + } + + @SuppressWarnings("deprecation") + public static void melt(Player player, Block block) { + if (GeneralMethods.isRegionProtectedFromBuild(player, "PhaseChange", block.getLocation())) { + return; + } else if (!SurgeWave.canThaw(block)) { + SurgeWave.thaw(block); + return; + } else if (!Torrent.canThaw(block)) { + Torrent.thaw(block); + return; + } + + WaterSpoutWave.thaw(block); + WaterCombo.thaw(block); + + if (isMeltable(block) && !TempBlock.isTempBlock(block) && WaterManipulation.canPhysicsChange(block)) { + if (block.getType() == Material.SNOW) { + block.setType(Material.AIR); + return; + } else if (PhaseChangeFreeze.getFrozenBlocks().containsKey(block)) { + PhaseChangeFreeze.thaw(block); + } else { + block.setType(Material.WATER); + block.setData(FULL); + } + } + } + + public static void evaporate(Player player, Block block) { + if (GeneralMethods.isRegionProtectedFromBuild(player, "PhaseChange", block.getLocation())) { + return; + } else if (isWater(block) && !TempBlock.isTempBlock(block) && WaterManipulation.canPhysicsChange(block)) { + block.setType(Material.AIR); + block.getWorld().playEffect(block.getLocation(), Effect.SMOKE, 1); + } + } + + @Override + public String getName() { + return "PhaseChange"; + } + + @Override + public void progress() { + } + + @Override + public Location getLocation() { + return location; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public int getSeaLevel() { + return seaLevel; + } + + public void setSeaLevel(int seaLevel) { + this.seaLevel = seaLevel; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getEvaporateRadius() { + return evaporateRadius; + } + + public void setEvaporateRadius(double evaporateRadius) { + this.evaporateRadius = evaporateRadius; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/waterbending/PlantArmor.java b/src/com/projectkorra/projectkorra/waterbending/PlantArmor.java index 69e772e1..5c7528e6 100644 --- a/src/com/projectkorra/projectkorra/waterbending/PlantArmor.java +++ b/src/com/projectkorra/projectkorra/waterbending/PlantArmor.java @@ -1,6 +1,8 @@ package com.projectkorra.projectkorra.waterbending; -import java.util.concurrent.ConcurrentHashMap; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.PlantAbility; import org.bukkit.Color; import org.bukkit.Location; @@ -13,219 +15,171 @@ import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.ClickType; +import java.util.Random; -public class PlantArmor { - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - - private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.PlantArmor.Cooldown"); - private static long DURATION = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.PlantArmor.Duration"); - private static int RESISTANCE = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.PlantArmor.Resistance"); +public class PlantArmor extends PlantAbility { - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.PlantArmor.SelectRange"); - private static int autoSelectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.PlantArmor.AutoSourcing.SelectRange"); - private static boolean auto = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.PlantArmor.AutoSourcing.Enabled"); - private static long autocooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.PlantArmor.AutoSourcing.Cooldown"); - - private boolean isAuto; - - private Player player; + private boolean formed; + private boolean hadEffect; + private int resistance; + private long duration; + private long cooldown; + private double range; + private Material blockType; private Block block; private Location location; - private Plantbending plantbending; - private long starttime; - private boolean formed = false; - private int resistance = RESISTANCE; - public ItemStack[] oldarmor; - public boolean hadEffect; - private long duration = DURATION; - public Material blocktype; - + private PlantRegrowth plantbending; + private ItemStack[] oldArmor; + public PlantArmor(Player player) { - if (instances.containsKey(player)) { + super(player); + + this.resistance = getConfig().getInt("Abilities.Water.PlantArmor.Resistance"); + this.range = getConfig().getInt("Abilities.Water.PlantArmor.Range"); + this.duration = getConfig().getLong("Abilities.Water.PlantArmor.Duration"); + this.cooldown = getConfig().getLong("Abilities.Water.PlantArmor.Cooldown"); + + this.range = getNightFactor(range); + this.duration = (long) getNightFactor(duration); + + if (CoreAbility.hasAbility(player, PlantArmor.class)) { + return; + } else if (bPlayer.isOnCooldown(this)) { return; } - - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (bPlayer.isOnCooldown("PlantArmor")) - return; - - this.player = player; - Double d = WaterMethods.getWaterbendingNightAugment(player.getWorld()) * duration; - duration = d.longValue(); - block = BlockSource.getWaterSourceBlock(player, autoSelectRange, selectRange, ClickType.LEFT_CLICK, auto, false, false, false, false, WaterMethods.canPlantbend(player)); + + block = getPlantSourceBlock(player, range, true); if (block == null) { return; } - if (BlockSource.isAuto(block)) { - isAuto = true; - } else { - isAuto = false; - } + location = block.getLocation(); hadEffect = player.hasPotionEffect(PotionEffectType.DAMAGE_RESISTANCE); - if (!canUse()) + if (!canUse()) { return; - plantbending = new Plantbending(block); - blocktype = block.getType(); + } + + plantbending = new PlantRegrowth(player, block); + blockType = block.getType(); block.setType(Material.AIR); - instances.put(player, this); + + start(); } private boolean canUse() { - if (!player.getWorld().equals(block.getWorld())) { - cancel(); + if (!bPlayer.canPlantbend() + || !bPlayer.canBend(this) + || GeneralMethods.isRegionProtectedFromBuild(this, location)) { + remove(); + return false; + } else if (location.distanceSquared(player.getEyeLocation()) > range * range) { + remove(); return false; } - - if (location.distance(player.getEyeLocation()) > selectRange) { - cancel(); - return false; - } - - if (!WaterMethods.canPlantbend(player)) { - cancel(); - return false; - } - return true; } - - public ItemStack getOriginalArmor(int i) { - return oldarmor[i]; - } - - private void playEffect() { - if (!formed) { - if (GeneralMethods.rand.nextInt(4) == 0) { - WaterMethods.playPlantbendingSound(location); - } - GeneralMethods.displayColoredParticle(location, "009933"); - Vector v = player.getEyeLocation().toVector().subtract(location.toVector()); - location = location.add(v.normalize()); - } - } - - private void cancel() { - if (plantbending != null) - plantbending.revert(); - if (instances.containsKey(player)) - instances.remove(player); - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (isAuto) { - bPlayer.addCooldown("PlantArmor", autocooldown); - } else { - bPlayer.addCooldown("PlantArmor", cooldown); - } - } - - private boolean inPosition() { - if (location.distance(player.getEyeLocation()) <= 1.5) - return true; - return false; - } private void formArmor() { - oldarmor = player.getInventory().getArmorContents(); - ItemStack helmet = new ItemStack(blocktype); + oldArmor = player.getInventory().getArmorContents(); + ItemStack helmet = new ItemStack(blockType); ItemStack chestplate = new ItemStack(Material.LEATHER_CHESTPLATE); - LeatherArmorMeta im = (LeatherArmorMeta) chestplate.getItemMeta(); - im.setColor(Color.GREEN); - chestplate.setItemMeta(im); + + LeatherArmorMeta itemMeta = (LeatherArmorMeta) chestplate.getItemMeta(); + itemMeta.setColor(Color.GREEN); + chestplate.setItemMeta(itemMeta); + ItemStack leggings = new ItemStack(Material.LEATHER_LEGGINGS); - leggings.setItemMeta(im); ItemStack boots = new ItemStack(Material.LEATHER_BOOTS); - boots.setItemMeta(im); + leggings.setItemMeta(itemMeta); + boots.setItemMeta(itemMeta); + player.getInventory().setHelmet(helmet); player.getInventory().setChestplate(chestplate); player.getInventory().setLeggings(leggings); player.getInventory().setBoots(boots); - if (!hadEffect) + + if (!hadEffect) { player.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 1000000, resistance - 1)); + } formed = true; - starttime = System.currentTimeMillis(); + startTime = System.currentTimeMillis(); } - public static void progressAll() { - for (Player player : instances.keySet()) { - progress(player); + private boolean inPosition() { + return location.distanceSquared(player.getEyeLocation()) <= 1.5 * 1.5; + } + + private void playEffect() { + if (!formed) { + if ((new Random()).nextInt(4) == 0) { + playPlantbendingSound(location); + } + + GeneralMethods.displayColoredParticle(location, "009933"); + Vector vector = player.getEyeLocation().toVector().subtract(location.toVector()); + location = location.add(vector.normalize()); } } - public static void progress(Player player) { - if (!instances.containsKey(player)) - return; - PlantArmor plantarmor = instances.get(player); - + @Override + public void progress() { if (player.isDead() || !player.isOnline()) { - plantarmor.removeEffect(); - plantarmor.cancel(); + remove(); return; } - if (plantarmor.formed) { - if (System.currentTimeMillis() > plantarmor.starttime + plantarmor.duration) { - plantarmor.removeEffect(); - plantarmor.cancel(); - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("PlantArmor", cooldown); + if (formed) { + if (System.currentTimeMillis() > startTime + duration) { + remove(); + bPlayer.addCooldown(this); return; } - } else { - if (!plantarmor.canUse()) - return; - - plantarmor.playEffect(); - - if (plantarmor.inPosition()) { - plantarmor.formArmor(); - } - } - - } - - private void removeEffect() { - player.getInventory().setArmorContents(oldarmor); - if (!hadEffect) - player.removePotionEffect(PotionEffectType.DAMAGE_RESISTANCE); - } - - public static void removeEffect(Player player) { - if (!instances.containsKey(player)) + } else if (!canUse()) { return; - instances.get(player).removeEffect(); + } + + playEffect(); + if (inPosition() && !formed) { + formArmor(); + } } - public static void removeAll() { - for (Player player : instances.keySet()) { - PlantArmor plantarmor = instances.get(player); - plantarmor.removeEffect(); - plantarmor.cancel(); + @Override + public void remove() { + super.remove(); + + if (oldArmor != null) { + player.getInventory().setArmorContents(oldArmor); + if (!hadEffect) { + player.removePotionEffect(PotionEffectType.DAMAGE_RESISTANCE); + } } + + if (plantbending != null) { + plantbending.remove(); + } + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return false; } public static boolean canRemoveArmor(Player player) { - if (instances.containsKey(player)) { - PlantArmor plantarmor = instances.get(player); - if (System.currentTimeMillis() < plantarmor.starttime + plantarmor.duration) + PlantArmor plantArmor = CoreAbility.getAbility(player, PlantArmor.class); + if (plantArmor != null) { + if (System.currentTimeMillis() < plantArmor.startTime + plantArmor.duration) { return false; + } } return true; } - - public Player getPlayer() { - return player; - } - - public int getResistance() { - return resistance; - } - + public void setResistance(int resistance) { this.resistance = resistance; if (!hadEffect) { @@ -233,4 +187,101 @@ public class PlantArmor { player.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 1000000, resistance - 1)); } } + + public int getResistance() { + return resistance; + } + + @Override + public String getName() { + return "PlantArmor"; + } + + @Override + public Location getLocation() { + if (location != null) { + return location; + } else if (block != null) { + return block.getLocation(); + } + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + public boolean isFormed() { + return formed; + } + + public void setFormed(boolean formed) { + this.formed = formed; + } + + public boolean isHadEffect() { + return hadEffect; + } + + public void setHadEffect(boolean hadEffect) { + this.hadEffect = hadEffect; + } + + public long getDuration() { + return duration; + } + + public void setDuration(long duration) { + this.duration = duration; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public Material getBlockType() { + return blockType; + } + + public void setBlockType(Material blockType) { + this.blockType = blockType; + } + + public Block getBlock() { + return block; + } + + public void setBlock(Block block) { + this.block = block; + } + + public PlantRegrowth getPlantbending() { + return plantbending; + } + + public void setPlantbending(PlantRegrowth plantbending) { + this.plantbending = plantbending; + } + + public ItemStack[] getOldArmor() { + return oldArmor; + } + + public void setOldArmor(ItemStack[] oldArmor) { + this.oldArmor = oldArmor; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + } diff --git a/src/com/projectkorra/projectkorra/waterbending/PlantRegrowth.java b/src/com/projectkorra/projectkorra/waterbending/PlantRegrowth.java new file mode 100644 index 00000000..22933f7e --- /dev/null +++ b/src/com/projectkorra/projectkorra/waterbending/PlantRegrowth.java @@ -0,0 +1,122 @@ +package com.projectkorra.projectkorra.waterbending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.PlantAbility; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +public class PlantRegrowth extends PlantAbility { + + private byte data; + private long time; + private long regrowTime; + private Material type; + private Block block; + + @SuppressWarnings("deprecation") + public PlantRegrowth(Player player, Block block) { + super(player); + + this.regrowTime = getConfig().getLong("Abilities.Water.Plantbending.RegrowTime"); + if (regrowTime != 0) { + this.block = block; + this.type = block.getType(); + this.data = block.getData(); + time = System.currentTimeMillis() + regrowTime / 2 + (long) (Math.random() * (double) regrowTime) / 2; + start(); + } + } + + @Override + @SuppressWarnings("deprecation") + public void remove() { + super.remove(); + if (block.getType() == Material.AIR) { + block.setType(type); + block.setData(data); + } else { + GeneralMethods.dropItems(block, GeneralMethods.getDrops(block, type, data, null)); + } + } + + @Override + public void progress() { + if (time < System.currentTimeMillis()) { + remove(); + } + } + + @Override + public String getName() { + return "PlantRegrowth"; + } + + @Override + public Location getLocation() { + return block != null ? block.getLocation() : null; + } + + @Override + public boolean isHiddenAbility() { + return true; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return true; + } + + public byte getData() { + return data; + } + + public void setData(byte data) { + this.data = data; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getRegrowTime() { + return regrowTime; + } + + public void setRegrowTime(long regrowTime) { + this.regrowTime = regrowTime; + } + + public Material getType() { + return type; + } + + public void setType(Material type) { + this.type = type; + } + + public Block getBlock() { + return block; + } + + public void setBlock(Block block) { + this.block = block; + } + +} diff --git a/src/com/projectkorra/projectkorra/waterbending/Plantbending.java b/src/com/projectkorra/projectkorra/waterbending/Plantbending.java deleted file mode 100644 index b6446aac..00000000 --- a/src/com/projectkorra/projectkorra/waterbending/Plantbending.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.projectkorra.projectkorra.waterbending; - -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; - -import org.bukkit.Material; -import org.bukkit.block.Block; - -import java.util.concurrent.ConcurrentHashMap; - -public class Plantbending { - - private static ConcurrentHashMap instances = new ConcurrentHashMap(); - - private static final long regrowtime = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.Plantbending.RegrowTime"); - private static int ID = Integer.MIN_VALUE; - - private Block block; - private Material type; - private byte data; - private long time; - private int id; - - @SuppressWarnings("deprecation") - public Plantbending(Block block) { - if (regrowtime != 0) { - this.block = block; - type = block.getType(); - data = block.getData(); - time = System.currentTimeMillis() + regrowtime / 2 + (long) (Math.random() * (double) regrowtime) / 2; - id = ID; - instances.put(id, this); - if (ID >= Integer.MAX_VALUE) { - ID = Integer.MIN_VALUE; - } else { - ID++; - } - } - } - - @SuppressWarnings("deprecation") - public void revert() { - if (block.getType() == Material.AIR) { - block.setType(type); - block.setData(data); - } else { - GeneralMethods.dropItems(block, GeneralMethods.getDrops(block, type, data, null)); - } - instances.remove(id); - } - - public static void regrow() { - for (int id : instances.keySet()) { - Plantbending plantbending = instances.get(id); - if (plantbending.time < System.currentTimeMillis()) { - plantbending.revert(); - } - } - } - - public static void regrowAll() { - for (int id : instances.keySet()) - instances.get(id).revert(); - } -} diff --git a/src/com/projectkorra/projectkorra/waterbending/SpikeField.java b/src/com/projectkorra/projectkorra/waterbending/SpikeField.java deleted file mode 100644 index 2cbe3129..00000000 --- a/src/com/projectkorra/projectkorra/waterbending/SpikeField.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.projectkorra.projectkorra.waterbending; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; - -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -public class SpikeField { - - private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.IceSpike.Cooldown"); - - private static int radius = 6; - public static int numofspikes = ((radius * 2) * (radius * 2)) / 16; - - Random ran = new Random(); - private int damage = 2; - private Vector thrown = new Vector(0, 1, 0); - - public SpikeField(Player p) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(p.getName()); - - if (bPlayer.isOnCooldown("IceSpike")) return; - int locX = p.getLocation().getBlockX(); - int locY = p.getLocation().getBlockY(); - int locZ = p.getLocation().getBlockZ(); - List iceblocks = new ArrayList(); - for (int x = -(radius - 1); x <= (radius - 1); x++) { - for (int z = -(radius - 1); z <= (radius - 1); z++) { - for (int y = -1; y <= 1; y++) { - Block testblock = p.getWorld().getBlockAt(locX + x, locY + y, locZ + z); - if (testblock.getType() == Material.ICE - && testblock.getRelative(BlockFace.UP).getType() == Material.AIR - && !(testblock.getX() == p.getEyeLocation() - .getBlock().getX() && testblock.getZ() == p - .getEyeLocation().getBlock().getZ())) { - iceblocks.add(testblock); - for(Block iceblockforsound : iceblocks) { - WaterMethods.playIcebendingSound(iceblockforsound.getLocation()); - } - } - } - } - } - - List entities = GeneralMethods.getEntitiesAroundPoint(p.getLocation(), radius); - - for (int i = 0; i < numofspikes; i++) { - if (iceblocks.isEmpty()) - return; - - Entity target = null; - Block targetblock = null; - for (Entity entity : entities) { - if (entity instanceof LivingEntity && entity.getEntityId() != p.getEntityId()) { - for (Block block : iceblocks) { - if (block.getX() == entity.getLocation().getBlockX() && block.getZ() == entity.getLocation().getBlockZ()) { - target = entity; - targetblock = block; - break; - } - } - } else { - continue; - } - } - - if (target != null) { - entities.remove(target); - } else { - targetblock = iceblocks.get(ran.nextInt(iceblocks.size())); - } - if (targetblock.getRelative(BlockFace.UP).getType() != Material.ICE) { - new IceSpike(p, targetblock.getLocation(), damage, thrown, cooldown); - bPlayer.addCooldown("IceSpike", cooldown); - iceblocks.remove(targetblock); - } - } - } -} \ No newline at end of file diff --git a/src/com/projectkorra/projectkorra/waterbending/SurgeWall.java b/src/com/projectkorra/projectkorra/waterbending/SurgeWall.java new file mode 100644 index 00000000..228e918e --- /dev/null +++ b/src/com/projectkorra/projectkorra/waterbending/SurgeWall.java @@ -0,0 +1,600 @@ +package com.projectkorra.projectkorra.waterbending; + +import com.projectkorra.projectkorra.BendingPlayer; +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.firebending.FireBlast; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.ClickType; +import com.projectkorra.projectkorra.util.TempBlock; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; + +public class SurgeWall extends WaterAbility { + + private static final byte FULL = 0x0; + private static final String RANGE_CONFIG = "Abilities.Water.Surge.Wall.Range"; + private static final ConcurrentHashMap AFFECTED_BLOCKS = new ConcurrentHashMap(); + private static final ConcurrentHashMap WALL_BLOCKS = new ConcurrentHashMap(); + + private boolean progressing; + private boolean settingUp; + private boolean forming; + private boolean frozen; + private long time; + private long interval; + private long cooldown; + private double radius; + private double range; + private Block sourceBlock; + private Location location; + private Location firstDestination; + private Location targetDestination; + private Vector firstDirection; + private Vector targetDirection; + + @SuppressWarnings("deprecation") + public SurgeWall(Player player) { + super(player); + + this.interval = 30; + this.cooldown = 0; + this.range = getConfig().getDouble(RANGE_CONFIG); + this.radius = getConfig().getDouble("Abilities.Water.Surge.Wall.Radius"); + + SurgeWave wave = CoreAbility.getAbility(player, SurgeWave.class); + if (wave != null && !wave.isProgressing()) { + wave.moveWater(); + return; + } + + if (bPlayer.isAvatarState()) { + radius = AvatarState.getValue(radius); + } + + SurgeWall wall = CoreAbility.getAbility(player, SurgeWall.class); + if (wall != null) { + if (wall.progressing) { + freezeThaw(); + } else if (prepare()) { + wall.remove(); + start(); + time = System.currentTimeMillis(); + } + } else if (prepare()) { + start(); + time = System.currentTimeMillis(); + } + + if (bPlayer.isOnCooldown(this)) { + return; + } else if (wall == null && WaterReturn.hasWaterBottle(player)) { + Location eyeloc = player.getEyeLocation(); + Block block = eyeloc.add(eyeloc.getDirection().normalize()).getBlock(); + + if (isTransparentToEarthbending(player, block) && isTransparentToEarthbending(player, eyeloc.getBlock())) { + block.setType(Material.WATER); + block.setData(FULL); + + wave = new SurgeWave(player); + wave.setCanHitSelf(false); + wave.moveWater(); + + if (!wave.isProgressing()) { + block.setType(Material.AIR); + wave.remove(); + } else { + WaterReturn.emptyWaterBottle(player); + } + } + } + } + + private void freezeThaw() { + if (!bPlayer.canIcebend()) { + return; + } else if (frozen) { + thaw(); + } else { + freeze(); + } + } + + private void freeze() { + frozen = true; + for (Block block : WALL_BLOCKS.keySet()) { + if (WALL_BLOCKS.get(block) == player) { + new TempBlock(block, Material.ICE, (byte) 0); + playIcebendingSound(block.getLocation()); + } + } + } + + private void thaw() { + frozen = false; + for (Block block : WALL_BLOCKS.keySet()) { + if (WALL_BLOCKS.get(block) == player) { + new TempBlock(block, Material.STATIONARY_WATER, (byte) 8); + } + } + } + + public boolean prepare() { + cancelPrevious(); + Block block = BlockSource.getWaterSourceBlock(player, range, ClickType.LEFT_CLICK, true, true, bPlayer.canPlantbend()); + + if (block != null && !GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + sourceBlock = block; + focusBlock(); + return true; + } + return false; + } + + private void cancelPrevious() { + SurgeWall oldWave = CoreAbility.getAbility(player, SurgeWall.class); + if (oldWave != null) { + if (oldWave.progressing) { + oldWave.removeWater(oldWave.sourceBlock); + } else { + oldWave.remove(); + } + } + } + + private void focusBlock() { + location = sourceBlock.getLocation(); + } + + @SuppressWarnings("deprecation") + public void moveWater() { + if (sourceBlock != null) { + targetDestination = player.getTargetBlock(getTransparentMaterialSet(), (int) range).getLocation(); + + if (targetDestination.distanceSquared(location) <= 1) { + progressing = false; + targetDestination = null; + } else { + progressing = true; + settingUp = true; + firstDestination = getToEyeLevel(); + firstDirection = getDirection(sourceBlock.getLocation(), firstDestination); + targetDirection = getDirection(firstDestination, targetDestination); + + if (isPlant(sourceBlock)) { + new PlantRegrowth(player, sourceBlock); + } + if (!GeneralMethods.isAdjacentToThreeOrMoreSources(sourceBlock)) { + sourceBlock.setType(Material.AIR); + } + addWater(sourceBlock); + } + + } + } + + private Location getToEyeLevel() { + Location loc = sourceBlock.getLocation().clone(); + loc.setY(targetDestination.getY()); + return loc; + } + + private Vector getDirection(Location location, Location destination) { + double x1, y1, z1; + double x0, y0, z0; + + x1 = destination.getX(); + y1 = destination.getY(); + z1 = destination.getZ(); + + x0 = location.getX(); + y0 = location.getY(); + z0 = location.getZ(); + + return new Vector(x1 - x0, y1 - y0, z1 - z0); + } + + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { + remove(); + return; + } + + if (System.currentTimeMillis() - time >= interval) { + time = System.currentTimeMillis(); + boolean matchesName = bPlayer.getBoundAbilityName().equalsIgnoreCase(getName()); + + if (!progressing && !matchesName) { + remove(); + return; + } else if (progressing && (!player.isSneaking() || !matchesName)) { + remove(); + return; + } else if (!progressing) { + sourceBlock.getWorld().playEffect(location, Effect.SMOKE, 4, (int) range); + return; + } + + if (forming) { + if ((new Random()).nextInt(7) == 0) { + playWaterbendingSound(location); + } + + ArrayList blocks = new ArrayList(); + Location targetLoc = GeneralMethods.getTargetedLocation(player, (int) range, 8, 9, 79); + location = targetLoc.clone(); + Vector eyeDir = player.getEyeLocation().getDirection(); + Vector vector; + Block block; + + for (double i = 0; i <= getNightFactor(radius); i += 0.5) { + for (double angle = 0; angle < 360; angle += 10) { + vector = GeneralMethods.getOrthogonalVector(eyeDir.clone(), angle, i); + block = targetLoc.clone().add(vector).getBlock(); + + if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + continue; + } else if (WALL_BLOCKS.containsKey(block)) { + blocks.add(block); + } else if (!blocks.contains(block) + && (block.getType() == Material.AIR + || block.getType() == Material.FIRE + || isWaterbendable(block))) { + WALL_BLOCKS.put(block, player); + addWallBlock(block); + blocks.add(block); + FireBlast.removeFireBlastsAroundPoint(block.getLocation(), 2); + } + } + } + + for (Block blocki : WALL_BLOCKS.keySet()) { + if (WALL_BLOCKS.get(blocki) == player && !blocks.contains(blocki)) { + finalRemoveWater(blocki); + } + } + return; + } + + if (sourceBlock.getLocation().distanceSquared(firstDestination) < 0.5 * 0.5 && settingUp) { + settingUp = false; + } + + Vector direction; + if (settingUp) { + direction = firstDirection; + } else { + direction = targetDirection; + } + + location = location.clone().add(direction); + + Block block = location.getBlock(); + if (block.getLocation().equals(sourceBlock.getLocation())) { + location = location.clone().add(direction); + block = location.getBlock(); + } + + if (block.getType() != Material.AIR) { + remove(); + return; + } else if (!progressing) { + remove(); + return; + } + + addWater(block); + removeWater(sourceBlock); + sourceBlock = block; + + if (location.distanceSquared(targetDestination) < 1) { + removeWater(sourceBlock);; + forming = true; + } + } + } + + private void addWallBlock(Block block) { + if (frozen) { + new TempBlock(block, Material.ICE, (byte) 0); + } else { + new TempBlock(block, Material.STATIONARY_WATER, (byte) 8); + } + } + + @Override + public void remove() { + super.remove(); + returnWater(); + finalRemoveWater(sourceBlock); + + for (Block block : WALL_BLOCKS.keySet()) { + if (WALL_BLOCKS.get(block) == player) { + finalRemoveWater(block); + } + } + + } + + private void removeWater(Block block) { + if (block != null) { + if (AFFECTED_BLOCKS.containsKey(block)) { + if (!GeneralMethods.isAdjacentToThreeOrMoreSources(block)) { + TempBlock.revertBlock(block, Material.AIR); + } + AFFECTED_BLOCKS.remove(block); + } + } + } + + private static void finalRemoveWater(Block block) { + if (AFFECTED_BLOCKS.containsKey(block)) { + TempBlock.revertBlock(block, Material.AIR); + AFFECTED_BLOCKS.remove(block); + } + if (WALL_BLOCKS.containsKey(block)) { + TempBlock.revertBlock(block, Material.AIR); + WALL_BLOCKS.remove(block); + } + } + + private void addWater(Block block) { + if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + return; + } else if (!TempBlock.isTempBlock(block)) { + new TempBlock(block, Material.STATIONARY_WATER, (byte) 8); + AFFECTED_BLOCKS.put(block, block); + } + } + + @SuppressWarnings("deprecation") + public static void form(Player player) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + return; + } + + int range = getConfig().getInt(RANGE_CONFIG); + SurgeWall wall = CoreAbility.getAbility(player, SurgeWall.class); + SurgeWave wave = CoreAbility.getAbility(player, SurgeWave.class); + + if (wall == null) { + if (wave == null + && BlockSource.getWaterSourceBlock(player, range, ClickType.LEFT_CLICK, true, true, bPlayer.canPlantbend()) == null + && WaterReturn.hasWaterBottle(player)) { + if (bPlayer.isOnCooldown("Surge")) { + return; + } + + Location eyeLoc = player.getEyeLocation(); + Block block = eyeLoc.add(eyeLoc.getDirection().normalize()).getBlock(); + if (isTransparentToEarthbending(player, block) && isTransparentToEarthbending(player, eyeLoc.getBlock())) { + block.setType(Material.WATER); + block.setData(FULL); + + wall = new SurgeWall(player); + wall.moveWater(); + if (!wall.progressing) { + block.setType(Material.AIR); + wall.remove(); + } else { + WaterReturn.emptyWaterBottle(player); + } + return; + } + } + + wave = new SurgeWave(player); + return; + } else { + if (isWaterbendable(player.getTargetBlock((HashSet) null, range), player)) { + wave = new SurgeWave(player); + return; + } + } + + if (wall != null) { + wall.moveWater(); + } + } + + public static void removeAllCleanup() { + for (Block block : AFFECTED_BLOCKS.keySet()) { + TempBlock.revertBlock(block, Material.AIR); + AFFECTED_BLOCKS.remove(block); + WALL_BLOCKS.remove(block); + } + for (Block block : WALL_BLOCKS.keySet()) { + TempBlock.revertBlock(block, Material.AIR); + AFFECTED_BLOCKS.remove(block); + WALL_BLOCKS.remove(block); + } + } + + + public static void thaw(Block block) { + finalRemoveWater(block); + } + + public static boolean wasBrokenFor(Player player, Block block) { + SurgeWall wall = CoreAbility.getAbility(player, SurgeWall.class); + if (wall != null) { + if (wall.sourceBlock == null) { + return false; + } else if (wall.sourceBlock.equals(block)) { + return true; + } + } + return false; + } + + private void returnWater() { + if (location != null) { + new WaterReturn(player, location.getBlock()); + } + } + + @Override + public String getName() { + return "Surge"; + } + + @Override + public Location getLocation() { + if (location != null) { + return location; + } else if (sourceBlock != null) { + return sourceBlock.getLocation(); + } + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isProgressing() { + return progressing; + } + + public void setProgressing(boolean progressing) { + this.progressing = progressing; + } + + public boolean isSettingUp() { + return settingUp; + } + + public void setSettingUp(boolean settingUp) { + this.settingUp = settingUp; + } + + public boolean isForming() { + return forming; + } + + public void setForming(boolean forming) { + this.forming = forming; + } + + public boolean isFrozen() { + return frozen; + } + + public void setFrozen(boolean frozen) { + this.frozen = frozen; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public Block getSourceBlock() { + return sourceBlock; + } + + public void setSourceBlock(Block sourceBlock) { + this.sourceBlock = sourceBlock; + } + + public Location getFirstDestination() { + return firstDestination; + } + + public void setFirstDestination(Location firstDestination) { + this.firstDestination = firstDestination; + } + + public Location getTargetDestination() { + return targetDestination; + } + + public void setTargetDestination(Location targetDestination) { + this.targetDestination = targetDestination; + } + + public Vector getFirstDirection() { + return firstDirection; + } + + public void setFirstDirection(Vector firstDirection) { + this.firstDirection = firstDirection; + } + + public Vector getTargetDirection() { + return targetDirection; + } + + public void setTargetDirection(Vector targetDirection) { + this.targetDirection = targetDirection; + } + + public static ConcurrentHashMap getAffectedBlocks() { + return AFFECTED_BLOCKS; + } + + public static ConcurrentHashMap getWallBlocks() { + return WALL_BLOCKS; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/waterbending/SurgeWave.java b/src/com/projectkorra/projectkorra/waterbending/SurgeWave.java new file mode 100644 index 00000000..96c5da1a --- /dev/null +++ b/src/com/projectkorra/projectkorra/waterbending/SurgeWave.java @@ -0,0 +1,584 @@ +package com.projectkorra.projectkorra.waterbending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; +import com.projectkorra.projectkorra.firebending.FireBlast; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.ClickType; +import com.projectkorra.projectkorra.util.TempBlock; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; + +public class SurgeWave extends WaterAbility { + + private boolean freezing; + private boolean activateFreeze; + private boolean progressing; + private boolean canHitSelf; + private long time; + private long cooldown; + private long interval; + private double currentRadius; + private double maxRadius; + private double range; + private double pushFactor; + private double verticalFactor; + private double maxFreezeRadius; + private Block sourceBlock; + private Location location; + private Location targetDestination; + private Location frozenLocation; + private Vector targetDirection; + private ConcurrentHashMap waveBlocks; + private ConcurrentHashMap frozenBlocks; + + public SurgeWave(Player player) { + super(player); + + SurgeWave wave = CoreAbility.getAbility(player, SurgeWave.class); + if (wave != null) { + if (wave.progressing && !wave.freezing) { + wave.freezing = true; + return; + } + } + + this.canHitSelf = true; + this.currentRadius = 1; + this.cooldown = GeneralMethods.getGlobalCooldown(); + this.interval = 30; + this.maxRadius = getConfig().getDouble("Abilities.Water.Surge.Wave.Radius"); + this.pushFactor = getConfig().getDouble("Abilities.Water.Surge.Wave.HorizontalPush"); + this.verticalFactor = getConfig().getDouble("Abilities.Water.Surge.Wave.VerticalPush"); + this.maxFreezeRadius = 7; + this.range = getConfig().getDouble("Abilities.Water.Surge.Wave.Range"); + this.waveBlocks = new ConcurrentHashMap(); + this.frozenBlocks = new ConcurrentHashMap(); + + if (bPlayer.isAvatarState()) { + maxRadius = AvatarState.getValue(maxRadius); + } + maxRadius = getNightFactor(maxRadius); + + if (prepare()) { + wave = CoreAbility.getAbility(player, SurgeWave.class); + if (wave != null) { + wave.remove(); + } + start(); + bPlayer.addCooldown(this); + time = System.currentTimeMillis(); + } + } + + private void addWater(Block block) { + if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + return; + } else if (!TempBlock.isTempBlock(block)) { + new TempBlock(block, Material.STATIONARY_WATER, (byte) 8); + waveBlocks.put(block, block); + } + } + + private void cancelPrevious() { + SurgeWave oldWave = CoreAbility.getAbility(player, SurgeWave.class); + if (oldWave != null) { + oldWave.remove(); + } + } + + private void clearWave() { + for (Block block : waveBlocks.keySet()) { + TempBlock.revertBlock(block, Material.AIR); + } + waveBlocks.clear(); + } + + private void finalRemoveWater(Block block) { + if (waveBlocks.containsKey(block)) { + TempBlock.revertBlock(block, Material.AIR); + waveBlocks.remove(block); + } + } + + private void focusBlock() { + location = sourceBlock.getLocation(); + } + + private void freeze() { + clearWave(); + if (!bPlayer.canIcebend()) { + return; + } + + double freezeradius = currentRadius; + if (freezeradius > maxFreezeRadius) { + freezeradius = maxFreezeRadius; + } + + for (Block block : GeneralMethods.getBlocksAroundPoint(frozenLocation, freezeradius)) { + if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation()) || GeneralMethods.isRegionProtectedFromBuild(player, "PhaseChange", block.getLocation())) { + continue; + } else if (TempBlock.isTempBlock(block)) { + continue; + } + + if (block.getType() == Material.AIR || block.getType() == Material.SNOW) { + new TempBlock(block, Material.ICE, (byte) 0); + frozenBlocks.put(block, block); + } + if (isWater(block)) { + PhaseChangeFreeze.freeze(player, block); + } + if (isPlant(block) && block.getType() != Material.LEAVES) { + block.breakNaturally(); + new TempBlock(block, Material.ICE, (byte) 0); + frozenBlocks.put(block, block); + } + for (Block sound : frozenBlocks.keySet()) { + if ((new Random()).nextInt(4) == 0) { + playWaterbendingSound(sound.getLocation()); + } + } + } + } + + private Vector getDirection(Location location, Location destination) { + double x1, y1, z1; + double x0, y0, z0; + + x1 = destination.getX(); + y1 = destination.getY(); + z1 = destination.getZ(); + + x0 = location.getX(); + y0 = location.getY(); + z0 = location.getZ(); + + return new Vector(x1 - x0, y1 - y0, z1 - z0); + } + + @SuppressWarnings("deprecation") + public void moveWater() { + if (bPlayer.isOnCooldown(this)) { + return; + } + bPlayer.addCooldown(this); + + if (sourceBlock != null) { + if (!sourceBlock.getWorld().equals(player.getWorld())) { + return; + } + + range = getNightFactor(range); + if (bPlayer.isAvatarState()) { + pushFactor = AvatarState.getValue(pushFactor); + } + + Entity target = GeneralMethods.getTargetedEntity(player, range); + if (target == null) { + targetDestination = player.getTargetBlock(getTransparentMaterialSet(), (int) range).getLocation(); + } else { + targetDestination = ((LivingEntity) target).getEyeLocation(); + } + + if (targetDestination.distanceSquared(location) <= 1) { + progressing = false; + targetDestination = null; + } else { + progressing = true; + targetDirection = getDirection(sourceBlock.getLocation(), targetDestination).normalize(); + targetDestination = location.clone().add(targetDirection.clone().multiply(range)); + + if (isPlant(sourceBlock)) { + new PlantRegrowth(player, sourceBlock); + } + if (!GeneralMethods.isAdjacentToThreeOrMoreSources(sourceBlock)) { + sourceBlock.setType(Material.AIR); + } + addWater(sourceBlock); + } + } + } + + public boolean prepare() { + cancelPrevious(); + Block block = BlockSource.getWaterSourceBlock(player, range, ClickType.SHIFT_DOWN, true, true, bPlayer.canPlantbend()); + if (block != null && !GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + sourceBlock = block; + focusBlock(); + return true; + } + return false; + } + + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { + remove(); + return; + } + + if (System.currentTimeMillis() - time >= interval) { + time = System.currentTimeMillis(); + if (!progressing && !bPlayer.getBoundAbilityName().equalsIgnoreCase(getName())) { + remove(); + return; + } else if (!progressing) { + sourceBlock.getWorld().playEffect(location, Effect.SMOKE, 4, (int) range); + return; + } + + if (activateFreeze) { + if (location.distanceSquared(player.getLocation()) > range * range) { + progressing = false; + remove(); + return; + } + } else { + Vector direction = targetDirection; + location = location.clone().add(direction); + Block blockl = location.getBlock(); + ArrayList blocks = new ArrayList(); + + if (!GeneralMethods.isRegionProtectedFromBuild(this, location) + && (((blockl.getType() == Material.AIR || blockl.getType() == Material.FIRE + || isPlant(blockl) || isWater(blockl) + || isWaterbendable(blockl, player))) + && blockl.getType() != Material.LEAVES)) { + for (double i = 0; i <= currentRadius; i += .5) { + for (double angle = 0; angle < 360; angle += 10) { + Vector vec = GeneralMethods.getOrthogonalVector(targetDirection, angle, i); + Block block = location.clone().add(vec).getBlock(); + + if (!blocks.contains(block) + && (block.getType() == Material.AIR || block.getType() == Material.FIRE) + || isWaterbendable(block)) { + blocks.add(block); + FireBlast.removeFireBlastsAroundPoint(block.getLocation(), 2); + } + + if ((new Random()).nextInt(15) == 0) { + playWaterbendingSound(location); + } + } + } + } + + for (Block block : waveBlocks.keySet()) { + if (!blocks.contains(block)) { + finalRemoveWater(block); + } + } + for (Block block : blocks) { + if (!waveBlocks.containsKey(block)) { + addWater(block); + } + } + + if (waveBlocks.isEmpty()) { + location = location.subtract(direction); + remove(); + progressing = false; + return; + } + + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2 * currentRadius)) { + boolean knockback = false; + for (Block block : waveBlocks.keySet()) { + if (entity.getLocation().distanceSquared(block.getLocation()) <= 4) { + if (entity instanceof LivingEntity && freezing && entity.getEntityId() != player.getEntityId()) { + activateFreeze = true; + frozenLocation = entity.getLocation(); + freeze(); + break; + } + if (entity.getEntityId() != player.getEntityId() || canHitSelf) { + knockback = true; + } + } + } + if (knockback) { + Vector dir = direction.clone(); + dir.setY(dir.getY() * verticalFactor); + GeneralMethods.setVelocity(entity, entity.getVelocity().clone().add(dir.clone().multiply(getNightFactor(pushFactor)))); + + entity.setFallDistance(0); + if (entity.getFireTicks() > 0) { + entity.getWorld().playEffect(entity.getLocation(), Effect.EXTINGUISH, 0); + } + entity.setFireTicks(0); + AirAbility.breakBreathbendingHold(entity); + } + } + + if (!progressing) { + remove(); + return; + } + + if (location.distanceSquared(targetDestination) < 1) { + progressing = false; + remove(); + returnWater(); + return; + } + if (currentRadius < maxRadius) { + currentRadius += 0.5; + } + } + } + } + + @Override + public void remove() { + super.remove(); + thaw(); + returnWater(); + for (Block block : waveBlocks.keySet()) { + finalRemoveWater(block); + } + } + + public void returnWater() { + if (location != null) { + new WaterReturn(player, location.getBlock()); + } + } + + private void thaw() { + for (Block block : frozenBlocks.keySet()) { + TempBlock.revertBlock(block, Material.AIR); + frozenBlocks.remove(block); + } + } + + public static boolean canThaw(Block block) { + for (SurgeWave surgeWave : CoreAbility.getAbilities(SurgeWave.class)) { + if (surgeWave.frozenBlocks.containsKey(block)) { + return false; + } + } + return true; + } + + public static void removeAllCleanup() { + for (SurgeWave surgeWave : CoreAbility.getAbilities(SurgeWave.class)) { + for (Block block : surgeWave.waveBlocks.keySet()) { + block.setType(Material.AIR); + surgeWave.waveBlocks.remove(block); + } + for (Block block : surgeWave.frozenBlocks.keySet()) { + block.setType(Material.AIR); + surgeWave.frozenBlocks.remove(block); + } + } + } + + public static boolean isBlockWave(Block block) { + for (SurgeWave surgeWave : CoreAbility.getAbilities(SurgeWave.class)) { + if (surgeWave.waveBlocks.containsKey(block)) { + return true; + } + } + return false; + } + + public static void thaw(Block block) { + for (SurgeWave surgeWave : CoreAbility.getAbilities(SurgeWave.class)) { + if (surgeWave.frozenBlocks.containsKey(block)) { + TempBlock.revertBlock(block, Material.AIR); + surgeWave.frozenBlocks.remove(block); + } + } + } + + @Override + public String getName() { + return "Surge"; + } + + @Override + public Location getLocation() { + if (location != null) { + return location; + } else if (sourceBlock != null) { + return sourceBlock.getLocation(); + } + return player != null ? player.getLocation() : null; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isFreezing() { + return freezing; + } + + public void setFreezing(boolean freezing) { + this.freezing = freezing; + } + + public boolean isActivateFreeze() { + return activateFreeze; + } + + public void setActivateFreeze(boolean activateFreeze) { + this.activateFreeze = activateFreeze; + } + + public boolean isProgressing() { + return progressing; + } + + public void setProgressing(boolean progressing) { + this.progressing = progressing; + } + + public boolean isCanHitSelf() { + return canHitSelf; + } + + public void setCanHitSelf(boolean canHitSelf) { + this.canHitSelf = canHitSelf; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public double getCurrentRadius() { + return currentRadius; + } + + public void setCurrentRadius(double currentRadius) { + this.currentRadius = currentRadius; + } + + public double getMaxRadius() { + return maxRadius; + } + + public void setMaxRadius(double maxRadius) { + this.maxRadius = maxRadius; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getPushFactor() { + return pushFactor; + } + + public void setPushFactor(double pushFactor) { + this.pushFactor = pushFactor; + } + + public double getVerticalFactor() { + return verticalFactor; + } + + public void setVerticalFactor(double verticalFactor) { + this.verticalFactor = verticalFactor; + } + + public double getMaxFreezeRadius() { + return maxFreezeRadius; + } + + public void setMaxFreezeRadius(double maxFreezeRadius) { + this.maxFreezeRadius = maxFreezeRadius; + } + + public Block getSourceBlock() { + return sourceBlock; + } + + public void setSourceBlock(Block sourceBlock) { + this.sourceBlock = sourceBlock; + } + + public Location getTargetDestination() { + return targetDestination; + } + + public void setTargetDestination(Location targetDestination) { + this.targetDestination = targetDestination; + } + + public Location getFrozenLocation() { + return frozenLocation; + } + + public void setFrozenLocation(Location frozenLocation) { + this.frozenLocation = frozenLocation; + } + + public Vector getTargetDirection() { + return targetDirection; + } + + public void setTargetDirection(Vector targetDirection) { + this.targetDirection = targetDirection; + } + + public ConcurrentHashMap getWaveBlocks() { + return waveBlocks; + } + + public ConcurrentHashMap getFrozenBlocks() { + return frozenBlocks; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/waterbending/Torrent.java b/src/com/projectkorra/projectkorra/waterbending/Torrent.java index 7feda4c0..7c7ab0cc 100644 --- a/src/com/projectkorra/projectkorra/waterbending/Torrent.java +++ b/src/com/projectkorra/projectkorra/waterbending/Torrent.java @@ -1,208 +1,170 @@ package com.projectkorra.projectkorra.waterbending; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.earthbending.EarthMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; import com.projectkorra.projectkorra.util.BlockSource; import com.projectkorra.projectkorra.util.ClickType; import com.projectkorra.projectkorra.util.ParticleEffect; import com.projectkorra.projectkorra.util.TempBlock; -public class Torrent { +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - private static ConcurrentHashMap frozenblocks = new ConcurrentHashMap(); +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; - static FileConfiguration config = ProjectKorra.plugin.getConfig(); - static long interval = 30; - static double RANGE = config.getInt("Abilities.Water.Torrent.Range"); - private static int defaultrange = 20; - private static int DAMAGE = config.getInt("Abilities.Water.Torrent.Damage"); - private static long cooldown = config.getLong("Abilities.Water.Torrent.Cooldown"); - private static int DEFLECT_DAMAGE = config.getInt("Abilities.Water.Torrent.DeflectDamage"); - private static int maxlayer = 3; - private static double factor = 1; - private static double radius = 3; - private static double ylimit = 0.2; +public class Torrent extends WaterAbility { - private static final byte full = 0x0; - - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.Torrent.SelectRange"); - private static int autoSelectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.Torrent.AutoSourcing.SelectRange"); - private static boolean auto = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.Torrent.AutoSourcing.Enabled"); - private static long autocooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.Torrent.AutoSourcing.Cooldown"); - private static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.Torrent.DynamicSourcing.Enabled"); - - private Block sourceblock; + private static final double CLEANUP_RANGE = 50; + private static final ConcurrentHashMap FROZEN_BLOCKS = new ConcurrentHashMap(); + + private boolean sourceSelected; + private boolean settingUp; + private boolean forming; + private boolean formed; + private boolean launch; + private boolean launching; + private boolean freeze; + private int layer; + private int maxLayer; + private long time; + private long interval; + private long cooldown; + private double startAngle; + private double angle; + private double radius; + private double factor; + private double yLimit; + private double damage; + private double deflectDamage; + private double range; + private double selectRange; + private Block sourceBlock; private TempBlock source; private Location location; - private Player player; - private long time; - private double startangle = 0; - private double angle = 20; - private int layer = 0; - private boolean sourceselected = false; - private boolean settingup = false; - private boolean forming = false; - private boolean formed = false; - private boolean launch = false; - private boolean launching = false; - public boolean freeze = false; - private double range = RANGE; - private int damage = DAMAGE; - private int deflectdamage = DEFLECT_DAMAGE; - - private boolean isAuto; - - private ArrayList blocks = new ArrayList(); - public ArrayList launchblocks = new ArrayList(); - private ArrayList hurtentities = new ArrayList(); - + private ArrayList blocks; + private ArrayList launchedBlocks; + private ArrayList hurtEntities; + public Torrent(Player player) { - if (instances.containsKey(player)) { - Torrent torrent = instances.get(player); - if (!torrent.sourceselected) { - instances.get(player).use(); + super(player); + + this.layer = 0; + this.maxLayer = 3; + this.factor = 1; + this.startAngle = 0; + this.angle = 20; + this.radius = 3; + this.yLimit = 0.2; + this.interval = 30; + this.damage = getConfig().getDouble("Abilities.Water.Torrent.Damage"); + this.deflectDamage = getConfig().getDouble("Abilities.Water.Torrent.DeflectDamage"); + this.range = getConfig().getDouble("Abilities.Water.Torrent.Range"); + this.cooldown = 0; + this.selectRange = 10; + this.blocks = new ArrayList<>(); + this.launchedBlocks = new ArrayList<>(); + this.hurtEntities = new ArrayList<>(); + + Torrent oldTorrent = CoreAbility.getAbility(player, Torrent.class); + if (oldTorrent != null) { + if (!oldTorrent.sourceSelected) { + oldTorrent.use(); + bPlayer.addCooldown(oldTorrent); return; } } - this.player = player; - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if(bPlayer.isOnCooldown("Torrent")) { - return; - } time = System.currentTimeMillis(); - sourceblock = BlockSource.getWaterSourceBlock(player, autoSelectRange, selectRange, ClickType.LEFT_CLICK, auto, dynamic, - true, true, WaterMethods.canIcebend(player), WaterMethods.canPlantbend(player)); - if (sourceblock != null) { - if (BlockSource.isAuto(sourceblock)) { - isAuto = true; - } else { - isAuto = false; - } - - sourceselected = true; - instances.put(player, this); + sourceBlock = BlockSource.getWaterSourceBlock(player, selectRange, ClickType.LEFT_CLICK, true, true, bPlayer.canPlantbend()); + if (sourceBlock != null && !GeneralMethods.isRegionProtectedFromBuild(this, sourceBlock.getLocation())) { + sourceSelected = true; + start(); } } private void freeze() { - if (layer == 0) + if (layer == 0) { return; - if (!GeneralMethods.canBend(player.getName(), "PhaseChange")) + } else if (!bPlayer.canBendIgnoreBindsCooldowns(getAbility("PhaseChange"))) { return; + } + List ice = GeneralMethods.getBlocksAroundPoint(location, layer); for (Block block : ice) { - if (EarthMethods.isTransparentToEarthbending(player, block) && block.getType() != Material.ICE) { + if (isTransparentToEarthbending(player, block) && block.getType() != Material.ICE) { TempBlock tblock = new TempBlock(block, Material.ICE, (byte) 0); - frozenblocks.put(tblock, player); - WaterMethods.playIcebendingSound(block.getLocation()); + FROZEN_BLOCKS.put(tblock, player); + playIcebendingSound(block.getLocation()); } } } - private void progress() { - if (player.isDead() || !player.isOnline()) { + @Override + public void progress() { + if (!bPlayer.canBendIgnoreCooldowns(this)) { remove(); return; } - if (!GeneralMethods.canBend(player.getName(), "Torrent")) { - remove(); - return; - } - - if (GeneralMethods.getBoundAbility(player) == null) { - remove(); - if (location != null) - returnWater(location); - return; - } - if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("Torrent")) { - remove(); - if (location != null) - returnWater(location); - return; - } - if (System.currentTimeMillis() > time + interval) { time = System.currentTimeMillis(); - if (sourceselected) { - if (!sourceblock.getWorld().equals(player.getWorld())) { - remove(); - return; - } - - if (sourceblock.getLocation().distance(player.getLocation()) > selectRange) { + if (sourceSelected) { + if (sourceBlock.getLocation().distanceSquared(player.getLocation()) > selectRange * selectRange) { return; } if (player.isSneaking()) { - sourceselected = false; - settingup = true; - if (WaterMethods.isPlant(sourceblock)) { - new Plantbending(sourceblock); - sourceblock.setType(Material.AIR); - } else if (!GeneralMethods.isAdjacentToThreeOrMoreSources(sourceblock)) { - sourceblock.setType(Material.AIR); + sourceSelected = false; + settingUp = true; + + if (isPlant(sourceBlock)) { + new PlantRegrowth(player, sourceBlock); + sourceBlock.setType(Material.AIR); + } else if (!GeneralMethods.isAdjacentToThreeOrMoreSources(sourceBlock)) { + sourceBlock.setType(Material.AIR); } - source = new TempBlock(sourceblock, Material.STATIONARY_WATER, (byte) 8); - location = sourceblock.getLocation(); + source = new TempBlock(sourceBlock, Material.STATIONARY_WATER, (byte) 8); + location = sourceBlock.getLocation(); } else { - WaterMethods.playFocusWaterEffect(sourceblock); + playFocusWaterEffect(sourceBlock); return; } } - if (settingup) { + if (settingUp) { if (!player.isSneaking()) { + location = source.getLocation(); remove(); - returnWater(source.getLocation()); return; } - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - Location eyeloc = player.getEyeLocation(); - double startangle = player.getEyeLocation().getDirection().angle(new Vector(1, 0, 0)); - double dx = radius * Math.cos(startangle); - double dy = 0; - double dz = radius * Math.sin(startangle); - Location setup = eyeloc.clone().add(dx, dy, dz); + Location eyeLoc = player.getEyeLocation(); + double startAngle = player.getEyeLocation().getDirection().angle(new Vector(1, 0, 0)); + double dx = radius * Math.cos(startAngle); + double dy = 0; + double dz = radius * Math.sin(startAngle); + Location setup = eyeLoc.clone().add(dx, dy, dz); + if (!location.getWorld().equals(player.getWorld())) { remove(); return; - } - - if (location.distance(setup) > defaultrange) { + } else if (location.distanceSquared(setup) > range * range) { remove(); return; } - - if (isAuto) { - bPlayer.addCooldown("Torrent", autocooldown); - } else { - bPlayer.addCooldown("Torrent", cooldown); - } if (location.getBlockY() > setup.getBlockY()) { Vector direction = new Vector(0, -1, 0); @@ -215,34 +177,32 @@ public class Torrent { location = location.clone().add(direction); } - if (location.distance(setup) <= 1) { - settingup = false; + if (location.distanceSquared(setup) <= 1) { + settingUp = false; source.revertBlock(); source = null; forming = true; - } else { - if (!location.getBlock().equals(source.getLocation().getBlock())) { - source.revertBlock(); - source = null; - Block block = location.getBlock(); - if (!EarthMethods.isTransparentToEarthbending(player, block) || block.isLiquid()) { - remove(); - return; - } - source = new TempBlock(location.getBlock(), Material.STATIONARY_WATER, (byte) 8); + } else if (!location.getBlock().equals(source.getLocation().getBlock())) { + source.revertBlock(); + source = null; + Block block = location.getBlock(); + if (!isTransparentToEarthbending(player, block) || block.isLiquid()) { + remove(); + return; } + source = new TempBlock(location.getBlock(), Material.STATIONARY_WATER, (byte) 8); } } if (forming && !player.isSneaking()) { + location = player.getEyeLocation().add(radius, 0, 0); remove(); - returnWater(player.getEyeLocation().add(radius, 0, 0)); return; } if (forming || formed) { - if (GeneralMethods.rand.nextInt(4) == 0) { - WaterMethods.playWaterbendingSound(location); + if ((new Random()).nextInt(4) == 0) { + playWaterbendingSound(location); } if (angle < 220) { angle += 20; @@ -250,6 +210,7 @@ public class Torrent { forming = false; formed = true; } + formRing(); if (blocks.isEmpty()) { remove(); @@ -258,7 +219,7 @@ public class Torrent { } if (formed && !player.isSneaking() && !launch) { - new TorrentBurst(player, radius); + new TorrentWave(player, radius); remove(); return; } @@ -281,123 +242,113 @@ public class Torrent { } if (!launch()) { remove(); - returnWater(location); return; } - } } - } @SuppressWarnings("deprecation") private boolean launch() { - if (launchblocks.isEmpty() && blocks.isEmpty()) { + if (launchedBlocks.isEmpty() && blocks.isEmpty()) { return false; } - if (launchblocks.isEmpty()) { + if (launchedBlocks.isEmpty()) { clearRing(); - // double startangle = Math.toDegrees(player.getEyeLocation() - // .getDirection().angle(new Vector(1, 0, 0))); Location loc = player.getEyeLocation(); - ArrayList doneblocks = new ArrayList(); - for (double theta = startangle; theta < angle + startangle; theta += 20) { + ArrayList doneBlocks = new ArrayList(); + for (double theta = startAngle; theta < angle + startAngle; theta += 20) { double phi = Math.toRadians(theta); double dx = Math.cos(phi) * radius; double dy = 0; double dz = Math.sin(phi) * radius; Location blockloc = loc.clone().add(dx, dy, dz); - if (Math.abs(theta - startangle) < 10) + + if (Math.abs(theta - startAngle) < 10) { location = blockloc.clone(); + } + Block block = blockloc.getBlock(); - if (!doneblocks.contains(block) && !GeneralMethods.isRegionProtectedFromBuild(player, "Torrent", blockloc)) { - if (EarthMethods.isTransparentToEarthbending(player, block) && !block.isLiquid()) { - launchblocks.add(new TempBlock(block, Material.STATIONARY_WATER, (byte) 8)); - doneblocks.add(block); - } else if (!EarthMethods.isTransparentToEarthbending(player, block)) + if (!doneBlocks.contains(block) && !GeneralMethods.isRegionProtectedFromBuild(this, blockloc)) { + if (isTransparentToEarthbending(player, block) && !block.isLiquid()) { + launchedBlocks.add(new TempBlock(block, Material.STATIONARY_WATER, (byte) 8)); + doneBlocks.add(block); + } else if (!isTransparentToEarthbending(player, block)) { break; + } } } - if (launchblocks.isEmpty()) { + if (launchedBlocks.isEmpty()) { return false; } else { return true; } } - Entity target = GeneralMethods.getTargetedEntity(player, range, hurtentities); - Location targetloc = player.getTargetBlock(EarthMethods.getTransparentEarthbending(), (int) range).getLocation(); - // Location targetloc = Methods.getTargetedLocation(player, range, - // Methods.transparentEarthbending); + Entity target = GeneralMethods.getTargetedEntity(player, range, hurtEntities); + Location targetLoc = player.getTargetBlock(getTransparentMaterialSet(), (int) range).getLocation(); if (target != null) { - targetloc = target.getLocation(); + targetLoc = target.getLocation(); } - ArrayList newblocks = new ArrayList(); - + ArrayList newBlocks = new ArrayList(); List entities = GeneralMethods.getEntitiesAroundPoint(player.getLocation(), range + 5); - List affectedentities = new ArrayList(); - - Block realblock = launchblocks.get(0).getBlock(); - - Vector dir = GeneralMethods.getDirection(location, targetloc).normalize(); + List affectedEntities = new ArrayList(); + Block realBlock = launchedBlocks.get(0).getBlock(); + Vector dir = GeneralMethods.getDirection(location, targetLoc).normalize(); if (target != null) { - targetloc = location.clone().add(dir.clone().multiply(10)); + targetLoc = location.clone().add(dir.clone().multiply(10)); + } + if (layer == 0) { + location = location.clone().add(dir); } - // Methods.verbose(layer); - if (layer == 0) - location = location.clone().add(dir); - - Block b = location.getBlock(); - - // player.sendBlockChange(location, 20, (byte) 0); - - if (location.distance(player.getLocation()) > range - || GeneralMethods.isRegionProtectedFromBuild(player, "Torrent", location)) { - if (layer < maxlayer) - if (freeze || layer < 1) + Block locBlock = location.getBlock(); + if (location.distanceSquared(player.getLocation()) > range * range || GeneralMethods.isRegionProtectedFromBuild(this, location)) { + if (layer < maxLayer) { + if (freeze || layer < 1) { layer++; - if (launchblocks.size() == 1) { + } + } + if (launchedBlocks.size() == 1) { remove(); - returnWater(location); return false; } - } else if (!EarthMethods.isTransparentToEarthbending(player, b)) { - // b.setType(Material.GLASS); - if (layer < maxlayer) { - // Methods.verbose(layer); - if (layer == 0) - hurtentities.clear(); - if (freeze || layer < 1) + } else if (!isTransparentToEarthbending(player, locBlock)) { + if (layer < maxLayer) { + if (layer == 0) { + hurtEntities.clear(); + } + if (freeze || layer < 1) { layer++; + } } if (freeze) { freeze(); - } else if (launchblocks.size() == 1) { + } else if (launchedBlocks.size() == 1) { + location = realBlock.getLocation(); remove(); - returnWater(realblock.getLocation()); return false; } } else { - if (b.equals(realblock) && layer == 0) { - // Methods.verbose(dir); + if (locBlock.equals(realBlock) && layer == 0) { return true; } - if (b.getLocation().distance(targetloc) > 1) { - if (WaterMethods.isWater(b)) { - ParticleEffect.WATER_BUBBLE.display((float) Math.random(), (float) Math.random(), (float) Math.random(), 0f, - 5, b.getLocation().clone().add(.5, .5, .5), 257D); + if (locBlock.getLocation().distanceSquared(targetLoc) > 1) { + if (isWater(locBlock)) { + ParticleEffect.WATER_BUBBLE.display((float) Math.random(), (float) Math.random(), (float) Math.random(), 0f, 5, locBlock.getLocation().clone().add(.5,.5,.5), 257D); } - newblocks.add(new TempBlock(b, Material.STATIONARY_WATER, (byte) 8)); + newBlocks.add(new TempBlock(locBlock, Material.STATIONARY_WATER, (byte) 8)); } else { - if (layer < maxlayer) { - if (layer == 0) - hurtentities.clear(); - if (freeze || layer < 1) + if (layer < maxLayer) { + if (layer == 0) { + hurtEntities.clear(); + } + if (freeze || layer < 1) { layer++; + } } if (freeze) { freeze(); @@ -405,61 +356,64 @@ public class Torrent { } } - for (int i = 0; i < launchblocks.size(); i++) { - TempBlock block = launchblocks.get(i); - if (i == launchblocks.size() - 1) { + for (int i = 0; i < launchedBlocks.size(); i++) { + TempBlock block = launchedBlocks.get(i); + if (i == launchedBlocks.size() - 1) { block.revertBlock(); } else { - newblocks.add(block); + newBlocks.add(block); for (Entity entity : entities) { - if (entity.getWorld() != block.getBlock().getWorld()) + if (entity.getWorld() != block.getBlock().getWorld()) { continue; - if (entity.getLocation().distance(block.getLocation()) <= 1.5 && !affectedentities.contains(entity)) { + } + if (entity.getLocation().distanceSquared(block.getLocation()) <= 1.5 * 1.5 && !affectedEntities.contains(entity)) { if (i == 0) { affect(entity, dir); } else { - affect(entity, GeneralMethods.getDirection(block.getLocation(), launchblocks.get(i - 1).getLocation()) - .normalize()); + affect(entity, GeneralMethods.getDirection(block.getLocation(), launchedBlocks.get(i - 1).getLocation()).normalize()); } - affectedentities.add(entity); + affectedEntities.add(entity); } } } } - launchblocks.clear(); - launchblocks.addAll(newblocks); + launchedBlocks.clear(); + launchedBlocks.addAll(newBlocks); - if (launchblocks.isEmpty()) + if (launchedBlocks.isEmpty()) { return false; - + } return true; } private void formRing() { clearRing(); - // double startangle = Math.toDegrees(player.getEyeLocation() - // .getDirection().angle(new Vector(1, 0, 0))); - startangle += 30; + startAngle += 30; + Location loc = player.getEyeLocation(); - ArrayList doneblocks = new ArrayList(); + ArrayList doneBlocks = new ArrayList(); + ArrayList affectedEntities = new ArrayList(); List entities = GeneralMethods.getEntitiesAroundPoint(loc, radius + 2); - List affectedentities = new ArrayList(); - for (double theta = startangle; theta < angle + startangle; theta += 20) { + + for (double theta = startAngle; theta < angle + startAngle; theta += 20) { double phi = Math.toRadians(theta); double dx = Math.cos(phi) * radius; double dy = 0; double dz = Math.sin(phi) * radius; - Location blockloc = loc.clone().add(dx, dy, dz); - Block block = blockloc.getBlock(); - if (!doneblocks.contains(block)) { - if (EarthMethods.isTransparentToEarthbending(player, block) && !block.isLiquid()) { + Location blockLoc = loc.clone().add(dx, dy, dz); + Block block = blockLoc.getBlock(); + + if (!doneBlocks.contains(block)) { + if (isTransparentToEarthbending(player, block) && !block.isLiquid()) { blocks.add(new TempBlock(block, Material.STATIONARY_WATER, (byte) 8)); - doneblocks.add(block); + doneBlocks.add(block); + for (Entity entity : entities) { - if (entity.getWorld() != blockloc.getWorld()) + if (entity.getWorld() != blockLoc.getWorld()) { continue; - if (!affectedentities.contains(entity) && entity.getLocation().distance(blockloc) <= 1.5) { + } + if (!affectedEntities.contains(entity) && entity.getLocation().distanceSquared(blockLoc) <= 1.5 * 1.5) { deflect(entity); } } @@ -475,39 +429,43 @@ public class Torrent { blocks.clear(); } + @Override public void remove() { + super.remove(); clearRing(); - for (TempBlock block : launchblocks) + for (TempBlock block : launchedBlocks) { block.revertBlock(); - launchblocks.clear(); - if (source != null) + } + + launchedBlocks.clear(); + if (source != null) { source.revertBlock(); - instances.remove(player); + } + + if (location != null) { + returnWater(location); + } } private void returnWater(Location location) { new WaterReturn(player, location.getBlock()); } - public static void use(Player player) { - if (instances.containsKey(player)) { - instances.get(player).use(); - } - } - @SuppressWarnings("deprecation") public static void create(Player player) { - if (instances.containsKey(player)) + if (CoreAbility.hasAbility(player, Torrent.class)) { return; + } + if (WaterReturn.hasWaterBottle(player)) { - Location eyeloc = player.getEyeLocation(); - Block block = eyeloc.add(eyeloc.getDirection().normalize()).getBlock(); - if (EarthMethods.isTransparentToEarthbending(player, block) - && EarthMethods.isTransparentToEarthbending(player, eyeloc.getBlock())) { + Location eyeLoc = player.getEyeLocation(); + Block block = eyeLoc.add(eyeLoc.getDirection().normalize()).getBlock(); + if (isTransparentToEarthbending(player, block) && isTransparentToEarthbending(player, eyeLoc.getBlock())) { block.setType(Material.WATER); - block.setData(full); + block.setData((byte) 0); Torrent tor = new Torrent(player); - if (tor.sourceselected || tor.settingup) { + + if (tor.sourceSelected || tor.settingUp) { WaterReturn.emptyWaterBottle(player); } else { block.setType(Material.AIR); @@ -518,13 +476,15 @@ public class Torrent { private void use() { launch = true; - if (launching) + if (launching) { freeze = true; + } } private void deflect(Entity entity) { - if (entity.getEntityId() == player.getEntityId()) + if (entity.getEntityId() == player.getEntityId()) { return; + } double x, z, vx, vz, mag; double angle = 50; angle = Math.toRadians(angle); @@ -538,9 +498,9 @@ public class Torrent { vz = (x * Math.sin(angle) + z * Math.cos(angle)) / mag; Vector vec = new Vector(vx, 0, vz).normalize().multiply(factor); - Vector velocity = entity.getVelocity(); - if (AvatarState.isAvatarState(player)) { + + if (bPlayer.isAvatarState()) { velocity.setX(AvatarState.getValue(vec.getX())); velocity.setZ(AvatarState.getValue(vec.getZ())); } else { @@ -551,61 +511,48 @@ public class Torrent { GeneralMethods.setVelocity(entity, velocity); entity.setFallDistance(0); if (entity instanceof LivingEntity) { - World world = player.getWorld(); - int damagedealt = deflectdamage; - if (WaterMethods.isNight(world)) { - damagedealt = (int) (WaterMethods.getWaterbendingNightAugment(world) * (double) deflectdamage); - } - GeneralMethods.damageEntity(player, entity, damagedealt, "Torrent"); - AirMethods.breakBreathbendingHold(entity); + double damageDealt = getNightFactor(deflectDamage); + GeneralMethods.damageEntity(this, entity, damageDealt); + AirAbility.breakBreathbendingHold(entity); } } private void affect(Entity entity, Vector direction) { - if (entity.getEntityId() == player.getEntityId()) + if (entity.getEntityId() == player.getEntityId()) { return; - if (direction.getY() > ylimit) { - direction.setY(ylimit); } - if (!freeze) + if (direction.getY() > yLimit) { + direction.setY(yLimit); + } + if (!freeze) { entity.setVelocity(direction.multiply(factor)); - if (entity instanceof LivingEntity && !hurtentities.contains(entity)) { - World world = player.getWorld(); - int damagedealt = damage; - if (WaterMethods.isNight(world)) { - damagedealt = (int) (WaterMethods.getWaterbendingNightAugment(world) * (double) damage); - } - // if (((LivingEntity) entity).getNoDamageTicks() == 0) { - GeneralMethods.damageEntity(player, entity, damagedealt, "Torrent"); - AirMethods.breakBreathbendingHold(entity); - // Methods.verbose("Hit! Health at " - // + ((LivingEntity) entity).getHealth()); - hurtentities.add(entity); - // } + } + if (entity instanceof LivingEntity && !hurtEntities.contains(entity)) { + double damageDealt = getNightFactor(damage); + GeneralMethods.damageEntity(this, entity, damageDealt); + AirAbility.breakBreathbendingHold(entity); + hurtEntities.add(entity); ((LivingEntity) entity).setNoDamageTicks(0); } } - public static void progressAll() { - for (Player player : instances.keySet()) - instances.get(player).progress(); - - for (TempBlock block : frozenblocks.keySet()) { - Player player = frozenblocks.get(block); - if (block.getBlock().getType() != Material.ICE) { - frozenblocks.remove(block); + public static void progressAllCleanup() { + for (TempBlock block : FROZEN_BLOCKS.keySet()) { + Player player = FROZEN_BLOCKS.get(block); + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + return; + } else if (block.getBlock().getType() != Material.ICE) { + FROZEN_BLOCKS.remove(block); continue; - } - if (!player.isOnline()) { + } else if (!player.isOnline()) { thaw(block); continue; - } - if (block.getBlock().getWorld() != player.getWorld()) { + } else if (block.getBlock().getWorld() != player.getWorld()) { thaw(block); continue; - } - if (block.getLocation().distance(player.getLocation()) > RANGE - || !GeneralMethods.canBend(player.getName(), "Torrent")) { + } else if (block.getLocation().distanceSquared(player.getLocation()) > CLEANUP_RANGE * CLEANUP_RANGE + || !bPlayer.canBendIgnoreBindsCooldowns(getAbility("Torrent"))) { thaw(block); } } @@ -614,66 +561,211 @@ public class Torrent { public static void thaw(Block block) { if (TempBlock.isTempBlock(block)) { TempBlock tblock = TempBlock.get(block); - if (frozenblocks.containsKey(tblock)) + if (FROZEN_BLOCKS.containsKey(tblock)) { thaw(tblock); + } } } public static void thaw(TempBlock block) { block.revertBlock(); - frozenblocks.remove(block); + FROZEN_BLOCKS.remove(block); } public static boolean canThaw(Block block) { if (TempBlock.isTempBlock(block)) { TempBlock tblock = TempBlock.get(block); - return !frozenblocks.containsKey(tblock); + return !FROZEN_BLOCKS.containsKey(tblock); } return true; } - public static void removeAll() { - for (Player player : instances.keySet()) - instances.get(player).remove(); - - for (TempBlock block : frozenblocks.keySet()) + public static void removeCleanup() { + for (TempBlock block : FROZEN_BLOCKS.keySet()) { thaw(block); - + } } public static boolean wasBrokenFor(Player player, Block block) { - if (instances.containsKey(player)) { - Torrent torrent = instances.get(player); - if (torrent.sourceblock == null) + Torrent torrent = CoreAbility.getAbility(player, Torrent.class); + if (torrent != null) { + if (torrent.sourceBlock == null) { return false; - if (torrent.sourceblock.equals(block)) + } + if (torrent.sourceBlock.equals(block)) { return true; + } } return false; } - public static String getDescription() { - return "Torrent is one of the strongest moves in a waterbender's arsenal. To use, first click a source block to select it; then hold shift to begin streaming the water around you. Water flowing around you this way will damage and knock back nearby enemies and projectiles. If you release shift during this, you will create a large wave that expands outwards from you, launching anything in its path back. Instead, if you click you release the water and channel it to flow towards your cursor. Anything caught in the blast will be tossed about violently and take damage. Finally, if you click again when the water is torrenting, it will freeze the area around it when it is obstructed."; + @Override + public String getName() { + return "Torrent"; } - public Player getPlayer() { - return player; + @Override + public Location getLocation() { + return location; } - public int getDamage() { + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isSourceSelected() { + return sourceSelected; + } + + public void setSourceSelected(boolean sourceSelected) { + this.sourceSelected = sourceSelected; + } + + public boolean isSettingUp() { + return settingUp; + } + + public void setSettingUp(boolean settingUp) { + this.settingUp = settingUp; + } + + public boolean isForming() { + return forming; + } + + public void setForming(boolean forming) { + this.forming = forming; + } + + public boolean isFormed() { + return formed; + } + + public void setFormed(boolean formed) { + this.formed = formed; + } + + public boolean isLaunch() { + return launch; + } + + public void setLaunch(boolean launch) { + this.launch = launch; + } + + public boolean isLaunching() { + return launching; + } + + public void setLaunching(boolean launching) { + this.launching = launching; + } + + public boolean isFreeze() { + return freeze; + } + + public void setFreeze(boolean freeze) { + this.freeze = freeze; + } + + public int getLayer() { + return layer; + } + + public void setLayer(int layer) { + this.layer = layer; + } + + public int getMaxLayer() { + return maxLayer; + } + + public void setMaxLayer(int maxLayer) { + this.maxLayer = maxLayer; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public double getStartAngle() { + return startAngle; + } + + public void setStartAngle(double startAngle) { + this.startAngle = startAngle; + } + + public double getAngle() { + return angle; + } + + public void setAngle(double angle) { + this.angle = angle; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getFactor() { + return factor; + } + + public void setFactor(double factor) { + this.factor = factor; + } + + public double getyLimit() { + return yLimit; + } + + public void setyLimit(double yLimit) { + this.yLimit = yLimit; + } + + public double getDamage() { return damage; } - public void setDamage(int damage) { + public void setDamage(double damage) { this.damage = damage; } - public int getDeflectdamage() { - return deflectdamage; + public double getDeflectDamage() { + return deflectDamage; } - public void setDeflectdamage(int deflectdamage) { - this.deflectdamage = deflectdamage; + public void setDeflectDamage(double deflectDamage) { + this.deflectDamage = deflectDamage; } public double getRange() { @@ -684,4 +776,60 @@ public class Torrent { this.range = range; } -} \ No newline at end of file + public double getSelectRange() { + return selectRange; + } + + public void setSelectRange(double selectRange) { + this.selectRange = selectRange; + } + + public Block getSourceBlock() { + return sourceBlock; + } + + public void setSourceBlock(Block sourceBlock) { + this.sourceBlock = sourceBlock; + } + + public TempBlock getSource() { + return source; + } + + public void setSource(TempBlock source) { + this.source = source; + } + + public ArrayList getBlocks() { + return blocks; + } + + public void setBlocks(ArrayList blocks) { + this.blocks = blocks; + } + + public static double getCleanupRange() { + return CLEANUP_RANGE; + } + + public static ConcurrentHashMap getFrozenBlocks() { + return FROZEN_BLOCKS; + } + + public ArrayList getLaunchedBlocks() { + return launchedBlocks; + } + + public ArrayList getHurtEntities() { + return hurtEntities; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/waterbending/TorrentBurst.java b/src/com/projectkorra/projectkorra/waterbending/TorrentBurst.java deleted file mode 100644 index acbf8abe..00000000 --- a/src/com/projectkorra/projectkorra/waterbending/TorrentBurst.java +++ /dev/null @@ -1,232 +0,0 @@ -package com.projectkorra.projectkorra.waterbending; - -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.util.TempBlock; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; - -public class TorrentBurst { - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - - private static int ID = Integer.MIN_VALUE; - private static double defaultmaxradius = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.Torrent.Wave.Radius"); - private static double dr = 0.5; - private static double defaultfactor = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.Torrent.Wave.Knockback"); - private static double MAX_HEIGHT = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.Torrent.Wave.Height"); - private static long interval = Torrent.interval; - - // private static final byte full = 0x0; - // private static final Vector reference = new Vector(1, 0, 0); - - private int id; - private long time; - private double radius = dr; - private double maxradius = defaultmaxradius; - private double factor = defaultfactor; - private double maxheight = MAX_HEIGHT; - private Location origin; - private Player player; - private ConcurrentHashMap> heights = new ConcurrentHashMap>(); - private ArrayList blocks = new ArrayList(); - private ArrayList affectedentities = new ArrayList(); - - public TorrentBurst(Player player) { - this(player, player.getEyeLocation(), dr); - } - - public TorrentBurst(Player player, Location location) { - this(player, location, dr); - } - - public TorrentBurst(Player player, double radius) { - this(player, player.getEyeLocation(), radius); - } - - public TorrentBurst(Player player, Location location, double radius) { - this.player = player; - World world = player.getWorld(); - origin = location.clone(); - time = System.currentTimeMillis(); - id = ID++; - factor = WaterMethods.waterbendingNightAugment(factor, world); - maxradius = WaterMethods.waterbendingNightAugment(maxradius, world); - this.radius = radius; - if (ID >= Integer.MAX_VALUE) { - ID = Integer.MIN_VALUE; - } - initializeHeightsMap(); - instances.put(id, this); - } - - private void initializeHeightsMap() { - for (int i = -1; i <= maxheight; i++) { - ConcurrentHashMap angles = new ConcurrentHashMap(); - double dtheta = Math.toDegrees(1 / (maxradius + 2)); - int j = 0; - for (double theta = 0; theta < 360; theta += dtheta) { - angles.put(j, theta); - j++; - } - heights.put(i, angles); - } - } - - private void progress() { - if (player.isDead() || !player.isOnline()) { - remove(); - return; - } - - if (!GeneralMethods.canBend(player.getName(), "Torrent")) { - remove(); - return; - } - - if (System.currentTimeMillis() > time + interval) { - if (radius < maxradius) { - radius += dr; - } else { - remove(); - returnWater(); - return; - } - - formBurst(); - - time = System.currentTimeMillis(); - - } - } - - private void formBurst() { - for (TempBlock tempBlock : blocks) { - tempBlock.revertBlock(); - } - - blocks.clear(); - - affectedentities.clear(); - - ArrayList indexlist = new ArrayList(); - indexlist.addAll(GeneralMethods.getEntitiesAroundPoint(origin, radius + 2)); - - ArrayList torrentblocks = new ArrayList(); - - if (indexlist.contains(player)) - indexlist.remove(player); - - for (int id : heights.keySet()) { - ConcurrentHashMap angles = heights.get(id); - for (int index : angles.keySet()) { - double angle = angles.get(index); - double theta = Math.toRadians(angle); - double dx = Math.cos(theta) * radius; - double dy = id; - double dz = Math.sin(theta) * radius; - Location location = origin.clone().add(dx, dy, dz); - Block block = location.getBlock(); - if (torrentblocks.contains(block)) - continue; - if (EarthMethods.isTransparentToEarthbending(player, block)) { - TempBlock tempBlock = new TempBlock(block, Material.STATIONARY_WATER, (byte) 8); - blocks.add(tempBlock); - torrentblocks.add(block); - } else { - angles.remove(index); - continue; - } - for (Entity entity : indexlist) { - if (!affectedentities.contains(entity)) { - if (entity.getLocation().distance(location) <= 2) { - affectedentities.add(entity); - affect(entity); - } - } - } - - for (Block sound : torrentblocks) { - if (GeneralMethods.rand.nextInt(50) == 0) { - WaterMethods.playWaterbendingSound(sound.getLocation()); - } - } - } - if (angles.isEmpty()) - heights.remove(id); - } - if (heights.isEmpty()) - remove(); - } - - private void affect(Entity entity) { - Vector direction = GeneralMethods.getDirection(origin, entity.getLocation()); - direction.setY(0); - direction.normalize(); - entity.setVelocity(entity.getVelocity().clone().add(direction.multiply(factor))); - } - - private void remove() { - for (TempBlock block : blocks) { - block.revertBlock(); - } - instances.remove(id); - } - - private void returnWater() { - Location location = new Location(origin.getWorld(), origin.getX() + radius, origin.getY(), origin.getZ()); - if (!location.getWorld().equals(player.getWorld())) - return; - if (location.distance(player.getLocation()) > maxradius + 5) - return; - new WaterReturn(player, location.getBlock()); - } - - public static void progressAll() { - for (int id : instances.keySet()) - instances.get(id).progress(); - } - - public static void removeAll() { - for (int id : instances.keySet()) - instances.get(id).remove(); - } - - public double getMaxradius() { - return maxradius; - } - - public void setMaxradius(double maxradius) { - this.maxradius = maxradius; - } - - public double getFactor() { - return factor; - } - - public void setFactor(double factor) { - this.factor = factor; - } - - public double getMaxheight() { - return maxheight; - } - - public void setMaxheight(double maxheight) { - this.maxheight = maxheight; - } - - public Player getPlayer() { - return player; - } -} diff --git a/src/com/projectkorra/projectkorra/waterbending/TorrentWave.java b/src/com/projectkorra/projectkorra/waterbending/TorrentWave.java new file mode 100644 index 00000000..cfc0c33b --- /dev/null +++ b/src/com/projectkorra/projectkorra/waterbending/TorrentWave.java @@ -0,0 +1,294 @@ +package com.projectkorra.projectkorra.waterbending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.util.TempBlock; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; + +public class TorrentWave extends WaterAbility { + + private long time; + private long interval; + private long cooldown; + private double radius; + private double maxRadius; + private double knockback; + private double maxHeight; + private double growSpeed; + private Location origin; + private ArrayList blocks; + private ArrayList affectedEntities; + private ConcurrentHashMap> heights; + + public TorrentWave(Player player, double radius) { + this(player, player.getEyeLocation(), radius); + } + + public TorrentWave(Player player, Location location, double radius) { + super(player); + + this.radius = radius; + this.interval = 30; + this.maxHeight = getConfig().getDouble("Abilities.Water.Torrent.Wave.Height"); + this.maxRadius = getConfig().getDouble("Abilities.Water.Torrent.Wave.Radius"); + this.knockback = getConfig().getDouble("Abilities.Water.Torrent.Wave.Knockback"); + this.cooldown = 0; + this.growSpeed = 0.5; + this.origin = location.clone(); + this.time = System.currentTimeMillis(); + this.heights = new ConcurrentHashMap<>(); + this.blocks = new ArrayList(); + this.affectedEntities = new ArrayList(); + + this.knockback = getNightFactor(knockback); + this.maxRadius = getNightFactor(maxRadius); + + initializeHeightsMap(); + start(); + bPlayer.addCooldown(this); + } + + private void initializeHeightsMap() { + for (int i = -1; i <= maxHeight; i++) { + ConcurrentHashMap angles = new ConcurrentHashMap<>(); + double dtheta = Math.toDegrees(1 / (maxRadius + 2)); + int j = 0; + + for (double theta = 0; theta < 360; theta += dtheta) { + angles.put(j, theta); + j++; + } + heights.put(i, angles); + } + } + + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { + remove(); + return; + + } + + if (System.currentTimeMillis() > time + interval) { + if (radius < maxRadius) { + radius += growSpeed; + } else { + remove(); + returnWater(); + return; + } + formBurst(); + time = System.currentTimeMillis(); + } + } + + private void formBurst() { + for (TempBlock tempBlock : blocks) { + tempBlock.revertBlock(); + } + + blocks.clear(); + affectedEntities.clear(); + + ArrayList indexList = new ArrayList(); + indexList.addAll(GeneralMethods.getEntitiesAroundPoint(origin, radius + 2)); + ArrayList torrentBlocks = new ArrayList(); + + if (indexList.contains(player)) { + indexList.remove(player); + } + + for (int id : heights.keySet()) { + ConcurrentHashMap angles = heights.get(id); + for (int index : angles.keySet()) { + double angle = angles.get(index); + double theta = Math.toRadians(angle); + double dx = Math.cos(theta) * radius; + double dy = id; + double dz = Math.sin(theta) * radius; + + Location location = origin.clone().add(dx, dy, dz); + Block block = location.getBlock(); + + if (torrentBlocks.contains(block)) { + continue; + } + + if (isTransparentToEarthbending(player, block)) { + TempBlock tempBlock = new TempBlock(block, Material.STATIONARY_WATER, (byte) 8); + blocks.add(tempBlock); + torrentBlocks.add(block); + } else { + angles.remove(index); + continue; + } + + for (Entity entity : indexList) { + if (!affectedEntities.contains(entity)) { + if (entity.getLocation().distanceSquared(location) <= 4) { + affectedEntities.add(entity); + affect(entity); + } + } + } + + Random random = new Random(); + for (Block sound : torrentBlocks) { + if (random.nextInt(50) == 0) { + playWaterbendingSound(sound.getLocation()); + } + } + } + if (angles.isEmpty()) { + heights.remove(id); + } + } + if (heights.isEmpty()) { + remove(); + } + } + + private void affect(Entity entity) { + Vector direction = GeneralMethods.getDirection(origin, entity.getLocation()); + direction.setY(0); + direction.normalize(); + entity.setVelocity(entity.getVelocity().clone().add(direction.multiply(knockback))); + } + + @Override + public void remove() { + super.remove(); + for (TempBlock block : blocks) { + block.revertBlock(); + } + } + + private void returnWater() { + Location location = new Location(origin.getWorld(), origin.getX() + radius, origin.getY(), origin.getZ()); + if (!location.getWorld().equals(player.getWorld())) { + return; + } + double radiusOffsetSquared = (maxRadius + 5) * (maxRadius + 5); + if (location.distanceSquared(player.getLocation()) > radiusOffsetSquared) { + return; + } + new WaterReturn(player, location.getBlock()); + } + + @Override + public String getName() { + return "Torrent"; + } + + @Override + public Location getLocation() { + return origin; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getMaxRadius() { + return maxRadius; + } + + public void setMaxRadius(double maxRadius) { + this.maxRadius = maxRadius; + } + + public double getKnockback() { + return knockback; + } + + public void setKnockback(double knockback) { + this.knockback = knockback; + } + + public double getMaxHeight() { + return maxHeight; + } + + public void setMaxHeight(double maxHeight) { + this.maxHeight = maxHeight; + } + + public double getGrowSpeed() { + return growSpeed; + } + + public void setGrowSpeed(double growSpeed) { + this.growSpeed = growSpeed; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public ArrayList getBlocks() { + return blocks; + } + + public ArrayList getAffectedEntities() { + return affectedEntities; + } + + public ConcurrentHashMap> getHeights() { + return heights; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + +} diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterArms.java b/src/com/projectkorra/projectkorra/waterbending/WaterArms.java index 363a6f70..aed9257a 100644 --- a/src/com/projectkorra/projectkorra/waterbending/WaterArms.java +++ b/src/com/projectkorra/projectkorra/waterbending/WaterArms.java @@ -1,11 +1,10 @@ package com.projectkorra.projectkorra.waterbending; -import com.projectkorra.projectkorra.Element; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.multiability.MultiAbilityManager; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.firebending.FireMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.FireAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.ability.util.MultiAbilityManager; import com.projectkorra.projectkorra.firebending.Lightning; import com.projectkorra.projectkorra.util.ParticleEffect; import com.projectkorra.projectkorra.util.TempBlock; @@ -16,7 +15,6 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import java.util.ArrayList; @@ -24,89 +22,100 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.ConcurrentHashMap; -public class WaterArms { +public class WaterArms extends WaterAbility { /** * Arm Enum value for deciding which arm is being used. */ - public enum Arm { - Right, Left; + public static enum Arm { + RIGHT, LEFT; } - private static FileConfiguration config = ProjectKorra.plugin.getConfig(); - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - public static ConcurrentHashMap revert = new ConcurrentHashMap(); - - private static Integer[] unbreakable = { 7, 8, 9, 10, 11, 49, 54, 90, 119, 120, 130, 146 }; - - private Player player; - private World world; - - private Arm activeArm = Arm.Right; + private static final ConcurrentHashMap BLOCK_REVERT_TIMES = new ConcurrentHashMap(); + private static final Integer[] UNBREAKABLES = { 7, 8, 9, 10, 11, 49, 54, 90, 119, 120, 130, 146 }; private boolean cooldownLeft; private boolean cooldownRight; - private boolean fullSource = true; - - private boolean leftArmConsumed = false; - private boolean rightArmConsumed = false; - - private int lengthReduction = 0; - - private int initLength = config.getInt("Abilities.Water.WaterArms.Arms.InitialLength"); - private int sourceGrabRange = config.getInt("Abilities.Water.WaterArms.Arms.SourceGrabRange"); - private int maxPunches = config.getInt("Abilities.Water.WaterArms.Arms.MaxAttacks"); - private int maxIceBlasts = config.getInt("Abilities.Water.WaterArms.Arms.MaxIceShots"); - private int maxUses = config.getInt("Abilities.Water.WaterArms.Arms.MaxAlternateUsage"); - private long cooldown = config.getLong("Abilities.Water.WaterArms.Arms.Cooldown"); - private boolean canUsePlantSource = config.getBoolean("Abilities.Water.WaterArms.Arms.AllowPlantSource"); - - private boolean lightningEnabled = config.getBoolean("Abilities.Water.WaterArms.Arms.Lightning.Enabled"); - private double lightningDamage = config.getDouble("Abilities.Water.WaterArms.Arms.Lightning.Damage"); - private boolean lightningKill = config.getBoolean("Abilities.Water.WaterArms.Arms.Lightning.KillUser"); - - private static String sneakMsg = config.getString("Abilities.Water.WaterArms.SneakMessage"); - - private int selectedSlot = 0; - private int freezeSlot = 4; - + private boolean fullSource; + private boolean leftArmConsumed; + private boolean rightArmConsumed; + private boolean canUsePlantSource; + private boolean lightningEnabled; + private boolean lightningKill; + private int lengthReduction; + private int initLength; + private int sourceGrabRange; + private int maxPunches; + private int maxIceBlasts; + private int maxUses; + private int selectedSlot; + private int freezeSlot; + private long cooldown; private long lastClickTime; - + private double lightningDamage; + private World world; + private String sneakMsg; + private Arm activeArm; + public WaterArms(Player player) { - if (instances.containsKey(player)) { + super(player); + + this.fullSource = true; + this.leftArmConsumed = false; + this.rightArmConsumed = false; + this.canUsePlantSource = getConfig().getBoolean("Abilities.Water.WaterArms.Arms.AllowPlantSource"); + this.lightningEnabled = getConfig().getBoolean("Abilities.Water.WaterArms.Arms.Lightning.Enabled"); + this.lightningKill = getConfig().getBoolean("Abilities.Water.WaterArms.Arms.Lightning.KillUser"); + this.initLength = getConfig().getInt("Abilities.Water.WaterArms.Arms.InitialLength"); + this.sourceGrabRange = getConfig().getInt("Abilities.Water.WaterArms.Arms.SourceGrabRange"); + this.maxPunches = getConfig().getInt("Abilities.Water.WaterArms.Arms.MaxAttacks"); + this.maxIceBlasts = getConfig().getInt("Abilities.Water.WaterArms.Arms.MaxIceShots"); + this.maxUses = getConfig().getInt("Abilities.Water.WaterArms.Arms.MaxAlternateUsage"); + this.cooldown = getConfig().getLong("Abilities.Water.WaterArms.Arms.Cooldown"); + this.lightningDamage = getConfig().getDouble("Abilities.Water.WaterArms.Arms.Lightning.Damage"); + this.sneakMsg = getConfig().getString("Abilities.Water.WaterArms.SneakMessage"); + this.lengthReduction = 0; + this.selectedSlot = 0; + this.freezeSlot = 4; + this.lastClickTime = 0; + this.world = player.getWorld(); + this.activeArm = Arm.RIGHT; + + WaterArms oldArms = CoreAbility.getAbility(player, WaterArms.class); + + if (oldArms != null) { if (player.isSneaking()) { - instances.get(player).prepareCancel(); + oldArms.prepareCancel(); } else { switch (player.getInventory().getHeldItemSlot()) { case 0: if (player.hasPermission("bending.ability.WaterArms.Pull")) { - new WaterArmsWhip(player, Whip.Pull); + new WaterArmsWhip(player, Whip.PULL); } break; case 1: if (player.hasPermission("bending.ability.WaterArms.Punch")) { - new WaterArmsWhip(player, Whip.Punch); + new WaterArmsWhip(player, Whip.PUNCH); } break; case 2: if (player.hasPermission("bending.ability.WaterArms.Grapple")) { - new WaterArmsWhip(player, Whip.Grapple); + new WaterArmsWhip(player, Whip.GRAPPLE); } break; case 3: if (player.hasPermission("bending.ability.WaterArms.Grab")) { - new WaterArmsWhip(player, Whip.Grab); + new WaterArmsWhip(player, Whip.GRAB); } break; case 4: - if (player.hasPermission("bending.ability.WaterArms.Freeze") && WaterMethods.canIcebend(player)) { + if (player.hasPermission("bending.ability.WaterArms.Freeze") && bPlayer.canIcebend()) { new WaterArmsFreeze(player); } break; case 5: if (player.hasPermission("bending.ability.WaterArms.Spear")) { - if (WaterMethods.canIcebend(player)) { + if (bPlayer.canIcebend()) { new WaterArmsSpear(player, true); } else { new WaterArmsSpear(player, false); @@ -119,40 +128,27 @@ public class WaterArms { } return; } - this.player = player; - if (canUse(player) && prepare()) { - world = player.getWorld(); - instances.put(player, this); + + + if (bPlayer.canBend(this) && prepare()) { + start(); MultiAbilityManager.bindMultiAbility(player, "WaterArms"); - if (ChatColor.stripColor(GeneralMethods.getBoundAbility(player)) == null) { + + if (ChatColor.stripColor(bPlayer.getBoundAbilityName()) == null) { remove(); return; } - player.sendMessage(WaterMethods.getWaterColor() + sneakMsg + " " + GeneralMethods.getBoundAbility(player)); + displayBoundMsg(); } } - private boolean canUse(Player player) { - if (GeneralMethods.getBoundAbility(player) == null) - return false; - if (!GeneralMethods.canBend(player.getName(), "WaterArms")) - return false; - if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterArms", player.getLocation())) - return false; - if (GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("WaterArms")) - return false; - if (GeneralMethods.getBoundAbility(player).equalsIgnoreCase("WaterArms")) - return true; - return false; - } - private boolean prepare() { - Block sourceBlock = WaterMethods.getWaterSourceBlock(player, sourceGrabRange, true, WaterMethods.canPlantbend(player), canUsePlantSource && WaterMethods.canPlantbend(player)); + Block sourceBlock = getWaterSourceBlock(player, sourceGrabRange, canUsePlantSource); if (sourceBlock != null) { - if (WaterMethods.isPlant(sourceBlock)) { + if (isPlant(sourceBlock)) { fullSource = false; } - ParticleEffect.LARGE_SMOKE.display(WaterMethods.getWaterSourceBlock(player, sourceGrabRange, true, WaterMethods.canPlantbend(player), canUsePlantSource && WaterMethods.canPlantbend(player)).getLocation().clone().add(0.5, 0.5, 0.5), 0, 0, 0, 0F, 4); + ParticleEffect.LARGE_SMOKE.display(getWaterSourceBlock(player, sourceGrabRange, canUsePlantSource).getLocation().clone().add(0.5, 0.5, 0.5), 0, 0, 0, 0F, 4); return true; } else if (WaterReturn.hasWaterBottle(player)) { WaterReturn.emptyWaterBottle(player); @@ -162,27 +158,18 @@ public class WaterArms { return false; } - private void progress() { - if (!instances.containsKey(player)) { - return; - } - if (player.isDead() || !player.isOnline() || !world.equals(player.getWorld())) { + @Override + public void progress() { + if (!world.equals(player.getWorld()) || !bPlayer.canBendIgnoreBindsCooldowns(this)) { remove(); return; - } - if (!GeneralMethods.canBend(player.getName(), "WaterArms")) { + } else if (!bPlayer.isToggled()) { remove(); return; - } - if (!GeneralMethods.getBendingPlayer(player.getName()).isToggled()) { + } else if (!MultiAbilityManager.hasMultiAbilityBound(player, "WaterArms")) { remove(); return; - } - if (!MultiAbilityManager.hasMultiAbilityBound(player, "WaterArms")) { - remove(); - return; - } - if (maxPunches == 0 || maxUses == 0 || maxIceBlasts == 0 || (leftArmConsumed && rightArmConsumed)) { + } else if (maxPunches == 0 || maxUses == 0 || maxIceBlasts == 0 || (leftArmConsumed && rightArmConsumed)) { remove(); return; } @@ -191,13 +178,15 @@ public class WaterArms { displayRightArm(); displayLeftArm(); - if (lightningEnabled) + if (lightningEnabled) { checkIfZapped(); + } } private boolean canPlaceBlock(Block block) { - if (!EarthMethods.isTransparentToEarthbending(player, block) && !(WaterMethods.isWater(block) && TempBlock.isTempBlock(block))) + if (!isTransparentToEarthbending(player, block) && !(isWater(block) && TempBlock.isTempBlock(block))) { return false; + } return true; } @@ -208,39 +197,43 @@ public class WaterArms { * @return false If arm cannot be fully displayed */ public boolean displayRightArm() { - if (rightArmConsumed) + if (rightArmConsumed) { return false; + } Location r1 = GeneralMethods.getRightSide(player.getLocation(), 1).add(0, 1.5, 0); - if (!canPlaceBlock(r1.getBlock())) + if (!canPlaceBlock(r1.getBlock())) { return false; + } if (!(getRightHandPos().getBlock().getLocation().equals(r1.getBlock().getLocation()))) { new TempBlock(r1.getBlock(), Material.STATIONARY_WATER, (byte) 5); - revert.put(r1.getBlock(), 0L); + BLOCK_REVERT_TIMES.put(r1.getBlock(), System.currentTimeMillis() + 1); } Location r2 = GeneralMethods.getRightSide(player.getLocation(), 2).add(0, 1.5, 0); - if (!canPlaceBlock(r2.getBlock())) + if (!canPlaceBlock(r2.getBlock())) { return false; + } new TempBlock(r2.getBlock(), Material.STATIONARY_WATER, (byte) 8); - revert.put(r2.getBlock(), 0L); + BLOCK_REVERT_TIMES.put(r2.getBlock(), 0L); for (int j = 0; j <= initLength; j++) { Location r3 = r2.clone().toVector().add(player.getLocation().clone().getDirection().multiply(j)).toLocation(player.getWorld()); if (!canPlaceBlock(r3.getBlock())) { - if (selectedSlot == freezeSlot && r3.getBlock().getType().equals(Material.ICE)) + if (selectedSlot == freezeSlot && r3.getBlock().getType().equals(Material.ICE)) { continue; + } return false; } - if (j >= 1 && selectedSlot == freezeSlot && WaterMethods.canIcebend(player)) { + if (j >= 1 && selectedSlot == freezeSlot && bPlayer.canIcebend()) { new TempBlock(r3.getBlock(), Material.ICE, (byte) 0); - revert.put(r3.getBlock(), 0L); + BLOCK_REVERT_TIMES.put(r3.getBlock(), 0L); } else { new TempBlock(r3.getBlock(), Material.STATIONARY_WATER, (byte) 8); - revert.put(r3.getBlock(), 0L); + BLOCK_REVERT_TIMES.put(r3.getBlock(), 0L); } } @@ -254,39 +247,43 @@ public class WaterArms { * @return false If the arm cannot be fully displayed. */ public boolean displayLeftArm() { - if (leftArmConsumed) + if (leftArmConsumed) { return false; + } Location l1 = GeneralMethods.getLeftSide(player.getLocation(), 1).add(0, 1.5, 0); - if (!canPlaceBlock(l1.getBlock())) + if (!canPlaceBlock(l1.getBlock())) { return false; + } if (!(getLeftHandPos().getBlock().getLocation().equals(l1.getBlock().getLocation()))) { new TempBlock(l1.getBlock(), Material.STATIONARY_WATER, (byte) 5); - revert.put(l1.getBlock(), 0L); + BLOCK_REVERT_TIMES.put(l1.getBlock(), 0L); } Location l2 = GeneralMethods.getLeftSide(player.getLocation(), 2).add(0, 1.5, 0); - if (!canPlaceBlock(l2.getBlock())) + if (!canPlaceBlock(l2.getBlock())) { return false; + } new TempBlock(l2.getBlock(), Material.STATIONARY_WATER, (byte) 8); - revert.put(l2.getBlock(), 0L); + BLOCK_REVERT_TIMES.put(l2.getBlock(), System.currentTimeMillis() + 1); for (int j = 0; j <= initLength; j++) { Location l3 = l2.clone().toVector().add(player.getLocation().clone().getDirection().multiply(j)).toLocation(player.getWorld()); if (!canPlaceBlock(l3.getBlock())) { - if (selectedSlot == freezeSlot && l3.getBlock().getType().equals(Material.ICE)) + if (selectedSlot == freezeSlot && l3.getBlock().getType().equals(Material.ICE)) { continue; + } return false; } - if (j >= 1 && selectedSlot == freezeSlot && WaterMethods.canIcebend(player)) { + if (j >= 1 && selectedSlot == freezeSlot && bPlayer.canIcebend()) { new TempBlock(l3.getBlock(), Material.ICE, (byte) 0); - revert.put(l3.getBlock(), 0L); + BLOCK_REVERT_TIMES.put(l3.getBlock(), System.currentTimeMillis() + 1); } else { new TempBlock(l3.getBlock(), Material.STATIONARY_WATER, (byte) 8); - revert.put(l3.getBlock(), 0L); + BLOCK_REVERT_TIMES.put(l3.getBlock(), System.currentTimeMillis() + 1); } } @@ -334,28 +331,31 @@ public class WaterArms { } private static void progressRevert(boolean ignoreTime) { - for (Block block : revert.keySet()) { - long time = revert.get(block); + for (Block block : BLOCK_REVERT_TIMES.keySet()) { + long time = BLOCK_REVERT_TIMES.get(block); if (System.currentTimeMillis() > time || ignoreTime) { - if (TempBlock.isTempBlock(block)) + if (TempBlock.isTempBlock(block)) { TempBlock.revertBlock(block, Material.AIR); - revert.remove(block); + } + BLOCK_REVERT_TIMES.remove(block); } } } private void checkIfZapped() { - for (Lightning l : Lightning.instances.values()) { - for (Lightning.Arc arc : l.getArcs()) { - for (Block arm : revert.keySet()) { + for (Lightning lightning : getAbilities(Lightning.class)) { + for (Lightning.Arc arc : lightning.getArcs()) { + for (Block arm : BLOCK_REVERT_TIMES.keySet()) { for (Location loc : arc.getPoints()) { if (arm.getLocation().getWorld() == loc.getWorld() && loc.distance(arm.getLocation()) <= 2.5) { - for (Location l1 : getOffsetLocations(4, arm.getLocation(), 1.25)) - FireMethods.playLightningbendingParticle(l1); - if (lightningKill) - GeneralMethods.damageEntity(l.getPlayer(), player, 60D, Element.Water, "Electrocution"); - else - GeneralMethods.damageEntity(l.getPlayer(), player, lightningDamage, Element.Water, "Electrocution"); + for (Location l1 : getOffsetLocations(4, arm.getLocation(), 1.25)) { + FireAbility.playLightningbendingParticle(l1); + } + if (lightningKill) { + GeneralMethods.damageEntity(lightning, player, 60D); + } else { + GeneralMethods.damageEntity(lightning, player, lightningDamage); + } } } } @@ -365,21 +365,19 @@ public class WaterArms { private static List getOffsetLocations(int amount, Location location, double offset) { List locations = new ArrayList(); - for (int i = 0; i < amount; i++) + for (int i = 0; i < amount; i++) { locations.add(location.clone().add((float) (Math.random() * offset), (float) (Math.random() * offset), (float) (Math.random() * offset))); + } return locations; } - public static void remove(Player player) { - if (instances.containsKey(player)) - instances.get(player).remove(); - } - + @Override public void remove() { + super.remove(); MultiAbilityManager.unbindMultiAbility(player); - if (player.isOnline()) - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("WaterArms", cooldown); - instances.remove(player); + if (player.isOnline()) { + bPlayer.addCooldown(this); + } } public void prepareCancel() { @@ -390,37 +388,37 @@ public class WaterArms { } } - public static void progressAll() { + public static void progressAllCleanup() { progressRevert(false); - for (Player p : instances.keySet()) - instances.get(p).progress(); - WaterArmsWhip.progressAll(); - WaterArmsFreeze.progressAll(); - WaterArmsSpear.progressAll(); + /* + * There is currently a bug where waterArms will display the arms and then + * progressRevert will revert the same blocks in the same tick before the user is + * able to see them, thus causing invisible arms. Simple fix is just to display the arms + * again. + */ + for (WaterArms waterArms : getAbilities(WaterArms.class)) { + waterArms.displayLeftArm(); + waterArms.displayRightArm(); + } + WaterArmsWhip.progressAllCleanup(); } - public static void removeAll() { + public static void removeAllCleanup() { progressRevert(true); - revert.clear(); - instances.clear(); - WaterArmsWhip.removeAll(); - WaterArmsFreeze.removeAll(); - WaterArmsSpear.removeAll(); + BLOCK_REVERT_TIMES.clear(); + WaterArmsWhip.removeAllCleanup(); } @SuppressWarnings("deprecation") public static boolean isUnbreakable(Block block) { - if (Arrays.asList(unbreakable).contains(block.getTypeId())) + if (Arrays.asList(UNBREAKABLES).contains(block.getTypeId())) { return true; + } return false; } - public static void displayBoundMsg(Player player) { - player.sendMessage(WaterMethods.getWaterColor() + sneakMsg + " " + GeneralMethods.getBoundAbility(player)); - } - public void displayBoundMsg() { - player.sendMessage(WaterMethods.getWaterColor() + sneakMsg + " " + GeneralMethods.getBoundAbility(player)); + player.sendMessage(getElement().getColor() + sneakMsg + " " + bPlayer.getBoundAbilityName()); } /** @@ -436,10 +434,11 @@ public class WaterArms { * Switches the active arm of a player. */ public void switchActiveArm() { - if (activeArm.equals(Arm.Right)) - activeArm = Arm.Left; - else - activeArm = Arm.Right; + if (activeArm.equals(Arm.RIGHT)) { + activeArm = Arm.LEFT; + } else { + activeArm = Arm.RIGHT; + } } /** @@ -449,12 +448,12 @@ public class WaterArms { */ public Arm switchPreferredArm() { switchActiveArm(); - if (activeArm.equals(Arm.Left)) { + if (activeArm.equals(Arm.LEFT)) { if (!displayLeftArm()) { switchActiveArm(); } } - if (activeArm.equals(Arm.Right)) { + if (activeArm.equals(Arm.RIGHT)) { if (!displayRightArm()) { switchActiveArm(); } @@ -464,9 +463,9 @@ public class WaterArms { public boolean canDisplayActiveArm() { switch (activeArm) { - case Left: + case LEFT: return displayLeftArm(); - case Right: + case RIGHT: return displayRightArm(); default: return false; @@ -475,26 +474,15 @@ public class WaterArms { public Location getActiveArmEnd() { switch (activeArm) { - case Left: + case LEFT: return getLeftArmEnd(); - case Right: + case RIGHT: return getRightArmEnd(); default: return null; } } - public static boolean hasPlayer(Player player) { - if (instances.containsKey(player)) { - return true; - } - return false; - } - - public Player getPlayer() { - return player; - } - public Boolean isFullSource() { return fullSource; } @@ -581,10 +569,10 @@ public class WaterArms { public void setActiveArmCooldown(boolean cooldown) { switch (activeArm) { - case Left: + case LEFT: setLeftArmCooldown(cooldown); return; - case Right: + case RIGHT: setRightArmCooldown(cooldown); return; default: @@ -592,6 +580,7 @@ public class WaterArms { } } + @Override public long getCooldown() { return cooldown; } @@ -599,4 +588,137 @@ public class WaterArms { public void setCooldown(long cooldown) { this.cooldown = cooldown; } + + @Override + public String getName() { + return "WaterArms"; + } + + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isCooldownLeft() { + return cooldownLeft; + } + + public void setCooldownLeft(boolean cooldownLeft) { + this.cooldownLeft = cooldownLeft; + } + + public boolean isCooldownRight() { + return cooldownRight; + } + + public void setCooldownRight(boolean cooldownRight) { + this.cooldownRight = cooldownRight; + } + + public boolean isCanUsePlantSource() { + return canUsePlantSource; + } + + public void setCanUsePlantSource(boolean canUsePlantSource) { + this.canUsePlantSource = canUsePlantSource; + } + + public boolean isLightningEnabled() { + return lightningEnabled; + } + + public void setLightningEnabled(boolean lightningEnabled) { + this.lightningEnabled = lightningEnabled; + } + + public boolean isLightningKill() { + return lightningKill; + } + + public void setLightningKill(boolean lightningKill) { + this.lightningKill = lightningKill; + } + + public int getInitLength() { + return initLength; + } + + public void setInitLength(int initLength) { + this.initLength = initLength; + } + + public int getSourceGrabRange() { + return sourceGrabRange; + } + + public void setSourceGrabRange(int sourceGrabRange) { + this.sourceGrabRange = sourceGrabRange; + } + + public int getSelectedSlot() { + return selectedSlot; + } + + public void setSelectedSlot(int selectedSlot) { + this.selectedSlot = selectedSlot; + } + + public int getFreezeSlot() { + return freezeSlot; + } + + public void setFreezeSlot(int freezeSlot) { + this.freezeSlot = freezeSlot; + } + + public long getLastClickTime() { + return lastClickTime; + } + + public void setLastClickTime(long lastClickTime) { + this.lastClickTime = lastClickTime; + } + + public World getWorld() { + return world; + } + + public void setWorld(World world) { + this.world = world; + } + + public String getSneakMsg() { + return sneakMsg; + } + + public void setSneakMsg(String sneakMsg) { + this.sneakMsg = sneakMsg; + } + + public static ConcurrentHashMap getBlockRevertTimes() { + return BLOCK_REVERT_TIMES; + } + + public static Integer[] getUnbreakables() { + return UNBREAKABLES; + } + + public void setFullSource(boolean fullSource) { + this.fullSource = fullSource; + } + + public void setActiveArm(Arm activeArm) { + this.activeArm = activeArm; + } + } diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterArmsFreeze.java b/src/com/projectkorra/projectkorra/waterbending/WaterArmsFreeze.java index f4a9788d..415e7e80 100644 --- a/src/com/projectkorra/projectkorra/waterbending/WaterArmsFreeze.java +++ b/src/com/projectkorra/projectkorra/waterbending/WaterArmsFreeze.java @@ -1,10 +1,8 @@ package com.projectkorra.projectkorra.waterbending; -import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.SubElement; -import com.projectkorra.projectkorra.earthbending.EarthMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.IceAbility; import com.projectkorra.projectkorra.util.ParticleEffect; import com.projectkorra.projectkorra.util.TempBlock; import com.projectkorra.projectkorra.util.TempPotionEffect; @@ -13,7 +11,6 @@ import com.projectkorra.projectkorra.waterbending.WaterArms.Arm; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; @@ -22,45 +19,39 @@ import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; -import java.util.concurrent.ConcurrentHashMap; - -public class WaterArmsFreeze { - - private static FileConfiguration config = ProjectKorra.plugin.getConfig(); - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - - private Player player; - private WaterArms waterArms; - - private int iceRange = config.getInt("Abilities.Water.WaterArms.Freeze.Range"); - private double iceDamage = config.getInt("Abilities.Water.WaterArms.Freeze.Damage"); - - private boolean usageCooldownEnabled = config.getBoolean("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldownEnabled"); - private long usageCooldown = config.getLong("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldown"); +public class WaterArmsFreeze extends IceAbility { + private boolean cancelled; + private boolean usageCooldownEnabled; + private int iceRange; + private int distanceTravelled; + private double iceDamage; + private long usageCooldown; + private Arm arm; private Location location; private Vector direction; - private int distanceTravelled; - private Arm arm; - private boolean cancelled; - - private int id; - private static int ID = Integer.MIN_VALUE; - + private WaterArms waterArms; + public WaterArmsFreeze(Player player) { - this.player = player; - direction = player.getEyeLocation().getDirection(); + super(player); + + this.usageCooldownEnabled = getConfig().getBoolean("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldownEnabled"); + this.iceRange = getConfig().getInt("Abilities.Water.WaterArms.Freeze.Range"); + this.iceDamage = getConfig().getInt("Abilities.Water.WaterArms.Freeze.Damage"); + this.usageCooldown = getConfig().getLong("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldown"); + this.direction = player.getEyeLocation().getDirection(); + createInstance(); } private void createInstance() { - if (WaterArms.instances.containsKey(player)) { - waterArms = WaterArms.instances.get(player); + waterArms = CoreAbility.getAbility(player, WaterArms.class); + + if (waterArms != null) { waterArms.switchPreferredArm(); arm = waterArms.getActiveArm(); - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (arm.equals(Arm.Left)) { + + if (arm.equals(Arm.LEFT)) { if (waterArms.isLeftArmCooldown() || bPlayer.isOnCooldown("WaterArms_LEFT")) { return; } else { @@ -70,7 +61,8 @@ public class WaterArmsFreeze { waterArms.setLeftArmCooldown(true); } } - if (arm.equals(Arm.Right)) { + + if (arm.equals(Arm.RIGHT)) { if (waterArms.isRightArmCooldown() || bPlayer.isOnCooldown("WaterArms_RIGHT")) { return; } else { @@ -80,32 +72,30 @@ public class WaterArmsFreeze { waterArms.setRightArmCooldown(true); } } + Vector dir = player.getLocation().getDirection(); location = waterArms.getActiveArmEnd().add(dir.normalize().multiply(1)); direction = GeneralMethods.getDirection(location, GeneralMethods.getTargetedLocation(player, iceRange, new Integer[] { 8, 9, 79, 174 })).normalize(); } else { return; } - id = ID; - instances.put(id, this); - if (ID == Integer.MAX_VALUE) - ID = Integer.MIN_VALUE; - ID++; + start(); } - private void progress() { + @Override + public void progress() { if (player.isDead() || !player.isOnline()) { remove(); return; - } - if (distanceTravelled > iceRange) { + } else if (distanceTravelled > iceRange) { remove(); return; } + if (distanceTravelled >= 5 && !cancelled) { cancelled = true; - if (WaterArms.instances.containsKey(player)) { - if (arm.equals(Arm.Left)) { + if (CoreAbility.hasAbility(player, WaterArms.class)) { + if (arm.equals(Arm.LEFT)) { waterArms.setLeftArmCooldown(false); } else { waterArms.setRightArmCooldown(false); @@ -113,6 +103,7 @@ public class WaterArmsFreeze { waterArms.setMaxIceBlasts(waterArms.getMaxIceBlasts() - 1); } } + if (!canPlaceBlock(location.getBlock())) { remove(); return; @@ -121,10 +112,9 @@ public class WaterArmsFreeze { } private boolean canPlaceBlock(Block block) { - if (!EarthMethods.isTransparentToEarthbending(player, block) && !((WaterMethods.isWater(block)) && TempBlock.isTempBlock(block))) { + if (!isTransparentToEarthbending(player, block) && !((isWater(block) || isIcebendable(block)) && TempBlock.isTempBlock(block))) { return false; - } - if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterArms", block.getLocation())) { + } else if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { return false; } return true; @@ -133,11 +123,11 @@ public class WaterArmsFreeze { private void progressIce() { ParticleEffect.SNOW_SHOVEL.display(location, (float) Math.random(), (float) Math.random(), (float) Math.random(), (float) 0.05, 5); new TempBlock(location.getBlock(), Material.ICE, (byte) 0); - WaterArms.revert.put(location.getBlock(), System.currentTimeMillis() + 10L); + WaterArms.getBlockRevertTimes().put(location.getBlock(), System.currentTimeMillis() + 10L); for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2.5)) { if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId() && !(entity instanceof ArmorStand)) { - GeneralMethods.damageEntity(player, entity, iceDamage, SubElement.Icebending, "WaterArms Freeze"); + GeneralMethods.damageEntity(this, entity, iceDamage); PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, 40, 2); new TempPotionEffect((LivingEntity) entity, effect); remove(); @@ -147,16 +137,19 @@ public class WaterArmsFreeze { for (int i = 0; i < 2; i++) { location = location.add(direction.clone().multiply(1)); - if (!canPlaceBlock(location.getBlock())) + if (!canPlaceBlock(location.getBlock())) { return; + } distanceTravelled++; } } - private void remove() { - if (WaterArms.instances.containsKey(player)) { + @Override + public void remove() { + super.remove(); + if (CoreAbility.hasAbility(player, WaterArms.class)) { if (!cancelled) { - if (arm.equals(Arm.Left)) { + if (arm.equals(Arm.LEFT)) { waterArms.setLeftArmCooldown(false); } else { waterArms.setRightArmCooldown(false); @@ -164,27 +157,107 @@ public class WaterArmsFreeze { waterArms.setMaxIceBlasts(waterArms.getMaxIceBlasts() - 1); } } - instances.remove(id); } - public static void progressAll() { - for (int ID : instances.keySet()) - instances.get(ID).progress(); + @Override + public String getName() { + return "WaterArms"; } - public static void removeAll() { - instances.clear(); + @Override + public Location getLocation() { + return location; } - public Player getPlayer() { - return player; + @Override + public long getCooldown() { + return usageCooldown; + } + + @Override + public boolean isSneakAbility() { + return true; } - public boolean getCancelled() { + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isCancelled() { return cancelled; } public void setCancelled(boolean cancelled) { this.cancelled = cancelled; } + + public boolean isUsageCooldownEnabled() { + return usageCooldownEnabled; + } + + public void setUsageCooldownEnabled(boolean usageCooldownEnabled) { + this.usageCooldownEnabled = usageCooldownEnabled; + } + + public int getIceRange() { + return iceRange; + } + + public void setIceRange(int iceRange) { + this.iceRange = iceRange; + } + + public int getDistanceTravelled() { + return distanceTravelled; + } + + public void setDistanceTravelled(int distanceTravelled) { + this.distanceTravelled = distanceTravelled; + } + + public double getIceDamage() { + return iceDamage; + } + + public void setIceDamage(double iceDamage) { + this.iceDamage = iceDamage; + } + + public long getUsageCooldown() { + return usageCooldown; + } + + public void setUsageCooldown(long usageCooldown) { + this.usageCooldown = usageCooldown; + } + + public Arm getArm() { + return arm; + } + + public void setArm(Arm arm) { + this.arm = arm; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public WaterArms getWaterArms() { + return waterArms; + } + + public void setWaterArms(WaterArms waterArms) { + this.waterArms = waterArms; + } + + public void setLocation(Location location) { + this.location = location; + } + } diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterArmsSpear.java b/src/com/projectkorra/projectkorra/waterbending/WaterArmsSpear.java index 4ba38d47..b51810ba 100644 --- a/src/com/projectkorra/projectkorra/waterbending/WaterArmsSpear.java +++ b/src/com/projectkorra/projectkorra/waterbending/WaterArmsSpear.java @@ -1,19 +1,16 @@ package com.projectkorra.projectkorra.waterbending; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.Element; +import com.projectkorra.projectkorra.BendingManager; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.earthbending.EarthMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; import com.projectkorra.projectkorra.util.TempBlock; import com.projectkorra.projectkorra.waterbending.WaterArms.Arm; -import com.projectkorra.rpg.event.EventManager; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; @@ -22,66 +19,66 @@ import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.List; -import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; -public class WaterArmsSpear { +public class WaterArmsSpear extends WaterAbility { - private static FileConfiguration config = ProjectKorra.plugin.getConfig(); - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - - private Player player; - private WaterArms waterArms; - - private List spearLocations = new ArrayList<>(); - - private int spearRange = config.getInt("Abilities.Water.WaterArms.Spear.Range"); - private double spearDamage = config.getDouble("Abilities.Water.WaterArms.Spear.Damage"); - private boolean spearDamageEnabled = config.getBoolean("Abilities.Water.WaterArms.Spear.DamageEnabled"); - private int spearSphere = config.getInt("Abilities.Water.WaterArms.Spear.Sphere"); - private long spearDuration = config.getLong("Abilities.Water.WaterArms.Spear.Duration"); - private int spearLength = config.getInt("Abilities.Water.WaterArms.Spear.Length"); - - private int spearRangeNight = config.getInt("Abilities.Water.WaterArms.Spear.NightAugments.Range.Normal"); - private int spearRangeFullMoon = config.getInt("Abilities.Water.WaterArms.Spear.NightAugments.Range.FullMoon"); - private int spearSphereNight = config.getInt("Abilities.Water.WaterArms.Spear.NightAugments.Sphere.Normal"); - private int spearSphereFullMoon = config.getInt("Abilities.Water.WaterArms.Spear.NightAugments.Sphere.FullMoon"); - private long spearDurationNight = config.getLong("Abilities.Water.WaterArms.Spear.NightAugments.Duration.Normal"); - private long spearDurationFullMoon = config.getLong("Abilities.Water.WaterArms.Spear.NightAugments.Duration.FullMoon"); - - private boolean usageCooldownEnabled = config.getBoolean("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldownEnabled"); - private long usageCooldown = config.getLong("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldown"); - - private Location location; - private Location initLocation; - private int distanceTravelled; - private Arm arm; - private int layer; private boolean hitEntity; private boolean canFreeze; - - private int id; - private static int ID = Integer.MIN_VALUE; - - Random rand = new Random(); + private boolean usageCooldownEnabled; + private boolean spearDamageEnabled; + private int spearLength; + private int spearRange; + private int spearRangeNight; + private int spearRangeFullMoon; + private int spearSphere; + private int spearSphereNight; + private int spearSphereFullMoon; + private int distanceTravelled; + private int layer; + private long spearDuration; + private long spearDurationNight; + private long spearDurationFullMoon; + private long usageCooldown; + private double spearDamage; + private Arm arm; + private Location location; + private Location initLocation; + private WaterArms waterArms; + private List spearLocations; public WaterArmsSpear(Player player, boolean freeze) { - this.player = player; + super(player); this.canFreeze = freeze; + + this.usageCooldownEnabled = getConfig().getBoolean("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldownEnabled"); + this.spearDamageEnabled = getConfig().getBoolean("Abilities.Water.WaterArms.Spear.DamageEnabled"); + this.spearLength = getConfig().getInt("Abilities.Water.WaterArms.Spear.Length"); + this.spearRange = getConfig().getInt("Abilities.Water.WaterArms.Spear.Range"); + this.spearRangeNight = getConfig().getInt("Abilities.Water.WaterArms.Spear.NightAugments.Range.Normal"); + this.spearRangeFullMoon = getConfig().getInt("Abilities.Water.WaterArms.Spear.NightAugments.Range.FullMoon"); + this.spearSphere = getConfig().getInt("Abilities.Water.WaterArms.Spear.Sphere"); + this.spearSphereNight = getConfig().getInt("Abilities.Water.WaterArms.Spear.NightAugments.Sphere.Normal"); + this.spearSphereFullMoon = getConfig().getInt("Abilities.Water.WaterArms.Spear.NightAugments.Sphere.FullMoon"); + this.spearDuration = getConfig().getLong("Abilities.Water.WaterArms.Spear.Duration"); + this.spearDurationNight = getConfig().getLong("Abilities.Water.WaterArms.Spear.NightAugments.Duration.Normal"); + this.spearDurationFullMoon = getConfig().getLong("Abilities.Water.WaterArms.Spear.NightAugments.Duration.FullMoon"); + this.usageCooldown = getConfig().getLong("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldown"); + this.spearDamage = getConfig().getDouble("Abilities.Water.WaterArms.Spear.Damage"); + this.spearLocations = new ArrayList<>(); + getNightAugments(); createInstance(); } private void getNightAugments() { World world = player.getWorld(); - if (WaterMethods.isNight(world)) { + if (isNight(world)) { if (GeneralMethods.hasRPG()) { - if (EventManager.marker.get(world).equalsIgnoreCase("LunarEclipse")) { - spearRange = 0; - spearSphere = 0; - spearDuration = 0; - } else if (EventManager.marker.get(world).equalsIgnoreCase("FullMoon")) { + if (isLunarEclipse(world)) { + spearRange = spearRangeFullMoon; + spearSphere = spearSphereFullMoon; + spearDuration = spearDurationFullMoon; + } else if (BendingManager.events.get(world).equalsIgnoreCase("FullMoon")) { spearRange = spearRangeFullMoon; spearSphere = spearSphereFullMoon; spearDuration = spearDurationFullMoon; @@ -91,20 +88,26 @@ public class WaterArmsSpear { spearDuration = spearDurationNight; } } else { - spearRange = spearRangeNight; - spearSphere = spearSphereNight; - spearDuration = spearDurationNight; + if (isFullMoon(world)) { + spearRange = spearRangeFullMoon; + spearSphere = spearSphereFullMoon; + spearDuration = spearDurationFullMoon; + } else { + spearRange = spearRangeNight; + spearSphere = spearSphereNight; + spearDuration = spearDurationNight; + } } } } private void createInstance() { - if (WaterArms.instances.containsKey(player)) { - waterArms = WaterArms.instances.get(player); + waterArms = CoreAbility.getAbility(player, WaterArms.class); + if (waterArms != null) { waterArms.switchPreferredArm(); arm = waterArms.getActiveArm(); - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (arm.equals(Arm.Left)) { + + if (arm.equals(Arm.LEFT)) { if (waterArms.isLeftArmCooldown() || bPlayer.isOnCooldown("WaterArms_LEFT") || !waterArms.displayLeftArm()) { return; } else { @@ -115,7 +118,7 @@ public class WaterArmsSpear { waterArms.setLeftArmCooldown(true); } } - if (arm.equals(Arm.Right)) { + if (arm.equals(Arm.RIGHT)) { if (waterArms.isRightArmCooldown() || bPlayer.isOnCooldown("WaterArms_RIGHT") || !waterArms.displayRightArm()) { return; } else { @@ -132,32 +135,29 @@ public class WaterArmsSpear { } else { return; } - id = ID; - instances.put(id, this); - if (ID == Integer.MAX_VALUE) - ID = Integer.MIN_VALUE; - ID++; + start(); } - private void progress() { + @Override + public void progress() { if (player.isDead() || !player.isOnline()) { remove(); return; - } - if (distanceTravelled > spearRange) { + } else if (distanceTravelled > spearRange) { remove(); return; } + if (!hitEntity) { progressSpear(); } else { createIceBall(); } + if (layer >= spearSphere) { remove(); return; - } - if (!canPlaceBlock(location.getBlock())) { + } else if (!canPlaceBlock(location.getBlock())) { if (canFreeze) { createSpear(); } @@ -174,17 +174,20 @@ public class WaterArmsSpear { location = entity.getLocation(); if (spearDamageEnabled) { - GeneralMethods.damageEntity(player, entity, spearDamage, Element.Water, "WaterArms Spear"); + GeneralMethods.damageEntity(this, entity, spearDamage); } return; } } + new TempBlock(location.getBlock(), Material.STATIONARY_WATER, (byte) 8); - WaterArms.revert.put(location.getBlock(), System.currentTimeMillis() + 600L); + WaterArms.getBlockRevertTimes().put(location.getBlock(), System.currentTimeMillis() + 600L); Vector direction = GeneralMethods.getDirection(initLocation, GeneralMethods.getTargetedLocation(player, spearRange, new Integer[] { 8, 9, 79, 174 })).normalize(); + location = location.add(direction.clone().multiply(1)); spearLocations.add(location.clone()); + if (!canPlaceBlock(location.getBlock())) { return; } @@ -197,12 +200,12 @@ public class WaterArmsSpear { if (i >= 0) { Block block = spearLocations.get(i).getBlock(); if (canPlaceBlock(block)) { - WaterMethods.playIcebendingSound(block.getLocation()); - if (WaterArms.revert.containsKey(block)) { - WaterArms.revert.remove(block); + playIcebendingSound(block.getLocation()); + if (WaterArms.getBlockRevertTimes().containsKey(block)) { + WaterArms.getBlockRevertTimes().remove(block); } new TempBlock(block, Material.ICE, (byte) 0); - WaterArms.revert.put(block, System.currentTimeMillis() + spearDuration + (long) (Math.random() * 500)); + WaterArms.getBlockRevertTimes().put(block, System.currentTimeMillis() + spearDuration + (long) (Math.random() * 500)); } } } @@ -211,65 +214,242 @@ public class WaterArmsSpear { private void createIceBall() { layer++; for (Block block : GeneralMethods.getBlocksAroundPoint(location, layer)) { - if (EarthMethods.isTransparentToEarthbending(player, block) && block.getType() != Material.ICE && !WaterArms.isUnbreakable(block)) { - WaterMethods.playIcebendingSound(block.getLocation()); + if (isTransparentToEarthbending(player, block) && block.getType() != Material.ICE && !WaterArms.isUnbreakable(block)) { + playIcebendingSound(block.getLocation()); new TempBlock(block, Material.ICE, (byte) 0); - WaterArms.revert.put(block, System.currentTimeMillis() + spearDuration + (long) (Math.random() * 500)); + WaterArms.getBlockRevertTimes().put(block, System.currentTimeMillis() + spearDuration + (long) (Math.random() * 500)); } } } private boolean canPlaceBlock(Block block) { - if (!EarthMethods.isTransparentToEarthbending(player, block) && !WaterMethods.isWater(block) && (TempBlock.isTempBlock(block) && !WaterArms.revert.containsKey(block))) { + if (!isTransparentToEarthbending(player, block) + && !((isWater(block) || isIcebendable(block)) && (TempBlock.isTempBlock(block) && !WaterArms.getBlockRevertTimes().containsKey(block)))) { return false; - } - if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterArms", block.getLocation())) { + } else if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { return false; - } - if (WaterArms.isUnbreakable(block) && !WaterMethods.isWater(block)) { + } else if (WaterArms.isUnbreakable(block) && !isWater(block)) { return false; } return true; } - private void remove() { - if (WaterArms.instances.containsKey(player)) { - if (arm.equals(Arm.Left)) { + @Override + public void remove() { + super.remove(); + if (CoreAbility.hasAbility(player, WaterArms.class)) { + if (arm.equals(Arm.LEFT)) { waterArms.setLeftArmCooldown(false); } else { waterArms.setRightArmCooldown(false); } waterArms.setMaxUses(waterArms.getMaxUses() - 1); } - instances.remove(id); } - public static void progressAll() { - for (int ID : instances.keySet()) - instances.get(ID).progress(); + @Override + public String getName() { + return "WaterArms"; } - public static void removeAll() { - instances.clear(); + @Override + public Location getLocation() { + if (location != null) { + return location; + } else { + return initLocation; + } } - public Player getPlayer() { - return player; + @Override + public long getCooldown() { + return usageCooldown; + } + + @Override + public boolean isSneakAbility() { + return true; } - public boolean getCanFreeze() { - return canFreeze; + @Override + public boolean isHarmlessAbility() { + return false; } - public void setCanFreeze(boolean freeze) { - this.canFreeze = freeze; - } - - public boolean getHasHitEntity() { + public boolean isHitEntity() { return hitEntity; } - public void setHitEntity(boolean hit) { - this.hitEntity = hit; + public void setHitEntity(boolean hitEntity) { + this.hitEntity = hitEntity; } + + public boolean isCanFreeze() { + return canFreeze; + } + + public void setCanFreeze(boolean canFreeze) { + this.canFreeze = canFreeze; + } + + public boolean isUsageCooldownEnabled() { + return usageCooldownEnabled; + } + + public void setUsageCooldownEnabled(boolean usageCooldownEnabled) { + this.usageCooldownEnabled = usageCooldownEnabled; + } + + public boolean isSpearDamageEnabled() { + return spearDamageEnabled; + } + + public void setSpearDamageEnabled(boolean spearDamageEnabled) { + this.spearDamageEnabled = spearDamageEnabled; + } + + public int getSpearLength() { + return spearLength; + } + + public void setSpearLength(int spearLength) { + this.spearLength = spearLength; + } + + public int getSpearRange() { + return spearRange; + } + + public void setSpearRange(int spearRange) { + this.spearRange = spearRange; + } + + public int getSpearRangeNight() { + return spearRangeNight; + } + + public void setSpearRangeNight(int spearRangeNight) { + this.spearRangeNight = spearRangeNight; + } + + public int getSpearRangeFullMoon() { + return spearRangeFullMoon; + } + + public void setSpearRangeFullMoon(int spearRangeFullMoon) { + this.spearRangeFullMoon = spearRangeFullMoon; + } + + public int getSpearSphere() { + return spearSphere; + } + + public void setSpearSphere(int spearSphere) { + this.spearSphere = spearSphere; + } + + public int getSpearSphereNight() { + return spearSphereNight; + } + + public void setSpearSphereNight(int spearSphereNight) { + this.spearSphereNight = spearSphereNight; + } + + public int getSpearSphereFullMoon() { + return spearSphereFullMoon; + } + + public void setSpearSphereFullMoon(int spearSphereFullMoon) { + this.spearSphereFullMoon = spearSphereFullMoon; + } + + public int getDistanceTravelled() { + return distanceTravelled; + } + + public void setDistanceTravelled(int distanceTravelled) { + this.distanceTravelled = distanceTravelled; + } + + public int getLayer() { + return layer; + } + + public void setLayer(int layer) { + this.layer = layer; + } + + public long getSpearDuration() { + return spearDuration; + } + + public void setSpearDuration(long spearDuration) { + this.spearDuration = spearDuration; + } + + public long getSpearDurationNight() { + return spearDurationNight; + } + + public void setSpearDurationNight(long spearDurationNight) { + this.spearDurationNight = spearDurationNight; + } + + public long getSpearDurationFullMoon() { + return spearDurationFullMoon; + } + + public void setSpearDurationFullMoon(long spearDurationFullMoon) { + this.spearDurationFullMoon = spearDurationFullMoon; + } + + public long getUsageCooldown() { + return usageCooldown; + } + + public void setUsageCooldown(long usageCooldown) { + this.usageCooldown = usageCooldown; + } + + public double getSpearDamage() { + return spearDamage; + } + + public void setSpearDamage(double spearDamage) { + this.spearDamage = spearDamage; + } + + public Arm getArm() { + return arm; + } + + public void setArm(Arm arm) { + this.arm = arm; + } + + public Location getInitLocation() { + return initLocation; + } + + public void setInitLocation(Location initLocation) { + this.initLocation = initLocation; + } + + public WaterArms getWaterArms() { + return waterArms; + } + + public void setWaterArms(WaterArms waterArms) { + this.waterArms = waterArms; + } + + public List getSpearLocations() { + return spearLocations; + } + + public void setLocation(Location location) { + this.location = location; + } + } diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterArmsWhip.java b/src/com/projectkorra/projectkorra/waterbending/WaterArmsWhip.java index 2f37575e..f30c47c1 100644 --- a/src/com/projectkorra/projectkorra/waterbending/WaterArmsWhip.java +++ b/src/com/projectkorra/projectkorra/waterbending/WaterArmsWhip.java @@ -1,21 +1,18 @@ package com.projectkorra.projectkorra.waterbending; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.Element; +import com.projectkorra.projectkorra.BendingManager; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.multiability.MultiAbilityManager; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.ability.util.MultiAbilityManager; import com.projectkorra.projectkorra.command.Commands; -import com.projectkorra.projectkorra.earthbending.EarthMethods; import com.projectkorra.projectkorra.util.TempBlock; import com.projectkorra.projectkorra.waterbending.WaterArms.Arm; -import com.projectkorra.rpg.event.EventManager; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; @@ -23,115 +20,125 @@ import org.bukkit.entity.Player; import org.bukkit.util.Vector; import java.util.HashMap; -import java.util.concurrent.ConcurrentHashMap; -public class WaterArmsWhip { +public class WaterArmsWhip extends WaterAbility { /** * Whip Enum value for deciding what ability should be executed. */ - public enum Whip { - Pull, Punch, Grapple, Grab; + public static enum Whip { + PULL, PUNCH, GRAPPLE, GRAB; } - private static FileConfiguration config = ProjectKorra.plugin.getConfig(); + private static final HashMap GRABBED_ENTITIES = new HashMap(); - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - public static HashMap grabbedEntities = new HashMap(); - - private Player player; - private WaterArms waterArms; - - private int whipLength = config.getInt("Abilities.Water.WaterArms.Whip.MaxLength"); - private int whipLengthWeak = config.getInt("Abilities.Water.WaterArms.Whip.MaxLengthWeak"); - - private int whipLengthNight = config.getInt("Abilities.Water.WaterArms.Whip.NightAugments.MaxLength.Normal"); - private int whipLengthFullMoon = config.getInt("Abilities.Water.WaterArms.Whip.NightAugments.MaxLength.FullMoon"); - - private int initLength = config.getInt("Abilities.Water.WaterArms.Arms.InitialLength"); - private double pullMultiplier = config.getDouble("Abilities.Water.WaterArms.Whip.Pull.Multiplier"); - private double punchDamage = config.getDouble("Abilities.Water.WaterArms.Whip.Punch.PunchDamage"); - private int punchLength = config.getInt("Abilities.Water.WaterArms.Whip.Punch.MaxLength"); - private int punchLengthNight = config.getInt("Abilities.Water.WaterArms.Whip.Punch.NightAugments.MaxLength.Normal"); - private int punchLengthFullMoon = config.getInt("Abilities.Water.WaterArms.Whip.Punch.NightAugments.MaxLength.FullMoon"); - private boolean grappleRespectRegions = config.getBoolean("Abilities.Water.WaterArms.Whip.Grapple.RespectRegions"); - private long holdTime = config.getLong("Abilities.Water.WaterArms.Whip.Grab.HoldTime"); - private boolean usageCooldownEnabled = config.getBoolean("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldownEnabled"); - private long usageCooldown = config.getLong("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldown"); - - private int activeLength = initLength; - private int whipSpeed = 2; - private boolean reverting = false; - private boolean hasDamaged = false; - private boolean grappled = false; - private boolean grabbed = false; - private double playerHealth; + private boolean reverting; + private boolean hasDamaged; + private boolean grappled; + private boolean grabbed; + private boolean grappleRespectRegions; + private boolean usageCooldownEnabled; + private int whipLength; + private int whipLengthWeak; + private int whipLengthNight; + private int whipLengthFullMoon; + private int initLength; + private int punchLength; + private int punchLengthNight; + private int punchLengthFullMoon; + private int activeLength; + private int whipSpeed; + private long holdTime; + private long usageCooldown; private long time; - - private LivingEntity grabbedEntity; - private Location end; + private double pullMultiplier; + private double punchDamage; + private double playerHealth; private Arm arm; private Whip ability; - - private int id; - private static int ID = Integer.MIN_VALUE; - + private LivingEntity grabbedEntity; + private Location end; + private WaterArms waterArms; + public WaterArmsWhip(Player player, Whip ability) { - if (instances.containsKey(getId(player))) { - WaterArmsWhip waw = instances.get(getId(player)); + super(player); + + this.ability = ability; + this.reverting = false; + this.hasDamaged = false; + this.grappled = false; + this.grabbed = false; + this.grappleRespectRegions = getConfig().getBoolean("Abilities.Water.WaterArms.Whip.Grapple.RespectRegions"); + this.usageCooldownEnabled = getConfig().getBoolean("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldownEnabled"); + this.whipLength = getConfig().getInt("Abilities.Water.WaterArms.Whip.MaxLength"); + this.whipLengthWeak = getConfig().getInt("Abilities.Water.WaterArms.Whip.MaxLengthWeak"); + this.whipLengthNight = getConfig().getInt("Abilities.Water.WaterArms.Whip.NightAugments.MaxLength.Normal"); + this.whipLengthFullMoon = getConfig().getInt("Abilities.Water.WaterArms.Whip.NightAugments.MaxLength.FullMoon"); + this.initLength = getConfig().getInt("Abilities.Water.WaterArms.Arms.InitialLength"); + this.punchLength = getConfig().getInt("Abilities.Water.WaterArms.Whip.Punch.MaxLength"); + this.punchLengthNight = getConfig().getInt("Abilities.Water.WaterArms.Whip.Punch.NightAugments.MaxLength.Normal"); + this.punchLengthFullMoon = getConfig().getInt("Abilities.Water.WaterArms.Whip.Punch.NightAugments.MaxLength.FullMoon"); + this.activeLength = initLength; + this.whipSpeed = 2; + this.holdTime = getConfig().getLong("Abilities.Water.WaterArms.Whip.Grab.HoldTime"); + this.usageCooldown = getConfig().getLong("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldown"); + this.pullMultiplier = getConfig().getDouble("Abilities.Water.WaterArms.Whip.Pull.Multiplier"); + this.punchDamage = getConfig().getDouble("Abilities.Water.WaterArms.Whip.Punch.PunchDamage"); + + WaterArmsWhip waw = CoreAbility.getAbility(player, WaterArmsWhip.class); + if (waw != null) { if (waw.grabbed) { waw.grabbed = false; if (waw.grabbedEntity != null) { - grabbedEntities.remove(waw.grabbedEntity); + GRABBED_ENTITIES.remove(waw.grabbedEntity); waw.grabbedEntity.setVelocity(waw.grabbedEntity.getVelocity().multiply(2.5)); } return; } - if (!waw.arm.equals(WaterArms.instances.get(player).getActiveArm())) { + if (!waw.arm.equals(CoreAbility.getAbility(player, WaterArms.class).getActiveArm())) { return; } } - this.player = player; - this.ability = ability; + getAugments(); createInstance(); } private void getAugments() { - if (ability.equals(Whip.Punch)) { + if (ability.equals(Whip.PUNCH)) { whipLength = punchLength; } World world = player.getWorld(); - if (WaterMethods.isNight(world)) { + if (isNight(world)) { if (GeneralMethods.hasRPG()) { - if (EventManager.marker.get(world).equalsIgnoreCase("LunarEclipse")) { - if (ability.equals(Whip.Punch)) { - whipLength = 0; + if (isLunarEclipse(world)) { + if (ability.equals(Whip.PUNCH)) { + whipLength = punchLengthFullMoon; } else { - whipLength = 0; + whipLength = whipLengthFullMoon; } - } else if (EventManager.marker.get(world).equalsIgnoreCase("FullMoon")) { - if (ability.equals(Whip.Punch)) { + } else if (BendingManager.events.get(world).equalsIgnoreCase("FullMoon")) { + if (ability.equals(Whip.PUNCH)) { whipLength = punchLengthFullMoon; } else { whipLength = whipLengthFullMoon; } } else { - if (ability.equals(Whip.Punch)) { + if (ability.equals(Whip.PUNCH)) { whipLength = punchLengthNight; } else { whipLength = whipLengthNight; } } } else { - if (WaterMethods.isFullMoon(world)) { - if (ability.equals(Whip.Punch)) { + if (isFullMoon(world)) { + if (ability.equals(Whip.PUNCH)) { whipLength = punchLengthFullMoon; } else { whipLength = whipLengthFullMoon; } } else { - if (ability.equals(Whip.Punch)) { + if (ability.equals(Whip.PUNCH)) { whipLength = punchLengthNight; } else { whipLength = whipLengthNight; @@ -142,14 +149,14 @@ public class WaterArmsWhip { } private void createInstance() { - if (WaterArms.instances.containsKey(player)) { - waterArms = WaterArms.instances.get(player); + waterArms = CoreAbility.getAbility(player, WaterArms.class); + if (waterArms != null) { waterArms.switchPreferredArm(); arm = waterArms.getActiveArm(); time = System.currentTimeMillis() + holdTime; playerHealth = player.getHealth(); - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (arm.equals(Arm.Left)) { + + if (arm.equals(Arm.LEFT)) { if (waterArms.isLeftArmCooldown() || bPlayer.isOnCooldown("WaterArms_LEFT")) { return; } else { @@ -159,7 +166,8 @@ public class WaterArmsWhip { waterArms.setLeftArmCooldown(true); } } - if (arm.equals(Arm.Right)) { + + if (arm.equals(Arm.RIGHT)) { if (waterArms.isRightArmCooldown() || bPlayer.isOnCooldown("WaterArms_RIGHT")) { return; } else { @@ -172,26 +180,22 @@ public class WaterArmsWhip { } else { return; } + if (!waterArms.isFullSource()) { whipLength = whipLengthWeak; } - id = ID; - instances.put(id, this); - if (ID == Integer.MAX_VALUE) - ID = Integer.MIN_VALUE; - ID++; + start(); } - private void progress() { - if (!WaterArms.instances.containsKey(player)) { + @Override + public void progress() { + if (!CoreAbility.hasAbility(player, WaterArms.class)) { remove(); return; - } - if (player.isDead() || !player.isOnline()) { + } else if (player.isDead() || !player.isOnline()) { remove(); return; - } - if (!MultiAbilityManager.hasMultiAbilityBound(player, "WaterArms")) { + } if (!MultiAbilityManager.hasMultiAbilityBound(player, "WaterArms")) { remove(); return; } @@ -222,10 +226,9 @@ public class WaterArmsWhip { } private boolean canPlaceBlock(Block block) { - if (!EarthMethods.isTransparentToEarthbending(player, block) && !(WaterMethods.isWater(block) && TempBlock.isTempBlock(block))) { + if (!isTransparentToEarthbending(player, block) && !(isWater(block) && TempBlock.isTempBlock(block))) { return false; - } - if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterArms", block.getLocation())) { + } else if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { return false; } return true; @@ -234,11 +237,13 @@ public class WaterArmsWhip { private void useArm() { if (waterArms.canDisplayActiveArm()) { Location l1 = null; - if (arm.equals(Arm.Left)) { + + if (arm.equals(Arm.LEFT)) { l1 = waterArms.getLeftArmEnd().clone(); } else { l1 = waterArms.getRightArmEnd().clone(); } + Vector dir = player.getLocation().getDirection(); for (int i = 1; i <= activeLength; i++) { Location l2 = l1.clone().add(dir.normalize().multiply(i)); @@ -252,19 +257,20 @@ public class WaterArmsWhip { } new TempBlock(l2.getBlock(), Material.STATIONARY_WATER, (byte) 8); - WaterArms.revert.put(l2.getBlock(), 0L); + WaterArms.getBlockRevertTimes().put(l2.getBlock(), System.currentTimeMillis() + 10); if (i == activeLength) { Location l3 = null; - if (arm.equals(Arm.Left)) { + if (arm.equals(Arm.LEFT)) { l3 = GeneralMethods.getRightSide(l2, 1); } else { l3 = GeneralMethods.getLeftSide(l2, 1); } + end = l3.clone(); if (canPlaceBlock(l3.getBlock())) { new TempBlock(l3.getBlock(), Material.STATIONARY_WATER, (byte) 3); - WaterArms.revert.put(l3.getBlock(), 0L); + WaterArms.getBlockRevertTimes().put(l3.getBlock(), System.currentTimeMillis() + 10); performAction(l3); } else { if (!l3.getBlock().getType().equals(Material.BARRIER)) { @@ -280,7 +286,7 @@ public class WaterArmsWhip { private void performAction(Location location) { Location endOfArm = waterArms.getLeftArmEnd().clone(); switch (ability) { - case Pull: + case PULL: for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2)) { if (entity instanceof Player && Commands.invincible.contains(((Player) entity).getName())) { continue; @@ -289,29 +295,30 @@ public class WaterArmsWhip { entity.setVelocity(vector.multiply(pullMultiplier)); } break; - case Punch: + case PUNCH: for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2)) { if (entity instanceof Player && Commands.invincible.contains(((Player) entity).getName())) { continue; } + Vector vector = entity.getLocation().toVector().subtract(endOfArm.toVector()); entity.setVelocity(vector.multiply(0.15)); if (entity instanceof LivingEntity) { if (entity.getEntityId() != player.getEntityId()) { hasDamaged = true; - GeneralMethods.damageEntity(player, entity, punchDamage, Element.Water, "WaterArms Punch"); + GeneralMethods.damageEntity(this, entity, punchDamage); } } } break; - case Grapple: + case GRAPPLE: grapplePlayer(end); break; - case Grab: + case GRAB: if (grabbedEntity == null) { for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2)) { - if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId() && !grabbedEntities.containsKey(entity)) { - grabbedEntities.put((LivingEntity) entity, id); + if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId() && !GRABBED_ENTITIES.containsKey(entity)) { + GRABBED_ENTITIES.put((LivingEntity) entity, this); grabbedEntity = (LivingEntity) entity; grabbed = true; reverting = true; @@ -330,21 +337,24 @@ public class WaterArmsWhip { if (grabbedEntity != null && grabbed) { if (!waterArms.canDisplayActiveArm() || grabbedEntity.isDead()) { grabbed = false; - grabbedEntities.remove(grabbedEntity); + GRABBED_ENTITIES.remove(grabbedEntity); return; } - Location newlocation = grabbedEntity.getLocation(); - double distance = location.distance(newlocation); + + Location newLocation = grabbedEntity.getLocation(); + double distance = location.distance(newLocation); double dx, dy, dz; - dx = location.getX() - newlocation.getX(); - dy = location.getY() - newlocation.getY(); - dz = location.getZ() - newlocation.getZ(); + dx = location.getX() - newLocation.getX(); + dy = location.getY() - newLocation.getY(); + dz = location.getZ() - newLocation.getZ(); Vector vector = new Vector(dx, dy, dz); - if (distance > .5) { + + if (distance > 0.5) { grabbedEntity.setVelocity(vector.normalize().multiply(.65)); } else { grabbedEntity.setVelocity(new Vector(0, 0, 0)); } + grabbedEntity.setFallDistance(0); if (grabbedEntity instanceof Creature) { ((Creature) grabbedEntity).setTarget(null); @@ -353,8 +363,8 @@ public class WaterArmsWhip { } private void grapplePlayer(Location location) { - if (reverting && grappled && player != null && end != null && ability.equals(Whip.Grapple)) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterArms", location) && grappleRespectRegions) { + if (reverting && grappled && player != null && end != null && ability.equals(Whip.GRAPPLE)) { + if (GeneralMethods.isRegionProtectedFromBuild(this, location) && grappleRespectRegions) { return; } Vector vector = player.getLocation().toVector().subtract(location.toVector()); @@ -363,30 +373,24 @@ public class WaterArmsWhip { } } - public static Integer getId(Player player) { - for (int id : instances.keySet()) { - if (instances.get(id).player.equals(player)) { - return id; - } - } - return 0; - } - public static void checkValidEntities() { - for (LivingEntity e : grabbedEntities.keySet()) { - if (instances.containsKey(grabbedEntities.get(e))) { - if (instances.get(grabbedEntities.get(e)).grabbedEntity == null) { - grabbedEntities.remove(e); + for (LivingEntity livingEnt : GRABBED_ENTITIES.keySet()) { + WaterArmsWhip whip = GRABBED_ENTITIES.get(livingEnt); + if (!whip.isRemoved()) { + if (whip.grabbedEntity == null) { + GRABBED_ENTITIES.remove(livingEnt); } } else { - grabbedEntities.remove(e); + GRABBED_ENTITIES.remove(livingEnt); } } } - private void remove() { - if (WaterArms.instances.containsKey(player)) { - if (arm.equals(Arm.Left)) { + @Override + public void remove() { + super.remove(); + if (CoreAbility.hasAbility(player, WaterArms.class)) { + if (arm.equals(Arm.LEFT)) { waterArms.setLeftArmCooldown(false); } else { waterArms.setRightArmCooldown(false); @@ -396,38 +400,167 @@ public class WaterArmsWhip { } waterArms.setMaxUses(waterArms.getMaxUses() - 1); } - instances.remove(id); } - public static void progressAll() { + public static void progressAllCleanup() { checkValidEntities(); - for (int ID : instances.keySet()) - instances.get(ID).progress(); } - public static void removeAll() { - grabbedEntities.clear(); - instances.clear(); + public static void removeAllCleanup() { + GRABBED_ENTITIES.clear(); } - public Player getPlayer() { - return player; + @Override + public String getName() { + return "WaterArms"; } - public Integer getWhipLength() { + @Override + public Location getLocation() { + return end; + } + + @Override + public long getCooldown() { + return usageCooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isReverting() { + return reverting; + } + + public void setReverting(boolean reverting) { + this.reverting = reverting; + } + + public boolean isHasDamaged() { + return hasDamaged; + } + + public void setHasDamaged(boolean hasDamaged) { + this.hasDamaged = hasDamaged; + } + + public boolean isGrappled() { + return grappled; + } + + public void setGrappled(boolean grappled) { + this.grappled = grappled; + } + + public boolean isGrabbed() { + return grabbed; + } + + public void setGrabbed(boolean grabbed) { + this.grabbed = grabbed; + } + + public boolean isGrappleRespectRegions() { + return grappleRespectRegions; + } + + public void setGrappleRespectRegions(boolean grappleRespectRegions) { + this.grappleRespectRegions = grappleRespectRegions; + } + + public boolean isUsageCooldownEnabled() { + return usageCooldownEnabled; + } + + public void setUsageCooldownEnabled(boolean usageCooldownEnabled) { + this.usageCooldownEnabled = usageCooldownEnabled; + } + + public int getWhipLength() { return whipLength; } - public void setArmLength(int armLength) { - this.whipLength = armLength; + public void setWhipLength(int whipLength) { + this.whipLength = whipLength; } - public Double getPunchDamage() { - return punchDamage; + public int getWhipLengthWeak() { + return whipLengthWeak; } - public void setPunchDamage(double damage) { - this.punchDamage = damage; + public void setWhipLengthWeak(int whipLengthWeak) { + this.whipLengthWeak = whipLengthWeak; + } + + public int getWhipLengthNight() { + return whipLengthNight; + } + + public void setWhipLengthNight(int whipLengthNight) { + this.whipLengthNight = whipLengthNight; + } + + public int getWhipLengthFullMoon() { + return whipLengthFullMoon; + } + + public void setWhipLengthFullMoon(int whipLengthFullMoon) { + this.whipLengthFullMoon = whipLengthFullMoon; + } + + public int getInitLength() { + return initLength; + } + + public void setInitLength(int initLength) { + this.initLength = initLength; + } + + public int getPunchLength() { + return punchLength; + } + + public void setPunchLength(int punchLength) { + this.punchLength = punchLength; + } + + public int getPunchLengthNight() { + return punchLengthNight; + } + + public void setPunchLengthNight(int punchLengthNight) { + this.punchLengthNight = punchLengthNight; + } + + public int getPunchLengthFullMoon() { + return punchLengthFullMoon; + } + + public void setPunchLengthFullMoon(int punchLengthFullMoon) { + this.punchLengthFullMoon = punchLengthFullMoon; + } + + public int getActiveLength() { + return activeLength; + } + + public void setActiveLength(int activeLength) { + this.activeLength = activeLength; + } + + public int getWhipSpeed() { + return whipSpeed; + } + + public void setWhipSpeed(int whipSpeed) { + this.whipSpeed = whipSpeed; } public long getHoldTime() { @@ -438,31 +571,88 @@ public class WaterArmsWhip { this.holdTime = holdTime; } - public boolean getReverting() { - return reverting; + public long getUsageCooldown() { + return usageCooldown; } - public void setReverting(boolean reverting) { - this.reverting = reverting; + public void setUsageCooldown(long usageCooldown) { + this.usageCooldown = usageCooldown; } - public boolean getGrappled() { - return grappled; + public long getTime() { + return time; } - public void setGrappled(boolean grappled) { - this.grappled = grappled; + public void setTime(long time) { + this.time = time; } - public boolean getGrabbed() { - return grabbed; + public double getPullMultiplier() { + return pullMultiplier; } - public void setGrabbed(boolean grabbed) { - this.grabbed = grabbed; + public void setPullMultiplier(double pullMultiplier) { + this.pullMultiplier = pullMultiplier; } - public LivingEntity getHeldEntity() { + public double getPunchDamage() { + return punchDamage; + } + + public void setPunchDamage(double punchDamage) { + this.punchDamage = punchDamage; + } + + public double getPlayerHealth() { + return playerHealth; + } + + public void setPlayerHealth(double playerHealth) { + this.playerHealth = playerHealth; + } + + public Arm getArm() { + return arm; + } + + public void setArm(Arm arm) { + this.arm = arm; + } + + public Whip getAbility() { + return ability; + } + + public void setAbility(Whip ability) { + this.ability = ability; + } + + public LivingEntity getGrabbedEntity() { return grabbedEntity; } + + public void setGrabbedEntity(LivingEntity grabbedEntity) { + this.grabbedEntity = grabbedEntity; + } + + public Location getEnd() { + return end; + } + + public void setEnd(Location end) { + this.end = end; + } + + public WaterArms getWaterArms() { + return waterArms; + } + + public void setWaterArms(WaterArms waterArms) { + this.waterArms = waterArms; + } + + public static HashMap getGrabbedEntities() { + return GRABBED_ENTITIES; + } + } diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterBubble.java b/src/com/projectkorra/projectkorra/waterbending/WaterBubble.java new file mode 100644 index 00000000..9d4f2ce7 --- /dev/null +++ b/src/com/projectkorra/projectkorra/waterbending/WaterBubble.java @@ -0,0 +1,46 @@ +package com.projectkorra.projectkorra.waterbending; + +import com.projectkorra.projectkorra.ability.WaterAbility; + +import org.bukkit.Location; +import org.bukkit.entity.Player; + +/** + * WaterBubble is currently implemented in AirBubble + */ +public class WaterBubble extends WaterAbility { + + public WaterBubble(Player player) { + super(player); + } + + @Override + public String getName() { + return "WaterBubble"; + } + + @Override + public void progress() { + } + + @Override + public Location getLocation() { + return null; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + +} diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterCombo.java b/src/com/projectkorra/projectkorra/waterbending/WaterCombo.java index cb6d5d6c..21aa5f07 100644 --- a/src/com/projectkorra/projectkorra/waterbending/WaterCombo.java +++ b/src/com/projectkorra/projectkorra/waterbending/WaterCombo.java @@ -1,15 +1,16 @@ package com.projectkorra.projectkorra.waterbending; -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.Element; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.SubElement; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.command.Commands; -import com.projectkorra.projectkorra.earthbending.EarthMethods; +import com.projectkorra.projectkorra.ability.ComboAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation; +import com.projectkorra.projectkorra.avatar.AvatarState; import com.projectkorra.projectkorra.firebending.FireCombo; import com.projectkorra.projectkorra.firebending.FireCombo.FireComboStream; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.ClickType; import com.projectkorra.projectkorra.util.ParticleEffect; import com.projectkorra.projectkorra.util.TempBlock; @@ -26,314 +27,136 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.concurrent.ConcurrentHashMap; -public class WaterCombo { +/* + * TODO: Combo classes should eventually be rewritten so that each combo is treated + * as an individual ability. In the mean time, we will just place "fake" + * classes so that CoreAbility will register each ability. + */ +public class WaterCombo extends WaterAbility implements ComboAbility { + public static enum AbilityState { ICE_PILLAR_RISING, ICE_BULLET_FORMING } - private static boolean enabled = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.WaterCombo.Enabled"); - public static long ICE_WAVE_COOLDOWN = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.WaterCombo.IceWave.Cooldown"); - - public static double ICE_PILLAR_HEIGHT = 8; - public static double ICE_PILLAR_RADIUS = 1.5; - public static double ICE_PILLAR_DAMAGE = 4; - public static double ICE_PILLAR_RANGE = 10; - public static long ICE_PILLAR_COOLDOWN = 500; - - public static double ICE_BULLET_RADIUS = ProjectKorra.plugin.getConfig().getDouble( - "Abilities.Water.WaterCombo.IceBullet.Radius"); - public static double ICE_BULLET_DAMAGE = ProjectKorra.plugin.getConfig().getDouble( - "Abilities.Water.WaterCombo.IceBullet.Damage"); - public static double ICE_BULLET_RANGE = ProjectKorra.plugin.getConfig().getDouble( - "Abilities.Water.WaterCombo.IceBullet.Range"); - public static double ICE_BULLET_ANIM_SPEED = ProjectKorra.plugin.getConfig().getDouble( - "Abilities.Water.WaterCombo.IceBullet.AnimationSpeed"); - public static int ICE_BULLET_MAX_SHOTS = ProjectKorra.plugin.getConfig().getInt( - "Abilities.Water.WaterCombo.IceBullet.MaxShots"); - public static long ICE_BULLET_COOLDOWN = ProjectKorra.plugin.getConfig().getLong( - "Abilities.Water.WaterCombo.IceBullet.Cooldown"); - public static long ICE_BULLET_SHOOT_TIME = ProjectKorra.plugin.getConfig().getLong( - "Abilities.Water.WaterCombo.IceBullet.ShootTime"); - - public static ArrayList instances = new ArrayList(); - public static ConcurrentHashMap frozenBlocks = new ConcurrentHashMap(); - - private Player player; - private BendingPlayer bplayer; - private String ability; + private static final ConcurrentHashMap FROZEN_BLOCKS = new ConcurrentHashMap<>(); + private boolean enabled; + private int leftClicks; + private int rightClicks; + private double damage; + private double speed; + private double range; + private double knockback; + private double radius; + private double shootTime; + private double shots; + private double maxShots; + private double animationSpeed; + private long cooldown; private long time; - private Location origin; - private Location currentLoc; - @SuppressWarnings("unused") - private Location destination; - private Vector direction; private AbilityState state; - private int progressCounter = 0; - private int leftClicks = 0, rightClicks = 0; - private double damage = 0, speed = 0, range = 0, knockback = 0, radius = 0, shootTime = 0, maxShots = 0; - private double shots = 0; - private long cooldown = 0; + private String name; + private Location origin; + private Location location; + private Vector direction; private WaterSourceGrabber waterGrabber; - @SuppressWarnings("unused") - private ArrayList affectedEntities = new ArrayList(); - private ArrayList tasks = new ArrayList(); - private ConcurrentHashMap affectedBlocks = new ConcurrentHashMap(); + private ArrayList tasks; + private ConcurrentHashMap affectedBlocks; - public WaterCombo(Player player, String ability) { - if (!enabled) - return; - if(!GeneralMethods.getBendingPlayer(player.getName()).hasElement(Element.Water)) - return; - if (Commands.isToggledForAll) - return; - if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", - player.getLocation())) - return; - if (!GeneralMethods.getBendingPlayer(player.getName()).isToggled()) - return; - time = System.currentTimeMillis(); - this.player = player; - this.ability = ability; - this.bplayer = GeneralMethods.getBendingPlayer(player.getName()); + public WaterCombo(Player player, String name) { + super(player); - if (!GeneralMethods.canBend(player.getName(), ability)) { + this.time = System.currentTimeMillis(); + this.name = name; + this.enabled = getConfig().getBoolean("Abilities.Water.WaterCombo.Enabled"); + this.tasks = new ArrayList<>(); + this.affectedBlocks = new ConcurrentHashMap<>(); + + if (!enabled || !bPlayer.canBendIgnoreBindsCooldowns(this)) { return; } - if (ability.equalsIgnoreCase("IceWave")) { - cooldown = ICE_WAVE_COOLDOWN; - } else if (ability.equalsIgnoreCase("IcePillar")) { - damage = ICE_PILLAR_DAMAGE; - range = ICE_PILLAR_RANGE; - radius = ICE_PILLAR_RADIUS; - cooldown = ICE_WAVE_COOLDOWN; - } else if (ability.equalsIgnoreCase("IceBullet")) { - damage = ICE_BULLET_DAMAGE; - range = ICE_BULLET_RANGE; - radius = ICE_BULLET_RADIUS; - cooldown = ICE_BULLET_COOLDOWN; - shootTime = ICE_BULLET_SHOOT_TIME; - maxShots = ICE_BULLET_MAX_SHOTS; - speed = 1; - } - double aug = WaterMethods.getWaterbendingNightAugment(player.getWorld()); - if(aug > 1) - aug = 1 + (aug - 1) / 3; - damage *= aug; - range *= aug; - shootTime *= aug; - maxShots *= aug; - radius *= aug; - if (AvatarState.isAvatarState(player)) { - cooldown = 0; - damage = AvatarState.getValue(damage); - range = AvatarState.getValue(range); - shootTime = AvatarState.getValue(shootTime); - maxShots = AvatarState.getValue(maxShots); - knockback = knockback * 1.3; + if (name.equalsIgnoreCase("IceWave")) { + this.cooldown = getConfig().getLong("Abilities.Water.WaterCombo.IceWave.Cooldown"); + } else if (name.equalsIgnoreCase("IceBullet")) { + this.damage = getConfig().getDouble("Abilities.Water.WaterCombo.IceBullet.Damage"); + this.range = getConfig().getDouble("Abilities.Water.WaterCombo.IceBullet.Range"); + this.radius = getConfig().getDouble("Abilities.Water.WaterCombo.IceBullet.Radius"); + this.cooldown = getConfig().getLong("Abilities.Water.WaterCombo.IceBullet.Cooldown"); + this.shootTime = getConfig().getLong("Abilities.Water.WaterCombo.IceBullet.ShootTime"); + this.maxShots = getConfig().getInt("Abilities.Water.WaterCombo.IceBullet.MaxShots"); + this.animationSpeed = getConfig().getDouble("Abilities.Water.WaterCombo.IceBullet.AnimationSpeed"); + this.speed = 1; } - if(ability.equalsIgnoreCase("IceBulletLeftClick") || ability.equalsIgnoreCase("IceBulletRightClick")) - { - ArrayList bullets = getWaterCombo(player, "IceBullet"); - if(bullets.size() == 0) - return; - for(WaterCombo bullet : bullets) - { - if(ability.equalsIgnoreCase("IceBulletLeftClick")) - { - if(bullet.leftClicks <= bullet.rightClicks) - bullet.leftClicks += 1; - } - else if(bullet.leftClicks >= bullet.rightClicks) - bullet.rightClicks += 1; - } + double aug = getNightFactor(player.getWorld()); + if (aug > 1) { + aug = 1 + (aug - 1) / 3; } - instances.add(this); - } - public void progress() { - progressCounter++; - if (player.isDead() || !player.isOnline()) { - remove(); + this.damage *= aug; + this.range *= aug; + this.shootTime *= aug; + this.maxShots *= aug; + this.radius *= aug; + + if (bPlayer.isAvatarState()) { + this.cooldown = 0; + this.damage = AvatarState.getValue(damage); + this.range = AvatarState.getValue(range); + this.shootTime = AvatarState.getValue(shootTime); + this.maxShots = AvatarState.getValue(maxShots); + this.knockback = knockback * 1.3; + } + + if (name.equalsIgnoreCase("IceBulletLeftClick") || name.equalsIgnoreCase("IceBulletRightClick")) { + ArrayList bullets = getWaterCombo(player, "IceBullet"); + if (bullets.size() == 0) { + return; + } + for (WaterCombo bullet : bullets) { + if (name.equalsIgnoreCase("IceBulletLeftClick")) { + if (bullet.leftClicks <= bullet.rightClicks) { + bullet.leftClicks += 1; + } + } else if (bullet.leftClicks >= bullet.rightClicks) { + bullet.rightClicks += 1; + } + } return; } + + start(); + } - if (ability.equalsIgnoreCase("IceWave")) { - if (origin == null - && WaterWave.containsType(player, - WaterWave.AbilityType.RELEASE)) { - if (bplayer.isOnCooldown("IceWave") - && !AvatarState.isAvatarState(player)) { - remove(); - return; - } - bplayer.addCooldown("IceWave", cooldown); - origin = player.getLocation(); - WaterWave wave = WaterWave.getType(player, - WaterWave.AbilityType.RELEASE).get(0); - wave.setIceWave(true); - } else if (!WaterWave.containsType(player, - WaterWave.AbilityType.RELEASE)) { - remove(); - return; - } - } else if (ability.equalsIgnoreCase("IcePillar")) { - // ABILITY NOT USED or Finished because RuneFist is creating a - // similar ability - if (progressCounter > 0) { - remove(); - return; - } - if (origin == null) { - if (bplayer.isOnCooldown("IcePillar") - && !AvatarState.isAvatarState(player)) { - remove(); - return; - } - origin = player.getLocation(); - Entity ent = GeneralMethods.getTargetedEntity(player, range, - new ArrayList()); - if (ent == null || !(ent instanceof LivingEntity)) { - remove(); - return; - } + public void createBlock(Block block, Material mat) { + createBlock(block, mat, (byte) 0); + } - Location startingLoc = GeneralMethods.getTopBlock( - ent.getLocation().add(0, -1, 0), (int) range) - .getLocation(); - if (startingLoc == null) { - remove(); - return; - } - startingLoc.setX(ent.getLocation().getX()); - startingLoc.setZ(ent.getLocation().getZ()); - int badBlocks = 0; - for (double x = -radius; x <= radius; x++) - for (double z = -radius; z <= radius; z++) { - Location tmpLoc = startingLoc.clone().add(x, 0, z); - if (tmpLoc.distance(startingLoc) > radius) - continue; + public void createBlock(Block block, Material mat, byte data) { + affectedBlocks.put(block, new TempBlock(block, mat, data)); + } - Block block = GeneralMethods.getTopBlock(tmpLoc, (int) range, - (int) range); - if (!WaterMethods.isWaterbendable(block, player)) - badBlocks++; - } - //Bukkit.broadcastMessage("Bad Blocks:" + badBlocks); - if (badBlocks > 5) { - remove(); - return; - } - this.origin = startingLoc; - this.currentLoc = origin.clone(); - this.state = AbilityState.ICE_PILLAR_RISING; - bplayer.addCooldown("IcePillar", cooldown); - } else if (this.state == AbilityState.ICE_PILLAR_RISING) { - if (Math.abs(currentLoc.distance(origin)) > ICE_PILLAR_HEIGHT) { - remove(); - return; - } - for (double x = -radius; x <= radius; x++) - for (double z = -radius; z <= radius; z++) { - Block block = currentLoc.clone().add(x, 0, z) - .getBlock(); - if (WaterMethods.isWaterbendable(block, player) - || block.getType() == Material.AIR) - if (block.getLocation().distance(currentLoc) > radius) - continue; - if (GeneralMethods.isRegionProtectedFromBuild(player, - "WaterManipulation", block.getLocation())) - continue; + public void drawWaterCircle(Location loc, double theta, double increment, double radius) { + drawWaterCircle(loc, theta, increment, radius, Material.STATIONARY_WATER, (byte) 0); + } - TempBlock tblock = new TempBlock(block, Material.ICE, - (byte) 0); - frozenBlocks.put(block, tblock); - } - currentLoc.add(0, 1, 0); - } - } else if (ability.equalsIgnoreCase("IceBullet")) { - if(shots > maxShots || !player.isSneaking()){ - remove(); - return; - } - if (origin == null) { - if (bplayer.isOnCooldown("IceBullet") - && !AvatarState.isAvatarState(player)) { - remove(); - return; - } - Block waterBlock = WaterMethods.getRandomWaterBlock(player, player.getLocation(), (int) range, true, WaterMethods.canIcebend(player), WaterMethods.canPlantbend(player)); - if (waterBlock == null) { - remove(); - return; - } - this.time = 0; - origin = waterBlock.getLocation(); - currentLoc = origin.clone(); - state = AbilityState.ICE_BULLET_FORMING; - bplayer.addCooldown("IceBullet", cooldown); - direction = new Vector(1, 0, 1); - waterGrabber = new WaterSourceGrabber(player, origin.clone()); - } else if (waterGrabber.getState() == WaterSourceGrabber.AnimationState.FAILED) { - remove(); - return; - } else if (waterGrabber.getState() == WaterSourceGrabber.AnimationState.FINISHED) { - if(this.time == 0) - this.time = System.currentTimeMillis(); - long timeDiff = System.currentTimeMillis() - this.time; - double animSpeed = ICE_BULLET_ANIM_SPEED; - if(this.state == AbilityState.ICE_BULLET_FORMING) - { - if(timeDiff < 1000 * animSpeed) - { - double steps = radius * ((timeDiff + 100) / (1000.0 * animSpeed)); - revertBlocks(); - for(double i = 0; i < steps; i++) - { - drawWaterCircle(player.getEyeLocation().clone().add(0, i, 0), 360, 5, radius - i); - drawWaterCircle(player.getEyeLocation().clone().add(0, -i, 0), 360, 5, radius - i); - } - } - else if(timeDiff < 2500 * animSpeed) - { - revertBlocks(); - for(double i = 0; i < radius; i++) - { - drawWaterCircle(player.getEyeLocation().clone().add(0, i, 0), 360, 5, radius - i, Material.ICE, (byte) 0); - drawWaterCircle(player.getEyeLocation().clone().add(0, -i, 0), 360, 5, radius - i, Material.ICE, (byte) 0); - } - } - - if(timeDiff < shootTime) - { - if(shots < rightClicks + leftClicks) - { - shots++; - Vector vec = player.getEyeLocation().getDirection().normalize(); - Location loc = player.getEyeLocation().add(vec.clone().multiply(radius + 1.3)); - FireComboStream fs = new FireComboStream(null, vec, - loc, range, speed, "IceBullet"); - fs.setDensity(10); - fs.setSpread(0.1F); - fs.setUseNewParticles(true); - fs.setParticleEffect(ParticleEffect.SNOW_SHOVEL); - fs.setCollides(false); - fs.runTaskTimer(ProjectKorra.plugin, (long) (0), 1L); - tasks.add(fs); - } - manageShots(); - } - else - remove(); - } - } else { - waterGrabber.progress(); + public void drawWaterCircle(Location loc, double theta, double increment, double radius, Material mat, byte data) { + double rotateSpeed = theta; + direction = GeneralMethods.rotateXZ(direction, rotateSpeed); + + for (double i = 0; i < theta; i += increment) { + Vector dir = GeneralMethods.rotateXZ(direction, i - theta / 2).normalize().multiply(radius); + dir.setY(0); + Block block = loc.clone().add(dir).getBlock(); + location = block.getLocation(); + + if (block.getType() == Material.AIR && !GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", block.getLocation())) { + createBlock(block, mat, data); } } } - + public void manageShots() { for (int i = 0; i < tasks.size(); i++) { if (((FireComboStream) tasks.get(i)).isCancelled()) { @@ -341,53 +164,149 @@ public class WaterCombo { i--; } } + for (int i = 0; i < tasks.size(); i++) { FireComboStream fstream = (FireComboStream) tasks.get(i); Location loc = fstream.getLocation(); - if (!EarthMethods.isTransparentToEarthbending(player, - loc.clone().add(0, 0.2, 0).getBlock())) { + if (!isTransparentToEarthbending(player, loc.clone().add(0, 0.2, 0).getBlock())) { fstream.remove(); return; } if (i % 2 == 0) { for (Entity entity : GeneralMethods.getEntitiesAroundPoint(loc, 1.5)) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", - entity.getLocation())) { + if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", entity.getLocation())) { remove(); return; } - /*if (!entity.equals(player) - && !affectedEntities.contains(entity)) { - affectedEntities.add(entity);*/ - if(!entity.equals(player)) { + + if (!entity.equals(player)) { if (knockback != 0) { Vector force = fstream.getDirection(); entity.setVelocity(force.multiply(knockback)); } - if (damage != 0) - if (entity instanceof LivingEntity) - if (fstream.getAbility().equalsIgnoreCase("IceBullet")) { - GeneralMethods.damageEntity(player, entity, damage, SubElement.Icebending, "IceBullets"); - } else { - GeneralMethods.damageEntity(player, entity, damage, Element.Water, "WaterCombo"); - } + if (damage != 0) { + if (entity instanceof LivingEntity) { + GeneralMethods.damageEntity(this, entity, damage); + } + } } } - if (GeneralMethods.blockAbilities(player, FireCombo.abilitiesToBlock, - loc, 1)) { + if (GeneralMethods.blockAbilities(player, FireCombo.getBlockableAbilities(), loc, 1)) { fstream.remove(); } } } } - public void createBlock(Block block, Material mat) { - createBlock(block, mat, (byte) 0); + + @Override + public void progress() { + if (player.isDead() || !player.isOnline()) { + remove(); + return; + } else if (name.equalsIgnoreCase("IceWave")) { + if (origin == null && WaterSpoutWave.containsType(player, WaterSpoutWave.AbilityType.RELEASE)) { + if (bPlayer.isOnCooldown("IceWave") && !bPlayer.isAvatarState()) { + remove(); + return; + } + + bPlayer.addCooldown("IceWave", cooldown); + origin = player.getLocation(); + WaterSpoutWave wave = WaterSpoutWave.getType(player, WaterSpoutWave.AbilityType.RELEASE).get(0); + wave.setIceWave(true); + } else if (!WaterSpoutWave.containsType(player, WaterSpoutWave.AbilityType.RELEASE)) { + remove(); + return; + } + } else if (name.equalsIgnoreCase("IceBullet")) { + if (shots > maxShots || !player.isSneaking()) { + remove(); + return; + } + + if (origin == null) { + if (bPlayer.isOnCooldown("IceBullet") && !bPlayer.isAvatarState()) { + remove(); + return; + } + + Block waterBlock = BlockSource.getWaterSourceBlock(player, range, ClickType.LEFT_CLICK, true, true, bPlayer.canPlantbend()); + if (waterBlock == null) { + remove(); + return; + } + + time = 0; + origin = waterBlock.getLocation(); + location = origin.clone(); + state = AbilityState.ICE_BULLET_FORMING; + bPlayer.addCooldown("IceBullet", cooldown); + direction = new Vector(1, 0, 1); + waterGrabber = new WaterSourceGrabber(player, origin.clone()); + } else if (waterGrabber.getState() == WaterSourceGrabber.AnimationState.FAILED) { + remove(); + return; + } else if (waterGrabber.getState() == WaterSourceGrabber.AnimationState.FINISHED) { + if (this.time == 0) { + this.time = System.currentTimeMillis(); + } + + long timeDiff = System.currentTimeMillis() - this.time; + if (this.state == AbilityState.ICE_BULLET_FORMING) { + if (timeDiff < 1000 * animationSpeed) { + double steps = radius * ((timeDiff + 100) / (1000.0 * animationSpeed)); + revertBlocks(); + for (double i = 0; i < steps; i++) { + drawWaterCircle(player.getEyeLocation().clone().add(0, i, 0), 360, 5, radius - i); + drawWaterCircle(player.getEyeLocation().clone().add(0, -i, 0), 360, 5, radius - i); + } + } else if (timeDiff < 2500 * animationSpeed) { + revertBlocks(); + for (double i = 0; i < radius; i++) { + drawWaterCircle(player.getEyeLocation().clone().add(0, i, 0), 360, 5, radius - i, Material.ICE, (byte) 0); + drawWaterCircle(player.getEyeLocation().clone().add(0, -i, 0), 360, 5, radius - i, Material.ICE, (byte) 0); + } + } + + if (timeDiff < shootTime) { + if (shots < rightClicks + leftClicks) { + shots++; + Vector vec = player.getEyeLocation().getDirection().normalize(); + Location loc = player.getEyeLocation().add(vec.clone().multiply(radius + 1.3)); + FireComboStream fs = new FireComboStream(null, vec, loc, range, speed, "IceBullet"); + + fs.setDensity(10); + fs.setSpread(0.1F); + fs.setUseNewParticles(true); + fs.setParticleEffect(ParticleEffect.SNOW_SHOVEL); + fs.setCollides(false); + fs.runTaskTimer(ProjectKorra.plugin, (0), 1L); + tasks.add(fs); + } + manageShots(); + } else { + remove(); + return; + } + } + } else { + waterGrabber.progress(); + } + } } - public void createBlock(Block block, Material mat, byte data) { - affectedBlocks.put(block, new TempBlock(block, mat, data)); + @Override + public void remove() { + super.remove(); + for (BukkitRunnable task : tasks) { + task.cancel(); + } + revertBlocks(); + if (waterGrabber != null) { + waterGrabber.remove(); + } } public void revertBlocks() { @@ -398,95 +317,260 @@ public class WaterCombo { affectedBlocks.remove(block); } } - public void drawWaterCircle(Location loc, double theta, double increment, double radius){ - drawWaterCircle(loc, theta, increment, radius, Material.STATIONARY_WATER, (byte) 0); - } - public void drawWaterCircle(Location loc, double theta, double increment, double radius, Material mat, byte data) { - double rotateSpeed = theta; - direction = GeneralMethods.rotateXZ(direction, rotateSpeed); - for (double i = 0; i < theta; i += increment) { - Vector dir = GeneralMethods.rotateXZ(direction, i - theta / 2).normalize() - .multiply(radius); - dir.setY(0); - Block block = loc.clone().add(dir).getBlock(); - currentLoc = block.getLocation(); - if (block.getType() == Material.AIR - && !GeneralMethods.isRegionProtectedFromBuild(player, - "WaterManipulation", block.getLocation())) - createBlock(block, mat, data); - } - } - - public void remove() { - instances.remove(this); - for (BukkitRunnable task : tasks) - task.cancel(); - revertBlocks(); - if(waterGrabber != null) - waterGrabber.remove(); - } - - public static void progressAll() { - for (int i = instances.size() - 1; i >= 0; i--) - instances.get(i).progress(); - } - - public static void removeAll() { - for (int i = instances.size() - 1; i >= 0; i--) { - instances.get(i).remove(); - } - } - - public Player getPlayer() { - return player; - } - - public static ArrayList getWaterCombo(Player player) { - ArrayList list = new ArrayList(); - for (WaterCombo combo : instances) - if (combo.player != null && combo.player == player) - list.add(combo); - return list; - } - - public static ArrayList getWaterCombo(Player player, - String ability) { - ArrayList list = new ArrayList(); - for (WaterCombo combo : instances) - if (combo.player != null && combo.player == player - && ability != null && combo.ability.equalsIgnoreCase(ability)) - list.add(combo); - return list; - } - - public static boolean removeAroundPoint(Player player, String ability, - Location loc, double radius) { - boolean removed = false; - for (int i = 0; i < instances.size(); i++) { - WaterCombo combo = instances.get(i); - if (combo.getPlayer().equals(player)) - continue; - - if (ability.equalsIgnoreCase("Twister") - && combo.ability.equalsIgnoreCase("Twister")) { - if (combo.currentLoc != null - && Math.abs(combo.currentLoc.distance(loc)) <= radius) { - instances.remove(combo); - removed = true; - } - } - } - return removed; - } public static boolean canThaw(Block block) { - return frozenBlocks.containsKey(block); + return FROZEN_BLOCKS.containsKey(block); + } + + public static ArrayList getWaterCombo(Player player, String ability) { + ArrayList list = new ArrayList(); + if (player == null || ability == null) { + return list; + } + for (WaterCombo combo : CoreAbility.getAbilities(player, WaterCombo.class)) { + if (player.equals(combo.player) && combo.name.equalsIgnoreCase(ability)) { + list.add(combo); + } + } + return list; } public static void thaw(Block block) { - if (frozenBlocks.containsKey(block)) { - frozenBlocks.get(block).revertBlock(); - frozenBlocks.remove(block); + if (FROZEN_BLOCKS.containsKey(block)) { + FROZEN_BLOCKS.get(block).revertBlock(); + FROZEN_BLOCKS.remove(block); } } -} \ No newline at end of file + + @Override + public String getName() { + return name != null ? name : "WaterCombo"; + } + + @Override + public Location getLocation() { + return location != null ? location : origin; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isHiddenAbility() { + return true; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + @Override + public String getInstructions() { + return null; + } + + @Override + public Object createNewComboInstance(Player player) { + return null; + } + + @Override + public ArrayList getCombination() { + return null; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public int getLeftClicks() { + return leftClicks; + } + + public void setLeftClicks(int leftClicks) { + this.leftClicks = leftClicks; + } + + public int getRightClicks() { + return rightClicks; + } + + public void setRightClicks(int rightClicks) { + this.rightClicks = rightClicks; + } + + public double getDamage() { + return damage; + } + + public void setDamage(double damage) { + this.damage = damage; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getKnockback() { + return knockback; + } + + public void setKnockback(double knockback) { + this.knockback = knockback; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public double getShootTime() { + return shootTime; + } + + public void setShootTime(double shootTime) { + this.shootTime = shootTime; + } + + public double getShots() { + return shots; + } + + public void setShots(double shots) { + this.shots = shots; + } + + public double getMaxShots() { + return maxShots; + } + + public void setMaxShots(double maxShots) { + this.maxShots = maxShots; + } + + public double getAnimationSpeed() { + return animationSpeed; + } + + public void setAnimationSpeed(double animationSpeed) { + this.animationSpeed = animationSpeed; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public AbilityState getState() { + return state; + } + + public void setState(AbilityState state) { + this.state = state; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public WaterSourceGrabber getWaterGrabber() { + return waterGrabber; + } + + public void setWaterGrabber(WaterSourceGrabber waterGrabber) { + this.waterGrabber = waterGrabber; + } + + public ArrayList getTasks() { + return tasks; + } + + public static ConcurrentHashMap getFrozenBlocks() { + return FROZEN_BLOCKS; + } + + public ConcurrentHashMap getAffectedBlocks() { + return affectedBlocks; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setName(String name) { + this.name = name; + } + + public void setLocation(Location location) { + this.location = location; + } + + public class IceWave extends WaterCombo { + + public IceWave(Player player, String name) { + super(player, "IceWave"); + } + + @Override + public String getName() { + return "IceWave"; + } + + } + + public class IceBullet extends WaterCombo { + + public IceBullet(Player player, String name) { + super(player, "IceBullet"); + } + + @Override + public String getName() { + return "IceBullet"; + } + + } + +} diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterManipulation.java b/src/com/projectkorra/projectkorra/waterbending/WaterManipulation.java index a54c3cfe..cf7f04f7 100644 --- a/src/com/projectkorra/projectkorra/waterbending/WaterManipulation.java +++ b/src/com/projectkorra/projectkorra/waterbending/WaterManipulation.java @@ -2,11 +2,11 @@ package com.projectkorra.projectkorra.waterbending; import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.airbending.AirMethods; +import com.projectkorra.projectkorra.ability.AirAbility; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.avatar.AvatarState; import com.projectkorra.projectkorra.earthbending.EarthBlast; -import com.projectkorra.projectkorra.earthbending.EarthMethods; import com.projectkorra.projectkorra.firebending.Combustion; import com.projectkorra.projectkorra.firebending.FireBlast; import com.projectkorra.projectkorra.util.BlockSource; @@ -18,349 +18,227 @@ import org.bukkit.Effect; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import java.util.ArrayList; import java.util.HashSet; +import java.util.Random; import java.util.concurrent.ConcurrentHashMap; -public class WaterManipulation { +public class WaterManipulation extends WaterAbility { - private static FileConfiguration config = ProjectKorra.plugin.getConfig(); - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - public static ConcurrentHashMap affectedblocks = new ConcurrentHashMap(); - public static ConcurrentHashMap prepared = new ConcurrentHashMap(); - - static double RANGE = config.getDouble("Abilities.Water.WaterManipulation.Range"); - private static double PUSH_FACTOR = config.getDouble("Abilities.Water.WaterManipulation.Push"); - private static double defaultdamage = config.getDouble("Abilities.Water.WaterManipulation.Damage"); - private static double speed = config.getDouble("Abilities.Water.WaterManipulation.Speed"); - private static long COOLDOWN = config.getLong("Abilities.Water.WaterManipulation.Cooldown"); - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.WaterManipulation.SelectRange"); - private static int autoSelectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.WaterManipulation.AutoSourcing.SelectRange"); - private static boolean auto = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.WaterManipulation.AutoSourcing.Enabled"); - private static long autocooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.WaterManipulation.AutoSourcing.Cooldown"); - private static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.WaterManipulation.DynamicSourcing.Enabled"); - private static long interval = (long) (1000. / speed); - - private boolean isAuto; - - private static final double deflectrange = 3; - // private static double speed = 1.5; - private static int ID = Integer.MIN_VALUE; - - private static final byte full = 0x0; - private static HashSet water = new HashSet(); - // private static final byte half = 0x4; - - Player player; + private static final ConcurrentHashMap AFFECTED_BLOCKS = new ConcurrentHashMap<>(); + + private boolean progressing; + private boolean falling; + private boolean settingUp; + private boolean displacing; + private boolean prepared; + private int dispelRange; private long time; - private double damage = defaultdamage; - private int displrange; - private int id; - private Location location = null; - private Block sourceblock = null; - private TempBlock trail, trail2; - private Location firstdestination = null; - private Location targetdestination = null; - private Vector firstdirection = null; - private Vector targetdirection = null; - private boolean progressing = false; - private boolean falling = false; - private boolean settingup = false; - // private boolean targetting = false; - private final boolean displacing = false; - private double range = RANGE; - private double pushfactor = PUSH_FACTOR; - private long cooldown = COOLDOWN; - + private long cooldown; + private long interval; + private double range; + private double pushFactor; + private double damage; + private double speed; + private double deflectRange; + private double affectingRadius; + private Block sourceBlock; + private Location location; + private TempBlock trail; + private TempBlock trail2; + private Location firstDestination; + private Location targetDestination; + private Vector firstDirection; + private Vector targetDirection; + private HashSet waterTypes; + public WaterManipulation(Player player) { - if (water.isEmpty()) { - water.add((byte) 0); - water.add((byte) 8); - water.add((byte) 9); - } - this.player = player; - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer.isOnCooldown("WaterManipulation")) - return; + super(player); + + this.progressing = false; + this.falling = false; + this.settingUp = false; + this.displacing = false; + this.affectingRadius = 2.0; + this.cooldown = getConfig().getLong("Abilities.Water.WaterManipulation.Cooldown"); + this.range = getConfig().getDouble("Abilities.Water.WaterManipulation.Range"); + this.pushFactor = getConfig().getDouble("Abilities.Water.WaterManipulation.Push"); + this.damage = getConfig().getDouble("Abilities.Water.WaterManipulation.Damage"); + this.speed = getConfig().getDouble("Abilities.Water.WaterManipulation.Speed"); + this.deflectRange = 3; + this.waterTypes = new HashSet(); + + this.interval = (long) (1000. / speed); + this.waterTypes.add((byte) 0); + this.waterTypes.add((byte) 8); + this.waterTypes.add((byte) 9); + if (prepare()) { - id = ID; - instances.put(id, this); - prepared.put(player, id); - if (ID == Integer.MAX_VALUE) - ID = Integer.MIN_VALUE; - ID++; + prepared = true; + start(); time = System.currentTimeMillis(); } } - public boolean prepare() { - // Block block = player.getTargetBlock(null, (int) range); - Block block = BlockSource.getWaterSourceBlock(player, autoSelectRange, selectRange, ClickType.SHIFT_DOWN, auto, dynamic, true, true, - WaterMethods.canIcebend(player), WaterMethods.canPlantbend(player)); - if (BlockSource.isAuto(block)) { - isAuto = true; - } else { - isAuto = false; + private void cancelPrevious() { + WaterManipulation old = CoreAbility.getAbility(player, WaterManipulation.class); + if (old != null && !old.progressing) { + old.remove(); } - // if (prepared.containsKey(player) - // && !Methods.isWaterbendable(block, player)) { - // instances.get(prepared.get(player)).displacing = true; - // instances.get(prepared.get(player)).moveWater(); - // } + } + + private void finalRemoveWater(Block block) { + if (trail != null) { + trail.revertBlock(); + trail = null; + } + if (trail2 != null) { + trail2.revertBlock(); + trail = null; + } + if (displacing) { + removeWater(block); + return; + } + if (AFFECTED_BLOCKS.containsKey(block)) { + if (!GeneralMethods.isAdjacentToThreeOrMoreSources(block)) { + block.setType(Material.AIR); + } + AFFECTED_BLOCKS.remove(block); + } + } + + private void focusBlock() { + location = sourceBlock.getLocation(); + } + + private Location getToEyeLevel() { + Location loc = sourceBlock.getLocation().clone(); + double dy = targetDestination.getY() - sourceBlock.getY(); + if (dy <= 2) { + loc.setY(sourceBlock.getY() + 2); + } else { + loc.setY(targetDestination.getY() - 1); + } + return loc; + } + + public void moveWater() { + if (sourceBlock != null) { + if (sourceBlock.getWorld().equals(player.getWorld())) { + targetDestination = getTargetLocation(player, range); + + if (targetDestination.distanceSquared(location) <= 1) { + progressing = false; + targetDestination = null; + remove(); + return; + } else { + progressing = true; + settingUp = true; + firstDestination = getToEyeLevel(); + firstDirection = GeneralMethods.getDirection(sourceBlock.getLocation(), firstDestination).normalize(); + targetDestination = GeneralMethods.getPointOnLine(firstDestination, targetDestination, range); + targetDirection = GeneralMethods.getDirection(firstDestination, targetDestination).normalize(); + + if (isPlant(sourceBlock)) { + new PlantRegrowth(player, sourceBlock); + } + addWater(sourceBlock); + } + } + bPlayer.addCooldown(this); + } + } + + public boolean prepare() { + Block block = BlockSource.getWaterSourceBlock(player, range, ClickType.SHIFT_DOWN, true, true, bPlayer.canPlantbend()); cancelPrevious(); block(player); + if (block != null) { - sourceblock = block; + sourceBlock = block; focusBlock(); return true; } return false; } - private void cancelPrevious() { - if (prepared.containsKey(player)) { - if (instances.containsKey(prepared.get(player))) { - WaterManipulation old = instances.get(prepared.get(player)); - if (!old.progressing) { - old.cancel(); - } - } + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { + remove(); + return; } - } - public void cancel() { - unfocusBlock(); - } - - private void focusBlock() { - location = sourceblock.getLocation(); - } - - private void unfocusBlock() { - remove(id); - } - - public void moveWater() { - if (sourceblock != null) { - if (sourceblock.getWorld().equals(player.getWorld())) { - targetdestination = getTargetLocation(player, range); - - if (targetdestination.distance(location) <= 1) { - progressing = false; - targetdestination = null; - remove(id); - } else { - progressing = true; - settingup = true; - firstdestination = getToEyeLevel(); - firstdirection = GeneralMethods.getDirection(sourceblock.getLocation(), firstdestination).normalize(); - targetdestination = GeneralMethods.getPointOnLine(firstdestination, targetdestination, range); - targetdirection = GeneralMethods.getDirection(firstdestination, targetdestination).normalize(); - - if (WaterMethods.isPlant(sourceblock)) - new Plantbending(sourceblock); - addWater(sourceblock); - } - - } - if (isAuto) { - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("WaterManipulation", autocooldown); - } else { - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("WaterManipulation", - cooldown); - } - } - } - - private static Location getTargetLocation(Player player) { - return getTargetLocation(player, RANGE); - } - - private static Location getTargetLocation(Player player, double range) { - Entity target = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); - Location location; - if (target == null) { - location = GeneralMethods.getTargetedLocation(player, range, EarthMethods.transparentToEarthbending); - } else { - // targetting = true; - location = ((LivingEntity) target).getEyeLocation(); - // location.setY(location.getY() - 1); - } - return location; - } - - private Location getToEyeLevel() { - Location loc = sourceblock.getLocation().clone(); - double dy = targetdestination.getY() - sourceblock.getY(); - if (dy <= 2) { - loc.setY(sourceblock.getY() + 2); - } else { - loc.setY(targetdestination.getY() - 1); - } - return loc; - } - - private static void remove(int id) { - Player player = instances.get(id).player; - if (prepared.containsKey(player)) { - if (prepared.get(player) == id) - prepared.remove(player); - } - instances.remove(id); - } - - private void redirect(Player player, Location targetlocation) { - if (progressing && !settingup) { - if (location.distance(player.getLocation()) <= range) - targetdirection = GeneralMethods.getDirection(location, targetlocation).normalize(); - targetdestination = targetlocation; - this.player = player; - } - } - - public static void progressAll() { - for (int ID : instances.keySet()) { - if (instances.get(ID) == null) { - instances.remove(ID); - continue; - } - instances.get(ID).progress(); - } - } - - private boolean progress() { - if (player.isDead() || !player.isOnline() || !GeneralMethods.canBend(player.getName(), "WaterManipulation")) { - breakBlock(); - return false; - } if (System.currentTimeMillis() - time >= interval) { - // removeWater(oldwater); - if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", location)) { - breakBlock(); - return false; - } - - time = System.currentTimeMillis(); - - if (GeneralMethods.getBoundAbility(player) == null) { - breakBlock(); - return false; - } - if (!progressing && !falling && !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("WaterManipulation")) { - unfocusBlock(); - return false; + if (!progressing && !falling && !bPlayer.getBoundAbilityName().equalsIgnoreCase(getName())) { + remove(); + return; } if (falling) { - // location = location.clone().add(0, -1, 0); - // - // if (location.getBlock().getType() != Material.AIR) { - // falling = false; - // unfocusBlock(); - // return false; - // } - // - // for (Entity entity : Methods.getEntitiesAroundPoint(location, - // 1)) { - // if (entity instanceof LivingEntity) { - // Methods.damageEntity(player, entity, damage); - // falling = false; - // } - // } - // - // if (!falling) { - // breakBlock(); - // return false; - // } - // - // location.getBlock().setType(sourceblock.getType()); - // sourceblock.setType(Material.AIR); - // - // sourceblock = location.getBlock(); - // if (!Methods.isSolid(sourceblock.getRelative(BlockFace.DOWN)) - // || targetting) { - // finalRemoveWater(sourceblock); - // } else { - // sourceblock.setData(full); - // affectedblocks.remove(sourceblock); - // } - // - // instances.remove(player.getEntityId()); - breakBlock(); - new WaterReturn(player, sourceblock); - return false; - + remove(); + new WaterReturn(player, sourceBlock); + return; } else { if (!progressing) { - sourceblock.getWorld().playEffect(location, Effect.SMOKE, 4, (int) range); - return false; + sourceBlock.getWorld().playEffect(location, Effect.SMOKE, 4, (int) range); + return; } - - // Methods.verbose(firstdestination); - - if (sourceblock.getLocation().distance(firstdestination) < .5) { - settingup = false; + + if (sourceBlock.getLocation().distanceSquared(firstDestination) < 0.5 * 0.5) { + settingUp = false; } - // if (!player.isSneaking() && displacing) { - // displacing = false; - // breakBlock(); - // return false; - // } - Vector direction; - if (settingup) { - direction = firstdirection; + if (settingUp) { + direction = firstDirection; } else { - direction = targetdirection; + direction = targetDirection; } Block block = location.getBlock(); if (displacing) { - Block targetblock = player.getTargetBlock((HashSet) null, displrange); - direction = GeneralMethods.getDirection(location, targetblock.getLocation()).normalize(); - if (!location.getBlock().equals(targetblock.getLocation())) { + Block targetBlock = player.getTargetBlock((HashSet) null, dispelRange); + direction = GeneralMethods.getDirection(location, targetBlock.getLocation()).normalize(); + if (!location.getBlock().equals(targetBlock.getLocation())) { location = location.clone().add(direction); block = location.getBlock(); - if (block.getLocation().equals(sourceblock.getLocation())) { + if (block.getLocation().equals(sourceBlock.getLocation())) { location = location.clone().add(direction); block = location.getBlock(); } } - } else { - WaterMethods.removeWaterSpouts(location, player); - AirMethods.removeAirSpouts(location, player); + WaterAbility.removeWaterSpouts(location, player); + AirAbility.removeAirSpouts(location, player); - if (GeneralMethods.rand.nextInt(4) == 0) { - WaterMethods.playWaterbendingSound(location); + if ((new Random()).nextInt(4) == 0) { + playWaterbendingSound(location); } - double radius = FireBlast.AFFECTING_RADIUS; + double radius = affectingRadius; Player source = player; if (!(location == null)) { - if (EarthBlast.annihilateBlasts(location, radius, source) - || WaterManipulation.annihilateBlasts(location, radius, source) + if (EarthBlast.annihilateBlasts(location, radius, source) + || WaterManipulation.annihilateBlasts(location, radius, source) || FireBlast.annihilateBlasts(location, radius, source)) { - breakBlock(); - new WaterReturn(player, sourceblock); - return false; + remove(); + new WaterReturn(player, sourceBlock); + return; } Combustion.removeAroundPoint(location, radius); } location = location.clone().add(direction); - block = location.getBlock(); - if (block.getLocation().equals(sourceblock.getLocation())) { + if (block.getLocation().equals(sourceBlock.getLocation())) { location = location.clone().add(direction); block = location.getBlock(); } @@ -384,55 +262,40 @@ public class WaterManipulation { } } - if (EarthMethods.isTransparentToEarthbending(player, block) && !block.isLiquid()) { + if (isTransparentToEarthbending(player, block) && !block.isLiquid()) { GeneralMethods.breakBlock(block); - } else if (block.getType() != Material.AIR && !WaterMethods.isWater(block)) { - breakBlock(); - new WaterReturn(player, sourceblock); - return false; + } else if (block.getType() != Material.AIR && !isWater(block)) { + remove(); + new WaterReturn(player, sourceBlock); + return; } if (!displacing) { - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, FireBlast.AFFECTING_RADIUS)) { + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, affectingRadius)) { if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId()) { - - // Block testblock = location.getBlock(); - // Block block1 = entity.getLocation().getBlock(); - // Block block2 = ((LivingEntity) entity) - // .getEyeLocation().getBlock(); - // - // if (testblock.equals(block1) - // || testblock.equals(block2)) { - Location location = player.getEyeLocation(); Vector vector = location.getDirection(); - entity.setVelocity(vector.normalize().multiply(pushfactor)); - // entity.setVelocity(entity.getVelocity().clone() - // .add(direction)); - if (AvatarState.isAvatarState(player)) + entity.setVelocity(vector.normalize().multiply(pushFactor)); + + if (bPlayer.isAvatarState()) { damage = AvatarState.getValue(damage); - GeneralMethods.damageEntity(player, entity, - (int) WaterMethods.waterbendingNightAugment(damage, player.getWorld()), "WaterManipulation"); - AirMethods.breakBreathbendingHold(entity); + } + damage = getNightFactor(damage); + GeneralMethods.damageEntity(this, entity, damage); + AirAbility.breakBreathbendingHold(entity); progressing = false; - // } } } } if (!progressing) { - breakBlock(); - new WaterReturn(player, sourceblock); - return false; + remove(); + new WaterReturn(player, sourceBlock); + return; } addWater(block); - reduceWater(sourceblock); - // if (block.getType() != Material.AIR) { - // block.setType(Material.GLOWSTONE); - // } else { - // block.setType(Material.GLASS); - // } + reduceWater(sourceBlock); if (trail2 != null) { trail2.revertBlock(); @@ -442,28 +305,25 @@ public class WaterManipulation { trail2 = trail; trail2.setType(Material.STATIONARY_WATER, (byte) 2); } - trail = new TempBlock(sourceblock, Material.STATIONARY_WATER, (byte) 1); - sourceblock = block; - - if (location.distance(targetdestination) <= 1 || location.distance(firstdestination) > range) { + trail = new TempBlock(sourceBlock, Material.STATIONARY_WATER, (byte) 1); + sourceBlock = block; + if (location.distanceSquared(targetDestination) <= 1 || location.distanceSquared(firstDestination) > range * range) { falling = true; progressing = false; } - - return true; } } - - return false; - } - private void breakBlock() { - - // removeWater(oldwater); - finalRemoveWater(sourceblock); - remove(id); + private void redirect(Player player, Location targetlocation) { + if (progressing && !settingUp) { + if (location.distanceSquared(player.getLocation()) <= range * range) { + targetDirection = GeneralMethods.getDirection(location, targetlocation).normalize(); + } + targetDestination = targetlocation; + this.player = player; + } } private void reduceWater(Block block) { @@ -471,87 +331,162 @@ public class WaterManipulation { removeWater(block); return; } - if (affectedblocks.containsKey(block)) { + if (AFFECTED_BLOCKS.containsKey(block)) { if (!GeneralMethods.isAdjacentToThreeOrMoreSources(block)) { - // && !Methods.adjacentToAnyWater(block)) { block.setType(Material.AIR); - // block.setType(Material.WATER); - // block.setData(half); } - // oldwater = block; - affectedblocks.remove(block); + AFFECTED_BLOCKS.remove(block); } } private void removeWater(Block block) { if (block != null) { - if (affectedblocks.containsKey(block)) { + if (AFFECTED_BLOCKS.containsKey(block)) { if (!GeneralMethods.isAdjacentToThreeOrMoreSources(block)) { block.setType(Material.AIR); } - affectedblocks.remove(block); + AFFECTED_BLOCKS.remove(block); } } } - private void finalRemoveWater(Block block) { - if (trail != null) { - trail.revertBlock(); - trail = null; - } - if (trail2 != null) { - trail2.revertBlock(); - trail = null; - } - if (displacing) { - removeWater(block); - return; - } - if (affectedblocks.containsKey(block)) { - if (!GeneralMethods.isAdjacentToThreeOrMoreSources(block)) { - // && !Methods.adjacentToAnyWater(block)) { - block.setType(Material.AIR); - // block.setType(Material.WATER); - // block.setData(half); - } - affectedblocks.remove(block); - } - } - @SuppressWarnings("deprecation") private static void addWater(Block block) { - if (!affectedblocks.containsKey(block)) { - affectedblocks.put(block, block); + if (!AFFECTED_BLOCKS.containsKey(block)) { + AFFECTED_BLOCKS.put(block, block); } - if (FreezeMelt.frozenblocks.containsKey(block)) - FreezeMelt.frozenblocks.remove(block); - if (WaterMethods.isWater(block)) { - ParticleEffect.WATER_BUBBLE.display((float) Math.random(), (float) Math.random(), (float) Math.random(), 0f, 5, - block.getLocation().clone().add(.5, .5, .5), 257D); + if (PhaseChangeFreeze.getFrozenBlocks().containsKey(block)) { + PhaseChangeFreeze.getFrozenBlocks().remove(block); + } + if (isWater(block)) { + ParticleEffect.WATER_BUBBLE.display((float) Math.random(), (float) Math.random(), + (float) Math.random(), 0f, 5, block.getLocation().clone().add(.5,.5,.5), 257D); } block.setType(Material.STATIONARY_WATER); - block.setData(full); + block.setData((byte) 0); + } + + public static boolean annihilateBlasts(Location location, double radius, Player player) { + boolean broke = false; + for (WaterManipulation manip : CoreAbility.getAbilities(WaterManipulation.class)) { + if (manip.location.getWorld().equals(location.getWorld()) && !player.equals(manip.player)) { + if (manip.location.distanceSquared(location) <= radius * radius) { + manip.remove(); + broke = true; + } + } + } + return broke; + } + + private static void block(Player player) { + for (WaterManipulation manip : CoreAbility.getAbilities(player, WaterManipulation.class)) { + if (!manip.location.getWorld().equals(player.getWorld())) { + continue; + } else if (!manip.progressing) { + continue; + } else if (GeneralMethods.isRegionProtectedFromBuild(manip, manip.location)) { + continue; + } + + Location location = player.getEyeLocation(); + Vector vector = location.getDirection(); + Location mloc = manip.location; + if (mloc.distanceSquared(location) <= manip.range * manip.range + && GeneralMethods.getDistanceFromLine(vector, location, manip.location) < manip.deflectRange + && mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) { + manip.remove(); + } + } + } + + public static boolean canBubbleWater(Block block) { + return canPhysicsChange(block); + } + + public static boolean canFlowFromTo(Block from, Block to) { + if (AFFECTED_BLOCKS.containsKey(to) || AFFECTED_BLOCKS.containsKey(from)) { + return false; + } else if (WaterSpout.getAffectedBlocks().containsKey(to) || WaterSpout.getAffectedBlocks().containsKey(from)) { + return false; + } else if (SurgeWall.getAffectedBlocks().containsKey(to) || SurgeWall.getAffectedBlocks().containsKey(from)) { + return false; + } else if (SurgeWall.getWallBlocks().containsKey(to) || SurgeWall.getWallBlocks().containsKey(from)) { + return false; + } else if (SurgeWave.isBlockWave(to) || SurgeWave.isBlockWave(from)) { + return false; + } else if (TempBlock.isTempBlock(to) || TempBlock.isTempBlock(from)) { + return false; + } else if (isAdjacentToFrozenBlock(to) || isAdjacentToFrozenBlock(from)) { + return false; + } + return true; + } + + public static boolean canPhysicsChange(Block block) { + if (AFFECTED_BLOCKS.containsKey(block)) { + return false; + } else if (WaterSpout.getAffectedBlocks().containsKey(block)) { + return false; + } else if (SurgeWall.getAffectedBlocks().containsKey(block)) { + return false; + } else if (SurgeWall.getWallBlocks().containsKey(block)) { + return false; + } else if (SurgeWave.isBlockWave(block)) { + return false; + } else if (TempBlock.isTempBlock(block)) { + return false; + } else if (TempBlock.isTouchingTempBlock(block)) { + return false; + } + return true; + } + + private static Location getTargetLocation(Player player, double range) { + Location location; + Entity target = GeneralMethods.getTargetedEntity(player, range); + + if (target == null) { + location = GeneralMethods.getTargetedLocation(player, range, getTransparentMaterial()); + } else { + location = ((LivingEntity) target).getEyeLocation(); + } + return location; } @SuppressWarnings("deprecation") public static void moveWater(Player player) { - if (prepared.containsKey(player)) { - if (instances.containsKey(prepared.get(player))) { - instances.get(prepared.get(player)).moveWater(); - } - prepared.remove(player); - } else if (WaterReturn.hasWaterBottle(player)) { - Location eyeloc = player.getEyeLocation(); - Block block = eyeloc.add(eyeloc.getDirection().normalize()).getBlock(); - if (EarthMethods.isTransparentToEarthbending(player, block) - && EarthMethods.isTransparentToEarthbending(player, eyeloc.getBlock())) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + return; + } if (bPlayer.isOnCooldown("WaterManipulation")) { + redirectTargettedBlasts(player); + return; + } - if (getTargetLocation(player).distance(block.getLocation()) > 1) { + boolean handledPrepare = false; + double range = 25; + for (WaterManipulation waterManip : CoreAbility.getAbilities(player, WaterManipulation.class)) { + range = waterManip.range; + if (waterManip.prepared) { + waterManip.prepared = false; + handledPrepare = true; + waterManip.moveWater(); + } + } + + if (!handledPrepare && WaterReturn.hasWaterBottle(player)) { + Location eyeLoc = player.getEyeLocation(); + Block block = eyeLoc.add(eyeLoc.getDirection().normalize()).getBlock(); + + if (isTransparentToEarthbending(player, block) && isTransparentToEarthbending(player, eyeLoc.getBlock())) { + if (getTargetLocation(player, range).distanceSquared(block.getLocation()) > 1) { block.setType(Material.WATER); - block.setData(full); - WaterManipulation watermanip = new WaterManipulation(player); - watermanip.moveWater(); - if (!watermanip.progressing) { + block.setData((byte) 0); + + WaterManipulation waterManip = new WaterManipulation(player); + waterManip.moveWater(); + if (!waterManip.progressing) { block.setType(Material.AIR); } else { WaterReturn.emptyWaterBottle(player); @@ -559,180 +494,142 @@ public class WaterManipulation { } } } - redirectTargettedBlasts(player); } private static void redirectTargettedBlasts(Player player) { - for (int id : instances.keySet()) { - WaterManipulation manip = instances.get(id); - - if (!manip.progressing) + for (WaterManipulation manip : CoreAbility.getAbilities(WaterManipulation.class)) { + if (!manip.progressing) { continue; - - if (!manip.location.getWorld().equals(player.getWorld())) + } else if (!manip.location.getWorld().equals(player.getWorld())) { continue; - - if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", manip.location)) + } else if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", manip.location)) { continue; + } - if (manip.player.equals(player)) - manip.redirect(player, getTargetLocation(player)); + if (manip.player.equals(player)) { + manip.redirect(player, getTargetLocation(player, manip.range)); + } Location location = player.getEyeLocation(); Vector vector = location.getDirection(); Location mloc = manip.location; - if (mloc.distance(location) <= manip.range - && GeneralMethods.getDistanceFromLine(vector, location, manip.location) < deflectrange - && mloc.distance(location.clone().add(vector)) < mloc - .distance(location.clone().add(vector.clone().multiply(-1)))) { - manip.redirect(player, getTargetLocation(player)); + if (mloc.distanceSquared(location) <= manip.range * manip.range + && GeneralMethods.getDistanceFromLine(vector, location, manip.location) < manip.deflectRange + && mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) { + manip.redirect(player, getTargetLocation(player, manip.range)); } - } } - private static void block(Player player) { - for (int id : instances.keySet()) { - WaterManipulation manip = instances.get(id); - - if (manip.player.equals(player)) - continue; - - if (!manip.location.getWorld().equals(player.getWorld())) - continue; - - if (!manip.progressing) - continue; - - if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", manip.location)) - continue; - - Location location = player.getEyeLocation(); - Vector vector = location.getDirection(); - Location mloc = manip.location; - if (mloc.distance(location) <= manip.range - && GeneralMethods.getDistanceFromLine(vector, location, manip.location) < deflectrange - && mloc.distance(location.clone().add(vector)) < mloc - .distance(location.clone().add(vector.clone().multiply(-1)))) { - manip.breakBlock(); - } - - } - } - - public static boolean progress(int ID) { - if (instances.containsKey(ID)) - return instances.get(ID).progress(); - return false; - } - - public static boolean canFlowFromTo(Block from, Block to) { - // if (to.getType() == Material.TORCH) - // return true; - if (affectedblocks.containsKey(to) || affectedblocks.containsKey(from)) { - // Methods.verbose("affectedblocks"); - return false; - } - if (WaterSpout.affectedblocks.containsKey(to) || WaterSpout.affectedblocks.containsKey(from)) { - // Methods.verbose("waterspout"); - return false; - } - if (WaterWall.affectedblocks.containsKey(to) || WaterWall.affectedblocks.containsKey(from)) { - // Methods.verbose("waterwallaffectedblocks"); - return false; - } - if (WaterWall.wallblocks.containsKey(to) || WaterWall.wallblocks.containsKey(from)) { - // Methods.verbose("waterwallwall"); - return false; - } - if (Wave.isBlockWave(to) || Wave.isBlockWave(from)) { - // Methods.verbose("wave"); - return false; - } - if (TempBlock.isTempBlock(to) || TempBlock.isTempBlock(from)) { - // Methods.verbose("tempblock"); - return false; - } - if (WaterMethods.isAdjacentToFrozenBlock(to) || WaterMethods.isAdjacentToFrozenBlock(from)) { - // Methods.verbose("frozen"); - return false; - } - - return true; - } - - public static boolean canPhysicsChange(Block block) { - if (affectedblocks.containsKey(block)) - return false; - if (WaterSpout.affectedblocks.containsKey(block)) - return false; - if (WaterWall.affectedblocks.containsKey(block)) - return false; - if (WaterWall.wallblocks.containsKey(block)) - return false; - if (Wave.isBlockWave(block)) - return false; - if (TempBlock.isTempBlock(block)) - return false; - if (TempBlock.isTouchingTempBlock(block)) - return false; - return true; - } - - public static void removeAll() { - for (int id : instances.keySet()) - instances.get(id).breakBlock(); - prepared.clear(); - } - - public static boolean canBubbleWater(Block block) { - return canPhysicsChange(block); + @Override + public void remove() { + super.remove(); + finalRemoveWater(sourceBlock); } public static void removeAroundPoint(Location location, double radius) { - for (int id : instances.keySet()) { - WaterManipulation manip = instances.get(id); - if (manip.location.getWorld().equals(location.getWorld())) - if (manip.location.distance(location) <= radius) - manip.breakBlock(); - } - } - - public static ArrayList getAroundPoint(Location location, double radius) { - ArrayList list = new ArrayList(); - for (int id : instances.keySet()) { - WaterManipulation manip = instances.get(id); - if (manip.location.getWorld().equals(location.getWorld())) - if (manip.location.distance(location) <= radius) - list.add(manip); - } - return list; - } - - public static boolean annihilateBlasts(Location location, double radius, Player source) { - boolean broke = false; - for (int id : instances.keySet()) { - WaterManipulation manip = instances.get(id); - if (manip.location.getWorld().equals(location.getWorld()) && !source.equals(manip.player)) - if (manip.location.distance(location) <= radius) { - manip.breakBlock(); - broke = true; + for (WaterManipulation manip : CoreAbility.getAbilities(WaterManipulation.class)) { + if (manip.location.getWorld().equals(location.getWorld())) { + if (manip.location.distanceSquared(location) <= radius * radius) { + manip.remove(); } + } } - return broke; } - public Player getPlayer() { - return player; + @Override + public String getName() { + return "WaterManipulation"; } - public double getDamage() { - return damage; + @Override + public Location getLocation() { + if (location != null) { + return location; + } else if (sourceBlock != null) { + return sourceBlock.getLocation(); + } + return null; } - public void setDamage(double damage) { - this.damage = damage; + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public boolean isProgressing() { + return progressing; + } + + public void setProgressing(boolean progressing) { + this.progressing = progressing; + } + + public boolean isFalling() { + return falling; + } + + public void setFalling(boolean falling) { + this.falling = falling; + } + + public boolean isSettingUp() { + return settingUp; + } + + public void setSettingUp(boolean settingUp) { + this.settingUp = settingUp; + } + + public boolean isDisplacing() { + return displacing; + } + + public void setDisplacing(boolean displacing) { + this.displacing = displacing; + } + + public boolean isPrepared() { + return prepared; + } + + public void setPrepared(boolean prepared) { + this.prepared = prepared; + } + + public int getDispelRange() { + return dispelRange; + } + + public void setDispelRange(int dispelRange) { + this.dispelRange = dispelRange; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; } public double getRange() { @@ -743,23 +640,108 @@ public class WaterManipulation { this.range = range; } - public double getPushfactor() { - return pushfactor; + public double getPushFactor() { + return pushFactor; } - public void setPushfactor(double pushfactor) { - this.pushfactor = pushfactor; + public void setPushFactor(double pushFactor) { + this.pushFactor = pushFactor; } - public long getCooldown() { - return cooldown; + public double getDamage() { + return damage; + } + + public void setDamage(double damage) { + this.damage = damage; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public double getDeflectRange() { + return deflectRange; + } + + public void setDeflectRange(double deflectRange) { + this.deflectRange = deflectRange; + } + + public Block getSourceBlock() { + return sourceBlock; + } + + public void setSourceBlock(Block sourceBlock) { + this.sourceBlock = sourceBlock; + } + + public TempBlock getTrail() { + return trail; + } + + public void setTrail(TempBlock trail) { + this.trail = trail; + } + + public TempBlock getTrail2() { + return trail2; + } + + public void setTrail2(TempBlock trail2) { + this.trail2 = trail2; + } + + public Location getFirstDestination() { + return firstDestination; + } + + public void setFirstDestination(Location firstDestination) { + this.firstDestination = firstDestination; + } + + public Location getTargetDestination() { + return targetDestination; + } + + public void setTargetDestination(Location targetDestination) { + this.targetDestination = targetDestination; + } + + public Vector getFirstDirection() { + return firstDirection; + } + + public void setFirstDirection(Vector firstDirection) { + this.firstDirection = firstDirection; + } + + public Vector getTargetDirection() { + return targetDirection; + } + + public void setTargetDirection(Vector targetDirection) { + this.targetDirection = targetDirection; + } + + public static ConcurrentHashMap getAffectedBlocks() { + return AFFECTED_BLOCKS; + } + + public HashSet getWaterTypes() { + return waterTypes; } public void setCooldown(long cooldown) { this.cooldown = cooldown; - if (player != null) - GeneralMethods.getBendingPlayer(player.getName()).addCooldown("WaterManipulation", cooldown); - } -} \ No newline at end of file + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterMethods.java b/src/com/projectkorra/projectkorra/waterbending/WaterMethods.java deleted file mode 100644 index a2fde826..00000000 --- a/src/com/projectkorra/projectkorra/waterbending/WaterMethods.java +++ /dev/null @@ -1,460 +0,0 @@ -package com.projectkorra.projectkorra.waterbending; - -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AbilityModuleManager; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.chiblocking.ChiMethods; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.TempBlock; -import com.projectkorra.rpg.RPGMethods; -import com.projectkorra.rpg.event.EventManager; - -import org.bukkit.ChatColor; -import org.bukkit.Effect; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.World; -import org.bukkit.World.Environment; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class WaterMethods { - - static ProjectKorra plugin; - private static FileConfiguration config = ProjectKorra.plugin.getConfig(); - private static Integer[] plantIds = { 6, 18, 31, 37, 38, 39, 40, 59, 81, 83, 86, 99, 100, 103, 104, 105, 106, 111, 161, 175 }; - - public WaterMethods(ProjectKorra plugin) { - WaterMethods.plugin = plugin; - } - - /** - * Checks to see if a Player is effected by BloodBending. - * - * @param player The player to check - * @return true If {@link ChiMethods#isChiBlocked(String)} is true
- * false If player is BloodBender and Bending is toggled on, or if - * player is in AvatarState - */ - public static boolean canBeBloodbent(Player player) { - if (AvatarState.isAvatarState(player)) - if (ChiMethods.isChiBlocked(player.getName())) - return true; - if (GeneralMethods.canBend(player.getName(), "Bloodbending") && !GeneralMethods.getBendingPlayer(player.getName()).isToggled()) - return false; - return true; - } - - /** - * Checks to see if a player can BloodBend. - * - * @param player The player to check - * @return true If player has permission node "bending.earth.bloodbending" - */ - public static boolean canBloodbend(Player player) { - if (player.hasPermission("bending.water.bloodbending")) - return true; - return false; - } - - public static boolean canBloodbendAtAnytime(Player player) { - if (canBloodbend(player) && player.hasPermission("bending.water.bloodbending.anytime")) - return true; - return false; - } - - public static boolean canIcebend(Player player) { - if (player.hasPermission("bending.water.icebending")) - return true; - return false; - } - - public static boolean canWaterHeal(Player player) { - if (player.hasPermission("bending.water.healing")) - return true; - return false; - } - - /** - * Checks to see if a player can PlantBend. - * - * @param player The player to check - * @return true If player has permission node "bending.ability.plantbending" - */ - public static boolean canPlantbend(Player player) { - return player.hasPermission("bending.water.plantbending"); - } - - public static double getWaterbendingNightAugment(World world) { - if (GeneralMethods.hasRPG()) { - if (isNight(world)) { - if (EventManager.marker.get(world).equalsIgnoreCase("LunarEclipse")) { - return RPGMethods.getFactor("LunarEclipse"); - } else if (EventManager.marker.get(world).equalsIgnoreCase("FullMoon")) { - return RPGMethods.getFactor("FullMoon"); - } - return config.getDouble("Properties.Water.NightFactor"); - } else { - return 1; - } - } else { - if (isNight(world)) - return config.getDouble("Properties.Water.NightFactor"); - return 1; - } - } - - /** - * Gets the WaterColor from the config. - * - * @return Config specified ChatColor - */ - public static ChatColor getWaterColor() { - return ChatColor.valueOf(config.getString("Properties.Chat.Colors.Water")); - } - - /** - * Gets the WaterSubColor from the config. - * - * @return Config specified ChatColor - */ - public static ChatColor getWaterSubColor() { - return ChatColor.valueOf(config.getString("Properties.Chat.Colors.WaterSub")); - } - - /** - * Finds a valid Water source for a Player. To use dynamic source selection, - * use BlockSource.getWaterSourceBlock() instead of this method. Dynamic - * source selection saves the user's previous source for future use. - * {@link BlockSource#getWaterSourceBlock(Player, double)} - * - * @param player the player that is attempting to Waterbend. - * @param range the maximum block selection range. - * @param plantbending true if the player can bend plants. - * @return a valid Water source block, or null if one could not be found. - */ - @SuppressWarnings("deprecation") - public static Block getWaterSourceBlock(Player player, int range, boolean water, boolean ice, boolean plant) { - Location location = player.getEyeLocation(); - Vector vector = location.getDirection().clone().normalize(); - for (double i = 0; i <= range; i++) { - Block block = location.clone().add(vector.clone().multiply(i)).getBlock(); - if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", location)) - continue; - if (isWater(block) && block.getData() == 0x0 && water) { - if (TempBlock.isTempBlock(block)) { - TempBlock tb = TempBlock.get(block); - byte full = 0x0; - if (tb.getState().getRawData() != full && (tb.getState().getType() != Material.WATER || tb.getState().getType() != Material.STATIONARY_WATER)) { - continue; - } - } - return block; - } - if (isIcebendable(block) && ice) { - return block; - } - if (isPlant(block) && plant) { - return block; - } - } - return null; - } - - /** - * Returns a random block within a radius of a location. - * @param location - * @param radius - * @return random block - */ - @SuppressWarnings("deprecation") - public static Block getRandomWaterBlock(Player player, Location location, int radius, boolean water, boolean ice, boolean plant) { - List checked = new ArrayList(); - List blocks = GeneralMethods.getBlocksAroundPoint(location, radius); - for (int i = 0; i < blocks.size(); i++) { - int index = GeneralMethods.rand.nextInt(blocks.size()); - while (checked.contains(index)) { - index = GeneralMethods.rand.nextInt(blocks.size()); - } - checked.add(index); - Block block = blocks.get(index); - if (block.getRelative(BlockFace.UP).getType() == Material.AIR) { - if (isWater(block) && block.getState().getRawData() == 0x0 && water) { - BlockSource.randomBlocks.add(block); - return block; - } - if (isIcebendable(block) && ice) { - BlockSource.randomBlocks.add(block); - return block; - } - if (isPlant(block) && plant) { - BlockSource.randomBlocks.add(block); - return block; - } - } - } - return null; - } - - public static boolean isAdjacentToFrozenBlock(Block block) { - BlockFace[] faces = { BlockFace.DOWN, BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.WEST, BlockFace.SOUTH }; - boolean adjacent = false; - for (BlockFace face : faces) { - if (FreezeMelt.frozenblocks.containsKey((block.getRelative(face)))) - adjacent = true; - } - - return adjacent; - } - - public static boolean isHealingAbility(String ability) { - return AbilityModuleManager.healingabilities.contains(ability); - } - - public static boolean isIcebendingAbility(String ability) { - return AbilityModuleManager.iceabilities.contains(ability); - } - - public static boolean isPlantbendingAbility(String ability) { - return AbilityModuleManager.plantabilities.contains(ability); - } - - public static boolean isBloodbendingAbility(String ability) { - return AbilityModuleManager.bloodabilities.contains(ability); - } - - public static boolean isFullMoon(World world) { - long days = world.getFullTime() / 24000; - long phase = days % 8; - if (phase == 0) { - return true; - } - return false; - } - - public static boolean isMeltable(Block block) { - if (block.getType() == Material.ICE || block.getType() == Material.SNOW) { - return true; - } - return false; - } - - public static boolean isNight(World world) { - if (world.getEnvironment() == Environment.NETHER || world.getEnvironment() == Environment.THE_END) { - return false; - } - - long time = world.getTime(); - if (time >= 12950 && time <= 23050) { - return true; - } - return false; - } - - @SuppressWarnings("deprecation") - public static boolean isPlant(Block block) { - if (block == null) { - return false; - } - if (Arrays.asList(plantIds).contains(block.getTypeId())) { - return true; - } - return false; - } - - public static boolean isWater(Block block) { - if (block.getType() == Material.WATER || block.getType() == Material.STATIONARY_WATER) - return true; - return false; - } - - public static boolean isWaterAbility(String ability) { - return AbilityModuleManager.waterbendingabilities.contains(ability); - } - - @SuppressWarnings("deprecation") - public static boolean isWaterbendable(Block block, Player player) { - byte full = 0x0; - if (TempBlock.isTempBlock(block)) - return false; - if ((block.getType() == Material.WATER || block.getType() == Material.STATIONARY_WATER) && block.getData() == full) - return true; - if (block.getType() == Material.ICE || block.getType() == Material.SNOW) - return true; - if (block.getType() == Material.PACKED_ICE && plugin.getConfig().getBoolean("Properties.Water.CanBendPackedIce")) - return true; - if (canPlantbend(player) && isPlant(block)) - return true; - return false; - } - - public static boolean isIcebendable(Block block) { - if (block.getType() == Material.ICE || block.getType() == Material.SNOW) - return true; - if (block.getType() == Material.PACKED_ICE && plugin.getConfig().getBoolean("Properties.Water.CanBendPackedIce")) - return true; - return false; - } - - public static boolean isPlantbendable(Block block, boolean leavesOnly) { - if (block.getType() == Material.LEAVES) - return true; - if (block.getType() == Material.LEAVES_2) - return true; - if (isPlant(block) && !leavesOnly) - return true; - return false; - } - - public static boolean isPlantbendable(Block block) { - return WaterMethods.isPlantbendable(block, false); - } - - public static void playFocusWaterEffect(Block block) { - block.getWorld().playEffect(block.getLocation(), Effect.SMOKE, 4, 20); - } - - /** - * Removes all water spouts in a location within a certain radius. - * - * @param loc The location to use - * @param radius The radius around the location to remove spouts in - * @param source The player causing the removal - */ - public static void removeWaterSpouts(Location loc, double radius, Player source) { - WaterSpout.removeSpouts(loc, radius, source); - } - - /** - * Removes all water spouts in a location with a radius of 1.5. - * - * @param loc The location to use - * @param source The player causing the removal - */ - public static void removeWaterSpouts(Location loc, Player source) { - removeWaterSpouts(loc, 1.5, source); - } - - public static double waterbendingNightAugment(double factor, World world) { - if (GeneralMethods.hasRPG()) { - if (isNight(world)) { - if (EventManager.marker.get(world).equalsIgnoreCase("LunarEclipse")) { - return RPGMethods.getFactor("LunarEclipse") * factor; - } else if (EventManager.marker.get(world).equalsIgnoreCase("FullMoon")) { - return RPGMethods.getFactor("FullMoon") * factor; - } - return config.getDouble("Properties.Water.NightFactor") * factor; - } else { - return 1 * factor; - } - } else { - if (isNight(world)) - return config.getDouble("Properties.Water.NightFactor") * factor; - return 1 * factor; - } - } - - public static boolean isNegativeEffect(PotionEffectType effect) { - if (effect.equals(PotionEffectType.POISON)) - return true; - if (effect.equals(PotionEffectType.BLINDNESS)) - return true; - if (effect.equals(PotionEffectType.CONFUSION)) - return true; - if (effect.equals(PotionEffectType.HARM)) - return true; - if (effect.equals(PotionEffectType.HUNGER)) - return true; - if (effect.equals(PotionEffectType.SLOW)) - return true; - if (effect.equals(PotionEffectType.SLOW_DIGGING)) - return true; - if (effect.equals(PotionEffectType.WEAKNESS)) - return true; - if (effect.equals(PotionEffectType.WITHER)) - return true; - return false; - } - - public static boolean isPositiveEffect(PotionEffectType effect) { - if (effect.equals(PotionEffectType.ABSORPTION)) - return true; - if (effect.equals(PotionEffectType.DAMAGE_RESISTANCE)) - return true; - if (effect.equals(PotionEffectType.FAST_DIGGING)) - return true; - if (effect.equals(PotionEffectType.FIRE_RESISTANCE)) - return true; - if (effect.equals(PotionEffectType.HEAL)) - return true; - if (effect.equals(PotionEffectType.HEALTH_BOOST)) - return true; - if (effect.equals(PotionEffectType.INCREASE_DAMAGE)) - return true; - if (effect.equals(PotionEffectType.JUMP)) - return true; - if (effect.equals(PotionEffectType.NIGHT_VISION)) - return true; - if (effect.equals(PotionEffectType.REGENERATION)) - return true; - if (effect.equals(PotionEffectType.SATURATION)) - return true; - if (effect.equals(PotionEffectType.SPEED)) - return true; - if (effect.equals(PotionEffectType.WATER_BREATHING)) - return true; - return false; - } - - public static boolean isNeutralEffect(PotionEffectType effect) { - if (effect.equals(PotionEffectType.INVISIBILITY)) - return true; - return false; - } - - public static void playWaterbendingSound(Location loc) { - if (plugin.getConfig().getBoolean("Properties.Water.PlaySound")) { - loc.getWorld().playSound(loc, Sound.WATER, 1, 10); - } - } - - public static void playIcebendingSound(Location loc) { - if (plugin.getConfig().getBoolean("Properties.Water.PlaySound")) { - loc.getWorld().playSound(loc, Sound.FIRE_IGNITE, 2, 10); - } - } - - public static void playPlantbendingSound(Location loc) { - if (plugin.getConfig().getBoolean("Properties.Water.PlaySound")) { - loc.getWorld().playSound(loc, Sound.STEP_GRASS, 1, 10); - } - } - - public static void stopBending() { - FreezeMelt.removeAll(); - IceSpike.removeAll(); - IceSpike2.removeAll(); - WaterManipulation.removeAll(); - WaterSpout.removeAll(); - WaterWall.removeAll(); - Wave.removeAll(); - Plantbending.regrowAll(); - OctopusForm.removeAll(); - Bloodbending.instances.clear(); - WaterWave.removeAll(); - WaterCombo.removeAll(); - WaterReturn.removeAll(); - WaterArms.removeAll(); - PlantArmor.removeAll(); - } -} diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterPassive.java b/src/com/projectkorra/projectkorra/waterbending/WaterPassive.java index 6ad42bd2..e8bc95f7 100644 --- a/src/com/projectkorra/projectkorra/waterbending/WaterPassive.java +++ b/src/com/projectkorra/projectkorra/waterbending/WaterPassive.java @@ -1,9 +1,10 @@ package com.projectkorra.projectkorra.waterbending; +import com.projectkorra.projectkorra.BendingPlayer; import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AbilityModuleManager; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.configuration.ConfigManager; import com.projectkorra.projectkorra.earthbending.EarthArmor; import com.projectkorra.projectkorra.util.TempBlock; @@ -15,44 +16,45 @@ import org.bukkit.entity.Player; public class WaterPassive { - private static double swimFactor = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.Passive.SwimSpeedFactor"); - public static boolean applyNoFall(Player player) { Block block = player.getLocation().getBlock(); - Block fallblock = block.getRelative(BlockFace.DOWN); - if (TempBlock.isTempBlock(fallblock) && (fallblock.getType().equals(Material.ICE))) + Block fallBlock = block.getRelative(BlockFace.DOWN); + if (TempBlock.isTempBlock(fallBlock) && (fallBlock.getType().equals(Material.ICE))) { return true; - if (WaterMethods.isWaterbendable(block, player) && !WaterMethods.isPlant(block)) + } else if (WaterAbility.isWaterbendable(block, player) && !WaterAbility.isPlant(block)) { return true; - if (fallblock.getType() == Material.AIR) + } else if (fallBlock.getType() == Material.AIR) { return true; - if ((WaterMethods.isWaterbendable(fallblock, player) && !WaterMethods.isPlant(fallblock)) || fallblock.getType() == Material.SNOW_BLOCK) + } else if ((WaterAbility.isWaterbendable(fallBlock, player) && !WaterAbility.isPlant(fallBlock)) || fallBlock.getType() == Material.SNOW_BLOCK) { return true; + } return false; } public static void handlePassive() { + double swimSpeed = getSwimSpeed(); + for (Player player : Bukkit.getServer().getOnlinePlayers()) { - String ability = GeneralMethods.getBoundAbility(player); - if (GeneralMethods.canBendPassive(player.getName(), Element.Water)) { - if (WaterSpout.instances.containsKey(player) || EarthArmor.instances.containsKey(player)) { + BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); + if (bPlayer == null) { + continue; + } + + String ability = bPlayer.getBoundAbilityName(); + CoreAbility coreAbil = CoreAbility.getAbility(ability); + if (bPlayer.canBendPassive(Element.WATER)) { + if (CoreAbility.hasAbility(player, WaterSpout.class) || CoreAbility.hasAbility(player, EarthArmor.class)) { continue; - } else if (ability == null || !AbilityModuleManager.shiftabilities.contains(ability)) { - if (player.isSneaking() && WaterMethods.isWater(player.getLocation().getBlock())) { - player.setVelocity(player.getEyeLocation().getDirection().clone().normalize().multiply(swimFactor)); + } else if (coreAbil == null || (coreAbil != null && !coreAbil.isSneakAbility())) { + if (player.isSneaking() && WaterAbility.isWater(player.getLocation().getBlock())) { + player.setVelocity(player.getEyeLocation().getDirection().clone().normalize().multiply(swimSpeed)); } } - -// if (player.getLocation().getBlock().isLiquid()) { -// for (Block block : GeneralMethods.getBlocksAroundPoint(player.getLocation(), 2)) { -// if (GeneralMethods.isAdjacentToThreeOrMoreSources(block) && WaterMethods.isWater(block)) { -// byte full = 0x0; -// block.setType(Material.WATER); -// block.setData(full); -// } -// } -// } } } } + + public static double getSwimSpeed() { + return ConfigManager.getConfig().getDouble("Abilities.Water.Passive.SwimSpeedFactor"); + } } diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterReturn.java b/src/com/projectkorra/projectkorra/waterbending/WaterReturn.java index 60c0b9c4..83b36274 100644 --- a/src/com/projectkorra/projectkorra/waterbending/WaterReturn.java +++ b/src/com/projectkorra/projectkorra/waterbending/WaterReturn.java @@ -1,7 +1,8 @@ package com.projectkorra.projectkorra.waterbending; import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.earthbending.EarthMethods; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; import com.projectkorra.projectkorra.util.TempBlock; import org.bukkit.Location; @@ -13,92 +14,70 @@ import org.bukkit.inventory.PlayerInventory; import org.bukkit.util.Vector; import java.util.HashMap; -import java.util.concurrent.ConcurrentHashMap; -public class WaterReturn { +public class WaterReturn extends WaterAbility { - private static ConcurrentHashMap instances = new ConcurrentHashMap(); - // private static int ID = Integer.MIN_VALUE; - private static long interval = 50; - private static double range = 30; - - private static final byte full = 0x0; - - private Player player; - // private int id; + private long time; + private long interval; + private double range; private Location location; private TempBlock block; - private long time; - + public WaterReturn(Player player, Block block) { - if (instances.containsKey(player)) + super(player); + if (CoreAbility.hasAbility(player, WaterReturn.class)) { return; - this.player = player; - location = block.getLocation(); - if (GeneralMethods.canBend(player.getName(), "WaterManipulation")) { - if (!GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", location) && GeneralMethods.canBend(player.getName(), "WaterManipulation")) { - if (EarthMethods.isTransparentToEarthbending(player, block) && !block.isLiquid() && hasEmptyWaterBottle()) - this.block = new TempBlock(block, Material.WATER, full); + } + + this.location = block.getLocation(); + this.range = 30; + this.interval = 50; + + this.range = getNightFactor(range); + + if (bPlayer.canBend(this)) { + if (isTransparentToEarthbending(player, block) && !block.isLiquid() && hasEmptyWaterBottle()) { + this.block = new TempBlock(block, Material.WATER, (byte) 0); } } - // if (ID >= Integer.MAX_VALUE) { - // ID = Integer.MIN_VALUE; - // } - // id = ID++; - instances.put(player, this); + start(); } - private void progress() { - if (!hasEmptyWaterBottle()) { + @Override + public void progress() { + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { remove(); return; - } - - if (player.isDead() || !player.isOnline()) { + } else if (!hasEmptyWaterBottle()) { remove(); return; - } - - if (!player.getWorld().equals(location.getWorld())) { - remove(); + } else if (System.currentTimeMillis() < time + interval) { return; } - if (System.currentTimeMillis() < time + interval) - return; - - time = System.currentTimeMillis(); - Vector direction = GeneralMethods.getDirection(location, player.getEyeLocation()).normalize(); + time = System.currentTimeMillis(); location = location.clone().add(direction); if (location == null || block == null) { remove(); return; + } else if (location.getBlock().equals(block.getLocation().getBlock())) { + return; } - if (location.getBlock().equals(block.getLocation().getBlock())) - return; - - if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", location)) { + if (location.distanceSquared(player.getEyeLocation()) > range * range) { remove(); return; - } - - if (location.distance(player.getEyeLocation()) > WaterMethods.waterbendingNightAugment(range, player.getWorld())) { - remove(); - return; - } - - if (location.distance(player.getEyeLocation()) <= 1.5) { + } else if (location.distanceSquared(player.getEyeLocation()) <= 1.5 * 1.5) { fillBottle(); return; } Block newblock = location.getBlock(); - if (EarthMethods.isTransparentToEarthbending(player, newblock) && !newblock.isLiquid()) { + if (isTransparentToEarthbending(player, newblock) && !newblock.isLiquid()) { block.revertBlock(); - block = new TempBlock(newblock, Material.WATER, full); + block = new TempBlock(newblock, Material.WATER, (byte) 0); } else { remove(); return; @@ -106,12 +85,12 @@ public class WaterReturn { } - private void remove() { + @Override + public void remove() { + super.remove(); if (block != null) { block.revertBlock(); - block = null; } - instances.remove(player); } private boolean hasEmptyWaterBottle() { @@ -127,6 +106,7 @@ public class WaterReturn { if (inventory.contains(Material.GLASS_BOTTLE)) { int index = inventory.first(Material.GLASS_BOTTLE); ItemStack item = inventory.getItem(index); + if (item.getAmount() == 1) { inventory.setItem(index, new ItemStack(Material.POTION)); } else { @@ -138,40 +118,25 @@ public class WaterReturn { } } } - remove(); } private static boolean isBending(Player player) { - for (int id : WaterManipulation.instances.keySet()) { - if (WaterManipulation.instances.get(id).player.equals(player)) - return true; - } - - if (OctopusForm.instances.containsKey(player)) + if (CoreAbility.hasAbility(player, WaterManipulation.class) + || CoreAbility.hasAbility(player, WaterManipulation.class) + || CoreAbility.hasAbility(player, OctopusForm.class) + || CoreAbility.hasAbility(player, SurgeWave.class) + || CoreAbility.hasAbility(player, SurgeWall.class) + || CoreAbility.hasAbility(player, IceSpikeBlast.class)) { return true; - - for (int id : Wave.instances.keySet()) { - if (Wave.instances.get(id).player.equals(player)) - return true; } - - for (int id : WaterWall.instances.keySet()) { - if (WaterWall.instances.get(id).player.equals(player)) - return true; - } - - if (IceSpike2.isBending(player)) - return true; - return false; } public static boolean hasWaterBottle(Player player) { - if (instances.containsKey(player)) - return false; - if (isBending(player)) + if (CoreAbility.hasAbility(player, WaterReturn.class) || isBending(player)) { return false; + } PlayerInventory inventory = player.getInventory(); return (inventory.contains(new ItemStack(Material.POTION), 1)); } @@ -179,6 +144,7 @@ public class WaterReturn { public static void emptyWaterBottle(Player player) { PlayerInventory inventory = player.getInventory(); int index = inventory.first(new ItemStack(Material.POTION)); + if (index != -1) { ItemStack item = inventory.getItem(index); if (item.getAmount() == 1) { @@ -187,6 +153,7 @@ public class WaterReturn { item.setAmount(item.getAmount() - 1); inventory.setItem(index, item); HashMap leftover = inventory.addItem(new ItemStack(Material.GLASS_BOTTLE)); + for (int left : leftover.keySet()) { player.getWorld().dropItemNaturally(player.getLocation(), leftover.get(left)); } @@ -194,19 +161,70 @@ public class WaterReturn { } } - public static void progressAll() { - for (Player player : instances.keySet()) { - instances.get(player).progress(); - } + public long getTime() { + return time; } - public static void removeAll() { - for (Player player : instances.keySet()) { - WaterReturn wr = instances.get(player); - if (wr.block != null) - wr.block.revertBlock(); - } - instances.clear(); + public void setTime(long time) { + this.time = time; } + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + @Override + public Location getLocation() { + return location; + } + + @Override + public boolean isSneakAbility() { + return false; + } + + @Override + public boolean isHarmlessAbility() { + return true; + } + + public void setLocation(Location location) { + this.location = location; + } + + public TempBlock getBlock() { + return block; + } + + public void setBlock(TempBlock block) { + this.block = block; + } + + @Override + public String getName() { + return "WaterReturn"; + } + + @Override + public long getCooldown() { + return 0; + } + + @Override + public boolean isHiddenAbility() { + return true; + } + } diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterSourceGrabber.java b/src/com/projectkorra/projectkorra/waterbending/WaterSourceGrabber.java index 627827a5..ac29e9c2 100644 --- a/src/com/projectkorra/projectkorra/waterbending/WaterSourceGrabber.java +++ b/src/com/projectkorra/projectkorra/waterbending/WaterSourceGrabber.java @@ -1,6 +1,7 @@ package com.projectkorra.projectkorra.waterbending; import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ability.WaterAbility; import com.projectkorra.projectkorra.util.TempBlock; import org.bukkit.Location; @@ -14,6 +15,7 @@ import java.util.HashSet; import java.util.concurrent.ConcurrentHashMap; public class WaterSourceGrabber { + /* * Using an initial WaterSource block, this class animates the block up to a * specific height and then toward the players location. @@ -23,59 +25,62 @@ public class WaterSourceGrabber { } private Player player; + private byte data; + private double animimationSpeed; private AnimationState state; - @SuppressWarnings("unused") - private Location origin, currentLoc; - private double animSpeed; - private Material mat; - private Byte data; - private ConcurrentHashMap affectedBlocks = new ConcurrentHashMap(); - - public WaterSourceGrabber(Player player, Location origin, double animSpeed) { - this.player = player; - this.origin = origin; - this.animSpeed = animSpeed; - this.mat = Material.STATIONARY_WATER; - this.data = 0x00; - this.currentLoc = origin.clone(); - this.state = AnimationState.RISING; - } + private Material material; + private Location currentLoc; + private ConcurrentHashMap affectedBlocks; public WaterSourceGrabber(Player player, Location origin) { this(player, origin, 1); } + + public WaterSourceGrabber(Player player, Location origin, double animationSpeed) { + this.player = player; + this.animimationSpeed = animationSpeed; + this.material = Material.STATIONARY_WATER; + this.data = 0; + this.currentLoc = origin.clone(); + this.state = AnimationState.RISING; + this.affectedBlocks = new ConcurrentHashMap<>(); + } public void progress() { - if (state == AnimationState.FAILED || state == AnimationState.FINISHED) + if (state == AnimationState.FAILED || state == AnimationState.FINISHED) { return; - - if (state == AnimationState.RISING) { + } else if (state == AnimationState.RISING) { revertBlocks(); double locDiff = player.getEyeLocation().getY() - currentLoc.getY(); - currentLoc.add(0, animSpeed * Math.signum(locDiff), 0); + currentLoc.add(0, animimationSpeed * Math.signum(locDiff), 0); Block block = currentLoc.getBlock(); - if (!(WaterMethods.isWaterbendable(block, player) || block.getType() == Material.AIR) || GeneralMethods.isRegionProtectedFromBuild(player, "WaterSpout", block.getLocation())) { + + if (!(WaterAbility.isWaterbendable(block, player) || block.getType() == Material.AIR) + || GeneralMethods.isRegionProtectedFromBuild(player, "WaterSpout", block.getLocation())) { remove(); return; } - createBlock(block, mat, data); - if (Math.abs(locDiff) < 1) + + createBlock(block, material, data); + if (Math.abs(locDiff) < 1) { state = AnimationState.TOWARD; + } } else { revertBlocks(); Location eyeLoc = player.getTargetBlock((HashSet) null, 2).getLocation(); eyeLoc.setY(player.getEyeLocation().getY()); Vector vec = GeneralMethods.getDirection(currentLoc, eyeLoc); - currentLoc.add(vec.normalize().multiply(animSpeed)); + currentLoc.add(vec.normalize().multiply(animimationSpeed)); Block block = currentLoc.getBlock(); - if (!(WaterMethods.isWaterbendable(block, player) || block.getType() == Material.AIR) || GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", block.getLocation())) { + if (!(WaterAbility.isWaterbendable(block, player) || block.getType() == Material.AIR) + || GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", block.getLocation())) { remove(); return; } - createBlock(block, mat, data); - if (currentLoc.distance(eyeLoc) < 1.1) { + createBlock(block, material, data); + if (currentLoc.distanceSquared(eyeLoc) < 1.2) { state = AnimationState.FINISHED; revertBlocks(); } @@ -107,32 +112,52 @@ public class WaterSourceGrabber { affectedBlocks.put(block, new TempBlock(block, mat, data)); } - public Material getMat() { - return mat; + public Player getPlayer() { + return player; } - public void setMat(Material mat) { - this.mat = mat; + public void setPlayer(Player player) { + this.player = player; } - public Byte getData() { + public byte getData() { return data; } - public void setData(Byte data) { + public void setData(byte data) { this.data = data; } + public double getAnimimationSpeed() { + return animimationSpeed; + } + + public void setAnimimationSpeed(double animimationSpeed) { + this.animimationSpeed = animimationSpeed; + } + + public Material getMaterial() { + return material; + } + + public void setMaterial(Material material) { + this.material = material; + } + + public Location getCurrentLoc() { + return currentLoc; + } + + public void setCurrentLoc(Location currentLoc) { + this.currentLoc = currentLoc; + } + + public ConcurrentHashMap getAffectedBlocks() { + return affectedBlocks; + } + public void setState(AnimationState state) { this.state = state; } - - public double getAnimSpeed() { - return animSpeed; - } - - public void setAnimSpeed(double animSpeed) { - this.animSpeed = animSpeed; - } - + } diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterSpout.java b/src/com/projectkorra/projectkorra/waterbending/WaterSpout.java index 79885282..f9490faa 100644 --- a/src/com/projectkorra/projectkorra/waterbending/WaterSpout.java +++ b/src/com/projectkorra/projectkorra/waterbending/WaterSpout.java @@ -2,282 +2,76 @@ package com.projectkorra.projectkorra.waterbending; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.chiblocking.Paralyze; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.ClickType; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; import com.projectkorra.projectkorra.util.Flight; import com.projectkorra.projectkorra.util.ParticleEffect; import com.projectkorra.projectkorra.util.TempBlock; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.Server; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffectType; -import java.util.ArrayList; +import java.util.Random; import java.util.concurrent.ConcurrentHashMap; -public class WaterSpout { +public class WaterSpout extends WaterAbility { - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - public static ConcurrentHashMap affectedblocks = new ConcurrentHashMap(); - public static ConcurrentHashMap newaffectedblocks = new ConcurrentHashMap(); - public static ConcurrentHashMap baseblocks = new ConcurrentHashMap(); - public static ConcurrentHashMap revert = new ConcurrentHashMap(); + private static final ConcurrentHashMap AFFECTED_BLOCKS = new ConcurrentHashMap(); + private static final ConcurrentHashMap NEW_AFFECTED_BLOCKS = new ConcurrentHashMap(); + private static final ConcurrentHashMap REVERT_BLOCKS = new ConcurrentHashMap(); - private static final int HEIGHT = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.WaterSpout.Height"); - private static final boolean PARTICLES = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.WaterSpout.Particles"); - private static final boolean BLOCKS = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.WaterSpout.BlockSpiral"); - - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.WaterSpout.Wave.SelectRange"); - - // private static final double threshold = .05; - // private static final byte half = 0x4; - @SuppressWarnings("unused") - private static final byte full = 0x0; - private Player player; - private Block base; - private TempBlock baseblock; - private int defaultheight = HEIGHT; - private long time = 0; - private long interval = 50; - private int angle = 0; + private boolean canBendOnPackedIce; + private boolean useParticles; + private boolean useBlockSpiral; + private int angle; + private long time; + private long interval; private double rotation; - private boolean canBendOnPackedIce = false; - + private double height; + private Block base; + private TempBlock baseBlock; + public WaterSpout(Player player) { - // if (BendingPlayer.getBendingPlayer(player).isOnCooldown( - // Abilities.WaterSpout)) - // return; - - if (instances.containsKey(player)) { - instances.get(player).remove(); + super(player); + + WaterSpout oldSpout = CoreAbility.getAbility(player, WaterSpout.class); + if (oldSpout != null) { + oldSpout.remove(); return; } - this.player = player; - this.canBendOnPackedIce = ProjectKorra.plugin.getConfig().getBoolean("Properties.Water.CanBendPackedIce"); - Block block = BlockSource.getWaterSourceBlock(player, selectRange, selectRange, ClickType.LEFT_CLICK, false, false, false, true, WaterMethods.canIcebend(player), WaterMethods.canPlantbend(player)); - - if(block != null) { - WaterWave wwave = new WaterWave(player, block, WaterWave.AbilityType.CLICK); - if (WaterWave.instances.contains(wwave)) { - return; - } + this.canBendOnPackedIce = ProjectKorra.plugin.getConfig().getBoolean("Properties.Water.CanBendPackedIce"); + this.useParticles = getConfig().getBoolean("Abilities.Water.WaterSpout.Particles"); + this.useBlockSpiral = getConfig().getBoolean("Abilities.Water.WaterSpout.BlockSpiral"); + this.height = getConfig().getDouble("Abilities.Water.WaterSpout.Height"); + this.interval = 50; + + WaterSpoutWave spoutWave = new WaterSpoutWave(player, WaterSpoutWave.AbilityType.CLICK); + if (spoutWave.isStarted()) { + return; } Block topBlock = GeneralMethods.getTopBlock(player.getLocation(), 0, -50); - if (topBlock == null) + if (topBlock == null) { topBlock = player.getLocation().getBlock(); - Material mat = topBlock.getType(); - if (mat != Material.WATER && mat != Material.STATIONARY_WATER && mat != Material.ICE && mat != Material.PACKED_ICE && mat != Material.SNOW && mat != Material.SNOW_BLOCK) - return; - if (mat == Material.PACKED_ICE && !canBendOnPackedIce) + } + + if (!isWater(topBlock) && !isIcebendable(topBlock) && !isSnow(topBlock)) { return; + } else if (topBlock.getType() == Material.PACKED_ICE && !canBendOnPackedIce) { + return; + } + new Flight(player); player.setAllowFlight(true); - instances.put(player, this); - spout(player); - - } - - private void remove() { - revertBaseBlock(player); - instances.remove(player); - } - - private static void progressRevert(boolean ignoreTime) { - for (Block block : revert.keySet()) { - long time = revert.get(block); - if (System.currentTimeMillis() > time || ignoreTime) { - if (TempBlock.isTempBlock(block)) - TempBlock.revertBlock(block, Material.AIR); - revert.remove(block); - } - } - } - - public static void handleSpouts(Server server) { - // affectedblocks.clear(); - newaffectedblocks.clear(); - progressRevert(false); - - for (Player player : instances.keySet()) { - if (!player.isOnline() || player.isDead()) { - instances.get(player).remove(); - } else if (GeneralMethods.canBend(player.getName(), "WaterSpout")) { - spout(player); - } else { - instances.get(player).remove(); - } - } - - for (Block block : affectedblocks.keySet()) { - if (!newaffectedblocks.containsKey(block)) { - remove(block); - } - } - - // for (Block block : affectedblocks.keySet()) { - // boolean remove = true; - // for (Player player : instances.keySet()) { - // if (Methods.hasAbility(player, Abilities.WaterSpout) - // && Methods.canBend(player, Abilities.WaterSpout) - // && player.getWorld() == block.getWorld()) { - // Location loc1 = player.getLocation().clone(); - // loc1.setY(0); - // Location loc2 = block.getLocation().clone(); - // loc2.setY(0); - // if (loc1.distance(loc2) < 1) - // remove = false; - // } - // } - // if (remove) - // remove(block); - // } - - } - - private static void remove(Block block) { - affectedblocks.remove(block); - TempBlock.revertBlock(block, Material.AIR); - // block.setType(Material.AIR); - // block.setData(half); - } - - public static void spout(Player player) { - WaterSpout spout = instances.get(player); - if (Bloodbending.isBloodbended(player) || Paralyze.isParalyzed(player)) { - instances.get(player).remove(); - } else { - - player.setFallDistance(0); - player.setSprinting(false); - if (GeneralMethods.rand.nextInt(4) == 0) { - WaterMethods.playWaterbendingSound(player.getLocation()); - } - // if (player.getVelocity().length() > threshold) { - // // Methods.verbose("Too fast!"); - // player.setVelocity(player.getVelocity().clone().normalize() - // .multiply(threshold * .5)); - // } - player.removePotionEffect(PotionEffectType.SPEED); - Location location = player.getLocation().clone().add(0, .2, 0); - Block block = location.clone().getBlock(); - int height = spoutableWaterHeight(location, player); - - // Methods.verbose(height + " " + WaterSpout.height + " " - // + affectedblocks.size()); - if (height != -1) { - location = spout.base.getLocation(); - for (int i = 1; i <= height; i++) { - block = location.clone().add(0, i, 0).getBlock(); - if (!TempBlock.isTempBlock(block)) { - new TempBlock(block, Material.STATIONARY_WATER, (byte) 8); - } - // block.setType(Material.WATER); - // block.setData(full); - if (!affectedblocks.containsKey(block)) { - affectedblocks.put(block, block); - } - instances.get(player).rotateParticles(block); - newaffectedblocks.put(block, block); - } - instances.get(player).displayWaterSpiral(location.clone().add(.5, 0, .5)); - if (player.getLocation().getBlockY() > block.getY()) { - player.setFlying(false); - } else { - new Flight(player); - player.setAllowFlight(true); - player.setFlying(true); - } - } else { - instances.get(player).remove(); - } - } - } - - public void rotateParticles(Block block) { - if (!PARTICLES) - return; - - if (System.currentTimeMillis() >= time + interval) { - time = System.currentTimeMillis(); - - Location location = block.getLocation(); - Location playerloc = player.getLocation(); - location = new Location(location.getWorld(), playerloc.getX(), location.getY(), playerloc.getZ()); - - double dy = playerloc.getY() - block.getY(); - if (dy > HEIGHT) - dy = HEIGHT; - float[] directions = { -0.5f, 0.325f, 0.25f, 0.125f, 0.f, 0.125f, 0.25f, 0.325f, 0.5f }; - int index = angle; - - angle++; - if (angle >= directions.length) - angle = 0; - for (int i = 1; i <= dy; i++) { - - index += 1; - if (index >= directions.length) - index = 0; - - Location effectloc2 = new Location(location.getWorld(), location.getX(), block.getY() + i, location.getZ()); - - ParticleEffect.WATER_SPLASH.display(effectloc2, directions[index], directions[index], directions[index], 5, HEIGHT + 5); - } - } - } - - private static int spoutableWaterHeight(Location location, Player player) { - WaterSpout spout = instances.get(player); - int height = spout.defaultheight; - if (WaterMethods.isNight(player.getWorld())) - height = (int) WaterMethods.waterbendingNightAugment((double) height, player.getWorld()); - int maxheight = (int) ((double) spout.defaultheight * ProjectKorra.plugin.getConfig().getDouble("Properties.Water.NightFactor")) + 5; - Block blocki; - for (int i = 0; i < maxheight; i++) { - blocki = location.clone().add(0, -i, 0).getBlock(); - if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterSpout", blocki.getLocation())) - return -1; - if (!affectedblocks.contains(blocki)) { - if (blocki.getType() == Material.WATER || blocki.getType() == Material.STATIONARY_WATER) { - if (!TempBlock.isTempBlock(blocki)) { - revertBaseBlock(player); - } - spout.base = blocki; - if (i > height) - return height; - return i; - } - if (blocki.getType() == Material.ICE || blocki.getType() == Material.SNOW || blocki.getType() == Material.SNOW_BLOCK || (blocki.getType() == Material.PACKED_ICE && spout.canBendOnPackedIce)) { - if (!TempBlock.isTempBlock(blocki)) { - revertBaseBlock(player); - instances.get(player).baseblock = new TempBlock(blocki, Material.STATIONARY_WATER, (byte) 8); - } - // blocki.setType(Material.WATER); - // blocki.setData(full); - spout.base = blocki; - if (i > height) - return height; - return i; - } - if ((blocki.getType() != Material.AIR && (!WaterMethods.isPlant(blocki) || !WaterMethods.canPlantbend(player)))) { - revertBaseBlock(player); - return -1; - } - } - } - revertBaseBlock(player); - return -1; + start(); } private void displayWaterSpiral(Location location) { - - if (!BLOCKS) { + if (!useBlockSpiral) { return; } @@ -285,6 +79,7 @@ public class WaterSpout { double height = 0; rotation += .4; int i = 0; + while (height < maxHeight) { i += 20; height += .4; @@ -296,76 +91,324 @@ public class WaterSpout { Block block = loc.getBlock(); if (block.getType().equals(Material.AIR) || !GeneralMethods.isSolid(block)) { - revert.put(block, 0L); + REVERT_BLOCKS.put(block, 0L); new TempBlock(block, Material.STATIONARY_WATER, (byte) 1); } } } - public static void revertBaseBlock(Player player) { - if (instances.containsKey(player)) { - if (instances.get(player).baseblock != null) { - instances.get(player).baseblock.revertBlock(); - instances.get(player).baseblock = null; + @Override + public void progress() { + if (player.isDead() || !player.isOnline() || !bPlayer.canBind(this)) { + remove(); + return; + } else { + player.setFallDistance(0); + player.setSprinting(false); + if ((new Random()).nextInt(4) == 0) { + playWaterbendingSound(player.getLocation()); + } + + player.removePotionEffect(PotionEffectType.SPEED); + Location location = player.getLocation().clone().add(0, .2, 0); + Block block = location.clone().getBlock(); + double height = spoutableWaterHeight(location); + + if (height != -1) { + location = base.getLocation(); + for (int i = 1; i <= height; i++) { + block = location.clone().add(0, i, 0).getBlock(); + + if (!TempBlock.isTempBlock(block)) { + new TempBlock(block, Material.STATIONARY_WATER, (byte) 8); + } + if (!AFFECTED_BLOCKS.containsKey(block)) { + AFFECTED_BLOCKS.put(block, block); + } + rotateParticles(block); + NEW_AFFECTED_BLOCKS.put(block, block); + } + + displayWaterSpiral(location.clone().add(.5, 0, .5)); + if (player.getLocation().getBlockY() > block.getY()) { + player.setFlying(false); + } else { + new Flight(player); + player.setAllowFlight(true); + player.setFlying(true); + } + } else { + remove(); + return; } } } - public static void removeAll() { - progressRevert(true); - revert.clear(); + @Override + public void remove() { + super.remove(); + revertBaseBlock(); + } - for (Player player : instances.keySet()) { - instances.get(player).remove(); - } - for (Block block : affectedblocks.keySet()) { - // block.setType(Material.AIR); - TempBlock.revertBlock(block, Material.AIR); - affectedblocks.remove(block); + public void revertBaseBlock() { + if (baseBlock != null) { + baseBlock.revertBlock(); + baseBlock = null; } } - public static ArrayList getPlayers() { - ArrayList players = new ArrayList(); - for (Player player : instances.keySet()) - players.add(player); - return players; - } + public void rotateParticles(Block block) { + if (!useParticles) { + return; + } - public static boolean removeSpouts(Location loc0, double radius, Player sourceplayer) { - boolean removed = false; - for (Player player : instances.keySet()) { - if (!player.equals(sourceplayer)) { - Location loc1 = player.getLocation().getBlock().getLocation(); - loc0 = loc0.getBlock().getLocation(); - double dx = loc1.getX() - loc0.getX(); - double dy = loc1.getY() - loc0.getY(); - double dz = loc1.getZ() - loc0.getZ(); + if (System.currentTimeMillis() >= time + interval) { + time = System.currentTimeMillis(); - double distance = Math.sqrt(dx * dx + dz * dz); + Location location = block.getLocation(); + Location playerLoc = player.getLocation(); + location = new Location(location.getWorld(), playerLoc.getX(), location.getY(), playerLoc.getZ()); - if (distance <= radius && dy > 0 && dy < instances.get(player).defaultheight) { - removed = true; - instances.get(player).remove(); + double dy = playerLoc.getY() - block.getY(); + if (dy > height) { + dy = height; + } + + float[] directions = { -0.5f, 0.325f, 0.25f, 0.125f, 0.f, 0.125f, 0.25f, 0.325f, 0.5f }; + int index = angle; + angle++; + if (angle >= directions.length) { + angle = 0; + } + for (int i = 1; i <= dy; i++) { + index += 1; + if (index >= directions.length) { + index = 0; } + + Location effectLoc2 = new Location(location.getWorld(), location.getX(), block.getY() + i, location.getZ()); + ParticleEffect.WATER_SPLASH.display(effectLoc2, directions[index], directions[index], directions[index], 5, (int) (height + 5)); + } + } + } + + private double spoutableWaterHeight(Location location) { + double newHeight = height; + if (isNight(player.getWorld())) { + newHeight = getNightFactor(newHeight); + } + + double maxHeight = (height * ProjectKorra.plugin.getConfig().getDouble("Properties.Water.NightFactor")) + 5; + Block blocki; + + for (int i = 0; i < maxHeight; i++) { + blocki = location.clone().add(0, -i, 0).getBlock(); + if (GeneralMethods.isRegionProtectedFromBuild(this, blocki.getLocation())) { + return -1; + } + + if (!AFFECTED_BLOCKS.contains(blocki)) { + if (isWater(blocki)) { + if (!TempBlock.isTempBlock(blocki)) { + revertBaseBlock(); + } + + base = blocki; + if (i > newHeight) { + return newHeight; + } + return i; + } + + if (isIcebendable(blocki) || isSnow(blocki)) { + if (!TempBlock.isTempBlock(blocki)) { + revertBaseBlock(); + baseBlock = new TempBlock(blocki, Material.STATIONARY_WATER, (byte) 8); + } + + base = blocki; + if (i > newHeight) { + return newHeight; + } + return i; + } + if ((blocki.getType() != Material.AIR && (!isPlant(blocki) || !bPlayer.canPlantbend()))) { + revertBaseBlock(); + return -1; + } + } + } + revertBaseBlock(); + return -1; + } + + public static void progressAllCleanup() { + NEW_AFFECTED_BLOCKS.clear(); + revertAllBlocks(false); + + for (Block block : AFFECTED_BLOCKS.keySet()) { + if (!NEW_AFFECTED_BLOCKS.containsKey(block)) { + AFFECTED_BLOCKS.remove(block); + TempBlock.revertBlock(block, Material.AIR); + } + } + } + + private static void revertAllBlocks(boolean ignoreTime) { + for (Block block : REVERT_BLOCKS.keySet()) { + long time = REVERT_BLOCKS.get(block); + if (System.currentTimeMillis() > time || ignoreTime) { + if (TempBlock.isTempBlock(block)) { + TempBlock.revertBlock(block, Material.AIR); + } + REVERT_BLOCKS.remove(block); + } + } + } + + public static void removeAllCleanup() { + revertAllBlocks(true); + REVERT_BLOCKS.clear(); + + for (Block block : AFFECTED_BLOCKS.keySet()) { + TempBlock.revertBlock(block, Material.AIR); + AFFECTED_BLOCKS.remove(block); + } + } + + public static boolean removeSpouts(Location loc0, double radius, Player sourcePlayer) { + boolean removed = false; + Location loc1 = sourcePlayer.getLocation().getBlock().getLocation(); + loc0 = loc0.getBlock().getLocation(); + double dx = loc1.getX() - loc0.getX(); + double dy = loc1.getY() - loc0.getY(); + double dz = loc1.getZ() - loc0.getZ(); + double distSquared = dx * dx + dz * dz; + + for (WaterSpout spout : CoreAbility.getAbilities(sourcePlayer, WaterSpout.class)) { + if (distSquared <= radius * radius && dy > 0 && dy < spout.height) { + removed = true; + spout.remove(); } } return removed; } - public static String getDescription() { - return "To use this ability, click while over or in water. " + "You will spout water up from beneath you to experience controlled levitation. " + "This ability is a toggle, so you can activate it then use other abilities and it " + "will remain on. If you try to spout over an area with no water, snow or ice, " + "the spout will dissipate and you will fall. Click again with this ability selected to deactivate it."; + @Override + public String getName() { + return "WaterSpout"; } - public Player getPlayer() { - return player; + @Override + public Location getLocation() { + return player != null ? player.getLocation() : null; } - public int getDefaultheight() { - return defaultheight; + @Override + public long getCooldown() { + return 0; } - public void setDefaultheight(int defaultheight) { - this.defaultheight = defaultheight; + @Override + public boolean isSneakAbility() { + return true; } + + @Override + public boolean isHarmlessAbility() { + return true; + } + + public boolean isCanBendOnPackedIce() { + return canBendOnPackedIce; + } + + public void setCanBendOnPackedIce(boolean canBendOnPackedIce) { + this.canBendOnPackedIce = canBendOnPackedIce; + } + + public boolean isUseParticles() { + return useParticles; + } + + public void setUseParticles(boolean useParticles) { + this.useParticles = useParticles; + } + + public boolean isUseBlockSpiral() { + return useBlockSpiral; + } + + public void setUseBlockSpiral(boolean useBlockSpiral) { + this.useBlockSpiral = useBlockSpiral; + } + + public int getAngle() { + return angle; + } + + public void setAngle(int angle) { + this.angle = angle; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getInterval() { + return interval; + } + + public void setInterval(long interval) { + this.interval = interval; + } + + public double getRotation() { + return rotation; + } + + public void setRotation(double rotation) { + this.rotation = rotation; + } + + public double getHeight() { + return height; + } + + public void setHeight(double height) { + this.height = height; + } + + public Block getBase() { + return base; + } + + public void setBase(Block base) { + this.base = base; + } + + public TempBlock getBaseBlock() { + return baseBlock; + } + + public void setBaseBlock(TempBlock baseBlock) { + this.baseBlock = baseBlock; + } + + public static ConcurrentHashMap getAffectedBlocks() { + return AFFECTED_BLOCKS; + } + + public static ConcurrentHashMap getNewAffectedBlocks() { + return NEW_AFFECTED_BLOCKS; + } + + public static ConcurrentHashMap getRevertBlocks() { + return REVERT_BLOCKS; + } + } \ No newline at end of file diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterSpoutWave.java b/src/com/projectkorra/projectkorra/waterbending/WaterSpoutWave.java new file mode 100644 index 00000000..c7d56932 --- /dev/null +++ b/src/com/projectkorra/projectkorra/waterbending/WaterSpoutWave.java @@ -0,0 +1,626 @@ +package com.projectkorra.projectkorra.waterbending; + +import com.projectkorra.projectkorra.GeneralMethods; +import com.projectkorra.projectkorra.ProjectKorra; +import com.projectkorra.projectkorra.ability.CoreAbility; +import com.projectkorra.projectkorra.ability.WaterAbility; +import com.projectkorra.projectkorra.util.BlockSource; +import com.projectkorra.projectkorra.util.ClickType; +import com.projectkorra.projectkorra.util.TempBlock; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.concurrent.ConcurrentHashMap; + +public class WaterSpoutWave extends WaterAbility { + + public static enum AbilityType { + CLICK, SHIFT, RELEASE + } + + public static enum AnimateState { + RISE, TOWARD_PLAYER, CIRCLE, SHRINK + } + + private static final ConcurrentHashMap FROZEN_BLOCKS = new ConcurrentHashMap(); + + private double radius; + private boolean charging; + private boolean iceWave; + private boolean iceOnly; + private boolean enabled; + private boolean moving; + private int progressCounter; + private long time; + private long cooldown; + private double range; + private double speed; + private double chargeTime; + private double flightTime; + private double waveRadius; + private double damage; + private double animationSpeed; + private AbilityType type; + private AnimateState animation; + private Vector direction; + private Location origin; + private Location location; + private ArrayList affectedEntities; + private ArrayList tasks; + private ConcurrentHashMap affectedBlocks; + + public WaterSpoutWave(Player player, AbilityType type) { + super(player); + + this.radius = 3.8; + this.waveRadius = 1.5; + this.animationSpeed = 1.2; + this.charging = false; + this.iceWave = false; + this.iceOnly = false; + this.enabled = getConfig().getBoolean("Abilities.Water.WaterSpout.Wave.Enabled"); + this.range = getConfig().getDouble("Abilities.Water.WaterSpout.Wave.Range"); + this.speed = getConfig().getDouble("Abilities.Water.WaterSpout.Wave.Speed"); + this.damage = getConfig().getDouble("Abilities.Water.WaterCombo.IceWave.Damage"); + this.chargeTime = getConfig().getLong("Abilities.Water.WaterSpout.Wave.ChargeTime"); + this.flightTime = getConfig().getLong("Abilities.Water.WaterSpout.Wave.FlightTime"); + this.cooldown = getConfig().getLong("Abilities.Water.WaterSpout.Wave.Cooldown"); + this.affectedBlocks = new ConcurrentHashMap<>(); + this.affectedEntities = new ArrayList<>(); + this.tasks = new ArrayList<>(); + + this.damage = getNightFactor(this.damage); + + if (!enabled || !bPlayer.canBend(this)) { + return; + } + + this.time = System.currentTimeMillis(); + this.type = type; + start(); + } + + @Override + public void progress() { + progressCounter++; + if (!bPlayer.canBendIgnoreBindsCooldowns(this)) { + remove(); + return; + } + + if (type != AbilityType.RELEASE) { + if (!player.hasPermission("bending.ability.WaterSpout.Wave")) { + remove(); + return; + } else if (!bPlayer.getBoundAbilityName().equalsIgnoreCase(getName())) { + remove(); + return; + } + } + + if (type == AbilityType.CLICK) { + if (origin == null) { + removeOldType(player, AbilityType.CLICK); + Block block = BlockSource.getWaterSourceBlock(player, range, ClickType.LEFT_CLICK, true, true, bPlayer.canBend(this)); + + if (block == null) { + remove(); + return; + } + + Block blockAbove = block.getRelative(BlockFace.UP); + if (blockAbove.getType() != Material.AIR && !isWaterbendable(blockAbove)) { + remove(); + return; + } + + origin = block.getLocation(); + if (!isWaterbendable(block) || GeneralMethods.isRegionProtectedFromBuild(this, origin)) { + remove(); + return; + } else if (iceOnly && !(isIcebendable(block) || isSnow(block))) { + remove(); + return; + } + } + + if (player.getLocation().distanceSquared(origin) > range * range) { + remove(); + return; + } else if (player.isSneaking()) { + new WaterSpoutWave(player, AbilityType.SHIFT); + return; + } + playFocusWaterEffect(origin.getBlock()); + } else if (type == AbilityType.SHIFT) { + if (direction == null) { + direction = player.getEyeLocation().getDirection(); + } + if (!charging) { + if (!containsType(player, AbilityType.SHIFT)) { + removeOldType(player, AbilityType.CLICK); + remove(); + return; + } + + charging = true; + animation = AnimateState.RISE; + if(!getType(player, AbilityType.CLICK).isEmpty()) { + WaterSpoutWave clickWave = getType(player, AbilityType.CLICK).get(0); + origin = clickWave.origin.clone(); + location = origin.clone(); + + if (isPlant(origin.getBlock())) { + new PlantRegrowth(player, origin.getBlock()); + } + } + } + + removeOldType(player, AbilityType.CLICK); + if (!player.isSneaking()) { + if (System.currentTimeMillis() - time > chargeTime) { + WaterSpoutWave wave = new WaterSpoutWave(player, AbilityType.RELEASE); + wave.animation = AnimateState.SHRINK; + wave.direction = direction; + } + remove(); + return; + } + + if (animation == AnimateState.RISE && location != null) { + revertBlocks(); + location.add(0, animationSpeed, 0); + Block block = location.getBlock(); + + if (!(isWaterbendable(block) || block.getType() == Material.AIR) || GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + remove(); + return; + } + createBlock(block, Material.STATIONARY_WATER); + if (location.distanceSquared(origin) > 4) { + animation = AnimateState.TOWARD_PLAYER; + } + } else if (animation == AnimateState.TOWARD_PLAYER) { + revertBlocks(); + Location eyeLoc = player.getTargetBlock((HashSet) null, 2).getLocation(); + eyeLoc.setY(player.getEyeLocation().getY()); + Vector vec = GeneralMethods.getDirection(location, eyeLoc); + location.add(vec.normalize().multiply(animationSpeed)); + Block block = location.getBlock(); + + if (!(isWaterbendable(block) || block.getType() == Material.AIR) || GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + remove(); + return; + } + + createBlock(block, Material.STATIONARY_WATER); + if (location.distanceSquared(eyeLoc) < 1.7) { + animation = AnimateState.CIRCLE; + Vector tempDir = player.getLocation().getDirection(); + tempDir.setY(0); + direction = tempDir.normalize(); + revertBlocks(); + } + } else if (animation == AnimateState.CIRCLE) { + drawCircle(120, 5); + } + } else if (type == AbilityType.RELEASE) { + if (animation == AnimateState.SHRINK) { + radius -= 0.20; + drawCircle(360, 15); + + if (radius < 1) { + revertBlocks(); + time = System.currentTimeMillis(); + animation = null; + } + } else { + moving = true; + if ((System.currentTimeMillis() - time > flightTime && !bPlayer.isAvatarState()) || player.isSneaking()) { + remove(); + return; + } + + player.setFallDistance(0f); + double currentSpeed = speed - (speed * (System.currentTimeMillis() - time) / flightTime); + double nightSpeed = getNightFactor(currentSpeed * 0.9); + currentSpeed = nightSpeed > currentSpeed ? nightSpeed : currentSpeed; + if (bPlayer.isAvatarState()) { + currentSpeed = getNightFactor(speed); + } + + player.setVelocity(player.getEyeLocation().getDirection().normalize().multiply(currentSpeed)); + for (Block block : GeneralMethods.getBlocksAroundPoint(player.getLocation().add(0, -1, 0), waveRadius)) { + if (block.getType() == Material.AIR && !GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + if (iceWave) { + createBlockDelay(block, Material.ICE, (byte) 0, 2L); + } else { + createBlock(block, Material.STATIONARY_WATER, (byte) 0); + } + } + } + revertBlocksDelay(20L); + + if (iceWave && progressCounter % 3 == 0) { + for (Entity entity : GeneralMethods.getEntitiesAroundPoint(player.getLocation().add(0, -1, 0), waveRadius * 1.5)) { + if (entity != this.player && entity instanceof LivingEntity && !affectedEntities.contains(entity)) { + affectedEntities.add(entity); + final double augment = getNightFactor(player.getWorld()); + GeneralMethods.damageEntity(this, entity, damage); + final Player fplayer = this.player; + final Entity fent = entity; + + new BukkitRunnable() { + @Override + public void run() { + createIceSphere(fplayer, fent, augment * 2.5); + } + }.runTaskLater(ProjectKorra.plugin, 6); + } + } + } + } + } + } + + public void drawCircle(double theta, double increment) { + double rotateSpeed = 45; + revertBlocks(); + direction = GeneralMethods.rotateXZ(direction, rotateSpeed); + for (double i = 0; i < theta; i += increment) { + Vector dir = GeneralMethods.rotateXZ(direction, i - theta / 2).normalize().multiply(radius); + dir.setY(0); + Block block = player.getEyeLocation().add(dir).getBlock(); + location = block.getLocation(); + if (block.getType() == Material.AIR && !GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) { + createBlock(block, Material.STATIONARY_WATER, (byte) 8); + } + } + } + + @Override + public void remove() { + super.remove(); + if (moving) { + bPlayer.addCooldown(this); + } + revertBlocks(); + for (BukkitRunnable task : tasks) { + task.cancel(); + } + } + + public void createBlockDelay(final Block block, final Material mat, final byte data, long delay) { + BukkitRunnable br = new BukkitRunnable() { + @Override + public void run() { + createBlock(block, mat, data); + } + }; + br.runTaskLater(ProjectKorra.plugin, delay); + tasks.add(br); + } + + public void createBlock(Block block, Material mat) { + createBlock(block, mat, (byte) 0); + } + + public void createBlock(Block block, Material mat, byte data) { + affectedBlocks.put(block, new TempBlock(block, mat, data)); + } + + public void revertBlocks() { + Enumeration keys = affectedBlocks.keys(); + while (keys.hasMoreElements()) { + Block block = keys.nextElement(); + affectedBlocks.get(block).revertBlock(); + affectedBlocks.remove(block); + } + } + + public void revertBlocksDelay(long delay) { + Enumeration keys = affectedBlocks.keys(); + while (keys.hasMoreElements()) { + final Block block = keys.nextElement(); + final TempBlock tblock = affectedBlocks.get(block); + affectedBlocks.remove(block); + + new BukkitRunnable() { + @Override + public void run() { + if (!FROZEN_BLOCKS.containsKey(block)) { + tblock.revertBlock(); + } + } + }.runTaskLater(ProjectKorra.plugin, delay); + } + } + + public void createIceSphere(Player player, Entity entity, double radius) { + for (double x = -radius; x <= radius; x += 0.5) { + for (double y = -radius; y <= radius; y += 0.5) { + for (double z = -radius; z <= radius; z += 0.5) { + Block block = entity.getLocation().getBlock().getLocation().add(x, y, z).getBlock(); + if (block.getLocation().distanceSquared(entity.getLocation().getBlock().getLocation()) > radius * radius) { + continue; + } + + if (block.getType() == Material.AIR || block.getType() == Material.ICE || isWaterbendable(block)) { + if (!FROZEN_BLOCKS.containsKey(block)) { + TempBlock tblock = new TempBlock(block, Material.ICE, (byte) 1); + FROZEN_BLOCKS.put(block, tblock); + } + } + } + } + } + } + + public static boolean containsType(Player player, AbilityType type) { + for (WaterSpoutWave wave : CoreAbility.getAbilities(player, WaterSpoutWave.class)) { + if (wave.type.equals(type)) { + return true; + } + } + return false; + } + + public void removeOldType(Player player, AbilityType type) { + for (WaterSpoutWave wave : CoreAbility.getAbilities(player, WaterSpoutWave.class)) { + if (wave.type.equals(type) && !wave.equals(this)) { + wave.remove(); + } + } + } + + public static ArrayList getType(Player player, AbilityType type) { + ArrayList list = new ArrayList(); + for (WaterSpoutWave wave : CoreAbility.getAbilities(player, WaterSpoutWave.class)) { + if (wave.type.equals(type)) { + list.add(wave); + } + } + return list; + } + + public static boolean wasBrokenFor(Player player, Block block) { + ArrayList waves = getType(player, AbilityType.CLICK); + if (!waves.isEmpty()) { + WaterSpoutWave wave = waves.get(0); + if (wave.origin == null) { + return false; + } else if (wave.origin.getBlock().equals(block)) { + return true; + } + } + return false; + } + + public static boolean canThaw(Block block) { + return FROZEN_BLOCKS.containsKey(block); + } + + public static void thaw(Block block) { + if (FROZEN_BLOCKS.containsKey(block)) { + FROZEN_BLOCKS.get(block).revertBlock(); + FROZEN_BLOCKS.remove(block); + } + } + + @Override + public Location getLocation() { + if (location != null) { + return location; + } else { + return origin; + } + } + + @Override + public String getName() { + return "WaterSpout"; + } + + @Override + public long getCooldown() { + return cooldown; + } + + @Override + public boolean isSneakAbility() { + return true; + } + + @Override + public boolean isHarmlessAbility() { + return false; + } + + public double getRadius() { + return radius; + } + + public void setRadius(double radius) { + this.radius = radius; + } + + public boolean isCharging() { + return charging; + } + + public void setCharging(boolean charging) { + this.charging = charging; + } + + public boolean isIceWave() { + return iceWave; + } + + public void setIceWave(boolean iceWave) { + this.iceWave = iceWave; + } + + public boolean isIceOnly() { + return iceOnly; + } + + public void setIceOnly(boolean iceOnly) { + this.iceOnly = iceOnly; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public boolean isMoving() { + return moving; + } + + public void setMoving(boolean moving) { + this.moving = moving; + } + + public int getProgressCounter() { + return progressCounter; + } + + public void setProgressCounter(int progressCounter) { + this.progressCounter = progressCounter; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public double getRange() { + return range; + } + + public void setRange(double range) { + this.range = range; + } + + public double getSpeed() { + return speed; + } + + public void setSpeed(double speed) { + this.speed = speed; + } + + public double getChargeTime() { + return chargeTime; + } + + public void setChargeTime(double chargeTime) { + this.chargeTime = chargeTime; + } + + public double getFlightTime() { + return flightTime; + } + + public void setFlightTime(double flightTime) { + this.flightTime = flightTime; + } + + public double getWaveRadius() { + return waveRadius; + } + + public void setWaveRadius(double waveRadius) { + this.waveRadius = waveRadius; + } + + public double getDamage() { + return damage; + } + + public void setDamage(double damage) { + this.damage = damage; + } + + public double getAnimationSpeed() { + return animationSpeed; + } + + public void setAnimationSpeed(double animationSpeed) { + this.animationSpeed = animationSpeed; + } + + public AbilityType getType() { + return type; + } + + public void setType(AbilityType type) { + this.type = type; + } + + public AnimateState getAnimation() { + return animation; + } + + public void setAnimation(AnimateState animation) { + this.animation = animation; + } + + public Vector getDirection() { + return direction; + } + + public void setDirection(Vector direction) { + this.direction = direction; + } + + public Location getOrigin() { + return origin; + } + + public void setOrigin(Location origin) { + this.origin = origin; + } + + public static ConcurrentHashMap getFrozenBlocks() { + return FROZEN_BLOCKS; + } + + public ArrayList getAffectedEntities() { + return affectedEntities; + } + + public ArrayList getTasks() { + return tasks; + } + + public ConcurrentHashMap getAffectedBlocks() { + return affectedBlocks; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } + + public void setLocation(Location location) { + this.location = location; + } + +} diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterWall.java b/src/com/projectkorra/projectkorra/waterbending/WaterWall.java deleted file mode 100644 index 01d62ce2..00000000 --- a/src/com/projectkorra/projectkorra/waterbending/WaterWall.java +++ /dev/null @@ -1,564 +0,0 @@ -package com.projectkorra.projectkorra.waterbending; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.firebending.FireBlast; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.ClickType; -import com.projectkorra.projectkorra.util.TempBlock; - -import org.bukkit.Effect; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.concurrent.ConcurrentHashMap; - -public class WaterWall { - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - public static ConcurrentHashMap affectedblocks = new ConcurrentHashMap(); - public static ConcurrentHashMap wallblocks = new ConcurrentHashMap(); - - private static int selectRANGE = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.Surge.Wall.SelectRange"); - private static final double defaultradius = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.Surge.Wall.Radius"); - // private static double speed = 1.5; - private static final long interval = 30; - private static final byte full = 0x0; - // private static final byte half = 0x4; - - private static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.Surge.Wall.DynamicSourcing.Enabled"); - - Player player; - private Location location = null; - private Block sourceblock = null; - // private Block oldwater = null; - private Location firstdestination = null; - private Location targetdestination = null; - private Vector firstdirection = null; - private Vector targetdirection = null; - // private boolean falling = false; - private boolean progressing = false; - private boolean settingup = false; - private boolean forming = false; - private boolean frozen = false; - private long time; - private double radius = defaultradius; - private double selectRange = selectRANGE; - - @SuppressWarnings("deprecation") - public WaterWall(Player player) { - this.player = player; - - if (Wave.instances.containsKey(player.getEntityId())) { - Wave wave = Wave.instances.get(player.getEntityId()); - if (!wave.progressing) { - Wave.launch(player); - return; - } - } - - if (AvatarState.isAvatarState(player)) { - radius = AvatarState.getValue(radius); - } - if (instances.containsKey(player.getEntityId())) { - if (instances.get(player.getEntityId()).progressing) { - freezeThaw(player); - } else if (prepare()) { - if (instances.containsKey(player.getEntityId())) { - instances.get(player.getEntityId()).cancel(); - } - // Methods.verbose("New water wall prepared"); - instances.put(player.getEntityId(), this); - time = System.currentTimeMillis(); - - } - } else if (prepare()) { - if (instances.containsKey(player.getEntityId())) { - instances.get(player.getEntityId()).cancel(); - } - instances.put(player.getEntityId(), this); - time = System.currentTimeMillis(); - } - - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (bPlayer.isOnCooldown("Surge")) - return; - - if (!instances.containsKey(player.getEntityId()) && WaterReturn.hasWaterBottle(player)) { - - Location eyeloc = player.getEyeLocation(); - Block block = eyeloc.add(eyeloc.getDirection().normalize()).getBlock(); - if (EarthMethods.isTransparentToEarthbending(player, block) && EarthMethods.isTransparentToEarthbending(player, eyeloc.getBlock())) { - block.setType(Material.WATER); - block.setData(full); - Wave wave = new Wave(player); - wave.canhitself = false; - wave.moveWater(); - if (!wave.progressing) { - block.setType(Material.AIR); - wave.cancel(); - } else { - WaterReturn.emptyWaterBottle(player); - } - } - - } - - } - - private static void freezeThaw(Player player) { - instances.get(player.getEntityId()).freezeThaw(); - } - - private void freezeThaw() { - if (!WaterMethods.canIcebend(player)) - return; - - if (frozen) { - thaw(); - } else { - freeze(); - } - } - - private void freeze() { - frozen = true; - for (Block block : wallblocks.keySet()) { - if (wallblocks.get(block) == player) { - new TempBlock(block, Material.ICE, (byte) 0); - WaterMethods.playIcebendingSound(block.getLocation()); - } - } - } - - private void thaw() { - frozen = false; - for (Block block : wallblocks.keySet()) { - if (wallblocks.get(block) == player) { - new TempBlock(block, Material.STATIONARY_WATER, (byte) 8); - } - } - } - - public boolean prepare() { - cancelPrevious(); - // Block block = player.getTargetBlock(null, (int) range); - Block block = BlockSource.getWaterSourceBlock(player, (int) selectRange, (int) selectRange, ClickType.LEFT_CLICK, false, dynamic, true, true, WaterMethods.canIcebend(player), WaterMethods.canPlantbend(player)); - if (block != null) { - sourceblock = block; - focusBlock(); - return true; - } - return false; - } - - private void cancelPrevious() { - if (instances.containsKey(player.getEntityId())) { - WaterWall old = instances.get(player.getEntityId()); - if (old.progressing) { - old.removeWater(old.sourceblock); - } else { - old.cancel(); - } - } - } - - public void cancel() { - unfocusBlock(); - } - - private void focusBlock() { - location = sourceblock.getLocation(); - } - - private void unfocusBlock() { - instances.remove(player.getEntityId()); - } - - @SuppressWarnings("deprecation") - public void moveWater() { - if (sourceblock != null) { - targetdestination = player.getTargetBlock(EarthMethods.getTransparentEarthbending(), (int) selectRange).getLocation(); - - if (targetdestination.distance(location) <= 1) { - progressing = false; - targetdestination = null; - } else { - progressing = true; - settingup = true; - firstdestination = getToEyeLevel(); - firstdirection = getDirection(sourceblock.getLocation(), firstdestination); - targetdirection = getDirection(firstdestination, targetdestination); - if (WaterMethods.isPlant(sourceblock)) - new Plantbending(sourceblock); - if (!GeneralMethods.isAdjacentToThreeOrMoreSources(sourceblock)) { - sourceblock.setType(Material.AIR); - } - addWater(sourceblock); - } - - } - } - - private Location getToEyeLevel() { - Location loc = sourceblock.getLocation().clone(); - loc.setY(targetdestination.getY()); - return loc; - } - - private Vector getDirection(Location location, Location destination) { - double x1, y1, z1; - double x0, y0, z0; - - x1 = destination.getX(); - y1 = destination.getY(); - z1 = destination.getZ(); - - x0 = location.getX(); - y0 = location.getY(); - z0 = location.getZ(); - - return new Vector(x1 - x0, y1 - y0, z1 - z0); - - } - - public static void progressAll() { - for (int ID : instances.keySet()) { - instances.get(ID).progress(); - } - } - - private boolean progress() { - if (player.isDead() || !player.isOnline()) { - breakBlock(); - // instances.remove(player.getEntityId()); - return false; - } - if (!GeneralMethods.canBend(player.getName(), "Surge")) { - //if (!forming) - // removeWater(oldwater); - breakBlock(); - returnWater(location); - unfocusBlock(); - return false; - } - - if (System.currentTimeMillis() - time >= interval) { - time = System.currentTimeMillis(); - - if (!forming) { - // removeWater(oldwater); - } - - if (GeneralMethods.getBoundAbility(player) == null) { - unfocusBlock(); - breakBlock(); - returnWater(location); - return false; - } - if (!progressing && !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("Surge")) { - unfocusBlock(); - return false; - } - - if (progressing && (!player.isSneaking() || !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("Surge"))) { - breakBlock(); - returnWater(location); - return false; - } - - if (!progressing) { - sourceblock.getWorld().playEffect(location, Effect.SMOKE, 4, (int) selectRange); - return false; - } - - if (forming) { - if (GeneralMethods.rand.nextInt(7) == 0) { - WaterMethods.playWaterbendingSound(location); - } - ArrayList blocks = new ArrayList(); - Location loc = GeneralMethods.getTargetedLocation(player, selectRange, 8, 9, 79); - location = loc.clone(); - Vector dir = player.getEyeLocation().getDirection(); - Vector vec; - Block block; - for (double i = 0; i <= WaterMethods.waterbendingNightAugment(radius, player.getWorld()); i += 0.5) { - for (double angle = 0; angle < 360; angle += 10) { - // loc.getBlock().setType(Material.GLOWSTONE); - vec = GeneralMethods.getOrthogonalVector(dir.clone(), angle, i); - block = loc.clone().add(vec).getBlock(); - if (GeneralMethods.isRegionProtectedFromBuild(player, "Surge", block.getLocation())) - continue; - if (wallblocks.containsKey(block)) { - blocks.add(block); - } else if (!blocks.contains(block) && (block.getType() == Material.AIR || block.getType() == Material.FIRE || WaterMethods.isWaterbendable(block, player))) { - wallblocks.put(block, player); - addWallBlock(block); - // if (frozen) { - // block.setType(Material.ICE); - // } else { - // block.setType(Material.WATER); - // block.setData(full); - // } - // block.setType(Material.GLASS); - blocks.add(block); - FireBlast.removeFireBlastsAroundPoint(block.getLocation(), 2); - // Methods.verbose(wallblocks.size()); - } - } - } - - for (Block blocki : wallblocks.keySet()) { - if (wallblocks.get(blocki) == player && !blocks.contains(blocki)) { - finalRemoveWater(blocki); - } - } - - return true; - } - - if (sourceblock.getLocation().distance(firstdestination) < .5 && settingup) { - settingup = false; - } - - Vector direction; - if (settingup) { - direction = firstdirection; - } else { - direction = targetdirection; - } - - location = location.clone().add(direction); - - Block block = location.getBlock(); - if (block.getLocation().equals(sourceblock.getLocation())) { - location = location.clone().add(direction); - block = location.getBlock(); - } - if (block.getType() != Material.AIR) { - breakBlock(); - returnWater(location.subtract(direction)); - return false; - } - - if (!progressing) { - breakBlock(); - return false; - } - - addWater(block); - removeWater(sourceblock); - sourceblock = block; - - if (location.distance(targetdestination) < 1) { - - removeWater(sourceblock); - // removeWater(oldwater); - forming = true; - } - - return true; - } - - return false; - - } - - private void addWallBlock(Block block) { - if (frozen) { - new TempBlock(block, Material.ICE, (byte) 0); - } else { - new TempBlock(block, Material.STATIONARY_WATER, (byte) 8); - } - } - - private void breakBlock() { - finalRemoveWater(sourceblock); - for (Block block : wallblocks.keySet()) { - if (wallblocks.get(block) == player) { - finalRemoveWater(block); - } - } - instances.remove(player.getEntityId()); - } - - // private void reduceWater(Block block) { - // if (affectedblocks.containsKey(block)) { - // if (!Methods.adjacentToThreeOrMoreSources(block)) { - // block.setType(Material.WATER); - // block.setData(half); - // } - // oldwater = block; - // } - // } - - private void removeWater(Block block) { - if (block != null) { - if (affectedblocks.containsKey(block)) { - if (!GeneralMethods.isAdjacentToThreeOrMoreSources(block)) { - TempBlock.revertBlock(block, Material.AIR); - } - affectedblocks.remove(block); - } - } - } - - private static void finalRemoveWater(Block block) { - if (affectedblocks.containsKey(block)) { - // block.setType(Material.WATER); - // block.setData(half); - // if (!Methods.adjacentToThreeOrMoreSources(block)) { - // block.setType(Material.AIR); - // } - TempBlock.revertBlock(block, Material.AIR); - affectedblocks.remove(block); - } - - if (wallblocks.containsKey(block)) { - // if (block.getType() == Material.ICE - // || block.getType() == Material.WATER - // || block.getType() == Material.STATIONARY_WATER) { - // block.setType(Material.AIR); - // } - TempBlock.revertBlock(block, Material.AIR); - wallblocks.remove(block); - // block.setType(Material.WATER); - // block.setData(half); - } - } - - private void addWater(Block block) { - - if (GeneralMethods.isRegionProtectedFromBuild(player, "Surge", block.getLocation())) - return; - - if (!TempBlock.isTempBlock(block)) { - new TempBlock(block, Material.STATIONARY_WATER, (byte) 8); - // new TempBlock(block, Material.ICE, (byte) 0); - affectedblocks.put(block, block); - } - } - - public static void moveWater(Player player) { - if (instances.containsKey(player.getEntityId())) { - instances.get(player.getEntityId()).moveWater(); - } - } - - public static boolean progress(int ID) { - return instances.get(ID).progress(); - } - - @SuppressWarnings("deprecation") - public static void form(Player player) { - - if (!instances.containsKey(player.getEntityId())) { - if (!Wave.instances.containsKey(player.getEntityId()) && BlockSource.getWaterSourceBlock(player, Wave.defaultrange, Wave.defaultrange, ClickType.LEFT_CLICK, false, Wave.dynamic, true, true, WaterMethods.canIcebend(player), WaterMethods.canPlantbend(player)) == null && WaterReturn.hasWaterBottle(player)) { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (bPlayer.isOnCooldown("Surge")) - return; - - Location eyeloc = player.getEyeLocation(); - Block block = eyeloc.add(eyeloc.getDirection().normalize()).getBlock(); - if (EarthMethods.isTransparentToEarthbending(player, block) && EarthMethods.isTransparentToEarthbending(player, eyeloc.getBlock())) { - block.setType(Material.WATER); - block.setData(full); - WaterWall wall = new WaterWall(player); - wall.moveWater(); - if (!wall.progressing) { - block.setType(Material.AIR); - wall.cancel(); - } else { - WaterReturn.emptyWaterBottle(player); - } - return; - } - } - - new Wave(player); - return; - } else { - if (WaterMethods.isWaterbendable(player.getTargetBlock((HashSet) null, (int) Wave.defaultrange), player)) { - new Wave(player); - return; - } - } - - moveWater(player); - } - - public static void removeAll() { - for (Block block : affectedblocks.keySet()) { - TempBlock.revertBlock(block, Material.AIR); - affectedblocks.remove(block); - wallblocks.remove(block); - } - for (Block block : wallblocks.keySet()) { - TempBlock.revertBlock(block, Material.AIR); - affectedblocks.remove(block); - wallblocks.remove(block); - } - } - - public static boolean canThaw(Block block) { - if (wallblocks.keySet().contains(block)) - return false; - return true; - } - - public static void thaw(Block block) { - finalRemoveWater(block); - } - - public static boolean wasBrokenFor(Player player, Block block) { - if (instances.containsKey(player.getEntityId())) { - WaterWall wall = instances.get(player.getEntityId()); - if (wall.sourceblock == null) - return false; - if (wall.sourceblock.equals(block)) - return true; - } - return false; - } - - private void returnWater(Location location) { - if (location != null) { - new WaterReturn(player, location.getBlock()); - } - } - - public static String getDescription() { - return "This ability has two distinct features. If you sneak to select a source block, " + "you can then click in a direction and a large wave will be launched in that direction. " + "If you sneak again while the wave is en route, the wave will freeze the next target it hits. " + "If, instead, you click to select a source block, you can hold sneak to form a wall of water at " + "your cursor location. Click to shift between a water wall and an ice wall. " + "Release sneak to dissipate it."; - } - - public Player getPlayer() { - return player; - } - - public double getRadius() { - return radius; - } - - public void setRadius(double radius) { - this.radius = radius; - } - - public double getRange() { - return selectRange; - } - - public void setRange(double range) { - this.selectRange = range; - } - -} \ No newline at end of file diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterWave.java b/src/com/projectkorra/projectkorra/waterbending/WaterWave.java deleted file mode 100644 index 703cc618..00000000 --- a/src/com/projectkorra/projectkorra/waterbending/WaterWave.java +++ /dev/null @@ -1,478 +0,0 @@ -package com.projectkorra.projectkorra.waterbending; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.Element; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.SubElement; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.util.TempBlock; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.concurrent.ConcurrentHashMap; - -public class WaterWave { - public static enum AbilityType { - CLICK, SHIFT, RELEASE - } - - public static enum AnimateState { - RISE, TOWARDPLAYER, CIRCLE, SHRINK - } - - public static ArrayList instances = new ArrayList(); - public static ConcurrentHashMap frozenBlocks = new ConcurrentHashMap(); - - public static boolean ICE_ONLY = false; - public static boolean ENABLED = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.WaterSpout.Wave.Enabled"); - public static double MAX_SPEED = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.WaterSpout.Wave.Speed"); - public static long CHARGE_TIME = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.WaterSpout.Wave.ChargeTime"); - public static long FLIGHT_TIME = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.WaterSpout.Wave.FlightTime"); - public static long COOLDOWN = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.WaterSpout.Wave.Cooldown"); - public static double WAVE_RADIUS = 1.5; - public static double ICE_WAVE_DAMAGE = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.WaterCombo.IceWave.Damage"); - - private static int selectRange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.WaterSpout.Wave.SelectRange"); - - private Player player; - private long time; - private Block block; - private AbilityType type; - private Location origin, currentLoc; - private Vector direction; - private double radius = 3.8; - private boolean charging = false; - private boolean iceWave = false; - private int progressCounter = 0; - private AnimateState anim; - private double speed = MAX_SPEED; - private double chargeTime = CHARGE_TIME; - private double flightTime = FLIGHT_TIME; - private double waveRadius = WAVE_RADIUS; - private double damage = ICE_WAVE_DAMAGE; - private long cooldown = COOLDOWN; - private ConcurrentHashMap affectedBlocks = new ConcurrentHashMap(); - private ArrayList affectedEntities = new ArrayList(); - private ArrayList tasks = new ArrayList(); - - public WaterWave(Player player, Block block, AbilityType type) { - if (!ENABLED || GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("WaterWave")) - return; - - this.player = player; - this.time = System.currentTimeMillis(); - this.type = type; - this.block = block; - instances.add(this); - - if (type == AbilityType.CLICK) - this.progress(); - } - - public void progress() { - progressCounter++; - if (player.isDead() || !player.isOnline()) { - remove(); - return; - } - if (origin != null && !player.getWorld().equals(origin.getWorld())) { - remove(); - return; - } - if (type != AbilityType.RELEASE) { - if (!GeneralMethods.canBend(player.getName(), "WaterSpout") || !player.hasPermission("bending.ability.WaterSpout.Wave")) { - remove(); - return; - } - String ability = GeneralMethods.getBoundAbility(player); - if (ability == null || !ability.equalsIgnoreCase("WaterSpout")) { - remove(); - return; - } - } - - if (type == AbilityType.CLICK) { - if (origin == null) { - removeType(player, AbilityType.CLICK); - - if (block == null) { - if(instances.contains(this)) { - remove(); - } - return; - } - instances.add(this); - Block blockAbove = block.getRelative(BlockFace.UP); - if (blockAbove.getType() != Material.AIR && !WaterMethods.isWaterbendable(blockAbove, player)) { - remove(); - return; - } - origin = block.getLocation(); - - if (!WaterMethods.isWaterbendable(block, player) || GeneralMethods.isRegionProtectedFromBuild(player, "WaterSpout", origin)) { - remove(); - return; - } - if (ICE_ONLY && !(block.getType() == Material.ICE || block.getType() == Material.SNOW || block.getType() == Material.PACKED_ICE)) { - remove(); - return; - } - } - if (player.getLocation().distance(origin) > selectRange) { - remove(); - return; - } else if (player.isSneaking()) { - new WaterWave(player, block, AbilityType.SHIFT); - return; - } - WaterMethods.playFocusWaterEffect(origin.getBlock()); - } else if (type == AbilityType.SHIFT) { - if (direction == null) { - direction = player.getEyeLocation().getDirection(); - } - if (!charging) { - if (!containsType(player, AbilityType.SHIFT)) { - removeType(player, AbilityType.CLICK); - remove(); - return; - } - //removeType(player, AbilityType.CLICK); - charging = true; - anim = AnimateState.RISE; - if(!getType(player, AbilityType.CLICK).isEmpty()) { - WaterWave clickSpear = getType(player, AbilityType.CLICK).get(0); - origin = clickSpear.origin.clone(); - currentLoc = origin.clone(); - - if (WaterMethods.isPlant(origin.getBlock())) - new Plantbending(origin.getBlock()); - } - - } - - removeType(player, AbilityType.CLICK); - if (!player.isSneaking()) { - if (System.currentTimeMillis() - time > chargeTime) { - WaterWave wwave = new WaterWave(player, block, AbilityType.RELEASE); - wwave.anim = AnimateState.SHRINK; - wwave.direction = direction; - } - remove(); - return; - } - - double animSpeed = 1.2; - if (anim == AnimateState.RISE && currentLoc != null) { - revertBlocks(); - currentLoc.add(0, animSpeed, 0); - Block block = currentLoc.getBlock(); - if (!(WaterMethods.isWaterbendable(block, player) || block.getType() == Material.AIR) || GeneralMethods.isRegionProtectedFromBuild(player, "WaterSpout", block.getLocation())) { - remove(); - return; - } - createBlock(block, Material.STATIONARY_WATER); - if (currentLoc.distance(origin) > 2) - anim = AnimateState.TOWARDPLAYER; - } else if (anim == AnimateState.TOWARDPLAYER) { - revertBlocks(); - Location eyeLoc = player.getTargetBlock((HashSet) null, 2).getLocation(); - eyeLoc.setY(player.getEyeLocation().getY()); - Vector vec = GeneralMethods.getDirection(currentLoc, eyeLoc); - currentLoc.add(vec.normalize().multiply(animSpeed)); - - Block block = currentLoc.getBlock(); - if (!(WaterMethods.isWaterbendable(block, player) || block.getType() == Material.AIR) || GeneralMethods.isRegionProtectedFromBuild(player, "WaterSpout", block.getLocation())) { - remove(); - return; - } - - createBlock(block, Material.STATIONARY_WATER); - if (currentLoc.distance(eyeLoc) < 1.3) { - anim = AnimateState.CIRCLE; - Vector tempDir = player.getLocation().getDirection(); - tempDir.setY(0); - direction = tempDir.normalize(); - revertBlocks(); - } - } else if (anim == AnimateState.CIRCLE) { - drawCircle(120, 5); - } - } else if (type == AbilityType.RELEASE) { - if (anim == AnimateState.SHRINK) { - radius -= 0.20; - drawCircle(360, 15); - if (radius < 1) { - revertBlocks(); - time = System.currentTimeMillis(); - anim = null; - } - } else { - if ((System.currentTimeMillis() - time > flightTime && !AvatarState.isAvatarState(player)) || player.isSneaking()) { - remove(); - return; - } - player.setFallDistance(0f); - double currentSpeed = speed - (speed * (double) (System.currentTimeMillis() - time) / (double) flightTime); - double nightSpeed = WaterMethods.waterbendingNightAugment(currentSpeed * 0.9, player.getWorld()); - currentSpeed = nightSpeed > currentSpeed ? nightSpeed : currentSpeed; - if (AvatarState.isAvatarState(player)) - currentSpeed = WaterMethods.waterbendingNightAugment(speed, player.getWorld()); - - player.setVelocity(player.getEyeLocation().getDirection().normalize().multiply(currentSpeed)); - for (Block block : GeneralMethods.getBlocksAroundPoint(player.getLocation().add(0, -1, 0), waveRadius)) - if (block.getType() == Material.AIR && !GeneralMethods.isRegionProtectedFromBuild(player, "WaterSpout", block.getLocation())) { - if (iceWave) - createBlockDelay(block, Material.ICE, (byte) 0, 2L); - else - createBlock(block, Material.STATIONARY_WATER, (byte) 0); - } - revertBlocksDelay(20L); - - if (iceWave && progressCounter % 3 == 0) { - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(player.getLocation().add(0, -1, 0), waveRadius * 1.5)) { - if (entity != this.player && entity instanceof LivingEntity && !affectedEntities.contains(entity)) { - affectedEntities.add(entity); - final double aug = WaterMethods.getWaterbendingNightAugment(player.getWorld()); - GeneralMethods.damageEntity(player, entity, aug * damage, Element.Water, SubElement.Icebending, "IceWave"); - final Player fplayer = this.player; - final Entity fent = entity; - new BukkitRunnable() { - public void run() { - createIceSphere(fplayer, fent, aug * 2.5); - } - }.runTaskLater(ProjectKorra.plugin, 6); - } - } - } - } - } - } - - public void drawCircle(double theta, double increment) { - double rotateSpeed = 45; - revertBlocks(); - direction = GeneralMethods.rotateXZ(direction, rotateSpeed); - for (double i = 0; i < theta; i += increment) { - Vector dir = GeneralMethods.rotateXZ(direction, i - theta / 2).normalize().multiply(radius); - dir.setY(0); - Block block = player.getEyeLocation().add(dir).getBlock(); - currentLoc = block.getLocation(); - if (block.getType() == Material.AIR && !GeneralMethods.isRegionProtectedFromBuild(player, "WaterSpout", block.getLocation())) - createBlock(block, Material.STATIONARY_WATER, (byte) 8); - } - } - - public void remove() { - instances.remove(this); - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - if (bPlayer != null) { - bPlayer.addCooldown("WaterWave", cooldown); - } - revertBlocks(); - for (BukkitRunnable task : tasks) - task.cancel(); - } - - public void createBlockDelay(final Block block, final Material mat, final byte data, long delay) { - BukkitRunnable br = new BukkitRunnable() { - @Override - public void run() { - createBlock(block, mat, data); - } - }; - br.runTaskLater(ProjectKorra.plugin, delay); - tasks.add(br); - } - - public void createBlock(Block block, Material mat) { - createBlock(block, mat, (byte) 0); - } - - public void createBlock(Block block, Material mat, byte data) { - affectedBlocks.put(block, new TempBlock(block, mat, data)); - } - - public void revertBlocks() { - Enumeration keys = affectedBlocks.keys(); - while (keys.hasMoreElements()) { - Block block = keys.nextElement(); - affectedBlocks.get(block).revertBlock(); - affectedBlocks.remove(block); - } - } - - public void revertBlocksDelay(long delay) { - Enumeration keys = affectedBlocks.keys(); - while (keys.hasMoreElements()) { - final Block block = keys.nextElement(); - final TempBlock tblock = affectedBlocks.get(block); - affectedBlocks.remove(block); - new BukkitRunnable() { - public void run() { - if (!frozenBlocks.containsKey(block)) - tblock.revertBlock(); - } - }.runTaskLater(ProjectKorra.plugin, delay); - } - } - - public void createIceSphere(Player player, Entity entity, double radius) { - for (double x = -radius; x <= radius; x += 0.5) - for (double y = -radius; y <= radius; y += 0.5) - for (double z = -radius; z <= radius; z += 0.5) { - Block block = entity.getLocation().getBlock().getLocation().add(x, y, z).getBlock(); - if (block.getLocation().distance(entity.getLocation().getBlock().getLocation()) > radius) - continue; - - if (block.getType() == Material.AIR || block.getType() == Material.ICE || WaterMethods.isWaterbendable(block, player)) { - - if (!frozenBlocks.containsKey(block)) { - TempBlock tblock = new TempBlock(block, Material.ICE, (byte) 1); - frozenBlocks.put(block, tblock); - } - } - } - } - - public static void progressAll() { - for (int i = 0; i < instances.size(); i++) - instances.get(i).progress(); - } - - public static void removeAll() { - for (int i = 0; i < instances.size(); i++) { - instances.get(i).remove(); - i--; - } - } - - public static boolean containsType(Player player, AbilityType type) { - for (int i = 0; i < instances.size(); i++) { - WaterWave wave = instances.get(i); - if (wave.player.equals(player) && wave.type.equals(type)) - return true; - } - return false; - } - - public static void removeType(Player player, AbilityType type) { - for (int i = 0; i < instances.size(); i++) { - WaterWave wave = instances.get(i); - if (wave.player.equals(player) && wave.type.equals(type)) { - instances.remove(i); - i--; - } - } - } - - public static ArrayList getType(Player player, AbilityType type) { - ArrayList list = new ArrayList(); - for (WaterWave spear : instances) { - if (spear.player.equals(player) && spear.type.equals(type)) - list.add(spear); - } - return list; - } - - public static boolean wasBrokenFor(Player player, Block block) { - if (containsType(player, AbilityType.CLICK)) { - WaterWave wwave = getType(player, AbilityType.CLICK).get(0); - if (wwave.origin == null) - return false; - if (wwave.origin.getBlock().equals(block)) - return true; - } - return false; - } - - public static boolean canThaw(Block block) { - return frozenBlocks.containsKey(block); - } - - public static void thaw(Block block) { - if (frozenBlocks.containsKey(block)) { - frozenBlocks.get(block).revertBlock(); - frozenBlocks.remove(block); - } - } - - public Player getPlayer() { - return player; - } - - public double getRadius() { - return radius; - } - - public static void setRadius(int range) { - selectRange = range; - } - - public double getRange() { - return selectRange; - } - - public void setRange(double radius) { - this.radius = radius; - } - - public double getSpeed() { - return speed; - } - - public void setSpeed(double speed) { - this.speed = speed; - } - - public double getChargeTime() { - return chargeTime; - } - - public void setChargeTime(double chargeTime) { - this.chargeTime = chargeTime; - } - - public double getFlightTime() { - return flightTime; - } - - public void setFlightTime(double flightTime) { - this.flightTime = flightTime; - } - - public double getWaveRadius() { - return waveRadius; - } - - public void setWaveRadius(double waveRadius) { - this.waveRadius = waveRadius; - } - - public double getDamage() { - return damage; - } - - public void setDamage(double damage) { - this.damage = damage; - } - - public void setIceWave(boolean b) { - this.iceWave = b; - } - - public boolean isIceWave() { - return this.iceWave; - } -} diff --git a/src/com/projectkorra/projectkorra/waterbending/WaterbendingManager.java b/src/com/projectkorra/projectkorra/waterbending/WaterbendingManager.java index dd0fff97..3c6d12d1 100644 --- a/src/com/projectkorra/projectkorra/waterbending/WaterbendingManager.java +++ b/src/com/projectkorra/projectkorra/waterbending/WaterbendingManager.java @@ -2,8 +2,6 @@ package com.projectkorra.projectkorra.waterbending; import com.projectkorra.projectkorra.ProjectKorra; -import org.bukkit.Bukkit; - public class WaterbendingManager implements Runnable { public ProjectKorra plugin; @@ -15,25 +13,11 @@ public class WaterbendingManager implements Runnable { @Override public void run() { WaterPassive.handlePassive(); - Plantbending.regrow(); - PlantArmor.progressAll(); - Bloodbending.progressAll(); - WaterSpout.handleSpouts(Bukkit.getServer()); - FreezeMelt.handleFrozenBlocks(); - OctopusForm.progressAll(); - Torrent.progressAll(); - TorrentBurst.progressAll(); - HealingWaters.heal(Bukkit.getServer()); - WaterReturn.progressAll(); - WaterManipulation.progressAll(); - WaterWall.progressAll(); - Wave.progressAll(); - IceSpike.progressAll(); - IceSpike2.progressAll(); - IceBlast.progressAll(); - WaterWave.progressAll(); - WaterCombo.progressAll(); - WaterArms.progressAll(); + PhaseChangeFreeze.handleFrozenBlocks(); + HealingWaters.heal(); + WaterSpout.progressAllCleanup(); + Torrent.progressAllCleanup(); + WaterArms.progressAllCleanup(); } } diff --git a/src/com/projectkorra/projectkorra/waterbending/Wave.java b/src/com/projectkorra/projectkorra/waterbending/Wave.java deleted file mode 100644 index 50df1149..00000000 --- a/src/com/projectkorra/projectkorra/waterbending/Wave.java +++ /dev/null @@ -1,534 +0,0 @@ -package com.projectkorra.projectkorra.waterbending; - -import com.projectkorra.projectkorra.BendingPlayer; -import com.projectkorra.projectkorra.GeneralMethods; -import com.projectkorra.projectkorra.ProjectKorra; -import com.projectkorra.projectkorra.ability.AvatarState; -import com.projectkorra.projectkorra.airbending.AirMethods; -import com.projectkorra.projectkorra.earthbending.EarthMethods; -import com.projectkorra.projectkorra.firebending.FireBlast; -import com.projectkorra.projectkorra.util.BlockSource; -import com.projectkorra.projectkorra.util.ClickType; -import com.projectkorra.projectkorra.util.TempBlock; - -import org.bukkit.Effect; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; - -public class Wave { - - public static ConcurrentHashMap instances = new ConcurrentHashMap(); - - private static final double defaultmaxradius = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.Surge.Wave.Radius"); - private static final double defaultfactor = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.Surge.Wave.HorizontalPush"); - private static final double defaultupfactor = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.Surge.Wave.VerticalPush"); - private static final double MAX_FREEZE_RADIUS = 7; - - private static final long interval = 30; - @SuppressWarnings("unused") - private static final byte full = 0x0; - static int defaultrange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.Surge.Wave.SelectRange"); - - public static boolean dynamic = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water.Surge.Wave.DynamicSourcing.Enabled"); - Player player; - private Location location = null; - private Block sourceblock = null; - private Location targetdestination = null; - private Vector targetdirection = null; - private ConcurrentHashMap wave = new ConcurrentHashMap(); - private ConcurrentHashMap frozenblocks = new ConcurrentHashMap(); - private long time; - private double radius = 1; - private double maxradius = defaultmaxradius; - private double factor = defaultfactor; - private double upfactor = defaultupfactor; - private double maxfreezeradius = MAX_FREEZE_RADIUS; - private boolean freeze = false; - private boolean activatefreeze = false; - private Location frozenlocation; - int range = defaultrange; - int maxrange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.Surge.Wave.Range"); - boolean progressing = false; - boolean canhitself = true; - - public Wave(Player player) { - this.player = player; - - if (instances.containsKey(player.getEntityId())) { - if (instances.get(player.getEntityId()).progressing && !instances.get(player.getEntityId()).freeze) { - instances.get(player.getEntityId()).freeze = true; - return; - } - } - - if (AvatarState.isAvatarState(player)) { - maxradius = AvatarState.getValue(maxradius); - } - maxradius = WaterMethods.waterbendingNightAugment(maxradius, player.getWorld()); - if (prepare()) { - if (instances.containsKey(player.getEntityId())) { - instances.get(player.getEntityId()).cancel(); - } - instances.put(player.getEntityId(), this); - time = System.currentTimeMillis(); - } - - } - - public boolean prepare() { - cancelPrevious(); - // Block block = player.getTargetBlock(null, (int) range); - Block block = BlockSource.getWaterSourceBlock(player, range, range, ClickType.SHIFT_DOWN, false, dynamic, true, true, WaterMethods.canPlantbend(player), WaterMethods.canPlantbend(player)); - if (block != null) { - sourceblock = block; - focusBlock(); - return true; - } - return false; - } - - private void cancelPrevious() { - if (instances.containsKey(player.getEntityId())) { - Wave old = instances.get(player.getEntityId()); - if (old.progressing) { - old.breakBlock(); - old.thaw(); - old.returnWater(old.location); - } else { - old.cancel(); - } - } - } - - public void cancel() { - unfocusBlock(); - } - - private void focusBlock() { - location = sourceblock.getLocation(); - } - - private void unfocusBlock() { - instances.remove(player.getEntityId()); - } - - @SuppressWarnings("deprecation") - public void moveWater() { - BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); - - if (bPlayer.isOnCooldown("Surge")) - return; - bPlayer.addCooldown("Surge", GeneralMethods.getGlobalCooldown()); - if (sourceblock != null) { - if (!sourceblock.getWorld().equals(player.getWorld())) { - return; - } - if (AvatarState.isAvatarState(player)) - factor = AvatarState.getValue(factor); - Entity target = GeneralMethods.getTargetedEntity(player, maxrange, new ArrayList()); - if (target == null) { - targetdestination = player.getTargetBlock(EarthMethods.getTransparentEarthbending(), maxrange).getLocation(); - } else { - targetdestination = ((LivingEntity) target).getEyeLocation(); - } - if (targetdestination.distance(location) <= 1) { - progressing = false; - targetdestination = null; - } else { - progressing = true; - targetdirection = getDirection(sourceblock.getLocation(), targetdestination).normalize(); - targetdestination = location.clone().add(targetdirection.clone().multiply(maxrange)); - if (WaterMethods.isPlant(sourceblock)) - new Plantbending(sourceblock); - if (!GeneralMethods.isAdjacentToThreeOrMoreSources(sourceblock)) { - sourceblock.setType(Material.AIR); - } - addWater(sourceblock); - - } - - } - } - - private Vector getDirection(Location location, Location destination) { - double x1, y1, z1; - double x0, y0, z0; - - x1 = destination.getX(); - y1 = destination.getY(); - z1 = destination.getZ(); - - x0 = location.getX(); - y0 = location.getY(); - z0 = location.getZ(); - - return new Vector(x1 - x0, y1 - y0, z1 - z0); - - } - - public static void progressAll() { - for (int ID : instances.keySet()) { - instances.get(ID).progress(); - } - } - - private boolean progress() { - if (player.isDead() || !player.isOnline() || !GeneralMethods.canBend(player.getName(), "Surge")) { - breakBlock(); - thaw(); - // instances.remove(player.getEntityId()); - return false; - } - if (System.currentTimeMillis() - time >= interval) { - time = System.currentTimeMillis(); - - if (GeneralMethods.getBoundAbility(player) == null) { - unfocusBlock(); - thaw(); - breakBlock(); - returnWater(location); - return false; - } - if (!progressing && !GeneralMethods.getBoundAbility(player).equalsIgnoreCase("Surge")) { - unfocusBlock(); - return false; - } - - if (!progressing) { - sourceblock.getWorld().playEffect(location, Effect.SMOKE, 4, range); - return false; - } - - if (location.getWorld() != player.getWorld()) { - thaw(); - breakBlock(); - return false; - } - - if (activatefreeze) { - if (location.distance(player.getLocation()) > maxrange) { - progressing = false; - thaw(); - breakBlock(); - return false; - } - if (GeneralMethods.getBoundAbility(player) == null) { - progressing = false; - thaw(); - breakBlock(); - returnWater(location); - return false; - } - if (!GeneralMethods.canBend(player.getName(), "Surge")) { - progressing = false; - thaw(); - breakBlock(); - returnWater(location); - return false; - } - - } else { - - Vector direction = targetdirection; - - location = location.clone().add(direction); - Block blockl = location.getBlock(); - - ArrayList blocks = new ArrayList(); - - if (!GeneralMethods.isRegionProtectedFromBuild(player, "Surge", location) && (((blockl.getType() == Material.AIR || blockl.getType() == Material.FIRE || WaterMethods.isPlant(blockl) || WaterMethods.isWater(blockl) || WaterMethods.isWaterbendable(blockl, player))) && blockl.getType() != Material.LEAVES)) { - - for (double i = 0; i <= radius; i += .5) { - for (double angle = 0; angle < 360; angle += 10) { - Vector vec = GeneralMethods.getOrthogonalVector(targetdirection, angle, i); - Block block = location.clone().add(vec).getBlock(); - if (!blocks.contains(block) && (block.getType() == Material.AIR || block.getType() == Material.FIRE) || WaterMethods.isWaterbendable(block, player)) { - blocks.add(block); - FireBlast.removeFireBlastsAroundPoint(block.getLocation(), 2); - } - - if (GeneralMethods.rand.nextInt(15) == 0) { - WaterMethods.playWaterbendingSound(location); - } - // if (!blocks.contains(block) - // && (Methods.isPlant(block) && block.getType() != - // Material.LEAVES)) { - // blocks.add(block); - // block.breakNaturally(); - // } - } - } - } - - for (Block block : wave.keySet()) { - if (!blocks.contains(block)) - finalRemoveWater(block); - } - - for (Block block : blocks) { - if (!wave.containsKey(block)) - addWater(block); - } - - if (wave.isEmpty()) { - // blockl.setType(Material.GLOWSTONE); - breakBlock(); - returnWater(location.subtract(direction)); - progressing = false; - return false; - } - - for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2 * radius)) { - - boolean knockback = false; - for (Block block : wave.keySet()) { - if (entity.getLocation().distance(block.getLocation()) <= 2) { - if (entity instanceof LivingEntity && freeze && entity.getEntityId() != player.getEntityId()) { - activatefreeze = true; - frozenlocation = entity.getLocation(); - freeze(); - break; - } - if (entity.getEntityId() != player.getEntityId() || canhitself) - knockback = true; - } - } - if (knockback) { - Vector dir = direction.clone(); - dir.setY(dir.getY() * upfactor); - GeneralMethods.setVelocity(entity, entity.getVelocity().clone().add(dir.clone().multiply(WaterMethods.waterbendingNightAugment(factor, player.getWorld())))); - entity.setFallDistance(0); - if (entity.getFireTicks() > 0) - entity.getWorld().playEffect(entity.getLocation(), Effect.EXTINGUISH, 0); - entity.setFireTicks(0); - AirMethods.breakBreathbendingHold(entity); - } - - } - - if (!progressing) { - breakBlock(); - return false; - } - - if (location.distance(targetdestination) < 1) { - progressing = false; - breakBlock(); - returnWater(location); - return false; - } - - if (radius < maxradius) - radius += .5; - - return true; - } - } - - return false; - - } - - private void breakBlock() { - for (Block block : wave.keySet()) { - finalRemoveWater(block); - } - instances.remove(player.getEntityId()); - } - - private void finalRemoveWater(Block block) { - if (wave.containsKey(block)) { - // block.setType(Material.WATER); - // block.setData(half); - // if (!Methods.adjacentToThreeOrMoreSources(block) || radius > 1) { - // block.setType(Material.AIR); - // } - TempBlock.revertBlock(block, Material.AIR); - wave.remove(block); - } - } - - private void addWater(Block block) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "Surge", block.getLocation())) - return; - if (!TempBlock.isTempBlock(block)) { - new TempBlock(block, Material.STATIONARY_WATER, (byte) 8); - // new TempBlock(block, Material.ICE, (byte) 0); - wave.put(block, block); - } - // block.setType(Material.WATER); - // block.setData(full); - // wave.put(block, block); - } - - private void clearWave() { - for (Block block : wave.keySet()) { - TempBlock.revertBlock(block, Material.AIR); - } - wave.clear(); - } - - public static void moveWater(Player player) { - if (instances.containsKey(player.getEntityId())) { - instances.get(player.getEntityId()).moveWater(); - } - } - - public static boolean progress(int ID) { - return instances.get(ID).progress(); - } - - public static boolean isBlockWave(Block block) { - for (int ID : instances.keySet()) { - if (instances.get(ID).wave.containsKey(block)) - return true; - } - return false; - } - - public static void launch(Player player) { - moveWater(player); - } - - public static void removeAll() { - for (int id : instances.keySet()) { - for (Block block : instances.get(id).wave.keySet()) { - block.setType(Material.AIR); - instances.get(id).wave.remove(block); - } - for (Block block : instances.get(id).frozenblocks.keySet()) { - block.setType(Material.AIR); - instances.get(id).frozenblocks.remove(block); - } - } - } - - private void freeze() { - - clearWave(); - - if (!WaterMethods.canIcebend(player)) - return; - - double freezeradius = radius; - if (freezeradius > maxfreezeradius) { - freezeradius = maxfreezeradius; - } - - for (Block block : GeneralMethods.getBlocksAroundPoint(frozenlocation, freezeradius)) { - if (GeneralMethods.isRegionProtectedFromBuild(player, "Surge", block.getLocation()) || GeneralMethods.isRegionProtectedFromBuild(player, "PhaseChange", block.getLocation())) - continue; - if (TempBlock.isTempBlock(block)) - continue; - if (block.getType() == Material.AIR || block.getType() == Material.SNOW) { - // block.setType(Material.ICE); - new TempBlock(block, Material.ICE, (byte) 0); - frozenblocks.put(block, block); - } - if (WaterMethods.isWater(block)) { - FreezeMelt.freeze(player, block); - } - if (WaterMethods.isPlant(block) && block.getType() != Material.LEAVES) { - block.breakNaturally(); - // block.setType(Material.ICE); - new TempBlock(block, Material.ICE, (byte) 0); - frozenblocks.put(block, block); - } - for (Block sound : frozenblocks.keySet()) { - if (GeneralMethods.rand.nextInt(4) == 0) { - WaterMethods.playWaterbendingSound(sound.getLocation()); - } - } - } - } - - private void thaw() { - for (Block block : frozenblocks.keySet()) { - // if (block.getType() == Material.ICE) { - // // block.setType(Material.WATER); - // // block.setData((byte) 0x7); - // block.setType(Material.AIR); - // } - TempBlock.revertBlock(block, Material.AIR); - frozenblocks.remove(block); - } - } - - public static void thaw(Block block) { - for (int id : instances.keySet()) { - if (instances.get(id).frozenblocks.containsKey(block)) { - // if (block.getType() == Material.ICE) { - // // block.setType(Material.WATER); - // // block.setData((byte) 0x7); - // block.setType(Material.AIR); - // } - TempBlock.revertBlock(block, Material.AIR); - instances.get(id).frozenblocks.remove(block); - } - } - } - - public static boolean canThaw(Block block) { - for (int id : instances.keySet()) { - if (instances.get(id).frozenblocks.containsKey(block)) { - return false; - } - } - return true; - } - - void returnWater(Location location) { - if (location != null) { - new WaterReturn(player, location.getBlock()); - } - } - - public static String getDescription() { - return "To use, place your cursor over a waterbendable object " + "(water, ice, plants if you have plantbending) and tap sneak " + "(default: shift). Smoke will appear where you've selected, " + "indicating the origin of your ability. After you have selected an origin, " + "simply left-click in any direction and you will see your water spout off in that " + "direction and form a large wave, knocking back all within its path. " + "If you look towards a creature when you use this ability, it will target that creature. " + "Additionally, tapping sneak while the wave is en route will cause that wave to encase the " + "first target it hits in ice."; - } - - public Player getPlayer() { - return player; - } - - public double getMaxradius() { - return maxradius; - } - - public void setMaxradius(double maxradius) { - this.maxradius = maxradius; - } - - public double getFactor() { - return factor; - } - - public void setFactor(double factor) { - this.factor = factor; - } - - public double getUpfactor() { - return upfactor; - } - - public void setUpfactor(double upfactor) { - this.upfactor = upfactor; - } - - public double getMaxfreezeradius() { - return maxfreezeradius; - } - - public void setMaxfreezeradius(double maxfreezeradius) { - this.maxfreezeradius = maxfreezeradius; - } - -} \ No newline at end of file diff --git a/src/plugin.yml b/src/plugin.yml index 8bef7d9a..22cd542f 100644 --- a/src/plugin.yml +++ b/src/plugin.yml @@ -1,6 +1,6 @@ name: ProjectKorra author: ProjectKorra -version: 1.8.0 BETA 9 +version: 1.8.0 BETA 6 main: com.projectkorra.projectkorra.ProjectKorra softdepend: [PreciousStones, WorldGuard, WorldEdit, Factions, MassiveCore, GriefPrevention, Towny, NoCheatPlus, LWC] commands: @@ -33,10 +33,6 @@ permissions: bending.command.give: true bending.command.invincible: true bending.command.check: true - bending.command.preset.bind.assign: true - bending.command.preset.bind.external: true - bending.command.preset.bind.external.assign: true - bending.command.copy.assign: true bending.admin.debug: true bending.admin.remove: true bending.player: @@ -46,7 +42,6 @@ permissions: bending.command.bind: true bending.command.display: true bending.command.toggle: true - bending.command.copy: true bending.command.choose: true bending.command.version: true bending.command.help: true