Merge pull request #49 from nathank33/master

Merged WaterWave into WaterSpout, OctopusForm Config Option
This commit is contained in:
MistPhizzle 2014-10-06 13:00:06 -04:00
commit 6dbedc7c77
10 changed files with 184 additions and 170 deletions

View file

@ -95,7 +95,6 @@ public class AbilityModuleManager {
if (a == StockAbilities.WaterManipulation) shiftabilities.add(a.name());
if (a == StockAbilities.IceSpike) shiftabilities.add(a.name());
if (a == StockAbilities.IceBlast) shiftabilities.add(a.name());
if (a == StockAbilities.WaterWave) shiftabilities.add(a.name());
}
}
else if (StockAbilities.isEarthbending(a)) {

View file

@ -18,14 +18,14 @@ public enum StockAbilities {
AvatarState,
// Project Korra
Extraction, Smokescreen, Combustion, LavaSurge, LavaFlow, Suffocate, IceBlast, WaterWave;
Extraction, Smokescreen, Combustion, LavaSurge, LavaFlow, Suffocate, IceBlast;
private enum AirbendingAbilities {
AirBlast, AirBubble, AirShield, AirSuction, AirSwipe, Tornado, AirScooter, AirSpout, AirBurst, Suffocate;
}
private enum WaterbendingAbilities {
WaterBubble, PhaseChange, HealingWaters, WaterManipulation, Surge, Bloodbending, WaterSpout, IceSpike, IceBlast, OctopusForm, Torrent, WaterWave;
WaterBubble, PhaseChange, HealingWaters, WaterManipulation, Surge, Bloodbending, WaterSpout, IceSpike, IceBlast, OctopusForm, Torrent;
}

View file

@ -269,6 +269,7 @@ public class ConfigManager {
config.addDefault("Abilities.Water.OctopusForm.Range", 10);
config.addDefault("Abilities.Water.OctopusForm.Radius", 3);
config.addDefault("Abilities.Water.OctopusForm.Damage", 3);
config.addDefault("Abilities.Water.OctopusForm.FormDelay", 50);
config.addDefault("Abilities.Water.PhaseChange.Enabled", true);
config.addDefault("Abilities.Water.PhaseChange.Description", "To use, simply left-click. "
@ -312,19 +313,13 @@ public class ConfigManager {
config.addDefault("Abilities.Water.WaterManipulation.Cooldown", 1000);
config.addDefault("Abilities.Water.WaterSpout.Enabled", true);
config.addDefault("Abilities.Water.WaterSpout.Description", "To use this ability, click while over or in water. "
+ "You will spout water up from beneath you to experience controlled levitation. "
+ "This ability is a toggle, so you can activate it then use other abilities and it "
+ "will remain on. If you try to spout over an area with no water, snow or ice, "
+ "the spout will dissipate and you will fall. Click again with this ability selected to deactivate it.");
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.");
config.addDefault("Abilities.Water.WaterSpout.Height", 20);
config.addDefault("Abilities.Water.WaterWave.Enabled", true);
config.addDefault("Abilities.Water.WaterWave.Description", "This ability provides a Waterbender with boosted mobility and transportation. To use, first click a source block to select it; then hold sneak (Default: Shift) to begin streaming the water around you. While the water is streaming around you let go of sneak and the water will form underneath your feet, blasting you off into the direction that you are facing. Additionally, taping sneak while riding the wave still stop it.");
config.addDefault("Abilities.Water.WaterWave.Range", 6);
config.addDefault("Abilities.Water.WaterWave.ChargeTime", 1000);
config.addDefault("Abilities.Water.WaterWave.FlightTime", 2000);
config.addDefault("Abilities.Water.WaterWave.Speed", 1.2);
config.addDefault("Abilities.Water.WaterSpout.Wave.Enabled", true);
config.addDefault("Abilities.Water.WaterSpout.Wave.Range", 6);
config.addDefault("Abilities.Water.WaterSpout.Wave.ChargeTime", 1000);
config.addDefault("Abilities.Water.WaterSpout.Wave.FlightTime", 2000);
config.addDefault("Abilities.Water.WaterSpout.Wave.Speed", 1.2);
config.addDefault("Abilities.Earth.Passive.Duration", 2500);

View file

@ -420,9 +420,6 @@ public class PKListener implements Listener {
if (abil.equalsIgnoreCase("Torrent")) {
Torrent.create(player);
}
if (abil.equalsIgnoreCase("WaterWave")) {
new WaterWave(player, WaterWave.AbilityType.SHIFT);
}
}
if (Methods.isEarthAbility(abil)) {
@ -757,9 +754,6 @@ public class PKListener implements Listener {
if (abil.equalsIgnoreCase("Torrent")) {
new Torrent(player);
}
if (abil.equalsIgnoreCase("WaterWave")) {
new WaterWave(player, WaterWave.AbilityType.CLICK);
}
}
if (Methods.isEarthAbility(abil)) {

View file

@ -22,7 +22,7 @@ public class OctopusForm {
private static int range = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.OctopusForm.Range");
private static int damage = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.OctopusForm.Damage");
private static long interval = 50;
private static long interval = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.OctopusForm.Damage.FormDelay");
static double radius = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.OctopusForm.Radius");
private static final byte full = 0x0;

View file

@ -31,7 +31,7 @@ public class WaterPassive {
if (Methods.canBendPassive(player.getName(), Element.Water)) {
if (WaterSpout.instances.containsKey(player) || EarthArmor.instances.containsKey(player)) {
continue;
} else if (ability == null || !AbilityModuleManager.shiftabilities.contains(ability) || ability.equalsIgnoreCase("WaterWave")) {
} else if (ability == null || !AbilityModuleManager.shiftabilities.contains(ability)) {
if (player.isSneaking() && Methods.isWater(player.getLocation().getBlock())) {
player.setVelocity(player.getEyeLocation().getDirection().clone().normalize().multiply(swimFactor));
}

View file

@ -3,14 +3,12 @@ package com.projectkorra.ProjectKorra.waterbending;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import com.projectkorra.ProjectKorra.Flight;
import com.projectkorra.ProjectKorra.Methods;
@ -44,6 +42,11 @@ public class WaterSpout {
return;
}
this.player = player;
WaterWave wwave = new WaterWave(player, WaterWave.AbilityType.CLICK);
if(WaterWave.instances.contains(wwave))
return;
Block topBlock = Methods.getTopBlock(player.getLocation(), 0, -50);
if(topBlock == null)
topBlock = player.getLocation().getBlock();

View file

@ -7,6 +7,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
@ -16,22 +17,29 @@ import com.projectkorra.ProjectKorra.ProjectKorra;
import com.projectkorra.ProjectKorra.TempBlock;
import com.projectkorra.ProjectKorra.Ability.AvatarState;
public class WaterWave
{
public static enum AbilityType{
public class WaterWave {
public static enum AbilityType {
CLICK, SHIFT, RELEASE
}
public static enum AnimateState{
public static enum AnimateState {
RISE, TOWARDPLAYER, CIRCLE, SHRINK
}
public static ArrayList<WaterWave> instances = new ArrayList<WaterWave>();
public static boolean ICE_ONLY = false;
public static double RANGE = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.WaterWave.Range");
public static double MAX_SPEED = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.WaterWave.Speed");
public static long CHARGE_TIME = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.WaterWave.ChargeTime");
public static long FLIGHT_TIME = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.WaterWave.FlightTime");
public static boolean ENABLED = ProjectKorra.plugin.getConfig().getBoolean(
"Abilities.Water.WaterSpout.Wave.Enabled");
public static double RANGE = ProjectKorra.plugin.getConfig().getDouble(
"Abilities.Water.WaterSpout.Wave.Range");
public static double MAX_SPEED = ProjectKorra.plugin.getConfig().getDouble(
"Abilities.Water.WaterSpout.Wave.Speed");
public static long CHARGE_TIME = ProjectKorra.plugin.getConfig().getLong(
"Abilities.Water.WaterSpout.Wave.ChargeTime");
public static long FLIGHT_TIME = ProjectKorra.plugin.getConfig().getLong(
"Abilities.Water.WaterSpout.Wave.FlightTime");
private Player player;
private long time;
private AbilityType type;
@ -41,95 +49,106 @@ public class WaterWave
private boolean charging = false;
private AnimateState anim;
private ConcurrentHashMap<Block, TempBlock> affectedBlocks = new ConcurrentHashMap<Block, TempBlock>();
public WaterWave(Player player, AbilityType type)
{
public WaterWave(Player player, AbilityType type) {
if(!ENABLED)
return;
this.player = player;
this.time = System.currentTimeMillis();
this.type = type;
instances.add(this);
if(type == AbilityType.CLICK)
if (type == AbilityType.CLICK)
this.progress();
}
public void progress()
{
public void progress() {
if (player.isDead() || !player.isOnline()) {
remove();
return;
}
if(type != AbilityType.RELEASE)
{
if(!Methods.canBend(player.getName(), "WaterWave")){
if (type != AbilityType.RELEASE) {
if (!Methods.canBend(player.getName(), "WaterSpout")
|| !player.hasPermission("bending.ability.WaterSpout.Wave")) {
remove();
return;
}
String ability = Methods.getBoundAbility(player);
if(ability == null || !ability.equalsIgnoreCase("WaterWave")){
if (ability == null || !ability.equalsIgnoreCase("WaterSpout")) {
remove();
return;
}
}
if(type == AbilityType.CLICK)
{
if(origin == null)
{
if (type == AbilityType.CLICK) {
if (origin == null) {
removeType(player, AbilityType.CLICK);
instances.add(this);
Block block = Methods.getWaterSourceBlock(player, RANGE, Methods.canPlantbend(player));
if(block == null || block.getLocation().clone().add(0,1,0).getBlock().getType() != Material.AIR){
Block block = Methods.getWaterSourceBlock(player, RANGE,
Methods.canPlantbend(player));
if (block == null) {
remove();
return;
}
Block blockAbove = block.getRelative(BlockFace.UP);
if (blockAbove.getType() != Material.AIR
&& !Methods.isWaterbendable(blockAbove, player)) {
remove();
return;
}
origin = block.getLocation();
if(!Methods.isWaterbendable(block, player) || Methods.isRegionProtectedFromBuild(player, "WaterWave", origin)){
if (!Methods.isWaterbendable(block, player)
|| Methods.isRegionProtectedFromBuild(player,
"WaterSpout", origin)) {
remove();
return;
}
if(ICE_ONLY && !(block.getType() == Material.ICE || block.getType() == Material.SNOW || block.getType() == Material.PACKED_ICE))
{
if (ICE_ONLY
&& !(block.getType() == Material.ICE
|| block.getType() == Material.SNOW || block
.getType() == Material.PACKED_ICE)) {
remove();
return;
}
}
if(player.getLocation().distance(origin) > RANGE){
if (player.getLocation().distance(origin) > RANGE) {
remove();
return;
} else if (player.isSneaking()) {
new WaterWave(player, AbilityType.SHIFT);
return;
}
Methods.playFocusWaterEffect(origin.getBlock());
}
else if(type == AbilityType.SHIFT)
{
if(direction == null){
} else if (type == AbilityType.SHIFT) {
if (direction == null) {
direction = player.getEyeLocation().getDirection();
}
if(!charging)
{
if(!containsType(player, AbilityType.CLICK)){
if (!charging) {
if (!containsType(player, AbilityType.CLICK)) {
removeType(player, AbilityType.CLICK);
remove();
return;
}
charging = true;
anim = AnimateState.RISE;
WaterWave clickSpear = getType(player, AbilityType.CLICK).get(0);
WaterWave clickSpear = getType(player, AbilityType.CLICK)
.get(0);
origin = clickSpear.origin.clone();
currentLoc = origin.clone();
if(Methods.isPlant(origin.getBlock()))
if (Methods.isPlant(origin.getBlock()))
new Plantbending(origin.getBlock());
//else
// Methods.addTempAirBlock(origin.getBlock());
// else
// Methods.addTempAirBlock(origin.getBlock());
}
removeType(player, AbilityType.CLICK);
if(!player.isSneaking()){
if(System.currentTimeMillis() - time > CHARGE_TIME)
{
if (!player.isSneaking()) {
if (System.currentTimeMillis() - time > CHARGE_TIME) {
WaterWave wwave = new WaterWave(player, AbilityType.RELEASE);
wwave.anim = AnimateState.SHRINK;
wwave.direction = direction;
@ -137,179 +156,183 @@ public class WaterWave
remove();
return;
}
double animSpeed = 1.2;
if(anim == AnimateState.RISE){
if (anim == AnimateState.RISE) {
revertBlocks();
currentLoc.add(0,animSpeed,0);
currentLoc.add(0, animSpeed, 0);
Block block = currentLoc.getBlock();
if(block.getType() != Material.AIR || Methods.isRegionProtectedFromBuild(player, "WaterWave", block.getLocation())){
if (!(Methods.isWaterbendable(block, player) || block.getType() == Material.AIR)
|| Methods.isRegionProtectedFromBuild(player,
"WaterSpout", block.getLocation())) {
remove();
return;
}
createBlock(block, Material.STATIONARY_WATER);
if(currentLoc.distance(origin) > 2)
if (currentLoc.distance(origin) > 2)
anim = AnimateState.TOWARDPLAYER;
}
else if(anim == AnimateState.TOWARDPLAYER)
{
} else if (anim == AnimateState.TOWARDPLAYER) {
revertBlocks();
Location eyeLoc = player.getTargetBlock(null, 2).getLocation();
eyeLoc.setY(player.getEyeLocation().getY());
Vector vec = Methods.getDirection(currentLoc, eyeLoc);
currentLoc.add(vec.normalize().multiply(animSpeed));
Block block = currentLoc.getBlock();
if(block.getType() != Material.AIR || Methods.isRegionProtectedFromBuild(player, "WaterWave", block.getLocation())){
if (!(Methods.isWaterbendable(block, player) || block.getType() == Material.AIR)
|| Methods.isRegionProtectedFromBuild(player,
"WaterSpout", block.getLocation())) {
remove();
return;
}
createBlock(block, Material.STATIONARY_WATER);
if(currentLoc.distance(eyeLoc) < 1.3)
{
if (currentLoc.distance(eyeLoc) < 1.3) {
anim = AnimateState.CIRCLE;
Vector tempDir = player.getLocation().getDirection();
tempDir.setY(0);
direction = tempDir.normalize();
revertBlocks();
}
} else if (anim == AnimateState.CIRCLE) {
drawCircle(120, 5);
}
else if(anim == AnimateState.CIRCLE)
{
drawCircle(120,5);
}
}
else if(type == AbilityType.RELEASE)
{
if(anim == AnimateState.SHRINK)
{
radius-=0.20;
drawCircle(360,15);
if(radius < 1){
} else if (type == AbilityType.RELEASE) {
if (anim == AnimateState.SHRINK) {
radius -= 0.20;
drawCircle(360, 15);
if (radius < 1) {
revertBlocks();
time = System.currentTimeMillis();
anim = null;
}
}
else
{
if((System.currentTimeMillis() - time > FLIGHT_TIME && !AvatarState.isAvatarState(player))
|| player.isSneaking())
{
} else {
if ((System.currentTimeMillis() - time > FLIGHT_TIME && !AvatarState
.isAvatarState(player)) || player.isSneaking()) {
remove();
return;
}
double currentSpeed = MAX_SPEED - (MAX_SPEED * (double)(System.currentTimeMillis() - time) / (double)FLIGHT_TIME);
double nightSpeed = Methods.waterbendingNightAugment(currentSpeed * 0.9, player.getWorld());
currentSpeed = nightSpeed > currentSpeed ? nightSpeed : currentSpeed;
if(AvatarState.isAvatarState(player))
currentSpeed = Methods.waterbendingNightAugment(MAX_SPEED, player.getWorld());
player.setVelocity(player.getEyeLocation().getDirection().normalize().multiply(currentSpeed));
for(Block block : Methods.getBlocksAroundPoint(player.getLocation().add(0,-1,0), 1.5))
if(block.getType() == Material.AIR && !Methods.isRegionProtectedFromBuild(player, "WaterWave", block.getLocation()))
createBlock(block,Material.STATIONARY_WATER,(byte)0);
double currentSpeed = MAX_SPEED
- (MAX_SPEED
* (double) (System.currentTimeMillis() - time) / (double) FLIGHT_TIME);
double nightSpeed = Methods.waterbendingNightAugment(
currentSpeed * 0.9, player.getWorld());
currentSpeed = nightSpeed > currentSpeed ? nightSpeed
: currentSpeed;
if (AvatarState.isAvatarState(player))
currentSpeed = Methods.waterbendingNightAugment(MAX_SPEED,
player.getWorld());
player.setVelocity(player.getEyeLocation().getDirection()
.normalize().multiply(currentSpeed));
for (Block block : Methods.getBlocksAroundPoint(player
.getLocation().add(0, -1, 0), 1.5))
if (block.getType() == Material.AIR
&& !Methods.isRegionProtectedFromBuild(player,
"WaterSpout", block.getLocation()))
createBlock(block, Material.STATIONARY_WATER, (byte) 0);
revertBlocksDelay(20L);
}
}
}
public void drawCircle(double theta, double increment)
{
public void drawCircle(double theta, double increment) {
double rotateSpeed = 45;
revertBlocks();
direction = Methods.rotateXZ(direction, rotateSpeed);
for(double i = 0; i < theta; i+=increment)
{
Vector dir = Methods.rotateXZ(direction, i - theta / 2).normalize().multiply(radius);
for (double i = 0; i < theta; i += increment) {
Vector dir = Methods.rotateXZ(direction, i - theta / 2).normalize()
.multiply(radius);
dir.setY(0);
Block block = player.getEyeLocation().add(dir).getBlock();
currentLoc = block.getLocation();
if(block.getType() == Material.AIR && !Methods.isRegionProtectedFromBuild(player, "WaterWave", block.getLocation()))
createBlock(block,Material.STATIONARY_WATER,(byte)8);
if (block.getType() == Material.AIR
&& !Methods.isRegionProtectedFromBuild(player,
"WaterSpout", block.getLocation()))
createBlock(block, Material.STATIONARY_WATER, (byte) 8);
}
}
public void remove()
{
public void remove() {
instances.remove(this);
revertBlocks();
}
public void createBlock(Block block, Material mat){
createBlock(block,mat,(byte)0);
public void createBlock(Block block, Material mat) {
createBlock(block, mat, (byte) 0);
}
public void createBlock(Block block, Material mat, byte data){
public void createBlock(Block block, Material mat, byte data) {
affectedBlocks.put(block, new TempBlock(block, mat, data));
}
public void revertBlocks()
{
public void revertBlocks() {
Enumeration<Block> keys = affectedBlocks.keys();
while(keys.hasMoreElements())
{
while (keys.hasMoreElements()) {
Block block = keys.nextElement();
affectedBlocks.get(block).revertBlock();
affectedBlocks.remove(block);
}
}
public void revertBlocksDelay(long delay)
{
public void revertBlocksDelay(long delay) {
Enumeration<Block> keys = affectedBlocks.keys();
while(keys.hasMoreElements())
{
while (keys.hasMoreElements()) {
final Block block = keys.nextElement();
final TempBlock tblock = affectedBlocks.get(block);
affectedBlocks.remove(block);
new BukkitRunnable(){
public void run()
{
new BukkitRunnable() {
public void run() {
tblock.revertBlock();
}
}.runTaskLater(ProjectKorra.plugin, delay);
}
}
public static void progressAll()
{
//Bukkit.broadcastMessage("Instances:" + instances.size());
for(int i = 0; i < instances.size(); i++)
public static void progressAll() {
// Bukkit.broadcastMessage("Instances:" + instances.size());
for (int i = 0; i < instances.size(); i++)
instances.get(i).progress();
}
public static void removeAll()
{
for(int i = 0; i < instances.size(); i++){
public static void removeAll() {
for (int i = 0; i < instances.size(); i++) {
instances.get(i).remove();
i--;
}
}
public static boolean containsType(Player player, AbilityType type)
{
for(int i = 0; i < instances.size(); i++){
public static boolean containsType(Player player, AbilityType type) {
for (int i = 0; i < instances.size(); i++) {
WaterWave spear = instances.get(i);
if(spear.player.equals(player) && spear.type.equals(type))
if (spear.player.equals(player) && spear.type.equals(type))
return true;
}
return false;
}
public static void removeType(Player player, AbilityType type)
{
for(int i = 0; i < instances.size(); i++){
public static void removeType(Player player, AbilityType type) {
for (int i = 0; i < instances.size(); i++) {
WaterWave spear = instances.get(i);
if(spear.player.equals(player) && spear.type.equals(type)){
if (spear.player.equals(player) && spear.type.equals(type)) {
instances.remove(i);
i--;
}
}
}
public static ArrayList<WaterWave> getType(Player player, AbilityType type)
{
public static ArrayList<WaterWave> getType(Player player, AbilityType type) {
ArrayList<WaterWave> list = new ArrayList<WaterWave>();
for(WaterWave spear : instances){
if(spear.player.equals(player) && spear.type.equals(type))
for (WaterWave spear : instances) {
if (spear.player.equals(player) && spear.type.equals(type))
list.add(spear);
}
return list;
}
public static boolean wasBrokenFor(Player player, Block block) {
if (containsType(player,AbilityType.CLICK)) {
WaterWave wwave = getType(player,AbilityType.CLICK).get(0);
if (containsType(player, AbilityType.CLICK)) {
WaterWave wwave = getType(player, AbilityType.CLICK).get(0);
if (wwave.origin == null)
return false;
if (wwave.origin.getBlock().equals(block))

View file

@ -195,6 +195,7 @@ Abilities:
Range: 10
Damage: 3
Radius: 3
FormDelay: 50
PhaseChange:
Enabled: true
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 things 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 targeting water with FreezeMelt, it will evaporate water around that block that is above sea level."
@ -232,15 +233,14 @@ Abilities:
Cooldown: 1000
WaterSpout:
Enabled: true
Description: "To use this ability, click while over or in water. You will spout water up from beneath you to experience controlled levitation. This ability is a toggle, so you can activate it then use other abilities and it will remain on. If you try to spout over an area with no water, snow, or ice, the spout will dissipate and you will fall. Click again with this ability selected to deactivate it."
Description: This ability provides a Waterbender with a new 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.
Height: 20
WaterWave:
Enabled: true
Description: "This ability provides a Waterbender with boosted mobility and transportation. To use, first click a source block to select it; then hold sneak (Default: Shift) to begin streaming the water around you. While the water is streaming around you let go of sneak and the water will form underneath your feet, blasting you off into the direction that you are facing. Additionally, taping sneak while riding the wave still stop it."
Range: 6
ChargeTime: 1000
FlightTime: 2000
Speed: 1.2
Wave:
Enabled: true
Range: 6
ChargeTime: 1000
FlightTime: 2000
Speed: 1.2
Earth:
Passive:
Duration: 2500

View file

@ -76,8 +76,8 @@ permissions:
bending.ability.WaterBubble: true
bending.ability.WaterManipulation: true
bending.ability.WaterSpout: true
bending.ability.WaterSpout.Wave: true
bending.ability.Plantbending: true
bending.ability.WaterWave: true
bending.message.nightmessage: true
bending.water.passive: true
bending.earth: