This commit is contained in:
MistPhizzle 2015-05-31 20:39:32 -04:00
commit 7862535a0b
19 changed files with 4214 additions and 1792 deletions

View file

@ -1,3 +1,4 @@
<<<<<<< HEAD
package com.projectkorra.ProjectKorra.Ability;
import java.io.File;
@ -125,6 +126,7 @@ public class AbilityModuleManager {
if (a == StockAbilities.WaterManipulation) shiftabilities.add(a.name());
if (a == StockAbilities.IceSpike) shiftabilities.add(a.name());
if (a == StockAbilities.IceBlast) shiftabilities.add(a.name());
if (a == StockAbilities.WaterArms) shiftabilities.add(a.name());
// Water Sub Abilities
if (a == StockAbilities.HealingWaters) subabilities.add(a.name());

View file

@ -0,0 +1,135 @@
package com.projectkorra.ProjectKorra.Ability.MultiAbility;
import java.util.ArrayList;
import com.projectkorra.ProjectKorra.MultiAbilityManager.MultiAbilitySub;
import com.projectkorra.ProjectKorra.SubElement;
import com.projectkorra.ProjectKorra.Utilities.AbilityLoadable;
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. new MultiAbilitySub("SubAbility", Element.Fire, SubElement.Lightning);
* @return
*/
public abstract ArrayList<MultiAbilitySub> getAbilities();
/**
* Void Method called whenever ProjectKorra stops and the ability is unloaded.
*
*/
public void stop(){
}
}

View file

@ -0,0 +1,98 @@
package com.projectkorra.ProjectKorra.Ability.MultiAbility;
import java.io.File;
import java.util.List;
import com.projectkorra.ProjectKorra.Element;
import com.projectkorra.ProjectKorra.MultiAbilityManager;
import com.projectkorra.ProjectKorra.MultiAbilityManager.MultiAbility;
import com.projectkorra.ProjectKorra.ProjectKorra;
import com.projectkorra.ProjectKorra.Ability.AbilityModuleManager;
import com.projectkorra.ProjectKorra.Ability.StockAbilities;
import com.projectkorra.ProjectKorra.Utilities.AbilityLoader;
public class MultiAbilityModuleManager
{
private final AbilityLoader<MultiAbilityModule> loader;
public static List<MultiAbilityModule> multiAbility;
public MultiAbilityModuleManager()
{
final File path = new File(ProjectKorra.plugin.getDataFolder().toString() + "/MultiAbilities/");
if (!path.exists())
{
path.mkdir();
}
loader = new AbilityLoader<MultiAbilityModule>(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 (StockAbilities a: StockAbilities.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());
}
}
}

View file

@ -18,14 +18,14 @@ public enum StockAbilities {
AvatarState,
// Project Korra
Extraction, MetalClips, Smokescreen, Combustion, LavaFlow, Suffocate, IceBlast, WarriorStance, AcrobatStance, QuickStrike, SwiftKick, EarthSmash, Flight;
Extraction, MetalClips, Smokescreen, Combustion, LavaFlow, Suffocate, IceBlast, WarriorStance, AcrobatStance, QuickStrike, SwiftKick, EarthSmash, Flight, WaterArms;
private enum AirbendingAbilities {
AirBlast, AirBubble, AirShield, AirSuction, AirSwipe, Tornado, AirScooter, AirSpout, AirBurst, Suffocate, Flight;
}
private enum WaterbendingAbilities {
WaterBubble, PhaseChange, HealingWaters, WaterManipulation, Surge, Bloodbending, WaterSpout, IceSpike, IceBlast, OctopusForm, Torrent;
WaterBubble, PhaseChange, HealingWaters, WaterManipulation, Surge, Bloodbending, WaterSpout, IceSpike, IceBlast, OctopusForm, Torrent, WaterArms;
}
@ -96,6 +96,11 @@ public enum StockAbilities {
;
}
private enum MultiAbilities
{
WaterArms;
}
public static boolean isFlightAbility(String ability)
{
for(FlightAbilities a : FlightAbilities.values())
@ -216,6 +221,13 @@ public enum StockAbilities {
return false;
}
public static boolean isMultiAbility(StockAbilities ability) {
for(MultiAbilities a: MultiAbilities.values()) {
if (a.name().equalsIgnoreCase(ability.name())) return true;
}
return false;
}
public static StockAbilities getAbility(int index) {
if (index == -1)
return null;

View file

@ -190,6 +190,11 @@ public class Commands {
return true;
}
if (MultiAbilityManager.hasMultiAbilityBound((Player) s)) {
s.sendMessage(ChatColor.RED + "You can't edit your binds right now!");
return true;
}
Player player = (Player) s;
String[] deletealiases = {"delete", "d", "del"};
@ -388,6 +393,12 @@ public class Commands {
s.sendMessage(ChatColor.RED + "This command is only usable by players.");
return true;
}
if (MultiAbilityManager.hasMultiAbilityBound((Player) s)) {
s.sendMessage(ChatColor.RED + "You can't edit your binds right now!");
return true;
}
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(s.getName());
if (args.length == 1) {
bPlayer.getAbilities().clear();

View file

@ -1,9 +1,9 @@
package com.projectkorra.ProjectKorra;
import org.bukkit.configuration.file.FileConfiguration;
import java.util.ArrayList;
import org.bukkit.configuration.file.FileConfiguration;
public class ConfigManager {
static ProjectKorra plugin;
@ -365,6 +365,62 @@ public class ConfigManager {
config.addDefault("Abilities.Water.Plantbending.RegrowTime", 180000);
config.addDefault("Abilities.Water.WaterArms.Enabled", true);
config.addDefault("Abilities.Water.WaterArms.Description", "One of the most diverse moves in a Waterbender's arsenal, this move creates tendrils "
+ "of water from the players arms to emulate their actual arms. Each water arms mode will be binded to a slot, switch slots to change mode. "
+ "To deactive the arms, hold Sneak and Double Left-Click."
+ "\nPull - Use your Arms to pull blocks, items, mobs or even players towards you!"
+ "\nPunch - An offensive attack, harming players or mobs!"
+ "\nGrapple - Scale walls and speed across battlefields, using your Arms as a grappling hook!"
+ "\nGrab - Grab an entity with your arm, and swing them about!"
+ "\nFreeze - Use your Arms to fire small blasts of ice in any direction!"
+ "\nSpear - Throw your Arms in any direction, freezing whatever it hits!");
config.addDefault("Abilities.Water.WaterArms.SneakMessage", "Active Ability:");
config.addDefault("Abilities.Water.WaterArms.Arms.InitialLength", 4);
config.addDefault("Abilities.Water.WaterArms.Arms.SourceGrabRange", 4);
config.addDefault("Abilities.Water.WaterArms.Arms.MaxAttacks", 10);
config.addDefault("Abilities.Water.WaterArms.Arms.MaxAlternateUsage", 50);
config.addDefault("Abilities.Water.WaterArms.Arms.MaxIceShots", 5);
config.addDefault("Abilities.Water.WaterArms.Arms.Cooldown", 20000);
config.addDefault("Abilities.Water.WaterArms.Arms.AllowPlantSource", true);
config.addDefault("Abilities.Water.WaterArms.Arms.Lightning.Enabled", true);
config.addDefault("Abilities.Water.WaterArms.Arms.Lightning.Damage", Double.valueOf(10.0));
config.addDefault("Abilities.Water.WaterArms.Arms.Lightning.KillUser", false);
config.addDefault("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldownEnabled", false);
config.addDefault("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldown", 200);
config.addDefault("Abilities.Water.WaterArms.Whip.MaxLength", 20);
config.addDefault("Abilities.Water.WaterArms.Whip.MaxLengthWeak", 12);
config.addDefault("Abilities.Water.WaterArms.Whip.NightAugments.MaxLength.Normal", 24);
config.addDefault("Abilities.Water.WaterArms.Whip.NightAugments.MaxLength.FullMoon", 30);
config.addDefault("Abilities.Water.WaterArms.Whip.Punch.PunchDamage", Double.valueOf(3.0));
config.addDefault("Abilities.Water.WaterArms.Whip.Grapple.RespectRegions", false);
config.addDefault("Abilities.Water.WaterArms.Whip.Grab.HoldTime", 10000);
config.addDefault("Abilities.Water.WaterArms.Freeze.Range", 20);
config.addDefault("Abilities.Water.WaterArms.Freeze.Damage", Double.valueOf(2.0));
config.addDefault("Abilities.Water.WaterArms.Spear.Range", 40);
config.addDefault("Abilities.Water.WaterArms.Spear.Damage", Double.valueOf(4.0));
config.addDefault("Abilities.Water.WaterArms.Spear.DamageEnabled", true);
config.addDefault("Abilities.Water.WaterArms.Spear.Sphere", 2);
config.addDefault("Abilities.Water.WaterArms.Spear.Duration", 6000);
config.addDefault("Abilities.Water.WaterArms.Spear.Length", 18);
config.addDefault("Abilities.Water.WaterArms.Spear.NightAugments.Range.Normal", 45);
config.addDefault("Abilities.Water.WaterArms.Spear.NightAugments.Range.FullMoon", 60);
config.addDefault("Abilities.Water.WaterArms.Spear.NightAugments.Sphere.Normal", 3);
config.addDefault("Abilities.Water.WaterArms.Spear.NightAugments.Sphere.FullMoon", 6);
config.addDefault("Abilities.Water.WaterArms.Spear.NightAugments.Duration.Normal", 7000);
config.addDefault("Abilities.Water.WaterArms.Spear.NightAugments.Duration.FullMoon", 12000);
config.addDefault("Abilities.Water.WaterBubble.Enabled", true);
config.addDefault("Abilities.Water.WaterBubble.Description","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.");
config.addDefault("Abilities.Water.WaterBubble.Radius", 7);

View file

@ -187,6 +187,12 @@ public class GeneralMethods {
* @see {@link #bindAbility(Player, String)}
*/
public static void bindAbility(Player player, String ability, int slot) {
if(MultiAbilityManager.playerAbilities.containsKey(player)){
player.sendMessage(ChatColor.RED + "You can't edit your binds right now!");
return;
}
BendingPlayer bPlayer = getBendingPlayer(player.getName());
bPlayer.getAbilities().put(slot, ability);
if (AirMethods.isAirAbility(ability)) {
@ -1360,6 +1366,9 @@ public class GeneralMethods {
if (bPlayer == null) return;
String uuid = bPlayer.uuid.toString();
//Temp code to block modifications of binds, Should be replaced when bind event is added.
if(MultiAbilityManager.playerAbilities.containsKey(Bukkit.getPlayer(bPlayer.getPlayerName())))
return;
HashMap<Integer, String> abilities = bPlayer.getAbilities();
DBConnection.sql.modifyQuery("UPDATE pk_players SET slot" + slot + " = '" + (abilities.get(slot) == null ? null : abilities.get(slot)) + "' WHERE uuid = '" + uuid + "'");
@ -1396,6 +1405,8 @@ public class GeneralMethods {
Flight.removeAll();
TempBlock.removeAll();
MultiAbilityManager.removeAll();
}
@ -1849,4 +1860,26 @@ public class GeneralMethods {
}
}
}
/**
* Returns a location with a specified distance away from the left side of a location.
* @param location
* @param distance
* @return
*/
public static Location getLeftSide(Location location, double distance){
float angle = location.getYaw()/60;
return location.clone().add(new Vector(Math.cos(angle), 0, Math.sin(angle)).normalize().multiply(distance));
}
/**
* Returns a location with a specified distance away from the right side of a location.
* @param location
* @param distance
* @return
*/
public static Location getRightSide(Location location, double distance){
float angle = location.getYaw()/60;
return location.clone().subtract(new Vector(Math.cos(angle), 0, Math.sin(angle)).normalize().multiply(distance));
}
}

View file

@ -0,0 +1,303 @@
package com.projectkorra.ProjectKorra;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import com.projectkorra.ProjectKorra.Ability.MultiAbility.MultiAbilityModule;
import com.projectkorra.ProjectKorra.Ability.MultiAbility.MultiAbilityModuleManager;
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;
public class MultiAbilityManager {
public static ConcurrentHashMap<Player, HashMap<Integer, String>> playerAbilities = new ConcurrentHashMap<Player, HashMap<Integer, String>>();
public static ConcurrentHashMap<Player, Integer> playerSlot = new ConcurrentHashMap<Player, Integer>();
public static ConcurrentHashMap<Player, String> playerBoundAbility = new ConcurrentHashMap<Player, String>();
public static ArrayList<MultiAbility> multiAbilityList = new ArrayList<MultiAbility>();
public MultiAbilityManager() {
ArrayList<MultiAbilitySub> waterArms = new ArrayList<MultiAbilitySub>();
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();
}
/**
* MultiAbility class.
* Manages each MultiAbility's sub abilities.
*
*/
public static class MultiAbility {
private String name;
private ArrayList<MultiAbilitySub> abilities;
public MultiAbility(String name, ArrayList<MultiAbilitySub> abilities){
this.name = name;
this.abilities = abilities;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ArrayList<MultiAbilitySub> getAbilities(){
return abilities;
}
public void setAbilities(ArrayList<MultiAbilitySub> abilities){
this.abilities = abilities;
}
}
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 String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Element getElement(){
return element;
}
public void setElement(Element element){
this.element = element;
}
public SubElement getSubElement(){
return sub;
}
public void setSubElement(SubElement sub){
this.sub = sub;
}
public ChatColor getAbilityColor(){
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);
}
}
}
/**
* Returns a MultiAbility based on name.
* @param multiAbility
* @return
*/
public static MultiAbility getMultiAbility(String multiAbility){
for(MultiAbility ma: multiAbilityList){
if(ma.getName().equalsIgnoreCase(multiAbility))
return ma;
}
return null;
}
/**
* 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<Integer, String> currAbilities = new HashMap<Integer, String>();
for(int i : bPlayer.getAbilities().keySet()){
currAbilities.put(i, bPlayer.getAbilities().get(i));
}
playerAbilities.put(player, currAbilities);
List<MultiAbilitySub> 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);
}
}
/**
* 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<Integer, String> 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 equivalent of GeneralMethods.getBoundAbility().
* Returns a boolean based on whether a player has a specific MultiAbility active.
* @param player
* @param multiAbility
* @return
*/
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;
}
/**
* Returns a boolean based on whether a player has a MultiAbility active.
* @param player
* @return
*/
public static boolean hasMultiAbilityBound(Player player){
if(playerAbilities.containsKey(player))
return true;
return false;
}
/**
* Returns the MultiAbility the player has bound.
* Returns null if no multiability is bound and active.
* @param player
* @return
*/
public static String getBoundMultiAbility(Player player){
if(playerBoundAbility.containsKey(player))
return playerBoundAbility.get(player);
return null;
}
public static void manage(){
new BukkitRunnable() {
public void run() {
scrollHotBarSlots();
}
}.runTaskTimer(ProjectKorra.plugin, 0, 1);
}
/**
* 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);
}
}
}
}
}
}
}
/**
* Clears all MultiAbility data for a player.
* Called on player quit event.
* @param player
*/
public static void remove(Player player){
if(hasMultiAbilityBound(player))
unbindMultiAbility(player);
playerAbilities.remove(player);
playerBoundAbility.remove(player);
playerSlot.remove(player);
}
/**
* Cleans up all MultiAbilities.
*/
public static void removeAll(){
List<MultiAbilityModule> abilities = MultiAbilityModuleManager.multiAbility;
for(MultiAbilityModule mam: abilities)
mam.stop();
playerAbilities.clear();
playerSlot.clear();
playerBoundAbility.clear();
}
}

View file

@ -132,6 +132,7 @@ import com.projectkorra.ProjectKorra.waterbending.IceSpike2;
import com.projectkorra.ProjectKorra.waterbending.Melt;
import com.projectkorra.ProjectKorra.waterbending.OctopusForm;
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;
@ -404,6 +405,7 @@ public class PKListener implements Listener {
}
}
MultiAbilityManager.remove(player);
FlightAbility.remove(event.getPlayer());
}
@ -440,6 +442,11 @@ public class PKListener implements Listener {
BlockSource.update(player, ClickType.SHIFT_DOWN);
}
if(!player.isSneaking() && WaterArms.hasPlayer(player)){
WaterArms.displayBoundMsg(player);
return;
}
AirScooter.check(player);
String abil = GeneralMethods.getBoundAbility(player);
@ -515,6 +522,10 @@ public class PKListener implements Listener {
if (abil.equalsIgnoreCase("Torrent")) {
Torrent.create(player);
}
if (abil.equalsIgnoreCase("WaterArms")) {
new WaterArms(player);
}
}
if (EarthMethods.isEarthAbility(abil)) {
@ -820,6 +831,7 @@ public class PKListener implements Listener {
AirScooter.check(player);
String abil = GeneralMethods.getBoundAbility(player);
if (abil == null && !MultiAbilityManager.hasMultiAbilityBound(player)) return;
if (abil == null) return;
if (GeneralMethods.canBend(player.getName(), abil)) {
if (GeneralMethods.isDisabledStockAbility(abil))
@ -1020,6 +1032,13 @@ public class PKListener implements Listener {
if (abil.equalsIgnoreCase("AvatarState")) {
new AvatarState(player);
}
if(MultiAbilityManager.hasMultiAbilityBound(player)){
abil = MultiAbilityManager.getBoundMultiAbility(player);
if (abil.equalsIgnoreCase("WaterArms")) {
new WaterArms(player);
}
}
}
}

View file

@ -2,6 +2,7 @@ package com.projectkorra.ProjectKorra;
import com.projectkorra.ProjectKorra.Ability.AbilityModuleManager;
import com.projectkorra.ProjectKorra.Ability.Combo.ComboModuleManager;
import com.projectkorra.ProjectKorra.Ability.MultiAbility.MultiAbilityModuleManager;
import com.projectkorra.ProjectKorra.Objects.Preset;
import com.projectkorra.ProjectKorra.Utilities.CraftingRecipes;
import com.projectkorra.ProjectKorra.airbending.AirbendingManager;
@ -33,6 +34,8 @@ public class ProjectKorra extends JavaPlugin {
new GeneralMethods(this);
new Commands(this);
new AbilityModuleManager(this);
new MultiAbilityModuleManager();
new MultiAbilityManager();
new ComboModuleManager();
new ComboManager();
new ChiComboManager();

View file

@ -7,6 +7,7 @@ import org.bukkit.util.Vector;
import com.projectkorra.ProjectKorra.BendingPlayer;
import com.projectkorra.ProjectKorra.GeneralMethods;
import com.projectkorra.ProjectKorra.ProjectKorra;
import com.projectkorra.ProjectKorra.waterbending.WaterArmsWhip;
public class HighJump {
@ -17,6 +18,12 @@ public class HighJump {
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);

View file

@ -0,0 +1,665 @@
package com.projectkorra.ProjectKorra.waterbending;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.ChatColor;
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 com.projectkorra.ProjectKorra.GeneralMethods;
import com.projectkorra.ProjectKorra.MultiAbilityManager;
import com.projectkorra.ProjectKorra.ProjectKorra;
import com.projectkorra.ProjectKorra.TempBlock;
import com.projectkorra.ProjectKorra.Utilities.ParticleEffect;
import com.projectkorra.ProjectKorra.earthbending.EarthMethods;
import com.projectkorra.ProjectKorra.firebending.FireMethods;
import com.projectkorra.ProjectKorra.firebending.Lightning;
import com.projectkorra.ProjectKorra.waterbending.WaterArmsWhip.Whip;
public class WaterArms {
/**
* Arm Enum value for deciding which arm is being used.
*/
public enum Arm {
Right, Left;
}
private static FileConfiguration config = ProjectKorra.plugin.getConfig();
public static ConcurrentHashMap<Player, WaterArms> instances = new ConcurrentHashMap<Player, WaterArms>();
public static ConcurrentHashMap<Block, Long> revert = new ConcurrentHashMap<Block, Long>();
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 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 long lastClickTime;
public WaterArms(Player player) {
if (instances.containsKey(player)) {
if (player.isSneaking()) {
instances.get(player).prepareCancel();
} else {
switch (player.getInventory().getHeldItemSlot()) {
case 0:
if (player.hasPermission("bending.ability.WaterArms.Pull")) {
new WaterArmsWhip(player, Whip.Pull);
}
break;
case 1:
if (player.hasPermission("bending.ability.WaterArms.Punch")) {
new WaterArmsWhip(player, Whip.Punch);
}
break;
case 2:
if (player
.hasPermission("bending.ability.WaterArms.Grapple")) {
new WaterArmsWhip(player, Whip.Grapple);
}
break;
case 3:
if (player.hasPermission("bending.ability.WaterArms.Grab")) {
new WaterArmsWhip(player, Whip.Grab);
}
break;
case 4:
if (player
.hasPermission("bending.ability.WaterArms.Freeze")
&& WaterMethods.canIcebend(player)) {
new WaterArmsFreeze(player);
}
break;
case 5:
if (player.hasPermission("bending.ability.WaterArms.Spear")) {
if (WaterMethods.canIcebend(player)) {
new WaterArmsSpear(player, true);
} else {
new WaterArmsSpear(player, false);
}
}
break;
default:
break;
}
}
return;
}
this.player = player;
if (canUse(player) && prepare()) {
world = player.getWorld();
instances.put(player, this);
MultiAbilityManager.bindMultiAbility(player, "WaterArms");
if (ChatColor.stripColor(GeneralMethods.getBoundAbility(player)) == null) {
remove();
return;
}
player.sendMessage(WaterMethods.getWaterColor() + sneakMsg + " "
+ GeneralMethods.getBoundAbility(player));
}
}
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, canUsePlantSource);
if (sourceblock != null) {
if (WaterMethods.isPlant(sourceblock)) {
fullSource = false;
}
ParticleEffect.LARGE_SMOKE.display(
WaterMethods
.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);
fullSource = false;
return true;
}
return false;
}
private void progress() {
if (!instances.containsKey(player)) {
return;
}
if (player.isDead() || !player.isOnline() || world != player.getWorld()) {
remove();
return;
}
if (!GeneralMethods.getBendingPlayer(player.getName()).isToggled()) {
remove();
return;
}
if (!MultiAbilityManager.hasMultiAbilityBound(player, "WaterArms")) {
remove();
return;
}
if (maxPunches == 0 || maxUses == 0 || maxIceBlasts == 0
|| (leftArmConsumed && rightArmConsumed)) {
remove();
return;
}
selectedSlot = player.getInventory().getHeldItemSlot();
displayRightArm();
displayLeftArm();
if (lightningEnabled)
checkIfZapped();
}
private boolean canPlaceBlock(Block block) {
if (!EarthMethods.isTransparentToEarthbending(player, block)
&& !(WaterMethods.isWater(block) && TempBlock
.isTempBlock(block)))
return false;
return true;
}
/**
* Displays the right arm. Returns false if the arm cannot be fully
* displayed.
*
* @return
*/
public boolean displayRightArm() {
if (rightArmConsumed)
return false;
Location r1 = GeneralMethods.getRightSide(player.getLocation(), 1).add(
0, 1.5, 0);
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);
}
Location r2 = GeneralMethods.getRightSide(player.getLocation(), 2).add(
0, 1.5, 0);
if (!canPlaceBlock(r2.getBlock()))
return false;
new TempBlock(r2.getBlock(), Material.STATIONARY_WATER, (byte) 0);
revert.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))
continue;
return false;
}
if (j >= 1 && selectedSlot == freezeSlot
&& WaterMethods.canIcebend(player)) {
new TempBlock(r3.getBlock(), Material.ICE, (byte) 0);
revert.put(r3.getBlock(), 0L);
} else {
new TempBlock(r3.getBlock(), Material.STATIONARY_WATER,
(byte) 0);
revert.put(r3.getBlock(), 0L);
}
}
return true;
}
/**
* Displays the left arm. Returns false if the arm cannot be fully
* displayed.
*
* @return
*/
public boolean displayLeftArm() {
if (leftArmConsumed)
return false;
Location l1 = GeneralMethods.getLeftSide(player.getLocation(), 1).add(
0, 1.5, 0);
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);
}
Location l2 = GeneralMethods.getLeftSide(player.getLocation(), 2).add(
0, 1.5, 0);
if (!canPlaceBlock(l2.getBlock()))
return false;
new TempBlock(l2.getBlock(), Material.STATIONARY_WATER, (byte) 0);
revert.put(l2.getBlock(), 0L);
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))
continue;
return false;
}
if (j >= 1 && selectedSlot == freezeSlot
&& WaterMethods.canIcebend(player)) {
new TempBlock(l3.getBlock(), Material.ICE, (byte) 0);
revert.put(l3.getBlock(), 0L);
} else {
new TempBlock(l3.getBlock(), Material.STATIONARY_WATER,
(byte) 0);
revert.put(l3.getBlock(), 0L);
}
}
return true;
}
/**
* Calculate roughly where the player's right hand is.
*
* @return
*/
private Location getRightHandPos() {
return GeneralMethods.getRightSide(player.getLocation(), .34).add(0,
1.5, 0);
}
/**
* Calculate roughly where the player's left hand is.
*
* @return
*/
private Location getLeftHandPos() {
return GeneralMethods.getLeftSide(player.getLocation(), .34).add(0,
1.5, 0);
}
/**
* Returns the location of the tip of the right arm, assuming it is fully
* extended. Use the displayRightArm() check to see if it is fully extended.
*
* @return
*/
public Location getRightArmEnd() {
Location r1 = GeneralMethods.getRightSide(player.getLocation(), 2).add(
0, 1.5, 0);
return r1.clone().add(
player.getLocation().getDirection().normalize()
.multiply(initLength));
}
/**
* Returns the location of the tip of the left arm assuming it is fully
* extended. Use the displayLeftArm() check to see if it is fully extended.
*
* @return
*/
public Location getLeftArmEnd() {
Location l1 = GeneralMethods.getLeftSide(player.getLocation(), 2).add(
0, 1.5, 0);
return l1.clone().add(
player.getLocation().getDirection().normalize()
.multiply(initLength));
}
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);
}
}
}
private void checkIfZapped() {
for (int i = 0; i < Lightning.instances.size(); i++) {
Lightning l = Lightning.instances.get(i);
for (Lightning.Arc arc : l.getArcs()) {
for (Block arm : revert.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(Lightning.instances
.get(i).getPlayer(), player, 60D);
else
GeneralMethods.damageEntity(Lightning.instances
.get(i).getPlayer(), player,
lightningDamage);
}
}
}
}
}
}
private static List<Location> getOffsetLocations(int amount,
Location location, double offset) {
List<Location> locations = new ArrayList<Location>();
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();
}
public void remove() {
MultiAbilityManager.unbindMultiAbility(player);
if (player.isOnline())
GeneralMethods.getBendingPlayer(player.getName()).addCooldown(
"WaterArms", cooldown);
instances.remove(player);
}
public void prepareCancel() {
if (System.currentTimeMillis() < lastClickTime + 500L) {
remove();
} else {
lastClickTime = System.currentTimeMillis();
}
}
public static void progressAll() {
progressRevert(false);
for (Player p : instances.keySet())
instances.get(p).progress();
WaterArmsWhip.progressAll();
WaterArmsFreeze.progressAll();
WaterArmsSpear.progressAll();
}
public static void removeAll() {
progressRevert(true);
revert.clear();
instances.clear();
WaterArmsWhip.removeAll();
WaterArmsFreeze.removeAll();
WaterArmsSpear.removeAll();
}
@SuppressWarnings("deprecation")
public static boolean isUnbreakable(Block block) {
if (Arrays.asList(unbreakable).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));
}
/**
* Returns the active arm of the player.
*
* @return
*/
public Arm getActiveArm() {
return activeArm;
}
/**
* Switches the active arm of a player.
*/
public void switchActiveArm() {
if (activeArm.equals(Arm.Right))
activeArm = Arm.Left;
else
activeArm = Arm.Right;
}
/**
* Switches to the most suitable arm for the player.
*
* @return
*/
public Arm switchPreferredArm() {
switchActiveArm();
if (activeArm.equals(Arm.Left)) {
if (!displayLeftArm()) {
switchActiveArm();
}
}
if (activeArm.equals(Arm.Right)) {
if (!displayRightArm()) {
switchActiveArm();
}
}
return getActiveArm();
}
public boolean canDisplayActiveArm() {
switch (activeArm) {
case Left:
return displayLeftArm();
case Right:
return displayRightArm();
default:
return false;
}
}
public Location getActiveArmEnd() {
switch (activeArm) {
case Left:
return getLeftArmEnd();
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;
}
public boolean getLeftArmConsumed() {
return leftArmConsumed;
}
public void setLeftArmConsumed(boolean consumed) {
this.leftArmConsumed = consumed;
}
public boolean getRightArmConsumed() {
return rightArmConsumed;
}
public void setRightArmConsumed(boolean consumed) {
this.rightArmConsumed = consumed;
}
public Integer getLengthReduction() {
return lengthReduction;
}
public void setLengthReduction(int lengthReduction) {
this.lengthReduction = lengthReduction;
}
public Integer getMaxPunches() {
return maxPunches;
}
public void setMaxPunches(int maxPunches) {
this.maxPunches = maxPunches;
}
public Integer getMaxUses() {
return maxUses;
}
public void setMaxUses(int maxUses) {
this.maxUses = maxUses;
}
public Integer getMaxIceBlasts() {
return maxIceBlasts;
}
public void setMaxIceBlasts(int maxIceBlasts) {
this.maxIceBlasts = maxIceBlasts;
}
public boolean canLightningDamage() {
return lightningEnabled;
}
public void setCanLightningDamage(boolean lightningEnabled) {
this.lightningEnabled = lightningEnabled;
}
public double getLightningDamage() {
return lightningDamage;
}
public void setLightningDamage(double lightningDamage) {
this.lightningDamage = lightningDamage;
}
public boolean isLeftArmCooldown() {
return cooldownLeft;
}
public void setLeftArmCooldown(boolean cooldown) {
this.cooldownLeft = cooldown;
}
public boolean isRightArmCooldown() {
return cooldownRight;
}
public void setRightArmCooldown(boolean cooldown) {
this.cooldownRight = cooldown;
}
public void setActiveArmCooldown(boolean cooldown) {
switch (activeArm) {
case Left:
setLeftArmCooldown(cooldown);
return;
case Right:
setRightArmCooldown(cooldown);
return;
default:
break;
}
}
public long getCooldown() {
return cooldown;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
}

View file

@ -0,0 +1,209 @@
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.configuration.file.FileConfiguration;
import org.bukkit.entity.ArmorStand;
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 com.projectkorra.ProjectKorra.BendingPlayer;
import com.projectkorra.ProjectKorra.GeneralMethods;
import com.projectkorra.ProjectKorra.ProjectKorra;
import com.projectkorra.ProjectKorra.TempBlock;
import com.projectkorra.ProjectKorra.TempPotionEffect;
import com.projectkorra.ProjectKorra.Utilities.ParticleEffect;
import com.projectkorra.ProjectKorra.earthbending.EarthMethods;
import com.projectkorra.ProjectKorra.waterbending.WaterArms.Arm;
public class WaterArmsFreeze {
private static FileConfiguration config = ProjectKorra.plugin.getConfig();
public static ConcurrentHashMap<Integer, WaterArmsFreeze> instances = new ConcurrentHashMap<Integer, WaterArmsFreeze>();
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");
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;
public WaterArmsFreeze(Player player) {
this.player = player;
direction = player.getEyeLocation().getDirection();
createInstance();
}
private void createInstance() {
if (WaterArms.instances.containsKey(player)) {
waterArms = WaterArms.instances.get(player);
waterArms.switchPreferredArm();
arm = waterArms.getActiveArm();
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player
.getName());
if (arm.equals(Arm.Left)) {
if (waterArms.isLeftArmCooldown()
|| bPlayer.isOnCooldown("WaterArms_LEFT")) {
return;
} else {
if (usageCooldownEnabled) {
bPlayer.addCooldown("WaterArms_LEFT", usageCooldown);
}
waterArms.setLeftArmCooldown(true);
}
}
if (arm.equals(Arm.Right)) {
if (waterArms.isRightArmCooldown()
|| bPlayer.isOnCooldown("WaterArms_RIGHT")) {
return;
} else {
if (usageCooldownEnabled) {
bPlayer.addCooldown("WaterArms_RIGHT", usageCooldown);
}
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++;
}
private void progress() {
if (player.isDead() || !player.isOnline()) {
remove();
return;
}
if (distanceTravelled > iceRange) {
remove();
return;
}
if (distanceTravelled >= 5 && !cancelled) {
cancelled = true;
if (WaterArms.instances.containsKey(player)) {
if (arm.equals(Arm.Left)) {
waterArms.setLeftArmCooldown(false);
} else {
waterArms.setRightArmCooldown(false);
}
waterArms.setMaxIceBlasts(waterArms.getMaxIceBlasts() - 1);
}
}
if (!canPlaceBlock(location.getBlock())) {
remove();
return;
}
progressIce();
}
private boolean canPlaceBlock(Block block) {
if (!EarthMethods.isTransparentToEarthbending(player, block)
&& !((WaterMethods.isWater(block) || WaterMethods
.isIcebendable(block)) && TempBlock.isTempBlock(block))) {
return false;
}
if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterArms",
block.getLocation())) {
return false;
}
return true;
}
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);
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location,
2.5)) {
if (entity instanceof LivingEntity
&& entity.getEntityId() != player.getEntityId()
&& !(entity instanceof ArmorStand)) {
GeneralMethods.damageEntity(player, entity, iceDamage);
PotionEffect effect = new PotionEffect(PotionEffectType.SLOW,
40, 2);
new TempPotionEffect((LivingEntity) entity, effect);
remove();
return;
}
}
for (int i = 0; i < 2; i++) {
location = location.add(direction.clone().multiply(1));
if (!canPlaceBlock(location.getBlock()))
return;
distanceTravelled++;
}
}
private void remove() {
if (WaterArms.instances.containsKey(player)) {
if (!cancelled) {
if (arm.equals(Arm.Left)) {
waterArms.setLeftArmCooldown(false);
} else {
waterArms.setRightArmCooldown(false);
}
waterArms.setMaxIceBlasts(waterArms.getMaxIceBlasts() - 1);
}
}
instances.remove(id);
}
public static void progressAll() {
for (int ID : instances.keySet())
instances.get(ID).progress();
}
public static void removeAll() {
instances.clear();
}
public Player getPlayer() {
return player;
}
public boolean getCancelled() {
return cancelled;
}
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
}

View file

@ -0,0 +1,321 @@
package com.projectkorra.ProjectKorra.waterbending;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
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.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.ProjectKorra.BendingManager;
import com.projectkorra.ProjectKorra.BendingPlayer;
import com.projectkorra.ProjectKorra.GeneralMethods;
import com.projectkorra.ProjectKorra.ProjectKorra;
import com.projectkorra.ProjectKorra.TempBlock;
import com.projectkorra.ProjectKorra.earthbending.EarthMethods;
import com.projectkorra.ProjectKorra.waterbending.WaterArms.Arm;
import com.projectkorra.rpg.WorldEvents;
public class WaterArmsSpear {
private static FileConfiguration config = ProjectKorra.plugin.getConfig();
public static ConcurrentHashMap<Integer, WaterArmsSpear> instances = new ConcurrentHashMap<Integer, WaterArmsSpear>();
private Player player;
private WaterArms waterArms;
private List<Location> 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();
public WaterArmsSpear(Player player, boolean freeze) {
this.player = player;
this.canFreeze = freeze;
getNightAugments();
createInstance();
}
private void getNightAugments() {
World world = player.getWorld();
if (WaterMethods.isNight(world)) {
if (GeneralMethods.hasRPG()) {
if (BendingManager.events.get(world).equalsIgnoreCase(
WorldEvents.LunarEclipse.toString())) {
spearRange = spearRangeFullMoon;
spearSphere = spearSphereFullMoon;
spearDuration = spearDurationFullMoon;
} else if (BendingManager.events.get(world).equalsIgnoreCase(
"FullMoon")) {
spearRange = spearRangeFullMoon;
spearSphere = spearSphereFullMoon;
spearDuration = spearDurationFullMoon;
} else {
spearRange = spearRangeNight;
spearSphere = spearSphereNight;
spearDuration = spearDurationNight;
}
} else {
if (WaterMethods.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.switchPreferredArm();
arm = waterArms.getActiveArm();
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player
.getName());
if (arm.equals(Arm.Left)) {
if (waterArms.isLeftArmCooldown()
|| bPlayer.isOnCooldown("WaterArms_LEFT")
|| !waterArms.displayLeftArm()) {
return;
} else {
if (usageCooldownEnabled) {
bPlayer.addCooldown("WaterArms_LEFT", usageCooldown);
}
waterArms.setLeftArmConsumed(true);
waterArms.setLeftArmCooldown(true);
}
}
if (arm.equals(Arm.Right)) {
if (waterArms.isRightArmCooldown()
|| bPlayer.isOnCooldown("WaterArms_RIGHT")
|| !waterArms.displayRightArm()) {
return;
} else {
if (usageCooldownEnabled) {
bPlayer.addCooldown("WaterArms_RIGHT", usageCooldown);
}
waterArms.setRightArmConsumed(true);
waterArms.setRightArmCooldown(true);
}
}
Vector dir = player.getLocation().getDirection();
location = waterArms.getActiveArmEnd().add(
dir.normalize().multiply(1));
initLocation = location.clone();
} else {
return;
}
id = ID;
instances.put(id, this);
if (ID == Integer.MAX_VALUE)
ID = Integer.MIN_VALUE;
ID++;
}
private void progress() {
if (player.isDead() || !player.isOnline()) {
remove();
return;
}
if (distanceTravelled > spearRange) {
remove();
return;
}
if (!hitEntity) {
progressSpear();
} else {
createIceBall();
}
if (layer >= spearSphere) {
remove();
return;
}
if (!canPlaceBlock(location.getBlock())) {
if (canFreeze) {
createSpear();
}
remove();
return;
}
}
private void progressSpear() {
for (int i = 0; i < 2; i++) {
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(
location, 2)) {
if (entity instanceof LivingEntity
&& entity.getEntityId() != player.getEntityId()
&& !(entity instanceof ArmorStand)) {
hitEntity = true;
location = entity.getLocation();
if (spearDamageEnabled) {
GeneralMethods
.damageEntity(player, entity, spearDamage);
}
return;
}
}
new TempBlock(location.getBlock(), Material.STATIONARY_WATER,
(byte) 0);
WaterArms.revert.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;
}
distanceTravelled++;
}
}
private void createSpear() {
for (int i = spearLocations.size() - spearLength; i < spearLocations
.size(); i++) {
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);
}
new TempBlock(block, Material.ICE, (byte) 0);
WaterArms.revert.put(block, System.currentTimeMillis()
+ spearDuration + (long) (Math.random() * 500));
}
}
}
}
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());
new TempBlock(block, Material.ICE, (byte) 0);
WaterArms.revert.put(block, System.currentTimeMillis()
+ spearDuration + (long) (Math.random() * 500));
}
}
}
private boolean canPlaceBlock(Block block) {
if (!EarthMethods.isTransparentToEarthbending(player, block)
&& !((WaterMethods.isWater(block) || WaterMethods
.isIcebendable(block)) && (TempBlock.isTempBlock(block) && !WaterArms.revert
.containsKey(block)))) {
return false;
}
if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterArms",
block.getLocation())) {
return false;
}
if (WaterArms.isUnbreakable(block) && !WaterMethods.isWater(block)) {
return false;
}
return true;
}
private void remove() {
if (WaterArms.instances.containsKey(player)) {
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();
}
public static void removeAll() {
instances.clear();
}
public Player getPlayer() {
return player;
}
public boolean getCanFreeze() {
return canFreeze;
}
public void setCanFreeze(boolean freeze) {
this.canFreeze = freeze;
}
public boolean getHasHitEntity() {
return hitEntity;
}
public void setHitEntity(boolean hit) {
this.hitEntity = hit;
}
}

View file

@ -0,0 +1,479 @@
package com.projectkorra.ProjectKorra.waterbending;
import java.util.HashMap;
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.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.ProjectKorra.BendingManager;
import com.projectkorra.ProjectKorra.BendingPlayer;
import com.projectkorra.ProjectKorra.Commands;
import com.projectkorra.ProjectKorra.GeneralMethods;
import com.projectkorra.ProjectKorra.MultiAbilityManager;
import com.projectkorra.ProjectKorra.ProjectKorra;
import com.projectkorra.ProjectKorra.TempBlock;
import com.projectkorra.ProjectKorra.earthbending.EarthMethods;
import com.projectkorra.ProjectKorra.waterbending.WaterArms.Arm;
import com.projectkorra.rpg.WorldEvents;
public class WaterArmsWhip {
/**
* Whip Enum value for deciding what ability should be executed.
*/
public enum Whip {
Pull, Punch, Grapple, Grab;
}
private static FileConfiguration config = ProjectKorra.plugin.getConfig();
public static ConcurrentHashMap<Integer, WaterArmsWhip> instances = new ConcurrentHashMap<Integer, WaterArmsWhip>();
public static HashMap<LivingEntity, Integer> grabbedEntities = new HashMap<LivingEntity, Integer>();
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 punchDamage = config
.getDouble("Abilities.Water.WaterArms.Whip.Punch.PunchDamage");
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 long time;
private LivingEntity grabbedEntity;
private Location end;
private Arm arm;
private Whip ability;
private int id;
private static int ID = Integer.MIN_VALUE;
public WaterArmsWhip(Player player, Whip ability) {
if (instances.containsKey(getId(player))) {
WaterArmsWhip waw = instances.get(getId(player));
if (waw.grabbed) {
waw.grabbed = false;
if (waw.grabbedEntity != null) {
grabbedEntities.remove(waw.grabbedEntity);
waw.grabbedEntity.setVelocity(waw.grabbedEntity
.getVelocity().multiply(2.5));
}
return;
}
if (!waw.arm.equals(WaterArms.instances.get(player).getActiveArm())) {
return;
}
}
this.player = player;
this.ability = ability;
getNightAugments();
createInstance();
}
private void getNightAugments() {
World world = player.getWorld();
if (WaterMethods.isNight(world)) {
if (GeneralMethods.hasRPG()) {
if (BendingManager.events.get(world).equalsIgnoreCase(
WorldEvents.LunarEclipse.toString())) {
whipLength = whipLengthFullMoon;
} else if (BendingManager.events.get(world).equalsIgnoreCase(
"FullMoon")) {
whipLength = whipLengthFullMoon;
} else {
whipLength = whipLengthNight;
}
} else {
if (WaterMethods.isFullMoon(world)) {
whipLength = whipLengthFullMoon;
} else {
whipLength = whipLengthNight;
}
}
}
}
private void createInstance() {
if (WaterArms.instances.containsKey(player)) {
waterArms = WaterArms.instances.get(player);
waterArms.switchPreferredArm();
arm = waterArms.getActiveArm();
time = System.currentTimeMillis() + holdTime;
playerHealth = player.getHealth();
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player
.getName());
if (arm.equals(Arm.Left)) {
if (waterArms.isLeftArmCooldown()
|| bPlayer.isOnCooldown("WaterArms_LEFT")) {
return;
} else {
if (usageCooldownEnabled) {
bPlayer.addCooldown("WaterArms_LEFT", usageCooldown);
}
waterArms.setLeftArmCooldown(true);
}
}
if (arm.equals(Arm.Right)) {
if (waterArms.isRightArmCooldown()
|| bPlayer.isOnCooldown("WaterArms_RIGHT")) {
return;
} else {
if (usageCooldownEnabled) {
bPlayer.addCooldown("WaterArms_RIGHT", usageCooldown);
}
waterArms.setRightArmCooldown(true);
}
}
} else {
return;
}
if (!waterArms.isFullSource()) {
whipLength = whipLengthWeak;
}
id = ID;
instances.put(id, this);
if (ID == Integer.MAX_VALUE)
ID = Integer.MIN_VALUE;
ID++;
}
private void progress() {
if (!WaterArms.instances.containsKey(player)) {
remove();
return;
}
if (player.isDead() || !player.isOnline()) {
remove();
return;
}
if (!MultiAbilityManager.hasMultiAbilityBound(player, "WaterArms")) {
remove();
return;
}
if (activeLength < whipLength && !reverting) {
activeLength += whipSpeed;
} else if (activeLength > initLength) {
if (!grabbed) {
activeLength -= whipSpeed;
}
} else {
remove();
return;
}
if (activeLength == whipLength && !grabbed) {
reverting = true;
}
if (grabbed
&& (System.currentTimeMillis() > time || playerHealth > player
.getHealth())) {
grabbed = false;
reverting = true;
}
useArm();
dragEntity(end);
grapplePlayer(end);
}
private boolean canPlaceBlock(Block block) {
if (!EarthMethods.isTransparentToEarthbending(player, block)
&& !(WaterMethods.isWater(block) && TempBlock
.isTempBlock(block))) {
return false;
}
if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterArms",
block.getLocation())) {
return false;
}
return true;
}
private void useArm() {
if (waterArms.canDisplayActiveArm()) {
Location l1 = null;
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));
if (!canPlaceBlock(l2.getBlock())) {
if (!l2.getBlock().getType().equals(Material.BARRIER)) {
grappled = true;
}
reverting = true;
break;
}
new TempBlock(l2.getBlock(), Material.STATIONARY_WATER,
(byte) 0);
WaterArms.revert.put(l2.getBlock(), 0L);
if (i == activeLength) {
Location l3 = null;
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);
performAction(l3);
} else {
if (!l3.getBlock().getType().equals(Material.BARRIER)) {
grappled = true;
}
reverting = true;
}
}
}
}
}
private void performAction(Location location) {
Location endOfArm = waterArms.getLeftArmEnd().clone();
switch (ability) {
case Pull:
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(
location, 2)) {
if (entity instanceof Player
&& Commands.invincible.contains(((Player) entity)
.getName())) {
continue;
}
Vector vector = endOfArm.toVector().subtract(
entity.getLocation().toVector());
entity.setVelocity(vector.multiply(0.15));
}
break;
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);
}
}
}
break;
case Grapple:
grapplePlayer(end);
break;
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);
grabbedEntity = (LivingEntity) entity;
grabbed = true;
reverting = true;
waterArms.setActiveArmCooldown(true);
break;
}
}
}
break;
default:
break;
}
}
private void dragEntity(Location location) {
if (grabbedEntity != null && grabbed) {
if (!waterArms.canDisplayActiveArm() || grabbedEntity.isDead()) {
grabbed = false;
grabbedEntities.remove(grabbedEntity);
return;
}
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();
Vector vector = new Vector(dx, dy, dz);
if (distance > .5) {
grabbedEntity.setVelocity(vector.normalize().multiply(1));
} else {
grabbedEntity.setVelocity(new Vector(0, 0, 0));
}
grabbedEntity.setFallDistance(0);
if (grabbedEntity instanceof Creature) {
((Creature) grabbedEntity).setTarget(null);
}
}
}
private void grapplePlayer(Location location) {
if (reverting && grappled && player != null && end != null
&& ability.equals(Whip.Grapple)) {
if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterArms",
location) && grappleRespectRegions) {
return;
}
Vector vector = player.getLocation().toVector()
.subtract(location.toVector());
player.setVelocity(vector.multiply(-0.25));
player.setFallDistance(0);
}
}
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);
}
} else {
grabbedEntities.remove(e);
}
}
}
private void remove() {
if (WaterArms.instances.containsKey(player)) {
if (arm.equals(Arm.Left)) {
waterArms.setLeftArmCooldown(false);
} else {
waterArms.setRightArmCooldown(false);
}
if (hasDamaged) {
waterArms.setMaxPunches(waterArms.getMaxPunches() - 1);
}
waterArms.setMaxUses(waterArms.getMaxUses() - 1);
}
instances.remove(id);
}
public static void progressAll() {
checkValidEntities();
for (int ID : instances.keySet())
instances.get(ID).progress();
}
public static void removeAll() {
grabbedEntities.clear();
instances.clear();
}
public Player getPlayer() {
return player;
}
public Integer getWhipLength() {
return whipLength;
}
public void setArmLength(int armLength) {
this.whipLength = armLength;
}
public Double getPunchDamage() {
return punchDamage;
}
public void setPunchDamage(double damage) {
this.punchDamage = damage;
}
public long getHoldTime() {
return holdTime;
}
public void setHoldTime(long holdTime) {
this.holdTime = holdTime;
}
public boolean getReverting() {
return reverting;
}
public void setReverting(boolean reverting) {
this.reverting = reverting;
}
public boolean getGrappled() {
return grappled;
}
public void setGrappled(boolean grappled) {
this.grappled = grappled;
}
public boolean getGrabbed() {
return grabbed;
}
public void setGrabbed(boolean grabbed) {
this.grabbed = grabbed;
}
public LivingEntity getHeldEntity() {
return grabbedEntity;
}
}

View file

@ -368,5 +368,6 @@ public class WaterMethods {
WaterWave.removeAll();
WaterCombo.removeAll();
WaterReturn.removeAll();
WaterArms.removeAll();
}
}

View file

@ -34,6 +34,7 @@ public class WaterbendingManager implements Runnable {
IceBlast.progressAll();
WaterWave.progressAll();
WaterCombo.progressAll();
WaterArms.progressAll();
} catch (Exception e) {
GeneralMethods.logError(e, false);
}

View file

@ -318,6 +318,66 @@ Abilities:
AnimationSpeed: 1
ShootTime: 5000
Cooldown: 10000
WaterArms:
Enabled: true
Description: |-
One of the most diverse moves in a Waterbender's arsenal, this move creates tendrils of water from the players arms to emulate their actual arms. Each water arms mode will be binded to a slot, switch slots to change mode. To deactive the arms, hold Sneak and Double Left-Click.
Pull - Use your Arms to pull blocks, items, mobs or even players towards you!
Punch - An offensive attack, harming players or mobs!
Grapple - Scale walls and speed across battlefields, using your Arms as a grappling hook!
Grab - Grab an entity with your arm, and swing them about!
Freeze - Use your Arms to fire small blasts of ice in any direction!
Spear - Throw your Arms in any direction, freezing whatever it hits!
SneakMessage: 'Active Ability:'
Arms:
InitialLength: 4
SourceGrabRange: 4
MaxAttacks: 10
MaxAlternateUsage: 50
MaxIceShots: 5
Cooldown: 20000
AllowPlantSource: true
Lightning:
Enabled: true
Damage: 10.0
KillUser: false
Cooldowns:
UsageCooldownEnabled: false
UsageCooldown: 200
AllowSpectatorUse: false
Whip:
MaxLength: 20
MaxLengthWeak: 12
NightAugments:
MaxLength:
Normal: 24
FullMoon: 30
Punch:
PunchDamage: 3.0
Grapple:
RespectRegions: false
Grab:
HoldTime: 10000
Freeze:
Range: 20
Damage: 2.0
Spear:
Range: 40
Damage: 4.0
DamageEnabled: true
Sphere: 2
Duration: 6000
Length: 18
NightAugments:
Range:
Normal: 45
FullMoon: 60
Sphere:
Normal: 3
FullMoon: 6
Duration:
Normal: 7000
FullMoon: 12000
Earth:
Passive:
Duration: 2500

View file

@ -31,6 +31,9 @@ permissions:
bending.command.invincible: true
bending.admin.debug: true
bending.admin.remove: true
bending.ability.WaterArms.Grab: true
bending.ability.WaterArms.Freeze: true
bending.ability.WaterArms.Spear: true
bending.player:
default: true
description: Grants access to most abilities and basic commands.
@ -95,6 +98,10 @@ permissions:
bending.water.passive: true
bending.water.icebending: true
bending.water.healing: true
bending.ability.WaterArms: true
bending.ability.WaterArms.Pull: true
bending.ability.WaterArms.Punch: true
bending.ability.WaterArms.Grapple: true
bending.earth:
default: true
description: Grants access to all Earthbending abilities.