mirror of
https://github.com/TotalFreedomMC/TF-ProjectKorra.git
synced 2025-02-11 19:50:37 +00:00
MERGE
This commit is contained in:
commit
7862535a0b
19 changed files with 4214 additions and 1792 deletions
|
@ -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());
|
||||
|
|
|
@ -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(){
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
303
src/com/projectkorra/ProjectKorra/MultiAbilityManager.java
Normal file
303
src/com/projectkorra/ProjectKorra/MultiAbilityManager.java
Normal 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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
665
src/com/projectkorra/ProjectKorra/waterbending/WaterArms.java
Normal file
665
src/com/projectkorra/ProjectKorra/waterbending/WaterArms.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -368,5 +368,6 @@ public class WaterMethods {
|
|||
WaterWave.removeAll();
|
||||
WaterCombo.removeAll();
|
||||
WaterReturn.removeAll();
|
||||
WaterArms.removeAll();
|
||||
}
|
||||
}
|
|
@ -34,6 +34,7 @@ public class WaterbendingManager implements Runnable {
|
|||
IceBlast.progressAll();
|
||||
WaterWave.progressAll();
|
||||
WaterCombo.progressAll();
|
||||
WaterArms.progressAll();
|
||||
} catch (Exception e) {
|
||||
GeneralMethods.logError(e, false);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue