Added IceBlast and new Icebending Methods

Lotta stuff
This commit is contained in:
AlexTheCoder 2014-09-03 19:03:49 -04:00
parent 654aa9477e
commit 7aeca555ed
9 changed files with 351 additions and 2 deletions

View file

@ -90,6 +90,7 @@ public class AbilityModuleManager {
if (a == StockAbilities.Torrent) shiftabilities.add(a.name());
if (a == StockAbilities.WaterManipulation) shiftabilities.add(a.name());
if (a == StockAbilities.IceSpike) shiftabilities.add(a.name());
if (a == StockAbilities.IceBlast) 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, Suffocate;
Extraction, Smokescreen, Combustion, LavaSurge, 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, OctopusForm, Torrent;
WaterBubble, PhaseChange, HealingWaters, WaterManipulation, Surge, Bloodbending, WaterSpout, IceSpike, IceBlast, OctopusForm, Torrent;
}
private enum EarthbendingAbilities {

View file

@ -224,6 +224,11 @@ public class ConfigManager {
+ "be at least partially submerged in water.");
config.addDefault("Abilities.Water.HealingWaters.Radius", 5);
config.addDefault("Abilities.Water.HealingWaters.Interval", 750);
config.addDefault("Abilities.Water.IceBlast.Enabled", true);
config.addDefault("Abilities.Water.IceBlast.Damage", 3);
config.addDefault("Abilities.Water.IceBlast.Range", 20);
config.addDefault("Abilities.Water.IceBlast.Description", "This is one of the most powerful abilities available to Waterbenders. NOT COMPLETE DESC FOR TESTING PURPOSES ONLY!");
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, "

View file

@ -931,6 +931,20 @@ public class Methods {
}
return null;
}
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 (isRegionProtectedFromBuild(player, "IceBlast", location))
continue;
if (isIcebendable(block)) {
return block;
}
}
return null;
}
public static boolean hasPermission(Player player, String ability) {
if (player.hasPermission("bending.ability." + ability)) return true;
@ -1357,6 +1371,12 @@ public class Methods {
if ((block.getType() == Material.LAVA || block.getType() == Material.STATIONARY_LAVA) && block.getData() == full) return true;
return false;
}
public static boolean isIcebendable(Block block) {
if (block.getType() == Material.ICE) return true;
if (block.getType() == Material.PACKED_ICE && plugin.getConfig().getBoolean("Properties.Water.CanBendPackedIce")) return true;
return false;
}
public static boolean isWeapon(Material mat) {

View file

@ -108,6 +108,7 @@ import com.projectkorra.ProjectKorra.firebending.RingOfFire;
import com.projectkorra.ProjectKorra.firebending.WallOfFire;
import com.projectkorra.ProjectKorra.waterbending.Bloodbending;
import com.projectkorra.ProjectKorra.waterbending.FreezeMelt;
import com.projectkorra.ProjectKorra.waterbending.IceBlast;
import com.projectkorra.ProjectKorra.waterbending.IceSpike2;
import com.projectkorra.ProjectKorra.waterbending.Melt;
import com.projectkorra.ProjectKorra.waterbending.OctopusForm;
@ -379,6 +380,9 @@ public class PKListener implements Listener {
if (abil.equalsIgnoreCase("Bloodbending")) {
new Bloodbending(player);
}
if (abil.equalsIgnoreCase("IceBlast")) {
new IceBlast(player);
}
if (abil.equalsIgnoreCase("IceSpike")) {
new IceSpike2(player);
}
@ -705,6 +709,9 @@ public class PKListener implements Listener {
if (abil.equalsIgnoreCase("Bloodbending")) {
Bloodbending.launch(player);
}
if (abil.equalsIgnoreCase("IceBlast")) {
IceBlast.activate(player);
}
if (abil.equalsIgnoreCase("IceSpike")) {
IceSpike2.activate(player);
}

View file

@ -0,0 +1,309 @@
package com.projectkorra.ProjectKorra.waterbending;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import com.projectkorra.ProjectKorra.BendingPlayer;
import com.projectkorra.ProjectKorra.Methods;
import com.projectkorra.ProjectKorra.ProjectKorra;
import com.projectkorra.ProjectKorra.TempBlock;
import com.projectkorra.ProjectKorra.TempPotionEffect;
import com.projectkorra.ProjectKorra.Utilities.ParticleEffect;
public class IceBlast {
private static ConcurrentHashMap<Integer, IceBlast> instances = new ConcurrentHashMap<Integer, IceBlast>();
private static double defaultrange = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.IceBlast.Damage");
private static int defaultdamage = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.IceBlast.Damage");
private static int ID = Integer.MIN_VALUE;
private static final long interval = 20;
private static final byte data = 0;
private static final double affectingradius = 2;
private static final double deflectrange = 3;
private int id;
private double range;
private boolean prepared = false;
private boolean settingup = false;
private boolean progressing = false;
private long time;
private Location location;
private Location firstdestination;
private Location destination;
private Block sourceblock;
private Player player;
private TempBlock source;
public IceBlast(Player player) {
block(player);
range = Methods.waterbendingNightAugment(defaultrange, player.getWorld());
this.player = player;
Block sourceblock = Methods.getIceSourceBlock(player, range);
if (sourceblock == null) {
return;
} else {
prepare(sourceblock);
}
}
private void prepare(Block block) {
for (IceBlast ice : getInstances(player)) {
if (ice.prepared) {
ice.cancel();
}
}
sourceblock = block;
location = sourceblock.getLocation();
prepared = true;
createInstance();
}
private void createInstance() {
id = ID++;
instances.put(id, this);
if (ID >= Integer.MAX_VALUE) {
ID = Integer.MIN_VALUE;
}
}
private static ArrayList<IceBlast> getInstances(Player player) {
ArrayList<IceBlast> list = new ArrayList<IceBlast>();
for (int id : instances.keySet()) {
IceBlast ice = instances.get(id);
if (ice.player.equals(player)) {
list.add(ice);
}
}
return list;
}
private static void block(Player player) {
for (int id : instances.keySet()) {
IceBlast ice = instances.get(id);
if (ice.player.equals(player))
continue;
if (!ice.location.getWorld().equals(player.getWorld()))
continue;
if (!ice.progressing)
continue;
if (Methods.isRegionProtectedFromBuild(player, "IceBlast", ice.location))
continue;
Location location = player.getEyeLocation();
Vector vector = location.getDirection();
Location mloc = ice.location;
if (mloc.distance(location) <= defaultrange
&& Methods.getDistanceFromLine(vector, location, ice.location) < deflectrange
&& mloc.distance(location.clone().add(vector)) <
mloc.distance(location.clone().add(vector.clone().multiply(-1)))) {
ice.cancel();
}
}
}
public static void activate(Player player) {
BendingPlayer bPlayer = Methods.getBendingPlayer(player.getName());
if (bPlayer.isOnCooldown("IceBlast")) return;
for (IceBlast ice : getInstances(player)) {
if (ice.prepared) {
ice.throwIce();
}
}
}
private void cancel() {
if (progressing) {
if (source != null)
source.revertBlock();
progressing = false;
}
instances.remove(id);
}
private void returnWater() {
new WaterReturn(player, sourceblock);
}
public static void removeAll() {
for (int id : instances.keySet()) {
instances.get(id).cancel();
}
instances.clear();
}
private void affect(LivingEntity entity) {
int damage = (int) Methods.waterbendingNightAugment(defaultdamage, player.getWorld());
if (entity instanceof Player) {
BendingPlayer bPlayer = Methods.getBendingPlayer(player.getName());
if (bPlayer.canBeSlowed()) {
PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, 70, 2);
new TempPotionEffect(entity, effect);
bPlayer.slow(10);
entity.damage(damage, player);
}
} else {
PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, 70, 2);
new TempPotionEffect(entity, effect);
entity.damage(damage, player);
}
Methods.breakBreathbendingHold(entity);
}
private void throwIce() {
if (!prepared)
return;
LivingEntity target = (LivingEntity) Methods.getTargetedEntity(player, range, new ArrayList<Entity>());
if (target == null) {
destination = Methods.getTargetedLocation(player, range, Methods.transparentToEarthbending);
} else {
destination = target.getEyeLocation();
}
location = sourceblock.getLocation();
if (destination.distance(location) < 1)
return;
firstdestination = location.clone();
if (destination.getY() - location.getY() > 2) {
firstdestination.setY(destination.getY() - 1);
} else {
firstdestination.add(0, 2, 0);
}
destination = Methods.getPointOnLine(firstdestination, destination, range);
progressing = true;
settingup = true;
prepared = false;
sourceblock.setType(Material.AIR);
source = new TempBlock(sourceblock, Material.PACKED_ICE, data);
}
private void progress() {
if (player.isDead() || !player.isOnline() || !Methods.canBend(player.getName(), "IceBlast")) {
cancel();
return;
}
if (!player.getWorld().equals(location.getWorld())) {
cancel();
return;
}
if (player.getEyeLocation().distance(location) >= range) {
if (progressing) {
cancel();
returnWater();
} else {
cancel();
}
return;
}
if ((Methods.getBoundAbility(player) == null || !Methods.getBoundAbility(player).equalsIgnoreCase("IceBlast")) && prepared) {
cancel();
return;
}
if (System.currentTimeMillis() < time + interval)
return;
time = System.currentTimeMillis();
if (progressing) {
Vector direction;
if (location.getBlockY() == firstdestination.getBlockY())
settingup = false;
if (location.distance(destination) <= 2) {
cancel();
returnWater();
return;
}
if (settingup) {
direction = Methods.getDirection(location, firstdestination).normalize();
} else {
direction = Methods.getDirection(location, destination).normalize();
}
location.add(direction);
Block block = location.getBlock();
if (block.equals(sourceblock))
return;
source.revertBlock();
source = null;
if (Methods.isTransparentToEarthbending(player, block) && !block.isLiquid()) {
Methods.breakBlock(block);
} else if (!Methods.isWater(block)) {
cancel();
returnWater();
return;
}
if (Methods.isRegionProtectedFromBuild(player, "IceBlast", location)) {
cancel();
returnWater();
return;
}
for (Entity entity : Methods.getEntitiesAroundPoint(location, affectingradius)) {
if (entity.getEntityId() != player.getEntityId() && entity instanceof LivingEntity) {
affect((LivingEntity) entity);
progressing = false;
returnWater();
}
}
if (!progressing) {
cancel();
return;
}
sourceblock = block;
source = new TempBlock(sourceblock, Material.PACKED_ICE, data);
ParticleEffect.SNOWBALL_POOF.display(location, (float) Math.random(), (float) Math.random(), (float) Math.random(), 0, 1000);
ParticleEffect.SNOW_SHOVEL.display(location, (float) Math.random(), (float) Math.random(), (float) Math.random(), 0, 1000);
location = location.add(direction.clone());
} else if (prepared) {
Methods.playFocusWaterEffect(sourceblock);
}
}
public static void progressAll() {
for (int id : instances.keySet()) {
instances.get(id).progress();
}
}
}

View file

@ -29,6 +29,7 @@ public class WaterbendingManager implements Runnable {
Wave.progressAll();
IceSpike.progressAll();
IceSpike2.progressAll();
IceBlast.progressAll();
}
}

View file

@ -167,6 +167,11 @@ Abilities:
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."
Radius: 5
Interval: 750
IceBlast:
Enabled: true
Damage: 3
Range: 20
Description: "This is one of the most powerful abilities available to Waterbenders. NOT COMPLETE DESC FOR TESTING PURPOSES ONLY!"
IceSpike:
Enabled: true
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 (default: shift) while selecting a water source will select that source that can 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) will not selecting a source, many ice spikes will erupt from around you, damaging and slowing those targets."

View file

@ -59,6 +59,7 @@ permissions:
description: Grants access to most waterbending abilities.
children:
bending.ability.HealingWaters: true
bending.ability.IceBlast: true
bending.ability.IceSpike: true
bending.ability.OctopusForm: true
bending.ability.PhaseChange: true