diff --git a/.gitignore b/.gitignore index 896e76f6..9cf427c9 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,9 @@ Icon .Trashes bin/ -*.classpath \ No newline at end of file +*.classpath +.idea/.name +*.xml +*.class +*.class +ProjectKorra.iml \ No newline at end of file diff --git a/out/production/ProjectKorra/plugin.yml b/out/production/ProjectKorra/plugin.yml new file mode 100644 index 00000000..37e8afeb --- /dev/null +++ b/out/production/ProjectKorra/plugin.yml @@ -0,0 +1,156 @@ +name: ProjectKorra +author: ProjectKorra +version: 1.6.0 BETA 14 +main: com.projectkorra.ProjectKorra.ProjectKorra +softdepend: [PreciousStones, WorldGuard, WorldEdit, Factions, MassiveCore, GriefPrevention, Towny, NoCheatPlus, LWC] +commands: + projectkorra: + aliases: [b,bending,mtla,tla,korra,pk,bend] + usage: / +permissions: + bending.admin: + default: op + description: Grants access to all commands and abilities. + children: + bending.player: true + bending.command.reload: true + bending.admin.permaremove: true + bending.command.avatar: true + bending.command.add.others: true + bending.command.add: true + bending.command.rechoose: true + bending.admin.choose: true + bending.ability.AvatarState: true + bending.ability.Bloodbending: true + bending.ability.Flight: true + bending.command.import: true + bending.command.toggle.all: true + bending.command.give: true + bending.command.invincible: true + bending.admin.debug: true + bending.admin.remove: true + bending.player: + default: true + description: Grants access to most abilities and basic commands. + children: + bending.command.bind: true + bending.command.display: true + bending.command.toggle: true + bending.command.choose: true + bending.command.version: true + bending.command.help: true + bending.command.clear: true + bending.command.who: true + bending.command.preset.list: true + bending.command.preset.create.2: true + bending.command.preset.create: true + bending.command.preset.bind: true + bending.command.preset.delete: true + bending.air: true + bending.water: true + bending.earth: true + bending.fire: true + bending.chi: true + bending.air: + default: true + description: Grants access to all airbending abilities. + children: + bending.ability.AirBlast: true + bending.ability.AirBubble: true + bending.ability.AirBurst: true + bending.ability.AirScooter: true + bending.ability.AirShield: true + bending.ability.AirSpout: true + bending.ability.AirSuction: true + bending.ability.AirSwipe: true + bending.ability.Suffocate: true + bending.ability.Tornado: true + bending.ability.AirCombo: true + bending.air.passive: true + bending.air.flight: true + bending.water: + default: true + description: Grants access to most waterbending abilities. + children: + bending.ability.HealingWaters: true + bending.ability.IceBlast: true + bending.ability.IceSpike: true + bending.ability.OctopusForm: true + bending.ability.PhaseChange: true + bending.ability.Surge: true + bending.ability.Torrent: true + bending.ability.WaterBubble: true + bending.ability.WaterManipulation: true + bending.ability.WaterSpout: true + bending.ability.WaterSpout.Wave: true + bending.ability.WaterCombo: true + bending.water.plantbending: true + bending.message.nightmessage: true + bending.water.passive: true + bending.water.icebending: true + bending.water.healing: true + bending.earth: + default: true + description: Grants access to all Earthbending abilities. + children: + bending.ability.Catapult: true + bending.ability.Collapse: true + bending.ability.EarthArmor: true + bending.ability.EarthBlast: true + bending.ability.EarthGrab: true + bending.ability.EarthTunnel: true + bending.ability.RaiseEarth: true + bending.ability.Shockwave: true + bending.ability.Tremorsense: true + bending.ability.Extraction: true + bending.ability.MetalClips: true + bending.ability.MetalClips.loot: false + bending.ability.MetalClips.4clips: false + bending.earth.passive: true + bending.earth.metalbending: true + bending.earth.lavabending: true + bending.earth.sandbending: true + bending.earth.grapplinghook: true + bending.ability.LavaSurge: true + bending.ability.LavaFlow: true + bending.ability.EarthSmash: true + bending.fire: + default: true + description: Grants access to all firebending abilities. + children: + bending.ability.Blaze: true + bending.ability.FireBlast: true + bending.ability.FireBurst: true + bending.ability.FireJet: true + bending.ability.FireShield: true + bending.ability.HeatControl: true + bending.ability.Illumination: true + bending.ability.Lightning: true + bending.ability.WallOfFire: true + bending.ability.Combustion: true + bending.ability.FireCombo: true + bending.message.daymessage: true + bending.fire.passive: true + bending.fire.lightningbending: true + bending.fire.combustionbending: true + bending.chi: + default: true + description: Grants access to all ChiBlocking abilities. + children: + bending.ability.HighJump: true + bending.ability.Paralyze: true + bending.ability.RapidPunch: true + bending.ability.Smokescreen: true + bending.ability.WarriorStance: true + bending.ability.AcrobatStance: true + bending.ability.QuickStrike: true + bending.ability.SwiftKick: true + bending.ability.ChiCombo: true + bending.chi.passive: true + bending.chi.grapplinghook: true + bending.avatar: + default: false + description: Grants the Avatar Color. + bending.ability.MetalClips.loot: + default: false + description: Lets a Metalbender loot a player's inventory of its iron. \ No newline at end of file diff --git a/src/com/projectkorra/ProjectKorra/Ability/Combo/ComboAbilityModule.java b/src/com/projectkorra/ProjectKorra/Ability/Combo/ComboAbilityModule.java new file mode 100644 index 00000000..046ebf9f --- /dev/null +++ b/src/com/projectkorra/ProjectKorra/Ability/Combo/ComboAbilityModule.java @@ -0,0 +1,127 @@ +package com.projectkorra.ProjectKorra.Ability.Combo; + +import com.projectkorra.ProjectKorra.ComboManager; +import com.projectkorra.ProjectKorra.SubElement; +import com.projectkorra.ProjectKorra.Utilities.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); + // TODO Auto-generated constructor stub + } + + /** + * 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 new file mode 100644 index 00000000..6b52ad87 --- /dev/null +++ b/src/com/projectkorra/ProjectKorra/Ability/Combo/ComboModuleManager.java @@ -0,0 +1,41 @@ +package com.projectkorra.ProjectKorra.Ability.Combo; + +import com.projectkorra.ProjectKorra.ComboManager; +import com.projectkorra.ProjectKorra.ProjectKorra; +import com.projectkorra.ProjectKorra.Utilities.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.add(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/ComboManager.java b/src/com/projectkorra/ProjectKorra/ComboManager.java index bd51d4d8..82e84cd2 100644 --- a/src/com/projectkorra/ProjectKorra/ComboManager.java +++ b/src/com/projectkorra/ProjectKorra/ComboManager.java @@ -1,15 +1,16 @@ package com.projectkorra.ProjectKorra; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.concurrent.ConcurrentHashMap; - -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; - +import com.projectkorra.ProjectKorra.Ability.Combo.ComboAbilityModule; import com.projectkorra.ProjectKorra.airbending.AirCombo; import com.projectkorra.ProjectKorra.firebending.FireCombo; import com.projectkorra.ProjectKorra.waterbending.WaterCombo; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; public class ComboManager { @@ -19,6 +20,9 @@ public class ComboManager private static final long CLEANUP_DELAY = 10000; public static ConcurrentHashMap> recentlyUsedAbilities = new ConcurrentHashMap>(); public static ArrayList comboAbilityList = new ArrayList(); + public static HashMap descriptions = new HashMap(); + public static HashMap instructions = new HashMap(); + public static HashMap authors = new HashMap(); public ComboManager() { @@ -120,24 +124,38 @@ public class ComboManager public static void addComboAbility(Player player, ClickType type) { String abilityName = Methods.getBoundAbility(player); - if(abilityName == null) + if (abilityName == null) return; - - AbilityInformation info = new AbilityInformation(abilityName,type,System.currentTimeMillis()); - addRecentAbility(player,info); - + + AbilityInformation info = new AbilityInformation(abilityName, type, System.currentTimeMillis()); + addRecentAbility(player, info); + ComboAbility comboAbil = checkForValidCombo(player); - if(comboAbil == null) + if (comboAbil == null) return; - - if(comboAbil.getComboType().equals(FireCombo.class)) + + if (comboAbil.getComboType().equals(FireCombo.class)) new FireCombo(player, comboAbil.getName()); - else if(comboAbil.getComboType().equals(AirCombo.class)) + else if (comboAbil.getComboType().equals(AirCombo.class)) new AirCombo(player, comboAbil.getName()); - else if(comboAbil.getComboType().equals(WaterCombo.class)) + else if (comboAbil.getComboType().equals(WaterCombo.class)) new WaterCombo(player, comboAbil.getName()); + else + { + for (ComboAbility ca : comboAbilityList) + { + if (comboAbil.getName().equals(ca.getName())) + { + if (ca.getComboType() instanceof ComboAbilityModule) + { + ((ComboAbilityModule) ca.getComboType()).createNewComboInstance(player); + return; + } + } + } + } } - + public static class AbilityInformation { private String abilityName; diff --git a/src/com/projectkorra/ProjectKorra/Commands.java b/src/com/projectkorra/ProjectKorra/Commands.java index 113f5fbc..3b94dc3a 100644 --- a/src/com/projectkorra/ProjectKorra/Commands.java +++ b/src/com/projectkorra/ProjectKorra/Commands.java @@ -1,6 +1,8 @@ package com.projectkorra.ProjectKorra; import com.projectkorra.ProjectKorra.Ability.AbilityModuleManager; +import com.projectkorra.ProjectKorra.Ability.Combo.ComboAbilityModule; +import com.projectkorra.ProjectKorra.Ability.Combo.ComboModuleManager; import com.projectkorra.ProjectKorra.Ability.StockAbilities; import com.projectkorra.ProjectKorra.Objects.Preset; import com.projectkorra.ProjectKorra.Utilities.GrapplingHookAPI; @@ -843,9 +845,10 @@ public class Commands { s.sendMessage(Methods.getSubBendingColor(Element.Water) + " Can Plantbend"); } if (Methods.canBloodbend(p)) { - s.sendMessage(Methods.getSubBendingColor(Element.Water) + " Can Bloodbend"); if(Methods.canBloodbendAtAnytime(p)) - s.sendMessage(Methods.getSubBendingColor(Element.Water) + " Anytime, on any day"); + s.sendMessage(Methods.getSubBendingColor(Element.Water) + " Can Bloodbend anytime, on any day"); + else + s.sendMessage(Methods.getSubBendingColor(Element.Water) + " Can Bloodbend"); } if (Methods.canIcebend(p)) { s.sendMessage(Methods.getSubBendingColor(Element.Water) + " Can Icebend"); @@ -1447,6 +1450,18 @@ public class Commands { s.sendMessage(ChatColor.GOLD + "FireJet (Tap Shift) > FireJet (Tap Shift) > FireShield (Tap Shift) > FireJet. "); s.sendMessage(Methods.getFireColor() + "JetBlaze" + ChatColor.WHITE + ": Damages and burns all enemies in the proximity of your FireJet."); s.sendMessage(ChatColor.GOLD + "FireJet (Tap Shift) > FireJet (Tap Shift) > Blaze (Tap Shift) > FireJet. "); + for(ComboAbilityModule cam : ComboModuleManager.combo) + { + if(cam.getElement().equals(Element.Fire.toString())) + { + ChatColor color = Methods.getAvatarColor(); + if(cam.getSubElement() == null) + color = Methods.getFireColor(); + else color = Methods.getSubBendingColor(Element.Fire); + s.sendMessage(color + cam.getName() + ChatColor.WHITE + ": " + cam.getDescription()); + s.sendMessage(ChatColor.GOLD + cam.getInstructions()); + } + } } if (args[1].equalsIgnoreCase("AirCombo")) { s.sendMessage(ChatColor.GOLD + "AirCombo:"); @@ -1456,19 +1471,70 @@ public class Commands { s.sendMessage(ChatColor.GOLD + "AirShield (Hold Shift) > AirSuction (Left Click) > AirBlast (Left Click)"); s.sendMessage(Methods.getAirColor() + "AirSweep" + ChatColor.WHITE + ": 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"); s.sendMessage(ChatColor.GOLD + "AirSwipe (Left Click) > AirSwipe (Left Click) > AirBurst (Hold Shift) > AirBurst (Left Click)"); + for(ComboAbilityModule cam : ComboModuleManager.combo) + { + if(cam.getElement().equals(Element.Air.toString())) + { + ChatColor color = Methods.getAvatarColor(); + if(cam.getSubElement() == null) + color = Methods.getAirColor(); + else color = Methods.getSubBendingColor(Element.valueOf(cam.getElement())); + s.sendMessage(color + cam.getName() + ChatColor.WHITE + ": " + cam.getDescription()); + s.sendMessage(ChatColor.GOLD + cam.getInstructions()); + } + } } if (args[1].equalsIgnoreCase("WaterCombo")) { s.sendMessage(ChatColor.GOLD + "WaterCombos:"); - s.sendMessage(Methods.getAirColor() + "IceWave" + ChatColor.WHITE + ": PhaseChange your WaterWave into an IceWave that freezes and damages enemies."); + s.sendMessage(Methods.getWaterColor() + "IceWave" + ChatColor.WHITE + ": PhaseChange your WaterWave into an IceWave that freezes and damages enemies."); s.sendMessage(ChatColor.GOLD + "Create a WaterSpout Wave > PhaseChange (Left Click)"); - s.sendMessage(Methods.getAirColor() + "IceBullet" + ChatColor.WHITE + ": 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."); + s.sendMessage(Methods.getWaterColor() + "IceBullet" + ChatColor.WHITE + ": 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."); s.sendMessage(ChatColor.GOLD + "WaterBubble (Tap Shift) > IceBlast (Hold Shift) > IceBlast (Left Click) > Wait for ice to Form > Then alternate between Left and Right click with IceBlast"); + for(ComboAbilityModule cam : ComboModuleManager.combo) + { + if(cam.getElement().equals(Element.Water.toString())) + { + ChatColor color = Methods.getAvatarColor(); + if(cam.getSubElement() == null) + color = Methods.getWaterColor(); + else color = Methods.getSubBendingColor(Element.valueOf(cam.getElement())); + s.sendMessage(color + cam.getName() + ChatColor.WHITE + ": " + cam.getDescription()); + s.sendMessage(ChatColor.GOLD + cam.getInstructions()); + } + } + } + if (args[1].equalsIgnoreCase("EarthCombo")) { + s.sendMessage(ChatColor.GOLD + "EarthCombos:"); + for(ComboAbilityModule cam : ComboModuleManager.combo) + { + if(cam.getElement().equals(Element.Earth.toString())) + { + ChatColor color = Methods.getAvatarColor(); + if(cam.getSubElement() == null) + color = Methods.getEarthColor(); + else color = Methods.getSubBendingColor(Element.valueOf(cam.getElement())); + s.sendMessage(color + cam.getName() + ChatColor.WHITE + ": " + cam.getDescription()); + s.sendMessage(ChatColor.GOLD + cam.getInstructions()); + } + } } if (args[1].equalsIgnoreCase("ChiCombo")) { s.sendMessage(ChatColor.GOLD + "ChiCombos:"); s.sendMessage(Methods.getChiColor() + "Immobilize" + ChatColor.WHITE + ": Deliver a series of strikes to an enemy to temporarely immobilize them."); s.sendMessage(ChatColor.GOLD + "QuickStrike > SwiftKick > QuickStrike > QuickStrike"); + for(ComboAbilityModule cam : ComboModuleManager.combo) + { + if(cam.getElement().equals(Element.Chi.toString())) + { + ChatColor color = Methods.getAvatarColor(); + if(cam.getSubElement() == null) + color = Methods.getChiColor(); + else color = Methods.getSubBendingColor(Element.valueOf(cam.getElement())); + s.sendMessage(color + cam.getName() + ChatColor.WHITE + ": " + cam.getDescription()); + s.sendMessage(ChatColor.GOLD + cam.getInstructions()); + } + } } if (Methods.abilityExists(args[1])) { String ability = Methods.getAbility(args[1]); diff --git a/src/com/projectkorra/ProjectKorra/ConfigManager.java b/src/com/projectkorra/ProjectKorra/ConfigManager.java index dafee7f2..c61fbeb6 100644 --- a/src/com/projectkorra/ProjectKorra/ConfigManager.java +++ b/src/com/projectkorra/ProjectKorra/ConfigManager.java @@ -66,6 +66,9 @@ public class ConfigManager { config.addDefault("Properties.GlobalCooldown", 500); config.addDefault("Properties.SeaLevel", 62); + config.addDefault("Properties.HorizontalCollisionPhysics.Enabled", true); + config.addDefault("Properties.HorizontalCollisionPhysics.WallDamageMinimumDistance", 5.0); + config.addDefault("Properties.CustomItems.GrapplingHook.Enable", true); config.addDefault("Properties.CustomItems.GrapplingHook.IronUses", 25); config.addDefault("Properties.CustomItems.GrapplingHook.GoldUses", 50); diff --git a/src/com/projectkorra/ProjectKorra/Methods.java b/src/com/projectkorra/ProjectKorra/Methods.java index 3501d47b..88521f63 100644 --- a/src/com/projectkorra/ProjectKorra/Methods.java +++ b/src/com/projectkorra/ProjectKorra/Methods.java @@ -17,6 +17,8 @@ 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.AvatarState; +import com.projectkorra.ProjectKorra.Ability.Combo.ComboAbilityModule; +import com.projectkorra.ProjectKorra.Ability.Combo.ComboModuleManager; import com.projectkorra.ProjectKorra.Ability.StockAbilities; import com.projectkorra.ProjectKorra.Utilities.ParticleEffect; import com.projectkorra.ProjectKorra.airbending.*; @@ -98,6 +100,24 @@ public class Methods { return false; } + public static boolean comboExists(String string) + { + for(ComboAbilityModule c : ComboModuleManager.combo) + if(string.equalsIgnoreCase(c.getName())) + return true; + + return false; + } + + public ComboAbilityModule getCombo(String name) + { + for(ComboAbilityModule c : ComboModuleManager.combo) + if(name.equalsIgnoreCase(c.getName())) + return c; + + return null; + } + public static boolean isDisabledStockAbility(String string){ for (String st : AbilityModuleManager.disabledStockAbilities){ if (string.equalsIgnoreCase(st)) diff --git a/src/com/projectkorra/ProjectKorra/Objects/HorizontalVelocityTracker.java b/src/com/projectkorra/ProjectKorra/Objects/HorizontalVelocityTracker.java index 48f1a74a..7d558f29 100644 --- a/src/com/projectkorra/ProjectKorra/Objects/HorizontalVelocityTracker.java +++ b/src/com/projectkorra/ProjectKorra/Objects/HorizontalVelocityTracker.java @@ -3,11 +3,13 @@ package com.projectkorra.ProjectKorra.Objects; import com.projectkorra.ProjectKorra.Methods; import com.projectkorra.ProjectKorra.ProjectKorra; import com.projectkorra.ProjectKorra.Utilities.HorizontalVelocityChangeEvent; +import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.util.Vector; +import java.util.List; import java.util.concurrent.ConcurrentHashMap; /** @@ -23,14 +25,19 @@ public class HorizontalVelocityTracker private Player instigator; private Vector lastVelocity; private Vector thisVelocity; + private Location launchLocation; + private Location impactLocation; public HorizontalVelocityTracker(Entity e, Player instigator, long delay) { + remove(e); entity = e; this.instigator = instigator; fireTime = System.currentTimeMillis(); this.delay = delay; - thisVelocity = e.getVelocity(); + thisVelocity = e.getVelocity().clone(); + launchLocation = e.getLocation().clone(); + impactLocation = launchLocation.clone(); this.delay = delay; update(); instances.put(entity, this); @@ -46,19 +53,34 @@ public class HorizontalVelocityTracker Vector diff = thisVelocity.subtract(lastVelocity); + List blocks = Methods.getBlocksAroundPoint(entity.getLocation(), 1.5); + if(entity.isOnGround()) + { remove(); + return; + } + + for(Block b : blocks) + { + if(Methods.isWater(b)) + { + remove(); + return; + } + } if(thisVelocity.length() < lastVelocity.length()) { if((diff.getX() > 1 || diff.getX() < -1) || (diff.getZ() > 1 || diff.getZ() < -1)) { - for(Block b : Methods.getBlocksAroundPoint(entity.getLocation(), 2)) + impactLocation = entity.getLocation(); + for (Block b : blocks) { - if(!Methods.isTransparentToEarthbending(instigator, b)) + if (!Methods.isTransparentToEarthbending(instigator, b)) { - ProjectKorra.plugin.getServer().getPluginManager().callEvent(new HorizontalVelocityChangeEvent(entity, instigator, lastVelocity, thisVelocity, diff)); + ProjectKorra.plugin.getServer().getPluginManager().callEvent(new HorizontalVelocityChangeEvent(entity, instigator, lastVelocity, thisVelocity, diff, launchLocation, impactLocation)); remove(); return; } diff --git a/src/com/projectkorra/ProjectKorra/PKListener.java b/src/com/projectkorra/ProjectKorra/PKListener.java index 8243d7ef..ca11ba8e 100644 --- a/src/com/projectkorra/ProjectKorra/PKListener.java +++ b/src/com/projectkorra/ProjectKorra/PKListener.java @@ -13,10 +13,7 @@ import com.projectkorra.ProjectKorra.earthbending.LavaFlow.AbilityType; import com.projectkorra.ProjectKorra.firebending.*; import com.projectkorra.ProjectKorra.firebending.Fireball; import com.projectkorra.ProjectKorra.waterbending.*; -import org.bukkit.ChatColor; -import org.bukkit.GameMode; -import org.bukkit.Location; -import org.bukkit.Material; +import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.entity.*; import org.bukkit.event.EventHandler; @@ -67,9 +64,18 @@ public class PKListener implements Listener { @EventHandler public void onHorizontalCollision(HorizontalVelocityChangeEvent e) { + if(!plugin.getConfig().getBoolean("Properties.HorizontalCollisionPhysics.Enabled")) + return; + if(e.getEntity() instanceof LivingEntity) { - Methods.damageEntity(e.getInstigator(), e.getEntity(), e.getDifference().length() * 2); + if(e.getEntity().getEntityId() != e.getInstigator().getEntityId()) + { + double minimumDistance = plugin.getConfig().getDouble("Properties.HorizontalCollisionPhysics.WallDamageMinimumDistance"); + double damage = ((e.getDistanceTraveled() - minimumDistance) < 0 ? 0 : e.getDistanceTraveled() - minimumDistance) / (e.getDifference().length()); + if(damage > 0) + Methods.damageEntity(e.getInstigator(), e.getEntity(), damage); + } } } diff --git a/src/com/projectkorra/ProjectKorra/ProjectKorra.java b/src/com/projectkorra/ProjectKorra/ProjectKorra.java index 1a731017..3e902187 100644 --- a/src/com/projectkorra/ProjectKorra/ProjectKorra.java +++ b/src/com/projectkorra/ProjectKorra/ProjectKorra.java @@ -1,13 +1,7 @@ package com.projectkorra.ProjectKorra; -import java.io.IOException; -import java.util.logging.Logger; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.plugin.java.JavaPlugin; - import com.projectkorra.ProjectKorra.Ability.AbilityModuleManager; +import com.projectkorra.ProjectKorra.Ability.Combo.ComboModuleManager; import com.projectkorra.ProjectKorra.Objects.Preset; import com.projectkorra.ProjectKorra.Utilities.CraftingRecipes; import com.projectkorra.ProjectKorra.airbending.AirbendingManager; @@ -16,6 +10,12 @@ import com.projectkorra.ProjectKorra.chiblocking.ChiblockingManager; import com.projectkorra.ProjectKorra.earthbending.EarthbendingManager; import com.projectkorra.ProjectKorra.firebending.FirebendingManager; import com.projectkorra.ProjectKorra.waterbending.WaterbendingManager; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.IOException; +import java.util.logging.Logger; public class ProjectKorra extends JavaPlugin { @@ -32,6 +32,7 @@ public class ProjectKorra extends JavaPlugin { new Methods(this); new Commands(this); new AbilityModuleManager(this); + new ComboModuleManager(); new ComboManager(); new ChiComboManager(); diff --git a/src/com/projectkorra/ProjectKorra/Utilities/HorizontalVelocityChangeEvent.java b/src/com/projectkorra/ProjectKorra/Utilities/HorizontalVelocityChangeEvent.java index 61de98d8..b000a4ea 100644 --- a/src/com/projectkorra/ProjectKorra/Utilities/HorizontalVelocityChangeEvent.java +++ b/src/com/projectkorra/ProjectKorra/Utilities/HorizontalVelocityChangeEvent.java @@ -1,5 +1,6 @@ package com.projectkorra.ProjectKorra.Utilities; +import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; @@ -21,7 +22,10 @@ public class HorizontalVelocityChangeEvent extends Event implements Cancellable private Vector from; private Vector to; private Vector difference; + private Location start; + private Location end; + @Deprecated public HorizontalVelocityChangeEvent(Entity entity, Player instigator, Vector from, Vector to, Vector difference) { this.entity = entity; @@ -31,6 +35,17 @@ 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) + { + this.entity = entity; + this.instigator = instigator; + this.from = from; + this.to = to; + this.difference = difference; + this.start = start; + this.end = end; + } + public Entity getEntity() { return entity; @@ -51,6 +66,21 @@ public class HorizontalVelocityChangeEvent extends Event implements Cancellable return to; } + public Location getStartPoint() + { + return start; + } + + public Location getEndPoint() + { + return end; + } + + public double getDistanceTraveled() + { + return start.distance(end); + } + public Vector getDifference() { return difference; diff --git a/src/com/projectkorra/ProjectKorra/airbending/AirBlast.java b/src/com/projectkorra/ProjectKorra/airbending/AirBlast.java index feaf55a8..b05eeaaf 100644 --- a/src/com/projectkorra/ProjectKorra/airbending/AirBlast.java +++ b/src/com/projectkorra/ProjectKorra/airbending/AirBlast.java @@ -262,7 +262,7 @@ public class AirBlast { return; Methods.setVelocity(entity, velocity); - new HorizontalVelocityTracker(entity, player, 200); + new HorizontalVelocityTracker(entity, player, 200l); entity.setFallDistance(0); if (!isUser && entity instanceof Player) { new Flight((Player) entity, player); diff --git a/src/com/projectkorra/ProjectKorra/waterbending/Bloodbending.java b/src/com/projectkorra/ProjectKorra/waterbending/Bloodbending.java index 2c684165..6525cbb3 100644 --- a/src/com/projectkorra/ProjectKorra/waterbending/Bloodbending.java +++ b/src/com/projectkorra/ProjectKorra/waterbending/Bloodbending.java @@ -91,6 +91,7 @@ public class Bloodbending { return; } Methods.damageEntity(player, target, 0); + HorizontalVelocityTracker.remove(target); Methods.breakBreathbendingHold(target); targetentities.put(target, target.getLocation().clone()); }