Rebase master and refactor

This commit is contained in:
Nathan Braun 2016-01-13 13:14:34 -08:00
parent 118ec1f32f
commit d2bd987895
209 changed files with 25922 additions and 23141 deletions

View file

@ -1,32 +1,26 @@
package com.projectkorra.projectkorra;
import com.projectkorra.projectkorra.ability.AvatarState;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.FireAbility;
import com.projectkorra.projectkorra.chiblocking.ChiCombo;
import com.projectkorra.projectkorra.chiblocking.RapidPunch;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
import com.projectkorra.projectkorra.firebending.FireMethods;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.object.HorizontalVelocityTracker;
import com.projectkorra.projectkorra.util.Flight;
import com.projectkorra.projectkorra.util.RevertChecker;
import com.projectkorra.projectkorra.util.TempPotionEffect;
import com.projectkorra.projectkorra.waterbending.WaterMethods;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.UUID;
public class BendingManager implements Runnable, ConfigLoadable {
public class BendingManager implements Runnable {
private static BendingManager instance;
private static String sunriseMessage = config.get().getString("Properties.Fire.DayMessage");
private static String sunsetMessage = config.get().getString("Properties.Fire.NightMessage");
private static String moonriseMessage = config.get().getString("Properties.Water.NightMessage");
private static String moonsetMessage = config.get().getString("Properties.Water.DayMessage");
public static HashMap<World, String> events = new HashMap<World, String>(); // holds any current event.
long time;
long interval;
@ -55,34 +49,44 @@ public class BendingManager implements Runnable, ConfigLoadable {
public void handleDayNight() {
for (World world : Bukkit.getServer().getWorlds()) {
if (!times.containsKey(world)) {
if (FireMethods.isDay(world)) {
if (FireAbility.isDay(world)) {
times.put(world, true);
} else {
times.put(world, false);
}
} else {
if (times.get(world) && !FireMethods.isDay(world)) {
if (times.get(world) && !FireAbility.isDay(world)) {
// The hashmap says it is day, but it is not.
times.put(world, false); // Sets time to night.
for (Player player : world.getPlayers()) {
if (GeneralMethods.isBender(player.getName(), Element.Water) && player.hasPermission("bending.message.daymessage")) {
player.sendMessage(WaterMethods.getWaterColor() + moonriseMessage);
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
continue;
}
if (GeneralMethods.isBender(player.getName(), Element.Fire) && player.hasPermission("bending.message.nightmessage")) {
player.sendMessage(FireMethods.getFireColor() + sunsetMessage);
if (bPlayer.hasElement(Element.WATER) && player.hasPermission("bending.message.daymessage")) {
player.sendMessage(Element.WATER.getColor() + getMoonriseMessage());
}
if (bPlayer.hasElement(Element.FIRE) && player.hasPermission("bending.message.nightmessage")) {
player.sendMessage(Element.FIRE.getColor() + getSunsetMessage());
}
}
}
if (!times.get(world) && FireMethods.isDay(world)) {
if (!times.get(world) && FireAbility.isDay(world)) {
// The hashmap says it is night, but it is day.
times.put(world, true);
for (Player player : world.getPlayers()) {
if (GeneralMethods.isBender(player.getName(), Element.Water) && player.hasPermission("bending.message.nightmessage")) {
player.sendMessage(WaterMethods.getWaterColor() + moonsetMessage);
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
continue;
}
if (GeneralMethods.isBender(player.getName(), Element.Fire) && player.hasPermission("bending.message.daymessage")) {
player.sendMessage(FireMethods.getFireColor() + sunriseMessage);
if (bPlayer.hasElement(Element.WATER) && player.hasPermission("bending.message.nightmessage")) {
player.sendMessage(Element.WATER.getColor() + getMoonsetMessage());
}
if (bPlayer.hasElement(Element.FIRE) && player.hasPermission("bending.message.daymessage")) {
player.sendMessage(Element.FIRE.getColor() + getSunriseMessage());
}
}
}
@ -96,29 +100,54 @@ public class BendingManager implements Runnable, ConfigLoadable {
time = System.currentTimeMillis();
ProjectKorra.time_step = interval;
AvatarState.manageAvatarStates();
CoreAbility.progressAll();
TempPotionEffect.progressAll();
handleDayNight();
Flight.handle();
RapidPunch.startPunchAll();
RevertChecker.revertAirBlocks();
ChiCombo.handleParalysis();
HorizontalVelocityTracker.updateAll();
handleCooldowns();
}
catch (Exception e) {
//GeneralMethods.stopBending();
} catch (Exception e) {
GeneralMethods.stopBending();
e.printStackTrace();
}
}
@Override
public void reloadVariables() {
sunriseMessage = config.get().getString("Properties.Fire.DayMessage");
sunsetMessage = config.get().getString("Properties.Fire.NightMessage");
moonriseMessage = config.get().getString("Properties.Water.NightMessage");
moonsetMessage = config.get().getString("Properties.Water.DayMessage");
public static String getSozinsCometMessage() {
return getConfig().getString("Properties.Fire.CometMessage");
}
public static String getSolarEclipseMessage() {
return getConfig().getString("Properties.Fire.SolarEclipseMessage");
}
public static String getSunriseMessage() {
return getConfig().getString("Properties.Fire.DayMessage");
}
public static String getSunsetMessage() {
return getConfig().getString("Properties.Fire.NightMessage");
}
public static String getMoonriseMessage() {
return getConfig().getString("Properties.Water.NightMessage");
}
public static String getFullMoonriseMessage() {
return getConfig().getString("Properties.Water.FullMoonMessage");
}
public static String getLunarEclipseMessage() {
return getConfig().getString("Properties.Water.LunarEclipseMessage");
}
public static String getMoonsetMessage() {
return getConfig().getString("Properties.Water.DayMessage");
}
private static FileConfiguration getConfig() {
return ConfigManager.getConfig();
}
}

View file

@ -1,23 +1,25 @@
package com.projectkorra.projectkorra;
import com.projectkorra.projectkorra.ability.AvatarState;
import com.projectkorra.projectkorra.ability.api.CoreAbility;
import com.projectkorra.projectkorra.ability.api.FireAbility;
import com.projectkorra.projectkorra.ability.api.SubAbility;
import com.projectkorra.projectkorra.ability.api.WaterAbility;
import com.projectkorra.projectkorra.airbending.AirMethods;
import com.projectkorra.projectkorra.chiblocking.ChiMethods;
import com.projectkorra.projectkorra.Element.SubElement;
import com.projectkorra.projectkorra.ability.Ability;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.FireAbility;
import com.projectkorra.projectkorra.ability.SubAbility;
import com.projectkorra.projectkorra.ability.WaterAbility;
import com.projectkorra.projectkorra.avatar.AvatarState;
import com.projectkorra.projectkorra.chiblocking.Paralyze;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.earthbending.EarthMethods;
import com.projectkorra.projectkorra.earthbending.MetalClips;
import com.projectkorra.projectkorra.event.PlayerCooldownChangeEvent;
import com.projectkorra.projectkorra.event.PlayerCooldownChangeEvent.Result;
import com.projectkorra.projectkorra.firebending.FireMethods;
import com.projectkorra.projectkorra.storage.DBConnection;
import com.projectkorra.projectkorra.waterbending.WaterMethods;
import com.projectkorra.projectkorra.waterbending.Bloodbending;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
@ -29,30 +31,28 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/**
* Class that presents a player and stores all bending information about the
* player.
* Class that presents a player and stores all bending information about the player.
*/
public class BendingPlayer {
/**
* ConcurrentHashMap that contains all instances of BendingPlayer, with UUID
* key.
* ConcurrentHashMap that contains all instances of BendingPlayer, with UUID key.
*/
private static ConcurrentHashMap<UUID, BendingPlayer> players = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<UUID, BendingPlayer> PLAYERS = new ConcurrentHashMap<>();
private boolean permaRemoved;
private boolean toggled;
private boolean tremorSense;
private boolean chiBlocked;
private long slowTime;
private Player player;
private UUID uuid;
private String name;
private Player player;
private FileConfiguration config;
private ChiAbility stance;
private ArrayList<Element> elements;
private HashMap<Integer, String> abilities;
private ConcurrentHashMap<String, Long> cooldowns;
private ConcurrentHashMap<Element, Boolean> toggledElements;
private boolean permaRemoved;
private boolean toggled = true;
private long slowTime = 0;
private boolean tremorSense = true;
private boolean chiBlocked = false;
private ConcurrentHashMap<Element, Boolean> toggledElements;
/**
* Creates a new {@link BendingPlayer}.
@ -63,44 +63,45 @@ public class BendingPlayer {
* @param abilities The known abilities
* @param permaRemoved The permanent removed status
*/
public BendingPlayer(UUID uuid, String playerName, ArrayList<Element> elements, HashMap<Integer, String> abilities, boolean permaRemoved) {
public BendingPlayer(UUID uuid, String playerName, ArrayList<Element> elements, HashMap<Integer, String> abilities,
boolean permaRemoved) {
this.uuid = uuid;
this.name = playerName;
this.elements = elements;
this.setAbilities(abilities);
this.permaRemoved = permaRemoved;
this.player = Bukkit.getPlayer(uuid);
this.config = ConfigManager.getConfig();
this.toggled = true;
this.tremorSense = true;
this.chiBlocked = false;
cooldowns = new ConcurrentHashMap<String, Long>();
toggledElements = new ConcurrentHashMap<Element, Boolean>();
toggledElements.put(Element.Air, true);
toggledElements.put(Element.Earth, true);
toggledElements.put(Element.Fire, true);
toggledElements.put(Element.Water, true);
toggledElements.put(Element.Chi, true);
toggledElements.put(Element.AIR, true);
toggledElements.put(Element.EARTH, true);
toggledElements.put(Element.FIRE, true);
toggledElements.put(Element.WATER, true);
toggledElements.put(Element.CHI, true);
players.put(uuid, this);
PLAYERS.put(uuid, this);
PKListener.login(this);
}
public void addCooldown(Ability ability, long cooldown) {
addCooldown(ability.getName(), cooldown);
}
/**
* Gets the map of {@link BendingPlayer}s.
*
* @return {@link #players}
*/
public static ConcurrentHashMap<UUID, BendingPlayer> getPlayers() {
return players;
public void addCooldown(CoreAbility ability) {
addCooldown(ability, ability.getCooldown());
}
/**
* Adds an ability to the cooldowns map while firing a
* {@link PlayerCooldownChangeEvent}.
* Adds an ability to the cooldowns map while firing a {@link PlayerCooldownChangeEvent}.
*
* @param ability Name of the ability
* @param cooldown The cooldown time
*/
public void addCooldown(String ability, long cooldown) {
PlayerCooldownChangeEvent event = new PlayerCooldownChangeEvent(Bukkit.getPlayer(uuid), ability, cooldown, Result.ADDED);
PlayerCooldownChangeEvent event = new PlayerCooldownChangeEvent(Bukkit.getPlayer(uuid), ability, Result.ADDED);
Bukkit.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
this.cooldowns.put(ability, cooldown + System.currentTimeMillis());
@ -112,8 +113,8 @@ public class BendingPlayer {
*
* @param e The element to add
*/
public void addElement(Element e) {
this.elements.add(e);
public void addElement(Element element) {
this.elements.add(element);
}
/**
@ -123,6 +124,109 @@ public class BendingPlayer {
chiBlocked = true;
}
/**
* Checks to see if a Player is effected by BloodBending.
*
* @return true If {@link ChiMethods#isChiBlocked(String)} is true <br />
* false If player is BloodBender and Bending is toggled on, or if player is in
* AvatarState
*/
public boolean canBeBloodbent() {
if (isAvatarState()) {
if (isChiBlocked()) {
return true;
}
}
if (canBendIgnoreBindsCooldowns(CoreAbility.getAbility("Bloodbending")) && !isToggled()) {
return false;
}
return true;
}
public boolean canBend(CoreAbility ability) {
return canBend(ability, false, false);
}
private boolean canBend(CoreAbility ability, boolean ignoreBinds, boolean ignoreCooldowns) {
if (ability == null) {
return false;
}
List<String> disabledWorlds = getConfig().getStringList("Properties.DisabledWorlds");
Location location = null;
if (player != null) {
location = player.getLocation();
}
if (player == null || !player.isOnline() || player.isDead()) {
return false;
} else if (location != null && !location.getWorld().equals(player.getWorld())) {
return false;
} else if (!ignoreCooldowns && isOnCooldown(ability.getName())) {
return false;
} else if (!ignoreBinds && !ability.getName().equals(getBoundAbilityName())) {
return false;
} else if (disabledWorlds != null && disabledWorlds.contains(player.getWorld().getName())) {
return false;
} else if (Commands.isToggledForAll || !isToggled() || !isElementToggled(ability.getElement())) {
return false;
} else if (player.getGameMode() == GameMode.SPECTATOR) {
return false;
}
if (!ignoreCooldowns && cooldowns.containsKey(name)) { // TODO: wtf is this
if (cooldowns.get(name) + getConfig().getLong("Properties.GlobalCooldown") >= System.currentTimeMillis()) {
return false;
}
cooldowns.remove(name);
}
if (isChiBlocked() || isParalyzed() || isBloodbended() || isControlledByMetalClips()) {
return false;
} else if (GeneralMethods.isRegionProtectedFromBuild(player, ability.getName(), location)) {
return false;
} else if (ability instanceof FireAbility && BendingManager.events.get(player.getWorld()) != null
&& BendingManager.events.get(player.getWorld()).equalsIgnoreCase("SolarEclipse")) {
return false;
} else if (ability instanceof WaterAbility && BendingManager.events.get(player.getWorld()) != null
&& BendingManager.events.get(player.getWorld()).equalsIgnoreCase("LunarEclipse")) {
return false;
}
if (!ignoreBinds && !canBind(ability)) {
return false;
}
return true;
}
public boolean canBendIgnoreBinds(CoreAbility ability) {
return canBend(ability, true, false);
}
public boolean canBendIgnoreBindsCooldowns(CoreAbility ability) {
return canBend(ability, true, true);
}
public boolean canBendIgnoreCooldowns(CoreAbility ability) {
return canBend(ability, false, true);
}
public boolean canBendPassive(Element element) {
if (element == null || player == null) {
return false;
} else if (!player.hasPermission("bending." + element.getName() + ".passive")) {
return false;
} else if (!isToggled() || !hasElement(element) || !isElementToggled(element)) {
return false;
} else if (isChiBlocked() || isParalyzed() || isBloodbended()) {
return false;
} else if (GeneralMethods.isRegionProtectedFromBuild(player, player.getLocation())) {
return false;
}
return true;
}
/**
* Checks to see if {@link BendingPlayer} can be slowed.
*
@ -132,41 +236,18 @@ public class BendingPlayer {
return (System.currentTimeMillis() > slowTime);
}
/**
* Checks to see if a player can use Flight.
*
* @return true If player has permission node "bending.air.flight"
*/
public boolean canAirFlight() {
return player.hasPermission("bending.air.flight");
}
/**
* Checks to see if a player can use SpiritualProjection.
*
* @param player The player to check
* @return true If player has permission node
* "bending.air.spiritualprojection"
*/
public boolean canUseSpiritualProjection() {
return player.hasPermission("bending.air.spiritualprojection");
}
/**
* Checks to see if a Player is effected by BloodBending.
*
* @return true If {@link ChiMethods#isChiBlocked(String)} is true <br />
* false If player is BloodBender and Bending is toggled on, or if
* player is in AvatarState
*/
public boolean canBeBloodbent() {
if (AvatarState.isAvatarState(player)) {
if (ChiMethods.isChiBlocked(name)) {
return true;
}
}
if (GeneralMethods.canBend(name, "Bloodbending") && !isToggled()) {
public boolean canBind(CoreAbility ability) {
if (ability == null || !player.isOnline()) {
return false;
} else if (!player.hasPermission("bending.ability." + ability.getName())) {
return false;
} else if (!hasElement(ability.getElement())) {
return false;
} else if (ability instanceof SubAbility) {
SubAbility subAbil = (SubAbility) ability;
if (!hasElement(subAbil.getParentElement())) {
return false;
}
}
return true;
}
@ -179,30 +260,58 @@ public class BendingPlayer {
public boolean canBloodbend() {
return player.hasPermission("bending.water.bloodbending");
}
public boolean canBloodbendAtAnytime() {
return canBloodbend() && player.hasPermission("bending.water.bloodbending.anytime");
}
public boolean canCombustionbend() {
return player.hasPermission("bending.fire.combustionbending");
}
public boolean canIcebend() {
return player.hasPermission("bending.water.icebending");
}
/**
* Checks to see if a player can LavaBend.
*
* @param player The player to check
* @return true If player has permission node "bending.earth.lavabending"
*/
public boolean canLavabend() {
return player.hasPermission("bending.earth.lavabending");
}
public boolean canLightningbend() {
return player.hasPermission("bending.fire.lightningbending");
}
/**
* Checks to see if a player can MetalBend.
*
* @param player The player to check
* @return true If player has permission node "bending.earth.metalbending"
*/
public boolean canMetalbend() {
return player.hasPermission("bending.earth.metalbending");
}
public boolean canPackedIcebend() {
return getConfig().getBoolean("Properties.Water.CanBendPackedIce");
}
/**
* Checks to see if a player can PlantBend.
*
* @param player The player to check
* @return true If player has permission node "bending.ability.plantbending"
*/
public static boolean canPlantbend(Player player) {
public boolean canPlantbend() {
return player.hasPermission("bending.water.plantbending");
}
public boolean canWaterHeal() {
return player.hasPermission("bending.water.healing");
}
/**
* Checks to see if a player can SandBend.
*
@ -214,31 +323,26 @@ public class BendingPlayer {
}
/**
* Checks to see if a player can MetalBend.
* Checks to see if a player can use Flight.
*
* @param player The player to check
* @return true If player has permission node "bending.earth.metalbending"
* @return true If player has permission node "bending.air.flight"
*/
public boolean canMetalbend() {
return player.hasPermission("bending.earth.metalbending");
public boolean canUseFlight() {
return player.hasPermission("bending.air.flight");
}
/**
* Checks to see if a player can LavaBend.
* Checks to see if a player can use SpiritualProjection.
*
* @param player The player to check
* @return true If player has permission node "bending.earth.lavabending"
* @return true If player has permission node "bending.air.spiritualprojection"
*/
public static boolean canLavabend(Player player) {
return player.hasPermission("bending.earth.lavabending");
public boolean canUseSpiritualProjection() {
return player.hasPermission("bending.air.spiritualprojection");
}
public static boolean canCombustionbend(Player player) {
return player.hasPermission("bending.fire.combustionbending");
}
public static boolean canLightningbend(Player player) {
return player.hasPermission("bending.fire.lightningbending");
public boolean canWaterHeal() {
return player.hasPermission("bending.water.healing");
}
/**
@ -250,6 +354,21 @@ public class BendingPlayer {
return this.abilities;
}
public CoreAbility getBoundAbility() {
return CoreAbility.getAbility(getBoundAbilityName());
}
/**
* Gets the Ability bound to the slot that the player is in.
*
* @return The Ability name bounded to the slot
*/
public String getBoundAbilityName() {
int slot = player.getInventory().getHeldItemSlot() + 1;
String name = getAbilities().get(slot);
return name != null ? name : "";
}
/**
* Gets the cooldown time of the ability.
*
@ -265,7 +384,7 @@ public class BendingPlayer {
}
return -1;
}
/**
* Gets the map of cooldowns of the {@link BendingPlayer}.
*
@ -293,6 +412,15 @@ public class BendingPlayer {
return this.name;
}
/**
* Gets the {@link ChiAbility Chi stance} the player is in
*
* @return The player's stance object
*/
public ChiAbility getStance() {
return stance;
}
/**
* Gets the unique identifier of the {@link BendingPlayer}.
*
@ -310,22 +438,43 @@ public class BendingPlayer {
public String getUUIDString() {
return this.uuid.toString();
}
/**
* Checks to see if the {@link BendingPlayer} knows a specific element.
*
* @param e The element to check
* @param element The element to check
* @return true If the player knows the element
*/
public boolean hasElement(Element e) {
return this.elements.contains(e);
public boolean hasElement(Element element) {
if (element == null) {
return false;
} else if (element == Element.AVATAR) {
// At the moment we'll allow for both permissions to return true.
// Later on we can consider deleting the bending.ability.avatarstate option.
return player.hasPermission("bending.avatar") || player.hasPermission("bending.ability.AvatarState");
} else if (!(element instanceof SubElement)) {
return this.elements.contains(element);
} else {
Element parentElement = ((SubElement) element).getParentElement();
String prefix = "bending." + parentElement.getName() + ".";
// Some permissions are bending.water.name and some are bending.water.namebending
if (player.hasPermission(prefix + element.getName())
|| player.hasPermission(prefix + element.getName() + "bending")) {
return true;
}
}
return false;
}
public boolean hasElement(String elementName) {
//TODO: Finish this
return true;
public boolean isAvatarState() {
return CoreAbility.hasAbility(player, AvatarState.class);
}
public boolean isBloodbended() {
return Bloodbending.isBloodbended(player);
}
/**
* Checks to see if the {@link BendingPlayer} is chi blocked.
*
@ -335,12 +484,21 @@ public class BendingPlayer {
return this.chiBlocked;
}
public boolean isElementToggled(Element e) {
if (e != null)
return this.toggledElements.get(e);
public boolean isControlledByMetalClips() {
return MetalClips.isControlled(player);
}
public boolean isElementToggled(Element element) {
if (element != null && toggledElements.containsKey(element)) {
return toggledElements.containsKey(element);
}
return true;
}
public boolean isOnCooldown(Ability ability) {
return isOnCooldown(ability.getName());
}
/**
* Checks to see if a specific ability is on cooldown.
*
@ -348,7 +506,14 @@ public class BendingPlayer {
* @return true if the cooldown map contains the ability
*/
public boolean isOnCooldown(String ability) {
return this.cooldowns.containsKey(ability);
if (this.cooldowns.containsKey(ability)) {
return System.currentTimeMillis() < cooldowns.get(ability);
}
return false;
}
public boolean isParalyzed() {
return Paralyze.isParalyzed(player);
}
/**
@ -368,11 +533,6 @@ public class BendingPlayer {
public boolean isToggled() {
return this.toggled;
}
public boolean isElementToggled(String elementName) {
// TODO: Finish this
return true;
}
/**
* Checks if the {@link BendingPlayer} is tremor sensing.
@ -383,13 +543,19 @@ public class BendingPlayer {
return this.tremorSense;
}
public void removeCooldown(CoreAbility ability) {
if (ability != null) {
removeCooldown(ability.getName());
}
}
/**
* Removes the cooldown of an ability.
*
* @param ability The ability's cooldown to remove
*/
public void removeCooldown(String ability) {
PlayerCooldownChangeEvent event = new PlayerCooldownChangeEvent(Bukkit.getPlayer(uuid), ability, 0, Result.REMOVED);
PlayerCooldownChangeEvent event = new PlayerCooldownChangeEvent(Bukkit.getPlayer(uuid), ability, Result.REMOVED);
Bukkit.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
this.cooldowns.remove(ability);
@ -397,8 +563,8 @@ public class BendingPlayer {
}
/**
* Sets the {@link BendingPlayer}'s abilities. This method also saves the
* abilities to the database.
* Sets the {@link BendingPlayer}'s abilities. This method also saves the abilities to the
* database.
*
* @param abilities The abilities to set/save
*/
@ -410,14 +576,14 @@ public class BendingPlayer {
}
/**
* Sets the {@link BendingPlayer}'s element. If the player had elements
* before they will be overwritten.
* Sets the {@link BendingPlayer}'s element. If the player had elements before they will be
* overwritten.
*
* @param e The element to set
*/
public void setElement(Element e) {
public void setElement(Element element) {
this.elements.clear();
this.elements.add(e);
this.elements.add(element);
}
/**
@ -428,6 +594,15 @@ public class BendingPlayer {
public void setPermaRemoved(boolean permaRemoved) {
this.permaRemoved = permaRemoved;
}
/**
* Sets the player's {@link ChiAbility Chi stance}
*
* @param stance The player's new stance object
*/
public void setStance(ChiAbility stance) {
this.stance = stance;
}
/**
* Slow the {@link BendingPlayer} for a certain amount of time.
@ -437,7 +612,7 @@ public class BendingPlayer {
public void slow(long cooldown) {
slowTime = System.currentTimeMillis() + cooldown;
}
/**
* Toggles the {@link BendingPlayer}'s bending.
*/
@ -445,10 +620,13 @@ public class BendingPlayer {
toggled = !toggled;
}
public void toggleElement(Element e) {
toggledElements.put(e, !toggledElements.get(e));
public void toggleElement(Element element) {
if (element == null) {
return;
}
toggledElements.put(element, !toggledElements.get(element));
}
/**
* Toggles the {@link BendingPlayer}'s tremor sensing.
*/
@ -462,75 +640,27 @@ public class BendingPlayer {
public void unblockChi() {
chiBlocked = false;
}
public boolean canBend(CoreAbility ability) {
if (player == null) {
return false;
public static BendingPlayer getBendingPlayer(OfflinePlayer oPlayer) {
if (oPlayer == null) {
return null;
}
if (isOnCooldown(ability.getName())) {
return false;
}
List<String> disabledWorlds = config.getStringList("Properties.DisabledWorlds");
if (disabledWorlds != null && disabledWorlds.contains(player.getWorld().getName())) {
return false;
}
if (Commands.isToggledForAll || !isToggled() || !isElementToggled(ability.getName())) {
return false;
}
if (player.getGameMode() == GameMode.SPECTATOR) {
return false;
}
if (cooldowns.containsKey(name)) {
if (cooldowns.get(name) + config.getLong("Properties.GlobalCooldown") >= System.currentTimeMillis()) {
return false;
}
cooldowns.remove(name);
}
if (isChiBlocked() || isParalyzed() || isBloodbended() || isControlledByMetalClips()) {
return false;
}
if (GeneralMethods.isRegionProtectedFromBuild(player, ability.getName(), player.getLocation())) {
return false;
}
if (ability instanceof FireAbility && BendingManager.events.get(player.getWorld()) != null && BendingManager.events.get(player.getWorld()).equalsIgnoreCase("SolarEclipse")) {
return false;
}
if (ability instanceof WaterAbility && BendingManager.events.get(player.getWorld()) != null && BendingManager.events.get(player.getWorld()).equalsIgnoreCase("LunarEclipse")) {
return false;
}
if (!canBind(ability)) {
return false;
}
return true;
return BendingPlayer.getPlayers().get(oPlayer.getUniqueId());
}
public boolean canBind(CoreAbility ability) {
public static BendingPlayer getBendingPlayer(Player player) {
if (player == null) {
return false;
return null;
}
if (!player.hasPermission("bending.ability." + ability)) {
return false;
}
if (!hasElement(ability.getElementName())) {
return false;
}
if (ability instanceof SubAbility) {
SubAbility subAbil = (SubAbility) ability;
if (!hasElement(subAbil.getSubElementName())) {
return false;
}
}
return true;
return getBendingPlayer(player.getName());
}
/**
* Attempts to get a {@link BendingPlayer} from specified player name. this
* method tries to get a {@link Player} object and gets the uuid and then
* calls {@link #getBendingPlayer(UUID)}
* Attempts to get a {@link BendingPlayer} from specified player name. this method tries to get
* a {@link Player} object and gets the uuid and then calls {@link #getBendingPlayer(UUID)}
*
* @param playerName The name of the Player
* @return The BendingPlayer object if {@link BendingPlayer#players}
* contains the player name
* @return The BendingPlayer object if {@link BendingPlayer#PLAYERS} contains the player name
*
* @see #getBendingPlayer(UUID)
*/
@ -539,7 +669,19 @@ public class BendingPlayer {
if (player == null) {
oPlayer = Bukkit.getOfflinePlayer(oPlayer.getUniqueId());
}
return BendingPlayer.getPlayers().get(oPlayer.getUniqueId());
return getBendingPlayer(oPlayer);
}
private static FileConfiguration getConfig() {
return ConfigManager.getConfig();
}
/**
* Gets the map of {@link BendingPlayer}s.
*
* @return {@link #PLAYERS}
*/
public static ConcurrentHashMap<UUID, BendingPlayer> getPlayers() {
return PLAYERS;
}
}

View file

@ -1,92 +1,90 @@
package com.projectkorra.projectkorra;
import java.util.Arrays;
import org.bukkit.ChatColor;
import com.projectkorra.projectkorra.airbending.AirMethods;
import com.projectkorra.projectkorra.chiblocking.ChiMethods;
import com.projectkorra.projectkorra.earthbending.EarthMethods;
import com.projectkorra.projectkorra.firebending.FireMethods;
import com.projectkorra.projectkorra.waterbending.WaterMethods;
import java.util.HashMap;
public enum Element {
public class Element {
Air (AirMethods.getAirColor(), AirMethods.getAirSubColor()),
Water (WaterMethods.getWaterColor(), WaterMethods.getWaterSubColor()),
Earth (EarthMethods.getEarthColor(), EarthMethods.getEarthSubColor()),
Fire (FireMethods.getFireColor(), FireMethods.getFireSubColor()),
Chi (ChiMethods.getChiColor(), ChiMethods.getChiColor());
private static final HashMap<String, Element> ALL_ELEMENTS = new HashMap<>(); // Must be initialized first
private ChatColor color, subcolor;
public static final Element AIR = new Element("Air");
public static final Element WATER = new Element("Water");
public static final Element EARTH = new Element("Earth");
public static final Element FIRE = new Element("Fire");
public static final Element CHI = new Element("Chi");
public static final Element AVATAR = new Element("Avatar");
public static final SubElement FLIGHT = new SubElement("Flight", AIR);
public static final SubElement SPIRITUAL = new SubElement("Spiritual", AIR);
public static final SubElement BLOOD = new SubElement("Blood", WATER);
public static final SubElement HEALING = new SubElement("Healing", WATER);
public static final SubElement ICE = new SubElement("Ice", WATER);
public static final SubElement PLANT = new SubElement("Plant", WATER);
public static final SubElement LAVA = new SubElement("Lava", EARTH);
public static final SubElement METAL = new SubElement("Metal", EARTH);
public static final SubElement SAND = new SubElement("Sand", EARTH);
public static final SubElement LIGHTNING = new SubElement("Lightning", FIRE);
public static final SubElement COMBUSTION = new SubElement("Combustion", FIRE);
private static final Element[] ELEMENTS = {AIR, WATER, EARTH, FIRE, CHI, FLIGHT, SPIRITUAL, BLOOD, HEALING, ICE, PLANT, LAVA, METAL, SAND, LIGHTNING, COMBUSTION};
private static final Element[] MAIN_ELEMENTS = {AIR, WATER, EARTH, FIRE, CHI};
private static final SubElement[] SUB_ELEMENTS = {FLIGHT, SPIRITUAL, BLOOD, HEALING, ICE, PLANT, LAVA, METAL, SAND, LIGHTNING, COMBUSTION};
private String name;
Element(ChatColor mainColor, ChatColor subColor) {
this.color = mainColor;
this.subcolor = subColor;
private Element(String name) {
this.name = name;
ALL_ELEMENTS.put(name.toLowerCase(), this);
}
/**
* Returns the chatcolor to be used associated with this element
* @return The Element ChatColor
* */
public ChatColor getChatColor() {
return color;
public ChatColor getColor() {
return ChatColor.valueOf(ProjectKorra.plugin.getConfig().getString("Properties.Chat.Colors." + name));
}
/**
* Returns the chatcolor that's associated the sub-elements of this element
* @return The SubElement ChatColor
* */
public ChatColor getSubColor() {
return subcolor;
public String getName() {
return name;
}
/**
* Returns all the subelements that should be associated with this element
* @return The Element's SubElements
* */
public SubElement[] getSubElements() {
if (this == Air) {
return new SubElement[] {SubElement.Flight, SubElement.SpiritualProjection};
}
if (this == Water) {
return new SubElement[] {SubElement.Bloodbending, SubElement.Icebending, SubElement.Plantbending, SubElement.Healing};
}
if (this == Fire) {
return new SubElement[] {SubElement.Combustion, SubElement.Lightning};
}
if (this == Earth) {
return new SubElement[] {SubElement.Sandbending, SubElement.Metalbending, SubElement.Lavabending};
}
return new SubElement[] {};
@Override
public String toString() {
return getColor() + getName();
}
public static Element getType(String string) {
for (Element element : Element.values()) {
if (element.toString().equalsIgnoreCase(string)) {
return element;
}
}
return null;
}
public static Element getType(int index) {
if (index == -1)
public static Element getElement(String name) {
if (name == null) {
return null;
return Arrays.asList(values()).get(index);
}
return ALL_ELEMENTS.get(name.toLowerCase());
}
/**
* Returns an element based on ChatColor.
* @param color
* @return
*/
public static Element getFromChatColor(ChatColor color) {
for (Element element : Element.values()) {
if (element.getChatColor().equals(color) || element.getSubColor().equals(color)) {
return element;
}
public static Element[] getElements() {
return ELEMENTS;
}
public static Element[] getMainElements() {
return MAIN_ELEMENTS;
}
public static SubElement[] getSubElements() {
return SUB_ELEMENTS;
}
public static class SubElement extends Element {
private Element parentElement;
private SubElement(String name, Element parentElement) {
super(name);
this.parentElement = parentElement;
}
@Override
public ChatColor getColor() {
return ChatColor.valueOf(ProjectKorra.plugin.getConfig().getString("Properties.Chat.Colors." + parentElement.name + "Sub"));
}
public Element getParentElement() {
return this.parentElement;
}
return null;
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,17 +1,14 @@
package com.projectkorra.projectkorra;
import com.projectkorra.projectkorra.ability.AbilityModuleManager;
import com.projectkorra.projectkorra.ability.combo.ComboManager;
import com.projectkorra.projectkorra.ability.combo.ComboModuleManager;
import com.projectkorra.projectkorra.ability.multiability.MultiAbilityManager;
import com.projectkorra.projectkorra.ability.multiability.MultiAbilityModuleManager;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.util.ComboManager;
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager;
import com.projectkorra.projectkorra.airbending.AirbendingManager;
import com.projectkorra.projectkorra.chiblocking.ChiblockingManager;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.earthbending.EarthbendingManager;
import com.projectkorra.projectkorra.firebending.FirebendingManager;
import com.projectkorra.projectkorra.object.Preset;
import com.projectkorra.projectkorra.storage.DBConnection;
import com.projectkorra.projectkorra.util.MetricsLite;
import com.projectkorra.projectkorra.util.RevertChecker;
@ -34,7 +31,7 @@ public class ProjectKorra extends JavaPlugin {
public static PKLogHandler handler;
public static long time_step = 1;
public Updater updater;
public AbilityModuleManager abManager;
@Override
public void onEnable() {
plugin = this;
@ -50,17 +47,14 @@ public class ProjectKorra extends JavaPlugin {
catch (SecurityException | IOException e) {
e.printStackTrace();
}
CoreAbility.registerAbilities();
new ConfigManager();
new GeneralMethods(this);
updater = new Updater(this, "http://projectkorra.com/forums/dev-builds.16/index.rss");
new Commands(this);
abManager = new AbilityModuleManager(this);
new MultiAbilityModuleManager();
new MultiAbilityManager();
new ComboModuleManager();
new ComboManager();
Preset.loadExternalPresets();
DBConnection.host = getConfig().getString("Storage.MySQL.host");
DBConnection.port = getConfig().getInt("Storage.MySQL.port");
@ -94,8 +88,9 @@ public class ProjectKorra extends JavaPlugin {
e.printStackTrace();
}
double cacheTime = ConfigManager.getConfig().getDouble("Properties.RegionProtection.CacheBlockTime");
GeneralMethods.deserializeFile();
GeneralMethods.startCacheCleaner(GeneralMethods.CACHE_TIME);
GeneralMethods.startCacheCleaner(cacheTime);
updater.checkUpdate();
}

View file

@ -1,65 +0,0 @@
package com.projectkorra.projectkorra;
import com.projectkorra.projectkorra.command.Commands;
import org.bukkit.ChatColor;
import java.util.Arrays;
public enum SubElement {
//Air
Flight (Element.Air, Commands.flightaliases),
SpiritualProjection (Element.Air, Commands.spiritualprojectionaliases),
//Water
Bloodbending (Element.Water, Commands.bloodaliases),
Healing (Element.Water, Commands.healingaliases),
Icebending (Element.Water, Commands.icealiases),
Plantbending (Element.Water, Commands.plantaliases),
// Earth
Metalbending (Element.Earth, Commands.metalbendingaliases),
Sandbending (Element.Earth, Commands.sandbendingaliases),
Lavabending (Element.Earth, Commands.lavabendingaliases),
// Fire
Combustion (Element.Fire, Commands.combustionaliases),
Lightning (Element.Fire, Commands.lightningaliases);
private Element element;
private String[] aliases;
SubElement(Element mainElement, String[] aliases) {
this.element = mainElement;
this.aliases = aliases;
}
/**Returns the main element associated with the subelement
* @return The main element*/
public Element getMainElement() {
return element;
}
/**Returns the subelement's chatcolor that should be used
* @return The subelement's ChatColor*/
public ChatColor getChatColor() {
return element.getSubColor();
}
public static SubElement getType(String string) {
for (SubElement se : SubElement.values()) {
if (Arrays.asList(se.aliases).contains(string.toLowerCase())) {
return se;
}
}
return null;
}
public static SubElement getType(int index) {
if (index == -1)
return null;
return Arrays.asList(values()).get(index);
}
}

View file

@ -0,0 +1,42 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import org.bukkit.Location;
import org.bukkit.entity.Player;
public interface Ability {
public void progress();
public void remove();
public boolean isSneakAbility();
/**
* Determines if this ability is considered harmless against other players. A harmless
* ability cannot manipulate another player. For example: AirPassive,
* WaterSpout, AirSpout, and FireJet.
* @return true if the ability is harmless and should be allowed in both PvP and non-PvP zones.
*/
public boolean isHarmlessAbility();
public boolean isIgniteAbility();
public boolean isExplosiveAbility();
public boolean isHiddenAbility();
public long getCooldown();
public Player getPlayer();
public String getName();
public String getDescription();
public Element getElement();
public Location getLocation();
}

View file

@ -1,123 +0,0 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.SubElement;
import com.projectkorra.projectkorra.util.AbilityLoadable;
public abstract class AbilityModule extends AbilityLoadable implements Cloneable {
/**
* AbilityModule Constructor.
*
* @param name The name of the ability.
*/
public AbilityModule(final String name) {
super(name);
}
/**
* Called when the ability is loaded by PK. This is where the developer
* registers Listeners and Permissions.
*/
public abstract void onThisLoad();
// Must be overridden
/**
* Accessor Method to get the version of the ability.
*
* @return The version of the ability as a String.
*/
public abstract String getVersion();
/**
* Accessor Method to get the Element of the ability. It is recommended to
* use the Element ENUM to get the returned String. This can be an empty
* String, in which case the ability will not belong to any element (such as
* AvatarState).
*
* @return The Element the ability belongs to.
*/
public abstract String getElement();
/**
* Accessor Method to get the name of the author.
*
* @return The name of the author.
*/
public abstract String getAuthor();
/**
* Accessor Method to get the description of the ability. This String is
* sent to any player who runs /pk display ability.
*
* @return The Description of the ability.
*/
public abstract String getDescription();
/**
* Accessor Method to get whether this ability uses sneaking to operate.
* Some features of the ProjectKorra plugin only work when this is false.
* (Fast Swimming for Waterbenders)
*
* @return Whether or not the ability uses the sneak key.
*/
public abstract boolean isShiftAbility();
/**
* Accessor Method to get whether this ability harms entities. AirSpout is
* an example of a harmless ability. For AirSpout, this returns true.
* IceBlast is an example of a harmful ability. For IceBlast, this returns
* false. Torrent is an example of both a harmless and a harmful ability.
* For Torrent, this returns false.
*
* @return Whether of not the ability can hurt entities.
*/
public abstract boolean isHarmlessAbility();
/**
* Accessor Method to get whether this ability can set fire to blocks.
*
* @return Whether or not this ability can ignite blocks.
*/
public boolean isIgniteAbility() {
return false;
}
/**
* Accessor Method to get whether this ability can create explosions.
*
* @return Whether or not this ability creates explosions.
*/
public boolean isExplodeAbility() {
return false;
}
/**
* Void Method called whenever ProjectKorra stops and the ability is
* unloaded.
*
*/
public void stop() {
}
/**
* Accessor Method to get which SubElement the ability belongs to. If
* isSubAbility() returns true, the developer absolutely must implement this
* as well.
*
* List of sub-elements:
*
* Water: Icebending. Bloodbending. Plantbending. Healing.
*
* Earth: Sandbending. Metalbending. Lavabending.
*
* Fire: Combustion. Lightning.
*
* Air: Flight. SpiritualProjection.
*
* @return The SubElement the ability belongs to.
*/
public SubElement getSubElement() {
return null;
}
}

View file

@ -1,427 +0,0 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.util.AbilityLoader;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
public class AbilityModuleManager {
static ProjectKorra plugin;
public static List<AbilityModule> ability;
private final AbilityLoader<AbilityModule> loader;
public static HashSet<String> abilities;
public static HashSet<String> disabledStockAbilities;
public static List<String> waterbendingabilities;
public static List<String> airbendingabilities;
public static List<String> earthbendingabilities;
public static List<String> firebendingabilities;
public static List<String> chiabilities;
public static List<String> shiftabilities;
public static HashMap<String, String> authors;
public static List<String> harmlessabilities;
public static List<String> igniteabilities;
public static List<String> explodeabilities;
public static List<String> metalbendingabilities;
public static List<String> earthsubabilities;
public static List<String> subabilities;
public static List<String> lightningabilities;
public static List<String> combustionabilities;
public static List<String> lavaabilities;
public static List<String> sandabilities;
public static List<String> metalabilities;
public static List<String> flightabilities;
public static List<String> spiritualprojectionabilities;
public static List<String> iceabilities;
public static List<String> healingabilities;
public static List<String> plantabilities;
public static List<String> bloodabilities;
public static HashMap<String, String> descriptions;
public AbilityModuleManager(final ProjectKorra plugin) {
AbilityModuleManager.plugin = plugin;
final File path = new File(plugin.getDataFolder().toString() + "/Abilities/");
if (!path.exists()) {
path.mkdir();
}
loader = new AbilityLoader<AbilityModule>(plugin, path, new Object[] {});
abilities = new HashSet<String>();
waterbendingabilities = new ArrayList<String>();
airbendingabilities = new ArrayList<String>();
earthbendingabilities = new ArrayList<String>();
firebendingabilities = new ArrayList<String>();
chiabilities = new ArrayList<String>();
shiftabilities = new ArrayList<String>();
descriptions = new HashMap<String, String>();
authors = new HashMap<String, String>();
harmlessabilities = new ArrayList<String>();
explodeabilities = new ArrayList<String>();
igniteabilities = new ArrayList<String>();
metalbendingabilities = new ArrayList<String>();
earthsubabilities = new ArrayList<String>();
subabilities = new ArrayList<String>();
ability = loader.load(AbilityModule.class);
disabledStockAbilities = new HashSet<String>();
lightningabilities = new ArrayList<String>();
combustionabilities = new ArrayList<String>();
flightabilities = new ArrayList<String>();
spiritualprojectionabilities = new ArrayList<String>();
metalabilities = new ArrayList<String>();
sandabilities = new ArrayList<String>();
lavaabilities = new ArrayList<String>();
healingabilities = new ArrayList<String>();
plantabilities = new ArrayList<String>();
iceabilities = new ArrayList<String>();
bloodabilities = new ArrayList<String>();
fill();
}
private void fill() {
for (StockAbility a : StockAbility.values()) {
if (StockAbility.isAirbending(a)) {
if (ProjectKorra.plugin.getConfig().getBoolean("Abilities.Air." + a.name() + ".Enabled")) {
abilities.add(a.name());
airbendingabilities.add(a.name());
descriptions.put(a.name(), ProjectKorra.plugin.getConfig().getString("Abilities.Air." + a.name() + ".Description"));
if (a == StockAbility.AirScooter)
harmlessabilities.add(a.name());
if (a == StockAbility.AirSpout)
harmlessabilities.add(a.name());
if (a == StockAbility.Tornado)
shiftabilities.add(a.name());
if (a == StockAbility.AirSuction)
shiftabilities.add(a.name());
if (a == StockAbility.AirSwipe)
shiftabilities.add(a.name());
if (a == StockAbility.AirBlast)
shiftabilities.add(a.name());
if (a == StockAbility.AirBurst)
shiftabilities.add(a.name());
if (a == StockAbility.AirShield)
shiftabilities.add(a.name());
if (a == StockAbility.Flight)
shiftabilities.add(a.name());
// Air Sub Abilities
if (a == StockAbility.Flight)
subabilities.add(a.name());
if (a == StockAbility.Flight)
flightabilities.add(a.name());
}
} else if (StockAbility.isWaterbending(a)) {
if (ProjectKorra.plugin.getConfig().getBoolean("Abilities.Water." + a.name() + ".Enabled")) {
abilities.add(a.name());
waterbendingabilities.add(a.name());
descriptions.put(a.name(), ProjectKorra.plugin.getConfig().getString("Abilities.Water." + a.name() + ".Description"));
if (a == StockAbility.WaterSpout)
harmlessabilities.add(a.name());
if (a == StockAbility.HealingWaters)
harmlessabilities.add(a.name());
if (a == StockAbility.Surge)
shiftabilities.add(a.name());
if (a == StockAbility.Bloodbending)
shiftabilities.add(a.name());
if (a == StockAbility.PhaseChange)
shiftabilities.add(a.name());
if (a == StockAbility.HealingWaters)
shiftabilities.add(a.name());
if (a == StockAbility.OctopusForm)
shiftabilities.add(a.name());
if (a == StockAbility.Torrent)
shiftabilities.add(a.name());
if (a == StockAbility.WaterManipulation)
shiftabilities.add(a.name());
if (a == StockAbility.IceSpike)
shiftabilities.add(a.name());
if (a == StockAbility.IceBlast)
shiftabilities.add(a.name());
if (a == StockAbility.WaterArms)
shiftabilities.add(a.name());
// Water Sub Abilities
if (a == StockAbility.HealingWaters)
subabilities.add(a.name());
if (a == StockAbility.Bloodbending)
subabilities.add(a.name());
if (a == StockAbility.PhaseChange)
subabilities.add(a.name());
if (a == StockAbility.IceSpike)
subabilities.add(a.name());
if (a == StockAbility.IceBlast)
subabilities.add(a.name());
if (a == StockAbility.PlantArmor)
subabilities.add(a.name());
if (a == StockAbility.HealingWaters)
healingabilities.add(a.name());
if (a == StockAbility.Bloodbending)
bloodabilities.add(a.name());
if (a == StockAbility.PhaseChange)
iceabilities.add(a.name());
if (a == StockAbility.IceSpike)
iceabilities.add(a.name());
if (a == StockAbility.IceBlast)
iceabilities.add(a.name());
if (a == StockAbility.PlantArmor)
plantabilities.add(a.name());
}
} else if (StockAbility.isEarthbending(a)) {
if (ProjectKorra.plugin.getConfig().getBoolean("Abilities.Earth." + a.name() + ".Enabled")) {
abilities.add(a.name());
earthbendingabilities.add(a.name());
descriptions.put(a.name(), ProjectKorra.plugin.getConfig().getString("Abilities.Earth." + a.name() + ".Description"));
if (a == StockAbility.Tremorsense)
harmlessabilities.add(a.name());
if (a == StockAbility.RaiseEarth)
shiftabilities.add(a.name());
if (a == StockAbility.Collapse)
shiftabilities.add(a.name());
if (a == StockAbility.EarthBlast)
shiftabilities.add(a.name());
if (a == StockAbility.Shockwave)
shiftabilities.add(a.name());
if (a == StockAbility.EarthTunnel)
shiftabilities.add(a.name());
if (a == StockAbility.EarthGrab)
shiftabilities.add(a.name());
if (a == StockAbility.LavaFlow)
shiftabilities.add(a.name());
if (a == StockAbility.MetalClips)
shiftabilities.add(a.name());
if (a == StockAbility.EarthSmash)
shiftabilities.add(a.name());
if (a == StockAbility.SandSpout)
shiftabilities.add(a.name());
// Earth Sub Abilities
if (a == StockAbility.MetalClips)
subabilities.add(a.name());
if (a == StockAbility.Extraction)
subabilities.add(a.name());
if (a == StockAbility.LavaFlow)
subabilities.add(a.name());
if (a == StockAbility.SandSpout)
subabilities.add(a.name());
if (a == StockAbility.MetalClips)
metalabilities.add(a.name());
if (a == StockAbility.Extraction)
metalabilities.add(a.name());
if (a == StockAbility.LavaFlow)
lavaabilities.add(a.name());
if (a == StockAbility.SandSpout)
sandabilities.add(a.name());
// if (a == StockAbility.LavaSurge) earthsubabilities.add(a.name());
}
} else if (StockAbility.isFirebending(a)) {
if (ProjectKorra.plugin.getConfig().getBoolean("Abilities.Fire." + a.name() + ".Enabled")) {
abilities.add(a.name());
firebendingabilities.add(a.name());
descriptions.put(a.name(), ProjectKorra.plugin.getConfig().getString("Abilities.Fire." + a.name() + ".Description"));
if (a == StockAbility.Illumination)
harmlessabilities.add(a.name());
if (a == StockAbility.Blaze)
igniteabilities.add(a.name());
if (a == StockAbility.FireBlast)
explodeabilities.add(a.name());
if (a == StockAbility.Lightning)
explodeabilities.add(a.name());
if (a == StockAbility.Combustion)
explodeabilities.add(a.name());
if (a == StockAbility.HeatControl)
shiftabilities.add(a.name());
if (a == StockAbility.Lightning)
shiftabilities.add(a.name());
if (a == StockAbility.FireBlast)
shiftabilities.add(a.name());
if (a == StockAbility.Blaze)
shiftabilities.add(a.name());
if (a == StockAbility.FireBurst)
shiftabilities.add(a.name());
// Fire Sub Abilities
if (a == StockAbility.Lightning)
subabilities.add(a.name());
if (a == StockAbility.Combustion)
subabilities.add(a.name());
if (a == StockAbility.Lightning)
lightningabilities.add(a.name());
if (a == StockAbility.Combustion)
combustionabilities.add(a.name());
}
} else if (StockAbility.isChiBlocking(a)) {
if (ProjectKorra.plugin.getConfig().getBoolean("Abilities.Chi." + a.name() + ".Enabled")) {
abilities.add(a.name());
chiabilities.add(a.name());
descriptions.put(a.name(), ProjectKorra.plugin.getConfig().getString("Abilities.Chi." + a.name() + ".Description"));
if (a == StockAbility.HighJump)
harmlessabilities.add(a.name());
}
} else {
if (ProjectKorra.plugin.getConfig().getBoolean("Abilities." + a.name() + ".Enabled")) {
abilities.add(a.name()); // AvatarState, etc.
descriptions.put(a.name(), ProjectKorra.plugin.getConfig().getString("Abilities." + a.name() + ".Description"));
}
}
}
for (AbilityModule ab : ability) {
try {
//To check if EarthBlast == Earthblast or for example, EarthBlast == EARTHBLAST
boolean succes = true;
for (String enabledAbility : abilities) {
if (enabledAbility.equalsIgnoreCase(ab.getName())) {
succes = false;
}
}
if (!succes)
continue;
ab.onThisLoad();
abilities.add(ab.getName());
for (StockAbility a : StockAbility.values()) {
if (a.name().equalsIgnoreCase(ab.getName())) {
disabledStockAbilities.add(a.name());
}
}
if (ab.getElement() == Element.Air.toString())
airbendingabilities.add(ab.getName());
if (ab.getElement() == Element.Water.toString())
waterbendingabilities.add(ab.getName());
if (ab.getElement() == Element.Earth.toString())
earthbendingabilities.add(ab.getName());
if (ab.getElement() == Element.Fire.toString())
firebendingabilities.add(ab.getName());
if (ab.getElement() == Element.Chi.toString())
chiabilities.add(ab.getName());
if (ab.isShiftAbility())
shiftabilities.add(ab.getName());
if (ab.isHarmlessAbility())
harmlessabilities.add(ab.getName());
if (ab.getSubElement() != null) {
subabilities.add(ab.getName());
switch (ab.getSubElement()) {
case Bloodbending:
bloodabilities.add(ab.getName());
break;
case Combustion:
combustionabilities.add(ab.getName());
break;
case Flight:
flightabilities.add(ab.getName());
break;
case Healing:
healingabilities.add(ab.getName());
break;
case Icebending:
iceabilities.add(ab.getName());
break;
case Lavabending:
lavaabilities.add(ab.getName());
break;
case Lightning:
lightningabilities.add(ab.getName());
break;
case Metalbending:
metalabilities.add(ab.getName());
break;
case Plantbending:
plantabilities.add(ab.getName());
break;
case Sandbending:
sandabilities.add(ab.getName());
break;
case SpiritualProjection:
spiritualprojectionabilities.add(ab.getName());
break;
}
}
// if (ab.isMetalbendingAbility()) metalbendingabilities.add(ab.getName());
descriptions.put(ab.getName(), ab.getDescription());
authors.put(ab.getName(), ab.getAuthor());
}
catch (Exception | Error e) { //If triggered means ability was made before specific version .
ProjectKorra.log.warning("The ability " + ab.getName() + " was not able to load, if this message shows again please remove it!");
//ProjectKorra.log.warning("The ability " + ab.getName() + " is either broken or outdated. Please remove it!");
e.printStackTrace();
ab.stop();
abilities.remove(ab.getName());
final AbilityModule skill = ab;
//Bellow to avoid ConcurrentModificationException
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
public void run() {
ability.remove(skill);
}
}, 10);
continue;
}
}
Collections.sort(airbendingabilities);
Collections.sort(firebendingabilities);
Collections.sort(earthbendingabilities);
Collections.sort(waterbendingabilities);
Collections.sort(chiabilities);
Collections.sort(iceabilities);
Collections.sort(lavaabilities);
Collections.sort(bloodabilities);
Collections.sort(sandabilities);
Collections.sort(metalabilities);
Collections.sort(lightningabilities);
Collections.sort(combustionabilities);
Collections.sort(healingabilities);
Collections.sort(flightabilities);
Collections.sort(plantabilities);
Collections.sort(spiritualprojectionabilities);
}
public List<String> getAbilities(String element) {
element = element.toLowerCase();
if (Arrays.asList(Commands.wateraliases).contains(element))
return waterbendingabilities;
else if (Arrays.asList(Commands.icealiases).contains(element))
return iceabilities;
else if (Arrays.asList(Commands.plantaliases).contains(element))
return plantabilities;
else if (Arrays.asList(Commands.healingaliases).contains(element))
return healingabilities;
else if (Arrays.asList(Commands.bloodaliases).contains(element))
return bloodabilities;
else if (Arrays.asList(Commands.airaliases).contains(element))
return airbendingabilities;
else if (Arrays.asList(Commands.flightaliases).contains(element))
return flightabilities;
else if (Arrays.asList(Commands.spiritualprojectionaliases).contains(element))
return spiritualprojectionabilities;
else if (Arrays.asList(Commands.earthaliases).contains(element))
return earthbendingabilities;
else if (Arrays.asList(Commands.lavabendingaliases).contains(element))
return lavaabilities;
else if (Arrays.asList(Commands.metalbendingaliases).contains(element))
return metalabilities;
else if (Arrays.asList(Commands.sandbendingaliases).contains(element))
return sandabilities;
else if (Arrays.asList(Commands.firealiases).contains(element))
return firebendingabilities;
else if (Arrays.asList(Commands.combustionaliases).contains(element))
return combustionabilities;
else if (Arrays.asList(Commands.lightningaliases).contains(element))
return lightningabilities;
else if (Arrays.asList(Commands.chialiases).contains(element))
return chiabilities;
return null;
}
}

View file

@ -0,0 +1,25 @@
package com.projectkorra.projectkorra.ability;
public interface AddonAbility {
/**
* Called when the ability is loaded by PK. This is where the developer
* registers Listeners and Permissions.
*/
public void load();
/**
* Void Method called whenever ProjectKorra stops and the ability is
* unloaded.
*/
public void stop();
public String getAuthor();
/**
* Accessor Method to get the version of the ability.
*
* @return The version of the ability as a String.
*/
public String getVersion();
}

View file

@ -0,0 +1,147 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.airbending.AirSpout;
import com.projectkorra.projectkorra.airbending.Suffocate;
import com.projectkorra.projectkorra.util.ParticleEffect;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public abstract class AirAbility extends ElementalAbility {
public AirAbility(Player player) {
super(player);
}
@Override
public boolean isIgniteAbility() {
return false;
}
@Override
public boolean isExplosiveAbility() {
return false;
}
@Override
public Element getElement() {
return Element.AIR;
}
/**
* Breaks a breathbendng hold on an entity or one a player is inflicting on an entity.
*
* @param entity The entity to be acted upon
*/
public static void breakBreathbendingHold(Entity entity) {
if (Suffocate.isBreathbent(entity)) {
Suffocate.breakSuffocate(entity);
return;
}
if (entity instanceof Player) {
Player player = (Player) entity;
if (Suffocate.isChannelingSphere(player)) {
Suffocate.remove(player);
}
}
}
/**
* Gets the Air Particles from the config.
*
* @return Config specified ParticleEffect
*/
public static ParticleEffect getAirbendingParticles() {
String particle = getConfig().getString("Properties.Air.Particles");
if (particle == null) {
return ParticleEffect.CLOUD;
} else if (particle.equalsIgnoreCase("spell")) {
return ParticleEffect.SPELL;
} else if (particle.equalsIgnoreCase("blacksmoke")) {
return ParticleEffect.SMOKE;
} else if (particle.equalsIgnoreCase("smoke")) {
return ParticleEffect.CLOUD;
} else if (particle.equalsIgnoreCase("smallsmoke")) {
return ParticleEffect.SNOW_SHOVEL;
} else {
return ParticleEffect.CLOUD;
}
}
/**
* Checks whether a location is within an AirShield.
*
* @param loc The location to check
* @return true If the location is inside an AirShield.
*/
public static boolean isWithinAirShield(Location loc) {
List<String> list = new ArrayList<String>();
list.add("AirShield");
return GeneralMethods.blockAbilities(null, list, loc, 0);
}
/**
* Plays an integer amount of air particles in a location.
*
* @param loc The location to use
* @param amount The amount of particles
*/
public static void playAirbendingParticles(Location loc, int amount) {
playAirbendingParticles(loc, amount, (float) Math.random(), (float) Math.random(), (float) Math.random());
}
/**
* Plays an integer amount of air particles in a location with a given xOffset, yOffset, and
* zOffset.
*
* @param loc The location to use
* @param amount The amount of particles
* @param xOffset The xOffset to use
* @param yOffset The yOffset to use
* @param zOffset The zOffset to use
*/
public static void playAirbendingParticles(Location loc, int amount, float xOffset, float yOffset, float zOffset) {
getAirbendingParticles().display(loc, xOffset, yOffset, zOffset, 0, amount);
}
/**
* Plays the Airbending Sound at a location if enabled in the config.
*
* @param loc The location to play the sound at
*/
public static void playAirbendingSound(Location loc) {
if (getConfig().getBoolean("Properties.Air.PlaySound")) {
loc.getWorld().playSound(loc, Sound.CREEPER_HISS, 1, 5);
}
}
/**
* Removes all air spouts in a location within a certain radius.
*
* @param loc The location to use
* @param radius The radius around the location to remove spouts in
* @param source The player causing the removal
*/
public static void removeAirSpouts(Location loc, double radius, Player source) {
AirSpout.removeSpouts(loc, radius, source);
}
/**
* Removes all air spouts in a location with a radius of 1.5.
*
* @param loc The location to use
* @param source The player causing the removal
*/
public static void removeAirSpouts(Location loc, Player source) {
removeAirSpouts(loc, 1.5, source);
}
}

View file

@ -0,0 +1,34 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
public abstract class AvatarAbility extends ElementalAbility {
public AvatarAbility(Player player) {
super(player);
}
@Override
public boolean isIgniteAbility() {
return false;
}
@Override
public boolean isExplosiveAbility() {
return false;
}
@Override
public final Element getElement() {
return Element.AVATAR;
}
public static void playAvatarSound(Location loc) {
loc.getWorld().playSound(loc, Sound.ANVIL_LAND, 1, 10);
}
}

View file

@ -1,139 +0,0 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.util.Flight;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class AvatarState {
public static ConcurrentHashMap<Player, AvatarState> instances = new ConcurrentHashMap<Player, AvatarState>();
//public static Map<String, Long> cooldowns = new HashMap<String, Long>();
public static Map<String, Long> startTimes = new HashMap<String, Long>();
public static FileConfiguration config = ProjectKorra.plugin.getConfig();
private static final long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.AvatarState.Cooldown");
private static boolean regenEnabled = config.getBoolean("Abilities.AvatarState.PotionEffects.Regeneration.Enabled");
private static int regenPower = config.getInt("Abilities.AvatarState.PotionEffects.Regeneration.Power") - 1;
private static boolean speedEnabled = config.getBoolean("Abilities.AvatarState.PotionEffects.Speed.Enabled");
private static int speedPower = config.getInt("Abilities.AvatarState.PotionEffects.Speed.Power") - 1;
private static boolean resistanceEnabled = config.getBoolean("Abilities.AvatarState.PotionEffects.DamageResistance.Enabled");
private static int resistancePower = config.getInt("Abilities.AvatarState.PotionEffects.DamageResistance.Power") - 1;
private static boolean fireResistanceEnabled = config.getBoolean("Abilities.AvatarState.PotionEffects.FireResistance.Enabled");
private static int fireResistancePower = config.getInt("Abilities.AvatarState.PotionEffects.FireResistance.Power") - 1;
private static long duration = config.getLong("Abilities.AvatarState.Duration");
public static final double factor = config.getDouble("Abilities.AvatarState.PowerMultiplier");
Player player;
// boolean canfly = false;
public AvatarState(Player player) {
this.player = player;
if (instances.containsKey(player)) {
instances.remove(player);
return;
}
//if (cooldowns.containsKey(player.getName())) {
//if (cooldowns.get(player.getName()) + cooldown >= System.currentTimeMillis()) {
//return;
//} else {
//cooldowns.remove(player.getName());
//}
//}
if (GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("AvatarState")) {
return;
}
new Flight(player);
GeneralMethods.playAvatarSound(player.getLocation());
instances.put(player, this);
GeneralMethods.getBendingPlayer(player.getName()).addCooldown("AvatarState", cooldown);
if (duration != 0) {
startTimes.put(player.getName(), System.currentTimeMillis());
}
}
public static void manageAvatarStates() {
for (Player player : instances.keySet()) {
progress(player);
}
}
public static boolean progress(Player player) {
return instances.get(player).progress();
}
private boolean progress() {
if (player.isDead() || !player.isOnline()) {
instances.remove(player);
return false;
}
if (!GeneralMethods.canBend(player.getName(), StockAbility.AvatarState.name())) {
instances.remove(player);
if (player != null) {
if (GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("AvatarState")) {
GeneralMethods.getBendingPlayer(player.getName()).removeCooldown("AvatarState");
}
return false;
}
}
if (startTimes.containsKey(player.getName())) {
if (startTimes.get(player.getName()) + duration < System.currentTimeMillis()) {
startTimes.remove(player.getName());
instances.remove(player);
}
}
addPotionEffects();
return true;
}
private void addPotionEffects() {
int duration = 70;
if (regenEnabled) {
player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, duration, regenPower));
}
if (speedEnabled) {
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, duration, speedPower));
}
if (resistanceEnabled) {
player.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, duration, resistancePower));
}
if (fireResistanceEnabled) {
player.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, duration, fireResistancePower));
}
}
public static boolean isAvatarState(Player player) {
if (instances.containsKey(player))
return true;
return false;
}
public static double getValue(double value) {
return factor * value;
}
public static int getValue(int value) {
return (int) factor * value;
}
public static ArrayList<Player> getPlayers() {
ArrayList<Player> players = new ArrayList<Player>();
for (Player player : instances.keySet()) {
players.add(player);
}
return players;
}
}

View file

@ -0,0 +1,11 @@
package com.projectkorra.projectkorra.ability;
import org.bukkit.entity.Player;
public abstract class BlockAbility extends ElementalAbility {
public BlockAbility(Player player) {
super(player);
}
}

View file

@ -0,0 +1,27 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import org.bukkit.entity.Player;
public abstract class BloodAbility extends WaterAbility implements SubAbility {
public BloodAbility(Player player) {
super(player);
}
@Override
public Class<? extends Ability> getParentAbility() {
return WaterAbility.class;
}
@Override
public Element getElement() {
return Element.BLOOD;
}
@Override
public Element getParentElement() {
return Element.WATER;
}
}

View file

@ -0,0 +1,28 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import org.bukkit.entity.Player;
public abstract class ChiAbility extends ElementalAbility {
public ChiAbility(Player player) {
super(player);
}
@Override
public boolean isIgniteAbility() {
return false;
}
@Override
public boolean isExplosiveAbility() {
return false;
}
@Override
public Element getElement() {
return Element.CHI;
}
}

View file

@ -0,0 +1,35 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
import org.bukkit.entity.Player;
import java.util.ArrayList;
public interface ComboAbility {
/**
* Accessor Method to get the instructions for using this combo.
*
* @return The steps for the combo.
*/
public abstract String getInstructions();
/**
* Creates a new instance of the combo from a specific player.
* ProjectKorra's ComboModuleManager will use this method once the combo
* steps have been used by the player.
*
* @return A new instance of the ability.
* @param player The player using the combo.
*/
public abstract Object createNewComboInstance(Player player);
/**
* Returns the list of abilities which constitute the combo.
*
* @return An ArrayList containing the combo's steps.
*/
public abstract ArrayList<AbilityInformation> getCombination();
}

View file

@ -1,19 +1,27 @@
package com.projectkorra.projectkorra.ability.api;
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import org.bukkit.entity.Player;
public abstract class CombustionAbility extends FireAbility implements SubAbility {
public CombustionAbility(Player player, boolean autoStart) {
super(player, autoStart);
}
public CombustionAbility(Player player) {
super(player);
}
@Override
public Class<? extends Ability> getParentAbility() {
return FireAbility.class;
}
@Override
public Element getElement() {
return Element.COMBUSTION;
}
@Override
public Element getParentElement() {
return Element.FIRE;
}
}

View file

@ -0,0 +1,386 @@
package com.projectkorra.projectkorra.ability;
import sun.reflect.ReflectionFactory;
import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.util.AbilityLoader;
import com.projectkorra.projectkorra.ability.util.ComboManager;
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager;
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager.MultiAbilityInfo;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
public abstract class CoreAbility implements Ability {
private static final ConcurrentHashMap<Class<? extends CoreAbility>, ConcurrentHashMap<UUID, ConcurrentHashMap<Integer, CoreAbility>>> INSTANCES = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<Class<? extends CoreAbility>, Set<CoreAbility>> INSTANCES_BY_CLASS = new ConcurrentHashMap<>();
private static final ConcurrentSkipListMap<String, CoreAbility> ABILITIES_BY_NAME = new ConcurrentSkipListMap<>();
private static int idCounter;
protected long startTime;
protected Player player;
protected BendingPlayer bPlayer;
private boolean started;
private boolean removed;
private int id;
static {
idCounter = Integer.MIN_VALUE;
}
public CoreAbility() {
// Need the default constructor for reflection purposes
}
public CoreAbility(Player player) {
if (player == null) {
return;
}
this.player = player;
this.bPlayer = BendingPlayer.getBendingPlayer(player);
this.startTime = System.currentTimeMillis();
this.started = false;
this.id = CoreAbility.idCounter;
if (idCounter == Integer.MAX_VALUE) {
idCounter = Integer.MIN_VALUE;
} else {
idCounter++;
}
}
public void start() {
if (player == null) {
return;
}
this.started = true;
this.startTime = System.currentTimeMillis();
Class<? extends CoreAbility> clazz = getClass();
UUID uuid = player.getUniqueId();
if (!INSTANCES.containsKey(clazz)) {
INSTANCES.put(clazz, new ConcurrentHashMap<UUID, ConcurrentHashMap<Integer, CoreAbility>>());
}
if (!INSTANCES.get(clazz).containsKey(uuid)) {
INSTANCES.get(clazz).put(uuid, new ConcurrentHashMap<Integer, CoreAbility>());
}
if (!INSTANCES_BY_CLASS.containsKey(clazz)) {
INSTANCES_BY_CLASS.put(clazz, Collections.newSetFromMap(new ConcurrentHashMap<CoreAbility, Boolean>()));
}
INSTANCES.get(clazz).get(uuid).put(this.id, this);
INSTANCES_BY_CLASS.get(clazz).add(this);
}
@Override
public void remove() {
if (player == null) {
return;
}
removed = true;
ConcurrentHashMap<UUID, ConcurrentHashMap<Integer, CoreAbility>> classMap = INSTANCES.get(getClass());
if (classMap != null) {
ConcurrentHashMap<Integer, CoreAbility> playerMap = classMap.get(player.getUniqueId());
if (playerMap != null) {
playerMap.remove(this.id);
if (playerMap.size() == 0) {
classMap.remove(player.getUniqueId());
}
}
if (classMap.size() == 0) {
INSTANCES.remove(getClass());
}
}
if (INSTANCES_BY_CLASS.containsKey(getClass())) {
INSTANCES_BY_CLASS.get(getClass()).remove(this);
}
}
public static void progressAll() {
for (Set<CoreAbility> setAbils : INSTANCES_BY_CLASS.values()) {
for (CoreAbility abil : setAbils) {
abil.progress();
}
}
}
public static void removeAll() {
for (Set<CoreAbility> setAbils : INSTANCES_BY_CLASS.values()) {
for (CoreAbility abil : setAbils) {
abil.remove();
}
}
}
public static void removeAll(Class<? extends CoreAbility> clazz) {
for (CoreAbility abil : getAbilities(clazz)) {
abil.remove();
}
}
public static <T extends CoreAbility> T getAbility(Player player, Class<T> clazz) {
Collection<T> abils = getAbilities(player, clazz);
if (abils.iterator().hasNext()) {
return abils.iterator().next();
}
return null;
}
public static CoreAbility getAbility(String abilityName) {
return abilityName != null ? ABILITIES_BY_NAME.get(abilityName.toLowerCase()) : null;
}
public static ArrayList<CoreAbility> getAbilities() {
return new ArrayList<CoreAbility>(ABILITIES_BY_NAME.values());
}
@SuppressWarnings("unchecked")
public static <T extends CoreAbility> Collection<T> getAbilities(Class<T> clazz) {
if (clazz == null || INSTANCES_BY_CLASS.get(clazz) == null || INSTANCES_BY_CLASS.get(clazz).size() == 0) {
return Collections.emptySet();
}
return (Collection<T>) CoreAbility.INSTANCES_BY_CLASS.get(clazz);
}
@SuppressWarnings("unchecked")
public static <T extends CoreAbility> Collection<T> getAbilities(Player player, Class<T> clazz) {
if (player == null || clazz == null || INSTANCES.get(clazz) == null || INSTANCES.get(clazz).get(player.getUniqueId()) == null) {
return Collections.emptySet();
}
return (Collection<T>) INSTANCES.get(clazz).get(player.getUniqueId()).values();
}
public static ArrayList<CoreAbility> getAbilitiesByElement(Element element) {
ArrayList<CoreAbility> abilities = new ArrayList<CoreAbility>();
if (element != null) {
for (CoreAbility ability : getAbilities()) {
if (ability.getElement() == element) {
abilities.add(ability);
} else if (ability instanceof SubAbility) {
SubAbility subAbil = (SubAbility) ability;
if (subAbil.getParentElement() == element) {
abilities.add(ability);
}
}
}
}
return abilities;
}
public static <T extends CoreAbility> boolean hasAbility(Player player, Class<T> clazz) {
return getAbility(player, clazz) != null;
}
public static HashSet<Player> getPlayers(Class<? extends CoreAbility> clazz) {
HashSet<Player> players = new HashSet<>();
if (clazz != null) {
ConcurrentHashMap<UUID, ConcurrentHashMap<Integer, CoreAbility>> uuidMap = INSTANCES.get(clazz);
if (uuidMap != null) {
for (UUID uuid : uuidMap.keySet()) {
Player uuidPlayer = Bukkit.getPlayer(uuid);
if (uuidPlayer != null) {
players.add(uuidPlayer);
}
}
}
}
return players;
}
public static void registerAbilities() {
ABILITIES_BY_NAME.clear();
registerPluginAbilities(ProjectKorra.plugin, "com.projectkorra");
registerAddonAbilities("/Abilities/");
}
public static void registerPluginAbilities(JavaPlugin plugin, String packagePrefix) {
if (plugin == null) {
return;
}
Class<?> pluginClass = plugin.getClass();
ClassLoader loader = pluginClass.getClassLoader();
ReflectionFactory rf = ReflectionFactory.getReflectionFactory();
try {
for (final ClassInfo info : ClassPath.from(loader).getAllClasses()) {
if (!info.getPackageName().startsWith(packagePrefix)) {
continue;
}
Class<?> clazz = null;
try {
clazz = info.load();
if (!CoreAbility.class.isAssignableFrom(clazz) || clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) {
continue;
}
Constructor<?> objDef = CoreAbility.class.getDeclaredConstructor();
Constructor<?> intConstr = rf.newConstructorForSerialization(clazz, objDef);;
CoreAbility ability = (CoreAbility) clazz.cast(intConstr.newInstance());
if (ability != null && ability.getName() != null) {
ABILITIES_BY_NAME.put(ability.getName().toLowerCase(), ability);
}
} catch (Exception e) {
} catch (Error e) {
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void registerAddonAbilities(String folder) {
ProjectKorra plugin = ProjectKorra.plugin;
File path = new File(plugin.getDataFolder().toString() + folder);
AbilityLoader<CoreAbility> abilityLoader = new AbilityLoader<CoreAbility>(plugin, path);
List<CoreAbility> loadedAbilities = abilityLoader.load(CoreAbility.class, CoreAbility.class);
for (CoreAbility coreAbil : loadedAbilities) {
if (!(coreAbil instanceof AddonAbility)) {
plugin.getLogger().warning(coreAbil.getName() + " is an addon ability and must implement the AddonAbility interface");
continue;
}
AddonAbility addon = (AddonAbility) coreAbil;
String name = coreAbil.getName();
try {
addon.load();
ABILITIES_BY_NAME.put(name.toLowerCase(), coreAbil);
if (coreAbil instanceof ComboAbility) {
ComboAbility combo = (ComboAbility) coreAbil;
if (combo.getCombination() != null) {
ComboManager.getComboAbilities().put(name, new ComboManager.ComboAbilityInfo(name, combo.getCombination(), combo));
ComboManager.getDescriptions().put(name, coreAbil.getDescription());
ComboManager.getInstructions().put(name, combo.getInstructions());
ComboManager.getAuthors().put(name, addon.getAuthor());
}
}
if (coreAbil instanceof MultiAbility) {
MultiAbility multiAbil = (MultiAbility) coreAbil;
MultiAbilityManager.multiAbilityList.add(new MultiAbilityInfo(name, multiAbil.getMultiAbilities()));
}
} catch (Exception | Error e) {
plugin.getLogger().warning("The ability " + coreAbil.getName() + " was not able to load, if this message shows again please remove it!");
e.printStackTrace();
addon.stop();
ABILITIES_BY_NAME.remove(coreAbil.getName(), coreAbil);
}
}
}
public long getStartTime() {
return startTime;
}
public boolean isStarted() {
return started;
}
public boolean isRemoved() {
return removed;
}
public BendingPlayer getBendingPlayer() {
return bPlayer;
}
public int getId() {
return id;
}
public boolean isHiddenAbility() {
return false;
}
@Override
public String getDescription() {
if (this instanceof SubAbility) {
return getConfig().getString("Abilities." + ((SubAbility) this).getParentElement().getName() + "." + getName() + ".Description");
}
return getConfig().getString("Abilities." + getElement().getName() + "." + getName() + ".Description");
}
@Override
public Player getPlayer() {
return player;
}
public static FileConfiguration getConfig() {
return ConfigManager.getConfig();
}
public static String getDebugString() {
StringBuilder sb = new StringBuilder();
int playerCounter = 0;
HashMap<String, Integer> classCounter = new HashMap<>();
for (ConcurrentHashMap<UUID, ConcurrentHashMap<Integer, CoreAbility>> map1 : INSTANCES.values()) {
playerCounter++;
for (ConcurrentHashMap<Integer, CoreAbility> map2 : map1.values()) {
for (CoreAbility coreAbil : map2.values()) {
String simpleName = coreAbil.getClass().getSimpleName();
if (classCounter.containsKey(simpleName)) {
classCounter.put(simpleName, classCounter.get(simpleName) + 1);
} else {
classCounter.put(simpleName, 1);
}
}
}
}
for (Set<CoreAbility> set : INSTANCES_BY_CLASS.values()) {
for (CoreAbility coreAbil : set) {
String simpleName = coreAbil.getClass().getSimpleName();
if (classCounter.containsKey(simpleName)) {
classCounter.put(simpleName, classCounter.get(simpleName) + 1);
} else {
classCounter.put(simpleName, 1);
}
}
}
sb.append("Class->UUID's in memory: " + playerCounter + "\n");
sb.append("Abilities in memory\n");
for (String className : classCounter.keySet()) {
sb.append(className + ": " + classCounter.get(className));
}
return sb.toString();
}
}

View file

@ -0,0 +1,595 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.earthbending.EarthPassive;
import com.projectkorra.projectkorra.earthbending.LavaFlow;
import com.projectkorra.projectkorra.earthbending.RaiseEarth;
import com.projectkorra.projectkorra.util.BlockSource;
import com.projectkorra.projectkorra.util.Information;
import com.projectkorra.projectkorra.util.ParticleEffect;
import com.projectkorra.projectkorra.util.TempBlock;
import org.bukkit.ChatColor;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
public abstract class EarthAbility extends BlockAbility {
private static final HashSet<Block> PREVENT_EARTHBENDING = new HashSet<Block>();
private static final ConcurrentHashMap<Block, Information> MOVED_EARTH = new ConcurrentHashMap<Block, Information>();
private static final ConcurrentHashMap<Integer, Information> TEMP_AIR_LOCATIONS = new ConcurrentHashMap<Integer, Information>();
private static final ArrayList<Block> PREVENT_PHYSICS = new ArrayList<Block>();
private static final ItemStack DIAMOND_PICKAXE = new ItemStack(Material.DIAMOND_PICKAXE);
public EarthAbility(Player player) {
super(player);
}
public int getEarthbendableBlocksLength(Block block, Vector direction, int maxlength) {
Location location = block.getLocation();
direction = direction.normalize();
for (int i = 0; i <= maxlength; i++) {
double j = i;
if (!isEarthbendable(location.clone().add(direction.clone().multiply(j)).getBlock())) {
return i;
}
}
return maxlength;
}
public Block getEarthSourceBlock(double range) {
return getEarthSourceBlock(player, getName(), range);
}
@Override
public Element getElement() {
return Element.EARTH;
}
public Block getLavaSourceBlock(double range) {
return getLavaSourceBlock(player, getName(), range);
}
public Block getTargetEarthBlock(int range) {
return getTargetEarthBlock(player, range);
}
public boolean isEarthbendable(Block block) {
return isEarthbendable(player, getName(), block);
}
@Override
public boolean isExplosiveAbility() {
return false;
}
@Override
public boolean isIgniteAbility() {
return false;
}
public boolean isMetalbendable(Block block) {
return isMetalbendable(block.getType());
}
public boolean isMetalbendable(Material material) {
return isMetalbendable(player, material);
}
public void moveEarth(Block block, Vector direction, int chainlength) {
moveEarth(block, direction, chainlength, true);
}
public boolean moveEarth(Block block, Vector direction, int chainlength, boolean throwplayer) {
if (isEarthbendable(block) && !GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) {
boolean up = false;
boolean down = false;
Vector norm = direction.clone().normalize();
if (norm.dot(new Vector(0, 1, 0)) == 1) {
up = true;
} else if (norm.dot(new Vector(0, -1, 0)) == 1) {
down = true;
}
Vector negnorm = norm.clone().multiply(-1);
Location location = block.getLocation();
ArrayList<Block> blocks = new ArrayList<Block>();
for (double j = -2; j <= chainlength; j++) {
Block checkblock = location.clone().add(negnorm.clone().multiply(j)).getBlock();
if (!PREVENT_PHYSICS.contains(checkblock)) {
blocks.add(checkblock);
PREVENT_PHYSICS.add(checkblock);
}
}
Block affectedblock = location.clone().add(norm).getBlock();
if (EarthPassive.isPassiveSand(block)) {
EarthPassive.revertSand(block);
}
if (affectedblock == null) {
return false;
} else if (isTransparent(affectedblock)) {
if (throwplayer) {
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(affectedblock.getLocation(), 1.75)) {
if (entity instanceof LivingEntity) {
LivingEntity lentity = (LivingEntity) entity;
if (lentity.getEyeLocation().getBlockX() == affectedblock.getX()
&& lentity.getEyeLocation().getBlockZ() == affectedblock.getZ()) {
if (!(entity instanceof FallingBlock)) {
entity.setVelocity(norm.clone().multiply(.75));
}
}
} else {
if (entity.getLocation().getBlockX() == affectedblock.getX()
&& entity.getLocation().getBlockZ() == affectedblock.getZ()) {
if (!(entity instanceof FallingBlock)) {
entity.setVelocity(norm.clone().multiply(.75));
}
}
}
}
}
if (up) {
Block topblock = affectedblock.getRelative(BlockFace.UP);
if (topblock.getType() != Material.AIR) {
GeneralMethods.breakBlock(affectedblock);
} else if (!affectedblock.isLiquid() && affectedblock.getType() != Material.AIR) {
moveEarthBlock(affectedblock, topblock);
}
} else {
GeneralMethods.breakBlock(affectedblock);
}
moveEarthBlock(block, affectedblock);
playEarthbendingSound(block.getLocation());
for (double i = 1; i < chainlength; i++) {
affectedblock = location.clone().add(negnorm.getX() * i, negnorm.getY() * i, negnorm.getZ() * i).getBlock();
if (!isEarthbendable(affectedblock)) {
if (down) {
if (isTransparent(affectedblock) && !affectedblock.isLiquid()
&& affectedblock.getType() != Material.AIR) {
moveEarthBlock(affectedblock, block);
}
}
break;
}
if (EarthPassive.isPassiveSand(affectedblock)) {
EarthPassive.revertSand(affectedblock);
}
if (block == null) {
for (Block checkblock : blocks) {
PREVENT_PHYSICS.remove(checkblock);
}
return false;
}
moveEarthBlock(affectedblock, block);
block = affectedblock;
}
int i = chainlength;
affectedblock = location.clone().add(negnorm.getX() * i, negnorm.getY() * i, negnorm.getZ() * i).getBlock();
if (!isEarthbendable(affectedblock)) {
if (down) {
if (isTransparent(affectedblock) && !affectedblock.isLiquid()) {
moveEarthBlock(affectedblock, block);
}
}
}
} else {
for (Block checkblock : blocks) {
PREVENT_PHYSICS.remove(checkblock);
}
return false;
}
for (Block checkblock : blocks) {
PREVENT_PHYSICS.remove(checkblock);
}
return true;
}
return false;
}
public void moveEarth(Location location, Vector direction, int chainlength) {
moveEarth(location, direction, chainlength, true);
}
public void moveEarth(Location location, Vector direction, int chainlength, boolean throwplayer) {
moveEarth(location.getBlock(), direction, chainlength, throwplayer);
}
/**
* Creates a temporary air block.
*
* @param block The block to use as a base
*/
public static void addTempAirBlock(Block block) {
Information info;
if (MOVED_EARTH.containsKey(block)) {
info = MOVED_EARTH.get(block);
MOVED_EARTH.remove(block);
} else {
info = new Information();
info.setBlock(block);
info.setState(block.getState());
}
block.setType(Material.AIR);
info.setTime(System.currentTimeMillis());
TEMP_AIR_LOCATIONS.put(info.getID(), info);
}
public static void displaySandParticle(Location loc, float xOffset, float yOffset, float zOffset, float amount, float speed, boolean red) {
if (amount <= 0)
return;
for (int x = 0; x < amount; x++) {
if (!red) {
ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.SAND, (byte) 0), new Vector(((Math.random() - 0.5) * xOffset), ((Math.random() - 0.5) * yOffset), ((Math.random() - 0.5) * zOffset)), speed, loc, 257.0D);
ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.SANDSTONE, (byte) 0), new Vector(((Math.random() - 0.5) * xOffset), ((Math.random() - 0.5) * yOffset), ((Math.random() - 0.5) * zOffset)), speed, loc, 257.0D);
} else if (red) {
ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.SAND, (byte) 1), new Vector(((Math.random() - 0.5) * xOffset), ((Math.random() - 0.5) * yOffset), ((Math.random() - 0.5) * zOffset)), speed, loc, 257.0D);
ParticleEffect.ITEM_CRACK.display(new ParticleEffect.ItemData(Material.RED_SANDSTONE, (byte) 0), new Vector(((Math.random() - 0.5) * xOffset), ((Math.random() - 0.5) * yOffset), ((Math.random() - 0.5) * zOffset)), speed, loc, 257.0D);
}
}
}
/**
* Finds a valid Earth source for a Player. To use dynamic source selection, use
* BlockSource.getEarthSourceBlock() instead of this method. Dynamic source selection saves the
* user's previous source for future use.
* {@link BlockSource#getEarthSourceBlock(Player, double, com.projectkorra.projectkorra.util.ClickType)}
*
* @param range the maximum block selection range.
* @return a valid Earth source block, or null if one could not be found.
*/
@SuppressWarnings("deprecation")
public static Block getEarthSourceBlock(Player player, String abilityName, double range) {
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
Block testblock = player.getTargetBlock(getTransparentMaterialSet(), (int) range);
if (bPlayer == null) {
return null;
} else if (isEarthbendable(player, testblock) || isMetalbendable(player, testblock.getType())) {
return testblock;
}
Location location = player.getEyeLocation();
Vector vector = location.getDirection().clone().normalize();
for (double i = 0; i <= range; i++) {
Block block = location.clone().add(vector.clone().multiply(i)).getBlock();
if (GeneralMethods.isRegionProtectedFromBuild(player, abilityName, location)) {
continue;
} else if (isEarthbendable(player, block)) {
return block;
}
}
return null;
}
public static Block getLavaSourceBlock(Player player, double range) {
return getLavaSourceBlock(player, null, range);
}
/**
* Finds a valid Lava source for a Player. To use dynamic source selection, use
* BlockSource.getLavaSourceBlock() instead of this method. Dynamic source selection saves the
* user's previous source for future use.
* {@link BlockSource#getLavaSourceBlock(Player, double, com.projectkorra.projectkorra.util.ClickType)}
*
* @param range the maximum block selection range.
* @return a valid Lava source block, or null if one could not be found.
*/
@SuppressWarnings("deprecation")
public static Block getLavaSourceBlock(Player player, String abilityName, double range) {
Location location = player.getEyeLocation();
Vector vector = location.getDirection().clone().normalize();
for (double i = 0; i <= range; i++) {
Block block = location.clone().add(vector.clone().multiply(i)).getBlock();
if (GeneralMethods.isRegionProtectedFromBuild(player, abilityName, location)) {
continue;
}
if (isLavabendable(block)) {
if (TempBlock.isTempBlock(block)) {
TempBlock tb = TempBlock.get(block);
byte full = 0x0;
if (tb.getState().getRawData() != full && !isLava(tb.getState().getType())) {
continue;
}
}
return block;
}
}
return null;
}
public static double getMetalAugment(double value) {
return value * getConfig().getDouble("Properties.Earth.MetalPowerFactor");
}
public static ConcurrentHashMap<Block, Information> getMovedEarth() {
return MOVED_EARTH;
}
/**
* Attempts to find the closest earth block near a given location.
*
* @param loc the initial location to search from.
* @param radius the maximum radius to search for the earth block.
* @param maxVertical the maximum block height difference between the starting location and the
* earth bendable block.
* @return an earth bendable block, or null.
*/
public static Block getNearbyEarthBlock(Location loc, double radius, int maxVertical) {
if (loc == null) {
return null;
}
int rotation = 30;
for (int i = 0; i < radius; i++) {
Vector tracer = new Vector(i, 0, 0);
for (int deg = 0; deg < 360; deg += rotation) {
Location searchLoc = loc.clone().add(tracer);
Block block = GeneralMethods.getTopBlock(searchLoc, maxVertical);
if (block != null && isEarthbendable(block.getType())) {
return block;
}
tracer = GeneralMethods.rotateXZ(tracer, rotation);
}
}
return null;
}
public static HashSet<Block> getPreventEarthbendingBlocks() {
return PREVENT_EARTHBENDING;
}
public static ArrayList<Block> getPreventPhysicsBlocks() {
return PREVENT_PHYSICS;
}
public static ChatColor getSubChatColor() {
return ChatColor.valueOf(ConfigManager.getConfig().getString("Properties.Chat.Colors.EarthSub"));
}
@SuppressWarnings("deprecation")
public static Block getTargetEarthBlock(Player player, int range) {
return player.getTargetBlock(getTransparentMaterialSet(), range);
}
public static ConcurrentHashMap<Integer, Information> getTempAirLocations() {
return TEMP_AIR_LOCATIONS;
}
public static boolean isEarthbendable(Material material) {
return getConfig().getStringList("Properties.Earth.EarthbendableBlocks").contains(material.toString());
}
public static boolean isEarthbendable(Player player, Block block) {
return isEarthbendable(player, null, block);
}
public static boolean isEarthbendable(Player player, String abilityName, Block block) {
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null || !isEarthbendable(block.getType()) || PREVENT_EARTHBENDING.contains(block)
|| GeneralMethods.isRegionProtectedFromBuild(player, abilityName, block.getLocation())) {
return false;
} else if (isMetal(block) && !bPlayer.canMetalbend()) {
return false;
}
return true;
}
public static boolean isEarthRevertOn() {
return getConfig().getBoolean("Properties.Earth.RevertEarthbending");
}
@SuppressWarnings("deprecation")
public static boolean isLavabendable(Block block) {
byte full = 0x0;
if (TempBlock.isTempBlock(block)) {
TempBlock tblock = TempBlock.instances.get(block);
if (tblock == null || !LavaFlow.getTempLavaBlocks().contains(tblock)) {
return false;
}
}
if (isLava(block) && block.getData() == full) {
return true;
}
return false;
}
public static boolean isMetalbendable(Player player, Material material) {
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
return bPlayer == null ? null : isMetal(material) && bPlayer.canMetalbend();
}
@SuppressWarnings("deprecation")
public static void moveEarthBlock(Block source, Block target) {
byte full = 0x0;
Information info;
if (MOVED_EARTH.containsKey(source)) {
info = MOVED_EARTH.get(source);
MOVED_EARTH.remove(source);
} else {
info = new Information();
info.setBlock(source);
info.setTime(System.currentTimeMillis());
info.setState(source.getState());
}
info.setTime(System.currentTimeMillis());
MOVED_EARTH.put(target, info);
if (GeneralMethods.isAdjacentToThreeOrMoreSources(source)) {
source.setType(Material.WATER);
source.setData(full);
} else {
source.setType(Material.AIR);
}
if (info.getState().getType() == Material.SAND) {
if (info.getState().getRawData() == (byte) 0x1) {
target.setType(Material.RED_SANDSTONE);
} else {
target.setType(Material.SANDSTONE);
}
} else {
target.setType(info.getState().getType());
target.setData(info.getState().getRawData());
}
}
public static void playEarthbendingSound(Location loc) {
if (getConfig().getBoolean("Properties.Earth.PlaySound")) {
loc.getWorld().playEffect(loc, Effect.GHAST_SHOOT, 0, 10);
}
}
public static void playMetalbendingSound(Location loc) {
if (getConfig().getBoolean("Properties.Earth.PlaySound")) {
loc.getWorld().playSound(loc, Sound.IRONGOLEM_HIT, 1, 10);
}
}
public static void playSandBendingSound(Location loc) {
if (getConfig().getBoolean("Properties.Earth.PlaySound")) {
loc.getWorld().playSound(loc, Sound.DIG_SAND, 1.5f, 5);
}
}
public static void removeAllEarthbendedBlocks() {
for (Block block : MOVED_EARTH.keySet()) {
revertBlock(block);
}
for (Integer i : TEMP_AIR_LOCATIONS.keySet()) {
revertAirBlock(i, true);
}
}
public static void removeRevertIndex(Block block) {
if (MOVED_EARTH.containsKey(block)) {
Information info = MOVED_EARTH.get(block);
if (block.getType() == Material.SANDSTONE && info.getType() == Material.SAND) {
block.setType(Material.SAND);
}
if (RaiseEarth.blockInAllAffectedBlocks(block)) {
EarthAbility.revertBlock(block);
}
MOVED_EARTH.remove(block);
}
}
public static void revertAirBlock(int i) {
revertAirBlock(i, false);
}
public static void revertAirBlock(int i, boolean force) {
if (!TEMP_AIR_LOCATIONS.containsKey(i)) {
return;
}
Information info = TEMP_AIR_LOCATIONS.get(i);
Block block = info.getState().getBlock();
if (block.getType() != Material.AIR && !block.isLiquid()) {
if (force || !MOVED_EARTH.containsKey(block)) {
TEMP_AIR_LOCATIONS.remove(i);
} else {
info.setTime(info.getTime() + 10000);
}
return;
} else {
info.getState().update(true);
TEMP_AIR_LOCATIONS.remove(i);
}
}
@SuppressWarnings("deprecation")
public static boolean revertBlock(Block block) {
byte full = 0x0;
if (!isEarthRevertOn()) {
MOVED_EARTH.remove(block);
return false;
}
if (MOVED_EARTH.containsKey(block)) {
Information info = MOVED_EARTH.get(block);
Block sourceblock = info.getState().getBlock();
if (info.getState().getType() == Material.AIR) {
MOVED_EARTH.remove(block);
return true;
}
if (block.equals(sourceblock)) {
info.getState().update(true);
if (RaiseEarth.blockInAllAffectedBlocks(sourceblock)) {
EarthAbility.revertBlock(sourceblock);
}
if (RaiseEarth.blockInAllAffectedBlocks(block)) {
EarthAbility.revertBlock(block);
}
MOVED_EARTH.remove(block);
return true;
}
if (MOVED_EARTH.containsKey(sourceblock)) {
addTempAirBlock(block);
MOVED_EARTH.remove(block);
return true;
}
if (sourceblock.getType() == Material.AIR || sourceblock.isLiquid()) {
info.getState().update(true);
} else {
GeneralMethods.dropItems(block,
GeneralMethods.getDrops(block, info.getState().getType(), info.getState().getRawData(), DIAMOND_PICKAXE));
}
if (GeneralMethods.isAdjacentToThreeOrMoreSources(block)) {
block.setType(Material.WATER);
block.setData(full);
} else {
block.setType(Material.AIR);
}
if (RaiseEarth.blockInAllAffectedBlocks(sourceblock)) {
EarthAbility.revertBlock(sourceblock);
}
if (RaiseEarth.blockInAllAffectedBlocks(block)) {
EarthAbility.revertBlock(block);
}
MOVED_EARTH.remove(block);
}
return true;
}
public static void stopBending() {
EarthPassive.removeAll();
if (isEarthRevertOn()) {
removeAllEarthbendedBlocks();
}
}
}

View file

@ -0,0 +1,205 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.rpg.event.EventManager;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffectType;
import java.util.Arrays;
import java.util.HashSet;
// Contains methods that all 5 elements should be capable of accessing
public abstract class ElementalAbility extends CoreAbility {
private static final Integer[] TRANSPARENT_MATERIAL = { 0, 6, 8, 9, 10, 11, 30, 31, 32, 37, 38, 39, 40, 50, 51, 59, 78, 83, 106, 175 };
private static final Integer[] PLANT_IDS = { 6, 18, 31, 37, 38, 39, 40, 59, 81, 83, 86, 99, 100, 103, 104, 105, 106, 111, 161, 175 };
private static final PotionEffectType[] POSITIVE_EFFECTS = {PotionEffectType.ABSORPTION, PotionEffectType.DAMAGE_RESISTANCE, PotionEffectType.FAST_DIGGING,
PotionEffectType.FIRE_RESISTANCE, PotionEffectType.HEAL, PotionEffectType.HEALTH_BOOST, PotionEffectType.INCREASE_DAMAGE, PotionEffectType.JUMP,
PotionEffectType.NIGHT_VISION, PotionEffectType.REGENERATION, PotionEffectType.SATURATION, PotionEffectType.SPEED, PotionEffectType.WATER_BREATHING};
private static final PotionEffectType[] NEUTRAL_EFFECTS = {PotionEffectType.INVISIBILITY};
private static final PotionEffectType[] NEGATIVE_EFFECTS = {PotionEffectType.POISON, PotionEffectType.BLINDNESS, PotionEffectType.CONFUSION,
PotionEffectType.HARM, PotionEffectType.HUNGER, PotionEffectType.SLOW, PotionEffectType.SLOW_DIGGING, PotionEffectType.WEAKNESS, PotionEffectType.WITHER};
public ElementalAbility(Player player) {
super(player);
}
public boolean isTransparent(Block block) {
return isTransparent(player, getName(), block);
}
public static Integer[] getTransparentMaterial() {
return TRANSPARENT_MATERIAL;
}
public static HashSet<Byte> getTransparentMaterialSet() {
HashSet<Byte> set = new HashSet<Byte>();
for (int i : TRANSPARENT_MATERIAL) {
set.add((byte) i);
}
return set;
}
public static boolean isDay(World world) {
long time = world.getTime();
if (world.getEnvironment() == Environment.NETHER || world.getEnvironment() == Environment.THE_END) {
return true;
}
if (time >= 23500 || time <= 12500) {
return true;
}
return false;
}
public static boolean isFullMoon(World world) {
if (GeneralMethods.hasRPG()) {
return EventManager.marker.get(world).equalsIgnoreCase("FullMoon");
} else {
long days = world.getFullTime() / 24000;
long phase = days % 8;
if (phase == 0) {
return true;
}
return false;
}
}
public static boolean isIce(Block block) {
return isIce(block.getType());
}
public static boolean isIce(Material material) {
return material == Material.ICE || material == Material.PACKED_ICE;
}
public static boolean isLava(Block block) {
return block != null ? isLava(block.getType()) : false;
}
public static boolean isLava(Material material) {
return material == Material.LAVA || material == Material.STATIONARY_LAVA;
}
public static boolean isLunarEclipse(World world) {
if (world == null) {
return false;
}
return EventManager.marker.get(world).equalsIgnoreCase("SolarEclipse");
}
public static boolean isMeltable(Block block) {
if (block.getType() == Material.ICE || block.getType() == Material.SNOW) {
return true;
}
return false;
}
public static boolean isMetal(Block block) {
return block != null ? isMetal(block.getType()) : false;
}
public static boolean isMetal(Material material) {
return getConfig().getStringList("Properties.Earth.MetalBlocks").contains(material.toString());
}
public static boolean isMetalBlock(Block block) {
if (block.getType() == Material.GOLD_BLOCK || block.getType() == Material.IRON_BLOCK
|| block.getType() == Material.IRON_ORE || block.getType() == Material.GOLD_ORE
|| block.getType() == Material.QUARTZ_BLOCK || block.getType() == Material.QUARTZ_ORE) {
return true;
}
return false;
}
public static boolean isNegativeEffect(PotionEffectType effect) {
for (PotionEffectType effect2 : NEGATIVE_EFFECTS) {
if (effect2.equals(effect)) {
return true;
}
}
return false;
}
public static boolean isNeutralEffect(PotionEffectType effect) {
for (PotionEffectType effect2 : NEUTRAL_EFFECTS) {
if (effect2.equals(effect)) {
return true;
}
}
return false;
}
public static boolean isNight(World world) {
if (world.getEnvironment() == Environment.NETHER || world.getEnvironment() == Environment.THE_END) {
return false;
}
long time = world.getTime();
if (time >= 12950 && time <= 23050) {
return true;
}
return false;
}
@SuppressWarnings("deprecation")
public static boolean isPlant(Block block) {
if (block == null) {
return false;
} else if (Arrays.asList(PLANT_IDS).contains(block.getTypeId())) {
return true;
}
return false;
}
public static boolean isPositiveEffect(PotionEffectType effect) {
for (PotionEffectType effect2 : POSITIVE_EFFECTS) {
if (effect2.equals(effect)) {
return true;
}
}
return false;
}
public static boolean isSozinsComet(World world) {
return world != null ? EventManager.marker.get(world).equalsIgnoreCase("SozinsComet") : false;
}
@SuppressWarnings("deprecation")
public static boolean isTransparent(Player player, String abilityName, Block block) {
return Arrays.asList(TRANSPARENT_MATERIAL).contains(block.getTypeId())
&& !GeneralMethods.isRegionProtectedFromBuild(player, abilityName, block.getLocation());
}
public static boolean isTransparentToEarthbending(Player player, Block block) {
return isTransparent(player, null, block);
}
public static boolean isUndead(Entity entity) {
if (entity == null) {
return false;
} else if (entity.getType() == EntityType.ZOMBIE || entity.getType() == EntityType.BLAZE
|| entity.getType() == EntityType.GIANT || entity.getType() == EntityType.IRON_GOLEM
|| entity.getType() == EntityType.MAGMA_CUBE || entity.getType() == EntityType.PIG_ZOMBIE
|| entity.getType() == EntityType.SKELETON || entity.getType() == EntityType.SLIME
|| entity.getType() == EntityType.SNOWMAN || entity.getType() == EntityType.ZOMBIE) {
return true;
}
return false;
}
public static boolean isWater(Block block) {
return block != null ? isWater(block.getType()) : null;
}
public static boolean isWater(Material material) {
return material == Material.WATER || material == Material.STATIONARY_WATER;
}
}

View file

@ -1,242 +1,224 @@
package com.projectkorra.projectkorra.firebending;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AbilityModuleManager;
import com.projectkorra.projectkorra.util.Information;
import com.projectkorra.projectkorra.util.ParticleEffect;
import com.projectkorra.rpg.RPGMethods;
import com.projectkorra.rpg.event.EventManager;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
public class FireMethods {
static ProjectKorra plugin;
private static FileConfiguration config = ProjectKorra.plugin.getConfig();
public static ConcurrentHashMap<Location, Information> tempFire = new ConcurrentHashMap<Location, Information>();
public FireMethods(ProjectKorra plugin) {
FireMethods.plugin = plugin;
}
public static boolean canCombustionbend(Player player) {
if (player.hasPermission("bending.fire.combustionbending"))
return true;
return false;
}
public static boolean canLightningbend(Player player) {
if (player.hasPermission("bending.fire.lightningbending"))
return true;
return false;
}
/**
* Returns if fire is allowed to completely replace blocks or if it should place a temp fire
* block.
*/
public static boolean canFireGrief() {
return config.getBoolean("Properties.Fire.FireGriefing");
}
/**
* Creates a fire block meant to replace other blocks but reverts when the fire dissipates or is
* destroyed.
*/
public static void createTempFire(Location loc) {
if (loc.getBlock().getType() == Material.AIR) {
loc.getBlock().setType(Material.FIRE);
return;
}
Information info = new Information();
long time = config.getLong("Properties.Fire.RevertTicks")
+ (long) (GeneralMethods.rand.nextDouble() * config.getLong("Properties.Fire.RevertTicks"));
if (tempFire.containsKey(loc)) {
info = tempFire.get(loc);
} else {
info.setBlock(loc.getBlock());
info.setLocation(loc);
info.setState(loc.getBlock().getState());
}
info.setTime(time + System.currentTimeMillis());
loc.getBlock().setType(Material.FIRE);
tempFire.put(loc, info);
}
/**
* Gets the firebending dayfactor from the config multiplied by a specific value if it is day.
*
* @param value The value
* @param world The world to pass into {@link #isDay(World)}
* @return value DayFactor multiplied by specified value when {@link #isDay(World)} is true <br />
* else <br />
* value The specified value in the parameters
*/
public static double getFirebendingDayAugment(double value, World world) {
if (isDay(world)) {
if (GeneralMethods.hasRPG()) {
if (EventManager.marker.get(world).equalsIgnoreCase("SozinsComet")) {
return RPGMethods.getFactor("SozinsComet") * value;
} else if (EventManager.marker.get(world).equalsIgnoreCase("SolarEclipse")) {
return RPGMethods.getFactor("SolarEclipse") * value;
} else {
return value * config.getDouble("Properties.Fire.DayFactor");
}
} else {
return value * config.getDouble("Properties.Fire.DayFactor");
}
}
return value;
}
/**
* Gets the FireColor from the config.
*
* @return Config specified ChatColor
*/
public static ChatColor getFireColor() {
return ChatColor.valueOf(config.getString("Properties.Chat.Colors.Fire"));
}
/**
* Gets the FireSubColor from the config.
*
* @return Config specified ChatColor
*/
public static ChatColor getFireSubColor() {
return ChatColor.valueOf(config.getString("Properties.Chat.Colors.FireSub"));
}
public static boolean isCombustionbendingAbility(String ability) {
return AbilityModuleManager.combustionabilities.contains(ability);
}
public static boolean isLightningbendingAbility(String ability) {
return AbilityModuleManager.lightningabilities.contains(ability);
}
public static boolean isDay(World world) {
long time = world.getTime();
if (world.getEnvironment() == Environment.NETHER || world.getEnvironment() == Environment.THE_END)
return true;
if (time >= 23500 || time <= 12500) {
return true;
}
return false;
}
public static boolean isFireAbility(String ability) {
return AbilityModuleManager.firebendingabilities.contains(ability);
}
public static void playLightningbendingParticle(Location loc) {
playLightningbendingParticle(loc, (float) Math.random(), (float) Math.random(), (float) Math.random());
}
public static void playLightningbendingParticle(Location loc, float xOffset, float yOffset, float zOffset) {
loc.setX(loc.getX() + Math.random() * (xOffset / 2 - -(xOffset / 2)));
loc.setY(loc.getY() + Math.random() * (yOffset / 2 - -(yOffset / 2)));
loc.setZ(loc.getZ() + Math.random() * (zOffset / 2 - -(zOffset / 2)));
GeneralMethods.displayColoredParticle(loc, "#01E1FF");
}
public static void playFirebendingParticles(Location loc, int amount, float xOffset, float yOffset, float zOffset) {
ParticleEffect.FLAME.display(loc, xOffset, yOffset, zOffset, 0, amount);
}
public static void playFirebendingSound(Location loc) {
if (plugin.getConfig().getBoolean("Properties.Fire.PlaySound")) {
loc.getWorld().playSound(loc, Sound.FIRE, 1, 10);
}
}
public static void playCombustionSound(Location loc) {
if (plugin.getConfig().getBoolean("Properties.Fire.PlaySound")) {
loc.getWorld().playSound(loc, Sound.FIREWORK_BLAST, 1, -1);
}
}
/**
* Checks whether a location is within a FireShield.
*
* @param loc The location to check
* @return true If the location is inside a FireShield.
*/
public static boolean isWithinFireShield(Location loc) {
List<String> list = new ArrayList<String>();
list.add("FireShield");
return GeneralMethods.blockAbilities(null, list, loc, 0);
}
/** Removes all temp fire that no longer needs to be there */
public static void removeFire() {
Iterator<Location> it = tempFire.keySet().iterator();
while (it.hasNext()) {
Location loc = it.next();
Information info = tempFire.get(loc);
if (info.getLocation().getBlock().getType() != Material.FIRE
&& info.getLocation().getBlock().getType() != Material.AIR) {
revertTempFire(loc);
} else if (info.getBlock().getType() == Material.AIR || System.currentTimeMillis() > info.getTime()) {
revertTempFire(loc);
}
}
}
/**
* Revert the temp fire at the location if any is there.
*
* @param location The Location
* */
@SuppressWarnings("deprecation")
public static void revertTempFire(Location location) {
if (!tempFire.containsKey(location))
return;
Information info = tempFire.get(location);
if (info.getLocation().getBlock().getType() != Material.FIRE && info.getLocation().getBlock().getType() != Material.AIR) {
if (info.getState().getType() == Material.RED_ROSE || info.getState().getType() == Material.YELLOW_FLOWER) {
info.getState()
.getBlock()
.getWorld()
.dropItemNaturally(info.getLocation(),
new ItemStack(info.getState().getData().getItemType(), 1, info.getState().getRawData()));
}
} else {
info.getBlock().setType(info.getState().getType());
info.getBlock().setData(info.getState().getRawData());
}
tempFire.remove(location);
}
public static void stopBending() {
FireStream.removeAll();
Fireball.removeAll();
WallOfFire.removeAll();
Lightning.removeAll();
FireShield.removeAll();
FireBlast.removeAll();
FireBurst.removeAll();
FireJet.removeAll();
Cook.removeAll();
Illumination.removeAll();
FireCombo.removeAll();
for (Location loc : tempFire.keySet()) {
revertTempFire(loc);
}
}
}
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.firebending.BlazeArc;
import com.projectkorra.projectkorra.util.Information;
import com.projectkorra.projectkorra.util.ParticleEffect;
import com.projectkorra.rpg.RPGMethods;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
public abstract class FireAbility extends ElementalAbility {
private static final ConcurrentHashMap<Location, Information> TEMP_FIRE = new ConcurrentHashMap<Location, Information>();
private static final Material[] IGNITABLE_MATERIALS = { Material.BEDROCK, Material.BOOKSHELF, Material.BRICK, Material.CLAY, Material.CLAY_BRICK,
Material.COAL_ORE, Material.COBBLESTONE, Material.DIAMOND_ORE, Material.DIAMOND_BLOCK, Material.DIRT,
Material.ENDER_STONE, Material.GLOWING_REDSTONE_ORE, Material.GOLD_BLOCK, Material.GRAVEL, Material.GRASS,
Material.HUGE_MUSHROOM_1, Material.HUGE_MUSHROOM_2, Material.LAPIS_BLOCK, Material.LAPIS_ORE, Material.LOG,
Material.MOSSY_COBBLESTONE, Material.MYCEL, Material.NETHER_BRICK, Material.NETHERRACK, Material.OBSIDIAN,
Material.REDSTONE_ORE, Material.SAND, Material.SANDSTONE, Material.SMOOTH_BRICK, Material.STONE, Material.SOUL_SAND,
Material.WOOD, Material.WOOL, Material.LEAVES, Material.LEAVES_2, Material.MELON_BLOCK, Material.PUMPKIN,
Material.JACK_O_LANTERN, Material.NOTE_BLOCK, Material.GLOWSTONE, Material.IRON_BLOCK, Material.DISPENSER,
Material.SPONGE, Material.IRON_ORE, Material.GOLD_ORE, Material.COAL_BLOCK, Material.WORKBENCH,
Material.HAY_BLOCK, Material.REDSTONE_LAMP_OFF, Material.REDSTONE_LAMP_ON, Material.EMERALD_ORE,
Material.EMERALD_BLOCK, Material.REDSTONE_BLOCK, Material.QUARTZ_BLOCK, Material.QUARTZ_ORE,
Material.STAINED_CLAY, Material.HARD_CLAY };
public FireAbility(Player player) {
super(player);
}
@Override
public boolean isIgniteAbility() {
return true;
}
@Override
public boolean isExplosiveAbility() {
return true;
}
@Override
public Element getElement() {
return Element.FIRE;
}
public double getDayFactor(double value) {
return player != null ? getDayFactor(value, player.getWorld()) : 1;
}
/**
* Returns if fire is allowed to completely replace blocks or if it should place a temp fire
* block.
*/
public static boolean canFireGrief() {
return getConfig().getBoolean("Properties.Fire.FireGriefing");
}
/**
* Creates a fire block meant to replace other blocks but reverts when the fire dissipates or is
* destroyed.
*/
public static void createTempFire(Location loc) {
if (loc.getBlock().getType() == Material.AIR) {
loc.getBlock().setType(Material.FIRE);
return;
}
Information info = new Information();
long time = getConfig().getLong("Properties.Fire.RevertTicks")
+ (long) ((new Random()).nextDouble() * getConfig().getLong("Properties.Fire.RevertTicks"));
if (TEMP_FIRE.containsKey(loc)) {
info = TEMP_FIRE.get(loc);
} else {
info.setBlock(loc.getBlock());
info.setLocation(loc);
info.setState(loc.getBlock().getState());
}
info.setTime(time + System.currentTimeMillis());
loc.getBlock().setType(Material.FIRE);
TEMP_FIRE.put(loc, info);
}
public static double getDayFactor() {
return getConfig().getDouble("Properties.Fire.DayFactor");
}
/**
* Gets the firebending dayfactor from the config multiplied by a specific value if it is day.
*
* @param value The value
* @param world The world to pass into {@link #isDay(World)}
* @return value DayFactor multiplied by specified value when {@link #isDay(World)} is true <br />
* else <br />
* value The specified value in the parameters
*/
public static double getDayFactor(double value, World world) {
if (isDay(world)) {
if (GeneralMethods.hasRPG()) {
if (isSozinsComet(world)) {
return RPGMethods.getFactor("SozinsComet") * value;
} else if (isLunarEclipse(world)) {
return RPGMethods.getFactor("SolarEclipse") * value;
} else {
return value * getDayFactor();
}
} else {
return value * getDayFactor();
}
}
return value;
}
public static ChatColor getSubChatColor() {
return ChatColor.valueOf(ConfigManager.getConfig().getString("Properties.Chat.Colors.FireSub"));
}
public static boolean isIgnitable(Block block) {
return block != null ? isIgnitable(block.getType()) : false;
}
public static boolean isIgnitable(Material material) {
return Arrays.asList(IGNITABLE_MATERIALS).contains(material);
}
/**
* Checks whether a location is within a FireShield.
*
* @param loc The location to check
* @return true If the location is inside a FireShield.
*/
public static boolean isWithinFireShield(Location loc) {
List<String> list = new ArrayList<String>();
list.add("FireShield");
return GeneralMethods.blockAbilities(null, list, loc, 0);
}
public static void playCombustionSound(Location loc) {
if (getConfig().getBoolean("Properties.Fire.PlaySound")) {
loc.getWorld().playSound(loc, Sound.FIREWORK_BLAST, 1, -1);
}
}
public static void playFirebendingParticles(Location loc, int amount, float xOffset, float yOffset, float zOffset) {
ParticleEffect.FLAME.display(loc, xOffset, yOffset, zOffset, 0, amount);
}
public static void playFirebendingSound(Location loc) {
if (getConfig().getBoolean("Properties.Fire.PlaySound")) {
loc.getWorld().playSound(loc, Sound.FIRE, 1, 10);
}
}
public static void playLightningbendingParticle(Location loc) {
playLightningbendingParticle(loc, (float) Math.random(), (float) Math.random(), (float) Math.random());
}
public static void playLightningbendingParticle(Location loc, float xOffset, float yOffset, float zOffset) {
loc.setX(loc.getX() + Math.random() * (xOffset / 2 - -(xOffset / 2)));
loc.setY(loc.getY() + Math.random() * (yOffset / 2 - -(yOffset / 2)));
loc.setZ(loc.getZ() + Math.random() * (zOffset / 2 - -(zOffset / 2)));
GeneralMethods.displayColoredParticle(loc, "#01E1FF");
}
/** Removes all temp fire that no longer needs to be there */
public static void removeFire() {
Iterator<Location> it = TEMP_FIRE.keySet().iterator();
while (it.hasNext()) {
Location loc = it.next();
Information info = TEMP_FIRE.get(loc);
if (info.getLocation().getBlock().getType() != Material.FIRE
&& info.getLocation().getBlock().getType() != Material.AIR) {
revertTempFire(loc);
} else if (info.getBlock().getType() == Material.AIR || System.currentTimeMillis() > info.getTime()) {
revertTempFire(loc);
}
}
}
/**
* Revert the temp fire at the location if any is there.
*
* @param location The Location
* */
@SuppressWarnings("deprecation")
public static void revertTempFire(Location location) {
if (!TEMP_FIRE.containsKey(location)) {
return;
}
Information info = TEMP_FIRE.get(location);
if (info.getLocation().getBlock().getType() != Material.FIRE && info.getLocation().getBlock().getType() != Material.AIR) {
if (info.getState().getType() == Material.RED_ROSE || info.getState().getType() == Material.YELLOW_FLOWER) {
ItemStack itemStack = new ItemStack(info.getState().getData().getItemType(), 1, info.getState().getRawData());
info.getState().getBlock().getWorld().dropItemNaturally(info.getLocation(), itemStack);
}
} else {
info.getBlock().setType(info.getState().getType());
info.getBlock().setData(info.getState().getRawData());
}
TEMP_FIRE.remove(location);
}
public static void stopBending() {
BlazeArc.removeAllCleanup();
for (Location loc : TEMP_FIRE.keySet()) {
revertTempFire(loc);
}
}
}

View file

@ -1,13 +1,11 @@
package com.projectkorra.projectkorra.ability.api;
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import org.bukkit.entity.Player;
public abstract class FlightAbility extends AirAbility implements SubAbility {
public FlightAbility(Player player, boolean autoStart) {
super(player, autoStart);
}
public FlightAbility(Player player) {
super(player);
}
@ -16,4 +14,14 @@ public abstract class FlightAbility extends AirAbility implements SubAbility {
public Class<? extends Ability> getParentAbility() {
return AirAbility.class;
}
@Override
public Element getElement() {
return Element.FLIGHT;
}
@Override
public Element getParentElement() {
return Element.AIR;
}
}

View file

@ -1,13 +1,11 @@
package com.projectkorra.projectkorra.ability.api;
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import org.bukkit.entity.Player;
public abstract class HealingAbility extends WaterAbility implements SubAbility {
public HealingAbility(Player player, boolean autoStart) {
super(player, autoStart);
}
public HealingAbility(Player player) {
super(player);
}
@ -16,4 +14,14 @@ public abstract class HealingAbility extends WaterAbility implements SubAbility
public Class<? extends Ability> getParentAbility() {
return WaterAbility.class;
}
@Override
public Element getElement() {
return Element.HEALING;
}
@Override
public Element getParentElement() {
return Element.WATER;
}
}

View file

@ -0,0 +1,27 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import org.bukkit.entity.Player;
public abstract class IceAbility extends WaterAbility implements SubAbility {
public IceAbility(Player player) {
super(player);
}
@Override
public Class<? extends Ability> getParentAbility() {
return WaterAbility.class;
}
@Override
public Element getElement() {
return Element.ICE;
}
@Override
public Element getParentElement() {
return Element.WATER;
}
}

View file

@ -1,13 +1,11 @@
package com.projectkorra.projectkorra.ability.api;
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import org.bukkit.entity.Player;
public abstract class LavaAbility extends EarthAbility implements SubAbility {
public LavaAbility(Player player, boolean autoStart) {
super(player, autoStart);
}
public LavaAbility(Player player) {
super(player);
}
@ -17,4 +15,14 @@ public abstract class LavaAbility extends EarthAbility implements SubAbility {
return EarthAbility.class;
}
@Override
public Element getElement() {
return Element.LAVA;
}
@Override
public Element getParentElement() {
return Element.EARTH;
}
}

View file

@ -1,13 +1,11 @@
package com.projectkorra.projectkorra.ability.api;
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import org.bukkit.entity.Player;
public abstract class LightningAbility extends FireAbility implements SubAbility {
public LightningAbility(Player player, boolean autoStart) {
super(player, autoStart);
}
public LightningAbility(Player player) {
super(player);
}
@ -16,4 +14,14 @@ public abstract class LightningAbility extends FireAbility implements SubAbility
public Class<? extends Ability> getParentAbility() {
return FireAbility.class;
}
@Override
public Element getElement() {
return Element.LIGHTNING;
}
@Override
public Element getParentElement() {
return Element.FIRE;
}
}

View file

@ -1,19 +1,27 @@
package com.projectkorra.projectkorra.ability.api;
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import org.bukkit.entity.Player;
public abstract class MetalAbility extends EarthAbility implements SubAbility {
public MetalAbility(Player player, boolean autoStart) {
super(player, autoStart);
}
public MetalAbility(Player player) {
super(player, false);
super(player);
}
@Override
public Class<? extends Ability> getParentAbility() {
return EarthAbility.class;
}
@Override
public Element getElement() {
return Element.METAL;
}
@Override
public Element getParentElement() {
return Element.EARTH;
}
}

View file

@ -0,0 +1,17 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager.MultiAbilityInfoSub;
import java.util.ArrayList;
public interface MultiAbility {
/**
* Returns the sub abilities of a MultiAbility. e.g. {@code new
* MultiAbilitySub("SubAbility", Element.Fire, SubElement.Lightning);}
*
* @return arraylist of multiabilitysub
*/
public abstract ArrayList<MultiAbilityInfoSub> getMultiAbilities();
}

View file

@ -0,0 +1,27 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import org.bukkit.entity.Player;
public abstract class PlantAbility extends WaterAbility implements SubAbility {
public PlantAbility(Player player) {
super(player);
}
@Override
public Class<? extends Ability> getParentAbility() {
return WaterAbility.class;
}
@Override
public Element getElement() {
return Element.PLANT;
}
@Override
public Element getParentElement() {
return Element.WATER;
}
}

View file

@ -1,15 +1,13 @@
package com.projectkorra.projectkorra.ability.api;
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import org.bukkit.entity.Player;
public abstract class SandAbility extends EarthAbility implements SubAbility {
public SandAbility(Player player, boolean autoStart) {
super(player, autoStart);
}
public SandAbility(Player player) {
super(player, false);
super(player);
}
@Override
@ -17,4 +15,14 @@ public abstract class SandAbility extends EarthAbility implements SubAbility {
return EarthAbility.class;
}
@Override
public Element getElement() {
return Element.SAND;
}
@Override
public Element getParentElement() {
return Element.EARTH;
}
}

View file

@ -0,0 +1,27 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
import org.bukkit.entity.Player;
public abstract class SpiritualAbility extends AirAbility implements SubAbility {
public SpiritualAbility(Player player) {
super(player);
}
@Override
public Class<? extends Ability> getParentAbility() {
return AirAbility.class;
}
@Override
public Element getElement() {
return Element.SPIRITUAL;
}
@Override
public Element getParentElement() {
return Element.WATER;
}
}

View file

@ -1,240 +0,0 @@
package com.projectkorra.projectkorra.ability;
import java.util.Arrays;
/**
* An enum representation of all ProjectKorra core abilities.
*/
public enum StockAbility {
// Old Bending
AirBlast, AirBubble, AirShield, AirSuction, AirSwipe, Tornado, AirScooter, AirSpout, AirBurst,
Catapult, RaiseEarth, EarthGrab, EarthTunnel, EarthBlast, Collapse, Tremorsense, EarthArmor, Shockwave,
HeatControl, Blaze, FireJet, Illumination, WallOfFire, FireBlast, Lightning, FireBurst, FireShield,
WaterBubble, PhaseChange, HealingWaters, WaterManipulation, Surge, Bloodbending, WaterSpout, IceSpike, OctopusForm, Torrent,
HighJump, RapidPunch, Paralyze,
AvatarState,
// Project Korra
Extraction, MetalClips, Smokescreen, Combustion, LavaFlow, Suffocate, IceBlast, WarriorStance, AcrobatStance, QuickStrike, SwiftKick, EarthSmash, Flight, WaterArms, SandSpout, PlantArmor;
public enum AirbendingAbilities {
AirBlast, AirBubble, AirShield, AirSuction, AirSwipe, Tornado, AirScooter, AirSpout, AirBurst, Suffocate, Flight;
}
public enum WaterbendingAbilities {
WaterBubble, PhaseChange, HealingWaters, WaterManipulation, Surge, Bloodbending, WaterSpout, IceSpike, IceBlast, OctopusForm, Torrent, WaterArms, PlantArmor;
}
public enum EarthbendingAbilities {
Catapult, RaiseEarth, EarthGrab, EarthTunnel, EarthBlast, Collapse, Tremorsense, EarthArmor, Shockwave, Extraction, MetalClips, LavaFlow, EarthSmash, SandSpout;
}
public enum FirebendingAbilities {
HeatControl, Blaze, FireJet, Illumination, WallOfFire, FireBlast, Lightning, FireBurst, FireShield, Combustion;
}
public enum ChiblockingAbilities {
HighJump, RapidPunch, Paralyze, Smokescreen, WarriorStance, AcrobatStance, QuickStrike, SwiftKick;
}
public enum FlightAbilities {
Flight;
}
private enum SpiritualProjectionAbilities {
;
}
public enum CombustionbendingAbilities {
Combustion;
}
public enum LightningbendingAbilities {
Lightning;
}
public enum LavabendingAbilities {
LavaFlow;
}
public enum MetalbendingAbilities {
Extraction, MetalClips;
}
public enum SandbendingAbilities {
SandSpout;
}
public enum HealingAbilities {
HealingWaters;
}
public enum IcebendingAbilities {
PhaseChange, IceBlast, IceSpike;
}
public enum BloodbendingAbilities {
Bloodbending;
}
public enum PlantbendingAbilities {
PlantArmor;
}
public enum MultiAbilities {
WaterArms;
}
public enum AvatarAbilities {
AvatarState;
}
public static boolean isFlightAbility(String ability) {
for (FlightAbilities a : FlightAbilities.values())
if (a.name().equalsIgnoreCase(ability))
return true;
return false;
}
public static boolean isSpiritualProjectionAbility(String ability) {
for (SpiritualProjectionAbilities a : SpiritualProjectionAbilities.values())
if (a.name().equalsIgnoreCase(ability))
return true;
return false;
}
public static boolean isCombustionbendingAbility(String ability) {
for (CombustionbendingAbilities a : CombustionbendingAbilities.values())
if (a.name().equalsIgnoreCase(ability))
return true;
return false;
}
public static boolean isLightningbendingAbility(String ability) {
for (LightningbendingAbilities a : LightningbendingAbilities.values())
if (a.name().equalsIgnoreCase(ability))
return true;
return false;
}
public static boolean isLavabendingAbility(String ability) {
for (LavabendingAbilities a : LavabendingAbilities.values())
if (a.name().equalsIgnoreCase(ability))
return true;
return false;
}
public static boolean isMetalbendingAbility(String ability) {
for (MetalbendingAbilities a : MetalbendingAbilities.values())
if (a.name().equalsIgnoreCase(ability))
return true;
return false;
}
public static boolean isSandbendingAbility(String ability) {
for (SandbendingAbilities a : SandbendingAbilities.values())
if (a.name().equalsIgnoreCase(ability))
return true;
return false;
}
public static boolean isHealingAbility(String ability) {
for (HealingAbilities a : HealingAbilities.values())
if (a.name().equalsIgnoreCase(ability))
return true;
return false;
}
public static boolean isIcebendingAbility(String ability) {
for (IcebendingAbilities a : IcebendingAbilities.values())
if (a.name().equalsIgnoreCase(ability))
return true;
return false;
}
public static boolean isBloodbendingAbility(String ability) {
for (BloodbendingAbilities a : BloodbendingAbilities.values())
if (a.name().equalsIgnoreCase(ability))
return true;
return false;
}
public static boolean isPlantbendingAbility(String ability) {
for (PlantbendingAbilities a : PlantbendingAbilities.values())
if (a.name().equalsIgnoreCase(ability))
return true;
return false;
}
public static boolean isStockAbility(String ability) {
for (StockAbility a : StockAbility.values()) {
if (a.name().equalsIgnoreCase(ability))
return true;
}
return false;
}
public static boolean isAirbending(StockAbility ability) {
for (AirbendingAbilities a : AirbendingAbilities.values()) {
if (a.name().equalsIgnoreCase(ability.name()))
return true;
}
return false;
}
public static boolean isWaterbending(StockAbility ability) {
for (WaterbendingAbilities a : WaterbendingAbilities.values()) {
if (a.name().equalsIgnoreCase(ability.name()))
return true;
}
return false;
}
public static boolean isEarthbending(StockAbility ability) {
for (EarthbendingAbilities a : EarthbendingAbilities.values()) {
if (a.name().equalsIgnoreCase(ability.name()))
return true;
}
return false;
}
public static boolean isFirebending(StockAbility ability) {
for (FirebendingAbilities a : FirebendingAbilities.values()) {
if (a.name().equalsIgnoreCase(ability.name()))
return true;
}
return false;
}
public static boolean isChiBlocking(StockAbility ability) {
for (ChiblockingAbilities a : ChiblockingAbilities.values()) {
if (a.name().equalsIgnoreCase(ability.name()))
return true;
}
return false;
}
public static boolean isMultiAbility(StockAbility ability) {
for (MultiAbilities a : MultiAbilities.values()) {
if (a.name().equalsIgnoreCase(ability.name()))
return true;
}
return false;
}
public static StockAbility getAbility(int index) {
if (index == -1)
return null;
if (index > StockAbility.values().length)
return null;
return Arrays.asList(StockAbility.values()).get(index);
}
}

View file

@ -0,0 +1,10 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.Element;
public interface SubAbility {
public Class<? extends Ability> getParentAbility();
public Element getParentElement();
}

View file

@ -0,0 +1,298 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.util.BlockSource;
import com.projectkorra.projectkorra.util.TempBlock;
import com.projectkorra.projectkorra.waterbending.PhaseChangeFreeze;
import com.projectkorra.projectkorra.waterbending.SurgeWall;
import com.projectkorra.projectkorra.waterbending.SurgeWave;
import com.projectkorra.projectkorra.waterbending.WaterArms;
import com.projectkorra.projectkorra.waterbending.WaterSpout;
import com.projectkorra.rpg.RPGMethods;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
public abstract class WaterAbility extends BlockAbility {
public WaterAbility(Player player) {
super(player);
}
public boolean canAutoSource() {
return getConfig().getBoolean("Abilities." + getElement() + "." + getName() + ".CanAutoSource");
}
public boolean canDynamicSource() {
return getConfig().getBoolean("Abilities." + getElement() + "." + getName() + ".CanDynamicSource");
}
@Override
public Element getElement() {
return Element.WATER;
}
public Block getIceSourceBlock(double range) {
return getIceSourceBlock(player, range);
}
public double getNightFactor() {
if (getLocation() != null) {
return getNightFactor(getLocation().getWorld());
}
return player != null ? getNightFactor(player.getLocation().getWorld()) : 1;
}
public double getNightFactor(double value) {
return player != null ? getNightFactor(value, player.getWorld()) : value;
}
public Block getPlantSourceBlock(double range) {
return getPlantSourceBlock(range, false);
}
public Block getPlantSourceBlock(double range, boolean onlyLeaves) {
return getPlantSourceBlock(player, range, onlyLeaves);
}
@Override
public boolean isExplosiveAbility() {
return false;
}
@Override
public boolean isIgniteAbility() {
return false;
}
public boolean isWaterbendable(Block block) {
return isWaterbendable(block, player);
}
public static boolean canBendPackedIce() {
return getConfig().getBoolean("Properties.Water.CanBendPackedIce");
}
public static Block getIceSourceBlock(Player player, double range) {
Location location = player.getEyeLocation();
Vector vector = location.getDirection().clone().normalize();
for (double i = 0; i <= range; i++) {
Block block = location.clone().add(vector.clone().multiply(i)).getBlock();
if (GeneralMethods.isRegionProtectedFromBuild(player, "IceBlast", location)) {
continue;
}
if (isIcebendable(block)) {
if (TempBlock.isTempBlock(block)) {
continue;
}
return block;
}
}
return null;
}
public static double getNightFactor(double value, World world) {
if (isNight(world)) {
if (GeneralMethods.hasRPG()) {
if (isLunarEclipse(world)) {
return RPGMethods.getFactor("LunarEclipse");
} else if (isFullMoon(world)) {
return RPGMethods.getFactor("FullMoon");
} else {
return value;
}
} else {
if (isFullMoon(world)) {
return getConfig().getDouble("Properties.Water.FullMoonFactor") * value;
} else {
return getConfig().getDouble("Properties.Water.NightFactor") * value;
}
}
} else {
return value;
}
}
public static double getNightFactor(World world) {
return getNightFactor(1, world);
}
public static Block getPlantSourceBlock(Player player, double range, boolean onlyLeaves) {
Location location = player.getEyeLocation();
Vector vector = location.getDirection().clone().normalize();
for (double i = 0; i <= range; i++) {
Block block = location.clone().add(vector.clone().multiply(i)).getBlock();
if (GeneralMethods.isRegionProtectedFromBuild(player, "PlantDisc", location)) {
continue;
} else if (isPlantbendable(block, onlyLeaves)) {
if (TempBlock.isTempBlock(block)) {
continue;
}
return block;
}
}
return null;
}
/**
* Finds a valid Water source for a Player. To use dynamic source selection,
* use BlockSource.getWaterSourceBlock() instead of this method. Dynamic
* source selection saves the user's previous source for future use.
* {@link BlockSource#getWaterSourceBlock(Player, double)}
*
* @param player the player that is attempting to Waterbend.
* @param range the maximum block selection range.
* @param plantbending true if the player can bend plants.
* @return a valid Water source block, or null if one could not be found.
*/
@SuppressWarnings("deprecation")
public static Block getWaterSourceBlock(Player player, double range, boolean plantbending) {
Location location = player.getEyeLocation();
Vector vector = location.getDirection().clone().normalize();
for (double i = 0; i <= range; i++) {
Block block = location.clone().add(vector.clone().multiply(i)).getBlock();
if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", location)) {
continue;
} else if (isWaterbendable(block, player) && (!isPlant(block) || plantbending)) {
if (TempBlock.isTempBlock(block)) {
TempBlock tb = TempBlock.get(block);
byte full = 0x0;
if (tb.getState().getRawData() != full
&& (tb.getState().getType() != Material.WATER || tb.getState().getType() != Material.STATIONARY_WATER)) {
continue;
}
}
return block;
}
}
return null;
}
public static boolean isAdjacentToFrozenBlock(Block block) {
BlockFace[] faces = { BlockFace.DOWN, BlockFace.UP, BlockFace.NORTH, BlockFace.EAST, BlockFace.WEST, BlockFace.SOUTH };
boolean adjacent = false;
for (BlockFace face : faces) {
if (PhaseChangeFreeze.getFrozenBlocks().containsKey((block.getRelative(face)))) {
adjacent = true;
}
}
return adjacent;
}
public static boolean isIcebendable(Block block) {
return block != null ? isIcebendable(block.getType()) : false;
}
public static boolean isIcebendable(Material material) {
if (material == Material.ICE) {
return true;
} else if (material == Material.PACKED_ICE && canBendPackedIce()) {
return true;
}
return false;
}
public static boolean isPlantbendable(Block block) {
return isPlantbendable(block, false);
}
public static boolean isPlantbendable(Block block, boolean leavesOnly) {
if (block.getType() == Material.LEAVES) {
return true;
} else if (block.getType() == Material.LEAVES_2) {
return true;
} else if (isPlant(block) && !leavesOnly) {
return true;
}
return false;
}
public static boolean isSnow(Block block) {
return block != null ? isSnow(block.getType()) : false;
}
public static boolean isSnow(Material material) {
return material == Material.SNOW || material == Material.SNOW_BLOCK;
}
@SuppressWarnings("deprecation")
public static boolean isWaterbendable(Block block, Player player) {
byte full = 0x0;
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (TempBlock.isTempBlock(block)) {
return false;
} else if (isWater(block) && block.getData() == full) {
return true;
} else if (block.getType() == Material.ICE || block.getType() == Material.SNOW) {
return true;
} else if (block.getType() == Material.PACKED_ICE && canBendPackedIce()) {
return true;
} else if (bPlayer != null && bPlayer.canPlantbend() && isPlant(block)) {
return true;
}
return false;
}
public static void playFocusWaterEffect(Block block) {
block.getWorld().playEffect(block.getLocation(), Effect.SMOKE, 4, 20);
}
public static void playIcebendingSound(Location loc) {
if (getConfig().getBoolean("Properties.Water.PlaySound")) {
loc.getWorld().playSound(loc, Sound.FIRE_IGNITE, 2, 10);
}
}
public static void playPlantbendingSound(Location loc) {
if (getConfig().getBoolean("Properties.Water.PlaySound")) {
loc.getWorld().playSound(loc, Sound.STEP_GRASS, 1, 10);
}
}
public static void playWaterbendingSound(Location loc) {
if (getConfig().getBoolean("Properties.Water.PlaySound")) {
loc.getWorld().playSound(loc, Sound.WATER, 1, 10);
}
}
/**
* Removes all water spouts in a location within a certain radius.
*
* @param loc The location to use
* @param radius The radius around the location to remove spouts in
* @param source The player causing the removal
*/
public static void removeWaterSpouts(Location loc, double radius, Player source) {
WaterSpout.removeSpouts(loc, radius, source);
}
/**
* Removes all water spouts in a location with a radius of 1.5.
*
* @param loc The location to use
* @param source The player causing the removal
*/
public static void removeWaterSpouts(Location loc, Player source) {
removeWaterSpouts(loc, 1.5, source);
}
public static void stopBending() {
PhaseChangeFreeze.removeAllCleanup();
WaterSpout.removeAllCleanup();
SurgeWall.removeAllCleanup();
SurgeWave.removeAllCleanup();
WaterArms.removeAllCleanup();
}
}

View file

@ -1,12 +0,0 @@
package com.projectkorra.projectkorra.ability.api;
public interface Ability {
public String getName();
public String getDescription();
public void progress();
public void remove();
}

View file

@ -1,32 +0,0 @@
package com.projectkorra.projectkorra.ability.api;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
public abstract class AirAbility extends CoreAbility {
public AirAbility(Player player, boolean autoStart) {
super(player, autoStart);
}
public AirAbility(Player player) {
this(player, false);
}
@Override
public final String getElementName() {
return "Air";
}
/**
* Gets the AirColor from the config.
*
* @return Config specified ChatColor
*/
public static ChatColor getAirColor() {
return ChatColor.valueOf(ConfigManager.getConfig().getString("Properties.Chat.Colors.Air"));
}
}

View file

@ -1,155 +0,0 @@
package com.projectkorra.projectkorra.ability.api;
import com.projectkorra.projectkorra.SubElement;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public abstract class CoreAbility implements Ability {
private static ConcurrentHashMap<Class<? extends CoreAbility>, ConcurrentHashMap<UUID, ConcurrentHashMap<Integer, CoreAbility>>> instances = new ConcurrentHashMap<>();
private static ConcurrentHashMap<Class<? extends CoreAbility>, Set<CoreAbility>> instancesByClass = new ConcurrentHashMap<>();
private static Integer idCounter;
private long startTime;
private Player player;
private Integer id;
private FileConfiguration config;
static {
idCounter = Integer.MIN_VALUE;
}
public CoreAbility(Player player, boolean autoStart) {
if (player == null) {
throw new IllegalArgumentException("Player cannot be null");
}
this.player = player;
this.startTime = System.currentTimeMillis();
this.config = ConfigManager.defaultConfig.get();
if (autoStart) {
start();
}
}
private void start() {
Class<? extends CoreAbility> clazz = getClass();
UUID uuid = player.getUniqueId();
if (!CoreAbility.instances.containsKey(clazz)) {
CoreAbility.instances.put(clazz, new ConcurrentHashMap<UUID, ConcurrentHashMap<Integer, CoreAbility>>());
CoreAbility.instancesByClass.put(clazz, Collections.newSetFromMap(new ConcurrentHashMap<CoreAbility, Boolean>()));
}
if (!CoreAbility.instances.get(clazz).containsKey(uuid)) {
CoreAbility.instances.get(clazz).put(uuid, new ConcurrentHashMap<Integer, CoreAbility>());
}
this.id = CoreAbility.idCounter;
if (CoreAbility.idCounter == Integer.MAX_VALUE) {
CoreAbility.idCounter = Integer.MIN_VALUE;
} else {
CoreAbility.idCounter++;
}
CoreAbility.instances.get(clazz).get(uuid).put(this.id, this);
CoreAbility.instancesByClass.get(clazz).add(this);
}
public CoreAbility(Player player) {
this(player, true);
}
public long getStartTime() {
return startTime;
}
public Player getPlayer() {
return player;
}
public Integer getId() {
return id;
}
public String getDescription() {
return config.getString("Properties." + getElementName() + "." + getName() + ".Description");
}
public FileConfiguration getConfig() {
return config;
}
@Override
public void remove() {
ConcurrentHashMap<UUID, ConcurrentHashMap<Integer, CoreAbility>> classMap = CoreAbility.instances.get(getClass());
ConcurrentHashMap<Integer, CoreAbility> playerMap = classMap.get(player.getUniqueId());
playerMap.remove(this.id);
if (playerMap.size() == 0) {
classMap.remove(playerMap);
}
CoreAbility.instancesByClass.get(getClass()).remove(this);
}
public static void progressAll() {
for (Set<CoreAbility> setAbils : CoreAbility.instancesByClass.values()) {
for (CoreAbility abil : setAbils) {
abil.progress();
}
}
}
public static void removeAll() {
for (Set<CoreAbility> setAbils : CoreAbility.instancesByClass.values()) {
for (CoreAbility abil : setAbils) {
abil.remove();
}
}
}
public static CoreAbility getAbility(Player player, Class<? extends CoreAbility> clazz) {
Collection<CoreAbility> abils = CoreAbility.getAbilities(player, clazz);
if (abils.iterator().hasNext()) {
return abils.iterator().next();
}
return null;
}
public static Collection<CoreAbility> getAbilities(Class<? extends CoreAbility> clazz) {
if (CoreAbility.instancesByClass.get(clazz).size() == 0) {
return Collections.emptySet();
}
return CoreAbility.instancesByClass.get(clazz);
}
public static Collection<CoreAbility> getAbilities(Player player, Class<? extends CoreAbility> clazz) {
if (player == null || CoreAbility.instances.get(clazz) == null || CoreAbility.instances.get(clazz).get(player.getUniqueId()) == null) {
return Collections.emptySet();
}
return CoreAbility.instances.get(clazz).get(player.getUniqueId()).values();
}
public ChatColor getElementColor() {
String element = (this instanceof SubAbility) ? getParentAbility().getElementName() + "Sub" : getElementName();
return ChatColor.valueOf(ConfigManager.getConfig().getString("Properties.Chat.Colors."+element));
}
public abstract String getName();
public abstract String getElementName();
public abstract Location getLocation();
public abstract long getCooldown();
}

View file

@ -1,46 +0,0 @@
package com.projectkorra.projectkorra.ability.api;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
public abstract class EarthAbility extends CoreAbility implements SourceAbility {
private boolean canAutoSource;
private boolean canDynamicSource;
private boolean canSelfSource;
public EarthAbility(Player player, boolean autoStart) {
super(player, autoStart);
}
public EarthAbility(Player player) {
this(player, false);
}
@Override
public final String getElementName() {
return "Earth";
}
/**
* Gets the EarthColor from the config.
*
* @return Config specified ChatColor
*/
public static ChatColor getEarthColor() {
return ChatColor.valueOf(ConfigManager.getConfig().getString("Properties.Chat.Colors.Earth"));
}
public boolean canAutoSource() {
return canAutoSource;
}
public boolean canDynamicSource() {
return canDynamicSource;
}
public boolean canSelfSource() {
return canSelfSource;
}
}

View file

@ -1,81 +0,0 @@
package com.projectkorra.projectkorra.ability.api;
import com.projectkorra.projectkorra.BendingManager;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.firebending.FireMethods;
import com.projectkorra.rpg.RPGMethods;
import com.projectkorra.rpg.WorldEvents;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
public abstract class FireAbility extends CoreAbility {
private double dayFactor;
public FireAbility(Player player, boolean autoStart) {
super(player, autoStart);
this.dayFactor = FireAbility.getFirebendingDayAugment(1, player.getWorld());
}
public FireAbility(Player player) {
this(player, false);
}
public double getDayFactor() {
return dayFactor;
}
public double getDayFactor(double value) {
return dayFactor * value;
}
@Override
public final String getElementName() {
return "Fire";
}
/**
* Gets the FireColor from the config.
*
* @return Config specified ChatColor
*/
public static ChatColor getFireColor() {
return ChatColor.valueOf(ConfigManager.getConfig().getString("Properties.Chat.Colors.Fire"));
}
public static boolean canFireGrief() {
return ConfigManager.getConfig().getBoolean("Properties.Fire.FireGriefing");
}
/**
* Gets the firebending dayfactor from the config multiplied by a specific value if it is day.
*
* @param value The value
* @param world The world to pass into {@link #isDay(World)}
* @return value DayFactor multiplied by specified value when {@link #isDay(World)} is true <br />
* else <br />
* value The specified value in the parameters
*/
public static double getFirebendingDayAugment(double value, World world) {
FileConfiguration config = ConfigManager.getConfig();
if (FireMethods.isDay(world)) { // TODO move the isDay method
if (GeneralMethods.hasRPG()) {
if (BendingManager.events.get(world).equalsIgnoreCase(WorldEvents.SozinsComet.toString())) {
return RPGMethods.getFactor(WorldEvents.SozinsComet) * value;
} else if (BendingManager.events.get(world).equalsIgnoreCase(WorldEvents.SolarEclipse.toString())) {
return RPGMethods.getFactor(WorldEvents.SolarEclipse) * value;
} else {
return value * config.getDouble("Properties.Fire.DayFactor");
}
} else {
return value * config.getDouble("Properties.Fire.DayFactor");
}
}
return value;
}
}

View file

@ -1,14 +0,0 @@
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.block.Block;
public interface SourceAbility {
public Block getSource();
public boolean canAutoSource();
public boolean canDynamicSource();
public boolean canSelfSource();
}

View file

@ -1,6 +0,0 @@
package com.projectkorra.projectkorra.ability.api;
public interface SubAbility {
public Class<? extends Ability> getParentAbility();
}

View file

@ -1,47 +0,0 @@
package com.projectkorra.projectkorra.ability.api;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
public abstract class WaterAbility extends CoreAbility implements SourceAbility {
private boolean canAutoSource;
private boolean canDynamicSource;
private boolean canSelfSource;
public WaterAbility(Player player, boolean autoStart) {
super(player, autoStart);
}
public WaterAbility(Player player) {
this(player, false);
}
@Override
public final String getElementName() {
return "Water";
}
/**
* Gets the WaterColor from the config.
*
* @return Config specified ChatColor
*/
public static ChatColor getWaterColor() {
return ChatColor.valueOf(ConfigManager.getConfig().getString("Properties.Chat.Colors.Water"));
}
public boolean canAutoSource() {
return canAutoSource;
}
public boolean canDynamicSource() {
return canDynamicSource;
}
public boolean canSelfSource() {
return canSelfSource;
}
}

View file

@ -1,116 +0,0 @@
package com.projectkorra.projectkorra.ability.combo;
import com.projectkorra.projectkorra.SubElement;
import com.projectkorra.projectkorra.util.AbilityLoadable;
import org.bukkit.entity.Player;
import java.util.ArrayList;
/**
* Created by Carbogen on 2/7/2015.
*/
public abstract class ComboAbilityModule extends AbilityLoadable implements Cloneable {
/**
* AbilityModule Constructor.
*
* @param name The name of the ability.
*/
public ComboAbilityModule(final String name) {
super(name);
}
/**
* Called when the ability is loaded by PK. This is where the developer
* registers Listeners and Permissions.
*/
public abstract void onThisLoad();
// Must be overridden
/**
* Accessor Method to get the version of the ability.
*
* @return The version of the ability as a String.
*/
public abstract String getVersion();
/**
* Accessor Method to get the Element of the ability. It is recommended to
* use the Element ENUM to get the returned String. This can be an empty
* String, in which case the ability will not belong to any element (such as
* AvatarState).
*
* @return The Element the ability belongs to.
*/
public abstract String getElement();
/**
* Accessor Method to get the name of the author.
*
* @return The name of the author.
*/
public abstract String getAuthor();
/**
* Accessor Method to get the description of the ability. This String is
* sent to any player who runs /pk display ability.
*
* @return The Description of the ability.
*/
public abstract String getDescription();
/**
* Accessor Method to get the instructions for using this combo.
*
* @return The steps for the combo.
*/
public abstract String getInstructions();
/**
* Creates a new instance of the combo from a specific player.
* ProjectKorra's ComboModuleManager will use this method once the combo
* steps have been used by the player.
*
* @return A new instance of the ability.
* @param player The player using the combo.
*/
public abstract Object createNewComboInstance(Player player);
/**
* Returns the list of abilities which constitute the combo.
*
* @return An ArrayList containing the combo's steps.
*/
public abstract ArrayList<ComboManager.AbilityInformation> getCombination();
/**
* Void Method called whenever ProjectKorra stops and the ability is
* unloaded.
*
*/
public void stop() {
}
/**
* Accessor Method to get which SubElement the ability belongs to. If
* isSubAbility() returns true, the developer absolutely must implement this
* as well.
*
* List of sub-elements:
*
* Water: Icebending. Bloodbending. Plantbending. Healing.
*
* Earth: Sandbending. Metalbending. Lavabending.
*
* Fire: Combustion. Lightning.
*
* Air: Flight. SpiritualProjection.
*
* @return The SubElement the ability belongs to.
*/
public SubElement getSubElement() {
return null;
}
}

View file

@ -1,35 +0,0 @@
package com.projectkorra.projectkorra.ability.combo;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.util.AbilityLoader;
import java.io.File;
import java.util.List;
public class ComboModuleManager {
private final AbilityLoader<ComboAbilityModule> loader;
public static List<ComboAbilityModule> combo;
public ComboModuleManager() {
final File path = new File(ProjectKorra.plugin.getDataFolder().toString() + "/Combos/");
if (!path.exists()) {
path.mkdir();
}
loader = new AbilityLoader<ComboAbilityModule>(ProjectKorra.plugin, path, new Object[] {});
combo = loader.load(ComboAbilityModule.class);
loadComboModules();
}
private void loadComboModules() {
for (ComboAbilityModule cm : combo) {
cm.onThisLoad();
ComboManager.comboAbilityList.put(cm.getName(), new ComboManager.ComboAbility(cm.getName(), cm.getCombination(), cm));
ComboManager.descriptions.put(cm.getName(), cm.getDescription());
ComboManager.instructions.put(cm.getName(), cm.getInstructions());
ComboManager.authors.put(cm.getName(), cm.getAuthor());
}
}
}

View file

@ -1,130 +0,0 @@
package com.projectkorra.projectkorra.ability.multiability;
import com.projectkorra.projectkorra.SubElement;
import com.projectkorra.projectkorra.ability.multiability.MultiAbilityManager.MultiAbilitySub;
import com.projectkorra.projectkorra.util.AbilityLoadable;
import java.util.ArrayList;
public abstract class MultiAbilityModule extends AbilityLoadable implements Cloneable {
public MultiAbilityModule(String name) {
super(name);
}
/**
* Called when the ability is loaded by PK. This is where the developer
* registers Listeners and Permissions.
*/
public abstract void onThisLoad();
/**
* Accessor Method to get the version of the ability.
*
* @return The version of the ability as a String.
*/
public abstract String getVersion();
/**
* Accessor Method to get the Element of the ability. It is recommended to
* use the Element ENUM to get the returned String. This can be an empty
* String, in which case the ability will not belong to any element (such as
* AvatarState).
*
* @return The Element the ability belongs to.
*/
public abstract String getElement();
/**
* Accessor Method to get the name of the author.
*
* @return The name of the author.
*/
public abstract String getAuthor();
/**
* Accessor Method to get the description of the ability. This String is
* sent to any player who runs /pk display ability.
*
* @return The Description of the ability.
*/
public abstract String getDescription();
/**
* Accessor Method to get whether this ability uses sneaking to operate.
* Some features of the ProjectKorra plugin only work when this is false.
* (Fast Swimming for Waterbenders)
*
* @return Whether or not the ability uses the sneak key.
*/
public boolean isShiftAbility() {
return true;
}
/**
* Accessor Method to get whether this ability harms entities. AirSpout is
* an example of a harmless ability. For AirSpout, this returns true.
* IceBlast is an example of a harmful ability. For IceBlast, this returns
* false. Torrent is an example of both a harmless and a harmful ability.
* For Torrent, this returns false.
*
* @return Whether of not the ability can hurt entities.
*/
public abstract boolean isHarmlessAbility();
/**
* Accessor Method to get whether this ability can set fire to blocks.
*
* @return Whether or not this ability can ignite blocks.
*/
public boolean isIgniteAbility() {
return false;
}
/**
* Accessor Method to get whether this ability can create explosions.
*
* @return Whether or not this ability creates explosions.
*/
public boolean isExplodeAbility() {
return false;
}
/**
* Accessor Method to get which SubElement the ability belongs to. If
* isSubAbility() returns true, the developer absolutely must implement this
* as well.
*
* List of sub-elements:
*
* Water: Icebending. Bloodbending. Plantbending. Healing.
*
* Earth: Sandbending. Metalbending. Lavabending.
*
* Fire: Combustion. Lightning.
*
* Air: Flight. SpiritualProjection.
*
* @return The SubElement the ability belongs to.
*/
public SubElement getSubElement() {
return null;
}
/**
* Returns the sub abilities of a MultiAbility. e.g. {@code new
* MultiAbilitySub("SubAbility", Element.Fire, SubElement.Lightning);}
*
* @return arraylist of multiabilitysub
*/
public abstract ArrayList<MultiAbilitySub> getAbilities();
/**
* Void Method called whenever ProjectKorra stops and the ability is
* unloaded.
*/
public void stop() {
}
}

View file

@ -1,96 +0,0 @@
package com.projectkorra.projectkorra.ability.multiability;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AbilityModuleManager;
import com.projectkorra.projectkorra.ability.StockAbility;
import com.projectkorra.projectkorra.ability.multiability.MultiAbilityManager.MultiAbility;
import com.projectkorra.projectkorra.util.AbilityLoader;
import java.io.File;
import java.util.List;
public class MultiAbilityModuleManager {
private final AbilityLoader<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 (StockAbility a : StockAbility.values()) {
if (a.name().equalsIgnoreCase(mam.getName())) {
AbilityModuleManager.disabledStockAbilities.add(a.name());
}
}
if (mam.getElement() == Element.Air.toString())
AbilityModuleManager.airbendingabilities.add(mam.getName());
if (mam.getElement() == Element.Water.toString())
AbilityModuleManager.waterbendingabilities.add(mam.getName());
if (mam.getElement() == Element.Earth.toString())
AbilityModuleManager.earthbendingabilities.add(mam.getName());
if (mam.getElement() == Element.Fire.toString())
AbilityModuleManager.firebendingabilities.add(mam.getName());
if (mam.getElement() == Element.Chi.toString())
AbilityModuleManager.chiabilities.add(mam.getName());
AbilityModuleManager.shiftabilities.add(mam.getName());
if (mam.isHarmlessAbility())
AbilityModuleManager.harmlessabilities.add(mam.getName());
if (mam.getSubElement() != null) {
AbilityModuleManager.subabilities.add(mam.getName());
switch (mam.getSubElement()) {
case Bloodbending:
AbilityModuleManager.bloodabilities.add(mam.getName());
break;
case Combustion:
AbilityModuleManager.combustionabilities.add(mam.getName());
break;
case Flight:
AbilityModuleManager.flightabilities.add(mam.getName());
break;
case Healing:
AbilityModuleManager.healingabilities.add(mam.getName());
break;
case Icebending:
AbilityModuleManager.iceabilities.add(mam.getName());
break;
case Lavabending:
AbilityModuleManager.lavaabilities.add(mam.getName());
break;
case Lightning:
AbilityModuleManager.lightningabilities.add(mam.getName());
break;
case Metalbending:
AbilityModuleManager.metalabilities.add(mam.getName());
break;
case Plantbending:
AbilityModuleManager.plantabilities.add(mam.getName());
break;
case Sandbending:
AbilityModuleManager.sandabilities.add(mam.getName());
break;
case SpiritualProjection:
AbilityModuleManager.spiritualprojectionabilities.add(mam.getName());
break;
}
}
MultiAbilityManager.multiAbilityList.add(new MultiAbility(mam.getName(), mam.getAbilities()));
AbilityModuleManager.descriptions.put(mam.getName(), mam.getDescription());
AbilityModuleManager.authors.put(mam.getName(), mam.getAuthor());
}
}
}

View file

@ -0,0 +1,129 @@
package com.projectkorra.projectkorra.ability.util;
import sun.reflect.ReflectionFactory;
import com.projectkorra.projectkorra.event.AbilityLoadEvent;
import com.projectkorra.projectkorra.util.FileExtensionFilter;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
public class AbilityLoader<T> implements Listener {
private final Plugin plugin;
private final File directory;
private final ArrayList<File> files;
private ClassLoader loader;
public AbilityLoader(Plugin plugin, File directory) {
this.plugin = plugin;
this.directory = directory;
this.files = new ArrayList<File>();
for (File f : directory.listFiles(new FileExtensionFilter(".jar"))) {
files.add(f);
}
List<URL> urls = new ArrayList<URL>();
for (File file : files) {
try {
urls.add(file.toURI().toURL());
}
catch (MalformedURLException e) {
e.printStackTrace();
}
}
this.loader = URLClassLoader.newInstance(urls.toArray(new URL[0]), plugin.getClass().getClassLoader());
}
/**
* @param classType
* @param parentClass a parent of classType that has a visible default constructor
* @return A list of all of the T objects that were loaded from the jar files within @param directory
*/
@SuppressWarnings("unchecked")
public List<T> load(Class<?> classType, Class<?> parentClass) {
ArrayList<T> loadables = new ArrayList<>();
for (File file : files) {
JarFile jarFile = null;
try {
jarFile = new JarFile(file);
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (!entry.getName().endsWith(".class")) {
continue;
}
String className = entry.getName().replace('/', '.').substring(0, entry.getName().length() - 6);
Class<?> clazz = null;
try {
clazz = Class.forName(className, true, loader);
} catch (Exception e) {
continue;
}
if (!classType.isAssignableFrom(clazz) || clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) {
continue;
}
ReflectionFactory rf = ReflectionFactory.getReflectionFactory();
Constructor<?> objDef = parentClass.getDeclaredConstructor();
Constructor<?> intConstr = rf.newConstructorForSerialization(clazz, objDef);
T loadable = (T) clazz.cast(intConstr.newInstance());
loadables.add(loadable);
AbilityLoadEvent<T> event = new AbilityLoadEvent<T>(plugin, loadable, jarFile);
plugin.getServer().getPluginManager().callEvent(event);
}
} catch (Exception e) {
e.printStackTrace();
plugin.getLogger().log(Level.WARNING, "Unknown cause");
plugin.getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load");
} finally {
if (jarFile != null) {
try {
jarFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
return loadables;
}
public ClassLoader getLoader() {
return loader;
}
public Plugin getPlugin() {
return plugin;
}
public File getDirectory() {
return directory;
}
public ArrayList<File> getFiles() {
return files;
}
}

View file

@ -1,404 +1,427 @@
package com.projectkorra.projectkorra.ability.combo;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.airbending.AirCombo;
import com.projectkorra.projectkorra.chiblocking.ChiCombo;
import com.projectkorra.projectkorra.firebending.FireCombo;
import com.projectkorra.projectkorra.util.ClickType;
import com.projectkorra.projectkorra.waterbending.WaterCombo;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
public class ComboManager {
private static final long CLEANUP_DELAY = 20 * 600;
public static ConcurrentHashMap<String, ArrayList<AbilityInformation>> recentlyUsedAbilities = new ConcurrentHashMap<String, ArrayList<AbilityInformation>>();
public static HashMap<String, ComboAbility> comboAbilityList = new HashMap<String, ComboAbility>();
public static HashMap<String, String> authors = new HashMap<String, String>();
public static HashMap<String, String> descriptions = new HashMap<String, String>();
public static HashMap<String, String> instructions = new HashMap<String, String>();
public ComboManager() {
ArrayList<AbilityInformation> fireKick = new ArrayList<AbilityInformation>();
fireKick.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK));
fireKick.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK));
fireKick.add(new AbilityInformation("FireBlast", ClickType.SHIFT_DOWN));
fireKick.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK));
comboAbilityList.put("FireKick", new ComboAbility("FireKick", fireKick, FireCombo.class));
descriptions.put("FireKick", "A short ranged arc of fire launches from the player's feet dealing moderate damage to enemies.");
instructions.put("FireKick", "FireBlast > FireBlast > (Hold Shift) > FireBlast.");
ArrayList<AbilityInformation> fireSpin = new ArrayList<AbilityInformation>();
fireSpin.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK));
fireSpin.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK));
fireSpin.add(new AbilityInformation("FireShield", ClickType.LEFT_CLICK));
fireSpin.add(new AbilityInformation("FireShield", ClickType.SHIFT_DOWN));
fireSpin.add(new AbilityInformation("FireShield", ClickType.SHIFT_UP));
comboAbilityList.put("FireSpin", new ComboAbility("FireSpin", fireSpin, FireCombo.class));
descriptions.put("FireSpin", "A circular array of fire that causes damage and massive knockback to nearby enemies.");
instructions.put("FireSpin", "FireBlast > FireBlast > FireShield > (Tap Shift).");
ArrayList<AbilityInformation> jetBlast = new ArrayList<AbilityInformation>();
jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN));
jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP));
jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN));
jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP));
jetBlast.add(new AbilityInformation("FireShield", ClickType.SHIFT_DOWN));
jetBlast.add(new AbilityInformation("FireShield", ClickType.SHIFT_UP));
jetBlast.add(new AbilityInformation("FireJet", ClickType.LEFT_CLICK));
comboAbilityList.put("JetBlast", new ComboAbility("JetBlast", jetBlast, FireCombo.class));
descriptions.put("JetBlast", "Create an explosive blast that propels your FireJet at higher speeds.");
instructions.put("JetBlast", "FireJet (Tap Shift) > FireJet (Tap Shift) > FireShield (Tap Shift) > FireJet.");
ArrayList<AbilityInformation> jetBlaze = new ArrayList<AbilityInformation>();
jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN));
jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP));
jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN));
jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP));
jetBlaze.add(new AbilityInformation("Blaze", ClickType.SHIFT_DOWN));
jetBlaze.add(new AbilityInformation("Blaze", ClickType.SHIFT_UP));
jetBlaze.add(new AbilityInformation("FireJet", ClickType.LEFT_CLICK));
comboAbilityList.put("JetBlaze", new ComboAbility("JetBlaze", jetBlaze, FireCombo.class));
descriptions.put("JetBlaze", "Damages and burns all enemies in the proximity of your FireJet.");
instructions.put("JetBlaze", "FireJet (Tap Shift) > FireJet (Tap Shift) > Blaze (Tap Shift) > FireJet.");
ArrayList<AbilityInformation> fireWheel = new ArrayList<AbilityInformation>();
fireWheel.add(new AbilityInformation("FireShield", ClickType.SHIFT_DOWN));
fireWheel.add(new AbilityInformation("FireShield", ClickType.RIGHT_CLICK));
fireWheel.add(new AbilityInformation("FireShield", ClickType.RIGHT_CLICK));
fireWheel.add(new AbilityInformation("Blaze", ClickType.SHIFT_UP));
comboAbilityList.put("FireWheel", new ComboAbility("FireWheel", fireWheel, FireCombo.class));
descriptions.put("FireWheel", "A high-speed wheel of fire that travels along the ground for long distances dealing high damage.");
instructions.put("FireWheel", "FireShield (Hold Shift) > Right Click a block in front of you twice > Switch to Blaze > Release Shift.");
ArrayList<AbilityInformation> twister = new ArrayList<AbilityInformation>();
twister.add(new AbilityInformation("AirShield", ClickType.SHIFT_DOWN));
twister.add(new AbilityInformation("AirShield", ClickType.SHIFT_UP));
twister.add(new AbilityInformation("Tornado", ClickType.SHIFT_DOWN));
twister.add(new AbilityInformation("AirBlast", ClickType.LEFT_CLICK));
comboAbilityList.put("Twister", new ComboAbility("Twister", twister, AirCombo.class));
descriptions.put("Twister", "Create a cyclone of air that travels along the ground grabbing nearby entities.");
instructions.put("Twister", "AirShield (Tap Shift) > Tornado (Hold Shift) > AirBlast (Left Click)");
ArrayList<AbilityInformation> airStream = new ArrayList<AbilityInformation>();
airStream.add(new AbilityInformation("AirShield", ClickType.SHIFT_DOWN));
airStream.add(new AbilityInformation("AirSuction", ClickType.LEFT_CLICK));
airStream.add(new AbilityInformation("AirBlast", ClickType.LEFT_CLICK));
comboAbilityList.put("AirStream", new ComboAbility("AirStream", airStream, AirCombo.class));
descriptions.put("AirStream", "Control a large stream of air that grabs onto enemies allowing you to direct them temporarily.");
instructions.put("AirStream", "AirShield (Hold Shift) > AirSuction (Left Click) > AirBlast (Left Click)");
/*
ArrayList<AbilityInformation> airSlice = new ArrayList<AbilityInformation>();
airSlice.add(new AbilityInformation("AirBlast",ClickType.LEFT_CLICK));
airSlice.add(new AbilityInformation("AirScooter",ClickType.SHIFT_DOWN));
airSlice.add(new AbilityInformation("AirScooter",ClickType.LEFT_CLICK));
comboAbilityList.put("AirSlice", new ComboAbility("AirSlice",airSlice,AirCombo.class));
*/
ArrayList<AbilityInformation> airSweep = new ArrayList<AbilityInformation>();
airSweep.add(new AbilityInformation("AirSwipe", ClickType.LEFT_CLICK));
airSweep.add(new AbilityInformation("AirSwipe", ClickType.LEFT_CLICK));
airSweep.add(new AbilityInformation("AirBurst", ClickType.SHIFT_DOWN));
airSweep.add(new AbilityInformation("AirBurst", ClickType.LEFT_CLICK));
comboAbilityList.put("AirSweep", new ComboAbility("AirSweep", airSweep, AirCombo.class));
descriptions.put("AirSweep", "Sweep the air in front of you hitting multiple enemies, causing moderate damage and a large knockback. The radius and direction of AirSweep is controlled by moving your mouse in a sweeping motion. For example, if you want to AirSweep upward, then move your mouse upward right after you left click AirBurst");
instructions.put("AirSweep", "AirSwipe (Left Click) > AirSwipe (Left Click) > AirBurst (Hold Shift) > AirBurst (Left Click)");
ArrayList<AbilityInformation> iceWave = new ArrayList<AbilityInformation>();
iceWave.add(new AbilityInformation("WaterSpout", ClickType.SHIFT_UP));
iceWave.add(new AbilityInformation("PhaseChange", ClickType.LEFT_CLICK));
comboAbilityList.put("IceWave", new ComboAbility("IceWave", iceWave, WaterCombo.class));
descriptions.put("IceWave", "PhaseChange your WaterWave into an IceWave that freezes and damages enemies.");
instructions.put("IceWave", "Create a WaterSpout Wave > PhaseChange (Left Click)");
/*
* ArrayList<AbilityInformation> icePillar = new
* ArrayList<AbilityInformation>(); icePillar.add(new
* AbilityInformation("IceSpike", ClickType.LEFT_CLICK));
* icePillar.add(new AbilityInformation("IceSpike",
* ClickType.LEFT_CLICK)); icePillar.add(new
* AbilityInformation("WaterSpout", ClickType.LEFT_CLICK));
* comboAbilityList.put(new ComboAbility("IcePillar", icePillar,
* WaterCombo.class));
*/
ArrayList<AbilityInformation> iceBullet = new ArrayList<AbilityInformation>();
iceBullet.add(new AbilityInformation("WaterBubble", ClickType.SHIFT_DOWN));
iceBullet.add(new AbilityInformation("WaterBubble", ClickType.SHIFT_UP));
iceBullet.add(new AbilityInformation("IceBlast", ClickType.SHIFT_DOWN));
comboAbilityList.put("IceBullet", new ComboAbility("IceBullet", iceBullet, WaterCombo.class));
descriptions.put("IceBullet", "Using a large cavern of ice, you can punch ice shards at your opponent causing moderate damage. To rapid fire, you must alternate between Left clicking and right clicking with IceBlast.");
instructions.put("IceBullet", "WaterBubble (Tap Shift) > IceBlast (Hold Shift) > Wait for ice to Form > Then alternate between Left and Right click with IceBlast");
ArrayList<AbilityInformation> iceBulletLeft = new ArrayList<AbilityInformation>();
iceBulletLeft.add(new AbilityInformation("IceBlast", ClickType.LEFT_CLICK));
comboAbilityList.put("IceBulletLeftClick", new ComboAbility("IceBulletLeftClick", iceBulletLeft, WaterCombo.class));
ArrayList<AbilityInformation> iceBulletRight = new ArrayList<AbilityInformation>();
iceBulletRight.add(new AbilityInformation("IceBlast", ClickType.RIGHT_CLICK));
comboAbilityList.put("IceBulletRightClick", new ComboAbility("IceBulletRightClick", iceBulletRight, WaterCombo.class));
ArrayList<AbilityInformation> immobilize = new ArrayList<AbilityInformation>();
immobilize.add(new AbilityInformation("QuickStrike", ClickType.LEFT_CLICK));
immobilize.add(new AbilityInformation("SwiftKick", ClickType.LEFT_CLICK));
immobilize.add(new AbilityInformation("QuickStrike", ClickType.LEFT_CLICK));
immobilize.add(new AbilityInformation("QuickStrike", ClickType.LEFT_CLICK));
comboAbilityList.put("Immobilize", new ComboAbility("Immobilize", immobilize, ChiCombo.class));
descriptions.put("Immobilize", "Immobilizes the opponent for several seconds.");
instructions.put("Immobilize", "QuickStrike (Left Click) > SwiftKick (Left Click) > QuickStrike (Left Click) > QuickStrike (Left Click)");
startCleanupTask();
}
public static void addComboAbility(Player player, ClickType type) {
String abilityName = GeneralMethods.getBoundAbility(player);
if (abilityName == null)
return;
AbilityInformation info = new AbilityInformation(abilityName, type, System.currentTimeMillis());
addRecentAbility(player, info);
ComboAbility comboAbil = checkForValidCombo(player);
if (comboAbil == null) {
return;
} else if (!player.hasPermission("bending.ability." + comboAbil.getName())) {
return;
}
if (comboAbil.getComboType().equals(FireCombo.class))
new FireCombo(player, comboAbil.getName());
else if (comboAbil.getComboType().equals(AirCombo.class))
new AirCombo(player, comboAbil.getName());
else if (comboAbil.getComboType().equals(WaterCombo.class))
new WaterCombo(player, comboAbil.getName());
else if (comboAbil.getComboType().equals(ChiCombo.class))
new ChiCombo(player, comboAbil.getName());
else {
if (comboAbil.getComboType() instanceof ComboAbilityModule) {
((ComboAbilityModule) comboAbil.getComboType()).createNewComboInstance(player);
return;
}
}
}
/**
* Adds an {@link AbilityInformation} to the player's
* {@link ComboManager#recentlyUsedAbilities recentlyUsedAbilities}.
*
* @param player The player to add the AbilityInformation for
* @param info The AbilityInformation to add
*/
public static void addRecentAbility(Player player, AbilityInformation info) {
ArrayList<AbilityInformation> list;
String name = player.getName();
if (recentlyUsedAbilities.containsKey(name))
list = recentlyUsedAbilities.get(name);
else
list = new ArrayList<AbilityInformation>();
list.add(info);
recentlyUsedAbilities.put(name, list);
//Bukkit.broadcastMessage("recentlyUsedAbilities: " + recentlyUsedAbilities.get(name).size());
}
/**
* Checks if a Player's {@link ComboManager#recentlyUsedAbilities
* recentlyUsedAbilities} contains a valid set of moves to perform any
* combos. If it does, it returns the valid combo.
*
* @param player The player for whom to check if a valid combo has been
* performed
* @return The ComboAbility of the combo that has been performed, or null if
* no valid combo was found
*/
public static ComboAbility checkForValidCombo(Player player) {
ArrayList<AbilityInformation> playerCombo = getRecentlyUsedAbilities(player, 8);
for (String ability : comboAbilityList.keySet()) {
ComboAbility customAbility = comboAbilityList.get(ability);
ArrayList<AbilityInformation> abilityCombo = customAbility.getAbilities();
int size = abilityCombo.size();
if (playerCombo.size() < size)
continue;
boolean isValid = true;
for (int i = 1; i <= size; i++) {
if (!playerCombo.get(playerCombo.size() - i).equalsWithoutTime(abilityCombo.get(abilityCombo.size() - i))) {
isValid = false;
break;
}
}
if (isValid)
return customAbility;
}
return null;
}
public static void cleanupOldCombos() {
recentlyUsedAbilities.clear();
}
/**
* Gets the player's most recently used abilities, up to a maximum of 10.
*
* @param player The player to get recent abilities for
* @param amount The amount of recent abilities to get, starting from most
* recent and getting older
* @return An ArrayList<{@link AbilityInformation}> of the player's recently
* used abilities
*/
public static ArrayList<AbilityInformation> getRecentlyUsedAbilities(Player player, int amount) {
String name = player.getName();
if (!recentlyUsedAbilities.containsKey(name))
return new ArrayList<AbilityInformation>();
ArrayList<AbilityInformation> list = recentlyUsedAbilities.get(name);
if (list.size() < amount)
return new ArrayList<AbilityInformation>(list);
ArrayList<AbilityInformation> tempList = new ArrayList<AbilityInformation>();
for (int i = 0; i < amount; i++)
tempList.add(0, list.get(list.size() - 1 - i));
return tempList;
}
/**
* Gets all of the combos for a given element.
*
* @param element The element to get combos for
* @return An ArrayList of the combos for that element
*/
public static ArrayList<String> getCombosForElement(Element element) {
ArrayList<String> list = new ArrayList<String>();
for (String comboab : descriptions.keySet()) {
if (GeneralMethods.getAbilityElement(comboAbilityList.get(comboab).getAbilities().get(0).getAbilityName()) == element)
list.add(comboab);
}
Collections.sort(list);
return list;
}
public static void startCleanupTask() {
new BukkitRunnable() {
public void run() {
cleanupOldCombos();
}
}.runTaskTimer(ProjectKorra.plugin, 0, CLEANUP_DELAY);
}
/**
* Contains information on an ability used in a combo.
*
* @author kingbirdy
*
*/
public static class AbilityInformation {
private String abilityName;
private ClickType clickType;
private long time;
public AbilityInformation(String name, ClickType type) {
this(name, type, 0);
}
public AbilityInformation(String name, ClickType type, long time) {
this.abilityName = name;
this.clickType = type;
this.time = time;
}
/**
* Compares if two {@link AbilityInformation}'s are equal without
* respect to {@link AbilityInformation#time time}.
*
* @param info The AbilityInformation to compare against
* @return True if they are equal without respect to time
*/
public boolean equalsWithoutTime(AbilityInformation info) {
return this.getAbilityName().equals(info.getAbilityName()) && this.getClickType().equals(info.getClickType());
}
/**
* Gets the name of the ability.
*
* @return The name of the ability.
*/
public String getAbilityName() {
return abilityName;
}
/**
* Gets the {@link ClickType} of the {@link AbilityInformation}.
*
* @return The ClickType
*/
public ClickType getClickType() {
return clickType;
}
public long getTime() {
return time;
}
public void setAbilityName(String abilityName) {
this.abilityName = abilityName;
}
public void setClickType(ClickType clickType) {
this.clickType = clickType;
}
public void setTime(long time) {
this.time = time;
}
public String toString() {
return abilityName + " " + clickType + " " + time;
}
}
public static class ComboAbility {
private String name;
private ArrayList<AbilityInformation> abilities;
private Object comboType;
public ComboAbility(String name, ArrayList<AbilityInformation> abilities, Object comboType) {
this.name = name;
this.abilities = abilities;
this.comboType = comboType;
}
public ArrayList<AbilityInformation> getAbilities() {
return abilities;
}
public Object getComboType() {
return comboType;
}
public String getName() {
return name;
}
public void setAbilities(ArrayList<AbilityInformation> abilities) {
this.abilities = abilities;
}
public void setComboType(Object comboType) {
this.comboType = comboType;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return name;
}
}
}
package com.projectkorra.projectkorra.ability.util;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.ComboAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.airbending.AirCombo;
import com.projectkorra.projectkorra.chiblocking.ChiCombo;
import com.projectkorra.projectkorra.firebending.FireCombo;
import com.projectkorra.projectkorra.util.ClickType;
import com.projectkorra.projectkorra.waterbending.WaterCombo;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
public class ComboManager {
private static final long CLEANUP_DELAY = 20 * 600;
private static final ConcurrentHashMap<String, ArrayList<AbilityInformation>> RECENTLY_USED = new ConcurrentHashMap<>();
private static final HashMap<String, ComboAbilityInfo> COMBO_ABILITIES = new HashMap<>();
private static final HashMap<String, String> AUTHORS = new HashMap<>();
private static final HashMap<String, String> DESCRIPTIONS = new HashMap<>();
private static final HashMap<String, String> INSTRUCTIONS = new HashMap<>();
public ComboManager() {
ArrayList<AbilityInformation> fireKick = new ArrayList<>();
fireKick.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK));
fireKick.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK));
fireKick.add(new AbilityInformation("FireBlast", ClickType.SHIFT_DOWN));
fireKick.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK));
COMBO_ABILITIES.put("FireKick", new ComboAbilityInfo("FireKick", fireKick, FireCombo.class));
DESCRIPTIONS.put("FireKick", "A short ranged arc of fire launches from the player's feet dealing moderate damage to enemies.");
INSTRUCTIONS.put("FireKick", "FireBlast > FireBlast > (Hold Shift) > FireBlast.");
ArrayList<AbilityInformation> fireSpin = new ArrayList<>();
fireSpin.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK));
fireSpin.add(new AbilityInformation("FireBlast", ClickType.LEFT_CLICK));
fireSpin.add(new AbilityInformation("FireShield", ClickType.LEFT_CLICK));
fireSpin.add(new AbilityInformation("FireShield", ClickType.SHIFT_DOWN));
fireSpin.add(new AbilityInformation("FireShield", ClickType.SHIFT_UP));
COMBO_ABILITIES.put("FireSpin", new ComboAbilityInfo("FireSpin", fireSpin, FireCombo.class));
DESCRIPTIONS.put("FireSpin", "A circular array of fire that causes damage and massive knockback to nearby enemies.");
INSTRUCTIONS.put("FireSpin", "FireBlast > FireBlast > FireShield > (Tap Shift).");
ArrayList<AbilityInformation> jetBlast = new ArrayList<>();
jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN));
jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP));
jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN));
jetBlast.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP));
jetBlast.add(new AbilityInformation("FireShield", ClickType.SHIFT_DOWN));
jetBlast.add(new AbilityInformation("FireShield", ClickType.SHIFT_UP));
jetBlast.add(new AbilityInformation("FireJet", ClickType.LEFT_CLICK));
COMBO_ABILITIES.put("JetBlast", new ComboAbilityInfo("JetBlast", jetBlast, FireCombo.class));
DESCRIPTIONS.put("JetBlast", "Create an explosive blast that propels your FireJet at higher speeds.");
INSTRUCTIONS.put("JetBlast", "FireJet (Tap Shift) > FireJet (Tap Shift) > FireShield (Tap Shift) > FireJet.");
ArrayList<AbilityInformation> jetBlaze = new ArrayList<>();
jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN));
jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP));
jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_DOWN));
jetBlaze.add(new AbilityInformation("FireJet", ClickType.SHIFT_UP));
jetBlaze.add(new AbilityInformation("Blaze", ClickType.SHIFT_DOWN));
jetBlaze.add(new AbilityInformation("Blaze", ClickType.SHIFT_UP));
jetBlaze.add(new AbilityInformation("FireJet", ClickType.LEFT_CLICK));
COMBO_ABILITIES.put("JetBlaze", new ComboAbilityInfo("JetBlaze", jetBlaze, FireCombo.class));
DESCRIPTIONS.put("JetBlaze", "Damages and burns all enemies in the proximity of your FireJet.");
INSTRUCTIONS.put("JetBlaze", "FireJet (Tap Shift) > FireJet (Tap Shift) > Blaze (Tap Shift) > FireJet.");
ArrayList<AbilityInformation> fireWheel = new ArrayList<>();
fireWheel.add(new AbilityInformation("FireShield", ClickType.SHIFT_DOWN));
fireWheel.add(new AbilityInformation("FireShield", ClickType.RIGHT_CLICK));
fireWheel.add(new AbilityInformation("FireShield", ClickType.RIGHT_CLICK));
fireWheel.add(new AbilityInformation("Blaze", ClickType.SHIFT_UP));
COMBO_ABILITIES.put("FireWheel", new ComboAbilityInfo("FireWheel", fireWheel, FireCombo.class));
DESCRIPTIONS.put("FireWheel", "A high-speed wheel of fire that travels along the ground for long distances dealing high damage.");
INSTRUCTIONS.put("FireWheel", "FireShield (Hold Shift) > Right Click a block in front of you twice > Switch to Blaze > Release Shift.");
ArrayList<AbilityInformation> twister = new ArrayList<AbilityInformation>();
twister.add(new AbilityInformation("AirShield", ClickType.SHIFT_DOWN));
twister.add(new AbilityInformation("AirShield", ClickType.SHIFT_UP));
twister.add(new AbilityInformation("Tornado", ClickType.SHIFT_DOWN));
twister.add(new AbilityInformation("AirBlast", ClickType.LEFT_CLICK));
COMBO_ABILITIES.put("Twister", new ComboAbilityInfo("Twister", twister, AirCombo.class));
DESCRIPTIONS.put("Twister", "Create a cyclone of air that travels along the ground grabbing nearby entities.");
INSTRUCTIONS.put("Twister", "AirShield (Tap Shift) > Tornado (Hold Shift) > AirBlast (Left Click)");
ArrayList<AbilityInformation> airStream = new ArrayList<>();
airStream.add(new AbilityInformation("AirShield", ClickType.SHIFT_DOWN));
airStream.add(new AbilityInformation("AirSuction", ClickType.LEFT_CLICK));
airStream.add(new AbilityInformation("AirBlast", ClickType.LEFT_CLICK));
COMBO_ABILITIES.put("AirStream", new ComboAbilityInfo("AirStream", airStream, AirCombo.class));
DESCRIPTIONS.put("AirStream", "Control a large stream of air that grabs onto enemies allowing you to direct them temporarily.");
INSTRUCTIONS.put("AirStream", "AirShield (Hold Shift) > AirSuction (Left Click) > AirBlast (Left Click)");
ArrayList<AbilityInformation> airSweep = new ArrayList<>();
airSweep.add(new AbilityInformation("AirSwipe", ClickType.LEFT_CLICK));
airSweep.add(new AbilityInformation("AirSwipe", ClickType.LEFT_CLICK));
airSweep.add(new AbilityInformation("AirBurst", ClickType.SHIFT_DOWN));
airSweep.add(new AbilityInformation("AirBurst", ClickType.LEFT_CLICK));
COMBO_ABILITIES.put("AirSweep", new ComboAbilityInfo("AirSweep", airSweep, AirCombo.class));
DESCRIPTIONS.put("AirSweep", "Sweep the air in front of you hitting multiple enemies, causing moderate damage and a large knockback. The radius and direction of AirSweep is controlled by moving your mouse in a sweeping motion. For example, if you want to AirSweep upward, then move your mouse upward right after you left click AirBurst");
INSTRUCTIONS.put("AirSweep", "AirSwipe (Left Click) > AirSwipe (Left Click) > AirBurst (Hold Shift) > AirBurst (Left Click)");
ArrayList<AbilityInformation> iceWave = new ArrayList<>();
iceWave.add(new AbilityInformation("WaterSpout", ClickType.SHIFT_UP));
iceWave.add(new AbilityInformation("PhaseChange", ClickType.LEFT_CLICK));
COMBO_ABILITIES.put("IceWave", new ComboAbilityInfo("IceWave", iceWave, WaterCombo.class));
DESCRIPTIONS.put("IceWave", "PhaseChange your WaterWave into an IceWave that freezes and damages enemies.");
INSTRUCTIONS.put("IceWave", "Create a WaterSpout Wave > PhaseChange (Left Click)");
ArrayList<AbilityInformation> iceBullet = new ArrayList<>();
iceBullet.add(new AbilityInformation("WaterBubble", ClickType.SHIFT_DOWN));
iceBullet.add(new AbilityInformation("WaterBubble", ClickType.SHIFT_UP));
iceBullet.add(new AbilityInformation("IceBlast", ClickType.SHIFT_DOWN));
COMBO_ABILITIES.put("IceBullet", new ComboAbilityInfo("IceBullet", iceBullet, WaterCombo.class));
DESCRIPTIONS.put("IceBullet", "Using a large cavern of ice, you can punch ice shards at your opponent causing moderate damage. To rapid fire, you must alternate between Left clicking and right clicking with IceBlast.");
INSTRUCTIONS.put("IceBullet", "WaterBubble (Tap Shift) > IceBlast (Hold Shift) > Wait for ice to Form > Then alternate between Left and Right click with IceBlast");
ArrayList<AbilityInformation> iceBulletLeft = new ArrayList<>();
iceBulletLeft.add(new AbilityInformation("IceBlast", ClickType.LEFT_CLICK));
COMBO_ABILITIES.put("IceBulletLeftClick", new ComboAbilityInfo("IceBulletLeftClick", iceBulletLeft, WaterCombo.class));
ArrayList<AbilityInformation> iceBulletRight = new ArrayList<>();
iceBulletRight.add(new AbilityInformation("IceBlast", ClickType.RIGHT_CLICK));
COMBO_ABILITIES.put("IceBulletRightClick", new ComboAbilityInfo("IceBulletRightClick", iceBulletRight, WaterCombo.class));
ArrayList<AbilityInformation> immobilize = new ArrayList<>();
immobilize.add(new AbilityInformation("QuickStrike", ClickType.LEFT_CLICK));
immobilize.add(new AbilityInformation("SwiftKick", ClickType.LEFT_CLICK));
immobilize.add(new AbilityInformation("QuickStrike", ClickType.LEFT_CLICK));
immobilize.add(new AbilityInformation("QuickStrike", ClickType.LEFT_CLICK));
COMBO_ABILITIES.put("Immobilize", new ComboAbilityInfo("Immobilize", immobilize, ChiCombo.class));
DESCRIPTIONS.put("Immobilize", "Immobilizes the opponent for several seconds.");
INSTRUCTIONS.put("Immobilize", "QuickStrike (Left Click) > SwiftKick (Left Click) > QuickStrike (Left Click) > QuickStrike (Left Click)");
startCleanupTask();
}
public static void addComboAbility(Player player, ClickType type) {
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
return;
}
String abilityName = bPlayer.getBoundAbilityName();
if (abilityName == null) {
return;
}
AbilityInformation info = new AbilityInformation(abilityName, type, System.currentTimeMillis());
addRecentAbility(player, info);
ComboAbilityInfo comboAbil = checkForValidCombo(player);
if (comboAbil == null) {
return;
} else if (!player.hasPermission("bending.ability." + comboAbil.getName())) {
return;
}
if (comboAbil.getComboType().equals(FireCombo.class)) {
new FireCombo(player, comboAbil.getName());
} else if (comboAbil.getComboType().equals(AirCombo.class)) {
new AirCombo(player, comboAbil.getName());
} else if (comboAbil.getComboType().equals(WaterCombo.class)) {
new WaterCombo(player, comboAbil.getName());
} else if (comboAbil.getComboType().equals(ChiCombo.class)) {
new ChiCombo(player, comboAbil.getName());
} else {
if (comboAbil.getComboType() instanceof ComboAbility) {
((ComboAbility) comboAbil.getComboType()).createNewComboInstance(player);
return;
}
}
}
/**
* Adds an {@link AbilityInformation} to the player's
* {@link ComboManager#RECENTLY_USED recentlyUsedAbilities}.
*
* @param player The player to add the AbilityInformation for
* @param info The AbilityInformation to add
*/
public static void addRecentAbility(Player player, AbilityInformation info) {
ArrayList<AbilityInformation> list;
String name = player.getName();
if (RECENTLY_USED.containsKey(name)) {
list = RECENTLY_USED.get(name);
} else {
list = new ArrayList<AbilityInformation>();
}
list.add(info);
RECENTLY_USED.put(name, list);
//Bukkit.broadcastMessage("recentlyUsedAbilities: " + recentlyUsedAbilities.get(name).size());
}
/**
* Checks if a Player's {@link ComboManager#RECENTLY_USED
* recentlyUsedAbilities} contains a valid set of moves to perform any
* combos. If it does, it returns the valid combo.
*
* @param player The player for whom to check if a valid combo has been
* performed
* @return The ComboAbility of the combo that has been performed, or null if
* no valid combo was found
*/
public static ComboAbilityInfo checkForValidCombo(Player player) {
ArrayList<AbilityInformation> playerCombo = getRecentlyUsedAbilities(player, 8);
for (String ability : COMBO_ABILITIES.keySet()) {
ComboAbilityInfo customAbility = COMBO_ABILITIES.get(ability);
ArrayList<AbilityInformation> abilityCombo = customAbility.getAbilities();
int size = abilityCombo.size();
if (playerCombo.size() < size) {
continue;
}
boolean isValid = true;
for (int i = 1; i <= size; i++) {
if (!playerCombo.get(playerCombo.size() - i).equalsWithoutTime(abilityCombo.get(abilityCombo.size() - i))) {
isValid = false;
break;
}
}
if (isValid) {
return customAbility;
}
}
return null;
}
public static void cleanupOldCombos() {
RECENTLY_USED.clear();
}
/**
* Gets the player's most recently used abilities, up to a maximum of 10.
*
* @param player The player to get recent abilities for
* @param amount The amount of recent abilities to get, starting from most
* recent and getting older
* @return An ArrayList<{@link AbilityInformation}> of the player's recently
* used abilities
*/
public static ArrayList<AbilityInformation> getRecentlyUsedAbilities(Player player, int amount) {
String name = player.getName();
if (!RECENTLY_USED.containsKey(name)) {
return new ArrayList<AbilityInformation>();
}
ArrayList<AbilityInformation> list = RECENTLY_USED.get(name);
if (list.size() < amount) {
return new ArrayList<AbilityInformation>(list);
}
ArrayList<AbilityInformation> tempList = new ArrayList<AbilityInformation>();
for (int i = 0; i < amount; i++) {
tempList.add(0, list.get(list.size() - 1 - i));
}
return tempList;
}
/**
* Gets all of the combos for a given element.
*
* @param element The element to get combos for
* @return An ArrayList of the combos for that element
*/
public static ArrayList<String> getCombosForElement(Element element) {
ArrayList<String> list = new ArrayList<String>();
for (String comboab : DESCRIPTIONS.keySet()) {
CoreAbility coreAbil = CoreAbility.getAbility(COMBO_ABILITIES.get(comboab).getAbilities().get(0).getAbilityName());
if (coreAbil != null && coreAbil.getElement() == element) {
list.add(comboab);
}
}
Collections.sort(list);
return list;
}
public static void startCleanupTask() {
new BukkitRunnable() {
@Override
public void run() {
cleanupOldCombos();
}
}.runTaskTimer(ProjectKorra.plugin, 0, CLEANUP_DELAY);
}
public static long getCleanupDelay() {
return CLEANUP_DELAY;
}
public static HashMap<String, ComboAbilityInfo> getComboAbilities() {
return COMBO_ABILITIES;
}
public static HashMap<String, String> getAuthors() {
return AUTHORS;
}
public static HashMap<String, String> getDescriptions() {
return DESCRIPTIONS;
}
public static HashMap<String, String> getInstructions() {
return INSTRUCTIONS;
}
/**
* Contains information on an ability used in a combo.
*
* @author kingbirdy
*
*/
public static class AbilityInformation {
private String abilityName;
private ClickType clickType;
private long time;
public AbilityInformation(String name, ClickType type) {
this(name, type, 0);
}
public AbilityInformation(String name, ClickType type, long time) {
this.abilityName = name;
this.clickType = type;
this.time = time;
}
/**
* Compares if two {@link AbilityInformation}'s are equal without
* respect to {@link AbilityInformation#time time}.
*
* @param info The AbilityInformation to compare against
* @return True if they are equal without respect to time
*/
public boolean equalsWithoutTime(AbilityInformation info) {
return this.getAbilityName().equals(info.getAbilityName()) && this.getClickType().equals(info.getClickType());
}
/**
* Gets the name of the ability.
*
* @return The name of the ability.
*/
public String getAbilityName() {
return abilityName;
}
/**
* Gets the {@link ClickType} of the {@link AbilityInformation}.
*
* @return The ClickType
*/
public ClickType getClickType() {
return clickType;
}
public long getTime() {
return time;
}
public void setAbilityName(String abilityName) {
this.abilityName = abilityName;
}
public void setClickType(ClickType clickType) {
this.clickType = clickType;
}
public void setTime(long time) {
this.time = time;
}
@Override
public String toString() {
return abilityName + " " + clickType + " " + time;
}
}
public static class ComboAbilityInfo {
private String name;
private ArrayList<AbilityInformation> abilities;
private Object comboType;
public ComboAbilityInfo(String name, ArrayList<AbilityInformation> abilities, Object comboType) {
this.name = name;
this.abilities = abilities;
this.comboType = comboType;
}
public ArrayList<AbilityInformation> getAbilities() {
return abilities;
}
public Object getComboType() {
return comboType;
}
public String getName() {
return name;
}
public void setAbilities(ArrayList<AbilityInformation> abilities) {
this.abilities = abilities;
}
public void setComboType(Object comboType) {
this.comboType = comboType;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
}

View file

@ -1,315 +1,286 @@
package com.projectkorra.projectkorra.ability.multiability;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.SubElement;
import com.projectkorra.projectkorra.airbending.AirMethods;
import com.projectkorra.projectkorra.chiblocking.ChiMethods;
import com.projectkorra.projectkorra.earthbending.EarthMethods;
import com.projectkorra.projectkorra.firebending.FireMethods;
import com.projectkorra.projectkorra.waterbending.WaterMethods;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
public class MultiAbilityManager {
public static ConcurrentHashMap<Player, HashMap<Integer, String>> playerAbilities = new ConcurrentHashMap<>();
public static ConcurrentHashMap<Player, Integer> playerSlot = new ConcurrentHashMap<>();
public static ConcurrentHashMap<Player, String> playerBoundAbility = new ConcurrentHashMap<>();
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();
}
/**
* 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);
}
}
/**
* Returns the MultiAbility the player has bound. Returns null if no
* multiability is bound and active.
*
* @param player The player to use
* @return name of multi ability bounded
*/
public static String getBoundMultiAbility(Player player) {
if (playerBoundAbility.containsKey(player))
return playerBoundAbility.get(player);
return null;
}
/**
* Returns a MultiAbility based on name.
*
* @param multiAbility Name of the multiability
* @return the multiability object or null
*/
public static MultiAbility getMultiAbility(String multiAbility) {
for (MultiAbility ma : multiAbilityList) {
if (ma.getName().equalsIgnoreCase(multiAbility))
return ma;
}
return null;
}
/**
* Returns a boolean based on whether a player has a MultiAbility active.
*
* @param player The player to check
* @return true If player has a multiability active
*/
public static boolean hasMultiAbilityBound(Player player) {
if (playerAbilities.containsKey(player))
return true;
return false;
}
/**
* MultiAbility equivalent of {@link GeneralMethods#getBoundAbility(Player)}. Returns a
* boolean based on whether a player has a specific MultiAbility active.
*
* @param player The player to check
* @param multiAbility The multiability name
* @return true If player has the specified multiability active
*/
public static boolean hasMultiAbilityBound(Player player, String multiAbility) {
if (playerAbilities.containsKey(player)) {
if (!playerBoundAbility.get(player).equals(multiAbility) && GeneralMethods.getBoundAbility(player) != null)
return false;
return true;
}
return false;
}
public static void manage() {
new BukkitRunnable() {
public void run() {
scrollHotBarSlots();
}
}.runTaskTimer(ProjectKorra.plugin, 0, 1);
}
/**
* Clears all MultiAbility data for a player. Called on player quit event.
*
* @param player
*/
public static void remove(Player player) {
playerAbilities.remove(player);
playerBoundAbility.remove(player);
playerSlot.remove(player);
}
/**
* Cleans up all MultiAbilities.
*/
public static void removeAll() {
List<MultiAbilityModule> abilities = MultiAbilityModuleManager.multiAbility;
for (MultiAbilityModule mam : abilities)
mam.stop();
playerAbilities.clear();
playerSlot.clear();
playerBoundAbility.clear();
}
/**
* Keeps track of the player's selected slot while a MultiAbility is active.
*/
public static void scrollHotBarSlots() {
if (!playerAbilities.isEmpty()) {
for (Player player : playerAbilities.keySet()) {
if (playerBoundAbility.containsKey(player)) {
if (GeneralMethods.getBoundAbility(player) == null) {
if (multiAbilityList.contains(getMultiAbility(playerBoundAbility.get(player)))) {
if (player.getInventory().getHeldItemSlot() > getMultiAbility(playerBoundAbility.get(player)).getAbilities().size()) {
player.getInventory().setHeldItemSlot(getMultiAbility(playerBoundAbility.get(player)).getAbilities().size() - 1);
} else {
player.getInventory().setHeldItemSlot(0);
}
}
}
}
}
}
}
/**
* Reverts a player's binds to a previous state before use of a
* MultiAbility.
*
* @param player
*/
public static void unbindMultiAbility(Player player) {
if (playerAbilities.containsKey(player)) {
HashMap<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 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 ArrayList<MultiAbilitySub> getAbilities() {
return abilities;
}
public String getName() {
return name;
}
public void setAbilities(ArrayList<MultiAbilitySub> abilities) {
this.abilities = abilities;
}
public void setName(String name) {
this.name = name;
}
}
public static class MultiAbilitySub {
private String name;
private Element element;
private SubElement sub;
public MultiAbilitySub(String name, Element element, SubElement sub) {
this.name = name;
this.element = element;
this.sub = sub;
}
public Element getElement() {
return element;
}
public String getName() {
return name;
}
public SubElement getSubElement() {
return sub;
}
public void setElement(Element element) {
this.element = element;
}
public void setName(String name) {
this.name = name;
}
public void setSubElement(SubElement sub) {
this.sub = sub;
}
public ChatColor getAbilityColor() {
if (element == null) {
return GeneralMethods.getAvatarColor();
}
if (sub == null) {
switch (element) {
case Air:
return AirMethods.getAirColor();
case Water:
return WaterMethods.getWaterColor();
case Fire:
return FireMethods.getFireColor();
case Earth:
return EarthMethods.getEarthColor();
case Chi:
return ChiMethods.getChiColor();
default:
return GeneralMethods.getAvatarColor();
}
} else {
return GeneralMethods.getSubBendingColor(element);
}
}
}
}
package com.projectkorra.projectkorra.ability.util;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
public class MultiAbilityManager {
public static ConcurrentHashMap<Player, HashMap<Integer, String>> playerAbilities = new ConcurrentHashMap<>();
public static ConcurrentHashMap<Player, Integer> playerSlot = new ConcurrentHashMap<>();
public static ConcurrentHashMap<Player, String> playerBoundAbility = new ConcurrentHashMap<>();
public static ArrayList<MultiAbilityInfo> multiAbilityList = new ArrayList<MultiAbilityInfo>();
public MultiAbilityManager() {
ArrayList<MultiAbilityInfoSub> waterArms = new ArrayList<MultiAbilityInfoSub>();
waterArms.add(new MultiAbilityInfoSub("Pull", Element.WATER));
waterArms.add(new MultiAbilityInfoSub("Punch", Element.WATER));
waterArms.add(new MultiAbilityInfoSub("Grapple", Element.WATER));
waterArms.add(new MultiAbilityInfoSub("Grab", Element.WATER));
waterArms.add(new MultiAbilityInfoSub("Freeze", Element.ICE));
waterArms.add(new MultiAbilityInfoSub("Spear", Element.ICE));
multiAbilityList.add(new MultiAbilityInfo("WaterArms", waterArms));
manage();
}
/**
* Sets up a player's binds for a MultiAbility.
*
* @param player
* @param multiAbility
*/
public static void bindMultiAbility(Player player, String multiAbility) {
if (playerAbilities.containsKey(player))
unbindMultiAbility(player);
playerSlot.put(player, player.getInventory().getHeldItemSlot());
playerBoundAbility.put(player, multiAbility);
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
HashMap<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<MultiAbilityInfoSub> modes = getMultiAbility(multiAbility).getAbilities();
bPlayer.getAbilities().clear();
for (int i = 0; i < modes.size(); i++) {
if (!player.hasPermission("bending.ability." + multiAbility + "." + modes.get(i).getName())) {
bPlayer.getAbilities().put(i + 1, new StringBuilder().append(modes.get(i).getAbilityColor()).append(ChatColor.STRIKETHROUGH).append(modes.get(i).getName()).toString());
} else {
bPlayer.getAbilities().put(i + 1, modes.get(i).getAbilityColor() + modes.get(i).getName());
}
}
if (player.isOnline()) {
bPlayer.addCooldown("MAM_Setup", 1L); // Support for bending
// scoreboards.
player.getInventory().setHeldItemSlot(0);
}
}
/**
* Returns the MultiAbility the player has bound. Returns null if no
* multiability is bound and active.
*
* @param player The player to use
* @return name of multi ability bounded
*/
public static String getBoundMultiAbility(Player player) {
if (playerBoundAbility.containsKey(player))
return playerBoundAbility.get(player);
return null;
}
/**
* Returns a MultiAbility based on name.
*
* @param multiAbility Name of the multiability
* @return the multiability object or null
*/
public static MultiAbilityInfo getMultiAbility(String multiAbility) {
for (MultiAbilityInfo ma : multiAbilityList) {
if (ma.getName().equalsIgnoreCase(multiAbility))
return ma;
}
return null;
}
/**
* Returns a boolean based on whether a player has a MultiAbility active.
*
* @param player The player to check
* @return true If player has a multiability active
*/
public static boolean hasMultiAbilityBound(Player player) {
if (playerAbilities.containsKey(player))
return true;
return false;
}
/**
* MultiAbility equivalent of {@link GeneralMethods#getBoundAbility(Player)}. Returns a
* boolean based on whether a player has a specific MultiAbility active.
*
* @param player The player to check
* @param multiAbility The multiability name
* @return true If player has the specified multiability active
*/
public static boolean hasMultiAbilityBound(Player player, String multiAbility) {
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
return false;
}
if (playerAbilities.containsKey(player)) {
if (!playerBoundAbility.get(player).equals(multiAbility) && bPlayer.getBoundAbility() != null)
return false;
return true;
}
return false;
}
public static void manage() {
new BukkitRunnable() {
public void run() {
scrollHotBarSlots();
}
}.runTaskTimer(ProjectKorra.plugin, 0, 1);
}
/**
* Clears all MultiAbility data for a player. Called on player quit event.
*
* @param player
*/
public static void remove(Player player) {
playerAbilities.remove(player);
playerBoundAbility.remove(player);
playerSlot.remove(player);
}
/**
* Cleans up all MultiAbilities.
*/
public static void removeAll() {
playerAbilities.clear();
playerSlot.clear();
playerBoundAbility.clear();
}
/**
* Keeps track of the player's selected slot while a MultiAbility is active.
*/
public static void scrollHotBarSlots() {
if (!playerAbilities.isEmpty()) {
for (Player player : playerAbilities.keySet()) {
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
continue;
}
if (playerBoundAbility.containsKey(player)) {
if (bPlayer.getBoundAbility() == null) {
if (multiAbilityList.contains(getMultiAbility(playerBoundAbility.get(player)))) {
if (player.getInventory().getHeldItemSlot() >= getMultiAbility(playerBoundAbility.get(player)).getAbilities().size()) {
player.getInventory().setHeldItemSlot(getMultiAbility(playerBoundAbility.get(player)).getAbilities().size() - 1);
}
}
}
}
}
}
}
/**
* Reverts a player's binds to a previous state before use of a
* MultiAbility.
*
* @param player
*/
public static void unbindMultiAbility(Player player) {
if (playerAbilities.containsKey(player)) {
HashMap<Integer, String> prevBinds = playerAbilities.get(player);
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
return;
}
int lastNonNull = -1;
for (int i = 1; i < 10; i++) {
if (prevBinds.get(i) != null)
lastNonNull = i;
bPlayer.getAbilities().put(i, prevBinds.get(i));
}
if (lastNonNull > -1)
GeneralMethods.saveAbility(bPlayer, lastNonNull, prevBinds.get(lastNonNull));
if (player.isOnline())
bPlayer.addCooldown("MAM_Setup", 1L); // Support for bending
// scoreboards.
playerAbilities.remove(player);
}
if (playerSlot.containsKey(player)) {
if (player.isOnline())
player.getInventory().setHeldItemSlot(playerSlot.get(player));
playerSlot.remove(player);
} else {
if (player.isOnline())
player.getInventory().setHeldItemSlot(0);
}
if (playerBoundAbility.containsKey(player))
playerBoundAbility.remove(player);
}
/**
* MultiAbility class. Manages each MultiAbility's sub abilities.
*
*/
public static class MultiAbilityInfo {
private String name;
private ArrayList<MultiAbilityInfoSub> abilities;
public MultiAbilityInfo(String name, ArrayList<MultiAbilityInfoSub> abilities) {
this.name = name;
this.abilities = abilities;
}
public ArrayList<MultiAbilityInfoSub> getAbilities() {
return abilities;
}
public String getName() {
return name;
}
public void setAbilities(ArrayList<MultiAbilityInfoSub> abilities) {
this.abilities = abilities;
}
public void setName(String name) {
this.name = name;
}
}
public static class MultiAbilityInfoSub {
private String name;
private Element element;
public MultiAbilityInfoSub(String name, Element element) {
this.name = name;
this.element = element;
}
public Element getElement() {
return element;
}
public String getName() {
return name;
}
public void setElement(Element element) {
this.element = element;
}
public void setName(String name) {
this.name = name;
}
public ChatColor getAbilityColor() {
return element != null ? element.getColor() : null;
}
}
}

View file

@ -4,9 +4,10 @@ import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AvatarState;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.avatar.AvatarState;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
import com.projectkorra.projectkorra.object.HorizontalVelocityTracker;
import com.projectkorra.projectkorra.util.Flight;
@ -27,191 +28,184 @@ import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
public class AirBlast implements ConfigLoadable {
public static ConcurrentHashMap<Integer, AirBlast> instances = new ConcurrentHashMap<>();
private static ConcurrentHashMap<Player, Location> origins = new ConcurrentHashMap<Player, Location>();
public class AirBlast extends AirAbility {
public static double speed = config.get().getDouble("Abilities.Air.AirBlast.Speed");
public static double defaultrange = config.get().getDouble("Abilities.Air.AirBlast.Range");
public static double affectingradius = config.get().getDouble("Abilities.Air.AirBlast.Radius");
public static double defaultpushfactor = config.get().getDouble("Abilities.Air.AirBlast.Push.Entities");
public static double otherpushfactor = config.get().getDouble("Abilities.Air.AirBlast.Push.Self");
private static final int MAX_TICKS = 10000;
private static final int ORIGIN_PARTICLE_COUNT = 4;
private static final double ORIGIN_SELECT_RANGE = 10;
private static final ConcurrentHashMap<Player, Location> ORIGINS = new ConcurrentHashMap<>();
public static boolean flickLevers = config.get().getBoolean("Abilities.Air.AirBlast.CanFlickLevers");
public static boolean openDoors = config.get().getBoolean("Abilities.Air.AirBlast.CanOpenDoors");
public static boolean pressButtons = config.get().getBoolean("Abilities.Air.AirBlast.CanPressButtons");
public static boolean coolLava = config.get().getBoolean("Abilities.Air.AirBlast.CanCoolLava");
private static double originselectrange = 10;
private static int idCounter = 0;
private static final int maxticks = 10000;
/* Package visible variables */
static double maxspeed = 1. / defaultpushfactor;
/* End Package visible variables */
// public static long interval = 2000;
public static byte full = 0x0;
Location location;
private boolean canFlickLevers;
private boolean canOpenDoors;
private boolean canPressButtons;
private boolean canCoolLava;
private boolean isFromOtherOrigin;
private boolean showParticles;
private int ticks;
private int particleCount;
private long cooldown;
private double speedFactor;
private double range;
private double pushFactor;
private double pushFactorForOthers;
private double damage;
private double speed;
private double radius;
private Location location;
private Location origin;
private Vector direction;
private Player player;
private double speedfactor;
private double range = defaultrange;
private double pushfactor = defaultpushfactor;
private double damage = 0;
private boolean otherorigin = false;
private boolean showParticles = true;
private int ticks = 0;
private int id = 0;
private ArrayList<Block> affectedlevers = new ArrayList<Block>();
private ArrayList<Entity> affectedentities = new ArrayList<Entity>();
private AirBurst source = null;
public AirBlast(Location location, Vector direction, Player player, double factorpush, AirBurst burst) {
if (location.getBlock().isLiquid()) {
return;
}
source = burst;
this.player = player;
origin = location.clone();
this.direction = direction.clone();
this.location = location.clone();
pushfactor *= factorpush;
instances.put(idCounter, this);
this.id = idCounter;
idCounter = (idCounter + 1) % Integer.MAX_VALUE;
}
private AirBurst source;
private Random random;
private ArrayList<Block> affectedLevers;
private ArrayList<Entity> affectedEntities;
public AirBlast(Player player) {
/* Initial Checks */
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName());
if (bPlayer.isOnCooldown("AirBlast"))
super(player);
if (bPlayer.isOnCooldown(this)) {
return;
if (player.getEyeLocation().getBlock().isLiquid()) {
} else if (player.getEyeLocation().getBlock().isLiquid()) {
return;
}
/* End Initial Checks */
// reloadVariables();
this.player = player;
if (origins.containsKey(player)) {
otherorigin = true;
origin = origins.get(player);
origins.remove(player);
Entity entity = GeneralMethods.getTargetedEntity(player, range, new ArrayList<Entity>());
setFields();
if (ORIGINS.containsKey(player)) {
Entity entity = GeneralMethods.getTargetedEntity(player, range);
this.isFromOtherOrigin = true;
this.origin = ORIGINS.get(player);
ORIGINS.remove(player);
if (entity != null) {
direction = GeneralMethods.getDirection(origin, entity.getLocation()).normalize();
this.direction = GeneralMethods.getDirection(origin, entity.getLocation()).normalize();
} else {
direction = GeneralMethods.getDirection(origin, GeneralMethods.getTargetedLocation(player, range)).normalize();
this.direction = GeneralMethods.getDirection(origin, GeneralMethods.getTargetedLocation(player, range)) .normalize();
}
} else {
origin = player.getEyeLocation();
direction = player.getEyeLocation().getDirection().normalize();
}
location = origin.clone();
instances.put(idCounter, this);
this.id = idCounter;
idCounter = (idCounter + 1) % Integer.MAX_VALUE;
bPlayer.addCooldown("AirBlast", GeneralMethods.getGlobalCooldown());
// time = System.currentTimeMillis();
// timers.put(player, System.currentTimeMillis());
this.location = origin.clone();
bPlayer.addCooldown(this);
start();
}
public AirBlast(Player player, Location location, Vector direction, double modifiedPushFactor, AirBurst burst) {
super(player);
if (location.getBlock().isLiquid()) {
return;
}
this.source = burst;
this.origin = location.clone();
this.direction = direction.clone();
this.location = location.clone();
setFields();
this.pushFactor *= modifiedPushFactor;
this.affectedLevers = new ArrayList<>();
this.affectedEntities = new ArrayList<>();
start();
}
private void setFields() {
this.range = getConfig().getDouble("Abilities.Air.AirBlast.Range");
this.speed = getConfig().getDouble("Abilities.Air.AirBlast.Speed");
this.range = getConfig().getDouble("Abilities.Air.AirBlast.Range");
this.radius = getConfig().getDouble("Abilities.Air.AirBlast.Radius");
this.pushFactor = getConfig().getDouble("Abilities.Air.AirBlast.Push.Entities");
this.pushFactorForOthers = getConfig().getDouble("Abilities.Air.AirBlast.Push.Self");
this.canFlickLevers = getConfig().getBoolean("Abilities.Air.AirBlast.CanFlickLevers");
this.canOpenDoors = getConfig().getBoolean("Abilities.Air.AirBlast.CanOpenDoors");
this.canPressButtons = getConfig().getBoolean("Abilities.Air.AirBlast.CanPressButtons");
this.canCoolLava = getConfig().getBoolean("Abilities.Air.AirBlast.CanCoolLava");
this.particleCount = 6;
this.cooldown = GeneralMethods.getGlobalCooldown();
this.isFromOtherOrigin = false;
this.showParticles = true;
this.random = new Random();
this.affectedLevers = new ArrayList<>();
this.affectedEntities = new ArrayList<>();
}
private static void playOriginEffect(Player player) {
if (!origins.containsKey(player))
return;
Location origin = origins.get(player);
if (player.isDead() || !player.isOnline())
return;
if (!origin.getWorld().equals(player.getWorld())) {
origins.remove(player);
if (!ORIGINS.containsKey(player)) {
return;
}
if (GeneralMethods.getBoundAbility(player) == null) {
origins.remove(player);
Location origin = ORIGINS.get(player);
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null || player.isDead() || !player.isOnline()) {
return;
} else if (!origin.getWorld().equals(player.getWorld())) {
ORIGINS.remove(player);
return;
} else if (!bPlayer.canBendIgnoreCooldowns(getAbility("AirBlast"))) {
ORIGINS.remove(player);
return;
} else if (origin.distanceSquared(player.getEyeLocation()) > ORIGIN_SELECT_RANGE * ORIGIN_SELECT_RANGE) {
ORIGINS.remove(player);
return;
}
if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirBlast")
|| !GeneralMethods.canBend(player.getName(), "AirBlast")) {
origins.remove(player);
return;
}
if (origin.distance(player.getEyeLocation()) > originselectrange) {
origins.remove(player);
return;
}
AirMethods.playAirbendingParticles(origin, 4);
// origin.getWorld().playEffect(origin, Effect.SMOKE, 4,
// (int) originselectrange);
playAirbendingParticles(origin, ORIGIN_PARTICLE_COUNT);
}
public static void progressAll() {
for (AirBlast blast : instances.values()) {
blast.progress();
}
for (Player player : origins.keySet()) {
public static void progressOrigins() {
for (Player player : ORIGINS.keySet()) {
playOriginEffect(player);
}
}
public static void setOrigin(Player player) {
Location location = GeneralMethods.getTargetedLocation(player, originselectrange, GeneralMethods.nonOpaque);
if (location.getBlock().isLiquid() || GeneralMethods.isSolid(location.getBlock()))
Location location = GeneralMethods.getTargetedLocation(player, ORIGIN_SELECT_RANGE, GeneralMethods.NON_OPAQUE);
if (location.getBlock().isLiquid() || GeneralMethods.isSolid(location.getBlock())) {
return;
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", location))
} else if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", location)) {
return;
}
if (origins.containsKey(player)) {
origins.replace(player, location);
if (ORIGINS.containsKey(player)) {
ORIGINS.replace(player, location);
} else {
origins.put(player, location);
ORIGINS.put(player, location);
}
}
private void advanceLocation() {
if (showParticles)
AirMethods.playAirbendingParticles(location, 6, 0.275F, 0.275F, 0.275F);
if (GeneralMethods.rand.nextInt(4) == 0) {
AirMethods.playAirbendingSound(location);
if (showParticles) {
playAirbendingParticles(location, particleCount, 0.275F, 0.275F, 0.275F);
}
location = location.add(direction.clone().multiply(speedfactor));
if (random.nextInt(4) == 0) {
playAirbendingSound(location);
}
location = location.add(direction.clone().multiply(speedFactor));
}
private void affect(Entity entity) {
boolean isUser = entity.getUniqueId() == player.getUniqueId();
if (!isUser || otherorigin) {
pushfactor = otherpushfactor;
if (!isUser || isFromOtherOrigin) {
pushFactor = pushFactorForOthers;
Vector velocity = entity.getVelocity();
// double mag = Math.abs(velocity.getY());
double max = maxspeed;
double factor = pushfactor;
if (AvatarState.isAvatarState(player)) {
max = AvatarState.getValue(maxspeed);
double max = speed / speedFactor;
double factor = pushFactor;
if (bPlayer.isAvatarState()) {
max = AvatarState.getValue(max);
factor = AvatarState.getValue(factor);
}
Vector push = direction.clone();
if (Math.abs(push.getY()) > max && !isUser) {
if (push.getY() < 0)
if (push.getY() < 0) {
push.setY(-max);
else
} else {
push.setY(max);
}
}
factor *= 1 - location.distance(origin) / (2 * range);
@ -231,87 +225,72 @@ public class AirBlast implements ConfigLoadable {
}
if (entity instanceof Player) {
if (Commands.invincible.contains(((Player) entity).getName()))
if (Commands.invincible.contains(((Player) entity).getName())) {
return;
}
}
if (Double.isNaN(velocity.length()))
if (Double.isNaN(velocity.length())) {
return;
}
GeneralMethods.setVelocity(entity, velocity);
if (source != null)
new HorizontalVelocityTracker(entity, player, 200l, "AirBurst", Element.Air, null);
else
new HorizontalVelocityTracker(entity, player, 200l, "AirBlast", Element.Air, null);
if (source != null) {
new HorizontalVelocityTracker(entity, player, 200l, "AirBurst", Element.AIR);
} else {
new HorizontalVelocityTracker(entity, player, 200l, "AirBlast", Element.AIR);
}
entity.setFallDistance(0);
if (!isUser && entity instanceof Player) {
new Flight((Player) entity, player);
}
if (entity.getFireTicks() > 0)
if (entity.getFireTicks() > 0) {
entity.getWorld().playEffect(entity.getLocation(), Effect.EXTINGUISH, 0);
entity.setFireTicks(0);
AirMethods.breakBreathbendingHold(entity);
}
if (source != null && (this.damage > 0 && entity instanceof LivingEntity && !entity.equals(player) && !affectedentities.contains(entity))) {
GeneralMethods.damageEntity(player, entity, damage, "AirBurst");
affectedentities.add(entity);
} else if (source == null && (damage > 0 && entity instanceof LivingEntity && !entity.equals(player) && !affectedentities.contains(entity))) {
GeneralMethods.damageEntity(player, entity, damage, "AirBlast");
affectedentities.add(entity);
entity.setFireTicks(0);
breakBreathbendingHold(entity);
if (damage > 0 && entity instanceof LivingEntity && !entity.equals(player) && !affectedEntities.contains(entity)) {
GeneralMethods.damageEntity(this, entity, damage);
affectedEntities.add(entity);
}
}
}
public Player getPlayer() {
return player;
}
public double getPushfactor() {
return pushfactor;
}
public double getRange() {
return range;
}
public boolean getShowParticles() {
return this.showParticles;
}
@SuppressWarnings("deprecation")
public boolean progress() {
// ProjectKorra.log.info("FireBlast id: " + getID());
@Override
public void progress() {
if (player.isDead() || !player.isOnline()) {
remove();
return false;
}
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", location)) {
return;
} else if (GeneralMethods.isRegionProtectedFromBuild(this, location)) {
remove();
return false;
return;
}
speedfactor = speed * (ProjectKorra.time_step / 1000.);
speedFactor = speed * (ProjectKorra.time_step / 1000.0);
ticks++;
if (ticks > maxticks) {
if (ticks > MAX_TICKS) {
remove();
return false;
return;
}
Block block = location.getBlock();
for (Block testblock : GeneralMethods.getBlocksAroundPoint(location, affectingradius)) {
for (Block testblock : GeneralMethods.getBlocksAroundPoint(location, radius)) {
if (testblock.getType() == Material.FIRE) {
testblock.setType(Material.AIR);
testblock.getWorld().playEffect(testblock.getLocation(), Effect.EXTINGUISH, 0);
}
if (GeneralMethods.isRegionProtectedFromBuild(getPlayer(), "AirBlast", block.getLocation()))
if (GeneralMethods.isRegionProtectedFromBuild(this, block.getLocation())) {
continue;
}
Material doorTypes[] = { Material.WOODEN_DOOR, Material.SPRUCE_DOOR, Material.BIRCH_DOOR, Material.JUNGLE_DOOR,
Material.ACACIA_DOOR, Material.DARK_OAK_DOOR };
if (Arrays.asList(doorTypes).contains(block.getType()) && openDoors) {
if (Arrays.asList(doorTypes).contains(block.getType()) && canOpenDoors) {
if (block.getData() >= 8) {
block = block.getRelative(BlockFace.DOWN);
}
@ -324,21 +303,7 @@ public class AirBlast implements ConfigLoadable {
block.getWorld().playSound(block.getLocation(), Sound.DOOR_OPEN, 10, 1);
}
}
if ((block.getType() == Material.LEVER) && !affectedlevers.contains(block) && flickLevers) {
// BlockState state = block.getState();
// Lever lever = (Lever) (state.getData());
// lever.setPowered(!lever.isPowered());
// state.setData(lever);
// state.update(true, true);
//
// Block relative = block.getRelative(((Attachable) block
// .getState().getData()).getFacing(), -1);
// relative.getState().update(true, true);
//
// for (Block block2 : Methods.getBlocksAroundPoint(
// relative.getLocation(), 2))
// block2.getState().update(true, true);
if ((block.getType() == Material.LEVER) && !affectedLevers.contains(block) && canFlickLevers) {
Lever lever = new Lever(Material.LEVER, block.getData());
lever.setPowered(!lever.isPowered());
block.setData(lever.getData());
@ -351,11 +316,8 @@ public class AirBlast implements ConfigLoadable {
supportState.update(true, false);
initialSupportState.update(true);
}
affectedlevers.add(block);
} else if ((block.getType() == Material.STONE_BUTTON) && !affectedlevers.contains(block) && pressButtons) {
affectedLevers.add(block);
} else if ((block.getType() == Material.STONE_BUTTON) && !affectedLevers.contains(block) && canPressButtons) {
final Button button = new Button(Material.STONE_BUTTON, block.getData());
button.setPowered(!button.isPowered());
block.setData(button.getData());
@ -370,7 +332,6 @@ public class AirBlast implements ConfigLoadable {
}
final Block btBlock = block;
new BukkitRunnable() {
public void run() {
button.setPowered(!button.isPowered());
@ -387,9 +348,8 @@ public class AirBlast implements ConfigLoadable {
}
}.runTaskLater(ProjectKorra.plugin, 10);
affectedlevers.add(block);
} else if ((block.getType() == Material.WOOD_BUTTON) && !affectedlevers.contains(block) && pressButtons) {
affectedLevers.add(block);
} else if ((block.getType() == Material.WOOD_BUTTON) && !affectedLevers.contains(block) && canPressButtons) {
final Button button = new Button(Material.WOOD_BUTTON, block.getData());
button.setPowered(!button.isPowered());
block.setData(button.getData());
@ -421,19 +381,19 @@ public class AirBlast implements ConfigLoadable {
}
}.runTaskLater(ProjectKorra.plugin, 15);
affectedlevers.add(block);
affectedLevers.add(block);
}
}
if ((GeneralMethods.isSolid(block) || block.isLiquid()) && !affectedlevers.contains(block) && coolLava) {
if ((GeneralMethods.isSolid(block) || block.isLiquid()) && !affectedLevers.contains(block) && canCoolLava) {
if (block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA) {
if (block.getData() == full) {
if (block.getData() == 0x0) {
block.setType(Material.OBSIDIAN);
} else {
block.setType(Material.COBBLESTONE);
}
}
remove();
return false;
return;
}
/*
@ -444,70 +404,206 @@ public class AirBlast implements ConfigLoadable {
double dist = location.distance(origin);
if (Double.isNaN(dist) || dist > range) {
remove();
return false;
return;
}
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, affectingradius)) {
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, radius)) {
affect(entity);
}
advanceLocation();
return true;
return;
}
public static boolean removeAirBlastsAroundPoint(Location location, double radius) {
boolean removed = false;
for (AirBlast airBlast : instances.values()) {
for (AirBlast airBlast : CoreAbility.getAbilities(AirBlast.class)) {
Location airBlastlocation = airBlast.location;
if (location.getWorld() == airBlastlocation.getWorld()) {
if (location.distance(airBlastlocation) <= radius)
if (location.distanceSquared(airBlastlocation) <= radius * radius) {
airBlast.remove();
}
removed = true;
}
}
return removed;
}
public void remove() {
instances.remove(id);
}
public static void removeAll() {
for (AirBlast ability : instances.values()) {
ability.remove();
}
@Override
public String getName() {
return "AirBlast";
}
@Override
public void reloadVariables() {
speed = config.get().getDouble("Abilities.Air.AirBlast.Speed");
defaultrange = config.get().getDouble("Abilities.Air.AirBlast.Range");
affectingradius = config.get().getDouble("Abilities.Air.AirBlast.Radius");
defaultpushfactor = config.get().getDouble("Abilities.Air.AirBlast.Push");
flickLevers = config.get().getBoolean("Abilities.Air.AirBlast.CanFlickLevers");
openDoors = config.get().getBoolean("Abilities.Air.AirBlast.CanOpenDoors");
pressButtons = config.get().getBoolean("Abilities.Air.AirBlast.CanPressButtons");
coolLava = config.get().getBoolean("Abilities.Air.AirBlast.CanCoolLava");
maxspeed = 1. / defaultpushfactor;
range = defaultrange;
pushfactor = defaultpushfactor;
public Location getLocation() {
return location;
}
public void setDamage(double dmg) {
this.damage = dmg;
@Override
public long getCooldown() {
return cooldown;
}
@Override
public boolean isSneakAbility() {
return true;
}
public void setPushfactor(double pushfactor) {
this.pushfactor = pushfactor;
@Override
public boolean isHarmlessAbility() {
return false;
}
public Location getOrigin() {
return origin;
}
public void setOrigin(Location origin) {
this.origin = origin;
}
public Vector getDirection() {
return direction;
}
public void setDirection(Vector direction) {
this.direction = direction;
}
public int getTicks() {
return ticks;
}
public void setTicks(int ticks) {
this.ticks = ticks;
}
public double getSpeedFactor() {
return speedFactor;
}
public void setSpeedFactor(double speedFactor) {
this.speedFactor = speedFactor;
}
public double getRange() {
return range;
}
public void setRange(double range) {
this.range = range;
}
public void setShowParticles(boolean show) {
this.showParticles = show;
public double getPushFactor() {
return pushFactor;
}
public void setPushFactor(double pushFactor) {
this.pushFactor = pushFactor;
}
public double getPushFactorForOthers() {
return pushFactorForOthers;
}
public void setPushFactorForOthers(double pushFactorForOthers) {
this.pushFactorForOthers = pushFactorForOthers;
}
public double getDamage() {
return damage;
}
public void setDamage(double damage) {
this.damage = damage;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public boolean isCanFlickLevers() {
return canFlickLevers;
}
public void setCanFlickLevers(boolean canFlickLevers) {
this.canFlickLevers = canFlickLevers;
}
public boolean isCanOpenDoors() {
return canOpenDoors;
}
public void setCanOpenDoors(boolean canOpenDoors) {
this.canOpenDoors = canOpenDoors;
}
public boolean isCanPressButtons() {
return canPressButtons;
}
public void setCanPressButtons(boolean canPressButtons) {
this.canPressButtons = canPressButtons;
}
public boolean isCanCoolLava() {
return canCoolLava;
}
public void setCanCoolLava(boolean canCoolLava) {
this.canCoolLava = canCoolLava;
}
public boolean isFromOtherOrigin() {
return isFromOtherOrigin;
}
public void setFromOtherOrigin(boolean isFromOtherOrigin) {
this.isFromOtherOrigin = isFromOtherOrigin;
}
public boolean isShowParticles() {
return showParticles;
}
public void setShowParticles(boolean showParticles) {
this.showParticles = showParticles;
}
public AirBurst getSource() {
return source;
}
public void setSource(AirBurst source) {
this.source = source;
}
public ArrayList<Block> getAffectedLevers() {
return affectedLevers;
}
public ArrayList<Entity> getAffectedEntities() {
return affectedEntities;
}
public void setLocation(Location location) {
this.location = location;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
}

View file

@ -1,42 +1,42 @@
package com.projectkorra.projectkorra.airbending;
import java.util.concurrent.ConcurrentHashMap;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.WaterAbility;
import com.projectkorra.projectkorra.waterbending.WaterManipulation;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
import com.projectkorra.projectkorra.waterbending.WaterManipulation;
import com.projectkorra.projectkorra.waterbending.WaterMethods;
import java.util.concurrent.ConcurrentHashMap;
public class AirBubble implements ConfigLoadable {
public static ConcurrentHashMap<Player, AirBubble> instances = new ConcurrentHashMap<>();
private static double DEFAULT_AIR_RADIUS = config.get().getDouble("Abilities.Air.AirBubble.Radius");
private static double DEFAULT_WATER_RADIUS = config.get().getDouble("Abilities.Water.WaterBubble.Radius");
public class AirBubble extends AirAbility {
private Player player;
private boolean waterBubble;
private double radius;
private double defaultAirRadius = DEFAULT_AIR_RADIUS;
private double defaultWaterRadius = DEFAULT_WATER_RADIUS;
private ConcurrentHashMap<Block, BlockState> waterorigins;
private double airRadius;
private double waterRadius;
private ConcurrentHashMap<Block, BlockState> waterOrigins;
public AirBubble(Player player) {
// reloadVariables();
this.player = player;
waterorigins = new ConcurrentHashMap<Block, BlockState>();
instances.put(player, this);
super(player);
this.radius = 0;
this.airRadius = getConfig().getDouble("Abilities.Air.AirBubble.Radius");
this.waterRadius = getConfig().getDouble("Abilities.Water.WaterBubble.Radius");
this.waterOrigins = new ConcurrentHashMap<>();
start();
}
public static boolean canFlowTo(Block block) {
for (AirBubble airBubble : instances.values()) {
for (AirBubble airBubble : CoreAbility.getAbilities(AirBubble.class)) {
if (airBubble.blockInBubble(block)) {
return false;
}
@ -44,167 +44,159 @@ public class AirBubble implements ConfigLoadable {
return true;
}
public static String getDescription() {
return "To use, the bender must merely have the ability selected."
+ " All water around the user in a small bubble will vanish,"
+ " replacing itself once the user either gets too far away or selects a different ability.";
}
public static void handleBubbles(Server server) {
for (Player player : server.getOnlinePlayers()) {
if (GeneralMethods.getBoundAbility(player) != null) {
if (GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirBubble")
|| GeneralMethods.getBoundAbility(player).equalsIgnoreCase("WaterBubble")) {
if (!instances.containsKey(player) && player.isSneaking()) {
new AirBubble(player);
public static void handleBubbles() {
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
continue;
}
String name = bPlayer.getBoundAbilityName();
if (name.equalsIgnoreCase("AirBubble") | name.equalsIgnoreCase("WaterBubble")) {
if (!CoreAbility.hasAbility(player, AirBubble.class) && player.isSneaking()) {
AirBubble airBubble = new AirBubble(player);
if (name.equalsIgnoreCase("WaterBubble")) {
airBubble.waterBubble = true;
}
}
}
}
AirBubble.progressAll();
}
public boolean blockInBubble(Block block) {
if (block.getWorld() != player.getWorld()) {
return false;
}
if (block.getLocation().distance(player.getLocation()) <= radius) {
} else if (block.getLocation().distanceSquared(player.getLocation()) <= radius * radius) {
return true;
}
return false;
}
public double getDefaultAirRadius() {
return defaultAirRadius;
@Override
public void progress() {
if (!player.isSneaking() || !bPlayer.canBend(this)) {
remove();
return;
} else {
pushWater();
}
}
public double getDefaultWaterRadius() {
return defaultWaterRadius;
private void pushWater() {
if (bPlayer.hasElement(Element.AIR)) {
radius = airRadius;
} else {
radius = waterRadius;
}
if (bPlayer.hasElement(Element.WATER) && isNight(player.getWorld())) {
radius = WaterAbility.getNightFactor(waterRadius, player.getWorld());
}
if (airRadius > radius && bPlayer.hasElement(Element.AIR)) {
radius = airRadius;
}
Location location = player.getLocation();
for (Block block : waterOrigins.keySet()) {
if (block.getWorld() != location.getWorld()) {
if (block.getType() == Material.AIR || isWater(block)) {
waterOrigins.get(block).update(true);
}
waterOrigins.remove(block);
} else if (block.getLocation().distanceSquared(location) > radius * radius) {
if (block.getType() == Material.AIR || isWater(block)) {
waterOrigins.get(block).update(true);
}
waterOrigins.remove(block);
}
}
for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) {
if (waterOrigins.containsKey(block)) {
continue;
} else if (!isWater(block)) {
continue;
} else if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBubble", block.getLocation())) {
continue;
} else if (block.getType() == Material.STATIONARY_WATER || block.getType() == Material.WATER) {
if (WaterManipulation.canBubbleWater(block)) {
waterOrigins.put(block, block.getState());
block.setType(Material.AIR);
}
}
}
}
public Player getPlayer() {
return player;
@Override
public void remove() {
super.remove();
for (Block block : waterOrigins.keySet()) {
if (block.getType() == Material.AIR || block.isLiquid()) {
waterOrigins.get(block).update(true);
}
}
}
@Override
public String getName() {
return waterBubble ? "WaterBubble" : "AirBubble";
}
@Override
public Location getLocation() {
return player != null ? player.getLocation() : null;
}
@Override
public long getCooldown() {
return 0;
}
@Override
public boolean isSneakAbility() {
return true;
}
@Override
public boolean isHarmlessAbility() {
return false;
}
public boolean isWaterBubble() {
return waterBubble;
}
public void setWaterBubble(boolean waterBubble) {
this.waterBubble = waterBubble;
}
public double getRadius() {
return radius;
}
public boolean progress() {
if (player.isDead() || !player.isOnline()) {
remove();
return false;
}
if (!player.isSneaking()) {
remove();
return false;
}
if (GeneralMethods.getBoundAbility(player) != null) {
if (GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirBubble")
&& GeneralMethods.canBend(player.getName(), "AirBubble")) {
pushWater();
return false;
}
if (GeneralMethods.getBoundAbility(player).equalsIgnoreCase("WaterBubble")
&& GeneralMethods.canBend(player.getName(), "WaterBubble")) {
pushWater();
return false;
}
}
remove();
return true;
}
private void pushWater() {
if (GeneralMethods.isBender(player.getName(), Element.Air)) {
radius = defaultAirRadius;
} else {
radius = defaultWaterRadius;
}
if (GeneralMethods.isBender(player.getName(), Element.Water) && WaterMethods.isNight(player.getWorld())) {
radius = WaterMethods.waterbendingNightAugment(defaultWaterRadius, player.getWorld());
}
if (defaultAirRadius > radius && GeneralMethods.isBender(player.getName(), Element.Air))
radius = defaultAirRadius;
Location location = player.getLocation();
for (Block block : waterorigins.keySet()) {
if (block.getWorld() != location.getWorld()) {
if (block.getType() == Material.AIR || WaterMethods.isWater(block))
waterorigins.get(block).update(true);
waterorigins.remove(block);
} else if (block.getLocation().distance(location) > radius) {
if (block.getType() == Material.AIR || WaterMethods.isWater(block))
waterorigins.get(block).update(true);
waterorigins.remove(block);
}
}
for (Block block : GeneralMethods.getBlocksAroundPoint(location, radius)) {
if (waterorigins.containsKey(block))
continue;
if (!WaterMethods.isWater(block))
continue;
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBubble", block.getLocation()))
continue;
if (block.getType() == Material.STATIONARY_WATER || block.getType() == Material.WATER) {
if (WaterManipulation.canBubbleWater(block)) {
waterorigins.put(block, block.getState());
block.setType(Material.AIR);
}
}
}
}
public static void progressAll() {
for (AirBubble ability : instances.values()) {
ability.progress();
}
}
@Override
public void reloadVariables() {
DEFAULT_AIR_RADIUS = config.get().getDouble("Abilities.Air.AirBubble.Radius");
DEFAULT_WATER_RADIUS = config.get().getDouble("Abilities.Water.WaterBubble.Radius");
defaultAirRadius = DEFAULT_AIR_RADIUS;
defaultWaterRadius = DEFAULT_WATER_RADIUS;
}
public void remove() {
for (Block block : waterorigins.keySet()) {
// byte data = waterorigins.get(block);
// byte data = 0x0;
// block = block.getLocation().getBlock();
// if (block.getType() == Material.AIR) {
// block.setType(Material.WATER);
// block.setData(data);
// }
if (block.getType() == Material.AIR || block.isLiquid())
waterorigins.get(block).update(true);
}
// instances.remove(uuid);
instances.remove(player);
}
public static void removeAll() {
for (AirBubble ability : instances.values()) {
ability.remove();
}
}
public void setDefaultAirRadius(double defaultAirRadius) {
this.defaultAirRadius = defaultAirRadius;
}
public void setDefaultWaterRadius(double defaultWaterRadius) {
this.defaultWaterRadius = defaultWaterRadius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getAirRadius() {
return airRadius;
}
public void setAirRadius(double airRadius) {
this.airRadius = airRadius;
}
public double getWaterRadius() {
return waterRadius;
}
public void setWaterRadius(double waterRadius) {
this.waterRadius = waterRadius;
}
public ConcurrentHashMap<Block, BlockState> getWaterOrigins() {
return waterOrigins;
}
}

View file

@ -1,7 +1,6 @@
package com.projectkorra.projectkorra.airbending;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
@ -9,87 +8,95 @@ import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AvatarState;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.avatar.AvatarState;
public class AirBurst implements ConfigLoadable {
public class AirBurst extends AirAbility {
public static ConcurrentHashMap<Player, AirBurst> instances = new ConcurrentHashMap<>();
private static final int CHARGED_SNEAK_PARTICLES = 10;
private static final double PARTICLES_PERCENTAGE = 50;
private static double PARTICLES_PERCENTAGE = 50;
private static double threshold = config.get().getDouble("Abilities.Air.AirBurst.FallThreshold");
private static double pushfactor = config.get().getDouble("Abilities.Air.AirBurst.PushFactor");
private static double damage = config.get().getDouble("Abilities.Air.AirBurst.Damage");
private static double deltheta = 10;
private static double delphi = 10;
private boolean isCharged;
private boolean isFallBurst;
private float playerFallDistance;
private long chargeTime;
private double fallThreshold;
private double pushFactor;
private double damage;
private double blastAngleTheta;
private double blastAnglePhi;
private ArrayList<AirBlast> blasts;
private ArrayList<Entity> affectedEntities;
private static long cooldown = config.get().getLong("Abilities.Air.AirBurst.Cooldown");
private Player player;
private long starttime;
private long chargetime = config.get().getLong("Abilities.Air.AirBurst.ChargeTime");
private boolean charged = false;
private ArrayList<AirBlast> blasts = new ArrayList<AirBlast>();
private ArrayList<Entity> affectedentities = new ArrayList<Entity>();
public AirBurst(Player player, boolean isFallBurst) {
super(player);
if (bPlayer.isOnCooldown(this)) {
remove();
return;
}
public AirBurst() {
// reloadVariables();
this.isFallBurst = isFallBurst;
this.isCharged = false;
this.blastAnglePhi = 10;
this.blastAngleTheta = 10;
this.playerFallDistance = player.getFallDistance();
this.chargeTime = getConfig().getLong("Abilities.Air.AirBurst.ChargeTime");
this.fallThreshold = getConfig().getDouble("Abilities.Air.AirBurst.FallThreshold");
this.pushFactor = getConfig().getDouble("Abilities.Air.AirBurst.PushFactor");
this.damage = getConfig().getDouble("Abilities.Air.AirBurst.Damage");
this.blasts = new ArrayList<>();
this.affectedEntities = new ArrayList<>();
if (bPlayer.isAvatarState()) {
this.chargeTime = 0;
this.damage = AvatarState.getValue(this.damage);
}
start();
}
public AirBurst(Player player) {
/* Initial Checks */
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName());
if (bPlayer.isOnCooldown("AirBurst"))
@Override
public void progress() {
if (!bPlayer.canBendIgnoreCooldowns(this)) {
remove();
return;
if (instances.containsKey(player))
return;
/* End Initial Checks */
// reloadVariables();
starttime = System.currentTimeMillis();
if (AvatarState.isAvatarState(player))
chargetime = 0;
this.player = player;
bPlayer.addCooldown("AirBurst", cooldown);
instances.put(player, this);
}
}
public static void coneBurst(Player player) {
if (instances.containsKey(player)) {
instances.get(player).coneBurst();
if (isFallBurst) {
if (playerFallDistance >= fallThreshold) {
fallBurst();
}
remove();
return;
}
if (System.currentTimeMillis() > startTime + chargeTime && !isCharged) {
isCharged = true;
}
if (!player.isSneaking()) {
if (isCharged) {
sphereBurst();
remove();
return;
} else {
remove();
return;
}
} else if (isCharged) {
Location location = player.getEyeLocation();
playAirbendingParticles(location, CHARGED_SNEAK_PARTICLES);
}
}
public static void fallBurst(Player player) {
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName());
if (!GeneralMethods.canBend(player.getName(), "AirBurst")) {
return;
}
if (player.getFallDistance() < threshold) {
return;
}
if (GeneralMethods.getBoundAbility(player) == null) {
return;
}
if (instances.containsKey(player)) {
return;
}
if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirBurst")) {
return;
}
if (bPlayer.isOnCooldown("AirBurst")) {
return;
}
private void fallBurst() {
Location location = player.getLocation();
double x, y, z;
double r = 1;
for (double theta = 75; theta < 105; theta += deltheta) {
double dphi = delphi / Math.sin(Math.toRadians(theta));
for (double theta = 75; theta < 105; theta += blastAngleTheta) {
double dphi = blastAnglePhi / Math.sin(Math.toRadians(theta));
for (double phi = 0; phi < 360; phi += dphi) {
double rphi = Math.toRadians(phi);
double rtheta = Math.toRadians(theta);
@ -97,25 +104,29 @@ public class AirBurst implements ConfigLoadable {
y = r * Math.sin(rphi) * Math.sin(rtheta);
z = r * Math.cos(rtheta);
Vector direction = new Vector(x, z, y);
AirBlast blast = new AirBlast(location, direction.normalize(), player, pushfactor, new AirBurst());
AirBlast blast = new AirBlast(player, location, direction.normalize(), pushFactor, this);
blast.setDamage(damage);
}
}
}
void addAffectedEntity(Entity entity) {
affectedentities.add(entity);
public static void coneBurst(Player player) {
if (CoreAbility.hasAbility(player, AirBurst.class)) {
AirBurst airBurst = CoreAbility.getAbility(player, AirBurst.class);
airBurst.startConeBurst();
airBurst.remove();
}
}
private void coneBurst() {
if (charged) {
private void startConeBurst() {
if (isCharged) {
Location location = player.getEyeLocation();
Vector vector = location.getDirection();
double angle = Math.toRadians(30);
double x, y, z;
double r = 1;
for (double theta = 0; theta <= 180; theta += deltheta) {
double dphi = delphi / Math.sin(Math.toRadians(theta));
for (double theta = 0; theta <= 180; theta += blastAngleTheta) {
double dphi = blastAnglePhi / Math.sin(Math.toRadians(theta));
for (double phi = 0; phi < 360; phi += dphi) {
double rphi = Math.toRadians(phi);
double rtheta = Math.toRadians(theta);
@ -124,21 +135,22 @@ public class AirBurst implements ConfigLoadable {
z = r * Math.cos(rtheta);
Vector direction = new Vector(x, z, y);
if (direction.angle(vector) <= angle) {
AirBlast blast = new AirBlast(location, direction.normalize(), player, pushfactor, this);
AirBlast blast = new AirBlast(player, location, direction.normalize(), pushFactor, this);
blast.setDamage(damage);
}
}
}
}
remove();
}
public void handleSmoothParticles() {
for (int i = 0; i < blasts.size(); i++) {
final AirBlast blast = blasts.get(i);
int toggleTime = 0;
if (i % 4 != 0)
if (i % 4 != 0) {
toggleTime = (int) (i % (100 / PARTICLES_PERCENTAGE)) + 3;
}
new BukkitRunnable() {
public void run() {
blast.setShowParticles(true);
@ -147,80 +159,15 @@ public class AirBurst implements ConfigLoadable {
}
}
boolean isAffectedEntity(Entity entity) {
return affectedentities.contains(entity);
}
public boolean progress() {
if (!GeneralMethods.canBend(player.getName(), "AirBurst")) {
remove();
return false;
}
if (GeneralMethods.getBoundAbility(player) == null) {
remove();
return false;
}
if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirBurst")) {
remove();
return false;
}
if (System.currentTimeMillis() > starttime + chargetime && !charged) {
charged = true;
}
if (!player.isSneaking()) {
if (charged) {
sphereBurst();
} else {
remove();
return false;
}
} else if (charged) {
Location location = player.getEyeLocation();
// location = location.add(location.getDirection().normalize());
AirMethods.playAirbendingParticles(location, 10);
// location.getWorld().playEffect(
// location,
// Effect.SMOKE,
// Methods.getIntCardinalDirection(player.getEyeLocation()
// .getDirection()), 3);
}
return true;
}
public static void progressAll() {
for (AirBurst ability : instances.values()) {
ability.progress();
}
}
public void remove() {
instances.remove(player);
}
public static void removeAll() {
for (AirBurst ability : instances.values()) {
ability.remove();
}
}
@Override
public void reloadVariables() {
threshold = config.get().getDouble("Abilities.Air.AirBurst.FallThreshold");
pushfactor = config.get().getDouble("Abilities.Air.AirBurst.PushFactor");
damage = config.get().getDouble("Abilities.Air.AirBurst.Damage");
chargetime = config.get().getLong("Abilities.Air.AirBurst.ChargeTime");
}
private void sphereBurst() {
if (charged) {
if (isCharged) {
Location location = player.getEyeLocation();
double x, y, z;
double r = 1;
for (double theta = 0; theta <= 180; theta += deltheta) {
double dphi = delphi / Math.sin(Math.toRadians(theta));
for (double theta = 0; theta <= 180; theta += blastAngleTheta) {
double dphi = blastAnglePhi / Math.sin(Math.toRadians(theta));
for (double phi = 0; phi < 360; phi += dphi) {
double rphi = Math.toRadians(phi);
double rtheta = Math.toRadians(theta);
@ -228,15 +175,119 @@ public class AirBurst implements ConfigLoadable {
y = r * Math.sin(rphi) * Math.sin(rtheta);
z = r * Math.cos(rtheta);
Vector direction = new Vector(x, z, y);
AirBlast blast = new AirBlast(location, direction.normalize(), player, pushfactor, this);
AirBlast blast = new AirBlast(player, location, direction.normalize(), pushFactor, this);
blast.setDamage(damage);
blast.setShowParticles(false);
blasts.add(blast);
}
}
}
// Methods.verbose("--" + AirBlast.instances.size() + "--");
remove();
handleSmoothParticles();
}
@Override
public String getName() {
return "AirBurst";
}
@Override
public Location getLocation() {
return player != null ? player.getLocation() : null;
}
@Override
public long getCooldown() {
return 0;
}
@Override
public boolean isSneakAbility() {
return true;
}
@Override
public boolean isHarmlessAbility() {
return false;
}
public void addAffectedEntity(Entity entity) {
affectedEntities.add(entity);
}
public boolean isAffectedEntity(Entity entity) {
return affectedEntities.contains(entity);
}
public long getChargeTime() {
return chargeTime;
}
public void setChargeTime(long chargeTime) {
this.chargeTime = chargeTime;
}
public double getFallThreshold() {
return fallThreshold;
}
public void setFallThreshold(double fallThreshold) {
this.fallThreshold = fallThreshold;
}
public double getPushFactor() {
return pushFactor;
}
public void setPushFactor(double pushFactor) {
this.pushFactor = pushFactor;
}
public double getDamage() {
return damage;
}
public void setDamage(double damage) {
this.damage = damage;
}
public double getBlastAngleTheta() {
return blastAngleTheta;
}
public void setBlastAngleTheta(double blastAngleTheta) {
this.blastAngleTheta = blastAngleTheta;
}
public double getBlastAnglePhi() {
return blastAnglePhi;
}
public void setBlastAnglePhi(double blastAnglePhi) {
this.blastAnglePhi = blastAnglePhi;
}
public boolean isCharged() {
return isCharged;
}
public void setCharged(boolean isCharged) {
this.isCharged = isCharged;
}
public boolean isFallBurst() {
return isFallBurst;
}
public void setFallBurst(boolean isFallBurst) {
this.isFallBurst = isFallBurst;
}
public ArrayList<AirBlast> getBlasts() {
return blasts;
}
public ArrayList<Entity> getAffectedEntities() {
return affectedEntities;
}
}

View file

@ -1,17 +1,16 @@
package com.projectkorra.projectkorra.airbending;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AvatarState;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.ComboAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.FireAbility;
import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
import com.projectkorra.projectkorra.avatar.AvatarState;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
import com.projectkorra.projectkorra.earthbending.EarthMethods;
import com.projectkorra.projectkorra.firebending.FireCombo;
import com.projectkorra.projectkorra.firebending.FireMethods;
import com.projectkorra.projectkorra.firebending.FireCombo.FireComboStream;
import com.projectkorra.projectkorra.util.ClickType;
import com.projectkorra.projectkorra.util.Flight;
import org.bukkit.Location;
@ -24,128 +23,102 @@ import org.bukkit.util.Vector;
import java.util.ArrayList;
public class AirCombo implements ConfigLoadable {
/*
* TODO: Combo classes should eventually be rewritten so that each combo is treated
* as an individual ability. In the mean time, we will just place "fake"
* classes so that CoreAbility will register each ability.
*/
public class AirCombo extends AirAbility implements ComboAbility {
public static enum AbilityState {
TWISTER_MOVING, TWISTER_STATIONARY
}
public static ArrayList<AirCombo> instances = new ArrayList<AirCombo>();
public static double twisterSpeed = config.get().getDouble("Abilities.Air.AirCombo.Twister.Speed");
public static double twisterRange = config.get().getDouble("Abilities.Air.AirCombo.Twister.Range");
public static double twisterHeight = config.get().getDouble("Abilities.Air.AirCombo.Twister.Height");
public static double twisterRadius = config.get().getDouble("Abilities.Air.AirCombo.Twister.Radius");
public static double twisterDegreePerParticle = config.get().getDouble("Abilities.Air.AirCombo.Twister.DegreesPerParticle");
public static double twisterHeightPerParticle = config.get().getDouble("Abilities.Air.AirCombo.Twister.HeightPerParticle");
public static long twisterRemoveDelay = config.get().getLong("Abilities.Air.AirCombo.Twister.RemoveDelay");
public static long twisterCooldown = config.get().getLong("Abilities.Air.AirCombo.Twister.Cooldown");
public static double airStreamSpeed = config.get().getDouble("Abilities.Air.AirCombo.AirStream.Speed");
public static double airStreamRange = config.get().getDouble("Abilities.Air.AirCombo.AirStream.Range");
public static double airStreamEntityHeight = config.get().getDouble("Abilities.Air.AirCombo.AirStream.EntityHeight");
public static long airStreamEntityDuration = config.get().getLong("Abilities.Air.AirCombo.AirStream.EntityDuration");
public static long airStreamCooldown = config.get().getLong("Abilities.Air.AirCombo.AirStream.Cooldown");
public static double airSweepSpeed = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Speed");
public static double airSweepRange = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Range");
public static double airSweepDamage = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Damage");
public static double airSweepKnockback = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Knockback");
public static long airSweepCooldown = config.get().getLong("Abilities.Air.AirCombo.AirSweep.Cooldown");
private static boolean enabled = config.get().getBoolean("Abilities.Air.AirCombo.Enabled");
public double airSliceSpeed = 0.7;
public double airSliceRange = 10;
public double airSliceDamage = 3;
public long airSliceCooldown = 500;
private Player player;
private BendingPlayer bPlayer;
private ClickType type;
private String ability;
private boolean isEnabled;
private int progressCounter;
private long cooldown;
private long time;
private double damage;
private double speed;
private double range;
private double knockback;
private double airStreamMaxEntityHeight;
private double airStreamEntityCarryDuration;
private double twisterHeight;
private double twisterRadius;
private double twisterDegreeParticles;
private double twisterHeightParticles;
private double twisterRemoveDelay;
private AbilityState state;
private String abilityName;
private Location origin;
private Location currentLoc;
private Location destination;
private Vector direction;
private int progressCounter = 0;
private double damage = 0, speed = 0, range = 0, knockback = 0;
private long cooldown = 0;
private AbilityState state;
private ArrayList<Entity> affectedEntities = new ArrayList<Entity>();
private ArrayList<BukkitRunnable> tasks = new ArrayList<BukkitRunnable>();
private ArrayList<Flight> flights = new ArrayList<Flight>();
private ArrayList<Entity> affectedEntities;
private ArrayList<BukkitRunnable> tasks;
private ArrayList<Flight> flights;
public AirCombo(Player player, String ability) {
/* Initial Checks */
super(player);
this.abilityName = ability;
this.isEnabled = getConfig().getBoolean("Abilities.Air.AirCombo.Enabled");
this.affectedEntities = new ArrayList<>();
this.tasks = new ArrayList<>();
this.flights = new ArrayList<>();
if (!enabled)
return;
if (Commands.isToggledForAll)
return;
this.bPlayer = GeneralMethods.getBendingPlayer(player.getName());
if (!bPlayer.isToggled())
return;
if (!bPlayer.hasElement(Element.Air))
return;
if (!GeneralMethods.canBend(player.getName(), ability)) {
if (!this.isEnabled || !bPlayer.canBendIgnoreBindsCooldowns(this)) {
return;
}
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", player.getLocation()))
return;
/* End Initial Checks */
// reloadVariables();
time = System.currentTimeMillis();
this.player = player;
this.ability = ability;
if (ability.equalsIgnoreCase("Twister")) {
damage = 0;
range = twisterRange;
speed = twisterSpeed;
cooldown = twisterCooldown;
this.range = getConfig().getDouble("Abilities.Air.AirCombo.Twister.Range");
this.speed = getConfig().getDouble("Abilities.Air.AirCombo.Twister.Speed");
this.cooldown = getConfig().getLong("Abilities.Air.AirCombo.Twister.Cooldown");
this.twisterHeight = getConfig().getDouble("Abilities.Air.AirCombo.Twister.Height");
this.twisterDegreeParticles = getConfig().getDouble("Abilities.Air.AirCombo.Twister.DegreesPerParticle");
this.twisterHeightParticles = getConfig().getDouble("Abilities.Air.AirCombo.Twister.HeightPerParticle");
this.twisterRemoveDelay = getConfig().getLong("Abilities.Air.AirCombo.Twister.RemoveDelay");
} else if (ability.equalsIgnoreCase("AirStream")) {
damage = 0;
range = airStreamRange;
speed = airStreamSpeed;
cooldown = airStreamCooldown;
} else if (ability.equalsIgnoreCase("AirSlice")) {
damage = airSliceDamage;
range = airSliceRange;
speed = airSliceSpeed;
cooldown = airSliceCooldown;
this.range = getConfig().getDouble("Abilities.Air.AirCombo.AirStream.Range");
this.speed = getConfig().getDouble("Abilities.Air.AirCombo.AirStream.Speed");
this.cooldown = getConfig().getLong("Abilities.Air.AirCombo.AirStream.Cooldown");
this.airStreamMaxEntityHeight = getConfig().getDouble("Abilities.Air.AirCombo.AirStream.EntityHeight");
this.airStreamEntityCarryDuration = getConfig().getLong("Abilities.Air.AirCombo.AirStream.EntityDuration");
} else if (ability.equalsIgnoreCase("AirSweep")) {
damage = airSweepDamage;
range = airSweepRange;
speed = airSweepSpeed;
knockback = airSweepKnockback;
cooldown = airSweepCooldown;
this.damage = getConfig().getDouble("Abilities.Air.AirCombo.AirSweep.Damage");
this.range = getConfig().getDouble("Abilities.Air.AirCombo.AirSweep.Range");
this.speed = getConfig().getDouble("Abilities.Air.AirCombo.AirSweep.Speed");
this.knockback = getConfig().getDouble("Abilities.Air.AirCombo.AirSweep.Knockback");
this.cooldown = getConfig().getLong("Abilities.Air.AirCombo.AirSweep.Cooldown");
}
if (AvatarState.isAvatarState(player)) {
cooldown = 0;
damage = AvatarState.getValue(damage);
range = AvatarState.getValue(range);
knockback = knockback * 1.4;
if (bPlayer.isAvatarState()) {
this.cooldown = 0;
this.damage = AvatarState.getValue(damage);
this.range = AvatarState.getValue(range);
this.knockback = knockback * 1.4;
this.airStreamMaxEntityHeight = AvatarState.getValue(airStreamMaxEntityHeight);
this.airStreamEntityCarryDuration = AvatarState.getValue(airStreamEntityCarryDuration);
}
instances.add(this);
bPlayer.addCooldown(this);
start();
}
@Override
public void progress() {
progressCounter++;
if (player.isDead() || !player.isOnline()) {
remove();
return;
} else if (currentLoc != null && GeneralMethods.isRegionProtectedFromBuild(this, currentLoc)) {
remove();
return;
}
if (ability.equalsIgnoreCase("Twister")) {
if (abilityName.equalsIgnoreCase("Twister")) {
if (destination == null) {
if (bPlayer.isOnCooldown("Twister") && !AvatarState.isAvatarState(player)) {
remove();
return;
}
bPlayer.addCooldown("Twister", cooldown);
state = AbilityState.TWISTER_MOVING;
direction = player.getEyeLocation().getDirection().clone().normalize();
direction.setY(0);
@ -153,15 +126,15 @@ public class AirCombo implements ConfigLoadable {
destination = player.getLocation().add(direction.clone().multiply(range));
currentLoc = origin.clone();
}
if (origin.distance(currentLoc) < origin.distance(destination) && state == AbilityState.TWISTER_MOVING)
if (origin.distanceSquared(currentLoc) < origin.distanceSquared(destination) && state == AbilityState.TWISTER_MOVING) {
currentLoc.add(direction.clone().multiply(speed));
else if (state == AbilityState.TWISTER_MOVING) {
} else if (state == AbilityState.TWISTER_MOVING) {
state = AbilityState.TWISTER_STATIONARY;
time = System.currentTimeMillis();
} else if (System.currentTimeMillis() - time >= twisterRemoveDelay) {
remove();
return;
} else if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", currentLoc)) {
} else if (GeneralMethods.isRegionProtectedFromBuild(this, currentLoc)) {
remove();
return;
}
@ -175,90 +148,84 @@ public class AirCombo implements ConfigLoadable {
double height = twisterHeight;
double radius = twisterRadius;
for (double y = 0; y < height; y += twisterHeightPerParticle) {
for (double y = 0; y < height; y += twisterHeightParticles) {
double animRadius = ((radius / height) * y);
for (double i = -180; i <= 180; i += twisterDegreePerParticle) {
for (double i = -180; i <= 180; i += twisterDegreeParticles) {
Vector animDir = GeneralMethods.rotateXZ(new Vector(1, 0, 1), i);
Location animLoc = currentLoc.clone().add(animDir.multiply(animRadius));
animLoc.add(0, y, 0);
AirMethods.playAirbendingParticles(animLoc, 1, 0, 0, 0);
playAirbendingParticles(animLoc, 1, 0, 0, 0);
}
}
AirMethods.playAirbendingSound(currentLoc);
playAirbendingSound(currentLoc);
for (int i = 0; i < height; i += 3)
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(currentLoc.clone().add(0, i, 0), radius * 0.75))
if (!affectedEntities.contains(entity) && !entity.equals(player))
for (int i = 0; i < height; i += 3) {
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(currentLoc.clone().add(0, i, 0), radius * 0.75)) {
if (!affectedEntities.contains(entity) && !entity.equals(player)) {
affectedEntities.add(entity);
}
}
}
for (Entity entity : affectedEntities) {
Vector forceDir = GeneralMethods.getDirection(entity.getLocation(), currentLoc.clone().add(0, height, 0));
if (entity instanceof Player) {
if (Commands.invincible.contains(((Player) entity).getName()))
if (Commands.invincible.contains(((Player) entity).getName())) {
break;
}
}
entity.setVelocity(forceDir.clone().normalize().multiply(0.3));
}
}
else if (ability.equalsIgnoreCase("AirStream")) {
} else if (abilityName.equalsIgnoreCase("AirStream")) {
if (destination == null) {
if (bPlayer.isOnCooldown("AirStream") && !AvatarState.isAvatarState(player)) {
remove();
return;
}
bPlayer.addCooldown("AirStream", cooldown);
origin = player.getEyeLocation();
currentLoc = origin.clone();
}
Entity target = GeneralMethods.getTargetedEntity(player, range, new ArrayList<Entity>());
Entity target = GeneralMethods.getTargetedEntity(player, range);
if (target instanceof Player) {
if (Commands.invincible.contains(((Player) target).getName()))
if (Commands.invincible.contains(((Player) target).getName())) {
return;
}
}
if (target != null && target.getLocation().distance(currentLoc) > 7)
if (target != null && target.getLocation().distanceSquared(currentLoc) > 49) {
destination = target.getLocation();
else
destination = GeneralMethods.getTargetedLocation(player, range, EarthMethods.transparentToEarthbending);
} else {
destination = GeneralMethods.getTargetedLocation(player, range, getTransparentMaterial());
}
direction = GeneralMethods.getDirection(currentLoc, destination).normalize();
currentLoc.add(direction.clone().multiply(speed));
if (!EarthMethods.isTransparentToEarthbending(player, currentLoc.getBlock()))
currentLoc.subtract(direction.clone().multiply(speed));
if (player.getWorld() != currentLoc.getWorld()) {
remove();
return;
}
if (Math.abs(player.getLocation().distance(currentLoc)) > range) {
remove();
return;
} else if (affectedEntities.size() > 0 && System.currentTimeMillis() - time >= airStreamEntityDuration) {
remove();
return;
} else if (!player.isSneaking()) {
remove();
return;
} else if (!EarthMethods.isTransparentToEarthbending(player, currentLoc.getBlock())) {
} else if (Math.abs(player.getLocation().distanceSquared(currentLoc)) > range * range) {
remove();
return;
} else if (currentLoc.getY() - origin.getY() > airStreamEntityHeight) {
} else if (affectedEntities.size() > 0 && System.currentTimeMillis() - time >= airStreamEntityCarryDuration) {
remove();
return;
} else if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", currentLoc)) {
} else if (!isTransparent(currentLoc.getBlock())) {
remove();
return;
} else if (FireMethods.isWithinFireShield(currentLoc)) {
} else if (currentLoc.getY() - origin.getY() > airStreamMaxEntityHeight) {
remove();
return;
} else if (AirMethods.isWithinAirShield(currentLoc)) {
} else if (GeneralMethods.isRegionProtectedFromBuild(this, currentLoc)) {
remove();
return;
} else if (FireAbility.isWithinFireShield(currentLoc)) {
remove();
return;
} else if (isWithinAirShield(currentLoc)) {
remove();
return;
} else if (!isTransparent(currentLoc.getBlock())) {
currentLoc.subtract(direction.clone().multiply(speed));
}
for (int i = 0; i < 10; i++) {
@ -270,7 +237,7 @@ public class AirCombo implements ConfigLoadable {
public void run() {
for (int angle = -180; angle <= 180; angle += 45) {
Vector orthog = GeneralMethods.getOrthogonalVector(dir.clone(), angle, 0.5);
AirMethods.playAirbendingParticles(loc.clone().add(orthog), 1, 0F, 0F, 0F);
playAirbendingParticles(loc.clone().add(orthog), 1, 0F, 0F, 0F);
}
}
};
@ -296,61 +263,16 @@ public class AirCombo implements ConfigLoadable {
entity.setVelocity(force.clone().normalize().multiply(speed));
entity.setFallDistance(0F);
}
}
else if (ability.equalsIgnoreCase("AirSlice")) {
} else if (abilityName.equalsIgnoreCase("AirSweep")) {
if (origin == null) {
if (bPlayer.isOnCooldown("AirSlice") && !AvatarState.isAvatarState(player)) {
remove();
return;
}
bPlayer.addCooldown("AirSlice", cooldown);
origin = player.getLocation();
currentLoc = origin.clone();
direction = player.getEyeLocation().getDirection();
for (double i = -5; i < 10; i += 1) {
FireComboStream fs = new FireComboStream(null, direction.clone().add(new Vector(0, 0.03 * i, 0)),
player.getLocation(), range, speed, "AirSlice");
fs.setDensity(1);
fs.setSpread(0F);
fs.setUseNewParticles(true);
fs.setParticleEffect(AirMethods.getAirbendingParticles());
fs.setCollides(false);
fs.runTaskTimer(ProjectKorra.plugin, 0, 1L);
tasks.add(fs);
}
}
manageAirVectors();
for (Entity entity : affectedEntities)
if (entity instanceof LivingEntity) {
remove();
return;
}
}
else if (ability.equalsIgnoreCase("AirSweep")) {
if (origin == null) {
if (bPlayer.isOnCooldown("AirSweep") && !AvatarState.isAvatarState(player)) {
remove();
return;
}
bPlayer.addCooldown("AirSweep", cooldown);
direction = player.getEyeLocation().getDirection().normalize();
origin = player.getLocation().add(direction.clone().multiply(10));
}
if (progressCounter < 8)
if (progressCounter < 8) {
return;
}
if (destination == null) {
destination = player.getLocation().add(player.getEyeLocation().getDirection().normalize().multiply(10));
// if (Math.abs(origin.distance(destination)) < 7) {
// remove();
// return;
// }
Vector origToDest = GeneralMethods.getDirection(origin, destination);
for (double i = 0; i < 30; i++) {
Vector vec = GeneralMethods.getDirection(player.getLocation(),
@ -360,7 +282,7 @@ public class AirCombo implements ConfigLoadable {
fs.setDensity(1);
fs.setSpread(0F);
fs.setUseNewParticles(true);
fs.setParticleEffect(AirMethods.getAirbendingParticles());
fs.setParticleEffect(getAirbendingParticles());
fs.setCollides(false);
fs.runTaskTimer(ProjectKorra.plugin, (long) (i / 2.5), 1L);
tasks.add(fs);
@ -385,15 +307,20 @@ public class AirCombo implements ConfigLoadable {
FireComboStream fstream = (FireComboStream) tasks.get(i);
Location loc = fstream.getLocation();
if (!EarthMethods.isTransparentToEarthbending(player, loc.getBlock())) {
if (!EarthMethods.isTransparentToEarthbending(player, loc.clone().add(0, 0.2, 0).getBlock())) {
if (GeneralMethods.isRegionProtectedFromBuild(this, loc)) {
fstream.remove();
return;
}
if (!isTransparent(loc.getBlock())) {
if (!isTransparent(loc.clone().add(0, 0.2, 0).getBlock())) {
fstream.remove();
return;
}
}
if (i % 3 == 0) {
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(loc, 2.5)) {
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", entity.getLocation())) {
if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) {
remove();
return;
}
@ -403,89 +330,53 @@ public class AirCombo implements ConfigLoadable {
Vector force = fstream.getDirection();
entity.setVelocity(force.multiply(knockback));
}
if (damage != 0)
if (entity instanceof LivingEntity)
if (damage != 0) {
if (entity instanceof LivingEntity) {
if (fstream.getAbility().equalsIgnoreCase("AirSweep")) {
GeneralMethods.damageEntity(player, entity, damage, Element.Air, "AirSweep");
GeneralMethods.damageEntity(this, entity, damage);
} else {
GeneralMethods.damageEntity(player, entity, damage, Element.Air, "AirCombo");
GeneralMethods.damageEntity(this, entity, damage);
}
}
}
}
}
if (GeneralMethods.blockAbilities(player, FireCombo.abilitiesToBlock, loc, 1)) {
if (GeneralMethods.blockAbilities(player, FireCombo.getBlockableAbilities(), loc, 1)) {
fstream.remove();
}
}
}
}
@Override
public void remove() {
instances.remove(this);
for (BukkitRunnable task : tasks)
super.remove();
for (BukkitRunnable task : tasks) {
task.cancel();
for (int i = 0; i < flights.size(); i++) {
Flight flight = flights.get(i);
}
for (Flight flight : flights) {
flight.revert();
flight.remove();
flights.remove(i);
i--;
}
}
public static void progressAll() {
for (int i = instances.size() - 1; i >= 0; i--)
instances.get(i).progress();
}
public static void removeAll() {
for (int i = instances.size() - 1; i >= 0; i--) {
instances.get(i).remove();
}
}
public Player getPlayer() {
return player;
}
public static ArrayList<AirCombo> getAirCombo(Player player) {
ArrayList<AirCombo> list = new ArrayList<AirCombo>();
for (AirCombo combo : instances)
if (combo.player != null && combo.player == player)
list.add(combo);
return list;
}
public static ArrayList<AirCombo> getAirCombo(Player player, ClickType type) {
ArrayList<AirCombo> list = new ArrayList<AirCombo>();
for (AirCombo combo : instances)
if (combo.player != null && combo.player == player && combo.type != null && combo.type == type)
list.add(combo);
return list;
}
public static boolean removeAroundPoint(Player player, String ability, Location loc, double radius) {
boolean removed = false;
for (int i = 0; i < instances.size(); i++) {
AirCombo combo = instances.get(i);
if (combo.getPlayer().equals(player))
for (AirCombo combo : CoreAbility.getAbilities(AirCombo.class)) {
if (combo.getPlayer().equals(player)) {
continue;
if (ability.equalsIgnoreCase("Twister") && combo.ability.equalsIgnoreCase("Twister")) {
} else if (ability.equalsIgnoreCase("Twister") && combo.abilityName.equalsIgnoreCase("Twister")) {
if (combo.currentLoc != null && Math.abs(combo.currentLoc.distance(loc)) <= radius) {
instances.remove(combo);
combo.remove();
removed = true;
}
}
else if (ability.equalsIgnoreCase("AirStream") && combo.ability.equalsIgnoreCase("AirStream")) {
} else if (ability.equalsIgnoreCase("AirStream") && combo.abilityName.equalsIgnoreCase("AirStream")) {
if (combo.currentLoc != null && Math.abs(combo.currentLoc.distance(loc)) <= radius) {
instances.remove(combo);
combo.remove();
removed = true;
}
}
else if (ability.equalsIgnoreCase("AirSweep") && combo.ability.equalsIgnoreCase("AirSweep")) {
} else if (ability.equalsIgnoreCase("AirSweep") && combo.abilityName.equalsIgnoreCase("AirSweep")) {
for (int j = 0; j < combo.tasks.size(); j++) {
FireComboStream fs = (FireComboStream) combo.tasks.get(j);
if (fs.getLocation() != null && fs.getLocation().getWorld().equals(loc.getWorld())
@ -500,28 +391,271 @@ public class AirCombo implements ConfigLoadable {
}
@Override
public void reloadVariables() {
twisterSpeed = config.get().getDouble("Abilities.Air.AirCombo.Twister.Speed");
twisterRange = config.get().getDouble("Abilities.Air.AirCombo.Twister.Range");
twisterHeight = config.get().getDouble("Abilities.Air.AirCombo.Twister.Height");
twisterRadius = config.get().getDouble("Abilities.Air.AirCombo.Twister.Radius");
twisterDegreePerParticle = config.get().getDouble("Abilities.Air.AirCombo.Twister.DegreesPerParticle");
twisterHeightPerParticle = config.get().getDouble("Abilities.Air.AirCombo.Twister.HeightPerParticle");
twisterRemoveDelay = config.get().getLong("Abilities.Air.AirCombo.Twister.RemoveDelay");
twisterCooldown = config.get().getLong("Abilities.Air.AirCombo.Twister.Cooldown");
airStreamSpeed = config.get().getDouble("Abilities.Air.AirCombo.AirStream.Speed");
airStreamRange = config.get().getDouble("Abilities.Air.AirCombo.AirStream.Range");
airStreamEntityHeight = config.get().getDouble("Abilities.Air.AirCombo.AirStream.EntityHeight");
airStreamEntityDuration = config.get().getLong("Abilities.Air.AirCombo.AirStream.EntityDuration");
airStreamCooldown = config.get().getLong("Abilities.Air.AirCombo.AirStream.Cooldown");
airSweepSpeed = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Speed");
airSweepRange = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Range");
airSweepDamage = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Damage");
airSweepKnockback = config.get().getDouble("Abilities.Air.AirCombo.AirSweep.Knockback");
airSweepCooldown = config.get().getLong("Abilities.Air.AirCombo.AirSweep.Cooldown");
enabled = config.get().getBoolean("Abilities.Air.AirCombo.Enabled");
public String getName() {
return abilityName == null ? "AirCombo" : abilityName;
}
@Override
public Location getLocation() {
if (currentLoc != null) {
return currentLoc;
} else if (origin != null) {
return origin;
} else if (player != null) {
return player.getLocation();
}
return null;
}
@Override
public long getCooldown() {
return cooldown;
}
@Override
public boolean isHiddenAbility() {
return true;
}
@Override
public boolean isSneakAbility() {
return true;
}
@Override
public boolean isHarmlessAbility() {
return false;
}
@Override
public String getInstructions() {
return null;
}
@Override
public Object createNewComboInstance(Player player) {
return null;
}
@Override
public ArrayList<AbilityInformation> getCombination() {
return null;
}
public String getAbilityName() {
return abilityName;
}
public void setAbilityName(String abilityName) {
this.abilityName = abilityName;
}
public Location getOrigin() {
return origin;
}
public void setOrigin(Location origin) {
this.origin = origin;
}
public Location getCurrentLoc() {
return currentLoc;
}
public void setCurrentLoc(Location currentLoc) {
this.currentLoc = currentLoc;
}
public Location getDestination() {
return destination;
}
public void setDestination(Location destination) {
this.destination = destination;
}
public Vector getDirection() {
return direction;
}
public void setDirection(Vector direction) {
this.direction = direction;
}
public AbilityState getState() {
return state;
}
public void setState(AbilityState state) {
this.state = state;
}
public boolean isEnabled() {
return isEnabled;
}
public void setEnabled(boolean isEnabled) {
this.isEnabled = isEnabled;
}
public int getProgressCounter() {
return progressCounter;
}
public void setProgressCounter(int progressCounter) {
this.progressCounter = progressCounter;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public double getDamage() {
return damage;
}
public void setDamage(double damage) {
this.damage = damage;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public double getRange() {
return range;
}
public void setRange(double range) {
this.range = range;
}
public double getKnockback() {
return knockback;
}
public void setKnockback(double knockback) {
this.knockback = knockback;
}
public double getAirStreamMaxEntityHeight() {
return airStreamMaxEntityHeight;
}
public void setAirStreamMaxEntityHeight(double airStreamMaxEntityHeight) {
this.airStreamMaxEntityHeight = airStreamMaxEntityHeight;
}
public double getAirStreamEntityCarryDuration() {
return airStreamEntityCarryDuration;
}
public void setAirStreamEntityCarryDuration(double airStreamEntityCarryDuration) {
this.airStreamEntityCarryDuration = airStreamEntityCarryDuration;
}
public double getTwisterHeight() {
return twisterHeight;
}
public void setTwisterHeight(double twisterHeight) {
this.twisterHeight = twisterHeight;
}
public double getTwisterRadius() {
return twisterRadius;
}
public void setTwisterRadius(double twisterRadius) {
this.twisterRadius = twisterRadius;
}
public double getTwisterDegreeParticles() {
return twisterDegreeParticles;
}
public void setTwisterDegreeParticles(double twisterDegreeParticles) {
this.twisterDegreeParticles = twisterDegreeParticles;
}
public double getTwisterHeightParticles() {
return twisterHeightParticles;
}
public void setTwisterHeightParticles(double twisterHeightParticles) {
this.twisterHeightParticles = twisterHeightParticles;
}
public double getTwisterRemoveDelay() {
return twisterRemoveDelay;
}
public void setTwisterRemoveDelay(double twisterRemoveDelay) {
this.twisterRemoveDelay = twisterRemoveDelay;
}
public ArrayList<Entity> getAffectedEntities() {
return affectedEntities;
}
public ArrayList<BukkitRunnable> getTasks() {
return tasks;
}
public ArrayList<Flight> getFlights() {
return flights;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
public class AirStream extends AirCombo {
public AirStream(Player player, String name) {
super(player, "AirStream");
}
@Override
public String getName() {
return "AirStream";
}
}
public class AirSweep extends AirCombo {
public AirSweep(Player player, String name) {
super(player, "AirSweep");
}
@Override
public String getName() {
return "AirSweep";
}
}
public class Twister extends AirCombo {
public Twister(Player player, String name) {
super(player, "Twister");
}
@Override
public String getName() {
return "Twister";
}
}
}

View file

@ -0,0 +1,142 @@
package com.projectkorra.projectkorra.airbending;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.FlightAbility;
import com.projectkorra.projectkorra.util.Flight;
public class AirFlight extends FlightAbility {
private static final ConcurrentHashMap<String, Integer> HITS = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, Boolean> HOVERING = new ConcurrentHashMap<>();
private boolean firstProgressIteration;
private int maxHitsBeforeRemoval;
private Flight flight;
public AirFlight(Player player) {
super(player);
this.maxHitsBeforeRemoval = 4;
this.firstProgressIteration = true;
start();
}
public static void addHit(Player player) {
AirFlight airFlight = CoreAbility.getAbility(player, AirFlight.class);
if (airFlight != null) {
if (HITS.containsKey(player.getName())) {
if (HITS.get(player.getName()) >= airFlight.maxHitsBeforeRemoval) {
HITS.remove(player.getName());
remove(player);
}
} else {
HITS.put(player.getName(), 1);
}
}
}
public static boolean isFlying(Player player) {
return CoreAbility.hasAbility(player, AirFlight.class);
}
public static boolean isHovering(Player player) {
return HOVERING.containsKey(player.getName());
}
public static void remove(Player player) {
if (isFlying(player)) {
CoreAbility.getAbility(player, AirFlight.class).remove();
}
}
public static void cleanup() {
HITS.clear();
HOVERING.clear();
}
public static void setHovering(Player player, boolean bool) {
String playername = player.getName();
if (bool) {
if (!HOVERING.containsKey(playername)) {
HOVERING.put(playername, true);
player.setVelocity(new Vector(0, 0, 0));
}
} else {
if (HOVERING.containsKey(playername)) {
HOVERING.remove(playername);
}
}
}
@Override
public void progress() {
boolean isHovering = isHovering(player);
if (!bPlayer.canBend(this)) {
remove();
return;
} else if (!player.isSneaking() && !isHovering && !firstProgressIteration) {
remove();
return;
} else if (player.getLocation().subtract(0, 0.5, 0).getBlock().getType() != Material.AIR) {
remove();
return;
}
if (flight == null) {
flight = new Flight(player);
player.setAllowFlight(true);
player.setVelocity(player.getEyeLocation().getDirection().normalize());
}
if (isHovering) {
Vector vec = player.getVelocity().clone();
vec.setY(0);
player.setVelocity(vec);
} else {
player.setVelocity(player.getEyeLocation().getDirection().normalize());
}
}
@Override
public void remove() {
super.remove();
HITS.remove(player.getName());
HOVERING.remove(player.getName());
if (flight != null) {
flight.revert();
}
}
@Override
public String getName() {
return "Flight";
}
@Override
public Location getLocation() {
return player != null ? player.getLocation() : null;
}
@Override
public long getCooldown() {
return 0;
}
@Override
public boolean isSneakAbility() {
return true;
}
@Override
public boolean isHarmlessAbility() {
return true;
}
}

View file

@ -1,268 +0,0 @@
package com.projectkorra.projectkorra.airbending;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AbilityModuleManager;
import com.projectkorra.projectkorra.util.ParticleEffect;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class AirMethods {
private static ProjectKorra plugin;
private static FileConfiguration config = ProjectKorra.plugin.getConfig();
public AirMethods(ProjectKorra plugin) {
AirMethods.plugin = plugin;
}
/**
* Checks to see if a player can use Flight.
*
* @param player The player to check
* @return true If player has permission node "bending.air.flight"
*/
public static boolean canAirFlight(Player player) {
if (player.hasPermission("bending.air.flight"))
return true;
return false;
}
/**
* Checks to see if a player can use SpiritualProjection.
*
* @param player The player to check
* @return true If player has permission node "bending.air.spiritualprojection"
*/
public static boolean canUseSpiritualProjection(Player player) {
if (player.hasPermission("bending.air.spiritualprojection"))
return true;
return false;
}
/**
* Gets the AirColor from the config.
*
* @return Config specified ChatColor
*/
public static ChatColor getAirColor() {
return ChatColor.valueOf(config.getString("Properties.Chat.Colors.Air"));
}
/**
* Gets the AirSubColor from the config.
*
* @return Config specified ChatColor
*/
public static ChatColor getAirSubColor() {
return ChatColor.valueOf(config.getString("Properties.Chat.Colors.AirSub"));
}
/**
* Checks whether an ability is an air ability.
*
* @param ability The ability to check
* @return true If the ability is an air ability.
*/
public static boolean isAirAbility(String ability) {
return AbilityModuleManager.airbendingabilities.contains(ability);
}
/**
* Checks whether an ability is a Flight ability.
*
* @param ability The ability to check
* @return true If the ability is a Flight ability.
*/
public static boolean isFlightAbility(String ability) {
return AbilityModuleManager.flightabilities.contains(ability);
}
/**
* Checks whether an ability is a SpiritualProjection ability.
*
* @param ability The ability to check
* @return true If the ability is a SpiritualProjection ability.
*/
public static boolean isSpiritualProjectionAbility(String ability) {
return AbilityModuleManager.spiritualprojectionabilities.contains(ability);
}
/**
* Gets the Air Particles from the config.
*
* @return Config specified ParticleEffect
*/
public static ParticleEffect getAirbendingParticles() {
String particle = plugin.getConfig().getString("Properties.Air.Particles");
if (particle == null)
return ParticleEffect.CLOUD;
else if (particle.equalsIgnoreCase("spell"))
return ParticleEffect.SPELL;
else if (particle.equalsIgnoreCase("blacksmoke"))
return ParticleEffect.SMOKE;
else if (particle.equalsIgnoreCase("smoke"))
return ParticleEffect.CLOUD;
else if (particle.equalsIgnoreCase("smallsmoke"))
return ParticleEffect.SNOW_SHOVEL;
else
return ParticleEffect.CLOUD;
}
/**
* Plays an integer amount of air particles in a location.
*
* @param loc The location to use
* @param amount The amount of particles
*/
public static void playAirbendingParticles(Location loc, int amount) {
playAirbendingParticles(loc, amount, (float) Math.random(), (float) Math.random(), (float) Math.random());
}
/**
* Plays an integer amount of air particles in a location with a given xOffset, yOffset, and
* zOffset.
*
* @param loc The location to use
* @param amount The amount of particles
* @param xOffset The xOffset to use
* @param yOffset The yOffset to use
* @param zOffset The zOffset to use
*/
public static void playAirbendingParticles(Location loc, int amount, float xOffset, float yOffset, float zOffset) {
getAirbendingParticles().display(loc, xOffset, yOffset, zOffset, 0, amount);
}
/**
* Removes all air spouts in a location within a certain radius.
*
* @param loc The location to use
* @param radius The radius around the location to remove spouts in
* @param source The player causing the removal
*/
public static void removeAirSpouts(Location loc, double radius, Player source) {
AirSpout.removeSpouts(loc, radius, source);
}
/**
* Removes all air spouts in a location with a radius of 1.5.
*
* @param loc The location to use
* @param source The player causing the removal
*/
public static void removeAirSpouts(Location loc, Player source) {
removeAirSpouts(loc, 1.5, source);
}
/**
* Stops all airbending systems. SHOULD ONLY BE USED ON PLUGIN DISABLING!
*/
public static void stopBending() {
AirBlast.removeAll();
AirBubble.removeAll();
AirShield.removeAll();
AirSuction.removeAll();
AirScooter.removeAll();
AirSpout.removeAll();
AirSwipe.removeAll();
Tornado.removeAll();
AirBurst.removeAll();
Suffocate.removeAll();
AirCombo.removeAll();
FlightAbility.removeAll();
}
/**
* Breaks a breathbendng hold on an entity or one a player is inflicting on an entity.
*
* @param entity The entity to be acted upon
*/
public static void breakBreathbendingHold(Entity entity) {
if (Suffocate.isBreathbent(entity)) {
Suffocate.breakSuffocate(entity);
return;
}
if (entity instanceof Player) {
Player player = (Player) entity;
if (Suffocate.isChannelingSphere(player)) {
Suffocate.remove(player);
}
}
}
/**
* Plays the Airbending Sound at a location if enabled in the config.
*
* @param loc The location to play the sound at
*/
public static void playAirbendingSound(Location loc) {
if (plugin.getConfig().getBoolean("Properties.Air.PlaySound")) {
loc.getWorld().playSound(loc, Sound.CREEPER_HISS, 1, 5);
}
}
/**
* Checks whether a location is within an AirShield.
*
* @param loc The location to check
* @return true If the location is inside an AirShield.
*/
public static boolean isWithinAirShield(Location loc) {
List<String> list = new ArrayList<String>();
list.add("AirShield");
return GeneralMethods.blockAbilities(null, list, loc, 0);
}
/**
* Checks whether a player can use the Flight ability.
*
* @param player The player to check
* @param first If the move is being activated
* @param hovering If the player is using the move to hover
* @return true If the player can use the move.
*/
public static boolean canFly(Player player, boolean first, boolean hovering) {
BendingPlayer bender = GeneralMethods.getBendingPlayer(player.getName());
if (!player.isOnline())
return false;
if (!player.isSneaking()) {
if (first) {
} else if (hovering) {
} else {
return false;
}
}
if (bender.isChiBlocked())
return false;
if (!player.isOnline())
return false;
if (bender.isPermaRemoved())
return false;
if (!bender.getElements().contains(Element.Air))
return false;
if (!GeneralMethods.canBend(player.getName(), "Flight"))
return false;
if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("Flight"))
return false;
if (GeneralMethods.isRegionProtectedFromBuild(player, "Flight", player.getLocation()))
return false;
if (player.getLocation().subtract(0, 0.5, 0).getBlock().getType() != Material.AIR)
return false;
return true;
}
}

View file

@ -1,10 +1,10 @@
package com.projectkorra.projectkorra.airbending;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import org.bukkit.Server;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
@ -12,65 +12,53 @@ import org.bukkit.potion.PotionEffectType;
import java.util.concurrent.ConcurrentHashMap;
public class AirPassive implements ConfigLoadable {
public class AirPassive {
private static ConcurrentHashMap<Player, Float> food = new ConcurrentHashMap<Player, Float>();
private static float factor = (float) config.get().getDouble("Abilities.Air.Passive.Factor");
private static int speedPower = config.get().getInt("Abilities.Air.Passive.Speed");
private static int jumpPower = config.get().getInt("Abilities.Air.Passive.Jump");
private static final ConcurrentHashMap<Player, Float> FOOD = new ConcurrentHashMap<>();
public static float getExhaustion(Player player, float level) {
if (!food.keySet().contains(player)) {
food.put(player, level);
if (!FOOD.keySet().contains(player)) {
FOOD.put(player, level);
return level;
} else {
float oldlevel = food.get(player);
float oldlevel = FOOD.get(player);
if (level < oldlevel) {
level = 0;
} else {
factor = (float) config.get().getDouble("Abilities.Air.Passive.Factor");
level = (level - oldlevel) * factor + oldlevel;
double factor = getFactor();
level = (float) ((level - oldlevel) * factor + oldlevel);
}
food.replace(player, level);
FOOD.replace(player, level);
return level;
}
}
public static void handlePassive(Server server) {
for (World world : server.getWorlds()) {
public static void handlePassive() {
for (World world : Bukkit.getServer().getWorlds()) {
for (Player player : world.getPlayers()) {
if (!player.isOnline())
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (!player.isOnline() || bPlayer == null) {
return;
if (GeneralMethods.canBendPassive(player.getName(), Element.Air)) {
player.setExhaustion(getExhaustion(player, player.getExhaustion())); // Handles
// Food
// Passive
}
if (bPlayer.canBendPassive(Element.AIR)) {
player.setExhaustion(getExhaustion(player, player.getExhaustion()));
if (player.isSprinting()) {
if (!player.hasPotionEffect(PotionEffectType.SPEED)) {
speedPower = config.get().getInt("Abilities.Air.Passive.Speed");
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 60, speedPower - 1)); // Handles
// Speed
// Passive
int speedPower = ConfigManager.getConfig().getInt("Abilities.Air.Passive.Speed");
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 60, speedPower - 1));
}
if (!player.hasPotionEffect(PotionEffectType.JUMP)) {
jumpPower = config.get().getInt("Abilities.Air.Passive.Jump");
player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 60, jumpPower - 1)); // Handles
// jump
// passive.
int jumpPower = ConfigManager.getConfig().getInt("Abilities.Air.Passive.Jump");
player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 60, jumpPower - 1));
}
}
}
}
}
}
@Override
public void reloadVariables() {
factor = (float) config.get().getDouble("Abilities.Air.Passive.Factor");
speedPower = config.get().getInt("Abilities.Air.Passive.Speed");
jumpPower = config.get().getInt("Abilities.Air.Passive.Jump");
public static double getFactor() {
return ConfigManager.getConfig().getDouble("Abilities.Air.Passive.Factor");
}
}

View file

@ -1,9 +1,10 @@
package com.projectkorra.projectkorra.airbending;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.WaterAbility;
import com.projectkorra.projectkorra.util.Flight;
import com.projectkorra.projectkorra.waterbending.WaterMethods;
import org.bukkit.Location;
import org.bukkit.block.Block;
@ -13,48 +14,50 @@ import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Random;
public class AirScooter implements ConfigLoadable {
public class AirScooter extends AirAbility {
public static ConcurrentHashMap<Player, AirScooter> instances = new ConcurrentHashMap<>();
private static final long SPIN_INTERVAL = 100;
private static final double SCOOTER_RADIUS = 1;
private static final double MAX_HEIGHT_FROM_GROUND = 7;
private static double configSpeed = config.get().getDouble("Abilities.Air.AirScooter.Speed");
private static final long interval = 100;
private static final double scooterradius = 1;
private Player player;
private Block floorblock;
private long time;
private double speed;
private ArrayList<Double> angles = new ArrayList<Double>();
private double spinInterval;
private double radius;
private double maxHeightFromGround;
private Block floorblock;
private Random random;
private ArrayList<Double> angles;
public AirScooter(Player player) {
/* Initial Check */
super(player);
if (check(player)) {
return;
} else if (!player.isSprinting() || GeneralMethods.isSolid(player.getEyeLocation().getBlock())
|| player.getEyeLocation().getBlock().isLiquid()) {
return;
} else if (GeneralMethods.isSolid(player.getLocation().add(0, -.5, 0).getBlock())) {
return;
}
if (!player.isSprinting() || GeneralMethods.isSolid(player.getEyeLocation().getBlock())
|| player.getEyeLocation().getBlock().isLiquid())
return;
if (GeneralMethods.isSolid(player.getLocation().add(0, -.5, 0).getBlock()))
return;
/* End Initial Check */
// reloadVariables();
this.player = player;
// wasflying = player.isFlying();
// canfly = player.getAllowFlight();
this.speed = getConfig().getDouble("Abilities.Air.AirScooter.Speed");
this.spinInterval = SPIN_INTERVAL;
this.radius = SCOOTER_RADIUS;
this.maxHeightFromGround = MAX_HEIGHT_FROM_GROUND;
this.random = new Random();
this.angles = new ArrayList<>();
new Flight(player);
player.setAllowFlight(true);
player.setFlying(true);
player.setSprinting(false);
time = System.currentTimeMillis();
for (int i = 0; i < 5; i++) {
angles.add((double) (60 * i));
}
instances.put(player, this);
speed = configSpeed;
progress();
start();
}
/**
@ -64,24 +67,16 @@ public class AirScooter implements ConfigLoadable {
* @return false If player doesn't have an instance
*/
public static boolean check(Player player) {
if (instances.containsKey(player)) {
instances.get(player).remove();
if (CoreAbility.hasAbility(player, AirScooter.class)) {
CoreAbility.getAbility(player, AirScooter.class).remove();
return true;
}
return false;
}
public static ArrayList<Player> getPlayers() {
ArrayList<Player> players = new ArrayList<Player>();
for (AirScooter scooter : instances.values()) {
players.add(scooter.getPlayer());
}
return players;
}
private void getFloor() {
floorblock = null;
for (int i = 0; i <= 7; i++) {
for (int i = 0; i <= maxHeightFromGround; i++) {
Block block = player.getEyeLocation().getBlock().getRelative(BlockFace.DOWN, i);
if (GeneralMethods.isSolid(block) || block.isLiquid()) {
floorblock = block;
@ -90,62 +85,26 @@ public class AirScooter implements ConfigLoadable {
}
}
public Player getPlayer() {
return player;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double value) {
this.speed = value; // Used in PK Items
}
public boolean progress() {
if (player.isDead() || !player.isOnline()) {
remove();
return false;
}
@Override
public void progress() {
getFloor();
// Methods.verbose(player);
if (floorblock == null) {
if (floorblock == null || !bPlayer.canBend(this) || !player.isFlying()) {
remove();
return false;
return;
}
if (!GeneralMethods.canBend(player.getName(), "AirScooter")) {
remove();
return false;
}
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirScooter", player.getLocation())) {
remove();
return false;
}
// if (Methods
// .isSolid(player
// .getEyeLocation()
// .clone()
// .add(player.getEyeLocation().getDirection().clone()
// .normalize()).getBlock())) {
// remove();
// return;
// }
// player.sendBlockChange(floorblock.getLocation(), 89, (byte) 1);
// player.getLocation().setY((double) floorblock.getY() + 2.5);
Vector velocity = player.getEyeLocation().getDirection().clone();
velocity.setY(0);
velocity = velocity.clone().normalize().multiply(speed);
if (System.currentTimeMillis() > time + interval) {
time = System.currentTimeMillis();
if (System.currentTimeMillis() > startTime + spinInterval) {
if (player.getVelocity().length() < speed * .5) {
remove();
return false;
return;
}
spinScooter();
}
double distance = player.getLocation().getY() - (double) floorblock.getY();
double dx = Math.abs(distance - 2.4);
if (distance > 2.75) {
@ -155,58 +114,108 @@ public class AirScooter implements ConfigLoadable {
} else {
velocity.setY(0);
}
Location loc = player.getLocation();
if (!WaterMethods.isWater(player.getLocation().add(0, 2, 0).getBlock()))
if (!WaterAbility.isWater(player.getLocation().add(0, 2, 0).getBlock())) {
loc.setY((double) floorblock.getY() + 1.5);
else
return false;
// player.setFlying(true);
// player.teleport(loc.add(velocity));
} else {
return;
}
player.setSprinting(false);
player.removePotionEffect(PotionEffectType.SPEED);
player.setVelocity(velocity);
if (GeneralMethods.rand.nextInt(4) == 0) {
AirMethods.playAirbendingSound(player.getLocation());
}
return true;
}
public static void progressAll() {
for (AirScooter ability : instances.values()) {
ability.progress();
if (random.nextInt(4) == 0) {
playAirbendingSound(player.getLocation());
}
}
@Override
public void reloadVariables() {
configSpeed = config.get().getDouble("Abilities.Air.AirScooter.Speed");
this.speed = configSpeed;
}
public void remove() {
instances.remove(player);
}
public static void removeAll() {
for (AirScooter ability : instances.values()) {
ability.remove();
}
super.remove();
player.setFlying(false);
player.setAllowFlight(false);
player.setSprinting(false);
}
private void spinScooter() {
Location origin = player.getLocation().clone();
origin.add(0, -scooterradius, 0);
origin.add(0, -radius, 0);
for (int i = 0; i < 5; i++) {
double x = Math.cos(Math.toRadians(angles.get(i))) * scooterradius;
double y = ((double) i) / 2 * scooterradius - scooterradius;
double z = Math.sin(Math.toRadians(angles.get(i))) * scooterradius;
AirMethods.playAirbendingParticles(origin.clone().add(x, y, z), 7);
// player.getWorld().playEffect(origin.clone().add(x, y, z),
// Effect.SMOKE, 4, (int) AirBlast.defaultrange);
double x = Math.cos(Math.toRadians(angles.get(i))) * radius;
double y = ((double) i) / 2 * radius - radius;
double z = Math.sin(Math.toRadians(angles.get(i))) * radius;
playAirbendingParticles(origin.clone().add(x, y, z), 7);
}
for (int i = 0; i < 5; i++) {
angles.set(i, angles.get(i) + 10);
}
}
@Override
public String getName() {
return "AirScooter";
}
@Override
public Location getLocation() {
return player.getLocation() != null ? player.getLocation() : null;
}
@Override
public long getCooldown() {
return 0;
}
@Override
public boolean isSneakAbility() {
return false;
}
@Override
public boolean isHarmlessAbility() {
return true;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public double getSpinInterval() {
return spinInterval;
}
public void setSpinInterval(double spinInterval) {
this.spinInterval = spinInterval;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getMaxHeightFromGround() {
return maxHeightFromGround;
}
public void setMaxHeightFromGround(double maxHeightFromGround) {
this.maxHeightFromGround = maxHeightFromGround;
}
public Block getFloorblock() {
return floorblock;
}
public void setFloorblock(Block floorblock) {
this.floorblock = floorblock;
}
}

View file

@ -1,14 +1,15 @@
package com.projectkorra.projectkorra.airbending;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AvatarState;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.avatar.AvatarState;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
import com.projectkorra.projectkorra.earthbending.EarthBlast;
import com.projectkorra.projectkorra.earthbending.SandSpout;
import com.projectkorra.projectkorra.firebending.BlazeArc;
import com.projectkorra.projectkorra.firebending.Combustion;
import com.projectkorra.projectkorra.firebending.FireBlast;
import com.projectkorra.projectkorra.firebending.FireStream;
import com.projectkorra.projectkorra.waterbending.WaterManipulation;
import com.projectkorra.projectkorra.waterbending.WaterSpout;
@ -21,146 +22,84 @@ import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import java.util.HashMap;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class AirShield implements ConfigLoadable {
public static ConcurrentHashMap<Player, AirShield> instances = new ConcurrentHashMap<>();
private static double MAX_RADIUS = config.get().getDouble("Abilities.Air.AirShield.Radius");
private static boolean isToggle = config.get().getBoolean("Abilities.Air.AirShield.IsAvatarStateToggle");
private static int numberOfStreams = (int) (.75 * (double) MAX_RADIUS);
private double maxradius = MAX_RADIUS;
private double radius = MAX_RADIUS;
private double speedfactor;
private Player player;
private HashMap<Integer, Integer> angles = new HashMap<Integer, Integer>();
public class AirShield extends AirAbility {
private boolean isToggledByAvatarState;
private double maxRadius;
private double radius;
private double speed;
private int numberOfStreams;
private int particleCount;
private Random random;
private HashMap<Integer, Integer> angles;
public AirShield(Player player) {
/* Initial Check */
if (AvatarState.isAvatarState(player) && instances.containsKey(player) && isToggle) {
// instances.remove(player.getUniqueId());
instances.get(player).remove();
super(player);
this.maxRadius = getConfig().getDouble("Abilities.Air.AirShield.Radius");
this.isToggledByAvatarState = getConfig().getBoolean("Abilities.Air.AirShield.IsAvatarStateToggle");
this.radius = this.maxRadius;
this.speed = 10;
this.numberOfStreams = (int) (.75 * this.maxRadius);
this.particleCount = 5;
this.random = new Random();
this.angles = new HashMap<>();
if (bPlayer.isAvatarState() && CoreAbility.hasAbility(player, AirShield.class) && isToggledByAvatarState) {
CoreAbility.getAbility(player, AirShield.class).remove();
return;
}
/* End Initial Check */
// reloadVariables();
this.player = player;
int angle = 0;
int di = (int) (maxradius * 2 / numberOfStreams);
for (int i = -(int) maxradius + di; i < (int) maxradius; i += di) {
int di = (int) (maxRadius * 2 / numberOfStreams);
for (int i = -(int) maxRadius + di; i < (int) maxRadius; i += di) {
angles.put(i, angle);
angle += 90;
if (angle == 360)
if (angle == 360) {
angle = 0;
}
}
instances.put(player, this);
}
public static String getDescription() {
return "Air Shield is one of the most powerful defensive techniques in existence. "
+ "To use, simply sneak (default: shift). " + "This will create a whirlwind of air around the user, "
+ "with a small pocket of safe space in the center. "
+ "This wind will deflect all projectiles and will prevent any creature from "
+ "entering it for as long as its maintained. ";
start();
}
public static boolean isWithinShield(Location loc) {
for (AirShield ashield : instances.values()) {
if (ashield.player.getLocation().getWorld() != loc.getWorld())
for (AirShield ashield : CoreAbility.getAbilities(AirShield.class)) {
if (!ashield.player.getWorld().equals(loc.getWorld())) {
return false;
if (ashield.player.getLocation().distance(loc) <= ashield.radius)
} else if (ashield.player.getLocation().distanceSquared(loc) <= ashield.radius * ashield.radius) {
return true;
}
}
return false;
}
public double getMaxradius() {
return maxradius;
}
public Player getPlayer() {
return player;
}
public boolean progress() {
if (player.isDead() || !player.isOnline()) {
remove();
return false;
}
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirShield", player.getLocation())) {
remove();
return false;
}
speedfactor = 1;
if (!GeneralMethods.canBend(player.getName(), "AirShield") || player.getEyeLocation().getBlock().isLiquid()) {
remove();
return false;
}
if (GeneralMethods.getBoundAbility(player) == null) {
remove();
return false;
}
if (isToggle) {
if (((!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirShield")) || (!player.isSneaking()))
&& !AvatarState.isAvatarState(player)) {
remove();
return false;
}
} else {
if (((!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirShield")) || (!player.isSneaking()))) {
remove();
return false;
}
}
//
// if (((!Methods.getBoundAbility(player).equalsIgnoreCase("AirShield")) || (!player
// .isSneaking()))) {
// remove();
// return false;
// }
rotateShield();
return true;
}
public static void progressAll() {
for (AirShield ability : instances.values()) {
ability.progress();
}
}
public void remove() {
instances.remove(player);
}
public static void removeAll() {
for (AirShield ability : instances.values()) {
ability.remove();
}
}
@Override
public void reloadVariables() {
MAX_RADIUS = config.get().getDouble("Abilities.Air.AirShield.Radius");
isToggle = config.get().getBoolean("Abilities.Air.AirShield.IsAvatarStateToggle");
numberOfStreams = (int) (.75 * (double) MAX_RADIUS);
maxradius = MAX_RADIUS;
public void progress() {
// AvatarState can use AirShield even when AirShield is not in the bound slot
if (player.getEyeLocation().getBlock().isLiquid()) {
remove();
return;
} else if (!bPlayer.isAvatarState() || !isToggledByAvatarState) {
if (!player.isSneaking() || !bPlayer.canBend(this)) {
remove();
return;
}
} else if (!bPlayer.canBendIgnoreBinds(this)) {
remove();
return;
}
rotateShield();
}
private void rotateShield() {
Location origin = player.getLocation();
FireBlast.removeFireBlastsAroundPoint(origin, radius);
Combustion.removeAroundPoint(origin, radius);
FireStream.removeAroundPoint(origin, radius);
BlazeArc.removeAroundPoint(origin, radius);
AirBlast.removeAirBlastsAroundPoint(origin, radius);
AirSuction.removeAirSuctionsAroundPoint(origin, radius);
EarthBlast.removeAroundPoint(origin, radius);
@ -169,9 +108,10 @@ public class AirShield implements ConfigLoadable {
WaterManipulation.removeAroundPoint(origin, radius);
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(origin, radius)) {
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirShield", entity.getLocation()))
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirShield", entity.getLocation())) {
continue;
if (origin.distance(entity.getLocation()) > 2) {
}
if (origin.distanceSquared(entity.getLocation()) > 4) {
double x, z, vx, vz, mag;
double angle = 50;
angle = Math.toRadians(angle);
@ -185,7 +125,7 @@ public class AirShield implements ConfigLoadable {
vz = (x * Math.sin(angle) + z * Math.cos(angle)) / mag;
Vector velocity = entity.getVelocity();
if (AvatarState.isAvatarState(player)) {
if (bPlayer.isAvatarState()) {
velocity.setX(AvatarState.getValue(vx));
velocity.setZ(AvatarState.getValue(vz));
} else {
@ -199,7 +139,7 @@ public class AirShield implements ConfigLoadable {
}
}
velocity.multiply(radius / maxradius);
velocity.multiply(radius / maxRadius);
GeneralMethods.setVelocity(entity, velocity);
entity.setFallDistance(0);
}
@ -215,43 +155,108 @@ public class AirShield implements ConfigLoadable {
Set<Integer> keys = angles.keySet();
for (int i : keys) {
double x, y, z;
double factor = radius / maxRadius;
double angle = (double) angles.get(i);
angle = Math.toRadians(angle);
double factor = radius / maxradius;
y = origin.getY() + factor * (double) i;
// double theta = Math.asin(y/radius);
double f = Math.sqrt(1 - factor * factor * ((double) i / radius) * ((double) i / radius));
x = origin.getX() + radius * Math.cos(angle) * f;
z = origin.getZ() + radius * Math.sin(angle) * f;
Location effect = new Location(origin.getWorld(), x, y, z);
if (!GeneralMethods.isRegionProtectedFromBuild(player, "AirShield", effect)) {
AirMethods.playAirbendingParticles(effect, 5);
if (GeneralMethods.rand.nextInt(4) == 0) {
AirMethods.playAirbendingSound(effect);
if (!GeneralMethods.isRegionProtectedFromBuild(this, effect)) {
playAirbendingParticles(effect, particleCount);
if (random.nextInt(4) == 0) {
playAirbendingSound(effect);
}
}
// origin.getWorld().playEffect(effect, Effect.SMOKE, 4,
// (int) AirBlast.defaultrange);
angles.put(i, angles.get(i) + (int) (10 * speedfactor));
angles.put(i, angles.get(i) + (int) (speed));
}
if (radius < maxradius) {
if (radius < maxRadius) {
radius += .3;
}
if (radius > maxradius)
radius = maxradius;
if (radius > maxRadius) {
radius = maxRadius;
}
}
@Override
public String getName() {
return "AirShield";
}
public void setMaxradius(double maxradius) {
this.maxradius = maxradius;
@Override
public Location getLocation() {
return player != null ? player.getLocation() : null;
}
@Override
public long getCooldown() {
return 0;
}
@Override
public boolean isSneakAbility() {
return true;
}
@Override
public boolean isHarmlessAbility() {
return false;
}
public boolean isToggledByAvatarState() {
return isToggledByAvatarState;
}
public void setToggledByAvatarState(boolean isToggledByAvatarState) {
this.isToggledByAvatarState = isToggledByAvatarState;
}
public double getMaxRadius() {
return maxRadius;
}
public void setMaxRadius(double maxRadius) {
this.maxRadius = maxRadius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public int getNumberOfStreams() {
return numberOfStreams;
}
public void setNumberOfStreams(int numberOfStreams) {
this.numberOfStreams = numberOfStreams;
}
public int getParticleCount() {
return particleCount;
}
public void setParticleCount(int particleCount) {
this.particleCount = particleCount;
}
public HashMap<Integer, Integer> getAngles() {
return angles;
}
}

View file

@ -1,57 +1,55 @@
package com.projectkorra.projectkorra.airbending;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.util.Flight;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
import com.projectkorra.projectkorra.util.Flight;
import java.util.Random;
public class AirSpout implements ConfigLoadable {
public class AirSpout extends AirAbility {
public static ConcurrentHashMap<Player, AirSpout> instances = new ConcurrentHashMap<>();
private static final Integer[] DIRECTIONS = { 0, 1, 2, 3, 5, 6, 7, 8 };
private static double HEIGHT = config.get().getDouble("Abilities.Air.AirSpout.Height");
private static final long interval = 100;
private Player player;
private long time;
private int angle = 0;
private double height = HEIGHT;
private int angle;
private long updateInterval;
private long cooldown;
private double height;
public AirSpout(Player player) {
/* Initial Check */
if (instances.containsKey(player)) {
instances.get(player).remove();
super(player);
AirSpout spout = CoreAbility.getAbility(player, AirSpout.class);
if (spout != null) {
spout.remove();
return;
}
/* End Initial Check */
// reloadVariables();
this.player = player;
time = System.currentTimeMillis();
new Flight(player);
instances.put(player, this);
progress();
}
public static ArrayList<Player> getPlayers() {
ArrayList<Player> players = new ArrayList<Player>();
for (AirSpout spout : instances.values()) {
players.add(spout.getPlayer());
if (!bPlayer.canBend(this)) {
remove();
return;
}
return players;
this.angle = 0;
this.cooldown = 0;
this.height = getConfig().getDouble("Abilities.Air.AirSpout.Height");
this.updateInterval = 100;
new Flight(player);
start();
bPlayer.addCooldown(this);
}
public static boolean removeSpouts(Location loc0, double radius, Player sourceplayer) {
boolean removed = false;
for (Player player : instances.keySet()) {
if (!player.equals(sourceplayer)) {
Location loc1 = player.getLocation().getBlock().getLocation();
for (AirSpout spout : CoreAbility.getAbilities(AirSpout.class)) {
if (!spout.player.equals(sourceplayer)) {
Location loc1 = spout.player.getLocation().getBlock().getLocation();
loc0 = loc0.getBlock().getLocation();
double dx = loc1.getX() - loc0.getX();
double dy = loc1.getY() - loc0.getY();
@ -59,8 +57,8 @@ public class AirSpout implements ConfigLoadable {
double distance = Math.sqrt(dx * dx + dz * dz);
if (distance <= radius && dy > 0 && dy < HEIGHT) {
instances.get(player).remove();
if (distance <= radius && dy > 0 && dy < spout.height) {
spout.remove();
removed = true;
}
}
@ -71,7 +69,6 @@ public class AirSpout implements ConfigLoadable {
private void allowFlight() {
player.setAllowFlight(true);
player.setFlying(true);
// flight speed too
}
private Block getGround() {
@ -85,26 +82,25 @@ public class AirSpout implements ConfigLoadable {
return null;
}
public double getHeight() {
return height;
}
public Player getPlayer() {
return player;
}
public boolean progress() {
if (player.isDead() || !player.isOnline() || !GeneralMethods.canBend(player.getName(), "AirSpout")
// || !Methods.hasAbility(player, Abilities.AirSpout)
|| player.getEyeLocation().getBlock().isLiquid() || GeneralMethods.isSolid(player.getEyeLocation().getBlock())) {
@Override
public void progress() {
if (player.isDead() || !player.isOnline() || !bPlayer.canBind(this)) {
remove();
return false;
return;
}
Block eyeBlock = player.getEyeLocation().getBlock();
if (eyeBlock.isLiquid() || GeneralMethods.isSolid(eyeBlock)) {
remove();
return;
}
player.setFallDistance(0);
player.setSprinting(false);
if (GeneralMethods.rand.nextInt(4) == 0) {
AirMethods.playAirbendingSound(player.getLocation());
if ((new Random()).nextInt(4) == 0) {
playAirbendingSound(player.getLocation());
}
Block block = getGround();
if (block != null) {
double dy = player.getLocation().getY() - block.getY();
@ -117,92 +113,91 @@ public class AirSpout implements ConfigLoadable {
} else {
remove();
}
return true;
}
public static void progressAll() {
for (AirSpout ability : instances.values()) {
ability.progress();
}
}
@Override
public void reloadVariables() {
HEIGHT = config.get().getDouble("Abilities.Air.AirSpout.Height");
height = HEIGHT;
}
public void remove() {
super.remove();
removeFlight();
instances.remove(player);
}
public static void removeAll() {
for (AirSpout ability : instances.values()) {
ability.remove();
}
}
private void removeFlight() {
player.setAllowFlight(false);
player.setFlying(false);
// player.setAllowFlight(player.getGameMode() == GameMode.CREATIVE);
// flight speed too
}
private void rotateAirColumn(Block block) {
if (player.getWorld() != block.getWorld())
if (!player.getWorld().equals(block.getWorld())) {
return;
if (System.currentTimeMillis() >= time + interval) {
time = System.currentTimeMillis();
}
if (System.currentTimeMillis() >= startTime + updateInterval) {
startTime = System.currentTimeMillis();
Location location = block.getLocation();
Location playerloc = player.getLocation();
location = new Location(location.getWorld(), playerloc.getX(), location.getY(), playerloc.getZ());
double dy = playerloc.getY() - block.getY();
if (dy > height)
dy = height;
Integer[] directions = { 0, 1, 2, 3, 5, 6, 7, 8 };
int index = angle;
double dy = Math.min(playerloc.getY() - block.getY(), height);
angle = angle >= DIRECTIONS.length ? 0 : angle + 1;
angle++;
if (angle >= directions.length)
angle = 0;
for (int i = 1; i <= dy; i++) {
index += 1;
if (index >= directions.length)
index = 0;
index = index >= DIRECTIONS.length ? 0 : index + 1;
Location effectloc2 = new Location(location.getWorld(), location.getX(), block.getY() + i, location.getZ());
AirMethods.playAirbendingParticles(effectloc2, 3, 0.4F, 0.4F, 0.4F);
// Methods.verbose(directions[index]);
// location.getWorld().playEffect(effectloc2, Effect.SMOKE, 0,
// (int) height + 5);
// location.getWorld().playEffect(effectloc2, Effect.SMOKE, 1,
// (int) height + 5);
// location.getWorld().playEffect(effectloc2, Effect.SMOKE, 2,
// (int) height + 5);
// location.getWorld().playEffect(effectloc2, Effect.SMOKE, 3,
// (int) height + 5);
// location.getWorld().playEffect(effectloc2, Effect.SMOKE, 5,
// (int) height + 5);
// location.getWorld().playEffect(effectloc2, Effect.SMOKE, 6,
// (int) height + 5);
// location.getWorld().playEffect(effectloc2, Effect.SMOKE, 7,
// (int) height + 5);
// location.getWorld().playEffect(effectloc2, Effect.SMOKE, 8,
// (int) height + 5);
playAirbendingParticles(effectloc2, 3, 0.4F, 0.4F, 0.4F);
}
}
}
@Override
public String getName() {
return "AirSpout";
}
@Override
public Location getLocation() {
return player != null ? player.getLocation() : null;
}
@Override
public long getCooldown() {
return cooldown;
}
@Override
public boolean isSneakAbility() {
return true;
}
@Override
public boolean isHarmlessAbility() {
return true;
}
public int getAngle() {
return angle;
}
public void setAngle(int angle) {
this.angle = angle;
}
public long getUpdateInterval() {
return updateInterval;
}
public void setUpdateInterval(long updateInterval) {
this.updateInterval = updateInterval;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
}

View file

@ -4,10 +4,10 @@ import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AvatarState;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.avatar.AvatarState;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
import com.projectkorra.projectkorra.earthbending.EarthMethods;
import com.projectkorra.projectkorra.object.HorizontalVelocityTracker;
import com.projectkorra.projectkorra.util.Flight;
import com.projectkorra.projectkorra.waterbending.WaterSpout;
@ -18,233 +18,172 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
public class AirSuction implements ConfigLoadable {
public static ConcurrentHashMap<Player, AirSuction> instances = new ConcurrentHashMap<>();
private static ConcurrentHashMap<Player, Location> origins = new ConcurrentHashMap<Player, Location>();
private static final double maxspeed = AirBlast.maxspeed;
private static final int maxticks = 10000;
// private static long soonesttime = config.get().getLong("Properties.GlobalCooldown");
private static double SPEED = config.get().getDouble("Abilities.Air.AirSuction.Speed");
private static double RANGE = config.get().getDouble("Abilities.Air.AirSuction.Range");
private static double RADIUS = config.get().getDouble("Abilities.Air.AirSuction.Radius");
private static double PUSH_FACTOR = config.get().getDouble("Abilities.Air.AirSuction.Push");
private static double originselectrange = 10;
public class AirSuction extends AirAbility {
private static final int ORIGIN_PARTICLE_COUNT = 6;
private static final int ABILITY_PARTICLE_COUNT = 6;
private static final int MAX_TICKS = 10000;
private static final double ORIGIN_SELECT_RANGE = 10;
private static final ConcurrentHashMap<Player, Location> ORIGINS = new ConcurrentHashMap<>();
private boolean hasOtherOrigin;
private int ticks;
private int particleCount;
private long cooldown;
private double speed;
private double range;
private double radius;
private double pushFactor;
private Random random;
private Location location;
private Location origin;
private Vector direction;
private Player player;
private boolean otherorigin = false;
private int ticks = 0;
private double speed = SPEED;
private double range = RANGE;
private double affectingradius = RADIUS;
private double pushfactor = PUSH_FACTOR;
// private long time;
private double speedfactor;
@SuppressWarnings("unused")
private ArrayList<Entity> affectedentities = new ArrayList<Entity>();
public AirSuction(Player player) {
/* Initial Check */
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName());
if (bPlayer.isOnCooldown("AirSuction"))
super(player);
if (bPlayer.isOnCooldown("AirSuction")) {
return;
}
if (player.getEyeLocation().getBlock().isLiquid()) {
return;
}
if (AirSpout.getPlayers().contains(player) || WaterSpout.getPlayers().contains(player)) {
if ( CoreAbility.hasAbility(player, AirSpout.class) || CoreAbility.hasAbility(player, WaterSpout.class)) {
return;
}
/* End Initial Check */
// reloadVariables();
this.player = player;
if (origins.containsKey(player)) {
origin = origins.get(player);
otherorigin = true;
origins.remove(player);
this.hasOtherOrigin = false;
this.ticks = 0;
this.particleCount = ABILITY_PARTICLE_COUNT;
this.speed = getConfig().getDouble("Abilities.Air.AirSuction.Speed");
this.range = getConfig().getDouble("Abilities.Air.AirSuction.Range");
this.radius = getConfig().getDouble("Abilities.Air.AirSuction.Radius");
this.pushFactor = getConfig().getDouble("Abilities.Air.AirSuction.Push");
this.cooldown = GeneralMethods.getGlobalCooldown();
this.random = new Random();
if (ORIGINS.containsKey(player)) {
origin = ORIGINS.get(player);
hasOtherOrigin = true;
ORIGINS.remove(player);
} else {
origin = player.getEyeLocation();
}
location = GeneralMethods.getTargetedLocation(player, range, GeneralMethods.nonOpaque);
location = GeneralMethods.getTargetedLocation(player, range, GeneralMethods.NON_OPAQUE);
direction = GeneralMethods.getDirection(location, origin).normalize();
Entity entity = GeneralMethods.getTargetedEntity(player, range, new ArrayList<Entity>());
Entity entity = GeneralMethods.getTargetedEntity(player, range);
if (entity != null) {
direction = GeneralMethods.getDirection(entity.getLocation(), origin).normalize();
location = getLocation(origin, direction.clone().multiply(-1));
// location =
// origin.clone().add(direction.clone().multiply(-range));
}
// }
instances.put(player, this);
bPlayer.addCooldown("AirSuction", GeneralMethods.getGlobalCooldown());
// time = System.currentTimeMillis();
// timers.put(player, System.currentTimeMillis());
}
public static String getDescription() {
return "To use, simply left-click in a direction. " + "A gust of wind will originate as far as it can in that direction"
+ " and flow towards you, sucking anything in its path harmlessly with it."
+ " Skilled benders can use this technique to pull items from precarious locations. "
+ "Additionally, tapping sneak will change the origin of your next " + "AirSuction to your targeted location.";
bPlayer.addCooldown("AirSuction", cooldown);
start();
}
private static void playOriginEffect(Player player) {
if (!origins.containsKey(player))
return;
Location origin = origins.get(player);
if (player.isDead() || !player.isOnline())
return;
if (!origin.getWorld().equals(player.getWorld())) {
origins.remove(player);
if (!ORIGINS.containsKey(player)) {
return;
}
if (GeneralMethods.getBoundAbility(player) == null) {
origins.remove(player);
Location origin = ORIGINS.get(player);
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null || player.isDead() || !player.isOnline()) {
return;
} else if (!origin.getWorld().equals(player.getWorld())) {
ORIGINS.remove(player);
return;
} else if (!bPlayer.canBendIgnoreCooldowns(getAbility("AirSuction"))) {
ORIGINS.remove(player);
return;
} else if (origin.distanceSquared(player.getEyeLocation()) > ORIGIN_SELECT_RANGE * ORIGIN_SELECT_RANGE) {
ORIGINS.remove(player);
return;
}
if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirSuction")
|| !GeneralMethods.canBend(player.getName(), "AirSuction")) {
origins.remove(player);
return;
}
if (origin.distance(player.getEyeLocation()) > originselectrange) {
origins.remove(player);
return;
}
AirMethods.playAirbendingParticles(origin, 6);
//
// origin.getWorld().playEffect(origin, Effect.SMOKE, 4,
// (int) originselectrange);
playAirbendingParticles(origin, ORIGIN_PARTICLE_COUNT);
}
public static void progressAll() {
for (AirSuction ability : instances.values()) {
ability.progress();
}
for (Player player : origins.keySet()) {
public static void progressOrigins() {
for (Player player : ORIGINS.keySet()) {
playOriginEffect(player);
}
}
public static void setOrigin(Player player) {
Location location = GeneralMethods.getTargetedLocation(player, originselectrange, GeneralMethods.nonOpaque);
if (location.getBlock().isLiquid() || GeneralMethods.isSolid(location.getBlock()))
Location location = GeneralMethods.getTargetedLocation(player, ORIGIN_SELECT_RANGE, GeneralMethods.NON_OPAQUE);
if (location.getBlock().isLiquid() || GeneralMethods.isSolid(location.getBlock())) {
return;
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirSuction", location))
} else if (GeneralMethods.isRegionProtectedFromBuild(player, "AirSuction", location)) {
return;
if (origins.containsKey(player)) {
origins.replace(player, location);
} else if (ORIGINS.containsKey(player)) {
ORIGINS.replace(player, location);
} else {
origins.put(player, location);
ORIGINS.put(player, location);
}
}
private void advanceLocation() {
AirMethods.playAirbendingParticles(location, 6, 0.275F, 0.275F, 0.275F);
if (GeneralMethods.rand.nextInt(4) == 0) {
AirMethods.playAirbendingSound(location);
playAirbendingParticles(location, particleCount, 0.275F, 0.275F, 0.275F);
if (random.nextInt(4) == 0) {
playAirbendingSound(location);
}
// location.getWorld().playEffect(location, Effect.SMOKE, 4,
// (int) AirBlast.defaultrange);
location = location.add(direction.clone().multiply(speedfactor));
}
public double getAffectingradius() {
return affectingradius;
double speedFactor = speed * (ProjectKorra.time_step / 1000.);
location = location.add(direction.clone().multiply(speedFactor));
}
private Location getLocation(Location origin, Vector direction) {
Location location = origin.clone();
for (double i = 1; i <= range; i++) {
location = origin.clone().add(direction.clone().multiply(i));
if (!EarthMethods.isTransparentToEarthbending(player, location.getBlock())
|| GeneralMethods.isRegionProtectedFromBuild(player, "AirSuction", location)) {
if (!isTransparent(location.getBlock())
|| GeneralMethods.isRegionProtectedFromBuild(this, location)) {
return origin.clone().add(direction.clone().multiply(i - 1));
}
}
return location;
}
public Player getPlayer() {
return player;
}
public double getPushfactor() {
return pushfactor;
}
public double getRange() {
return range;
}
public double getSpeed() {
return speed;
}
public boolean progress() {
@Override
public void progress() {
if (player.isDead() || !player.isOnline()) {
remove();
return false;
}
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirSuction", location)) {
return;
} else if (GeneralMethods.isRegionProtectedFromBuild(player, "AirSuction", location)) {
remove();
return false;
return;
}
speedfactor = speed * (ProjectKorra.time_step / 1000.);
ticks++;
if (ticks > maxticks) {
if (ticks > MAX_TICKS) {
remove();
return false;
}
// if (player.isSneaking()
// && Methods.getBendingAbility(player) == Abilities.AirSuction) {
// new AirSuction(player);
// }
if ((location.distance(origin) > range) || (location.distance(origin) <= 1)) {
return;
} else if ((location.distanceSquared(origin) > range * range) || (location.distanceSquared(origin) <= 1)) {
remove();
return false;
return;
}
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, affectingradius)) {
// if (affectedentities.contains(entity))
// continue;
// affectedentities.add(entity);
if (entity.getEntityId() != player.getEntityId() || otherorigin) {
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, radius)) {
if (entity.getEntityId() != player.getEntityId() || hasOtherOrigin) {
Vector velocity = entity.getVelocity();
double max = maxspeed;
double factor = pushfactor;
if (AvatarState.isAvatarState(player)) {
max = AvatarState.getValue(maxspeed);
double max = speed;
double factor = pushFactor;
if (bPlayer.isAvatarState()) {
max = AvatarState.getValue(max);
factor = AvatarState.getValue(factor);
}
Vector push = direction.clone();
if (Math.abs(push.getY()) > max && entity.getEntityId() != player.getEntityId()) {
if (push.getY() < 0)
if (push.getY() < 0) {
push.setY(-max);
else
} else {
push.setY(max);
}
}
factor *= 1 - location.distance(origin) / (2 * range);
@ -260,44 +199,37 @@ public class AirSuction implements ConfigLoadable {
}
if (entity instanceof Player) {
if (Commands.invincible.contains(((Player) entity).getName()))
if (Commands.invincible.contains(((Player) entity).getName())) {
continue;
}
}
GeneralMethods.setVelocity(entity, velocity);
new HorizontalVelocityTracker(entity, player, 200l, "AirSuction", Element.Air, null);
new HorizontalVelocityTracker(entity, player, 200l, "AirSuction", Element.AIR);
entity.setFallDistance(0);
if (entity.getEntityId() != player.getEntityId() && entity instanceof Player) {
new Flight((Player) entity, player);
}
if (entity.getFireTicks() > 0)
entity.getWorld().playEffect(entity.getLocation(), Effect.EXTINGUISH, 0);
entity.setFireTicks(0);
AirMethods.breakBreathbendingHold(entity);
if (entity.getFireTicks() > 0) {
entity.getWorld().playEffect(entity.getLocation(), Effect.EXTINGUISH, 0);
}
entity.setFireTicks(0);
breakBreathbendingHold(entity);
}
}
advanceLocation();
return true;
}
public void remove() {
instances.remove(player);
}
public static void removeAll() {
for (AirSuction ability : instances.values()) {
ability.remove();
}
}
public static boolean removeAirSuctionsAroundPoint(Location location, double radius) {
boolean removed = false;
for (AirSuction airSuction : instances.values()) {
for (AirSuction airSuction : CoreAbility.getAbilities(AirSuction.class)) {
Location airSuctionlocation = airSuction.location;
if (location.getWorld() == airSuctionlocation.getWorld()) {
if (location.distance(airSuctionlocation) <= radius)
if (location.distanceSquared(airSuctionlocation) <= radius * radius) {
airSuction.remove();
}
removed = true;
}
}
@ -305,30 +237,108 @@ public class AirSuction implements ConfigLoadable {
}
@Override
public void reloadVariables() {
SPEED = config.get().getDouble("Abilities.Air.AirSuction.Speed");
RANGE = config.get().getDouble("Abilities.Air.AirSuction.Range");
RADIUS = config.get().getDouble("Abilities.Air.AirSuction.Radius");
PUSH_FACTOR = config.get().getDouble("Abilities.Air.AirSuction.Push");
speed = SPEED;
range = RANGE;
affectingradius = RADIUS;
pushfactor = PUSH_FACTOR;
public String getName() {
return "AirSuction";
}
public void setAffectingradius(double affectingradius) {
this.affectingradius = affectingradius;
@Override
public Location getLocation() {
return location;
}
public void setPushfactor(double pushfactor) {
this.pushfactor = pushfactor;
@Override
public long getCooldown() {
return cooldown;
}
@Override
public boolean isSneakAbility() {
return true;
}
@Override
public boolean isHarmlessAbility() {
return false;
}
public Location getOrigin() {
return origin;
}
public void setOrigin(Location origin) {
this.origin = origin;
}
public Vector getDirection() {
return direction;
}
public void setDirection(Vector direction) {
this.direction = direction;
}
public boolean isHasOtherOrigin() {
return hasOtherOrigin;
}
public void setHasOtherOrigin(boolean hasOtherOrigin) {
this.hasOtherOrigin = hasOtherOrigin;
}
public int getTicks() {
return ticks;
}
public void setTicks(int ticks) {
this.ticks = ticks;
}
public int getParticleCount() {
return particleCount;
}
public void setParticleCount(int particleCount) {
this.particleCount = particleCount;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public double getRange() {
return range;
}
public void setRange(double range) {
this.range = range;
}
public void setSpeed(double speed) {
this.speed = speed;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getPushFactor() {
return pushFactor;
}
public void setPushFactor(double pushFactor) {
this.pushFactor = pushFactor;
}
public void setLocation(Location location) {
this.location = location;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
}

View file

@ -1,9 +1,18 @@
package com.projectkorra.projectkorra.airbending;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.WaterAbility;
import com.projectkorra.projectkorra.avatar.AvatarState;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.earthbending.EarthBlast;
import com.projectkorra.projectkorra.firebending.Combustion;
import com.projectkorra.projectkorra.firebending.FireBlast;
import com.projectkorra.projectkorra.firebending.Illumination;
import com.projectkorra.projectkorra.util.Flight;
import com.projectkorra.projectkorra.waterbending.WaterManipulation;
import org.bukkit.Location;
import org.bukkit.Material;
@ -14,95 +23,78 @@ import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AvatarState;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
import com.projectkorra.projectkorra.earthbending.EarthBlast;
import com.projectkorra.projectkorra.firebending.Combustion;
import com.projectkorra.projectkorra.firebending.FireBlast;
import com.projectkorra.projectkorra.firebending.Illumination;
import com.projectkorra.projectkorra.util.Flight;
import com.projectkorra.projectkorra.waterbending.WaterManipulation;
import com.projectkorra.projectkorra.waterbending.WaterMethods;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
public class AirSwipe implements ConfigLoadable {
public class AirSwipe extends AirAbility {
public static ConcurrentHashMap<Player, AirSwipe> instances = new ConcurrentHashMap<>();
private static int stepsize = 4;
private static int ARC = config.get().getInt("Abilities.Air.AirSwipe.Arc");
private static int defaultdamage = config.get().getInt("Abilities.Air.AirSwipe.Damage");
private static double PUSH_FACTOR = config.get().getDouble("Abilities.Air.AirSwipe.Push");
private static double AFFECTING_RADIUS = config.get().getDouble("Abilities.Air.AirSwipe.Radius");
private static double RANGE = config.get().getDouble("Abilities.Air.AirSwipe.Range");
private static double SPEED = config.get().getDouble("Abilities.Air.AirSwipe.Speed");
private static double MAX_FACTOR = config.get().getDouble("Abilities.Air.AirSwipe.ChargeFactor");
private static byte full = AirBlast.full;
private static long MAX_CHARGE_TIME = config.get().getLong("Abilities.Air.AirSwipe.MaxChargeTime");
private static Integer[] breakables = { 6, 31, 32, 37, 38, 39, 40, 59, 81, 83, 106, 175 };
private final int MAX_AFFECTABLE_ENTITIES = 10;
private double speedfactor;
private static final Integer[] BREAKABLES = { 6, 31, 32, 37, 38, 39, 40, 59, 81, 83, 106, 175 };
private static byte FULL_LIQUID_DATA = 0x0;
private static final int STEP_SIZE = 4;
// Limiting the entities reduces the risk of crashing
private static final int MAX_AFFECTABLE_ENTITIES = 10;
private boolean charging;
private int arc;
private int particleCount;
private long maxChargeTime;
private long cooldown;
private double damage;
private double pushFactor;
private double speed;
private double range;
private double radius;
private double maxChargeFactor;
private Location origin;
private Player player;
private boolean charging = false;
private long time;
private double damage = defaultdamage;
private double pushfactor = PUSH_FACTOR;
private double speed = SPEED;
private double range = RANGE;
private double maxfactor = MAX_FACTOR;
private double affectingradius = AFFECTING_RADIUS;
private int arc = ARC;
private long maxchargetime = MAX_CHARGE_TIME;
private ConcurrentHashMap<Vector, Location> elements = new ConcurrentHashMap<Vector, Location>();
private ArrayList<Entity> affectedentities = new ArrayList<Entity>();
private Random random;
private ConcurrentHashMap<Vector, Location> elements;
private ArrayList<Entity> affectedEntities;
public AirSwipe(Player player) {
this(player, false);
}
public AirSwipe(Player player, boolean charging) {
/* Initial Check */
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName());
if (bPlayer.isOnCooldown("AirSwipe"))
return;
if (player.getEyeLocation().getBlock().isLiquid()) {
super(player);
this.charging = charging;
this.origin = player.getEyeLocation();
this.charging = false;
this.particleCount = 3;
this.arc = getConfig().getInt("Abilities.Air.AirSwipe.Arc");
this.maxChargeTime = getConfig().getLong("Abilities.Air.AirSwipe.MaxChargeTime");
this.cooldown = getConfig().getLong("Abilities.Air.AirSwipe.Cooldown");
this.damage = getConfig().getDouble("Abilities.Air.AirSwipe.Damage");
this.pushFactor = getConfig().getDouble("Abilities.Air.AirSwipe.Push");
this.speed = getConfig().getDouble("Abilities.Air.AirSwipe.Speed") * (ProjectKorra.time_step / 1000.0);
this.range = getConfig().getDouble("Abilities.Air.AirSwipe.Range");
this.radius = getConfig().getDouble("Abilities.Air.AirSwipe.Radius");
this.maxChargeFactor = getConfig().getDouble("Abilities.Air.AirSwipe.chargeFactor");
this.random = new Random();
this.elements = new ConcurrentHashMap<>();
this.affectedEntities = new ArrayList<>();
if (bPlayer.isOnCooldown(this) || player.getEyeLocation().getBlock().isLiquid()) {
return;
}
/* End Initial Check */
// reloadVariables();
this.player = player;
this.charging = charging;
origin = player.getEyeLocation();
time = System.currentTimeMillis();
instances.put(player, this);
bPlayer.addCooldown("AirSwipe", ProjectKorra.plugin.getConfig().getLong("Abilities.Air.AirSwipe.Cooldown"));
if (!charging)
if (!charging) {
launch();
}
public static void charge(Player player) {
new AirSwipe(player, true);
}
start();
bPlayer.addCooldown(this);
}
public static boolean removeSwipesAroundPoint(Location loc, double radius) {
boolean removed = false;
for (AirSwipe aswipe : instances.values()) {
for (AirSwipe aswipe : CoreAbility.getAbilities(AirSwipe.class)) {
for (Vector vec : aswipe.elements.keySet()) {
Location vectorLoc = aswipe.elements.get(vec);
if (vectorLoc != null && vectorLoc.getWorld().equals(loc.getWorld())) {
if (vectorLoc.distance(loc) <= radius) {
// instances.remove(aswipe.uuid);
if (vectorLoc.distanceSquared(loc) <= radius * radius) {
aswipe.remove();
removed = true;
}
@ -114,24 +106,23 @@ public class AirSwipe implements ConfigLoadable {
@SuppressWarnings("deprecation")
private void advanceSwipe() {
affectedentities.clear();
affectedEntities.clear();
for (Vector direction : elements.keySet()) {
Location location = elements.get(direction);
if (direction != null && location != null) {
location = location.clone().add(direction.clone().multiply(speedfactor));
location = location.clone().add(direction.clone().multiply(speed));
elements.replace(direction, location);
if (location.distance(origin) > range || GeneralMethods.isRegionProtectedFromBuild(player, "AirSwipe", location)) {
if (location.distanceSquared(origin) > range * range
|| GeneralMethods.isRegionProtectedFromBuild(this, location)) {
elements.remove(direction);
} else {
AirMethods.removeAirSpouts(location, player);
WaterMethods.removeWaterSpouts(location, player);
double radius = FireBlast.AFFECTING_RADIUS;
Player source = player;
if (EarthBlast.annihilateBlasts(location, radius, source)
|| WaterManipulation.annihilateBlasts(location, radius, source)
|| FireBlast.annihilateBlasts(location, radius, source)
removeAirSpouts(location, player);
WaterAbility.removeWaterSpouts(location, player);
if (EarthBlast.annihilateBlasts(location, radius, player)
|| WaterManipulation.annihilateBlasts(location, radius, player)
|| FireBlast.annihilateBlasts(location, radius, player)
|| Combustion.removeAroundPoint(location, radius)) {
elements.remove(direction);
damage = 0;
@ -140,7 +131,7 @@ public class AirSwipe implements ConfigLoadable {
}
Block block = location.getBlock();
for (Block testblock : GeneralMethods.getBlocksAroundPoint(location, affectingradius)) {
for (Block testblock : GeneralMethods.getBlocksAroundPoint(location, radius)) {
if (testblock.getType() == Material.FIRE) {
testblock.setType(Material.AIR);
}
@ -155,74 +146,72 @@ public class AirSwipe implements ConfigLoadable {
} else {
elements.remove(direction);
}
if (block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA) {
if (block.getData() == full) {
if (isLava(block)) {
if (block.getData() == FULL_LIQUID_DATA) {
block.setType(Material.OBSIDIAN);
} else {
block.setType(Material.COBBLESTONE);
}
}
} else {
AirMethods.playAirbendingParticles(location, 3, 0.2F, 0.2F, 0);
if (GeneralMethods.rand.nextInt(4) == 0) {
AirMethods.playAirbendingSound(location);
playAirbendingParticles(location, particleCount, 0.2F, 0.2F, 0);
if (random.nextInt(4) == 0) {
playAirbendingSound(location);
}
affectPeople(location, direction);
}
}
// } else {
// elements.remove(direction);
}
}
if (elements.isEmpty()) {
remove();
}
}
private void affectPeople(Location location, Vector direction) {
WaterMethods.removeWaterSpouts(location, player);
AirMethods.removeAirSpouts(location, player);
final List<Entity> entities = GeneralMethods.getEntitiesAroundPoint(location, affectingradius);
final List<Entity> surroundingEntities = GeneralMethods.getEntitiesAroundPoint(location, 4);
WaterAbility.removeWaterSpouts(location, player);
removeAirSpouts(location, player);
final List<Entity> entities = GeneralMethods.getEntitiesAroundPoint(location, radius);
final Vector fDirection = direction;
for (int i = 0; i < entities.size(); i++) {
final Entity entity = entities.get(i);
new BukkitRunnable() {
public void run() {
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirSwipe", entity.getLocation()))
if (GeneralMethods.isRegionProtectedFromBuild(AirSwipe.this, entity.getLocation())) {
return;
}
if (entity.getEntityId() != player.getEntityId() && entity instanceof LivingEntity) {
if (entity instanceof Player) {
if (Commands.invincible.contains(((Player) entity).getName()))
if (Commands.invincible.contains(((Player) entity).getName())) {
return;
}
if (surroundingEntities.size() < MAX_AFFECTABLE_ENTITIES) {
if (AvatarState.isAvatarState(player)) {
GeneralMethods.setVelocity(entity, fDirection.multiply(AvatarState.getValue(pushfactor)));
} else {
GeneralMethods.setVelocity(entity, fDirection.multiply(pushfactor));
}
}
if (entity instanceof LivingEntity && !affectedentities.contains(entity)) {
if (damage != 0)
if (entities.size() < MAX_AFFECTABLE_ENTITIES) {
if (bPlayer.isAvatarState()) {
GeneralMethods.setVelocity(entity, fDirection.multiply(AvatarState.getValue(pushFactor)));
} else {
GeneralMethods.setVelocity(entity, fDirection.multiply(pushFactor));
}
}
if (entity instanceof LivingEntity && !affectedEntities.contains(entity)) {
if (damage != 0) {
GeneralMethods.damageEntity(player, entity, damage, "AirSwipe");
affectedentities.add(entity);
}
affectedEntities.add(entity);
}
if (entity instanceof Player) {
new Flight((Player) entity, player);
}
AirMethods.breakBreathbendingHold(entity);
breakBreathbendingHold(entity);
if (elements.containsKey(fDirection)) {
elements.remove(fDirection);
}
} else if (entity.getEntityId() != player.getEntityId() && !(entity instanceof LivingEntity)) {
if (AvatarState.isAvatarState(player)) {
GeneralMethods.setVelocity(entity, fDirection.multiply(AvatarState.getValue(pushfactor)));
if (bPlayer.isAvatarState()) {
GeneralMethods.setVelocity(entity, fDirection.multiply(AvatarState.getValue(pushFactor)));
} else {
GeneralMethods.setVelocity(entity, fDirection.multiply(pushfactor));
GeneralMethods.setVelocity(entity, fDirection.multiply(pushFactor));
}
}
}
@ -230,46 +219,10 @@ public class AirSwipe implements ConfigLoadable {
}
}
public double getAffectingradius() {
return affectingradius;
}
public int getArc() {
return arc;
}
public double getDamage() {
return damage;
}
public long getMaxchargetime() {
return maxchargetime;
}
public double getMaxfactor() {
return maxfactor;
}
public Player getPlayer() {
return player;
}
public double getPushfactor() {
return pushfactor;
}
public double getRange() {
return range;
}
public double getSpeed() {
return speed;
}
@SuppressWarnings("deprecation")
private boolean isBlockBreakable(Block block) {
Integer id = block.getTypeId();
if (Arrays.asList(breakables).contains(id) && !Illumination.blocks.containsKey(block)) {
if (Arrays.asList(BREAKABLES).contains(id) && !Illumination.getBlocks().containsKey(block)) {
return true;
}
return false;
@ -277,7 +230,7 @@ public class AirSwipe implements ConfigLoadable {
private void launch() {
origin = player.getEyeLocation();
for (int i = -arc; i <= arc; i += stepsize) {
for (int i = -arc; i <= arc; i += STEP_SIZE) {
double angle = Math.toRadians((double) i);
Vector direction = player.getEyeLocation().getDirection().clone();
@ -295,110 +248,169 @@ public class AirSwipe implements ConfigLoadable {
}
}
public boolean progress() {
public void progress() {
if (player.isDead() || !player.isOnline()) {
remove();
return false;
return;
}
speedfactor = speed * (ProjectKorra.time_step / 1000.);
if (!charging) {
if (elements.isEmpty()) {
remove();
return false;
return;
}
advanceSwipe();
} else {
if (GeneralMethods.getBoundAbility(player) == null) {
if (!bPlayer.canBend(this)) {
remove();
return false;
}
if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("AirSwipe")
|| !GeneralMethods.canBend(player.getName(), "AirSwipe")) {
remove();
return false;
return;
}
if (!player.isSneaking()) {
double factor = 1;
if (System.currentTimeMillis() >= time + maxchargetime) {
factor = maxfactor;
} else if (AvatarState.isAvatarState(player)) {
if (System.currentTimeMillis() >= startTime + maxChargeTime) {
factor = maxChargeFactor;
} else if (bPlayer.isAvatarState()) {
factor = AvatarState.getValue(factor);
} else {
factor = maxfactor * (double) (System.currentTimeMillis() - time) / (double) maxchargetime;
factor = maxChargeFactor * (double) (System.currentTimeMillis() - startTime) / (double) maxChargeTime;
}
charging = false;
launch();
if (factor < 1)
factor = 1;
factor = Math.max(1, factor);
damage *= factor;
pushfactor *= factor;
return true;
} else if (System.currentTimeMillis() >= time + maxchargetime) {
AirMethods.playAirbendingParticles(player.getEyeLocation(), 3);
pushFactor *= factor;
return;
} else if (System.currentTimeMillis() >= startTime + maxChargeTime) {
playAirbendingParticles(player.getEyeLocation(), particleCount);
}
}
return true;
}
public static void progressAll() {
for (AirSwipe ability : instances.values()) {
ability.progress();
}
}
public void remove() {
instances.remove(player);
}
public static void removeAll() {
for (AirSwipe ability : instances.values()) {
ability.remove();
}
}
@Override
public void reloadVariables() {
ARC = config.get().getInt("Abilities.Air.AirSwipe.Arc");
defaultdamage = config.get().getInt("Abilities.Air.AirSwipe.Damage");
PUSH_FACTOR = config.get().getDouble("Abilities.Air.AirSwipe.Push");
AFFECTING_RADIUS = config.get().getDouble("Abilities.Air.AirSwipe.Radius");
RANGE = config.get().getDouble("Abilities.Air.AirSwipe.Range");
SPEED = config.get().getDouble("Abilities.Air.AirSwipe.Speed");
MAX_FACTOR = config.get().getDouble("Abilities.Air.AirSwipe.ChargeFactor");
MAX_CHARGE_TIME = config.get().getLong("Abilities.Air.AirSwipe.MaxChargeTime");
public String getName() {
return "AirSwipe";
}
public void setAffectingradius(double affectingradius) {
this.affectingradius = affectingradius;
@Override
public Location getLocation() {
return elements.size() != 0 ? elements.values().iterator().next() : null;
}
@Override
public long getCooldown() {
return cooldown;
}
@Override
public boolean isSneakAbility() {
return true;
}
@Override
public boolean isHarmlessAbility() {
return false;
}
public Location getOrigin() {
return origin;
}
public void setOrigin(Location origin) {
this.origin = origin;
}
public boolean isCharging() {
return charging;
}
public void setCharging(boolean charging) {
this.charging = charging;
}
public int getArc() {
return arc;
}
public void setArc(int arc) {
this.arc = arc;
}
public int getParticleCount() {
return particleCount;
}
public void setParticleCount(int particleCount) {
this.particleCount = particleCount;
}
public long getMaxChargeTime() {
return maxChargeTime;
}
public void setMaxChargeTime(long maxChargeTime) {
this.maxChargeTime = maxChargeTime;
}
public double getDamage() {
return damage;
}
public void setDamage(double damage) {
this.damage = damage;
}
public void setMaxchargetime(long maxchargetime) {
this.maxchargetime = maxchargetime;
public double getPushFactor() {
return pushFactor;
}
public void setMaxfactor(double maxfactor) {
this.maxfactor = maxfactor;
public void setPushFactor(double pushFactor) {
this.pushFactor = pushFactor;
}
public void setPushfactor(double pushfactor) {
this.pushfactor = pushfactor;
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public double getRange() {
return range;
}
public void setRange(double range) {
this.range = range;
}
public void setSpeed(double speed) {
this.speed = speed;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getMaxChargeFactor() {
return maxChargeFactor;
}
public void setMaxChargeFactor(double maxChargeFactor) {
this.maxChargeFactor = maxChargeFactor;
}
public ConcurrentHashMap<Vector, Location> getElements() {
return elements;
}
public ArrayList<Entity> getAffectedEntities() {
return affectedEntities;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
}

View file

@ -2,8 +2,6 @@ package com.projectkorra.projectkorra.airbending;
import com.projectkorra.projectkorra.ProjectKorra;
import org.bukkit.Bukkit;
public class AirbendingManager implements Runnable {
public ProjectKorra plugin;
@ -14,19 +12,10 @@ public class AirbendingManager implements Runnable {
@Override
public void run() {
AirBlast.progressAll();
AirPassive.handlePassive(Bukkit.getServer());
AirBurst.progressAll();
AirScooter.progressAll();
Suffocate.progressAll();
AirSpout.progressAll();
AirBubble.handleBubbles(Bukkit.getServer());
AirSuction.progressAll();
AirSwipe.progressAll();
Tornado.progressAll();
AirShield.progressAll();
AirCombo.progressAll();
FlightAbility.progressAll();
AirBlast.progressOrigins();
AirPassive.handlePassive();
AirBubble.handleBubbles();
AirSuction.progressOrigins();
}
}

View file

@ -1,127 +0,0 @@
package com.projectkorra.projectkorra.airbending;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
import com.projectkorra.projectkorra.util.Flight;
public class FlightAbility implements ConfigLoadable {
public static ConcurrentHashMap<Player, FlightAbility> instances = new ConcurrentHashMap<>();
private static ConcurrentHashMap<String, Integer> hits = new ConcurrentHashMap<String, Integer>();
private static ConcurrentHashMap<String, Boolean> hovering = new ConcurrentHashMap<String, Boolean>();
private Player player;
private Flight flight;
private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Air.Flight.Cooldown");
public FlightAbility(Player player) {
this.player = player;
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName());
if (bPlayer.isOnCooldown("Flight"))
return;
if (!AirMethods.canFly(player, true, false))
return;
if (flight == null)
flight = new Flight(player);
player.setAllowFlight(true);
player.setVelocity(player.getEyeLocation().getDirection().normalize());
bPlayer.addCooldown("Flight", cooldown);
instances.put(player, this);
}
public static void addHit(Player player) {
if (contains(player)) {
if (hits.containsKey(player.getName())) {
if (hits.get(player.getName()) >= 4) {
hits.remove(player.getName());
remove(player);
}
} else {
hits.put(player.getName(), 1);
}
}
}
public static boolean contains(Player player) {
return instances.containsKey(player);
}
public static boolean isHovering(Player player) {
return hovering.containsKey(player.getName());
}
public static void remove(Player player) {
if (contains(player))
instances.get(player).remove();
}
public static void removeAll() {
for (FlightAbility ability : instances.values()) {
ability.remove();
}
hits.clear();
hovering.clear();
}
public static void setHovering(Player player, boolean bool) {
String playername = player.getName();
if (bool) {
if (!hovering.containsKey(playername)) {
hovering.put(playername, true);
player.setVelocity(new Vector(0, 0, 0));
}
} else {
if (hovering.containsKey(playername)) {
hovering.remove(playername);
}
}
}
public boolean progress() {
if (!AirMethods.canFly(player, false, isHovering(player))) {
remove(player);
return false;
}
if (flight == null)
flight = new Flight(player);
if (isHovering(player)) {
Vector vec = player.getVelocity().clone();
vec.setY(0);
player.setVelocity(vec);
} else {
player.setVelocity(player.getEyeLocation().getDirection().normalize());
}
return true;
}
public static void progressAll() {
for (FlightAbility ability : instances.values()) {
ability.progress();
}
}
@Override
public void reloadVariables() {
}
public void remove() {
String name = player.getName();
instances.remove(player);
hits.remove(name);
hovering.remove(name);
if (flight != null)
flight.revert();
}
}

View file

@ -2,7 +2,6 @@ package com.projectkorra.projectkorra.airbending;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
@ -12,11 +11,11 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AvatarState;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.avatar.AvatarState;
/**
* Suffocate
@ -27,91 +26,68 @@ import com.projectkorra.projectkorra.configuration.ConfigLoadable;
* used on multiple entities within a large radius. If the user is damaged while performing this
* ability then the ability is removed.
*/
public class Suffocate implements ConfigLoadable {
public class Suffocate extends AirAbility {
public static ConcurrentHashMap<Player, Suffocate> instances = new ConcurrentHashMap<>();
public static enum SpiralType {
HORIZONTAL1, HORIZONTAL2, VERTICAL1, VERTICAL2, DIAGONAL1, DIAGONAL2
};
private static boolean CAN_SUFFOCATE_UNDEAD = config.get().getBoolean("Abilities.Air.Suffocate.CanBeUsedOnUndeadMobs");
private static boolean REQUIRE_CONSTANT_AIM = config.get().getBoolean("Abilities.Air.Suffocate.RequireConstantAim");
private static double ANIM_RADIUS = config.get().getDouble("Abilities.Air.Suffocate.AnimationRadius");
private static int ANIM_PARTICLE_AMOUNT = config.get().getInt("Abilities.Air.Suffocate.AnimationParticleAmount");
private static double ANIM_SPEED = config.get().getDouble("Abilities.Air.Suffocate.AnimationSpeed");
private static long CHARGE_TIME = config.get().getLong("Abilities.Air.Suffocate.ChargeTime");
private static long COOLDOWN = config.get().getLong("Abilities.Air.Suffocate.Cooldown");
private static double RANGE = config.get().getDouble("Abilities.Air.Suffocate.Range");
private static double AIM_RADIUS = config.get().getDouble("Abilities.Air.Suffocate.RequireConstantAimRadius");
private static double DAMAGE = config.get().getDouble("Abilities.Air.Suffocate.Damage");
private static double DAMAGE_INITIAL_DELAY = config.get().getDouble("Abilities.Air.Suffocate.DamageInitialDelay");
private static double DAMAGE_INTERVAL = config.get().getDouble("Abilities.Air.Suffocate.DamageInterval");
private static int SLOW = config.get().getInt("Abilities.Air.Suffocate.SlowPotency");
private static double SLOW_INTERVAL = config.get().getDouble("Abilities.Air.Suffocate.SlowInterval");
private static double SLOW_DELAY = config.get().getDouble("Abilities.Air.Suffocate.SlowDelay");
private static int BLIND = config.get().getInt("Abilities.Air.Suffocate.BlindPotentcy");
private static double BLIND_DELAY = config.get().getDouble("Abilities.Air.Suffocate.BlindDelay");
private static double BLIND_INTERVAL = config.get().getDouble("Abilities.Air.Suffocate.BlindInterval");
private Player player;
private BendingPlayer bplayer;
private boolean started = false;
private long time;
private boolean started;
private boolean requireConstantAim;
private boolean canSuffocateUndead;
private int particleCount;
private long chargeTime;
private long cooldown;
private double range;
private double radius;
private double damage;
private double damageDelay;
private double damageRepeat;
private double slow;
private double slowRepeat;
private double slowDelay;
private double constantAimRadius;
private double blind;
private double blindDelay;
private double blindRepeat;
private double animationSpeed;
private ArrayList<BukkitRunnable> tasks;
private ArrayList<LivingEntity> targets;
private boolean reqConstantAim;
private boolean canSuffUndead;
private long chargeTime, cooldown;
private int particleScale;
private double range, radius;
private double speedFactor;
private double aimRadius;
private double damage, damageDelay, damageRepeat;
private double slow, slowRepeat, slowDelay;
private double blind, blindDelay, blindRepeat;
private Integer[] transparent = {0, 6, 8, 9, 10, 11, 27, 28, 30, 31, 32,
37, 38, 39, 40, 50, 51, 55, 59, 63, 64,
65, 66, 68, 69, 70, 71, 72, 75, 76, 77,
78, 83, 93, 94, 104, 105, 111, 115, 117,
132, 141, 142, 143, 147, 148, 149, 150,
157, 175, 176, 177, 183, 184, 185, 187,
193, 194, 195, 196, 197};
public Suffocate(Player player) {
this.player = player;
bplayer = GeneralMethods.getBendingPlayer(player.getName());
targets = new ArrayList<LivingEntity>();
tasks = new ArrayList<BukkitRunnable>();
time = System.currentTimeMillis();
// reloadVariables();
reqConstantAim = REQUIRE_CONSTANT_AIM;
canSuffUndead = CAN_SUFFOCATE_UNDEAD;
chargeTime = CHARGE_TIME;
cooldown = COOLDOWN;
particleScale = ANIM_PARTICLE_AMOUNT;
range = RANGE;
radius = ANIM_RADIUS;
speedFactor = ANIM_SPEED;
aimRadius = AIM_RADIUS;
damage = DAMAGE;
damageDelay = DAMAGE_INITIAL_DELAY;
damageRepeat = DAMAGE_INTERVAL;
slow = SLOW;
slowRepeat = SLOW_INTERVAL;
slowDelay = SLOW_DELAY;
blind = BLIND;
blindDelay = BLIND_DELAY;
blindRepeat = BLIND_INTERVAL;
if (instances.containsKey(player)) {
super(player);
if (bPlayer.isOnCooldown(this)) {
return;
} else if (CoreAbility.hasAbility(player, Suffocate.class)) {
return;
}
if (AvatarState.isAvatarState(player)) {
this.started = false;
this.requireConstantAim = getConfig().getBoolean("Abilities.Air.Suffocate.RequireConstantAim");
this.canSuffocateUndead = getConfig().getBoolean("Abilities.Air.Suffocate.CanBeUsedOnUndeadMobs");
this.particleCount = getConfig().getInt("Abilities.Air.Suffocate.AnimationParticleAmount");
this.animationSpeed = getConfig().getDouble("Abilities.Air.Suffocate.AnimationSpeed");
this.chargeTime = getConfig().getLong("Abilities.Air.Suffocate.ChargeTime");
this.cooldown = getConfig().getLong("Abilities.Air.Suffocate.Cooldown");
this.range = getConfig().getDouble("Abilities.Air.Suffocate.Range");
this.radius = getConfig().getDouble("Abilities.Air.Suffocate.AnimationRadius");
this.constantAimRadius = getConfig().getDouble("Abilities.Air.Suffocate.RequireConstantAimRadius");
this.damage = getConfig().getDouble("Abilities.Air.Suffocate.Damage");
this.damageDelay = getConfig().getDouble("Abilities.Air.Suffocate.DamageInitialDelay");
this.damageRepeat = getConfig().getDouble("Abilities.Air.Suffocate.DamageInterval");
this.slow = getConfig().getInt("Abilities.Air.Suffocate.SlowPotency");
this.slowRepeat = getConfig().getDouble("Abilities.Air.Suffocate.SlowInterval");
this.slowDelay = getConfig().getDouble("Abilities.Air.Suffocate.SlowDelay");
this.blind = getConfig().getInt("Abilities.Air.Suffocate.BlindPotentcy");
this.blindDelay = getConfig().getDouble("Abilities.Air.Suffocate.BlindDelay");
this.blindRepeat = getConfig().getDouble("Abilities.Air.Suffocate.BlindInterval");
this.targets = new ArrayList<LivingEntity>();
this.tasks = new ArrayList<BukkitRunnable>();
if (bPlayer.isAvatarState()) {
cooldown = 0;
chargeTime = 0;
reqConstantAim = false;
requireConstantAim = false;
damage = AvatarState.getValue(damage);
range *= 2;
slow = AvatarState.getValue(slow);
@ -119,36 +95,27 @@ public class Suffocate implements ConfigLoadable {
blind = AvatarState.getValue(blind);
blindRepeat = AvatarState.getValue(blindRepeat);
}
if (particleScale < 1)
particleScale = 1;
else if (particleScale > 2)
particleScale = 2;
if (AvatarState.isAvatarState(player)) {
for (Entity ent : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), range))
if (ent instanceof LivingEntity && !ent.equals(player))
targets.add((LivingEntity) ent);
} else {
//Entity ent = GeneralMethods.getTargetedEntity(player, range, new ArrayList<Entity>());
List<Entity> entities = new ArrayList<Entity>();
for (int i = 0; i < 6; i++) {
Location location = GeneralMethods.getTargetedLocation(player, i, transparent);
entities = GeneralMethods.getEntitiesAroundPoint(location, 1.7);
if (entities.contains(player))
entities.remove(player);
if (entities != null && !entities.isEmpty() && !entities.contains(player)) {
break;
}
}
if (entities == null || entities.isEmpty()) {
return;
}
Entity target = entities.get(0);
if (target != null && target instanceof LivingEntity)
targets.add((LivingEntity) target);
if (particleCount < 1) {
particleCount = 1;
} else if (particleCount > 2) {
particleCount = 2;
}
if (!canSuffUndead) {
if (bPlayer.isAvatarState()) {
for (Entity ent : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), range)) {
if (ent instanceof LivingEntity && !ent.equals(player)) {
targets.add((LivingEntity) ent);
}
}
} else {
Entity ent = GeneralMethods.getTargetedEntity(player, range);
if (ent != null && ent instanceof LivingEntity) {
targets.add((LivingEntity) ent);
}
}
if (!canSuffocateUndead) {
for (int i = 0; i < targets.size(); i++) {
LivingEntity target = targets.get(i);
if (GeneralMethods.isUndead(target)) {
@ -158,242 +125,18 @@ public class Suffocate implements ConfigLoadable {
}
}
if (targets.size() == 0)
return;
else if (bplayer.isOnCooldown("suffocate"))
return;
bplayer.addCooldown("suffocate", cooldown);
instances.put(player, this);
bPlayer.addCooldown(this);
start();
}
/** Stops an entity from being suffocated **/
public static void breakSuffocate(Entity entity) {
for (Suffocate suffocate : instances.values()) {
if (suffocate.targets.contains(entity)) {
suffocate.breakSuffocateLocal(entity);
}
}
}
/** Checks if an entity is being suffocated **/
public static boolean isBreathbent(Entity entity) {
for (Suffocate suffocate : instances.values()) {
if (suffocate.targets.contains(entity)) {
return suffocate.started;
}
}
return false;
}
/** Determines if a player is Suffocating entities **/
public static boolean isChannelingSphere(Player player) {
return instances.containsKey(player);
}
/**
* Removes an instance of Suffocate if player is the one suffocating entities
**/
public static void remove(Player player) {
if (instances.containsKey(player)) {
instances.get(player).remove();
}
}
public static void removeAll() {
for (Suffocate ability : instances.values()) {
ability.remove();
}
}
/**
* Removes all instances of Suffocate at loc within the radius threshold. The location of a
* Suffocate is defined at the benders location, not the location of the entities being
* suffocated.
*
* @param causer The player causing this instance to be removed
**/
public static boolean removeAtLocation(Player causer, Location loc, double radius) {
for (Player player : instances.keySet()) {
Suffocate suff = instances.get(player);
if (causer == null || !player.equals(causer)) {
Location playerLoc = suff.getPlayer().getLocation();
if (playerLoc.getWorld().equals(loc.getWorld()) && playerLoc.distance(loc) <= radius) {
suff.remove();
return true;
}
}
}
return false;
}
/**
* Animates this instance of the Suffocate ability. Depending on the specific time (dt) the
* ability will create a different set of SuffocationSpirals.
*/
public void animate() {
long curTime = System.currentTimeMillis();
long dt = curTime - time - chargeTime;
int steps = 8 * particleScale;
long delay = 2 / particleScale;
long t1 = (long) (1500 * speedFactor);
long t2 = (long) (2500 * speedFactor);
long t3 = (long) (5000 * speedFactor);
long t4 = (long) (6000 * speedFactor);
for (LivingEntity lent : targets) {
final LivingEntity target = lent;
if (dt < t1) {
new SuffocateSpiral(target, steps, radius, delay, 0, 0.25 - (0.25 * (double) dt / (double) t1), 0,
SpiralType.HORIZONTAL1);
new SuffocateSpiral(target, steps, radius, delay, 0, 0.25 - (0.25 * (double) dt / (double) t1), 0,
SpiralType.HORIZONTAL2);
} else if (dt < t2) {
new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.HORIZONTAL1);
new SuffocateSpiral(target, steps * 2, radius, delay, 0, 0, 0, SpiralType.VERTICAL1);
new SuffocateSpiral(target, steps * 2, radius, delay, 0, 0, 0, SpiralType.VERTICAL2);
} else if (dt < t3) {
new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.HORIZONTAL1);
new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.VERTICAL1);
new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.VERTICAL2);
} else if (dt < t4) {
new SuffocateSpiral(target, steps, radius
- Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double) (dt - t3) / (double) (t4 - t3)))), delay, 0, 0,
0, SpiralType.HORIZONTAL1);
new SuffocateSpiral(target, steps, radius
- Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double) (dt - t3) / (double) (t4 - t3)))), delay, 0, 0,
0, SpiralType.VERTICAL1);
new SuffocateSpiral(target, steps, radius
- Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double) (dt - t3) / (double) (t4 - t3)))), delay, 0, 0,
0, SpiralType.VERTICAL2);
} else {
new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.HORIZONTAL1);
new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.VERTICAL1);
new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.VERTICAL2);
}
}
}
/** Stops an entity from being suffocated **/
public void breakSuffocateLocal(Entity entity) {
if (targets.contains(entity))
targets.remove(entity);
}
public double getAimRadius() {
return aimRadius;
}
public double getBlind() {
return blind;
}
public double getBlindDelay() {
return blindDelay;
}
public double getBlindRepeat() {
return blindRepeat;
}
public long getChargeTime() {
return chargeTime;
}
public long getCooldown() {
return cooldown;
}
public double getDamage() {
return damage;
}
public double getDamageDelay() {
return damageDelay;
}
public double getDamageRepeat() {
return damageRepeat;
}
public int getParticleScale() {
return particleScale;
}
public Player getPlayer() {
return player;
}
public double getRadius() {
return radius;
}
public double getRange() {
return range;
}
public double getSlow() {
return slow;
}
public double getSlowDelay() {
return slowDelay;
}
public double getslowRepeat() {
return slowRepeat;
}
public double getSpeedFactor() {
return speedFactor;
}
public ArrayList<LivingEntity> getTargets() {
return targets;
}
public ArrayList<BukkitRunnable> getTasks() {
return tasks;
}
public long getTime() {
return time;
}
public boolean isCanSuffUndead() {
return canSuffUndead;
}
public boolean isReqConstantAim() {
return reqConstantAim;
}
public boolean isStarted() {
return started;
}
/**
* Progresses this instance of Suffocate by 1 tick.
*
* @return true If progress does not stop, progresses succesfully
*/
public boolean progress() {
if (targets.size() == 0) {
remove();
return false;
}
if (player.isDead() || !player.isOnline()) {
remove();
return false;
}
String ability = GeneralMethods.getBoundAbility(player);
if (ability == null || !ability.equalsIgnoreCase("Suffocate") || !GeneralMethods.canBend(player.getName(), "Suffocate")) {
remove();
return false;
}
@Override
public void progress() {
for (int i = 0; i < targets.size(); i++) {
LivingEntity target = targets.get(i);
if (target.isDead() || !target.getWorld().equals(player.getWorld())
|| target.getLocation().distance(player.getEyeLocation()) > range) {
if (target.isDead()
|| !target.getWorld().equals(player.getWorld())
|| target.getLocation().distanceSquared(player.getEyeLocation()) > range * range
|| GeneralMethods.isRegionProtectedFromBuild(this, target.getLocation())) {
breakSuffocateLocal(target);
i--;
} else if (target instanceof Player) {
@ -404,16 +147,16 @@ public class Suffocate implements ConfigLoadable {
}
}
}
if (targets.size() == 0) {
if (targets.size() == 0 || !bPlayer.canBendIgnoreCooldowns(this)) {
remove();
return false;
return;
}
if (reqConstantAim) {
if (requireConstantAim) {
double dist = player.getEyeLocation().distance(targets.get(0).getEyeLocation());
Location targetLoc = player.getEyeLocation().clone()
.add(player.getEyeLocation().getDirection().normalize().multiply(dist));
List<Entity> ents = GeneralMethods.getEntitiesAroundPoint(targetLoc, aimRadius);
List<Entity> ents = GeneralMethods.getEntitiesAroundPoint(targetLoc, constantAimRadius);
for (int i = 0; i < targets.size(); i++) {
LivingEntity target = targets.get(i);
@ -424,12 +167,12 @@ public class Suffocate implements ConfigLoadable {
}
if (targets.size() == 0) {
remove();
return false;
return;
}
}
if (System.currentTimeMillis() - time < chargeTime) {
return false;
if (System.currentTimeMillis() - startTime < chargeTime) {
return;
} else if (!started) {
started = true;
final Player fplayer = player;
@ -466,43 +209,124 @@ public class Suffocate implements ConfigLoadable {
animate();
if (!player.isSneaking()) {
remove();
return;
}
}
/** Stops an entity from being suffocated **/
public static void breakSuffocate(Entity entity) {
for (Suffocate suffocate : CoreAbility.getAbilities(Suffocate.class)) {
if (suffocate.targets.contains(entity)) {
suffocate.breakSuffocateLocal(entity);
}
}
}
/** Checks if an entity is being suffocated **/
public static boolean isBreathbent(Entity entity) {
for (Suffocate suffocate : CoreAbility.getAbilities(Suffocate.class)) {
if (suffocate.targets.contains(entity)) {
return suffocate.started;
}
}
return false;
}
/** Determines if a player is Suffocating entities **/
public static boolean isChannelingSphere(Player player) {
return CoreAbility.hasAbility(player, Suffocate.class);
}
/**
* Removes an instance of Suffocate if player is the one suffocating entities
**/
public static void remove(Player player) {
Suffocate suff = CoreAbility.getAbility(player, Suffocate.class);
if (suff != null) {
suff.remove();
}
}
/**
* Removes all instances of Suffocate at loc within the radius threshold. The location of a
* Suffocate is defined at the benders location, not the location of the entities being
* suffocated.
*
* @param causer The player causing this instance to be removed
**/
public static boolean removeAtLocation(Player causer, Location loc, double radius) {
if (causer == null) {
return false;
}
return true;
for (Suffocate suff : CoreAbility.getAbilities(Suffocate.class)) {
if (!suff.player.equals(causer)) {
Location playerLoc = suff.getPlayer().getLocation();
if (playerLoc.getWorld().equals(loc.getWorld()) && playerLoc.distanceSquared(loc) <= radius * radius) {
suff.remove();
return true;
}
}
}
return false;
}
public static void progressAll() {
for (Suffocate ability : instances.values()) {
ability.progress();
/**
* Animates this instance of the Suffocate ability. Depending on the specific time (dt) the
* ability will create a different set of SuffocationSpirals.
*/
public void animate() {
int steps = 8 * particleCount;
long curTime = System.currentTimeMillis();
long dt = curTime - startTime - chargeTime;
long delay = 2 / particleCount;
long t1 = (long) (1500 * animationSpeed);
long t2 = (long) (2500 * animationSpeed);
long t3 = (long) (5000 * animationSpeed);
long t4 = (long) (6000 * animationSpeed);
for (LivingEntity lent : targets) {
final LivingEntity target = lent;
if (dt < t1) {
new SuffocateSpiral(target, steps, radius, delay, 0, 0.25 - (0.25 * (double) dt / (double) t1), 0,
SpiralType.HORIZONTAL1);
new SuffocateSpiral(target, steps, radius, delay, 0, 0.25 - (0.25 * (double) dt / (double) t1), 0,
SpiralType.HORIZONTAL2);
} else if (dt < t2) {
new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.HORIZONTAL1);
new SuffocateSpiral(target, steps * 2, radius, delay, 0, 0, 0, SpiralType.VERTICAL1);
new SuffocateSpiral(target, steps * 2, radius, delay, 0, 0, 0, SpiralType.VERTICAL2);
} else if (dt < t3) {
new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.HORIZONTAL1);
new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.VERTICAL1);
new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.VERTICAL2);
} else if (dt < t4) {
new SuffocateSpiral(target, steps, radius
- Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double) (dt - t3) / (double) (t4 - t3)))), delay, 0, 0,
0, SpiralType.HORIZONTAL1);
new SuffocateSpiral(target, steps, radius
- Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double) (dt - t3) / (double) (t4 - t3)))), delay, 0, 0,
0, SpiralType.VERTICAL1);
new SuffocateSpiral(target, steps, radius
- Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double) (dt - t3) / (double) (t4 - t3)))), delay, 0, 0,
0, SpiralType.VERTICAL2);
} else {
new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.HORIZONTAL1);
new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.VERTICAL1);
new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.VERTICAL2);
}
}
}
@Override
public void reloadVariables() {
CAN_SUFFOCATE_UNDEAD = config.get().getBoolean("Abilities.Air.Suffocate.CanBeUsedOnUndeadMobs");
REQUIRE_CONSTANT_AIM = config.get().getBoolean("Abilities.Air.Suffocate.RequireConstantAim");
ANIM_RADIUS = config.get().getDouble("Abilities.Air.Suffocate.AnimationRadius");
ANIM_PARTICLE_AMOUNT = config.get().getInt("Abilities.Air.Suffocate.AnimationParticleAmount");
ANIM_SPEED = config.get().getDouble("Abilities.Air.Suffocate.AnimationSpeed");
CHARGE_TIME = config.get().getLong("Abilities.Air.Suffocate.ChargeTime");
COOLDOWN = config.get().getLong("Abilities.Air.Suffocate.Cooldown");
RANGE = config.get().getDouble("Abilities.Air.Suffocate.Range");
AIM_RADIUS = config.get().getDouble("Abilities.Air.Suffocate.RequireConstantAimRadius");
DAMAGE = config.get().getDouble("Abilities.Air.Suffocate.Damage");
DAMAGE_INITIAL_DELAY = config.get().getDouble("Abilities.Air.Suffocate.DamageInitialDelay");
DAMAGE_INTERVAL = config.get().getDouble("Abilities.Air.Suffocate.DamageInterval");
SLOW = config.get().getInt("Abilities.Air.Suffocate.SlowPotency");
SLOW_INTERVAL = config.get().getDouble("Abilities.Air.Suffocate.SlowInterval");
SLOW_DELAY = config.get().getDouble("Abilities.Air.Suffocate.SlowDelay");
BLIND = config.get().getInt("Abilities.Air.Suffocate.BlindPotentcy");
BLIND_DELAY = config.get().getDouble("Abilities.Air.Suffocate.BlindDelay");
BLIND_INTERVAL = config.get().getDouble("Abilities.Air.Suffocate.BlindInterval");
/** Stops an entity from being suffocated **/
public void breakSuffocateLocal(Entity entity) {
if (targets.contains(entity)) {
targets.remove(entity);
}
}
/** Removes this instance of the ability **/
@Override
public void remove() {
instances.remove(player);
super.remove();
for (int i = 0; i < tasks.size(); i++) {
tasks.get(i).cancel();
tasks.remove(i);
@ -510,98 +334,6 @@ public class Suffocate implements ConfigLoadable {
}
}
public void setAimRadius(double aimRadius) {
this.aimRadius = aimRadius;
}
public void setBlind(double blind) {
this.blind = blind;
}
public void setBlindDelay(double blindDelay) {
this.blindDelay = blindDelay;
}
public void setBlindRepeat(double blindRepeat) {
this.blindRepeat = blindRepeat;
}
public void setCanSuffUndead(boolean canSuffUndead) {
this.canSuffUndead = canSuffUndead;
}
public void setChargeTime(long chargeTime) {
this.chargeTime = chargeTime;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
public void setDamage(double damage) {
this.damage = damage;
}
public void setDamageDelay(double damageDelay) {
this.damageDelay = damageDelay;
}
public void setDamageRepeat(double damageRepeat) {
this.damageRepeat = damageRepeat;
}
public void setParticleScale(int particleScale) {
this.particleScale = particleScale;
}
public void setRadius(double radius) {
this.radius = radius;
}
public void setRange(double range) {
this.range = range;
}
public void setReqConstantAim(boolean reqConstantAim) {
this.reqConstantAim = reqConstantAim;
}
public void setSlow(double slow) {
this.slow = slow;
}
public void setSlowDelay(double slowDelay) {
this.slowDelay = slowDelay;
}
public void setslowRepeat(double slowRepeat) {
this.slowRepeat = slowRepeat;
}
public void setSpeedFactor(double speedFactor) {
this.speedFactor = speedFactor;
}
public void setStarted(boolean started) {
this.started = started;
}
public void setTargets(ArrayList<LivingEntity> targets) {
this.targets = targets;
}
public void setTasks(ArrayList<BukkitRunnable> tasks) {
this.tasks = tasks;
}
public void setTime(long time) {
this.time = time;
}
public static enum SpiralType {
HORIZONTAL1, HORIZONTAL2, VERTICAL1, VERTICAL2, DIAGONAL1, DIAGONAL2
};
/**
* ** Animates a Spiral of air particles around a location or a targetted entity. The direction
* of the spiral is determined by SpiralType, and each type is calculated independently from one
@ -636,9 +368,8 @@ public class Suffocate implements ConfigLoadable {
this.dy = dy;
this.dz = dz;
this.type = type;
loc = target.getEyeLocation();
i = 0;
this.loc = target.getEyeLocation();
this.i = 0;
this.runTaskTimer(ProjectKorra.plugin, 0L, interval);
tasks.add(this);
}
@ -662,9 +393,8 @@ public class Suffocate implements ConfigLoadable {
this.dy = dy;
this.dz = dz;
this.type = type;
loc = startLoc.clone();
i = 0;
this.loc = startLoc.clone();
this.i = 0;
this.runTaskTimer(ProjectKorra.plugin, 0L, interval);
tasks.add(this);
}
@ -707,10 +437,197 @@ public class Suffocate implements ConfigLoadable {
loc.setZ(tempLoc.getZ() + radius * Math.cos(Math.toRadians((double) i / (double) totalSteps * 360)));
}
AirMethods.getAirbendingParticles().display(loc, (float) 0, (float) 0, (float) 0, 0, 1);
if (i == totalSteps + 1)
getAirbendingParticles().display(loc, (float) 0, (float) 0, (float) 0, 0, 1);
if (i == totalSteps + 1) {
this.cancel();
}
i++;
}
}
@Override
public String getName() {
return "Suffocate";
}
@Override
public Location getLocation() {
if (targets.size() > 0) {
return targets.get(0).getLocation();
} else if (player != null) {
return player.getLocation();
}
return null;
}
@Override
public long getCooldown() {
return cooldown;
}
@Override
public boolean isSneakAbility() {
return true;
}
@Override
public boolean isHarmlessAbility() {
return false;
}
public boolean isStarted() {
return started;
}
public void setStarted(boolean started) {
this.started = started;
}
public boolean isRequireConstantAim() {
return requireConstantAim;
}
public void setRequireConstantAim(boolean requireConstantAim) {
this.requireConstantAim = requireConstantAim;
}
public boolean isCanSuffocateUndead() {
return canSuffocateUndead;
}
public void setCanSuffocateUndead(boolean canSuffocateUndead) {
this.canSuffocateUndead = canSuffocateUndead;
}
public int getParticleCount() {
return particleCount;
}
public void setParticleCount(int particleCount) {
this.particleCount = particleCount;
}
public long getChargeTime() {
return chargeTime;
}
public void setChargeTime(long chargeTime) {
this.chargeTime = chargeTime;
}
public double getRange() {
return range;
}
public void setRange(double range) {
this.range = range;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getDamage() {
return damage;
}
public void setDamage(double damage) {
this.damage = damage;
}
public double getDamageDelay() {
return damageDelay;
}
public void setDamageDelay(double damageDelay) {
this.damageDelay = damageDelay;
}
public double getDamageRepeat() {
return damageRepeat;
}
public void setDamageRepeat(double damageRepeat) {
this.damageRepeat = damageRepeat;
}
public double getSlow() {
return slow;
}
public void setSlow(double slow) {
this.slow = slow;
}
public double getSlowRepeat() {
return slowRepeat;
}
public void setSlowRepeat(double slowRepeat) {
this.slowRepeat = slowRepeat;
}
public double getSlowDelay() {
return slowDelay;
}
public void setSlowDelay(double slowDelay) {
this.slowDelay = slowDelay;
}
public double getConstantAimRadius() {
return constantAimRadius;
}
public void setConstantAimRadius(double constantAimRadius) {
this.constantAimRadius = constantAimRadius;
}
public double getBlind() {
return blind;
}
public void setBlind(double blind) {
this.blind = blind;
}
public double getBlindDelay() {
return blindDelay;
}
public void setBlindDelay(double blindDelay) {
this.blindDelay = blindDelay;
}
public double getBlindRepeat() {
return blindRepeat;
}
public void setBlindRepeat(double blindRepeat) {
this.blindRepeat = blindRepeat;
}
public double getAnimationSpeed() {
return animationSpeed;
}
public void setAnimationSpeed(double animationSpeed) {
this.animationSpeed = animationSpeed;
}
public ArrayList<BukkitRunnable> getTasks() {
return tasks;
}
public ArrayList<LivingEntity> getTargets() {
return targets;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
}

View file

@ -1,8 +1,9 @@
package com.projectkorra.projectkorra.airbending;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.util.Flight;
import org.bukkit.Location;
import org.bukkit.Material;
@ -10,173 +11,98 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
import com.projectkorra.projectkorra.util.Flight;
import java.util.HashSet;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
public class Tornado implements ConfigLoadable {
public class Tornado extends AirAbility {
public static ConcurrentHashMap<Player, Tornado> instances = new ConcurrentHashMap<>();
private static double MAX_HEIGHT = config.get().getDouble("Abilities.Air.Tornado.Height");
private static double PLAYER_PUSH_FACTOR = config.get().getDouble("Abilities.Air.Tornado.PlayerPushFactor");
private static double MAX_RADIUS = config.get().getDouble("Abilities.Air.Tornado.Radius");
private static double RANGE = config.get().getDouble("Abilities.Air.Tornado.Range");
private static double NPC_PUSH_FACTOR = config.get().getDouble("Abilities.Air.Tornado.MobPushFactor");
private static int numberOfStreams = (int) (.3 * (double) MAX_HEIGHT);
// private static double speed = .75;
// private static double speedfactor = 1000 * speed
// * (Bending.time_step / 1000.);
private static double speedfactor = 1;
private ConcurrentHashMap<Integer, Integer> angles = new ConcurrentHashMap<Integer, Integer>();
private int numberOfStreams;
private int particleCount;
private double speed;
private double maxHeight;
private double playerPushFactor;
private double radius;
private double range;
private double npcPushFactor;
private double currentHeight;
private double currentRadius;
private Flight flight;
private Location origin;
private Player player;
private double maxheight = MAX_HEIGHT;
private double PCpushfactor = PLAYER_PUSH_FACTOR;
private double maxradius = MAX_RADIUS;
private double range = RANGE;
private double NPCpushfactor = NPC_PUSH_FACTOR;
private double height = 2;
private double radius = height / maxheight * maxradius;
// private boolean canfly;
private Random random;
private ConcurrentHashMap<Integer, Integer> angles;
public Tornado(Player player) {
// reloadVariables();
this.player = player;
// canfly = player.getAllowFlight();
// player.setAllowFlight(true);
origin = player.getTargetBlock((HashSet<Material>) null, (int) range).getLocation();
origin.setY(origin.getY() - 1. / 10. * height);
super(player);
this.origin = player.getTargetBlock((HashSet<Material>) null, (int) range).getLocation();
this.origin.setY(origin.getY() - 1.0 / 10.0 * currentHeight);
this.maxHeight = getConfig().getDouble("Abilities.Air.Tornado.Height");
this.playerPushFactor = getConfig().getDouble("Abilities.Air.Tornado.PlayerPushFactor");
this.radius = getConfig().getDouble("Abilities.Air.Tornado.Radius");
this.range = getConfig().getDouble("Abilities.Air.Tornado.Range");
this.npcPushFactor = getConfig().getDouble("Abilities.Air.Tornado.MobPushFactor");
this.speed = 1;
this.numberOfStreams = (int) (.3 * (double) maxHeight);
this.currentHeight = 2;
this.currentRadius = currentHeight / maxHeight * radius;
this.random = new Random();
this.angles = new ConcurrentHashMap<>();
int angle = 0;
for (int i = 0; i <= maxheight; i += (int) maxheight / numberOfStreams) {
for (int i = 0; i <= maxHeight; i += (int) maxHeight / numberOfStreams) {
angles.put(i, angle);
angle += 90;
if (angle == 360)
if (angle == 360) {
angle = 0;
}
}
new Flight(player);
this.flight = new Flight(player);
player.setAllowFlight(true);
instances.put(player, this);
}
public static ArrayList<Player> getPlayers() {
ArrayList<Player> players = new ArrayList<Player>();
for (Tornado tornado : instances.values()) {
players.add(tornado.getPlayer());
}
return players;
}
public double getMaxheight() {
return maxheight;
}
public double getMaxradius() {
return maxradius;
}
public double getNPCpushfactor() {
return NPCpushfactor;
}
public double getPCpushfactor() {
return PCpushfactor;
}
public Player getPlayer() {
return player;
}
public double getRange() {
return range;
}
public boolean progress() {
if (player.isDead() || !player.isOnline()) {
remove();
return false;
}
if (!GeneralMethods.canBend(player.getName(), "Tornado") || player.getEyeLocation().getBlock().isLiquid()) {
remove();
return false;
}
String abil = GeneralMethods.getBoundAbility(player);
if (abil == null) {
remove();
return false;
}
if (!abil.equalsIgnoreCase("Tornado") || !player.isSneaking()) {
remove();
return false;
}
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", origin)) {
remove();
return false;
}
rotateTornado();
return true;
}
public static void progressAll() {
for (Tornado ability : instances.values()) {
ability.progress();
}
}
public void remove() {
instances.remove(player);
}
public static void removeAll() {
for (Tornado ability : instances.values()) {
ability.remove();
}
start();
}
@Override
public void reloadVariables() {
MAX_HEIGHT = config.get().getDouble("Abilities.Air.Tornado.Height");
PLAYER_PUSH_FACTOR = config.get().getDouble("Abilities.Air.Tornado.PlayerPushFactor");
MAX_RADIUS = config.get().getDouble("Abilities.Air.Tornado.Radius");
RANGE = config.get().getDouble("Abilities.Air.Tornado.Range");
NPC_PUSH_FACTOR = config.get().getDouble("Abilities.Air.Tornado.MobPushFactor");
numberOfStreams = (int) (.3 * (double) MAX_HEIGHT);
maxheight = MAX_HEIGHT;
PCpushfactor = PLAYER_PUSH_FACTOR;
maxradius = MAX_RADIUS;
range = RANGE;
NPCpushfactor = NPC_PUSH_FACTOR;
radius = height / maxheight * maxradius;
public void progress() {
if (player.getEyeLocation().getBlock().isLiquid() || !player.isSneaking() || !bPlayer.canBendIgnoreCooldowns(this)) {
remove();
return;
} else if (GeneralMethods.isRegionProtectedFromBuild(this, origin)) {
remove();
return;
}
rotateTornado();
}
@Override
public void remove() {
super.remove();
flight.remove();
player.setAllowFlight(false);
}
private void rotateTornado() {
origin = player.getTargetBlock((HashSet<Material>) null, (int) range).getLocation();
double timefactor = height / maxheight;
radius = timefactor * maxradius;
double timefactor = currentHeight / maxHeight;
currentRadius = timefactor * radius;
if (origin.getBlock().getType() != Material.AIR) {
origin.setY(origin.getY() - 1. / 10. * height);
origin.setY(origin.getY() - 1. / 10. * currentHeight);
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(origin, height)) {
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", entity.getLocation()))
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(origin, currentHeight)) {
if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) {
continue;
}
double y = entity.getLocation().getY();
double factor;
if (y > origin.getY() && y < origin.getY() + height) {
factor = (y - origin.getY()) / height;
if (y > origin.getY() && y < origin.getY() + currentHeight) {
factor = (y - origin.getY()) / currentHeight;
Location testloc = new Location(origin.getWorld(), origin.getX(), y, origin.getZ());
if (testloc.distance(entity.getLocation()) < radius * factor) {
if (testloc.distance(entity.getLocation()) < currentRadius * factor) {
double x, z, vx, vz, mag;
double angle = 100;
double vy = 0.7 * NPCpushfactor;
double vy = 0.7 * npcPushFactor;
angle = Math.toRadians(angle);
x = entity.getLocation().getX() - origin.getX();
@ -188,7 +114,7 @@ public class Tornado implements ConfigLoadable {
vz = (x * Math.sin(angle) + z * Math.cos(angle)) / mag;
if (entity instanceof Player) {
vy = 0.05 * PCpushfactor;
vy = 0.05 * playerPushFactor;
}
if (entity.getEntityId() == player.getEntityId()) {
@ -199,18 +125,20 @@ public class Tornado implements ConfigLoadable {
double py = playerloc.getY();
double oy = origin.getY();
double dy = py - oy;
if (dy >= height * .95) {
if (dy >= currentHeight * .95) {
vy = 0;
} else if (dy >= height * .85) {
vy = 6.0 * (.95 - dy / height);
} else if (dy >= currentHeight * .85) {
vy = 6.0 * (.95 - dy / currentHeight);
} else {
vy = .6;
}
}
if (entity instanceof Player) {
if (Commands.invincible.contains(((Player) entity).getName()))
if (Commands.invincible.contains(((Player) entity).getName())) {
continue;
}
}
Vector velocity = entity.getVelocity();
@ -221,7 +149,7 @@ public class Tornado implements ConfigLoadable {
GeneralMethods.setVelocity(entity, velocity);
entity.setFallDistance(0);
AirMethods.breakBreathbendingHold(entity);
breakBreathbendingHold(entity);
if (entity instanceof Player) {
new Flight((Player) entity);
@ -231,59 +159,143 @@ public class Tornado implements ConfigLoadable {
}
for (int i : angles.keySet()) {
double x, y, z;
double x, y, z, factor;
double angle = (double) angles.get(i);
angle = Math.toRadians(angle);
double factor;
y = origin.getY() + timefactor * (double) i;
factor = (double) i / height;
factor = (double) i / currentHeight;
x = origin.getX() + timefactor * factor * radius * Math.cos(angle);
z = origin.getZ() + timefactor * factor * radius * Math.sin(angle);
x = origin.getX() + timefactor * factor * currentRadius * Math.cos(angle);
z = origin.getZ() + timefactor * factor * currentRadius * Math.sin(angle);
Location effect = new Location(origin.getWorld(), x, y, z);
if (!GeneralMethods.isRegionProtectedFromBuild(player, "AirBlast", effect)) {
AirMethods.playAirbendingParticles(effect, 4);
if (GeneralMethods.rand.nextInt(20) == 0) {
AirMethods.playAirbendingSound(effect);
if (!GeneralMethods.isRegionProtectedFromBuild(this, effect)) {
playAirbendingParticles(effect, particleCount);
if (random.nextInt(20) == 0) {
playAirbendingSound(effect);
}
}
// origin.getWorld().playEffect(effect, Effect.SMOKE, 4, (int)
// AirBlast.defaultrange);
angles.put(i, angles.get(i) + 25 * (int) speedfactor);
angles.put(i, angles.get(i) + 25 * (int) speed);
}
}
if (height < maxheight) {
height += 1;
}
if (height > maxheight) {
height = maxheight;
}
currentHeight = currentHeight > maxHeight ? maxHeight : currentHeight + 1;
}
public void setMaxheight(double maxheight) {
this.maxheight = maxheight;
@Override
public String getName() {
return "Tornado";
}
public void setMaxradius(double maxradius) {
this.maxradius = maxradius;
@Override
public Location getLocation() {
return player != null ? player.getLocation() : null;
}
public void setNPCpushfactor(double nPCpushfactor) {
NPCpushfactor = nPCpushfactor;
@Override
public long getCooldown() {
return 0;
}
@Override
public boolean isSneakAbility() {
return true;
}
public void setPCpushfactor(double pCpushfactor) {
PCpushfactor = pCpushfactor;
@Override
public boolean isHarmlessAbility() {
return false;
}
public Location getOrigin() {
return origin;
}
public void setOrigin(Location origin) {
this.origin = origin;
}
public int getNumberOfStreams() {
return numberOfStreams;
}
public void setNumberOfStreams(int numberOfStreams) {
this.numberOfStreams = numberOfStreams;
}
public int getParticleCount() {
return particleCount;
}
public void setParticleCount(int particleCount) {
this.particleCount = particleCount;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public double getMaxHeight() {
return maxHeight;
}
public void setMaxHeight(double maxHeight) {
this.maxHeight = maxHeight;
}
public double getPlayerPushFactor() {
return playerPushFactor;
}
public void setPlayerPushFactor(double playerPushFactor) {
this.playerPushFactor = playerPushFactor;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getRange() {
return range;
}
public void setRange(double range) {
this.range = range;
}
public double getNpcPushFactor() {
return npcPushFactor;
}
public void setNpcPushFactor(double npcPushFactor) {
this.npcPushFactor = npcPushFactor;
}
public double getCurrentHeight() {
return currentHeight;
}
public void setCurrentHeight(double currentHeight) {
this.currentHeight = currentHeight;
}
public double getCurrentRadius() {
return currentRadius;
}
public void setCurrentRadius(double currentRadius) {
this.currentRadius = currentRadius;
}
public ConcurrentHashMap<Integer, Integer> getAngles() {
return angles;
}
}

View file

@ -0,0 +1,232 @@
package com.projectkorra.projectkorra.avatar;
import com.projectkorra.projectkorra.ability.AvatarAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.util.Flight;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.HashMap;
public class AvatarState extends AvatarAbility {
private static final HashMap<String, Long> START_TIMES = new HashMap<>();
private boolean regenEnabled;
private boolean speedEnabled;
private boolean resistanceEnabled;
private boolean fireResistanceEnabled;
private int regenPower;
private int speedPower;
private int resistancePower;
private int fireResistancePower;
private long duration;
private long cooldown;
private double factor;
public AvatarState(Player player) {
super(player);
AvatarState oldAbil = CoreAbility.getAbility(player, AvatarState.class);
if (oldAbil != null) {
oldAbil.remove();
return;
} else if (bPlayer.isOnCooldown(this)) {
return;
}
this.regenEnabled = getConfig().getBoolean("Abilities.AvatarState.PotionEffects.Regeneration.Enabled");
this.speedEnabled = getConfig().getBoolean("Abilities.AvatarState.PotionEffects.Speed.Enabled");
this.resistanceEnabled = getConfig().getBoolean("Abilities.AvatarState.PotionEffects.DamageResistance.Enabled");
this.fireResistanceEnabled = getConfig().getBoolean("Abilities.AvatarState.PotionEffects.FireResistance.Enabled");
this.regenPower = getConfig().getInt("Abilities.AvatarState.PotionEffects.Regeneration.Power") - 1;
this.speedPower = getConfig().getInt("Abilities.AvatarState.PotionEffects.Speed.Power") - 1;
this.resistancePower = getConfig().getInt("Abilities.AvatarState.PotionEffects.DamageResistance.Power") - 1;
this.fireResistancePower = getConfig().getInt("Abilities.AvatarState.PotionEffects.FireResistance.Power") - 1;
this.duration = getConfig().getLong("Abilities.AvatarState.Duration");
this.cooldown = getConfig().getLong("Abilities.AvatarState.Cooldown");
this.factor = getConfig().getDouble("Abilities.AvatarState.PowerMultiplier");
new Flight(player);
playAvatarSound(player.getLocation());
start();
bPlayer.addCooldown(this);
if (duration != 0) {
START_TIMES.put(player.getName(), System.currentTimeMillis());
}
}
@Override
public void progress() {
if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
if (player != null) {
if (bPlayer.isOnCooldown(this)) {
bPlayer.removeCooldown(this);
}
}
remove();
return;
}
if (START_TIMES.containsKey(player.getName())) {
if (START_TIMES.get(player.getName()) + duration < System.currentTimeMillis()) {
START_TIMES.remove(player.getName());
remove();
return;
}
}
addPotionEffects();
}
private void addPotionEffects() {
int duration = 70;
if (regenEnabled) {
player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, duration, regenPower));
}
if (speedEnabled) {
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, duration, speedPower));
}
if (resistanceEnabled) {
player.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, duration, resistancePower));
}
if (fireResistanceEnabled) {
player.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, duration, fireResistancePower));
}
}
public static double getValue(double value) {
double factor = getConfig().getDouble("Abilities.AvatarState.PowerMultiplier");
return factor * value;
}
public static int getValue(int value) {
return (int) getValue((double) value);
}
public static double getValue(double value, Player player) {
AvatarState astate = getAbility(player, AvatarState.class);
if (astate != null) {
return astate.getFactor() * value;
}
return value;
}
@Override
public String getName() {
return "AvatarState";
}
@Override
public Location getLocation() {
return player != null ? player.getLocation() : null;
}
@Override
public long getCooldown() {
return cooldown;
}
@Override
public boolean isSneakAbility() {
return false;
}
@Override
public boolean isHarmlessAbility() {
return true;
}
public boolean isRegenEnabled() {
return regenEnabled;
}
public void setRegenEnabled(boolean regenEnabled) {
this.regenEnabled = regenEnabled;
}
public boolean isSpeedEnabled() {
return speedEnabled;
}
public void setSpeedEnabled(boolean speedEnabled) {
this.speedEnabled = speedEnabled;
}
public boolean isResistanceEnabled() {
return resistanceEnabled;
}
public void setResistanceEnabled(boolean resistanceEnabled) {
this.resistanceEnabled = resistanceEnabled;
}
public boolean isFireResistanceEnabled() {
return fireResistanceEnabled;
}
public void setFireResistanceEnabled(boolean fireResistanceEnabled) {
this.fireResistanceEnabled = fireResistanceEnabled;
}
public int getRegenPower() {
return regenPower;
}
public void setRegenPower(int regenPower) {
this.regenPower = regenPower;
}
public int getSpeedPower() {
return speedPower;
}
public void setSpeedPower(int speedPower) {
this.speedPower = speedPower;
}
public int getResistancePower() {
return resistancePower;
}
public void setResistancePower(int resistancePower) {
this.resistancePower = resistancePower;
}
public int getFireResistancePower() {
return fireResistancePower;
}
public void setFireResistancePower(int fireResistancePower) {
this.fireResistancePower = fireResistancePower;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
public double getFactor() {
return factor;
}
public void setFactor(double factor) {
this.factor = factor;
}
public static HashMap<String, Long> getStartTimes() {
return START_TIMES;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
}

View file

@ -1,105 +1,75 @@
package com.projectkorra.projectkorra.chiblocking;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.earthbending.MetalClips;
import com.projectkorra.projectkorra.waterbending.Bloodbending;
import com.projectkorra.projectkorra.ability.ChiAbility;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.concurrent.ConcurrentHashMap;
public class AcrobatStance {
public static double CHI_BLOCK_BOOST = ProjectKorra.plugin.getConfig().getDouble("Abilities.Chi.AcrobatStance.ChiBlockBoost");
public static double PARA_DODGE_BOOST = ProjectKorra.plugin.getConfig().getDouble("Abilities.Chi.AcrobatStance.ParalyzeChanceDecrease");
public static ConcurrentHashMap<Player, AcrobatStance> instances = new ConcurrentHashMap<Player, AcrobatStance>();
private Player player;
public double chiBlockBost = CHI_BLOCK_BOOST;
public double paralyzeDodgeBoost = PARA_DODGE_BOOST;
public int speed = ChiPassive.speedPower + 1;
public int jump = ChiPassive.jumpPower + 1;
public class AcrobatStance extends ChiAbility {
private int speed;
private int jump;
private double chiBlockBoost;
private double paralyzeDodgeBoost;
public AcrobatStance(Player player) {
this.player = player;
if (instances.containsKey(player)) {
instances.remove(player);
return;
super(player);
this.chiBlockBoost = getConfig().getDouble("Abilities.Chi.AcrobatStance.ChiBlockBoost");
this.paralyzeDodgeBoost = getConfig().getDouble("Abilities.Chi.AcrobatStance.ParalyzeChanceDecrease");
this.speed = ChiPassive.getSpeedPower() + 1;
this.jump = ChiPassive.getJumpPower() + 1;
ChiAbility stance = bPlayer.getStance();
if (stance != null && !(stance instanceof AcrobatStance)) {
stance.remove();
bPlayer.setStance(this);
}
if (WarriorStance.isInWarriorStance(player)) {
WarriorStance.remove(player);
}
instances.put(player, this);
start();
}
@Override
public void progress() {
if (player.isDead() || !player.isOnline()) {
if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
remove();
return;
}
if (!GeneralMethods.canBend(player.getName(), "AcrobatStance")) {
remove();
return;
}
if (MetalClips.isControlled(player) || Paralyze.isParalyzed(player) || Bloodbending.isBloodbended(player)) {
remove();
return;
}
if (!player.hasPotionEffect(PotionEffectType.SPEED)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 60, speed));
}
if (!player.hasPotionEffect(PotionEffectType.JUMP)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 60, jump));
}
}
public static void progressAll() {
for (Player player : instances.keySet()) {
instances.get(player).progress();
}
@Override
public String getName() {
return "AcrobatStance";
}
private void remove() {
instances.remove(player);
@Override
public Location getLocation() {
return player != null ? player.getLocation() : null;
}
public static void remove(Player player) {
instances.remove(player);
@Override
public long getCooldown() {
return 0;
}
public static boolean isInAcrobatStance(Player player) {
return instances.containsKey(player);
@Override
public boolean isSneakAbility() {
return false;
}
public double getChiBlockBost() {
return chiBlockBost;
@Override
public boolean isHarmlessAbility() {
return true;
}
public void setChiBlockBost(double chiBlockBost) {
this.chiBlockBost = chiBlockBost;
}
public double getParalyzeDodgeBoost() {
return paralyzeDodgeBoost;
}
public void setParalyzeDodgeBoost(double paralyzeDodgeBoost) {
this.paralyzeDodgeBoost = paralyzeDodgeBoost;
}
public Player getPlayer() {
return player;
}
public int getSpeed() {
return speed;
}
@ -115,4 +85,21 @@ public class AcrobatStance {
public void setJump(int jump) {
this.jump = jump;
}
public double getChiBlockBoost() {
return chiBlockBoost;
}
public void setChiBlockBoost(double chiBlockBoost) {
this.chiBlockBoost = chiBlockBoost;
}
public double getParalyzeDodgeBoost() {
return paralyzeDodgeBoost;
}
public void setParalyzeDodgeBoost(double paralyzeDodgeBoost) {
this.paralyzeDodgeBoost = paralyzeDodgeBoost;
}
}

View file

@ -1,51 +1,54 @@
package com.projectkorra.projectkorra.chiblocking;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.ComboAbility;
import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* A representation of all chi combo moves.
* @author kingbirdy
*
/*
* TODO: Combo classes should eventually be rewritten so that each combo is treated
* as an individual ability. In the mean time, we will just place "fake"
* classes so that CoreAbility will register each ability.
*/
public class ChiCombo {
public class ChiCombo extends ChiAbility implements ComboAbility {
private static boolean enabled = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Chi.ChiCombo.Enabled");
public static long IMMOBILIZE_DURATION = ProjectKorra.plugin.getConfig().getLong("Abilities.Chi.ChiCombo.Immobilize.ParalyzeDuration");
public static long IMMOBILIZE_COOLDOWN = ProjectKorra.plugin.getConfig().getLong("Abilities.Chi.ChiCombo.Immobilize.Cooldown");
/**
* A List of every instance of an active {@link ChiCombo}.
*/
public static List<ChiCombo> instances = new ArrayList<ChiCombo>();
/**
* a Map containing every entity which is paralyzed, and the time in milliseconds at which they will be unparalyzed.
*/
public static Map<Entity, Long> paralyzedEntities = new HashMap<Entity, Long>();
private static final ConcurrentHashMap<Entity, Long> PARALYZED_ENTITIES = new ConcurrentHashMap<>();
//private Player player;
private boolean enabled;
private long duration;
private long cooldown;
private Entity target;
private String name;
public ChiCombo(Player player, String ability) {
if (!enabled)
super(player);
this.name = ability;
this.enabled = getConfig().getBoolean("Abilities.Chi.ChiCombo.Enabled");
if (!enabled) {
return;
}
if (ability.equalsIgnoreCase("Immobilize")) {
if (!GeneralMethods.canBend(player.getName(), "Immobilize") || GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("Immobilize"))
this.cooldown = getConfig().getLong("Abilities.Chi.ChiCombo.Immobilize.Cooldown");
this.duration = getConfig().getLong("Abilities.Chi.ChiCombo.Immobilize.ParalyzeDuration");
if (!bPlayer.canBendIgnoreBinds(this)) {
return;
else {
//this.player = player;
target = GeneralMethods.getTargetedEntity(player, 5, new ArrayList<Entity>());
paralyze(target, IMMOBILIZE_DURATION);
instances.add(this);
GeneralMethods.getBendingPlayer(player.getName()).addCooldown("Immobilize", IMMOBILIZE_COOLDOWN);
} else {
target = GeneralMethods.getTargetedEntity(player, 5);
paralyze(target, duration);
start();
bPlayer.addCooldown(this);
}
}
}
@ -57,7 +60,7 @@ public class ChiCombo {
* @param duration The time in milliseconds the target will be paralyzed
*/
private static void paralyze(Entity target, Long duration) {
paralyzedEntities.put(target, (System.currentTimeMillis() + duration));
PARALYZED_ENTITIES.put(target, (System.currentTimeMillis() + duration));
}
/**
@ -78,34 +81,124 @@ public class ChiCombo {
* @return True if the entity is paralyzed, false otherwise
*/
public static boolean isParalyzed(Entity entity) {
return paralyzedEntities.containsKey(entity);
return PARALYZED_ENTITIES.containsKey(entity);
}
/**
* Checks the status of all paralyzed entities. If their paralysis has expired,
* it removes them from {@link ChiCombo#paralyzedEntities paralyzedEntities} and
* it removes them from {@link ChiCombo#PARALYZED_ENTITIES paralyzedEntities} and
* removes the instance of the combo from {@link ChiCombo#instances instances}.
*/
public static void handleParalysis() {
for (Entity e : paralyzedEntities.keySet()) {
if (paralyzedEntities.get(e) <= System.currentTimeMillis()) {
paralyzedEntities.remove(e);
List<Integer> remove = new ArrayList<Integer>();
for (ChiCombo c : instances) {
if (e == null || c.target == null) {
remove.add(instances.indexOf(c));
continue;
for (Entity entity : PARALYZED_ENTITIES.keySet()) {
if (PARALYZED_ENTITIES.get(entity) <= System.currentTimeMillis()) {
PARALYZED_ENTITIES.remove(entity);
for (ChiCombo combo : getAbilities(ChiCombo.class)) {
if (combo.target.equals(entity)) {
combo.remove();
}
if (c.target.equals(e))
remove.add(instances.indexOf(c));
}
for (int i : remove) {
if (i >= instances.size()) {
continue;
}
instances.remove(i);
}
}
}
}
@Override
public String getName() {
return name != null ? name : "ChiCombo";
}
@Override
public void progress() {
}
@Override
public Location getLocation() {
return target != null ? target.getLocation() : null;
}
@Override
public long getCooldown() {
return cooldown;
}
@Override
public boolean isHiddenAbility() {
return true;
}
@Override
public boolean isSneakAbility() {
return true;
}
@Override
public boolean isHarmlessAbility() {
return false;
}
@Override
public String getInstructions() {
return null;
}
@Override
public Object createNewComboInstance(Player player) {
return null;
}
@Override
public ArrayList<AbilityInformation> getCombination() {
return null;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
public Entity getTarget() {
return target;
}
public void setTarget(Entity target) {
this.target = target;
}
public static ConcurrentHashMap<Entity, Long> getParalyzedEntities() {
return PARALYZED_ENTITIES;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
public void setName(String name) {
this.name = name;
}
public class Immobilize extends ChiCombo {
public Immobilize(Player player, String name) {
super(player, "Immobilize");
}
@Override
public String getName() {
return "Immobilize";
}
}
}

View file

@ -1,56 +0,0 @@
package com.projectkorra.projectkorra.chiblocking;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AbilityModuleManager;
import org.bukkit.ChatColor;
import org.bukkit.configuration.file.FileConfiguration;
public class ChiMethods {
static ProjectKorra plugin;
private static FileConfiguration config = ProjectKorra.plugin.getConfig();
public ChiMethods(ProjectKorra plugin) {
ChiMethods.plugin = plugin;
}
/**
* Gets the ChiColor from the config.
*
* @return Config specified ChatColor
*/
public static ChatColor getChiColor() {
return ChatColor.valueOf(config.getString("Properties.Chat.Colors.Chi"));
}
/**
* Checks whether an ability is a chi ability.
*
* @param ability The ability to check
* @return true If the ability is a chi ability.
*/
public static boolean isChiAbility(String ability) {
return AbilityModuleManager.chiabilities.contains(ability);
}
/**
* Checks whether a player is chiblocked.
*
* @param player The player to check
* @return true If the player is chiblocked.
*/
public static boolean isChiBlocked(String player) {
if (GeneralMethods.getBendingPlayer(player) != null) {
return GeneralMethods.getBendingPlayer(player).isChiBlocked();
}
return false;
}
public static void stopBending() {
RapidPunch.instances.clear();
WarriorStance.instances.clear();
AcrobatStance.instances.clear();
}
}

View file

@ -2,42 +2,43 @@ package com.projectkorra.projectkorra.chiblocking;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.airbending.Suffocate;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
public class ChiPassive {
private static FileConfiguration config = ProjectKorra.plugin.getConfig();
public static double FallReductionFactor = config.getDouble("Abilities.Chi.Passive.FallReductionFactor");
public static int jumpPower = config.getInt("Abilities.Chi.Passive.Jump");
public static int speedPower = config.getInt("Abilities.Chi.Passive.Speed");
public static double chance = config.getDouble("Abilities.Chi.Passive.BlockChi.Chance");
public static int duration = config.getInt("Abilities.Chi.Passive.BlockChi.Duration");
static long ticks = (duration / 1000) * 20;
public static boolean willChiBlock(Player attacker, Player player) {
if (AcrobatStance.isInAcrobatStance(attacker)) {
chance = chance + AcrobatStance.CHI_BLOCK_BOOST;
}
if (GeneralMethods.getBoundAbility(player) == "QuickStrike") {
chance = chance + QuickStrike.blockChance;
}
if (GeneralMethods.getBoundAbility(player) == "SwiftKick") {
chance = chance + SwiftKick.blockChance;
}
if (Math.random() > chance/100) {
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
return false;
}
if (ChiMethods.isChiBlocked(player.getName())) {
ChiAbility stance = bPlayer.getStance();
QuickStrike quickStrike = CoreAbility.getAbility(player, QuickStrike.class);
SwiftKick swiftKick = CoreAbility.getAbility(player, SwiftKick.class);
double newChance = 0;
if (stance != null && stance instanceof AcrobatStance) {
newChance = getChance() + ((AcrobatStance) stance).getChiBlockBoost();
}
if (quickStrike != null) {
newChance = getChance() + quickStrike.getBlockChance();
} else if (swiftKick != null) {
newChance = getChance() + swiftKick.getBlockChance();
}
if (Math.random() > newChance / 100.0) {
return false;
} else if (bPlayer.isChiBlocked()) {
return false;
}
return true;
@ -47,30 +48,64 @@ public class ChiPassive {
if (Suffocate.isChannelingSphere(player)) {
Suffocate.remove(player);
}
final BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName());
if (bPlayer == null)
final BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
return;
}
bPlayer.blockChi();
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(ProjectKorra.plugin, new Runnable() {
@Override
public void run() {
bPlayer.unblockChi();
}
}, ticks);
}, getTicks());
}
public static void handlePassive() {
for (Player player : Bukkit.getOnlinePlayers()) {
if (GeneralMethods.canBendPassive(player.getName(), Element.Chi) && !GeneralMethods.canBendPassive(player.getName(), Element.Air)) { // If they're an airbender and gets the boosts we want to give them that instead of the Chi.
if (player.isSprinting()) {
if (!player.hasPotionEffect(PotionEffectType.JUMP) && !AcrobatStance.isInAcrobatStance(player)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 60, jumpPower - 1));
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
continue;
}
if (bPlayer.canBendPassive(Element.CHI) && !bPlayer.canBendPassive(Element.AIR)) { // If they're an airbender and gets the boosts we want to give them that instead of the Chi.
ChiAbility stance = bPlayer.getStance();
if (player.isSprinting() && !(stance instanceof AcrobatStance)) {
if (!player.hasPotionEffect(PotionEffectType.JUMP)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.JUMP, 60, getJumpPower() - 1));
}
if (!player.hasPotionEffect(PotionEffectType.SPEED) && !AcrobatStance.isInAcrobatStance(player)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 60, speedPower - 1));
if (!player.hasPotionEffect(PotionEffectType.SPEED)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 60, getSpeedPower() - 1));
}
}
}
}
}
public static double getFallReductionFactor() {
return ConfigManager.getConfig().getDouble("Abilities.Chi.Passive.FallReductionFactor");
}
public static int getJumpPower() {
return ConfigManager.getConfig().getInt("Abilities.Chi.Passive.Jump");
}
public static int getSpeedPower() {
return ConfigManager.getConfig().getInt("Abilities.Chi.Passive.Speed");
}
public static double getChance() {
return ConfigManager.getConfig().getDouble("Abilities.Chi.Passive.BlockChi.Chance");
}
public static int getDuration() {
return ConfigManager.getConfig().getInt("Abilities.Chi.Passive.BlockChi.Duration");
}
public static long getTicks() {
return (getDuration() / 1000) * 20;
}
}

View file

@ -6,7 +6,6 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class ChiblockingManager implements Runnable {
public ProjectKorra plugin;
public ChiblockingManager(ProjectKorra plugin) {
@ -16,8 +15,6 @@ public class ChiblockingManager implements Runnable {
@Override
public void run() {
ChiPassive.handlePassive();
WarriorStance.progressAll();
AcrobatStance.progressAll();
for (Player player : Bukkit.getOnlinePlayers()) {
Smokescreen.removeFromHashMap(player);
if (Paralyze.isParalyzed(player)) {

View file

@ -1,45 +1,87 @@
package com.projectkorra.projectkorra.chiblocking;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.waterbending.WaterArmsWhip;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
public class HighJump {
private int jumpheight = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.HighJump.Height");
private long cooldown = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.HighJump.Cooldown");
public HighJump(Player p) {
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(p.getName());
if (bPlayer.isOnCooldown("HighJump"))
return;
if (WaterArmsWhip.grabbedEntities.containsKey(p)) {
WaterArmsWhip waw = WaterArmsWhip.instances.get(WaterArmsWhip.grabbedEntities.get(p));
if (waw != null) {
waw.setGrabbed(false);
}
}
jump(p);
bPlayer.addCooldown("HighJump", cooldown);
public class HighJump extends ChiAbility {
private int height;
private long cooldown;
public HighJump(Player player) {
super(player);
this.height = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.HighJump.Height");
this.cooldown = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.HighJump.Cooldown");
start();
}
private void jump(Player p) {
if (!GeneralMethods.isSolid(p.getLocation().getBlock().getRelative(BlockFace.DOWN)))
if (!GeneralMethods.isSolid(p.getLocation().getBlock().getRelative(BlockFace.DOWN))) {
return;
}
Vector vec = p.getVelocity();
vec.setY(jumpheight);
vec.setY(height);
p.setVelocity(vec);
return;
}
public static String getDescription() {
return "To use this ability, simply click. You will jump quite high. This ability has a short cooldown.";
@Override
public void progress() {
if (bPlayer.isOnCooldown(this)) {
remove();
return;
}
jump(player);
WaterArmsWhip waw = WaterArmsWhip.getGrabbedEntities().get(player);
if (waw != null) {
waw.setGrabbed(false);
}
bPlayer.addCooldown(this);
}
@Override
public String getName() {
return "HighJump";
}
@Override
public Location getLocation() {
return player != null ? player.getLocation() : null;
}
@Override
public long getCooldown() {
return cooldown;
}
@Override
public boolean isSneakAbility() {
return false;
}
@Override
public boolean isHarmlessAbility() {
return true;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
}

View file

@ -1,48 +1,58 @@
package com.projectkorra.projectkorra.chiblocking;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AvatarState;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.airbending.Suffocate;
import com.projectkorra.projectkorra.command.Commands;
import org.bukkit.Location;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.util.concurrent.ConcurrentHashMap;
public class Paralyze {
public class Paralyze extends ChiAbility {
private static ConcurrentHashMap<Entity, Long> entities = new ConcurrentHashMap<Entity, Long>();
private static ConcurrentHashMap<Entity, Long> cooldowns = new ConcurrentHashMap<Entity, Long>();
private static final String DURATION_STRING = "Abilities.Chi.Paralyze.Duration";
private static final ConcurrentHashMap<Entity, Long> ENTITIES = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<Entity, Long> COOLDOWNS = new ConcurrentHashMap<>();
private static final long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Chi.Paralyze.Cooldown");
private static final long duration = ProjectKorra.plugin.getConfig().getLong("Abilities.Chi.Paralyze.Duration");
private long cooldown;
private Entity target;
public Paralyze(Player sourceplayer, Entity targetentity) {
if (GeneralMethods.getBoundAbility(sourceplayer) == null)
return;
if (GeneralMethods.isBender(sourceplayer.getName(), Element.Chi) && GeneralMethods.getBoundAbility(sourceplayer).equalsIgnoreCase("Paralyze") && GeneralMethods.canBend(sourceplayer.getName(), "Paralyze")) {
if (cooldowns.containsKey(targetentity)) {
if (System.currentTimeMillis() < cooldowns.get(targetentity) + cooldown) {
super(sourceplayer);
this.target = targetentity;
this.cooldown = getConfig().getLong("Abilities.Chi.Paralyze.Cooldown");
start();
}
@Override
public void progress() {
if (bPlayer.canBendIgnoreCooldowns(this)) {
if (COOLDOWNS.containsKey(target)) {
if (System.currentTimeMillis() < COOLDOWNS.get(target) + cooldown) {
return;
} else {
cooldowns.remove(targetentity);
COOLDOWNS.remove(target);
}
}
if (targetentity instanceof Player) {
if (Commands.invincible.contains(((Player) targetentity).getName()))
if (target instanceof Player) {
if (Commands.invincible.contains(((Player) target).getName())) {
remove();
return;
}
}
paralyze(targetentity);
cooldowns.put(targetentity, System.currentTimeMillis());
paralyze(target);
COOLDOWNS.put(target, System.currentTimeMillis());
} else {
remove();
}
}
private static void paralyze(Entity entity) {
entities.put(entity, System.currentTimeMillis());
ENTITIES.put(entity, System.currentTimeMillis());
if (entity instanceof Creature) {
((Creature) entity).setTarget(null);
}
@ -54,19 +64,75 @@ public class Paralyze {
}
}
//TODO change paralyze to use Spigot metadata rather than checking this class
public static boolean isParalyzed(Entity entity) {
if (entity instanceof Player) {
if (AvatarState.isAvatarState((Player) entity))
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer((Player) entity);
if (bPlayer != null && bPlayer.isAvatarState()) {
return false;
}
}
if (entities.containsKey(entity)) {
if (System.currentTimeMillis() < entities.get(entity) + duration) {
if (ENTITIES.containsKey(entity)) {
if (System.currentTimeMillis() < ENTITIES.get(entity) + getDuration()) {
return true;
}
entities.remove(entity);
ENTITIES.remove(entity);
}
return false;
}
@Override
public String getName() {
return "Paralyze";
}
@Override
public Location getLocation() {
return target != null ? target.getLocation() : null;
}
@Override
public long getCooldown() {
return cooldown;
}
@Override
public boolean isSneakAbility() {
return false;
}
@Override
public boolean isHarmlessAbility() {
return false;
}
public static long getDuration() {
return getConfig().getLong(DURATION_STRING);
}
public Entity getTarget() {
return target;
}
public void setTarget(Entity target) {
this.target = target;
}
public static String getDurationString() {
return DURATION_STRING;
}
public static ConcurrentHashMap<Entity, Long> getEntities() {
return ENTITIES;
}
public static ConcurrentHashMap<Entity, Long> getCooldowns() {
return COOLDOWNS;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
}

View file

@ -1,46 +1,87 @@
package com.projectkorra.projectkorra.chiblocking;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.ChiAbility;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.util.ArrayList;
public class QuickStrike {
public static int damage = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.QuickStrike.Damage");
public static int blockChance = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.QuickStrike.ChiBlockChance");
public class QuickStrike extends ChiAbility {
private int damage;
private int blockChance;
private Entity target;
public QuickStrike(Player player) {
if (!isEligible(player))
super(player);
this.damage = getConfig().getInt("Abilities.Chi.QuickStrike.Damage");
this.blockChance = getConfig().getInt("Abilities.Chi.QuickStrike.ChiBlockChance");
target = GeneralMethods.getTargetedEntity(player, 2);
start();
}
@Override
public void progress() {
if (target == null) {
return;
Entity e = GeneralMethods.getTargetedEntity(player, 2, new ArrayList<Entity>());
if (e == null)
return;
GeneralMethods.damageEntity(player, e, damage, "QuickStrike");
if (e instanceof Player && ChiPassive.willChiBlock(player, (Player)e)) {
ChiPassive.blockChi((Player) e);
}
GeneralMethods.damageEntity(this, target, damage);
if (target instanceof Player && ChiPassive.willChiBlock(player, (Player) target)) {
ChiPassive.blockChi((Player) target);
}
remove();
}
public boolean isEligible(Player player) {
if (!GeneralMethods.canBend(player.getName(), "QuickStrike"))
return false;
if (GeneralMethods.getBoundAbility(player) == null)
return false;
if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("QuickStrike"))
return false;
if (GeneralMethods.isRegionProtectedFromBuild(player, "QuickStrike", player.getLocation()))
return false;
return true;
@Override
public String getName() {
return "QuickStrike";
}
@Override
public Location getLocation() {
return player != null ? player.getLocation() : null;
}
@Override
public long getCooldown() {
return 0;
}
@Override
public boolean isSneakAbility() {
return false;
}
@Override
public boolean isHarmlessAbility() {
return false;
}
public int getDamage() {
return damage;
}
public void setDamage(int damage) {
this.damage = damage;
}
public int getBlockChance() {
return blockChance;
}
public void setBlockChance(int blockChance) {
this.blockChance = blockChance;
}
public Entity getTarget() {
return target;
}
public void setTarget(Entity target) {
this.target = target;
}
}

View file

@ -1,84 +1,80 @@
package com.projectkorra.projectkorra.chiblocking;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.airbending.Suffocate;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
public class RapidPunch extends ChiAbility {
public class RapidPunch {
public static ConcurrentHashMap<Player, RapidPunch> instances = new ConcurrentHashMap<Player, RapidPunch>();
public static List<Player> punching = new ArrayList<Player>();
private int damage = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.RapidPunch.Damage");
private int punches = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.RapidPunch.Punches");
private int distance = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.RapidPunch.Distance");
private long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Chi.RapidPunch.Cooldown");
private int numpunches;
// private long timers;
private int damage;
private int punches;
private int distance;
private long cooldown;
private int numPunches;
private Entity target;
private Player player;
public RapidPunch(Player p) {
this.player = p;
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(p.getName());
if (instances.containsKey(p))
return;
if (bPlayer.isOnCooldown("RapidPunch"))
return;
Entity t = GeneralMethods.getTargetedEntity(p, distance, new ArrayList<Entity>());
if (t == null)
return;
this.target = t;
this.numpunches = 0;
instances.put(p, this);
public RapidPunch(Player player) {
super(player);
this.damage = getConfig().getInt("Abilities.Chi.RapidPunch.Damage");
this.punches = getConfig().getInt("Abilities.Chi.RapidPunch.Punches");
this.distance = getConfig().getInt("Abilities.Chi.RapidPunch.Distance");
this.cooldown = getConfig().getLong("Abilities.Chi.RapidPunch.Cooldown");
this.target = GeneralMethods.getTargetedEntity(player, distance);
start();
}
public static void startPunchAll() {
for (Player player : instances.keySet()) {
if (player != null)
instances.get(player).startPunch(player);
@Override
public void progress() {
if (numPunches >= punches || target == null || !(target instanceof LivingEntity)) {
remove();
return;
}
}
public void startPunch(Player p) {
if (numpunches >= punches)
instances.remove(p);
if (target instanceof LivingEntity && target != null) {
LivingEntity lt = (LivingEntity) target;
GeneralMethods.damageEntity(p, target, damage, "RapidPunch");
if (target instanceof Player) {
if (ChiPassive.willChiBlock(p, (Player) target)) {
ChiPassive.blockChi((Player) target);
}
if (Suffocate.isChannelingSphere((Player) target)) {
Suffocate.remove((Player) target);
}
LivingEntity lt = (LivingEntity) target;
GeneralMethods.damageEntity(this, target, damage);
if (target instanceof Player) {
if (ChiPassive.willChiBlock(player, (Player) target)) {
ChiPassive.blockChi((Player) target);
}
if (Suffocate.isChannelingSphere((Player) target)) {
Suffocate.remove((Player) target);
}
lt.setNoDamageTicks(0);
}
GeneralMethods.getBendingPlayer(p.getName()).addCooldown("RapidPunch", cooldown);
swing(p);
numpunches++;
lt.setNoDamageTicks(0);
bPlayer.addCooldown(this);
numPunches++;
}
@Override
public String getName() {
return "RapidPunch";
}
private void swing(Player p) {
@Override
public Location getLocation() {
return target != null ? target.getLocation() : null;
}
public static String getDescription() {
return "This ability allows the chiblocker to punch rapidly in a short period. To use, simply punch." + " This has a short cooldown.";
@Override
public long getCooldown() {
return cooldown;
}
@Override
public boolean isSneakAbility() {
return false;
}
@Override
public boolean isHarmlessAbility() {
return false;
}
public int getDamage() {
@ -89,28 +85,6 @@ public class RapidPunch {
this.damage = damage;
}
public int getDistance() {
return distance;
}
public void setDistance(int distance) {
this.distance = distance;
}
public long getCooldown() {
return cooldown;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
if (player != null)
GeneralMethods.getBendingPlayer(player.getName()).addCooldown("RapidPunch", cooldown);
}
public Player getPlayer() {
return player;
}
public int getPunches() {
return punches;
}
@ -119,11 +93,32 @@ public class RapidPunch {
this.punches = punches;
}
public int getNumpunches() {
return numpunches;
public int getDistance() {
return distance;
}
public void setNumpunches(int numpunches) {
this.numpunches = numpunches;
public void setDistance(int distance) {
this.distance = distance;
}
public int getNumPunches() {
return numPunches;
}
public void setNumPunches(int numPunches) {
this.numPunches = numPunches;
}
public Entity getTarget() {
return target;
}
public void setTarget(Entity target) {
this.target = target;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
}

View file

@ -1,8 +1,7 @@
package com.projectkorra.projectkorra.chiblocking;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.command.Commands;
import org.bukkit.Effect;
@ -13,34 +12,38 @@ import org.bukkit.entity.Snowball;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
public class Smokescreen {
public class Smokescreen extends ChiAbility {
public static HashMap<String, Long> cooldowns = new HashMap<String, Long>();
public static List<Integer> snowballs = new ArrayList<Integer>();
public static HashMap<String, Long> blinded = new HashMap<String, Long>();
private long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Chi.Smokescreen.Cooldown");
public static int duration = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.Smokescreen.Duration");
public static double radius = ProjectKorra.plugin.getConfig().getDouble("Abilities.Chi.Smokescreen.Radius");
private static final ConcurrentHashMap<Integer, Smokescreen> SNOWBALLS = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, Long> BLINDED_TIMES = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, Smokescreen> BLINDED_TO_ABILITY = new ConcurrentHashMap<>();
private int duration;
private long cooldown;
private double radius;
public Smokescreen(Player player) {
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName());
if (bPlayer.isOnCooldown("Smokescreen"))
return;
snowballs.add(player.launchProjectile(Snowball.class).getEntityId());
bPlayer.addCooldown("Smokescreen", cooldown);
super(player);
this.cooldown = getConfig().getLong("Abilities.Chi.Smokescreen.Cooldown");
this.duration = getConfig().getInt("Abilities.Chi.Smokescreen.Duration");
this.radius = getConfig().getDouble("Abilities.Chi.Smokescreen.Radius");
start();
}
@Override
public void progress() {
SNOWBALLS.put(player.launchProjectile(Snowball.class).getEntityId(), this);
bPlayer.addCooldown(this);
remove();
}
public static void playEffect(Location loc) {
int z = -2;
int x = -2;
int y = 0;
for (int i = 0; i < 125; i++) {
Location newLoc = new Location(loc.getWorld(), loc.getX() + x, loc.getY() + y, loc.getZ() + z);
for (int direction = 0; direction < 8; direction++) {
@ -48,7 +51,6 @@ public class Smokescreen {
}
if (z == 2) {
z = -2;
// y++;
}
if (x == 2) {
x = -2;
@ -58,24 +60,89 @@ public class Smokescreen {
}
}
public static void applyBlindness(Entity entity) {
public void applyBlindness(Entity entity) {
if (entity instanceof Player) {
if (Commands.invincible.contains(((Player) entity).getName()))
if (Commands.invincible.contains(((Player) entity).getName())) {
return;
} else if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) {
return;
}
Player p = (Player) entity;
p.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, duration * 20, 2));
blinded.put(p.getName(), System.currentTimeMillis());
BLINDED_TIMES.put(p.getName(), System.currentTimeMillis());
BLINDED_TO_ABILITY.put(p.getName(), this);
}
}
public static void removeFromHashMap(Entity entity) {
if (entity instanceof Player) {
Player p = (Player) entity;
if (blinded.containsKey(p.getName())) {
if (blinded.get(p.getName()) + duration >= System.currentTimeMillis()) {
blinded.remove(p.getName());
if (BLINDED_TIMES.containsKey(p.getName())) {
Smokescreen smokescreen = BLINDED_TO_ABILITY.get(p.getName());
if (BLINDED_TIMES.get(p.getName()) + smokescreen.duration >= System.currentTimeMillis()) {
BLINDED_TIMES.remove(p.getName());
BLINDED_TO_ABILITY.remove(p.getName());
}
}
}
}
@Override
public String getName() {
return "Smokescreen";
}
@Override
public Location getLocation() {
return player != null ? player.getLocation() : null;
}
@Override
public long getCooldown() {
return cooldown;
}
@Override
public boolean isSneakAbility() {
return false;
}
@Override
public boolean isHarmlessAbility() {
return false;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public static ConcurrentHashMap<Integer, Smokescreen> getSnowballs() {
return SNOWBALLS;
}
public static ConcurrentHashMap<String, Long> getBlindedTimes() {
return BLINDED_TIMES;
}
public static ConcurrentHashMap<String, Smokescreen> getBlindedToAbility() {
return BLINDED_TO_ABILITY;
}
}

View file

@ -1,55 +1,93 @@
package com.projectkorra.projectkorra.chiblocking;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.ChiAbility;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.util.ArrayList;
public class SwiftKick {
public static int damage = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.SwiftKick.Damage");
public static int blockChance = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.ChiCombo.ChiBlockChance");
public class SwiftKick extends ChiAbility {
private int damage;
private int blockChance;
private long cooldown;
private Entity target;
public SwiftKick(Player player) {
if (!isEligible(player))
return;
Entity e = GeneralMethods.getTargetedEntity(player, 4, new ArrayList<Entity>());
if (e == null)
return;
GeneralMethods.damageEntity(player, e, damage, "SwiftKick");
if (e instanceof Player && ChiPassive.willChiBlock(player, (Player)e)) {
ChiPassive.blockChi((Player) e);
}
GeneralMethods.getBendingPlayer(player.getName()).addCooldown("SwiftKick", 4000);
super(player);
this.damage = getConfig().getInt("Abilities.Chi.SwiftKick.Damage");
this.cooldown = getConfig().getInt("Abilities.Chi.ChiCombo.ChiBlockChance");
this.cooldown = 4000;
this.target = GeneralMethods.getTargetedEntity(player, 4);
start();
}
@SuppressWarnings("deprecation")
public boolean isEligible(Player player) {
if (!GeneralMethods.canBend(player.getName(), "SwiftKick"))
return false;
@Override
public void progress() {
if (target == null) {
remove();
return;
}
GeneralMethods.damageEntity(this, target, damage);
if (target instanceof Player && ChiPassive.willChiBlock(player, (Player) target)) {
ChiPassive.blockChi((Player) target);
}
bPlayer.addCooldown(this);
remove();
}
@Override
public String getName() {
return "SwiftKick";
}
if (GeneralMethods.getBoundAbility(player) == null)
return false;
if (!GeneralMethods.getBoundAbility(player).equalsIgnoreCase("SwiftKick"))
return false;
if (GeneralMethods.isRegionProtectedFromBuild(player, "SwiftKick", player.getLocation()))
return false;
if (GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("SwiftKick"))
return false;
if (player.isOnGround())
return false;
@Override
public Location getLocation() {
return player != null ? player.getLocation() : null;
}
@Override
public long getCooldown() {
return cooldown;
}
@Override
public boolean isSneakAbility() {
return true;
}
@Override
public boolean isHarmlessAbility() {
return false;
}
public int getDamage() {
return damage;
}
public void setDamage(int damage) {
this.damage = damage;
}
public int getBlockChance() {
return blockChance;
}
public void setBlockChance(int blockChance) {
this.blockChance = blockChance;
}
public Entity getTarget() {
return target;
}
public void setTarget(Entity target) {
this.target = target;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
}

View file

@ -1,79 +1,68 @@
package com.projectkorra.projectkorra.chiblocking;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.StockAbility;
import com.projectkorra.projectkorra.waterbending.Bloodbending;
import com.projectkorra.projectkorra.ability.ChiAbility;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.concurrent.ConcurrentHashMap;
public class WarriorStance {
public int strength = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.WarriorStance.Strength") - 1;
public int resistance = ProjectKorra.plugin.getConfig().getInt("Abilities.Chi.WarriorStance.Resistance");
private Player player;
public static ConcurrentHashMap<Player, WarriorStance> instances = new ConcurrentHashMap<Player, WarriorStance>();
public class WarriorStance extends ChiAbility {
private int strength;
private int resistance;
public WarriorStance(Player player) {
this.player = player;
if (instances.containsKey(player)) {
instances.remove(player);
return;
super(player);
this.strength = getConfig().getInt("Abilities.Chi.WarriorStance.Strength") - 1;
this.resistance = getConfig().getInt("Abilities.Chi.WarriorStance.Resistance");
ChiAbility stance = bPlayer.getStance();
if (stance != null && !(stance instanceof WarriorStance)) {
stance.remove();
bPlayer.setStance(this);
}
if (AcrobatStance.isInAcrobatStance(player)) {
AcrobatStance.remove(player);
}
instances.put(player, this);
start();
}
private void progress() {
if (player.isDead() || !player.isOnline()) {
remove();
return;
}
if (!GeneralMethods.canBend(player.getName(), StockAbility.WarriorStance.toString())) {
remove();
return;
}
if (Paralyze.isParalyzed(player) || Bloodbending.isBloodbended(player)) {
@Override
public void progress() {
if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
remove();
return;
}
if (!player.hasPotionEffect(PotionEffectType.DAMAGE_RESISTANCE)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 60, resistance));
}
if (!player.hasPotionEffect(PotionEffectType.INCREASE_DAMAGE)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.INCREASE_DAMAGE, 60, strength));
}
}
public static void progressAll() {
for (Player player : instances.keySet()) {
instances.get(player).progress();
}
@Override
public String getName() {
return "WarriorStance";
}
private void remove() {
instances.remove(player);
@Override
public Location getLocation() {
return player != null ? player.getLocation() : null;
}
public static boolean isInWarriorStance(Player player) {
if (instances.containsKey(player))
return true;
@Override
public long getCooldown() {
return 0;
}
@Override
public boolean isSneakAbility() {
return false;
}
public static void remove(Player player) {
instances.remove(player);
@Override
public boolean isHarmlessAbility() {
return true;
}
public int getStrength() {
@ -91,8 +80,5 @@ public class WarriorStance {
public void setResistance(int resistance) {
this.resistance = resistance;
}
public Player getPlayer() {
return player;
}
}

View file

@ -52,10 +52,10 @@ public class AddCommand extends PKCommand {
* @param element The element to add
*/
private void add(CommandSender sender, Player target, String element) {
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(target.getName());
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(target);
if (bPlayer == null) {
GeneralMethods.createBendingPlayer(target.getUniqueId(), target.getName());
bPlayer = GeneralMethods.getBendingPlayer(target.getName());
bPlayer = BendingPlayer.getBendingPlayer(target);
}
if (bPlayer.isPermaRemoved()) {
sender.sendMessage(ChatColor.RED + "That player's bending was permanently removed.");
@ -63,9 +63,10 @@ public class AddCommand extends PKCommand {
}
if (Arrays.asList(Commands.elementaliases).contains(element.toLowerCase())) {
element = getElement(element.toLowerCase());
Element type = Element.getType(element);
Element type = Element.getElement(element);
bPlayer.addElement(type);
ChatColor color = GeneralMethods.getElementColor(type);
ChatColor color = type.getColor();
if (element.charAt(0) == 'w' || element.charAt(0) == 'f') {
target.sendMessage(color + "You are also a " + Character.toString(element.charAt(0)).toUpperCase() + element.substring(1) + "bender.");
} else if (element.charAt(0) == 'e' || element.charAt(0) == 'a') {

View file

@ -1,9 +1,9 @@
package com.projectkorra.projectkorra.command;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.object.Preset;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
@ -11,14 +11,10 @@ import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AbilityModuleManager;
import com.projectkorra.projectkorra.ability.combo.ComboAbilityModule;
import com.projectkorra.projectkorra.ability.combo.ComboManager;
import com.projectkorra.projectkorra.ability.combo.ComboManager.ComboAbility;
import com.projectkorra.projectkorra.ability.combo.ComboModuleManager;
import com.projectkorra.projectkorra.object.Preset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Completes tabbing for the bending command/subcommands.
@ -30,15 +26,21 @@ public class BendingTabComplete implements TabCompleter {
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
if (args.length == 0 || args[0].equals(""))
return getPossibleCompletionsForGivenArgs(args, getCommandsForUser(sender));
if (args.length >= 2) {
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(sender.getName());
if (args[0].equalsIgnoreCase("bind") || args[0].equalsIgnoreCase("b")) {
if (args.length > 3 || !sender.hasPermission("bending.command.bind") || !(sender instanceof Player))
return new ArrayList<String>();
List<String> abilities = new ArrayList<String>();
if (args.length == 2) {
for (String abil : AbilityModuleManager.abilities) {
if (GeneralMethods.canBind(sender.getName(), abil)) {
abilities.add(abil);
if (bPlayer != null) {
for (CoreAbility coreAbil : CoreAbility.getAbilities()) {
if (!coreAbil.isHiddenAbility() && bPlayer.canBind(coreAbil)) {
abilities.add(coreAbil.getName());
}
}
}
} else {
@ -46,6 +48,7 @@ public class BendingTabComplete implements TabCompleter {
abilities.add("" + i);
}
}
Collections.sort(abilities);
return getPossibleCompletionsForGivenArgs(args, abilities);
} else if (args[0].equalsIgnoreCase("display") || args[0].equalsIgnoreCase("d")) {
@ -79,13 +82,16 @@ public class BendingTabComplete implements TabCompleter {
if (args.length > 3 || !sender.hasPermission("bending.command.add"))
return new ArrayList<String>();
List<String> l = new ArrayList<String>();
if (args.length == 2) {
if (args.length == 2)
{
l.add("Air");
l.add("Earth");
l.add("Fire");
l.add("Water");
l.add("Chi");
} else {
}
else
{
for (Player p : Bukkit.getOnlinePlayers()) {
l.add(p.getName());
}
@ -103,25 +109,16 @@ public class BendingTabComplete implements TabCompleter {
if (args.length > 2 || !sender.hasPermission("bending.command.help"))
return new ArrayList<String>();
List<String> list = new ArrayList<String>();
for (Element e : Element.values()) {
list.add(e.toString());
for (Element e : Element.getElements()) {
list.add(e.getName());
}
List<String> abils = new ArrayList<String>();
for (String abil : AbilityModuleManager.abilities) {
if (GeneralMethods.canBind(sender.getName(), abil)) {
abils.add(abil);
}
}
for (ComboAbility abil : ComboManager.comboAbilityList.values()) {
if (GeneralMethods.canBind(sender.getName(), abil.getName()) && (abil.getName() != "IceBulletRightClick" && abil.getName() != "IceBulletLeftClick")) {
abils.add(abil.getName());
}
}
for (ComboAbilityModule abil : ComboModuleManager.combo) {
if (GeneralMethods.canBind(sender.getName(), abil.getName())) {
abils.add(abil.getName());
for (CoreAbility coreAbil : CoreAbility.getAbilities()) {
if (bPlayer.canBind(coreAbil)) {
abils.add(coreAbil.getName());
}
}
Collections.sort(abils);
list.addAll(abils);
return getPossibleCompletionsForGivenArgs(args, list);
@ -134,7 +131,7 @@ public class BendingTabComplete implements TabCompleter {
}
return getPossibleCompletionsForGivenArgs(args, players);
} else if (args[0].equalsIgnoreCase("preset") || args[0].equalsIgnoreCase("presets") || args[0].equalsIgnoreCase("pre") || args[0].equalsIgnoreCase("set") || args[0].equalsIgnoreCase("p")) {
if (args.length > 4 || !sender.hasPermission("bending.command.preset") || !(sender instanceof Player))
if (args.length > 3 || !sender.hasPermission("bending.command.preset") || !(sender instanceof Player))
return new ArrayList<String>();
List<String> l = new ArrayList<String>();
if (args.length == 2) {
@ -150,28 +147,10 @@ public class BendingTabComplete implements TabCompleter {
for (Preset preset : presets) {
presetNames.add(preset.getName());
}
}
if (sender.hasPermission("bending.command.preset.bind.external")) {
if (Preset.externalPresets.keySet().size() > 0) {
for (String externalPreset : Preset.externalPresets.keySet()) {
presetNames.add(externalPreset);
}
}
}
if (presetNames.size() == 0)
} else
return new ArrayList<String>();
return getPossibleCompletionsForGivenArgs(args, presetNames);
} else if (args.length == 4 && Arrays.asList(new String[] {"bind", "b"}).contains(args[1].toLowerCase())) {
if (!sender.hasPermission("bending.command.preset.bind.assign") || (Preset.externalPresets.keySet().contains(args[2].toLowerCase())) && !sender.hasPermission("bending.command.preset.bind.external.other")) {
return new ArrayList<String>();
}
List<String> players = new ArrayList<String>();
for (Player p : Bukkit.getOnlinePlayers()) {
players.add(p.getName());
}
return getPossibleCompletionsForGivenArgs(args, players);
}
return new ArrayList<String>();
} else if (args[0].equalsIgnoreCase("remove") || args[0].equalsIgnoreCase("rm")) {
if (args.length > 3 || !sender.hasPermission("bending.command.remove"))
return new ArrayList<String>();
@ -196,17 +175,7 @@ public class BendingTabComplete implements TabCompleter {
l.add(p.getName());
}
return getPossibleCompletionsForGivenArgs(args, l);
} else if (args[0].equalsIgnoreCase("copy") || args[0].equalsIgnoreCase("co")) {
//If they can't use the command, have over 3 args (copy <player> <player>), or if have over 2 args and can't assign to other players
if (!sender.hasPermission("bending.command.copy") || args.length > 4 || (args.length > 3 && !sender.hasPermission("bending.command.copy.assign")))
return new ArrayList<String>(); //Return nothing
List<String> l = new ArrayList<String>();
for (Player p : Bukkit.getOnlinePlayers()) {
l.add(p.getName());
}
return getPossibleCompletionsForGivenArgs(args, l);
}
else if (!PKCommand.instances.keySet().contains(args[0].toLowerCase())) {
} else if (!PKCommand.instances.keySet().contains(args[0].toLowerCase())) {
return new ArrayList<String>();
}
} else {

View file

@ -1,6 +1,8 @@
package com.projectkorra.projectkorra.command;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.CoreAbility;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@ -23,36 +25,44 @@ public class BindCommand extends PKCommand {
return;
}
if (!GeneralMethods.abilityExists(args.get(0))) {
CoreAbility coreAbil = CoreAbility.getAbility(args.get(0));
if (coreAbil == null || coreAbil.isHiddenAbility()) {
sender.sendMessage(ChatColor.RED + "That ability doesn't exist.");
return;
}
String ability = GeneralMethods.getAbility(args.get(0));
// bending bind [Ability]
if (args.size() == 1) {
bind(sender, ability, ((Player) sender).getInventory().getHeldItemSlot()+1);
bind(sender, args.get(0), ((Player) sender).getInventory().getHeldItemSlot()+1);
}
// bending bind [ability] [#]
if (args.size() == 2) {
bind(sender, ability, Integer.parseInt(args.get(1)));
bind(sender, args.get(0), Integer.parseInt(args.get(1)));
}
}
private void bind(CommandSender sender, String ability, int slot) {
if (slot < 1 || slot > 9) {
if (!(sender instanceof Player)) {
return;
} else if (slot < 1 || slot > 9) {
sender.sendMessage(ChatColor.RED + "Slot must be an integer between 1 and 9.");
return;
}
if (!GeneralMethods.canBind(((Player) sender).getName(), ability)) {
sender.sendMessage(ChatColor.RED + "You don't have permission to bend this element.");
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer((Player) sender);
CoreAbility coreAbil = CoreAbility.getAbility(ability);
if (bPlayer == null) {
sender.sendMessage(ChatColor.RED + "Please wait one moment while we load your bending information.");
return;
} else if (!GeneralMethods.getBendingPlayer(sender.getName()).isElementToggled(GeneralMethods.getAbilityElement(ability))) {
} else if (coreAbil == null || !bPlayer.canBind(coreAbil)) {
sender.sendMessage(ChatColor.RED + "You don't have permission to bend this ability.");
return;
} else if (!bPlayer.isElementToggled(coreAbil.getElement())) {
sender.sendMessage(ChatColor.RED + "You have that ability's element toggled off currently.");
}
GeneralMethods.bindAbility((Player) sender, GeneralMethods.getAbility(ability), slot);
String name = coreAbil != null ? coreAbil.getName() : null;
GeneralMethods.bindAbility((Player) sender, name, slot);
}
}

View file

@ -33,10 +33,10 @@ public class ChooseCommand extends PKCommand {
return;
}
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(sender.getName());
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(sender.getName());
if (bPlayer == null) {
GeneralMethods.createBendingPlayer(((Player) sender).getUniqueId(), sender.getName());
bPlayer = GeneralMethods.getBendingPlayer(sender.getName());
bPlayer = BendingPlayer.getBendingPlayer(sender.getName());
}
if (bPlayer.isPermaRemoved()) {
sender.sendMessage(ChatColor.RED + "Your bending was permanently removed.");
@ -83,32 +83,38 @@ public class ChooseCommand extends PKCommand {
*
* @param sender The CommandSender who issued the command
* @param target The Player to add the element to
* @param element The element to add to the Player
* @param elementName The element to add to the Player
*/
private void add(CommandSender sender, Player target, String element) {
element = getElement(element);
Element e = Element.getType(element);
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(target.getName());
bPlayer.setElement(e);
ChatColor color = GeneralMethods.getElementColor(e);
if (element.charAt(0) == 'w' || element.charAt(0) == 'f') {
target.sendMessage(color + "You are now a " + Character.toString(element.charAt(0)).toUpperCase() + element.substring(1) + "bender.");
} else if (element.charAt(0) == 'e' || element.charAt(0) == 'a') {
target.sendMessage(color + "You are now an " + Character.toString(element.charAt(0)).toUpperCase() + element.substring(1) + "bender.");
} else if (element.equalsIgnoreCase("chi")) {
private void add(CommandSender sender, Player target, String elementName) {
elementName = getElement(elementName);
Element element = Element.getElement(elementName);
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(target);
if (bPlayer == null) {
return;
}
bPlayer.setElement(element);
ChatColor color = element != null ? element.getColor() : null;
if (elementName.charAt(0) == 'w' || elementName.charAt(0) == 'f') {
target.sendMessage(color + "You are now a " + Character.toString(elementName.charAt(0)).toUpperCase() + elementName.substring(1) + "bender.");
} else if (elementName.charAt(0) == 'e' || elementName.charAt(0) == 'a') {
target.sendMessage(color + "You are now an " + Character.toString(elementName.charAt(0)).toUpperCase() + elementName.substring(1) + "bender.");
} else if (elementName.equalsIgnoreCase("chi")) {
target.sendMessage(color + "You are now a Chiblocker.");
}
if (!(sender instanceof Player) || !((Player) sender).equals(target)) {
if (element.charAt(0) == 'w' || element.charAt(0) == 'f') {
sender.sendMessage(ChatColor.DARK_AQUA + target.getName() + color + " is now a " + Character.toString(element.charAt(0)).toUpperCase() + element.substring(1) + "bender.");
} else if (element.charAt(0) == 'e' || element.charAt(0) == 'a') {
sender.sendMessage(ChatColor.DARK_AQUA + target.getName() + color + " is now an " + Character.toString(element.charAt(0)).toUpperCase() + element.substring(1) + "bender.");
} else if (element.equalsIgnoreCase("chi")) {
if (elementName.charAt(0) == 'w' || elementName.charAt(0) == 'f') {
sender.sendMessage(ChatColor.DARK_AQUA + target.getName() + color + " is now a " + Character.toString(elementName.charAt(0)).toUpperCase() + elementName.substring(1) + "bender.");
} else if (elementName.charAt(0) == 'e' || elementName.charAt(0) == 'a') {
sender.sendMessage(ChatColor.DARK_AQUA + target.getName() + color + " is now an " + Character.toString(elementName.charAt(0)).toUpperCase() + elementName.substring(1) + "bender.");
} else if (elementName.equalsIgnoreCase("chi")) {
target.sendMessage(color + "You are now a Chiblocker.");
}
}
GeneralMethods.removeUnusableAbilities(target.getName());
GeneralMethods.saveElements(bPlayer);
Bukkit.getServer().getPluginManager().callEvent(new PlayerChangeElementEvent(sender, target, e, Result.CHOOSE));
Bukkit.getServer().getPluginManager().callEvent(new PlayerChangeElementEvent(sender, target, element, Result.CHOOSE));
}
}

View file

@ -2,7 +2,7 @@ package com.projectkorra.projectkorra.command;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.multiability.MultiAbilityManager;
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@ -28,10 +28,10 @@ public class ClearCommand extends PKCommand {
return;
}
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(sender.getName());
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(sender.getName());
if (bPlayer == null) {
GeneralMethods.createBendingPlayer(((Player) sender).getUniqueId(), sender.getName());
bPlayer = GeneralMethods.getBendingPlayer(sender.getName());
bPlayer = BendingPlayer.getBendingPlayer(sender.getName());
}
if (args.size() == 0) {
bPlayer.getAbilities().clear();

View file

@ -80,7 +80,6 @@ public class Commands {
PluginCommand projectkorra = plugin.getCommand("projectkorra");
new AddCommand();
new BindCommand();
new CopyCommand();
new CheckCommand();
new ChooseCommand();
new ClearCommand();

View file

@ -1,101 +0,0 @@
package com.projectkorra.projectkorra.command;
import java.util.HashMap;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
public class CopyCommand extends PKCommand {
public CopyCommand() {
super("copy", "/bending copy <Player> [Player]", "This command will allow the user to copy the binds of another player either for himself or assign them to <Player> if specified.", new String[] { "copy", "co" });
}
@Override
public void execute(CommandSender sender, List<String> args) {
if (!correctLength(sender, args.size(), 1, 2)) {
return;
} else if (args.size() == 1) {
if (!hasPermission(sender) || !isPlayer(sender)) {
return;
}
Player orig = Bukkit.getPlayer(args.get(0));
if (orig == null || !orig.isOnline()) {
sender.sendMessage(ChatColor.RED + "Player not found.");
return;
}
boolean boundAll = assignAbilities(sender, orig, (Player) sender, true);
sender.sendMessage(ChatColor.GREEN + "Your bound abilities have been made the same as " + ChatColor.YELLOW + orig.getName());
if (!boundAll) {
sender.sendMessage(ChatColor.RED + "Some abilities were not bound because you cannot bend the required element.");
}
} else if (args.size() == 2) {
if (!hasPermission(sender, "assign")) {
sender.sendMessage(ChatColor.RED + "You don't have permission to do that.");
return;
}
Player orig = ProjectKorra.plugin.getServer().getPlayer(args.get(0));
Player target = ProjectKorra.plugin.getServer().getPlayer(args.get(1));
if ((orig == null || !orig.isOnline()) || (target == null || !target.isOnline())) {
sender.sendMessage(ChatColor.RED + "That player is not online.");
return;
}
boolean boundAll = assignAbilities(sender, orig, target, false);
sender.sendMessage(ChatColor.GREEN + "The bound abilities of " + ChatColor.YELLOW + target.getName() + ChatColor.GREEN + " have been been made the same as " + ChatColor.YELLOW + orig.getName());
target.sendMessage(ChatColor.GREEN + "Your bound abilities have been made the same as " + ChatColor.YELLOW + orig.getName());
if (!boundAll) {
sender.sendMessage(ChatColor.RED + "Some abilities were not bound because you cannot bend the required element.");
}
}
}
@SuppressWarnings("unchecked")
private boolean assignAbilities(CommandSender sender, Player player, Player player2, boolean self) {
BendingPlayer orig = GeneralMethods.getBendingPlayer(player.getName());
BendingPlayer target = GeneralMethods.getBendingPlayer(player2.getName());
if (orig == null) {
GeneralMethods.createBendingPlayer(((Player) player).getUniqueId(), player.getName());
orig = GeneralMethods.getBendingPlayer(player.getName());
}
if (target == null) {
GeneralMethods.createBendingPlayer(((Player) player2).getUniqueId(), player2.getName());
target = GeneralMethods.getBendingPlayer(player2.getName());
}
if (orig.isPermaRemoved()) {
if (self) {
player.sendMessage(ChatColor.RED + "Your bending was permanently removed.");
} else {
sender.sendMessage(ChatColor.RED + "That players bending was permanently removed.");
}
return false;
}
HashMap<Integer, String> abilities = (HashMap<Integer, String>) orig.getAbilities().clone();
boolean boundAll = true;
for (int i = 1; i <= 9; i++) {
if (!GeneralMethods.canBend(player2.getName(), abilities.get(i))) {
abilities.remove(i);
boundAll = false;
}
}
target.setAbilities(abilities);
return boundAll;
}
}

View file

@ -2,16 +2,11 @@ package com.projectkorra.projectkorra.command;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.Element.SubElement;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.SubElement;
import com.projectkorra.projectkorra.ability.AbilityModuleManager;
import com.projectkorra.projectkorra.ability.combo.ComboManager;
import com.projectkorra.projectkorra.airbending.AirMethods;
import com.projectkorra.projectkorra.chiblocking.ChiMethods;
import com.projectkorra.projectkorra.earthbending.EarthMethods;
import com.projectkorra.projectkorra.firebending.FireMethods;
import com.projectkorra.projectkorra.waterbending.WaterMethods;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.SubAbility;
import com.projectkorra.projectkorra.ability.util.ComboManager;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@ -39,55 +34,61 @@ public class DisplayCommand extends PKCommand {
//bending display [Element]
if (args.size() == 1) {
String element = args.get(0).toLowerCase();
String elementName = args.get(0).toLowerCase();
//combos
if (Arrays.asList(Commands.comboaliases).contains(element)) {
element = getElement(element);
Element e = Element.getType(element);
ArrayList<String> combos = ComboManager.getCombosForElement(e);
if (Arrays.asList(Commands.comboaliases).contains(elementName)) {
elementName = this.getElement(elementName);
Element element = Element.getElement(elementName);
ChatColor color = element != null ? element.getColor() : null;
ArrayList<String> combos = ComboManager.getCombosForElement(element);
if (combos.isEmpty()) {
sender.sendMessage(GeneralMethods.getElementColor(e) + "There are no " + element + " combos avaliable.");
sender.sendMessage(color + "There are no " + elementName + " combos avaliable.");
return;
}
for (String combomove : combos) {
if (!sender.hasPermission("bending.ability." + combomove))
continue;
ChatColor color = GeneralMethods.getComboColor(combomove);
sender.sendMessage(color + combomove);
}
return;
}
//normal elements
else if (Arrays.asList(Commands.elementaliases).contains(element)) {
element = getElement(element);
displayElement(sender, element);
else if (Arrays.asList(Commands.elementaliases).contains(elementName)) {
elementName = getElement(elementName);
displayElement(sender, elementName);
}
//subelements
else if (Arrays.asList(Commands.subelementaliases).contains(element)) {
displaySubElement(sender, element);
else if (Arrays.asList(Commands.subelementaliases).contains(elementName)) {
displaySubElement(sender, elementName);
}
//avatar
else if (Arrays.asList(Commands.avataraliases).contains(element)) {
else if (Arrays.asList(Commands.avataraliases).contains(elementName)) {
displayAvatar(sender);
}
else {
ChatColor w = ChatColor.WHITE;
sender.sendMessage(ChatColor.RED + "Not a valid argument." + ChatColor.WHITE + "\nElements: " + AirMethods.getAirColor() + "Air" + ChatColor.WHITE + " | " + WaterMethods.getWaterColor() + "Water" + ChatColor.WHITE + " | " + EarthMethods.getEarthColor() + "Earth" + ChatColor.WHITE + " | " + FireMethods.getFireColor() + "Fire" + ChatColor.WHITE + " | " + ChiMethods.getChiColor() + "Chi");
sender.sendMessage(ChatColor.RED + "Not a valid argument." + ChatColor.WHITE + "\nElements: "
+ Element.AIR.getColor() + "Air" + ChatColor.WHITE + " | "
+ Element.WATER.getColor() + "Water" + ChatColor.WHITE + " | "
+ Element.EARTH.getColor() + "Earth" + ChatColor.WHITE + " | "
+ Element.FIRE.getColor() + "Fire" + ChatColor.WHITE + " | "
+ Element.CHI.getColor() + "Chi");
sender.sendMessage(w + "SubElements: "
+ w + "\n-" + GeneralMethods.getSubBendingColor(Element.Air) + " Flight"
+ w + "\n-" + GeneralMethods.getSubBendingColor(Element.Earth) + " Lavabending"
+ w + "\n-" + GeneralMethods.getSubBendingColor(Element.Earth) + " Metalbending"
+ w + "\n-" + GeneralMethods.getSubBendingColor(Element.Earth) + " Sandbending"
+ w + "\n-" + GeneralMethods.getSubBendingColor(Element.Fire) + " Combustion"
+ w + "\n-" + GeneralMethods.getSubBendingColor(Element.Fire) + " Lightning"
+ w + "\n-" + GeneralMethods.getSubBendingColor(Element.Water) + " Bloodbending"
+ w + "\n-" + GeneralMethods.getSubBendingColor(Element.Water) + " Healing"
+ w + "\n-" + GeneralMethods.getSubBendingColor(Element.Water) + " Icebending"
+ w + "\n-" + GeneralMethods.getSubBendingColor(Element.Water) + " Plantbending");
+ w + "\n-" + Element.AIR.getColor() + " Flight"
+ w + "\n-" + Element.EARTH.getColor() + " Lavabending"
+ w + "\n-" + Element.EARTH.getColor() + " Metalbending"
+ w + "\n-" + Element.EARTH.getColor() + " Sandbending"
+ w + "\n-" + Element.FIRE.getColor() + " Combustion"
+ w + "\n-" + Element.FIRE.getColor() + " Lightning"
+ w + "\n-" + Element.WATER.getColor() + " Bloodbending"
+ w + "\n-" + Element.WATER.getColor() + " Healing"
+ w + "\n-" + Element.WATER.getColor() + " Icebending"
+ w + "\n-" + Element.WATER.getColor() + " Plantbending");
}
}
if (args.size() == 0) {
@ -101,23 +102,18 @@ public class DisplayCommand extends PKCommand {
}
private void displayAvatar(CommandSender sender) {
List<String> abilities = new ArrayList<>();
for (String ability : AbilityModuleManager.abilities) {
if (!AbilityModuleManager.airbendingabilities.contains(ability) && !AbilityModuleManager.earthbendingabilities.contains(ability) && !AbilityModuleManager.firebendingabilities.contains(ability) && !AbilityModuleManager.waterbendingabilities.contains(ability) && !AbilityModuleManager.chiabilities.contains(ability)) {
abilities.add(ability);
}
}
ArrayList<CoreAbility> abilities = CoreAbility.getAbilitiesByElement(Element.AVATAR);
if (abilities.isEmpty()) {
sender.sendMessage(ChatColor.YELLOW + "There are no " + GeneralMethods.getAvatarColor() + "avatar" + ChatColor.YELLOW + " abilities on this server!");
sender.sendMessage(ChatColor.YELLOW + "There are no " + Element.AVATAR.getColor() + "avatar" + ChatColor.YELLOW + " abilities on this server!");
return;
}
for (String ability : abilities) {
for (CoreAbility ability : abilities) {
if (sender instanceof Player) {
if (GeneralMethods.canView((Player) sender, ability)) {
sender.sendMessage(GeneralMethods.getAvatarColor() + ability);
if (GeneralMethods.canView((Player) sender, ability.getName())) {
sender.sendMessage(ability.getElement().getColor() + ability.getName());
}
} else {
sender.sendMessage(GeneralMethods.getAvatarColor() + ability);
sender.sendMessage(ability.getElement().getColor() + ability.getName());
}
}
}
@ -129,22 +125,26 @@ public class DisplayCommand extends PKCommand {
* @param element The element to show the moves for
*/
private void displayElement(CommandSender sender, String element) {
List<String> abilities = ProjectKorra.plugin.abManager.getAbilities(element);
if (abilities == null) {
element = this.getElement(element);
ArrayList<CoreAbility> abilities = CoreAbility.getAbilitiesByElement(Element.getElement(element));
if (abilities.isEmpty()) {
sender.sendMessage(ChatColor.RED + "You must select a valid element.");
return;
} else if (abilities.isEmpty()) {
sender.sendMessage(ChatColor.YELLOW + "There are no " + GeneralMethods.getElementColor(Element.valueOf(element)) + element + ChatColor.YELLOW + " abilities enabled on the server.");
sender.sendMessage(ChatColor.YELLOW + "There are no " + element + " abilities enabled on the server.");
}
for (String ability : abilities) {
if (GeneralMethods.isSubAbility(ability))
for (CoreAbility ability : abilities) {
if (ability instanceof SubAbility || ability.isHiddenAbility()) {
continue;
if (!(sender instanceof Player) || GeneralMethods.canView((Player) sender, ability)) {
sender.sendMessage(GeneralMethods.getElementColor(Element.getType(element)) + ability);
}
if (!(sender instanceof Player) || GeneralMethods.canView((Player) sender, ability.getName())) {
sender.sendMessage(ability.getElement().getColor() + ability.getName());
}
}
if (element.equalsIgnoreCase("earth")) {
//sender.sendMessage(ChatColor.DARK_GREEN + "Combos: " + ChatColor.GREEN + "/bending display EarthCombos");
if (sender.hasPermission("bending.earth.lavabending")) {
sender.sendMessage(ChatColor.DARK_GREEN + "Lavabending abilities: " + ChatColor.GREEN + "/bending display Lavabending");
}
@ -154,17 +154,12 @@ public class DisplayCommand extends PKCommand {
if (sender.hasPermission("bending.earth.sandbending")) {
sender.sendMessage(ChatColor.DARK_GREEN + "Sandbending abilities: " + ChatColor.GREEN + "/bending display Sandbending");
}
}
if (element.equalsIgnoreCase("air")) {
} else if (element.equalsIgnoreCase("air")) {
sender.sendMessage(ChatColor.DARK_GRAY + "Combos: " + ChatColor.GRAY + "/bending display AirCombos");
if (sender.hasPermission("bending.air.flight")) {
sender.sendMessage(ChatColor.DARK_GRAY + "Flight abilities: " + ChatColor.GRAY + "/bending display Flight");
}
//if (sender.hasPermission("bending.air.spiritualprojection")) {
// sender.sendMessage(ChatColor.DARK_GRAY + "SpiritualProjection abilities: " + ChatColor.GRAY + "/bending display spiritualprojection");
//}
}
if (element.equalsIgnoreCase("fire")) {
} else if (element.equalsIgnoreCase("fire")) {
sender.sendMessage(ChatColor.DARK_RED + "Combos: " + ChatColor.RED + "/bending display FireCombos");
if (sender.hasPermission("bending.fire.lightningbending")) {
sender.sendMessage(ChatColor.DARK_RED + "Lightning abilities: " + ChatColor.RED + "/bending display Lightning");
@ -172,8 +167,7 @@ public class DisplayCommand extends PKCommand {
if (sender.hasPermission("bending.fire.combustionbending")) {
sender.sendMessage(ChatColor.DARK_RED + "Combustion abilities: " + ChatColor.RED + "/bending display Combustion");
}
}
if (element.equalsIgnoreCase("water")) {
} else if (element.equalsIgnoreCase("water")) {
sender.sendMessage(ChatColor.DARK_AQUA + "Combos: " + ChatColor.AQUA + "/bending display WaterCombos");
if (sender.hasPermission("bending.water.bloodbending")) {
sender.sendMessage(ChatColor.DARK_AQUA + "Bloodbending abilities: " + ChatColor.AQUA + "/bending display Bloodbending");
@ -187,8 +181,7 @@ public class DisplayCommand extends PKCommand {
if (sender.hasPermission("bending.water.plantbending")) {
sender.sendMessage(ChatColor.DARK_AQUA + "Plantbending abilities: " + ChatColor.AQUA + "/bending display Plantbending");
}
}
if (element.equalsIgnoreCase("chi")) {
} else if (element.equalsIgnoreCase("chi")) {
sender.sendMessage(ChatColor.GOLD + "Combos: " + ChatColor.YELLOW + "/bending display ChiCombos");
}
}
@ -200,16 +193,23 @@ public class DisplayCommand extends PKCommand {
* @param element The subelement to show the moves for
*/
private void displaySubElement(CommandSender sender, String element) {
List<String> abilities = ProjectKorra.plugin.abManager.getAbilities(element);
if (abilities.isEmpty() && element != null) {
Element e = SubElement.getType(element.toLowerCase()).getMainElement();
ChatColor color = GeneralMethods.getSubBendingColor(e);
element = this.getElement(element);
Element mainElement = Element.getElement(element);
List<CoreAbility> abilities = CoreAbility.getAbilitiesByElement(mainElement);
if (mainElement instanceof SubElement) {
mainElement = ((SubElement) mainElement).getParentElement();
}
ChatColor color = mainElement != null ? mainElement.getColor() : null;
if (abilities.isEmpty() && mainElement != null) {
sender.sendMessage(ChatColor.YELLOW + "There are no " + color + element + ChatColor.YELLOW + " abilities installed!");
return;
}
for (String ability : abilities) {
if (!(sender instanceof Player) || GeneralMethods.canView((Player) sender, ability)) {
sender.sendMessage(GeneralMethods.getSubBendingColor(Element.getType(getElement(element))) + ability);
for (CoreAbility ability : abilities) {
if (!(sender instanceof Player) || GeneralMethods.canView((Player) sender, ability.getName())) {
sender.sendMessage(color + ability.getName());
}
}
}
@ -220,10 +220,10 @@ public class DisplayCommand extends PKCommand {
* @param sender The CommandSender to output the bound abilities to
*/
private void displayBinds(CommandSender sender) {
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(sender.getName());
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(sender.getName());
if (bPlayer == null) {
GeneralMethods.createBendingPlayer(((Player) sender).getUniqueId(), sender.getName());
bPlayer = GeneralMethods.getBendingPlayer(sender.getName());
bPlayer = BendingPlayer.getBendingPlayer(sender.getName());
}
HashMap<Integer, String> abilities = bPlayer.getAbilities();
@ -235,8 +235,9 @@ public class DisplayCommand extends PKCommand {
for (int i = 1; i <= 9; i++) {
String ability = abilities.get(i);
if (ability != null && !ability.equalsIgnoreCase("null"))
sender.sendMessage(i + " - " + GeneralMethods.getAbilityColor(ability) + ability);
CoreAbility coreAbil = CoreAbility.getAbility(ability);
if (coreAbil != null && !ability.equalsIgnoreCase("null"))
sender.sendMessage(i + " - " + coreAbil.getElement().getColor() + ability);
}
}
}

View file

@ -1,20 +1,14 @@
package com.projectkorra.projectkorra.command;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AbilityModuleManager;
import com.projectkorra.projectkorra.ability.combo.ComboManager;
import com.projectkorra.projectkorra.airbending.AirMethods;
import com.projectkorra.projectkorra.chiblocking.ChiMethods;
import com.projectkorra.projectkorra.earthbending.EarthMethods;
import com.projectkorra.projectkorra.firebending.FireMethods;
import com.projectkorra.projectkorra.waterbending.WaterMethods;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.ability.ComboAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.util.ComboManager;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
@ -22,7 +16,7 @@ import java.util.List;
*/
public class HelpCommand extends PKCommand {
public HelpCommand() {
super("help", "/bending help [Topic/Page]", "This command provides information on how to use other commands in ProjectKorra.", new String[] { "help", "h" });
super("help", "/bending help", "This command provides information on how to use other commands in ProjectKorra.", new String[] { "help", "h" });
}
@Override
@ -30,75 +24,52 @@ public class HelpCommand extends PKCommand {
if (!hasPermission(sender) || !correctLength(sender, args.size(), 0, 1))
return;
else if (args.size() == 0) {
List<String> strings = new ArrayList<String>();
for (PKCommand command : instances.values()) {
if (!command.getName().equalsIgnoreCase("help") && sender.hasPermission("bending.command." + command.getName())) {
strings.add(command.getProperUse());
}
}
Collections.sort(strings);
Collections.reverse(strings);
strings.add(instances.get("help").getProperUse());
Collections.reverse(strings);
for (String s : getPage(strings, ChatColor.GOLD + "Commands: <required> [optional]", 1, false)) {
sender.sendMessage(ChatColor.YELLOW + s);
sender.sendMessage(ChatColor.YELLOW + command.getProperUse());
}
return;
}
String arg = args.get(0);
if (isNumeric(arg)) {
List<String> strings = new ArrayList<String>();
for (PKCommand command : instances.values()) {
if (!command.getName().equalsIgnoreCase("help") && sender.hasPermission("bending.command." + command.getName())) {
strings.add(command.getProperUse());
}
}
Collections.sort(strings);
Collections.reverse(strings);
strings.add(instances.get("help").getProperUse());
Collections.reverse(strings);
for (String s : getPage(strings, ChatColor.GOLD + "Commands: <required> [optional]", Integer.valueOf(arg), false)) {
sender.sendMessage(ChatColor.YELLOW + s);
}
} else if (instances.keySet().contains(arg.toLowerCase())) {//bending help command
String arg = args.get(0).toLowerCase();
if (instances.keySet().contains(arg.toLowerCase())) { //bending help command
instances.get(arg).help(sender, true);
} else if (Arrays.asList(Commands.comboaliases).contains(arg)) { //bending help elementcombo
sender.sendMessage(ChatColor.GOLD + "Proper Usage: " + ChatColor.RED + "/bending display " + arg + ChatColor.GOLD + " or " + ChatColor.RED + "/bending help <Combo Name>");
} else if (GeneralMethods.abilityExists(arg)) { //bending help ability
String ability = GeneralMethods.getAbility(arg);
ChatColor color = GeneralMethods.getAbilityColor(ability);
sender.sendMessage(color + ability + " - ");
sender.sendMessage(color + AbilityModuleManager.descriptions.get(GeneralMethods.getAbility(ability)));
} else if (CoreAbility.getAbility(arg) != null && !(CoreAbility.getAbility(arg) instanceof ComboAbility)) { //bending help ability
CoreAbility ability = CoreAbility.getAbility(arg);
ChatColor color = ability.getElement().getColor();
sender.sendMessage(color + ability.getName() + " - ");
sender.sendMessage(color + ability.getDescription());
} else if (Arrays.asList(Commands.airaliases).contains(args.get(0))) {
sender.sendMessage(AirMethods.getAirColor() + "Air is the element of freedom. Airbenders are natural pacifists and " + "great explorers. There is nothing stopping them from scaling the tallest of mountains and walls easily. They specialize in redirection, " + "from blasting things away with gusts of winds, to forming a shield around them to prevent damage. Easy to get across flat terrains, " + "such as oceans, there is practically no terrain off limits to Airbenders. They lack much raw damage output, but make up for it with " + "with their ridiculous amounts of utility and speed.");
sender.sendMessage(ChatColor.YELLOW + "Airbenders can chain their abilities into combos, type " + AirMethods.getAirColor() + "/b help AirCombos" + ChatColor.YELLOW + " for more information.");
sender.sendMessage(Element.AIR.getColor() + "Air is the element of freedom. Airbenders are natural pacifists and " + "great explorers. There is nothing stopping them from scaling the tallest of mountains and walls easily. They specialize in redirection, " + "from blasting things away with gusts of winds, to forming a shield around them to prevent damage. Easy to get across flat terrains, " + "such as oceans, there is practically no terrain off limits to Airbenders. They lack much raw damage output, but make up for it with " + "with their ridiculous amounts of utility and speed.");
sender.sendMessage(ChatColor.YELLOW + "Airbenders can chain their abilities into combos, type " + Element.AIR.getColor() + "/b help AirCombos" + ChatColor.YELLOW + " for more information.");
sender.sendMessage(ChatColor.YELLOW + "Learn More: " + ChatColor.DARK_AQUA + "http://tinyurl.com/qffg9m3");
} else if (Arrays.asList(Commands.wateraliases).contains(args.get(0))) {
sender.sendMessage(WaterMethods.getWaterColor() + "Water is the element of change. Waterbending focuses on using your " + "opponents own force against them. Using redirection and various dodging tactics, you can be made " + "practically untouchable by an opponent. Waterbending provides agility, along with strong offensive " + "skills while in or near water.");
sender.sendMessage(ChatColor.YELLOW + "Waterbenders can chain their abilities into combos, type " + WaterMethods.getWaterColor() + "/b help WaterCombos" + ChatColor.YELLOW + " for more information.");
sender.sendMessage(Element.WATER.getColor() + "Water is the element of change. Waterbending focuses on using your " + "opponents own force against them. Using redirection and various dodging tactics, you can be made " + "practically untouchable by an opponent. Waterbending provides agility, along with strong offensive " + "skills while in or near water.");
sender.sendMessage(ChatColor.YELLOW + "Waterbenders can chain their abilities into combos, type " + Element.WATER.getColor() + "/b help WaterCombos" + ChatColor.YELLOW + " for more information.");
sender.sendMessage(ChatColor.YELLOW + "Learn More: " + ChatColor.DARK_AQUA + "http://tinyurl.com/lod3plv");
} else if (Arrays.asList(Commands.earthaliases).contains(args.get(0))) {
sender.sendMessage(EarthMethods.getEarthColor() + "Earth is the element of substance. Earthbenders share many of the " + "same fundamental techniques as Waterbenders, but their domain is quite different and more readily " + "accessible. Earthbenders dominate the ground and subterranean, having abilities to pull columns " + "of rock straight up from the earth or drill their way through the mountain. They can also launch " + "themselves through the air using pillars of rock, and will not hurt themselves assuming they land " + "on something they can bend. The more skilled Earthbenders can even bend metal.");
sender.sendMessage(Element.EARTH.getColor() + "Earth is the element of substance. Earthbenders share many of the " + "same fundamental techniques as Waterbenders, but their domain is quite different and more readily " + "accessible. Earthbenders dominate the ground and subterranean, having abilities to pull columns " + "of rock straight up from the earth or drill their way through the mountain. They can also launch " + "themselves through the air using pillars of rock, and will not hurt themselves assuming they land " + "on something they can bend. The more skilled Earthbenders can even bend metal.");
//sender.sendMessage(ChatColor.YELLOW + "Earthbenders can chain their abilities into combos, type " + EarthMethods.getEarthColor() + "/b help EarthCombos" + ChatColor.YELLOW + " for more information.");
sender.sendMessage(ChatColor.YELLOW + "Learn More: " + ChatColor.DARK_AQUA + "http://tinyurl.com/qaudl42");
} else if (Arrays.asList(Commands.firealiases).contains(args.get(0))) {
sender.sendMessage(FireMethods.getFireColor() + "Fire is the element of power. Firebenders focus on destruction and " + "incineration. Their abilities are pretty straight forward: set things on fire. They do have a bit " + "of utility however, being able to make themselves un-ignitable, extinguish large areas, cook food " + "in their hands, extinguish large areas, small bursts of flight, and then comes the abilities to shoot " + "fire from your hands.");
sender.sendMessage(ChatColor.YELLOW + "Firebenders can chain their abilities into combos, type " + FireMethods.getFireColor() + "/b help FireCombos" + ChatColor.YELLOW + " for more information.");
sender.sendMessage(Element.FIRE.getColor() + "Fire is the element of power. Firebenders focus on destruction and " + "incineration. Their abilities are pretty straight forward: set things on fire. They do have a bit " + "of utility however, being able to make themselves un-ignitable, extinguish large areas, cook food " + "in their hands, extinguish large areas, small bursts of flight, and then comes the abilities to shoot " + "fire from your hands.");
sender.sendMessage(ChatColor.YELLOW + "Firebenders can chain their abilities into combos, type " + Element.FIRE.getColor() + "/b help FireCombos" + ChatColor.YELLOW + " for more information.");
sender.sendMessage(ChatColor.YELLOW + "Learn More: " + ChatColor.DARK_AQUA + "http://tinyurl.com/k4fkjhb");
} else if (Arrays.asList(Commands.chialiases).contains(args.get(0))) {
sender.sendMessage(ChiMethods.getChiColor() + "Chiblockers focus on bare handed combat, utilizing their agility and " + "speed to stop any bender right in their path. Although they lack the ability to bend any of the " + "other elements, they are great in combat, and a serious threat to any bender. Chiblocking was " + "first shown to be used by Ty Lee in Avatar: The Last Airbender, then later by members of the " + "Equalists in The Legend of Korra.");
sender.sendMessage(ChatColor.YELLOW + "Chiblockers can chain their abilities into combos, type " + ChiMethods.getChiColor() + "/b help ChiCombos" + ChatColor.YELLOW + " for more information.");
sender.sendMessage(Element.CHI.getColor() + "Chiblockers focus on bare handed combat, utilizing their agility and " + "speed to stop any bender right in their path. Although they lack the ability to bend any of the " + "other elements, they are great in combat, and a serious threat to any bender. Chiblocking was " + "first shown to be used by Ty Lee in Avatar: The Last Airbender, then later by members of the " + "Equalists in The Legend of Korra.");
sender.sendMessage(ChatColor.YELLOW + "Chiblockers can chain their abilities into combos, type " + Element.CHI.getColor() + "/b help ChiCombos" + ChatColor.YELLOW + " for more information.");
sender.sendMessage(ChatColor.YELLOW + "Learn More: " + ChatColor.DARK_AQUA + "http://tinyurl.com/mkp9n6y");
} else {
//combos - handled differently because they're stored in CamelCase in ComboManager
for (String combo : ComboManager.descriptions.keySet()) {
for (String combo : ComboManager.getDescriptions().keySet()) {
if (combo.equalsIgnoreCase(arg)) {
ChatColor color = GeneralMethods.getComboColor(combo);
CoreAbility coreAbility = CoreAbility.getAbility(combo);
ChatColor color = coreAbility != null ? coreAbility.getElement().getColor() : null;
sender.sendMessage(color + combo + " (Combo) - ");
sender.sendMessage(color + ComboManager.descriptions.get(combo));
sender.sendMessage(ChatColor.GOLD + "Usage: " + ComboManager.instructions.get(combo));
sender.sendMessage(color + ComboManager.getDescriptions().get(combo));
sender.sendMessage(ChatColor.GOLD + "Usage: " + ComboManager.getInstructions().get(combo));
return;
}
}

View file

@ -4,7 +4,6 @@ import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.StockAbility;
import com.projectkorra.projectkorra.storage.DBConnection;
import org.bukkit.Bukkit;
@ -56,30 +55,18 @@ public class ImportCommand extends PKCommand {
String playername = string;
@SuppressWarnings("deprecation")
UUID uuid = ProjectKorra.plugin.getServer().getOfflinePlayer(playername).getUniqueId();
ArrayList<Element> element = new ArrayList<Element>();
List<Integer> oe = bendingPlayers.getIntegerList(string + ".BendingTypes");
HashMap<Integer, String> abilities = new HashMap<Integer, String>();
List<Integer> oa = bendingPlayers.getIntegerList(string + ".SlotAbilities");
ArrayList<Element> elements = new ArrayList<Element>();
List<Integer> bendingTypes = bendingPlayers.getIntegerList(string + ".BendingTypes");
boolean permaremoved = bendingPlayers.getBoolean(string + ".Permaremoved");
int slot = 1;
for (int i : oa) {
if (StockAbility.getAbility(i) != null) {
abilities.put(slot, StockAbility.getAbility(i).toString());
slot++;
} else {
abilities.put(slot, null);
slot++;
Element[] mainElements = Element.getMainElements();
for (int i : bendingTypes) {
if (i < mainElements.length) {
elements.add(mainElements[i]);
}
}
for (int i : oe) {
if (Element.getType(i) != null) {
element.add(Element.getType(i));
}
}
BendingPlayer bPlayer = new BendingPlayer(uuid, playername, element, abilities, permaremoved);
BendingPlayer bPlayer = new BendingPlayer(uuid, playername, elements, new HashMap<Integer, String>(), permaremoved);
bPlayers.add(bPlayer);
}
@ -110,15 +97,15 @@ public class ImportCommand extends PKCommand {
}
StringBuilder elements = new StringBuilder();
BendingPlayer bPlayer = bPlayers.pop();
if (bPlayer.hasElement(Element.Air))
if (bPlayer.hasElement(Element.AIR))
elements.append("a");
if (bPlayer.hasElement(Element.Water))
if (bPlayer.hasElement(Element.WATER))
elements.append("w");
if (bPlayer.hasElement(Element.Earth))
if (bPlayer.hasElement(Element.EARTH))
elements.append("e");
if (bPlayer.hasElement(Element.Fire))
if (bPlayer.hasElement(Element.FIRE))
elements.append("f");
if (bPlayer.hasElement(Element.Chi))
if (bPlayer.hasElement(Element.CHI))
elements.append("c");
HashMap<Integer, String> abilities = bPlayer.getAbilities();

View file

@ -4,13 +4,8 @@ import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@ -154,66 +149,39 @@ public abstract class PKCommand implements SubCommand {
* otherwise
*/
public String getElement(String element) {
if (Arrays.asList(Commands.firealiases).contains(element) || Arrays.asList(Commands.firecomboaliases).contains(element) || Arrays.asList(Commands.combustionaliases).contains(element) || Arrays.asList(Commands.lightningaliases).contains(element))
if (Arrays.asList(Commands.firealiases).contains(element) || Arrays.asList(Commands.firecomboaliases).contains(element))
return "fire";
else if (Arrays.asList(Commands.earthaliases).contains(element) || Arrays.asList(Commands.earthcomboaliases).contains(element) || Arrays.asList(Commands.metalbendingaliases).contains(element) || Arrays.asList(Commands.sandbendingaliases).contains(element) || Arrays.asList(Commands.lavabendingaliases).contains(element))
return "earth";
else if (Arrays.asList(Commands.airaliases).contains(element) || Arrays.asList(Commands.aircomboaliases).contains(element) || Arrays.asList(Commands.spiritualprojectionaliases).contains(element) || Arrays.asList(Commands.flightaliases).contains(element))
return "air";
else if (Arrays.asList(Commands.wateraliases).contains(element) || Arrays.asList(Commands.watercomboaliases).contains(element) || Arrays.asList(Commands.healingaliases).contains(element) || Arrays.asList(Commands.bloodaliases).contains(element) || Arrays.asList(Commands.icealiases).contains(element) || Arrays.asList(Commands.plantaliases).contains(element))
return "water";
else if (Arrays.asList(Commands.combustionaliases).contains(element))
return "combustion";
else if (Arrays.asList(Commands.lightningaliases).contains(element))
return "lightning";
else if (Arrays.asList(Commands.earthaliases).contains(element) || Arrays.asList(Commands.earthcomboaliases).contains(element))
return "earth";
else if (Arrays.asList(Commands.metalbendingaliases).contains(element))
return "metal";
else if (Arrays.asList(Commands.sandbendingaliases).contains(element))
return "sand";
else if (Arrays.asList(Commands.lavabendingaliases).contains(element))
return "lava";
else if (Arrays.asList(Commands.airaliases).contains(element) || Arrays.asList(Commands.aircomboaliases).contains(element))
return "air";
else if (Arrays.asList(Commands.spiritualprojectionaliases).contains(element))
return "spiritual";
else if (Arrays.asList(Commands.flightaliases).contains(element))
return "flight";
else if (Arrays.asList(Commands.wateraliases).contains(element) || Arrays.asList(Commands.watercomboaliases).contains(element))
return "water";
else if (Arrays.asList(Commands.healingaliases).contains(element))
return "healing";
else if (Arrays.asList(Commands.bloodaliases).contains(element))
return "blood";
else if (Arrays.asList(Commands.icealiases).contains(element))
return "ice";
else if (Arrays.asList(Commands.plantaliases).contains(element))
return "plant";
else if (Arrays.asList(Commands.chialiases).contains(element) || Arrays.asList(Commands.chicomboaliases).contains(element))
return "chi";
return null;
}
/**
* Returns a boolean if the string provided is numerical.
* @param id
* @return boolean
*/
protected boolean isNumeric(String id) {
NumberFormat formatter = NumberFormat.getInstance();
ParsePosition pos = new ParsePosition(0);
formatter.parse(id, pos);
return id.length() == pos.getIndex();
}
/**
* Returns a list for of commands for a page.
* @param entries
* @param title
* @param page
* @return
*/
protected List<String> getPage(List<String> entries, String title, int page, boolean alphabetical) {
List<String> strings = new ArrayList<String>();
if (alphabetical) {
Collections.sort(entries);
}
if (page < 1) {
page = 1;
}
if ((page * 8) - 8 >= entries.size()) {
page = Math.round(entries.size() / 8) + 1;
if (page < 1) {
page = 1;
}
}
strings.add(ChatColor.GOLD + "ProjectKorra " + ChatColor.DARK_GRAY + "- [" + ChatColor.GRAY + page + "/" + (int) Math.ceil((entries.size()+.0)/(8+.0)) + ChatColor.DARK_GRAY + "]");
strings.add(title);
if (entries.size() > ((page * 8) - 8)) {
for (int i = ((page * 8) - 8); i < entries.size(); i++) {
if (entries.get(i) != null) {
strings.add(entries.get(i).toString());
}
if (i >= (page * 8)-1) {
break;
}
}
}
return strings;
}
}

View file

@ -46,10 +46,10 @@ public class PermaremoveCommand extends PKCommand {
return;
}
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName());
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
GeneralMethods.createBendingPlayer(player.getUniqueId(), player.getName());
bPlayer = GeneralMethods.getBendingPlayer(player.getName());
bPlayer = BendingPlayer.getBendingPlayer(player.getName());
}
if (bPlayer.isPermaRemoved()) {

View file

@ -2,10 +2,9 @@ package com.projectkorra.projectkorra.command;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.multiability.MultiAbilityManager;
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager;
import com.projectkorra.projectkorra.object.Preset;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -29,10 +28,9 @@ public class PresetCommand extends PKCommand {
super("preset", "/bending preset create|bind|list|delete [name]", "This command manages Presets, which are saved bindings. Use /bending preset list to view your existing presets, use /bending [create|delete] [name] to manage your presets, and use /bending bind [name] to bind an existing preset.", new String[] { "preset", "presets", "pre", "set", "p" });
}
@SuppressWarnings("unchecked")
@Override
public void execute(CommandSender sender, List<String> args) {
if (!isPlayer(sender) || !correctLength(sender, args.size(), 1, 3)) {
if (!isPlayer(sender) || !correctLength(sender, args.size(), 1, 2)) {
return;
} else if (MultiAbilityManager.hasMultiAbilityBound((Player) sender)) {
sender.sendMessage(ChatColor.RED + "You can't edit your binds right now!");
@ -40,12 +38,6 @@ public class PresetCommand extends PKCommand {
}
Player player = (Player) sender;
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName());
if (bPlayer == null) {
GeneralMethods.createBendingPlayer(((Player) player).getUniqueId(), player.getName());
bPlayer = GeneralMethods.getBendingPlayer(player.getName());
}
//bending preset list
if (args.size() == 1) {
@ -82,88 +74,16 @@ public class PresetCommand extends PKCommand {
sender.sendMessage(ChatColor.GREEN + "You have deleted your preset named: " + ChatColor.YELLOW + name);
return;
} else if (Arrays.asList(bindaliases).contains(args.get(0)) && hasPermission(sender, "bind")) { //bending preset bind name
if (args.size() < 3) {
boolean boundAll = false;
if (Preset.presetExists(player, name)) {
Preset preset = Preset.getPreset(player, name);
boundAll = Preset.bindPreset(player, preset);
} else if (Preset.externalPresetExists(name) && hasPermission(sender, "bind.external")) {
boundAll = Preset.bindExternalPreset(player, name);
} else if (!Preset.externalPresetExists(name) && hasPermission(sender, "bind.external")) {
sender.sendMessage(ChatColor.RED + "No external preset with that name exists.");
return;
} else if (bPlayer.isPermaRemoved()) {
player.sendMessage(ChatColor.RED + "Your bending was permanently removed.");
return;
} else {
sender.sendMessage(ChatColor.RED + "You don't have a preset with that name.");
return;
}
sender.sendMessage(ChatColor.GREEN + "Your bound slots have been set to match the " + ChatColor.YELLOW + name + ChatColor.GREEN + " preset.");
if (!boundAll) {
sender.sendMessage(ChatColor.RED + "Some abilities were not bound because you cannot bend the required element.");
}
} else if (hasPermission(sender, "bind.external.assign") && Preset.externalPresetExists(name)) {
if (!Preset.externalPresetExists(name)) {
sender.sendMessage(ChatColor.RED + "No external preset with that name exists.");
return;
}
Player player2 = Bukkit.getPlayer(args.get(2));
if (player2 != null && player2.isOnline()) {
BendingPlayer bPlayer2 = GeneralMethods.getBendingPlayer(player2.getName());
if (bPlayer2 == null) {
GeneralMethods.createBendingPlayer(((Player) player2).getUniqueId(), player2.getName());
bPlayer = GeneralMethods.getBendingPlayer(player2.getName());
}
if (bPlayer2.isPermaRemoved()) {
player.sendMessage(ChatColor.RED + "Your bending was permanently removed.");
return;
}
boolean boundAll = Preset.bindExternalPreset(player2, name);
sender.sendMessage(ChatColor.GREEN + "The bound slots of " + ChatColor.YELLOW + player2.getName() + ChatColor.GREEN + " have been set to match the " + ChatColor.YELLOW + name + ChatColor.GREEN + " preset.");
player2.sendMessage(ChatColor.GREEN + "Your bound slots have been set to match the " + ChatColor.YELLOW + name + ChatColor.GREEN + " preset.");
if (!boundAll) {
player2.sendMessage(ChatColor.RED + "Some abilities were not bound, either the preset contains invalid abilities or you cannot bend the required elements.");
}
return;
} else {
sender.sendMessage(ChatColor.RED + "Player not found.");
}
} else if (hasPermission(sender, "bind.assign") && Preset.presetExists(player, name)) {
if (!Preset.presetExists(player, name)) {
sender.sendMessage(ChatColor.RED + "You don't have a preset with that name.");
return;
}
Player player2 = Bukkit.getPlayer(args.get(2));
if (player2 != null && player2.isOnline()) {
BendingPlayer bPlayer2 = GeneralMethods.getBendingPlayer(player2.getName());
if (bPlayer2 == null) {
GeneralMethods.createBendingPlayer(((Player) player2).getUniqueId(), player2.getName());
bPlayer = GeneralMethods.getBendingPlayer(player2.getName());
}
if (bPlayer2.isPermaRemoved()) {
player.sendMessage(ChatColor.RED + "Your bending was permanently removed.");
return;
}
Preset preset = Preset.getPreset(player, name);
boolean boundAll = Preset.bindPreset(player2, preset);
sender.sendMessage(ChatColor.GREEN + "The bound slots of " + ChatColor.YELLOW + player2.getName() + ChatColor.GREEN + " have been set to match your " + ChatColor.YELLOW + name + ChatColor.GREEN + " preset.");
player2.sendMessage(ChatColor.GREEN + "Your bound slots have been set to match " + ChatColor.YELLOW + player.getName() + "'s " + name + ChatColor.GREEN + " preset.");
if (!boundAll) {
player2.sendMessage(ChatColor.RED + "Some abilities were not bound, either the preset contains invalid abilities or you cannot bend the required elements.");
}
return;
} else {
sender.sendMessage(ChatColor.RED + "Player not found.");
}
if (!Preset.presetExists(player, name)) {
sender.sendMessage(ChatColor.RED + "You don't have a preset with that name.");
return;
}
boolean boundAll = Preset.bindPreset(player, name);
sender.sendMessage(ChatColor.GREEN + "Your bound slots have been set to match the " + ChatColor.YELLOW + name + ChatColor.GREEN + " preset.");
if (!boundAll) {
sender.sendMessage(ChatColor.RED + "Some abilities were not bound because you cannot bend the required element.");
}
return;
} else if (Arrays.asList(createaliases).contains(args.get(0)) && hasPermission(sender, "create")) { //bending preset create name
int limit = GeneralMethods.getMaxPresets(player);
@ -175,16 +95,16 @@ public class PresetCommand extends PKCommand {
return;
}
if (bPlayer == null) {
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null)
return;
}
HashMap<Integer, String> abilities = (HashMap<Integer, String>) bPlayer.getAbilities().clone();
HashMap<Integer, String> abilities = bPlayer.getAbilities();
Preset preset = new Preset(player.getUniqueId(), name, abilities);
preset.save(player);
preset.save();
sender.sendMessage(ChatColor.GREEN + "Created preset with the name: " + ChatColor.YELLOW + name);
} else {
help(sender, false);
}
}
}

View file

@ -3,7 +3,6 @@ package com.projectkorra.projectkorra.command;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.chiblocking.ChiMethods;
import com.projectkorra.projectkorra.event.PlayerChangeElementEvent;
import com.projectkorra.projectkorra.event.PlayerChangeElementEvent.Result;
@ -32,18 +31,20 @@ public class RemoveCommand extends PKCommand {
Player player = Bukkit.getPlayer(args.get(0));
if (player == null) {
Element e = Element.getType(getElement(args.get(0)));
if (e != null && sender instanceof Player) {
if (GeneralMethods.getBendingPlayer(sender.getName()).hasElement(e)) {
GeneralMethods.getBendingPlayer(sender.getName()).getElements().remove(e);
GeneralMethods.saveElements(GeneralMethods.getBendingPlayer(sender.getName()));
Element e = Element.getElement(getElement(args.get(0)));
BendingPlayer senderBPlayer = BendingPlayer.getBendingPlayer(sender.getName());
if (senderBPlayer != null && e != null && sender instanceof Player) {
if (senderBPlayer.hasElement(e)) {
senderBPlayer.getElements().remove(e);
GeneralMethods.saveElements(senderBPlayer);
GeneralMethods.removeUnusableAbilities(sender.getName());
if (e == Element.Chi) {
sender.sendMessage(ChiMethods.getChiColor() + "You have removed your chiblocking.");
if (e == Element.CHI) {
sender.sendMessage(Element.CHI.getColor() + "You have removed your chiblocking.");
return;
}
sender.sendMessage(GeneralMethods.getElementColor(e) + "You have removed your " + e.toString().toLowerCase() + "bending.");
Bukkit.getServer().getPluginManager().callEvent(new PlayerChangeElementEvent(sender, (Player) sender, e, Result.REMOVE));
sender.sendMessage(e.getColor() + "You have removed your " + e.toString().toLowerCase() + "bending.");
return;
} else {
sender.sendMessage(ChatColor.RED + "You do not have that element!");
@ -54,13 +55,13 @@ public class RemoveCommand extends PKCommand {
return;
}
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName());
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
GeneralMethods.createBendingPlayer(player.getUniqueId(), player.getName());
bPlayer = GeneralMethods.getBendingPlayer(player.getName());
bPlayer = BendingPlayer.getBendingPlayer(player);
}
if (args.size() == 2) {
Element e = Element.getType(getElement(args.get(1)));
Element e = Element.getElement(getElement(args.get(1)));
if (e != null) {
if (!bPlayer.hasElement(e)) {
sender.sendMessage(ChatColor.DARK_RED + "Targeted player does not have that element");
@ -69,12 +70,12 @@ public class RemoveCommand extends PKCommand {
bPlayer.getElements().remove(e);
GeneralMethods.saveElements(bPlayer);
GeneralMethods.removeUnusableAbilities(player.getName());
if (e == Element.Chi) {
sender.sendMessage(ChiMethods.getChiColor() + "You have removed the chiblocking of " + ChatColor.DARK_AQUA + player.getName());
player.sendMessage(ChiMethods.getChiColor() + "Your chiblocking has been removed by " + ChatColor.DARK_AQUA + sender.getName());
if (e == Element.CHI) {
sender.sendMessage(Element.CHI.getColor() + "You have removed the chiblocking of " + ChatColor.DARK_AQUA + player.getName());
player.sendMessage(Element.CHI.getColor() + "Your chiblocking has been removed by " + ChatColor.DARK_AQUA + sender.getName());
} else {
sender.sendMessage(GeneralMethods.getElementColor(e) + "You have removed the " + getElement(args.get(1)).toLowerCase() + "bending of " + ChatColor.DARK_AQUA + player.getName());
player.sendMessage(GeneralMethods.getElementColor(e) + "Your " + getElement(args.get(1)).toLowerCase() + "bending has been removed by " + ChatColor.DARK_AQUA + sender.getName());
sender.sendMessage(e.getColor() + "You have removed the " + getElement(args.get(1)).toLowerCase() + "bending of " + ChatColor.DARK_AQUA + player.getName());
player.sendMessage(e.getColor() + "Your " + getElement(args.get(1)).toLowerCase() + "bending has been removed by " + ChatColor.DARK_AQUA + sender.getName());
}
Bukkit.getServer().getPluginManager().callEvent(new PlayerChangeElementEvent(sender, player, e, Result.REMOVE));
return;

View file

@ -3,7 +3,6 @@ package com.projectkorra.projectkorra.command;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.chiblocking.ChiMethods;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@ -34,10 +33,10 @@ public class ToggleCommand extends PKCommand {
sender.sendMessage(ChatColor.RED + "Bending is currently toggled off for all players.");
return;
}
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(sender.getName());
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(sender.getName());
if (bPlayer == null) {
GeneralMethods.createBendingPlayer(((Player) sender).getUniqueId(), sender.getName());
bPlayer = GeneralMethods.getBendingPlayer(sender.getName());
bPlayer = BendingPlayer.getBendingPlayer(sender.getName());
}
if (bPlayer.isToggled()) {
sender.sendMessage(ChatColor.RED + "Your bending has been toggled off. You will not be able to use most abilities until you toggle it back.");
@ -62,46 +61,54 @@ public class ToggleCommand extends PKCommand {
if (!(sender instanceof Player))
sender.sendMessage(ChatColor.RED + "Bending has been toggled off for all players.");
}
} else if (sender instanceof Player && args.size() == 1 && Element.getType(getElement(args.get(0))) != null && GeneralMethods.getBendingPlayer(sender.getName()).hasElement(Element.getType(getElement(args.get(0))))) {
Element e = Element.getType(getElement(args.get(0)));
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(sender.getName());
} else if (sender instanceof Player && args.size() == 1
&& Element.getElement(getElement(args.get(0))) != null
&& BendingPlayer.getBendingPlayer(sender.getName()).hasElement(Element.getElement(getElement(args.get(0))))) {
Element e = Element.getElement(getElement(args.get(0)));
ChatColor color = e != null ? e.getColor() : null;
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(sender.getName());
bPlayer.toggleElement(e);
if (bPlayer.isElementToggled(e) == false) {
if (e == Element.Chi) {
sender.sendMessage(ChiMethods.getChiColor() + "You have toggled off your chiblocking");
if (e == Element.CHI) {
sender.sendMessage(color + "You have toggled off your chiblocking");
} else {
sender.sendMessage(GeneralMethods.getElementColor(e) + "You have toggled off your " + getElement(args.get(0)).toLowerCase() + "bending");
sender.sendMessage(color + "You have toggled off your " + getElement(args.get(0)).toLowerCase() + "bending");
}
} else {
if (e == Element.Chi) {
sender.sendMessage(ChiMethods.getChiColor() + "You have toggled on your chiblocking");
if (e == Element.CHI) {
sender.sendMessage(color + "You have toggled on your chiblocking");
} else {
sender.sendMessage(GeneralMethods.getElementColor(e) + "You have toggled on your " + getElement(args.get(0)).toLowerCase() + "bending");
sender.sendMessage(color + "You have toggled on your " + getElement(args.get(0)).toLowerCase() + "bending");
}
}
} else if (sender instanceof Player && args.size() == 2 && Element.getType(getElement(args.get(0))) != null && GeneralMethods.getBendingPlayer(sender.getName()).hasElement(Element.getType(getElement(args.get(0))))) {
} else if (sender instanceof Player && args.size() == 2
&& Element.getElement(getElement(args.get(0))) != null
&& BendingPlayer.getBendingPlayer(sender.getName()).hasElement(Element.getElement(getElement(args.get(0))))) {
Player target = Bukkit.getPlayer(args.get(1));
if (!hasAdminPermission(sender)) return;
if (target == null) {
sender.sendMessage(ChatColor.RED + "Target is not found.");
}
Element e = Element.getType(getElement(args.get(0)));
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(target.getName());
Element e = Element.getElement(getElement(args.get(0)));
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(target.getName());
ChatColor color = e != null ? e.getColor() : null;
if (bPlayer.isElementToggled(e) == true) {
if (e == Element.Chi) {
sender.sendMessage(ChiMethods.getChiColor() + "You have toggled off " + ChatColor.DARK_AQUA + target.getName() + "'s chiblocking");
target.sendMessage(ChiMethods.getChiColor() + "Your chiblocking has been toggled off by " + ChatColor.DARK_AQUA + sender.getName());
if (e == Element.CHI) {
sender.sendMessage(color + "You have toggled off " + ChatColor.DARK_AQUA + target.getName() + "'s chiblocking");
target.sendMessage(color + "Your chiblocking has been toggled off by " + ChatColor.DARK_AQUA + sender.getName());
} else {
sender.sendMessage(GeneralMethods.getElementColor(e) + "You have toggled off " + ChatColor.DARK_AQUA + target.getName() + "'s " + getElement(args.get(0)).toLowerCase() + "bending");
target.sendMessage(GeneralMethods.getElementColor(e) + "Your " + getElement(args.get(0)).toLowerCase() + "bending has been toggled off by " + ChatColor.DARK_AQUA + sender.getName());
sender.sendMessage(color + "You have toggled off " + ChatColor.DARK_AQUA + target.getName() + "'s " + getElement(args.get(0)).toLowerCase() + "bending");
target.sendMessage(color + "Your " + getElement(args.get(0)).toLowerCase() + "bending has been toggled off by " + ChatColor.DARK_AQUA + sender.getName());
}
} else {
if (e == Element.Chi) {
sender.sendMessage(ChiMethods.getChiColor() + "You have toggled on " + ChatColor.DARK_AQUA + target.getName() + "'s chiblocking");
target.sendMessage(ChiMethods.getChiColor() + "Your chiblocking has been toggled on by " + ChatColor.DARK_AQUA + sender.getName());
if (e == Element.CHI) {
sender.sendMessage(color + "You have toggled on " + ChatColor.DARK_AQUA + target.getName() + "'s chiblocking");
target.sendMessage(color + "Your chiblocking has been toggled on by " + ChatColor.DARK_AQUA + sender.getName());
} else {
sender.sendMessage(GeneralMethods.getElementColor(e) + "You have toggled on " + ChatColor.DARK_AQUA + target.getName() + "'s " + getElement(args.get(0)).toLowerCase() + "bending");
target.sendMessage(GeneralMethods.getElementColor(e) + "Your " + getElement(args.get(0)).toLowerCase() + "bending has been toggled on by " + ChatColor.DARK_AQUA + sender.getName());
sender.sendMessage(color + "You have toggled on " + ChatColor.DARK_AQUA + target.getName() + "'s " + getElement(args.get(0)).toLowerCase() + "bending");
target.sendMessage(color + "Your " + getElement(args.get(0)).toLowerCase() + "bending has been toggled on by " + ChatColor.DARK_AQUA + sender.getName());
}
}
bPlayer.toggleElement(e);

View file

@ -4,11 +4,7 @@ import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.airbending.AirMethods;
import com.projectkorra.projectkorra.chiblocking.ChiMethods;
import com.projectkorra.projectkorra.earthbending.EarthMethods;
import com.projectkorra.projectkorra.firebending.FireMethods;
import com.projectkorra.projectkorra.waterbending.WaterMethods;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.rpg.RPGMethods;
import org.bukkit.Bukkit;
@ -34,7 +30,7 @@ public class WhoCommand extends PKCommand {
Map<String, String> staff = new HashMap<String, String>();
public WhoCommand() {
super("who", "/bending who [Player/Page]", "This command will tell you what element all players that are online are (If you don't specify a player) or give you information about the player that you specify.", new String[] { "who", "w" });
super("who", "/bending who [Player]", "This command will tell you what element all players that are online are (If you don't specify a player) or give you information about the player that you specify.", new String[] { "who", "w" });
staff.put("8621211e-283b-46f5-87bc-95a66d68880e", ChatColor.RED + "ProjectKorra Founder"); // MistPhizzle
@ -70,73 +66,64 @@ public class WhoCommand extends PKCommand {
public void execute(CommandSender sender, List<String> args) {
if (!hasPermission(sender) || !correctLength(sender, args.size(), 0, 1)) {
return;
} else if (args.size() == 1 && args.get(0).length() > 2) {
} else if (args.size() == 1) {
whoPlayer(sender, args.get(0));
} else if (args.size() == 0 || args.size() == 1) {
int page = 1;
if (args.size() == 1 && isNumeric(args.get(0))) {
page = Integer.valueOf(args.get(0));
}
} else if (args.size() == 0) {
List<String> players = new ArrayList<String>();
for (Player player : Bukkit.getOnlinePlayers()) {
String playerName = player.getName();
String result = "";
BendingPlayer bp = GeneralMethods.getBendingPlayer(playerName);
BendingPlayer bp = BendingPlayer.getBendingPlayer(playerName);
if (bp == null) {
GeneralMethods.createBendingPlayer(player.getUniqueId(), player.getName());
bp = GeneralMethods.getBendingPlayer(player.getName());
bp = BendingPlayer.getBendingPlayer(player.getName());
}
if (bp.hasElement(Element.Air)) {
result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.Air) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&7&mA") : AirMethods.getAirColor() + "A");
if (bp.hasElement(Element.AIR)) {
result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.AIR) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&7&mA") : Element.AIR.getColor() + "A");
}
if (bp.hasElement(Element.Earth)) {
if (bp.hasElement(Element.EARTH)) {
if (result == "") {
result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.Earth) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&a&mE") : EarthMethods.getEarthColor() + "E");
result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.EARTH) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&a&mE") : Element.EARTH.getColor() + "E");
} else {
result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.Earth) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&a&mE") : EarthMethods.getEarthColor() + "E");
result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.EARTH) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&a&mE") : Element.EARTH.getColor() + "E");
}
}
if (bp.hasElement(Element.Fire)) {
if (bp.hasElement(Element.FIRE)) {
if (result == "") {
result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.Fire) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&c&mF") : FireMethods.getFireColor() + "F");
result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.FIRE) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&c&mF") : Element.FIRE.getColor() + "F");
} else {
result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.Fire) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&c&mF") : FireMethods.getFireColor() + "F");
result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.FIRE) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&c&mF") : Element.FIRE.getColor() + "F");
}
}
if (bp.hasElement(Element.Water)) {
if (bp.hasElement(Element.WATER)) {
if (result == "") {
result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.Water) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&b&mW") : WaterMethods.getWaterColor() + "W");
result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.WATER) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&b&mW") : Element.WATER.getColor() + "W");
} else {
result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.Water) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&b&mW") : WaterMethods.getWaterColor() + "W");
result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.WATER) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&b&mW") : Element.WATER.getColor() + "W");
}
}
if (bp.hasElement(Element.Chi)) {
if (bp.hasElement(Element.CHI)) {
if (result == "") {
result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.Chi) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&6&mC") : ChiMethods.getChiColor() + "C");
result = ChatColor.WHITE + playerName + " - " + ((!bp.isElementToggled(Element.CHI) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&6&mC") : Element.CHI.getColor() + "C");
} else {
result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.Chi) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&6&mC") : ChiMethods.getChiColor() + "C");
result = result + ChatColor.WHITE + " | " + ((!bp.isElementToggled(Element.CHI) || !bp.isToggled()) ? ChatColor.translateAlternateColorCodes('&', "&6&mC") : Element.CHI.getColor() + "C");
}
}
if (staff.containsKey(player.getUniqueId().toString())) {
if (result == "") {
result = ChatColor.WHITE + playerName + " | " + staff.get(player.getUniqueId().toString());
result = ChatColor.WHITE + playerName + staff.get(player.getUniqueId().toString());
} else {
result = result + ChatColor.WHITE + " | " + staff.get(player.getUniqueId().toString());
}
}
if (result == ""){
result = ChatColor.WHITE + playerName;
}
players.add(result);
}
if (players.isEmpty()) {
sender.sendMessage(ChatColor.RED + "There is no one online.");
} else {
//for (String st : players) {
// sender.sendMessage(st);
//}
for (String s : getPage(players, ChatColor.GOLD + "Players:", page, true)) {
sender.sendMessage(s);
for (String st : players) {
sender.sendMessage(st);
}
}
}
@ -154,7 +141,6 @@ public class WhoCommand extends PKCommand {
//Player player = Bukkit.getPlayer(playerName);
@SuppressWarnings("deprecation")
final OfflinePlayer player = Bukkit.getOfflinePlayer(playerName);
BendingPlayer bplayer = GeneralMethods.getBendingPlayer(player.getName());
if (player == null || !player.hasPlayedBefore()) {
sender.sendMessage(ChatColor.RED + "Player not found!");
return;
@ -164,8 +150,9 @@ public class WhoCommand extends PKCommand {
}
Player player_ = (Player) (player.isOnline() ? player : null);
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (!BendingPlayer.getPlayers().containsKey(player.getUniqueId())) {
if (bPlayer == null) {
GeneralMethods.createBendingPlayer(player.getUniqueId(), playerName);
BukkitRunnable runnable = new BukkitRunnable() {
@Override
@ -193,99 +180,82 @@ public class WhoCommand extends PKCommand {
runnable.runTaskAsynchronously(ProjectKorra.plugin);
return;
}
if (BendingPlayer.getPlayers().containsKey(player.getUniqueId())) {
bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer != null) {
sender.sendMessage(player.getName() + (!player.isOnline() ? ChatColor.RESET + " (Offline)" : "") + " - ");
if (GeneralMethods.isBender(playerName, Element.Air)) {
if(bplayer.isElementToggled(Element.Air)) {
sender.sendMessage(AirMethods.getAirColor() + "- Airbender");
} else {
sender.sendMessage(AirMethods.getAirColor() + "" + ChatColor.STRIKETHROUGH + "- Airbender");
if (bPlayer.hasElement(Element.AIR)) {
sender.sendMessage(Element.AIR + "- Airbender");
if (player_ != null && bPlayer.canUseFlight()) {
sender.sendMessage(Element.FLIGHT.getColor() + " Can Fly");
}
if (player_ != null && AirMethods.canAirFlight((Player) player)) {
sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Air) + " Can Fly");
}
if (player_ != null && AirMethods.canUseSpiritualProjection((Player) player)) {
sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Air) + " Can use Spiritual Projection");
if (player_ != null && bPlayer.canUseSpiritualProjection()) {
sender.sendMessage(Element.SPIRITUAL.getColor() + " Can use Spiritual Projection");
}
}
if (GeneralMethods.isBender(playerName, Element.Water)) {
if(bplayer.isElementToggled(Element.Water)) {
sender.sendMessage(WaterMethods.getWaterColor() + "- Waterbender");
} else {
sender.sendMessage(WaterMethods.getWaterColor() + "" + ChatColor.STRIKETHROUGH + "- Waterbender");
if (bPlayer.hasElement(Element.WATER)) {
sender.sendMessage(Element.WATER.getColor() + "- Waterbender");
if (player_ != null && bPlayer.canPlantbend()) {
sender.sendMessage(Element.PLANT.getColor() + " Can Plantbend");
}
if (player_ != null && WaterMethods.canPlantbend((Player) player)) {
sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Water) + " Can Plantbend");
}
if (player_ != null && WaterMethods.canBloodbend((Player) player)) {
if (WaterMethods.canBloodbendAtAnytime((Player) player)) {
sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Water) + " Can Bloodbend anytime, on any day");
if (player_ != null && bPlayer.canBloodbend()) {
if (bPlayer.canBloodbendAtAnytime()) {
sender.sendMessage(Element.BLOOD.getColor() + " Can Bloodbend anytime, on any day");
} else {
sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Water) + " Can Bloodbend");
sender.sendMessage(Element.BLOOD.getColor() + " Can Bloodbend");
}
}
if (player_ != null && WaterMethods.canIcebend((Player) player)) {
sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Water) + " Can Icebend");
if (player_ != null && bPlayer.canIcebend()) {
sender.sendMessage(Element.ICE.getColor() + " Can Icebend");
}
if (player_ != null && WaterMethods.canWaterHeal((Player) player)) {
sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Water) + " Can Heal");
if (player_ != null && bPlayer.canWaterHeal()) {
sender.sendMessage(Element.HEALING.getColor() + " Can Heal");
}
}
if (GeneralMethods.isBender(playerName, Element.Earth)) {
if(bplayer.isElementToggled(Element.Earth)) {
sender.sendMessage(EarthMethods.getEarthColor() + "- Earthbender");
} else {
sender.sendMessage(EarthMethods.getEarthColor() + "" + ChatColor.STRIKETHROUGH + "- Earthbender");
if (bPlayer.hasElement(Element.EARTH)) {
sender.sendMessage(Element.EARTH.getColor() + "- Earthbender");
if (player_ != null && bPlayer.canMetalbend()) {
sender.sendMessage(Element.METAL.getColor() + " Can Metalbend");
}
if (player_ != null && EarthMethods.canMetalbend((Player) player)) {
sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Earth) + " Can Metalbend");
if (player_ != null && bPlayer.canLavabend()) {
sender.sendMessage(Element.LAVA.getColor() + " Can Lavabend");
}
if (player_ != null && EarthMethods.canLavabend((Player) player)) {
sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Earth) + " Can Lavabend");
}
if (player_ != null && EarthMethods.canSandbend((Player) player)) {
sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Earth) + " Can Sandbend");
if (player_ != null && bPlayer.canSandbend()) {
sender.sendMessage(Element.SAND.getColor() + " Can Sandbend");
}
}
if (GeneralMethods.isBender(playerName, Element.Fire)) {
if(bplayer.isElementToggled(Element.Fire)) {
sender.sendMessage(FireMethods.getFireColor() + "- Firebender");
} else {
sender.sendMessage(FireMethods.getFireColor() + "" + ChatColor.STRIKETHROUGH + "- Firebender");
if (bPlayer.hasElement(Element.FIRE)) {
sender.sendMessage(Element.FIRE.getColor() + "- Firebender");
if (player_ != null && bPlayer.canCombustionbend()) {
sender.sendMessage(Element.COMBUSTION.getColor() + " Can Combustionbend");
}
if (player_ != null && FireMethods.canCombustionbend((Player) player)) {
sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Fire) + " Can Combustionbend");
}
if (player_ != null && FireMethods.canLightningbend((Player) player)) {
sender.sendMessage(GeneralMethods.getSubBendingColor(Element.Fire) + " Can Lightningbend");
if (player_ != null && bPlayer.canLightningbend()) {
sender.sendMessage(Element.LIGHTNING.getColor() + " Can Lightningbend");
}
}
if (GeneralMethods.isBender(playerName, Element.Chi)) {
if(bplayer.isElementToggled(Element.Chi)) {
sender.sendMessage(ChiMethods.getChiColor() + "- Chiblocker");
} else {
sender.sendMessage(ChiMethods.getChiColor() + "" + ChatColor.STRIKETHROUGH + "- Chiblocker");
}
if (bPlayer.hasElement(Element.CHI)) {
sender.sendMessage(Element.CHI.getColor() + "- ChiBlocker");
}
BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(playerName);
UUID uuid = player.getUniqueId();
if (bPlayer != null) {
sender.sendMessage("Abilities: ");
for (int i = 1; i <= 9; i++) {
String ability = bPlayer.getAbilities().get(i);
if (ability == null || ability.equalsIgnoreCase("null")) {
CoreAbility coreAbil = CoreAbility.getAbility(ability);
if (coreAbil == null) {
continue;
} else {
sender.sendMessage(i + " - " + GeneralMethods.getAbilityColor(ability) + ability);
sender.sendMessage(i + " - " + coreAbil.getElement().getColor() + ability);
}
}
}
if (GeneralMethods.hasRPG()) {
if (RPGMethods.isCurrentAvatar(player.getUniqueId())) {
sender.sendMessage(GeneralMethods.getAvatarColor() + "Current Avatar");
sender.sendMessage(Element.AVATAR.getColor() + "Current Avatar");
} else if (RPGMethods.hasBeenAvatar(player.getUniqueId())) {
sender.sendMessage(GeneralMethods.getAvatarColor() + "Former Avatar");
sender.sendMessage(Element.AVATAR.getColor() + "Former Avatar");
}
}

View file

@ -1,18 +0,0 @@
package com.projectkorra.projectkorra.configuration;
/**
* Represents something that loads values from configs.
*
* @author Jacklin213
* @version 1.0.0
*/
public interface ConfigLoadable {
Config config = ConfigManager.defaultConfig;
/**
* Reload/Loads variables from the configuration.
*/
public void reloadVariables();
}

View file

@ -7,41 +7,19 @@ import java.util.ArrayList;
public class ConfigManager {
public static Config presetConfig;
public static Config deathMsgConfig;
public static Config defaultConfig;
public ConfigManager() {
presetConfig = new Config(new File("presets.yml"));
deathMsgConfig = new Config(new File("deathmessages.yml"));
defaultConfig = new Config(new File("config.yml"));
configCheck(ConfigType.DEFAULT);
configCheck(ConfigType.DEATH_MESSAGE);
configCheck(ConfigType.PRESETS);
}
public static void configCheck(ConfigType type) {
FileConfiguration config;
switch (type) {
case PRESETS:
config = presetConfig.get();
ArrayList<String> abilities = new ArrayList<String>();
abilities.add("FireBlast");
abilities.add("AirBlast");
abilities.add("WaterManipulation");
abilities.add("EarthBlast");
abilities.add("FireBurst");
abilities.add("AirBurst");
abilities.add("Torrent");
abilities.add("Shockwave");
abilities.add("AvatarState");
config.addDefault("Example", abilities);
presetConfig.save();
break;
case DEATH_MESSAGE:
config = deathMsgConfig.get();
@ -113,18 +91,15 @@ public class ConfigManager {
earthbendable.add("NETHERRACK");
earthbendable.add("QUARTZ_ORE");
earthbendable.add("REDSTONE_ORE");
earthbendable.add("SAND");
earthbendable.add("SANDSTONE");
earthbendable.add("RED_SANDSTONE");
earthbendable.add("MYCEL");
ArrayList<String> metals = new ArrayList<String>();
metals.add("IRON_BLOCK");
metals.add("GOLD_BLOCK");
metals.add("QUARTZ_BLOCK");
ArrayList<String> sands = new ArrayList<String>();
sands.add("SAND");
sands.add("SANDSTONE");
sands.add("RED_SAND");
sands.add("RED_SANDSTONE");
config.addDefault("Properties.Chat.Enable", true);
config.addDefault("Properties.Chat.Format", "<name>: <message>");
@ -178,13 +153,11 @@ public class ConfigManager {
config.addDefault("Properties.Water.NightFactor", 1.5);
config.addDefault("Properties.Water.FullMoonFactor", 2.0);
config.addDefault("Properties.Water.CanBendPackedIce", true);
config.addDefault("Properties.Water.CanBendFromBentBlocks", false);
config.addDefault("Properties.Water.PlaySound", true);
config.addDefault("Properties.Water.NightMessage", "You feel the strength of the rising moon empowering your waterbending.");
config.addDefault("Properties.Water.DayMessage", "You feel the empowering of your waterbending subside as the moon sets.");
config.addDefault("Properties.Water.LunarEclipseMessage", "A lunar eclipse is out! Waterbendings are temporarily powerless.");
config.addDefault("Properties.Water.FullMoonMessage", "A full moon is rising, empowering your waterbending like never before.");
config.addDefault("Properties.Water.Range", 4);
config.addDefault("Properties.Earth.RevertEarthbending", true);
config.addDefault("Properties.Earth.SafeRevert", true);
@ -192,10 +165,8 @@ public class ConfigManager {
config.addDefault("Properties.Earth.CanBendWithWeapons", true);
config.addDefault("Properties.Earth.EarthbendableBlocks", earthbendable);
config.addDefault("Properties.Earth.MetalBlocks", metals);
config.addDefault("Properties.Earth.SandBlocks", sands);
config.addDefault("Properties.Earth.MetalPowerFactor", 1.5);
config.addDefault("Properties.Earth.PlaySound", true);
config.addDefault("Properties.Earth.Range", 4);
config.addDefault("Properties.Fire.CanBendWithWeapons", true);
config.addDefault("Properties.Fire.DayFactor", 1.25);
@ -248,12 +219,11 @@ public class ConfigManager {
config.addDefault("Abilities.Air.AirBubble.Radius", 7);
config.addDefault("Abilities.Air.AirBurst.Enabled", true);
config.addDefault("Abilities.Air.AirBurst.Description", "AirBurst is one of the most powerful abilities in the airbender's arsenal. " + "To use, press and hold sneak to charge your burst. " + "Once charged, you can either release sneak to release the burst in a sphere around you " + "or click to launch a cone-shaped burst of air in front of you. " + "Additionally, having this ability selected when you land on the ground from a " + "large enough fall will create a burst of air around you.");
config.addDefault("Abilities.Air.AirBurst.Description", "AirBurst is one of the most powerful abilities in the airbender's arsenal. " + "To use, press and hold sneak to charge your burst. " + "Once charged, you can either release sneak to launch a cone-shaped burst " + "of air in front of you, or click to release the burst in a sphere around you. " + "Additionally, having this ability selected when you land on the ground from a " + "large enough fall will create a burst of air around you.");
config.addDefault("Abilities.Air.AirBurst.FallThreshold", 10);
config.addDefault("Abilities.Air.AirBurst.PushFactor", 1.5);
config.addDefault("Abilities.Air.AirBurst.ChargeTime", 1750);
config.addDefault("Abilities.Air.AirBurst.Damage", 0);
config.addDefault("Abilities.Air.AirBurst.Cooldown", 0);
config.addDefault("Abilities.Air.AirScooter.Enabled", true);
config.addDefault("Abilities.Air.AirScooter.Description", "AirScooter is a fast means of transportation. To use, sprint, jump then click with " + "this ability selected. You will hop on a scooter of air and be propelled forward " + "in the direction you're looking (you don't need to press anything). " + "This ability can be used to levitate above liquids, but it cannot go up steep slopes. " + "Any other actions will deactivate this ability.");
@ -293,7 +263,6 @@ public class ConfigManager {
config.addDefault("Abilities.Air.Flight.Enabled", true);
config.addDefault("Abilities.Air.Flight.Description", "Jump in the air, crouch (default: shift) and hold with this ability bound and you will glide around in the direction you look. While flying, click to Hover. Click again to disable Hovering.");
config.addDefault("Abilities.Air.Flight.HoverEnabled", true);
config.addDefault("Abilities.Air.Flight.Cooldown", 0);
config.addDefault("Abilities.Air.Suffocate.Enabled", true);
config.addDefault("Abilities.Air.Suffocate.Description", "This ability is one of the most dangerous abilities an Airbender possesses. To use, simply look at an entity and hold shift. The entity will begin taking damage as you extract the air from their lungs. Any bender caught in this sphere will only be able to use basic moves, such as AirSwipe, WaterManipulation, FireBlast, or EarthBlast. An entity can be knocked out of the sphere by certain bending arts, and your attention will be disrupted if you are hit by bending.");
@ -346,7 +315,7 @@ public class ConfigManager {
config.addDefault("Abilities.Water.Bloodbending.Enabled", true);
config.addDefault("Abilities.Water.Bloodbending.Description", "This ability was made illegal for a reason. With this ability selected, sneak while " + "targetting something and you will bloodbend that target. Bloodbent targets cannot move, " + "bend or attack. You are free to control their actions by looking elsewhere - they will " + "be forced to move in that direction. Additionally, clicking while bloodbending will " + "launch that target off in the direction you're looking. " + "People who are capable of bloodbending are immune to your technique, and you are immune to theirs.");
config.addDefault("Abilities.Water.Bloodbending.CanOnlyBeUsedAtNight", true);
config.addDefault("Abilities.Water.Bloodbending.CanOnlyBeUsedAtNight", false);
config.addDefault("Abilities.Water.Bloodbending.CanBeUsedOnUndeadMobs", true);
config.addDefault("Abilities.Water.Bloodbending.ThrowFactor", 2);
config.addDefault("Abilities.Water.Bloodbending.Range", 10);
@ -357,7 +326,6 @@ public class ConfigManager {
config.addDefault("Abilities.Water.HealingWaters.Enabled", true);
config.addDefault("Abilities.Water.HealingWaters.Description", "To use, the bender must be at least partially submerged in water. " + "If the user is not sneaking, this ability will automatically begin " + "working provided the user has it selected. If the user is sneaking, " + "he/she is channeling the healing to their target in front of them. " + "In order for this channel to be successful, the user and the target must " + "be at least partially submerged in water.");
config.addDefault("Abilities.Water.HealingWaters.ShiftRequired", true);
config.addDefault("Abilities.Water.HealingWaters.Radius", 5);
config.addDefault("Abilities.Water.HealingWaters.Interval", 750);
config.addDefault("Abilities.Water.HealingWaters.Power", 1);
@ -366,10 +334,8 @@ public class ConfigManager {
config.addDefault("Abilities.Water.IceBlast.Damage", 3);
config.addDefault("Abilities.Water.IceBlast.Range", 20);
config.addDefault("Abilities.Water.IceBlast.Cooldown", 1500);
config.addDefault("Abilities.Water.IceBlast.SelectRange", 12);
config.addDefault("Abilities.Water.IceBlast.Description", "This ability offers a powerful ice utility for Waterbenders. It can be used to fire an explosive burst of ice at an opponent, spraying ice and snow around it. To use, simply tap sneak (Default: Shift) while targeting a block of ice to select it as a source. From there, you can just left click to send the blast off at your opponent.");
config.addDefault("Abilities.Water.IceBlast.DynamicSourcing.Enabled", true);
config.addDefault("Abilities.Water.IceSpike.Enabled", true);
config.addDefault("Abilities.Water.IceSpike.Description", "This ability has many functions. Clicking while targetting ice, or an entity over some ice, " + "will raise a spike of ice up, damaging and slowing the target. Tapping sneak (shift) while" + " selecting a water source will select that source that can then be fired with a click. Firing" + " this will launch a spike of ice at your target, dealing a bit of damage and slowing the target. " + "If you sneak (shift) while not selecting a source, many ice spikes will erupt from around you, " + "damaging and slowing those targets.");
config.addDefault("Abilities.Water.IceSpike.Cooldown", 2000);
@ -379,8 +345,6 @@ public class ConfigManager {
config.addDefault("Abilities.Water.IceSpike.Height", 6);
config.addDefault("Abilities.Water.IceSpike.Projectile.Range", 20);
config.addDefault("Abilities.Water.IceSpike.Projectile.Damage", 1);
config.addDefault("Abilities.Water.IceSpike.Projectile.SelectRange", 12);
config.addDefault("Abilities.Water.IceSpike.DynamicSourcing.Enabled", true);
config.addDefault("Abilities.Water.OctopusForm.Enabled", true);
config.addDefault("Abilities.Water.OctopusForm.Description", "This ability allows the waterbender to manipulate a large quantity of water into a form resembling that of an octopus. " + "To use, click to select a water source. Then, hold sneak to channel this ability. " + "While channeling, the water will form itself around you and has a chance to block incoming attacks. " + "Additionally, you can click while channeling to attack things near you, dealing damage and knocking them back. " + "Releasing shift at any time will dissipate the form.");
@ -390,55 +354,36 @@ public class ConfigManager {
config.addDefault("Abilities.Water.OctopusForm.Damage", 4);
config.addDefault("Abilities.Water.OctopusForm.Knockback", 1.75);
config.addDefault("Abilities.Water.OctopusForm.FormDelay", 40);
config.addDefault("Abilities.Water.OctopusForm.SelectRange", 12);
config.addDefault("Abilities.Water.OctopusForm.Cooldown", 0);
config.addDefault("Abilities.Water.OctopusForm.AutoSourcing.Enabled", true);
config.addDefault("Abilities.Water.OctopusForm.AutoSourcing.Cooldown", 1500);
config.addDefault("Abilities.Water.OctopusForm.AutoSourcing.SelectRange", 5);
config.addDefault("Abilities.Water.OctopusForm.DynamicSourcing.Enabled", true);
config.addDefault("Abilities.Water.PhaseChange.Enabled", true);
config.addDefault("Abilities.Water.PhaseChange.Description", "To use, simply left-click. " + "Any water you are looking at within range will instantly freeze over into solid ice. " + "Provided you stay within range of the ice and do not unbind FreezeMelt, " + "that ice will not thaw. If, however, you do either of those the ice will instantly thaw. " + "If you sneak (default: shift), anything around where you are looking at will instantly melt. " + "Since this is a more favorable state for these things, they will never re-freeze unless they " + "would otherwise by nature or some other bending ability. Additionally, if you tap sneak while " + "targetting water with FreezeMelt, it will evaporate water around that block that is above " + "sea level. ");
config.addDefault("Abilities.Water.PhaseChange.Range", 15);
config.addDefault("Abilities.Water.PhaseChange.Radius", 4);
config.addDefault("Abilities.Water.PhaseChange.Cooldown", 0);
config.addDefault("Abilities.Water.PhaseChange.Range", 20);
config.addDefault("Abilities.Water.PhaseChange.Radius", 5);
config.addDefault("Abilities.Water.PlantArmor.Enabled", true);
config.addDefault("Abilities.Water.PlantArmor.Description", "PlantArmor is a defensive ability in the arsenal of the plantbender. Clicking on leaves with this ability will temporarily clad you in strong armor made out of plants! You can use this defensively, but you can also use the armor as a source for other plantbending skills.");
config.addDefault("Abilities.Water.PlantArmor.Duration", 7500);
config.addDefault("Abilities.Water.PlantArmor.Resistance", 1);
config.addDefault("Abilities.Water.PlantArmor.Cooldown", 10000);
config.addDefault("Abilities.Water.PlantArmor.SelectRange", 12);
config.addDefault("Abilities.Water.PlantArmor.AutoSourcing.Enabled", true);
config.addDefault("Abilities.Water.PlantArmor.AutoSourcing.Cooldown", 10000);
config.addDefault("Abilities.Water.PlantArmor.AutoSourcing.SelectRange", 5);
config.addDefault("Abilities.Water.PlantArmor.Range", 10);
config.addDefault("Abilities.Water.Surge.Enabled", true);
config.addDefault("Abilities.Water.Surge.Description", "This ability has two distinct features. If you sneak to select a source block, you can then click in a direction and a large wave will be launched in that direction. If you sneak again while the wave is en route, the wave will freeze the next target it hits. If, instead, you click to select a source block, you can hold sneak to form a wall of water at your cursor location. Click to shift between a water wall and an ice wall. Release sneak to dissipate it.");
config.addDefault("Abilities.Water.Surge.Wave.Radius", 3);
config.addDefault("Abilities.Water.Surge.Wave.Range", 20);
config.addDefault("Abilities.Water.Surge.Wave.SelectRange", 6);
config.addDefault("Abilities.Water.Surge.Wave.HorizontalPush", 1);
config.addDefault("Abilities.Water.Surge.Wave.DynamicSourcing.Enabled", true);
config.addDefault("Abilities.Water.Surge.VerticalPush", 0.2);
config.addDefault("Abilities.Water.Surge.Wall.Range", 5);
config.addDefault("Abilities.Water.Surge.Wall.Radius", 2);
config.addDefault("Abilities.Water.Surge.Wall.SelectRange", 5);
config.addDefault("Abilities.Water.Surge.Wall.DynamicSourcing.Enabled", true);
config.addDefault("Abilities.Water.Torrent.Enabled", true);
config.addDefault("Abilities.Water.Torrent.Description", "Torrent is one of the strongest moves in a waterbender's arsenal. To use, first click a source block to select it; then hold shift to begin streaming the water around you. Water flowing around you this way will damage and knock back nearby enemies and projectiles. If you release shift during this, you will create a large wave that expands outwards from you, launching anything in its path back. Instead, if you click you release the water and channel it to flow towards your cursor. Anything caught in the blast will be tossed about violently and take damage. Finally, if you click again when the water is torrenting, it will freeze the area around it when it is obstructed.");
config.addDefault("Abilities.Water.Torrent.Range", 25);
config.addDefault("Abilities.Water.Torrent.DeflectDamage", 1);
config.addDefault("Abilities.Water.Torrent.Damage", 3);
config.addDefault("Abilities.Water.Torrent.Cooldown", 1500);
config.addDefault("Abilities.Water.Torrent.Wave.Radius", 15);
config.addDefault("Abilities.Water.Torrent.Wave.Knockback", 1.5);
config.addDefault("Abilities.Water.Torrent.Wave.Height", 1);
config.addDefault("Abilities.Water.Torrent.SelectRange", 12);
config.addDefault("Abilities.Water.Torrent.AutoSourcing.Enabled", true);
config.addDefault("Abilities.Water.Torrent.AutoSourcing.Cooldown", 1500);
config.addDefault("Abilities.Water.Torrent.AutoSourcing.SelectRange", 5);
config.addDefault("Abilities.Water.Torrent.DynamicSourcing.Enabled", true);
config.addDefault("Abilities.Water.Plantbending.RegrowTime", 180000);
@ -505,13 +450,7 @@ public class ConfigManager {
config.addDefault("Abilities.Water.WaterManipulation.Range", 30);
config.addDefault("Abilities.Water.WaterManipulation.Speed", 35);
config.addDefault("Abilities.Water.WaterManipulation.Push", 0.3);
config.addDefault("Abilities.Water.WaterManipulation.SelectRange", 12);
config.addDefault("Abilities.Water.WaterManipulation.AutoSourcing.Enabled", true);
config.addDefault("Abilities.Water.WaterManipulation.AutoSourcing.Cooldown", 1500);
config.addDefault("Abilities.Water.WaterManipulation.AutoSourcing.SelectRange", 5);
config.addDefault("Abilities.Water.WaterManipulation.DynamicSourcing.Enabled", true);
config.addDefault("Abilities.Water.WaterManipulation.Cooldown", 1500);
config.addDefault("Abilities.Water.WaterManipulation.Cooldown", 1000);
config.addDefault("Abilities.Water.WaterSpout.Enabled", true);
config.addDefault("Abilities.Water.WaterSpout.Description", "This ability provides a Waterbender with a means of transportation. To use, simply left click while in or over water to spout water up beneath you, experiencing controlled levitation. Left clicking again while the spout is active will cause it to disappear. Alternatively, tapping a Waterbendable block while not in Water will select a water block as a source, from there, you can tap sneak (Default:Shift) to channel the Water around you. Releasing the sneak will create a wave allowing you a quick burst of controlled transportation. While riding the wave you may press sneak to cause the wave to disappear.");
@ -520,10 +459,11 @@ public class ConfigManager {
config.addDefault("Abilities.Water.WaterSpout.Particles", false);
config.addDefault("Abilities.Water.WaterSpout.Wave.Particles", false);
config.addDefault("Abilities.Water.WaterSpout.Wave.Enabled", true);
config.addDefault("Abilities.Water.WaterSpout.Wave.Range", 6);
config.addDefault("Abilities.Water.WaterSpout.Wave.ChargeTime", 500);
config.addDefault("Abilities.Water.WaterSpout.Wave.FlightTime", 2500);
config.addDefault("Abilities.Water.WaterSpout.Wave.Speed", 1.3);
config.addDefault("Abilities.Water.WaterSpout.Wave.SelectRange", 12);
config.addDefault("Abilities.Water.WaterSpout.Wave.Cooldown", 4500);
config.addDefault("Abilities.Water.WaterCombo.Enabled", true);
config.addDefault("Abilities.Water.WaterCombo.IceWave.Damage", 4);
@ -544,46 +484,32 @@ public class ConfigManager {
config.addDefault("Abilities.Earth.Catapult.Length", 6);
config.addDefault("Abilities.Earth.Catapult.Speed", 10);
config.addDefault("Abilities.Earth.Catapult.Push", 4);
config.addDefault("Abilities.Earth.Catapult.ShiftModifier", 2);
config.addDefault("Abilities.Earth.Catapult.Cooldown", 0);
config.addDefault("Abilities.Earth.Collapse.Enabled", true);
config.addDefault("Abilities.Earth.Collapse.Description", " To use, simply left-click on an earthbendable block. " + "That block and the earthbendable blocks above it will be shoved " + "back into the earth below them, if they can. " + "This ability does have the capacity to trap something inside of it, " + "although it is incredibly difficult to do so. " + "Additionally, press sneak with this ability to affect an area around your targetted location - " + "all earth that can be moved downwards will be moved downwards. " + "This ability is especially risky or deadly in caves, depending on the " + "earthbender's goal and technique.");
config.addDefault("Abilities.Earth.Collapse.SelectRange", 20);
config.addDefault("Abilities.Earth.Collapse.Range", 20);
config.addDefault("Abilities.Earth.Collapse.Radius", 7);
config.addDefault("Abilities.Earth.Collapse.Speed", 8);
config.addDefault("Abilities.Earth.Collapse.Cooldown", 0);
config.addDefault("Abilities.Earth.Collapse.DynamicSourcing.Enabled", true);
config.addDefault("Abilities.Earth.EarthArmor.Enabled", true);
config.addDefault("Abilities.Earth.EarthArmor.Description", "This ability encases the earthbender in temporary armor. To use, click on a block that is earthbendable. If there is another block under it that is earthbendable, the block will fly to you and grant you temporary armor and damage reduction. This ability has a long cooldown.");
config.addDefault("Abilities.Earth.EarthArmor.Duration", 10000);
config.addDefault("Abilities.Earth.EarthArmor.Strength", 2);
config.addDefault("Abilities.Earth.EarthArmor.SelectRange", 20);
config.addDefault("Abilities.Earth.EarthArmor.Cooldown", 17500);
config.addDefault("Abilities.Earth.EarthArmor.AutoSourcing.Enabled", true);
config.addDefault("Abilities.Earth.EarthArmor.AutoSourcing.SelectRange", 5);
config.addDefault("Abilities.Earth.EarthArmor.AutoSourcing.Cooldown", 17500);
config.addDefault("Abilities.Earth.EarthBlast.Enabled", true);
config.addDefault("Abilities.Earth.EarthBlast.Description", "To use, place your cursor over an earthbendable object (dirt, rock, ores, etc) " + "and tap sneak (default: shift). The object will temporarily turn to stone, " + "indicating that you have it focused as the source for your ability. " + "After you have selected an origin (you no longer need to be sneaking), " + "simply left-click in any direction and you will see your object launch " + "off in that direction, smashing into any creature in its path. If you look " + "towards a creature when you use this ability, it will target that creature. " + "A collision from Earth Blast both knocks the target back and deals some damage. " + "You cannot have multiple of these abilities flying at the same time.");
config.addDefault("Abilities.Earth.EarthBlast.CanHitSelf", false);
config.addDefault("Abilities.Earth.EarthBlast.Radius", 30);
config.addDefault("Abilities.Earth.EarthBlast.PrepareRange", 10);
config.addDefault("Abilities.Earth.EarthBlast.Range", 30);
config.addDefault("Abilities.Earth.EarthBlast.Speed", 35);
config.addDefault("Abilities.Earth.EarthBlast.SelectRange", 20);
config.addDefault("Abilities.Earth.EarthBlast.Revert", true);
config.addDefault("Abilities.Earth.EarthBlast.Damage", 3);
config.addDefault("Abilities.Earth.EarthBlast.Push", 0.3);
config.addDefault("Abilities.Earth.EarthBlast.Cooldown", 1500);
config.addDefault("Abilities.Earth.EarthBlast.AutoSourcing.Enabled", true);
config.addDefault("Abilities.Earth.EarthBlast.AutoSourcing.Cooldown", 1500);
config.addDefault("Abilities.Earth.EarthBlast.AutoSourcing.SelectRange", 5);
config.addDefault("Abilities.Earth.EarthBlast.DynamicSourcing.Enabled", true);
config.addDefault("Abilities.Earth.EarthGrab.Enabled", true);
config.addDefault("Abilities.Earth.EarthGrab.Description", "To use, simply left-click while targeting a creature within range. " + "This ability will erect a circle of earth to trap the creature in.");
config.addDefault("Abilities.Earth.EarthGrab.Range", 8);
config.addDefault("Abilities.Earth.EarthGrab.Cooldown", 0);
config.addDefault("Abilities.Earth.EarthTunnel.Enabled", true);
config.addDefault("Abilities.Earth.EarthTunnel.Description", "Earth Tunnel is a completely utility ability for earthbenders. To use, simply sneak (default: shift) in the direction you want to tunnel. You will slowly begin tunneling in the direction you're facing for as long as you sneak or if the tunnel has been dug long enough. This ability will be interrupted if it hits a block that cannot be earthbent.");
@ -607,7 +533,7 @@ public class ConfigManager {
config.addDefault("Abilities.Earth.LavaFlow.ShiftCleanupDelay", 10000);
config.addDefault("Abilities.Earth.LavaFlow.ClickLavaCleanupDelay", 7000);
config.addDefault("Abilities.Earth.LavaFlow.ClickLandCleanupDelay", 20000);
config.addDefault("Abilities.Earth.LavaFlow.ClickRange", 10);
config.addDefault("Abilities.Earth.LavaFlow.ClickRange", 10.0);
config.addDefault("Abilities.Earth.LavaFlow.ShiftRadius", 7.0);
config.addDefault("Abilities.Earth.LavaFlow.ShiftPlatformRadius", 1.5);
config.addDefault("Abilities.Earth.LavaFlow.ClickRadius", 5.0);
@ -621,15 +547,13 @@ public class ConfigManager {
config.addDefault("Abilities.Earth.LavaFlow.DownwardFlow", 4);
config.addDefault("Abilities.Earth.LavaFlow.AllowNaturalFlow", false);
config.addDefault("Abilities.Earth.LavaFlow.ParticleDensity", 0.11);
config.addDefault("Abilities.Earth.LavaFlow.DynamicSourcing.Enabled", true);
config.addDefault("Abilities.Earth.EarthSmash.Enabled", true);
config.addDefault("Abilities.Earth.EarthSmash.Description", "To raise an EarthSmash hold sneak (default: shift) for approximately 1.5 seconds, " + "then release while aiming at dirt. To grab the EarthSmash aim at the center and hold sneak, " + "the EarthSmash will follow your mouse. You can shoot the EarthSmash by grabbing onto it and left clicking. " + "To ride the EarthSmash simply hop ontop of it and hold sneak while aiming in the direction that you wish to go. " + "Another way to ride an EarthSmash is to grab it with sneak and then right click it. " + "Use EarthSmash as a defensive shield, a powerful attack, or an advanced means of transportation.");
config.addDefault("Abilities.Earth.EarthSmash.AllowGrab", true);
config.addDefault("Abilities.Earth.EarthSmash.AllowShooting", true);
config.addDefault("Abilities.Earth.EarthSmash.AllowFlight", true);
config.addDefault("Abilities.Earth.EarthSmash.SelectRange", 10);
config.addDefault("Abilities.Earth.EarthSmash.GrabRange", 3.0);
config.addDefault("Abilities.Earth.EarthSmash.GrabRange", 10);
config.addDefault("Abilities.Earth.EarthSmash.ChargeTime", 1500);
config.addDefault("Abilities.Earth.EarthSmash.Cooldown", 2500);
config.addDefault("Abilities.Earth.EarthSmash.ShotRange", 30);
@ -640,6 +564,16 @@ public class ConfigManager {
config.addDefault("Abilities.Earth.EarthSmash.FlightTimer", 3000);
config.addDefault("Abilities.Earth.EarthSmash.RemoveTimer", 30000);
// config.addDefault("Abilities.Earth.LavaSurge.Enabled", true);
// config.addDefault("Abilities.Earth.LavaSurge.Description", "LavaSurge is a fundamental move for any Lavabender out there. To use, simply sneak (Default: Shift) while looking at a source of Earth or Lava, then click in a direction. A surge of lava will swiftly travel towards the target you were pointing at, dealing moderate damage, a large knockback, and setting them on fire.");
// config.addDefault("Abilities.Earth.LavaSurge.Damage", 4);
// config.addDefault("Abilities.Earth.LavaSurge.Cooldown", 1000);
// config.addDefault("Abilities.Earth.LavaSurge.FractureRadius", 1);
// config.addDefault("Abilities.Earth.LavaSurge.PrepareRange", 7);
// config.addDefault("Abilities.Earth.LavaSurge.TravelRange", 15);
// config.addDefault("Abilities.Earth.LavaSurge.MaxLavaWaves", 10);
// config.addDefault("Abilities.Earth.LavaSurge.SourceCanBeEarth", true);
config.addDefault("Abilities.Earth.MetalClips.Enabled", true);
config.addDefault("Abilities.Earth.MetalClips.Description", "MetalClips has the potential to be both an offensive and a utility ability. To start, you must carry smelted Iron Ingots in your inventory. To apply the clips onto an entity, simply click at them. If the entity is a Zombie, a Skeleton, or a Player, the clips will form armor around the entity, giving you some control over them. Each additional clip will give you more control. If you have permission to do so, you may crush the entity against a wall with a 4th clip, hurting them. Without explicit permissions, you will only be able to strap three clips on your target. If the entity is not one of the above, the clip will simply do damage and fall to the ground, to be collected. Another permission requiring action is throwing entities. To do so, click while controlling a metalclipped entity");
config.addDefault("Abilities.Earth.MetalClips.Damage", 2);
@ -653,11 +587,9 @@ public class ConfigManager {
config.addDefault("Abilities.Earth.RaiseEarth.Enabled", true);
config.addDefault("Abilities.Earth.RaiseEarth.Description", "To use, simply left-click on an earthbendable block. " + "A column of earth will shoot upwards from that location. " + "Anything in the way of the column will be brought up with it, " + "leaving talented benders the ability to trap brainless entities up there. " + "Additionally, simply sneak (default shift) looking at an earthbendable block. " + "A wall of earth will shoot upwards from that location. " + "Anything in the way of the wall will be brought up with it. ");
config.addDefault("Abilities.Earth.RaiseEarth.Column.Height", 6);
config.addDefault("Abilities.Earth.RaiseEarth.SelectRange", 15);
config.addDefault("Abilities.Earth.RaiseEarth.Wall.Range", 15);
config.addDefault("Abilities.Earth.RaiseEarth.Wall.Height", 6);
config.addDefault("Abilities.Earth.RaiseEarth.Wall.Width", 6);
config.addDefault("Abilities.Earth.RaiseEarth.Cooldown", 0);
config.addDefault("Abilities.Earth.RaiseEarth.DynamicSourcing.Enabled", true);
config.addDefault("Abilities.Earth.Shockwave.Enabled", true);
config.addDefault("Abilities.Earth.Shockwave.Description", "This is one of the most powerful moves in the earthbender's arsenal. " + "To use, you must first charge it by holding sneak (default: shift). " + "Once charged, you can release sneak to create an enormous shockwave of earth, " + "disturbing all earth around you and expanding radially outwards. " + "Anything caught in the shockwave will be blasted back and dealt damage. " + "If you instead click while charged, the disruption is focused in a cone in front of you. " + "Lastly, if you fall from a great enough height with this ability selected, you will automatically create a shockwave.");
@ -666,7 +598,6 @@ public class ConfigManager {
config.addDefault("Abilities.Earth.Shockwave.Damage", 4);
config.addDefault("Abilities.Earth.Shockwave.Knockback", 1.1);
config.addDefault("Abilities.Earth.Shockwave.Range", 15);
config.addDefault("Abilities.Earth.Shockwave.Cooldown", 0);
config.addDefault("Abilities.Earth.SandSpout.Enabled", true);
config.addDefault("Abilities.Earth.SandSpout.Description", "SandSpout is a core move for travelling, evasion, and mobility for sandbenders. To use, simply left click while over sand or sandstone, and a column of sand will form at your feet, enabling you to levitate. Any mobs or players that touch your column will receive damage and be blinded. Beware, as the spout will stop working when no longer over sand!");
@ -689,7 +620,6 @@ public class ConfigManager {
config.addDefault("Abilities.Fire.Blaze.ArcOfFire.Arc", 16);
config.addDefault("Abilities.Fire.Blaze.ArcOfFire.Range", 7);
config.addDefault("Abilities.Fire.Blaze.RingOfFire.Range", 7);
config.addDefault("Abilities.Fire.Blaze.Cooldown", 0);
config.addDefault("Abilities.Fire.Combustion.Enabled", true);
config.addDefault("Abilities.Fire.Combustion.Description", "Combustion is a powerful ability only known by a few skilled Firebenders. It allows the bender to Firebend with their mind, concentrating energy to create a powerful blast. To use, simply tap sneak (Default: Shift) to launch the blast. This technique is highly destructive and very effective, it also comes with a long cooldown.");
@ -721,11 +651,10 @@ public class ConfigManager {
config.addDefault("Abilities.Fire.FireBlast.Charged.FireTicks", 4);
config.addDefault("Abilities.Fire.FireBurst.Enabled", true);
config.addDefault("Abilities.Fire.FireBurst.Description", "FireBurst is a very powerful firebending ability. " + "To use, press and hold sneak to charge your burst. " + "Once charged, you can either release sneak to release the burst in a sphere around you or " + "click to launch a cone-shaped burst of flames in front of you.");
config.addDefault("Abilities.Fire.FireBurst.Description", "FireBurst is a very powerful firebending ability. " + "To use, press and hold sneak to charge your burst. " + "Once charged, you can either release sneak to launch a cone-shaped burst " + "of flames in front of you, or click to release the burst in a sphere around you. ");
config.addDefault("Abilities.Fire.FireBurst.Damage", 2);
config.addDefault("Abilities.Fire.FireBurst.ChargeTime", 3500);
config.addDefault("Abilities.Fire.FireBurst.Range", 15);
config.addDefault("Abilities.Fire.FireBurst.Cooldown", 0);
config.addDefault("Abilities.Fire.FireJet.Enabled", true);
config.addDefault("Abilities.Fire.FireJet.Description", "This ability is used for a limited burst of flight for firebenders. Clicking with this " + "ability selected will launch you in the direction you're looking, granting you " + "controlled flight for a short time. This ability can be used mid-air to prevent falling " + "to your death, but on the ground it can only be used if standing on a block that's " + "ignitable (e.g. not snow or water).");

View file

@ -14,9 +14,5 @@ public enum ConfigType {
/**
* Death Message configuration represented by deathmessages.yml
*/
DEATH_MESSAGE,
/**
* Preset configuration represented by presets.yml
*/
PRESETS;
DEATH_MESSAGE;
}

View file

@ -1,7 +1,7 @@
package com.projectkorra.projectkorra.earthbending;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.EarthAbility;
import org.bukkit.Location;
import org.bukkit.block.Block;
@ -9,121 +9,94 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.configuration.ConfigLoadable;
// TODO: Remove Catapult.Speed from the Configuration
public class Catapult extends EarthAbility {
public class Catapult implements ConfigLoadable {
public static ConcurrentHashMap<Player, Catapult> instances = new ConcurrentHashMap<>();
private static int LENGTH = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.Catapult.Length");
private static double SPEED = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Catapult.Speed");
private static double PUSH = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Catapult.Push");
private static double SHIFT = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Catapult.ShiftModifier");
private static long COOLDOWN = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.Catapult.Cooldown");
private int length = LENGTH;
private double speed = SPEED;
private double push = PUSH;
private double shift = SHIFT;
private long cooldown = COOLDOWN;
private Player player;
private boolean catapult;
private boolean moving;
private boolean flying;
private int length;
private int distance;
private long cooldown;
private double push;
private Location origin;
private Location location;
private Vector direction;
private int distance;
private boolean catapult = false;
private boolean moving = false;
private boolean flying = false;
public Catapult(Player player) {
/* Initial Checks */
BendingPlayer bplayer = GeneralMethods.getBendingPlayer(player.getName());
if (bplayer.isOnCooldown("Catapult"))
super(player);
setFields();
this.origin = player.getEyeLocation().clone();
this.direction = origin.getDirection().clone().normalize();
if (!bPlayer.canBend(this)) {
return;
/* End Initial Checks */
// reloadVariables();
this.player = player;
origin = player.getEyeLocation().clone();
direction = origin.getDirection().clone().normalize();
}
Vector neg = direction.clone().multiply(-1);
Block block;
distance = 0;
for (int i = 0; i <= length; i++) {
location = origin.clone().add(neg.clone().multiply((double) i));
block = location.getBlock();
if (EarthMethods.isEarthbendable(player, block)) {
distance = EarthMethods.getEarthbendableBlocksLength(player, block, neg, length - i);
if (isEarthbendable(block)) {
distance = getEarthbendableBlocksLength(block, neg, length - i);
break;
} else if (!EarthMethods.isTransparentToEarthbending(player, block)) {
} else if (!isTransparent(block)) {
break;
}
}
if (distance != 0) {
if ((double) distance >= location.distance(origin)) {
if ((double) distance * distance >= location.distanceSquared(origin)) {
catapult = true;
}
if (player.isSneaking())
distance = (int) (distance / shift);
if (player.isSneaking()) {
distance = distance / 2;
}
moving = true;
instances.put(player, this);
bplayer.addCooldown("Catapult", cooldown);
start();
bPlayer.addCooldown(this);
}
}
public Catapult(Player player, Catapult source) {
this.player = player;
// reloadVariables();
super(player);
flying = true;
moving = false;
setFields();
location = source.location.clone();
direction = source.direction.clone();
distance = source.distance;
instances.put(player, this);
EarthMethods.playEarthbendingSound(player.getLocation());
start();
playEarthbendingSound(player.getLocation());
fly();
}
public static String getDescription() {
return "To use, left-click while looking in the direction you want to be launched. "
+ "A pillar of earth will jut up from under you and launch you in that direction - "
+ "if and only if there is enough earth behind where you're looking to launch you. "
+ "Skillful use of this ability takes much time and work, and it does result in the "
+ "death of certain gung-ho earthbenders. If you plan to use this ability, be sure "
+ "you've read about your passive ability you innately have as an earthbender.";
}
public static ArrayList<Player> getPlayers() {
ArrayList<Player> players = new ArrayList<Player>();
for (Catapult cata : instances.values()) {
players.add(cata.getPlayer());
}
return players;
private void setFields() {
this.length = getConfig().getInt("Abilities.Earth.Catapult.Length");
this.push = getConfig().getDouble("Abilities.Earth.Catapult.Push");
this.distance = 0;
this.cooldown = 0;
this.catapult = false;
this.moving = false;
this.flying = false;
}
private void fly() {
if (player.isDead() || !player.isOnline()) {
remove();
return;
}
if (!player.getWorld().equals(location.getWorld())) {
} else if (!player.getWorld().equals(location.getWorld())) {
remove();
return;
}
if (player.getLocation().distance(location) < 3) {
if (!moving)
} else if (player.getLocation().distanceSquared(location) < 9) {
if (!moving) {
flying = false;
}
return;
}
@ -133,31 +106,16 @@ public class Catapult implements ConfigLoadable {
return;
}
}
Vector vector = direction.clone().multiply(push * distance / length);
vector.setY(player.getVelocity().getY());
player.setVelocity(vector);
}
public int getLength() {
return length;
}
public Player getPlayer() {
return player;
}
public double getPush() {
return push;
}
public double getSpeed() {
return speed;
}
private boolean moveEarth() {
location = location.clone().add(direction);
if (catapult) {
if (location.distance(origin) < .5) {
if (location.distance(origin) < 0.5) {
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(origin, 2)) {
if (entity instanceof Player) {
Player target = (Player) entity;
@ -168,69 +126,137 @@ public class Catapult implements ConfigLoadable {
return false;
}
} else {
if (location.distance(origin) <= length - distance) {
double lengthSquared = (length - distance) * (length - distance);
if (location.distanceSquared(origin) <= lengthSquared) {
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2)) {
entity.setVelocity(direction.clone().multiply(push * distance / length));
}
return false;
}
}
EarthMethods.moveEarth(player, location.clone().subtract(direction), direction, distance, false);
moveEarth(location.clone().subtract(direction), direction, distance, false);
return true;
}
public boolean progress() {
if (player.isDead() || !player.isOnline()) {
@Override
public void progress() {
if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
remove();
return false;
return;
}
if (moving)
if (moving) {
if (!moveEarth()) {
moving = false;
}
if (flying)
fly();
if (!flying && !moving)
remove();
return true;
}
public static void progressAll() {
for (Catapult ability : instances.values()) {
ability.progress();
}
}
public static void removeAll() {
for (Catapult ability : instances.values()) {
ability.remove();
if (flying) {
fly();
} else if (!moving) {
remove();
return;
}
}
@Override
public void reloadVariables() {
LENGTH = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.Catapult.Length");
SPEED = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Catapult.Speed");
PUSH = ProjectKorra.plugin.getConfig().getDouble("Abilities.Earth.Catapult.Push");
public String getName() {
return "Catapult";
}
public void remove() {
instances.remove(player);
@Override
public Location getLocation() {
if (player != null) {
return player.getLocation();
}
return null;
}
@Override
public long getCooldown() {
return cooldown;
}
@Override
public boolean isSneakAbility() {
return false;
}
@Override
public boolean isHarmlessAbility() {
return false;
}
public Location getOrigin() {
return origin;
}
public void setOrigin(Location origin) {
this.origin = origin;
}
public Vector getDirection() {
return direction;
}
public void setDirection(Vector direction) {
this.direction = direction;
}
public boolean isCatapult() {
return catapult;
}
public void setCatapult(boolean catapult) {
this.catapult = catapult;
}
public boolean isMoving() {
return moving;
}
public void setMoving(boolean moving) {
this.moving = moving;
}
public boolean isFlying() {
return flying;
}
public void setFlying(boolean flying) {
this.flying = flying;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getDistance() {
return distance;
}
public void setDistance(int distance) {
this.distance = distance;
}
public double getPush() {
return push;
}
public void setPush(double push) {
this.push = push;
}
public void setSpeed(double speed) {
this.speed = speed;
public void setLocation(Location location) {
this.location = location;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
}

Some files were not shown because too many files have changed in this diff Show more