mirror of
https://github.com/TotalFreedomMC/TF-ProjectKorra.git
synced 2024-12-22 16:05:01 +00:00
Implemented new collision detection system (#636)
This commit is contained in:
parent
ca40454356
commit
5096d3d399
56 changed files with 2098 additions and 948 deletions
|
@ -211,11 +211,15 @@ public class GeneralMethods {
|
|||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
* <p>
|
||||
* Cycles through a list of ability names to check if any instances of the
|
||||
* abilities exist at a specific location. If an instance of the ability is
|
||||
* found then it will be removed, with the exception FireShield, and
|
||||
* AirShield.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean blockAbilities(Player player, List<String> abilitiesToBlock, Location loc, double radius) {
|
||||
boolean hasBlocked = false;
|
||||
for (String ability : abilitiesToBlock) {
|
||||
|
|
|
@ -11,6 +11,8 @@ import org.bukkit.plugin.java.JavaPlugin;
|
|||
|
||||
import com.bekvon.bukkit.residence.protection.FlagPermissions;
|
||||
import com.projectkorra.projectkorra.ability.CoreAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.CollisionInitializer;
|
||||
import com.projectkorra.projectkorra.ability.util.CollisionManager;
|
||||
import com.projectkorra.projectkorra.ability.util.ComboManager;
|
||||
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager;
|
||||
import com.projectkorra.projectkorra.airbending.AirbendingManager;
|
||||
|
@ -33,6 +35,7 @@ public class ProjectKorra extends JavaPlugin {
|
|||
public static ProjectKorra plugin;
|
||||
public static Logger log;
|
||||
public static PKLogHandler handler;
|
||||
public static CollisionManager collisionManager;
|
||||
public static long time_step = 1;
|
||||
public Updater updater;
|
||||
|
||||
|
@ -59,6 +62,9 @@ public class ProjectKorra extends JavaPlugin {
|
|||
new MultiAbilityManager();
|
||||
new ComboManager();
|
||||
CoreAbility.registerAbilities();
|
||||
collisionManager = new CollisionManager();
|
||||
new CollisionInitializer(collisionManager).initializeCollisions();
|
||||
collisionManager.startCollisionDetection();
|
||||
|
||||
Preset.loadExternalPresets();
|
||||
|
||||
|
|
|
@ -2,11 +2,14 @@ package com.projectkorra.projectkorra.ability;
|
|||
|
||||
import com.projectkorra.projectkorra.Element;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.airbending.AirSpout;
|
||||
import com.projectkorra.projectkorra.airbending.Suffocate;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect.ParticleData;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -34,6 +37,16 @@ public abstract class AirAbility extends ElementalAbility {
|
|||
public Element getElement() {
|
||||
return Element.AIR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCollision(Collision collision) {
|
||||
super.handleCollision(collision);
|
||||
if (collision.isRemovingFirst()) {
|
||||
ParticleData particleData = (ParticleEffect.ParticleData) new ParticleEffect.BlockData(Material.WOOL, (byte) 0);
|
||||
ParticleEffect.BLOCK_CRACK.display(particleData, 1F, 1F, 1F, 0.1F, 10, collision.getLocationFirst(), 50);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Breaks a breathbendng hold on an entity or one a player is inflicting on an entity.
|
||||
|
@ -77,11 +90,15 @@ public abstract class AirAbility extends ElementalAbility {
|
|||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
* <p>
|
||||
* Checks whether a location is within an AirShield.
|
||||
*
|
||||
* @param loc The location to check
|
||||
* @return true If the location is inside an AirShield.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isWithinAirShield(Location loc) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("AirShield");
|
||||
|
@ -124,22 +141,30 @@ public abstract class AirAbility extends ElementalAbility {
|
|||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
* <p>
|
||||
* 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
|
||||
*/
|
||||
@Deprecated
|
||||
public static void removeAirSpouts(Location loc, double radius, Player source) {
|
||||
AirSpout.removeSpouts(loc, radius, source);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
* <p>
|
||||
* 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
|
||||
*/
|
||||
@Deprecated
|
||||
public static void removeAirSpouts(Location loc, Player source) {
|
||||
removeAirSpouts(loc, 1.5, source);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import java.util.concurrent.ConcurrentSkipListMap;
|
|||
import java.util.jar.JarFile;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
@ -29,6 +30,8 @@ import com.projectkorra.projectkorra.Element;
|
|||
import com.projectkorra.projectkorra.Element.SubElement;
|
||||
import com.projectkorra.projectkorra.ProjectKorra;
|
||||
import com.projectkorra.projectkorra.ability.util.AbilityLoader;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.ability.util.CollisionManager;
|
||||
import com.projectkorra.projectkorra.ability.util.ComboManager;
|
||||
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager;
|
||||
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager.MultiAbilityInfo;
|
||||
|
@ -40,9 +43,14 @@ import com.projectkorra.projectkorra.event.AbilityStartEvent;
|
|||
import sun.reflect.ReflectionFactory;
|
||||
|
||||
/**
|
||||
* CoreAbility provides default implementation of an Ability, including methods to control
|
||||
* the life cycle of a specific instance. CoreAbility also provides a system to load CoreAbilities
|
||||
* within a {@link JavaPlugin}, or located in an external {@link JarFile}.
|
||||
* CoreAbility provides default implementation of an Ability, including methods
|
||||
* to control the life cycle of a specific instance. CoreAbility also provides a
|
||||
* system to load CoreAbilities within a {@link JavaPlugin}, or located in an
|
||||
* external {@link JarFile}.
|
||||
* <p>
|
||||
* For {@link CollisionManager} and {@link Collision}, a CoreAbility may need to
|
||||
* override {@link #isCollidable()}, {@link #getCollisionRadius()},
|
||||
* {@link #handleCollision(Collision)}, and {@link #getLocations()}.
|
||||
*
|
||||
* @see #start()
|
||||
* @see #progress()
|
||||
|
@ -51,35 +59,41 @@ import sun.reflect.ReflectionFactory;
|
|||
* @see #registerPluginAbilities(JavaPlugin, String)
|
||||
*/
|
||||
public abstract class CoreAbility implements Ability {
|
||||
|
||||
|
||||
private static final Map<Class<? extends CoreAbility>, Map<UUID, Map<Integer, CoreAbility>>> INSTANCES = new ConcurrentHashMap<>();
|
||||
private static final Map<Class<? extends CoreAbility>, Set<CoreAbility>> INSTANCES_BY_CLASS = new ConcurrentHashMap<>();
|
||||
private static final Map<String, CoreAbility> ABILITIES_BY_NAME = new ConcurrentSkipListMap<>();
|
||||
|
||||
private static final Map<String, CoreAbility> ABILITIES_BY_NAME = new ConcurrentSkipListMap<>(); // preserves ordering
|
||||
private static final Map<Class<? extends CoreAbility>, CoreAbility> ABILITIES_BY_CLASS = new ConcurrentHashMap<>();
|
||||
private static final double DEFAULT_COLLISION_RADIUS = 0.3;
|
||||
|
||||
private static int idCounter;
|
||||
|
||||
protected long startTime;
|
||||
protected Player player;
|
||||
protected BendingPlayer bPlayer;
|
||||
|
||||
|
||||
private boolean started;
|
||||
private boolean removed;
|
||||
private int id;
|
||||
private long startTime;
|
||||
private long startTick;
|
||||
|
||||
static {
|
||||
idCounter = Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The default constructor is needed to create a fake instance of each CoreAbility via reflection
|
||||
* in {@link #registerAbilities()}. More specifically, {@link #registerPluginAbilities} calls
|
||||
* getDeclaredConstructor which is only usable with a public default constructor. Reflection lets us
|
||||
* create a list of all of the plugin's abilities when the plugin first loads.
|
||||
* The default constructor is needed to create a fake instance of each
|
||||
* CoreAbility via reflection in {@link #registerAbilities()}. More
|
||||
* specifically, {@link #registerPluginAbilities} calls
|
||||
* getDeclaredConstructor which is only usable with a public default
|
||||
* constructor. Reflection lets us create a list of all of the plugin's
|
||||
* abilities when the plugin first loads.
|
||||
*
|
||||
* @see #ABILITIES_BY_NAME
|
||||
* @see #getAbility(String)
|
||||
*/
|
||||
public CoreAbility() {}
|
||||
public CoreAbility() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new CoreAbility instance but does not start it.
|
||||
|
@ -91,13 +105,14 @@ public abstract class CoreAbility implements Ability {
|
|||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this.player = player;
|
||||
this.bPlayer = BendingPlayer.getBendingPlayer(player);
|
||||
this.startTime = System.currentTimeMillis();
|
||||
this.started = false;
|
||||
this.id = CoreAbility.idCounter;
|
||||
|
||||
this.startTick = getCurrentTick();
|
||||
|
||||
if (idCounter == Integer.MAX_VALUE) {
|
||||
idCounter = Integer.MIN_VALUE;
|
||||
} else {
|
||||
|
@ -106,9 +121,10 @@ public abstract class CoreAbility implements Ability {
|
|||
}
|
||||
|
||||
/**
|
||||
* Causes the ability to begin updating every tick by calling {@link #progress()}
|
||||
* until {@link #remove()} is called. This method cannot be overridden, and any code
|
||||
* that needs to be performed before start should be handled in the constructor.
|
||||
* Causes the ability to begin updating every tick by calling
|
||||
* {@link #progress()} until {@link #remove()} is called. This method cannot
|
||||
* be overridden, and any code that needs to be performed before start
|
||||
* should be handled in the constructor.
|
||||
*
|
||||
* @see #getStartTime()
|
||||
* @see #isStarted()
|
||||
|
@ -120,7 +136,7 @@ public abstract class CoreAbility implements Ability {
|
|||
}
|
||||
AbilityStartEvent event = new AbilityStartEvent(this);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if(event.isCancelled()) {
|
||||
if (event.isCancelled()) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
@ -144,11 +160,12 @@ public abstract class CoreAbility implements Ability {
|
|||
}
|
||||
|
||||
/**
|
||||
* Causes this CoreAbility instance to be removed, and {@link #progress} will no longer
|
||||
* be called every tick. If this method is overridden then the new method must call
|
||||
* <b>super.remove()</b>.
|
||||
* Causes this CoreAbility instance to be removed, and {@link #progress}
|
||||
* will no longer be called every tick. If this method is overridden then
|
||||
* the new method must call <b>super.remove()</b>.
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see #isRemoved()
|
||||
*/
|
||||
@Override
|
||||
|
@ -156,10 +173,10 @@ public abstract class CoreAbility implements Ability {
|
|||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Bukkit.getServer().getPluginManager().callEvent(new AbilityEndEvent(this));
|
||||
removed = true;
|
||||
|
||||
|
||||
Map<UUID, Map<Integer, CoreAbility>> classMap = INSTANCES.get(getClass());
|
||||
if (classMap != null) {
|
||||
Map<Integer, CoreAbility> playerMap = classMap.get(player.getUniqueId());
|
||||
|
@ -169,7 +186,7 @@ public abstract class CoreAbility implements Ability {
|
|||
classMap.remove(player.getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (classMap.size() == 0) {
|
||||
INSTANCES.remove(getClass());
|
||||
}
|
||||
|
@ -194,7 +211,8 @@ public abstract class CoreAbility implements Ability {
|
|||
}
|
||||
|
||||
/**
|
||||
* Removes every CoreAbility instance that has been started but not yet removed.
|
||||
* Removes every CoreAbility instance that has been started but not yet
|
||||
* removed.
|
||||
*/
|
||||
public static void removeAll() {
|
||||
for (Set<CoreAbility> setAbils : INSTANCES_BY_CLASS.values()) {
|
||||
|
@ -202,7 +220,7 @@ public abstract class CoreAbility implements Ability {
|
|||
abil.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (CoreAbility coreAbility : ABILITIES_BY_NAME.values()) {
|
||||
if (coreAbility instanceof AddonAbility) {
|
||||
AddonAbility addon = (AddonAbility) coreAbility;
|
||||
|
@ -212,8 +230,8 @@ public abstract class CoreAbility implements Ability {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns any T CoreAbility that has been started and not yet removed. May return null if
|
||||
* no such ability exists.
|
||||
* Returns any T CoreAbility that has been started and not yet removed. May
|
||||
* return null if no such ability exists.
|
||||
*
|
||||
* @param player the player that created the CoreAbility instance
|
||||
* @param clazz the class of the type of CoreAbility
|
||||
|
@ -226,16 +244,18 @@ public abstract class CoreAbility implements Ability {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a "fake" instance for the CoreAbility represented by abilityName. This method
|
||||
* does not look into CoreAbility instances that were created by Players, instead this
|
||||
* method looks at the CoreAbilities that were created via Reflection by {@link #registerAbilities()}
|
||||
* when the plugin was first loaded.
|
||||
* Returns a "fake" instance for the CoreAbility represented by abilityName.
|
||||
* This method does not look into CoreAbility instances that were created by
|
||||
* Players, instead this method looks at the CoreAbilities that were created
|
||||
* via Reflection by {@link #registerAbilities()} when the plugin was first
|
||||
* loaded.
|
||||
*
|
||||
* <p>These "fake" instances have a null player, but methods such as
|
||||
* {@link Ability#getName()}, and {@link Ability#getElement()} will still work, as will checking
|
||||
* the type of the ability with instanceof.
|
||||
* <p>
|
||||
* These "fake" instances have a null player, but methods such as
|
||||
* {@link Ability#getName()}, and {@link Ability#getElement()} will still
|
||||
* work, as will checking the type of the ability with instanceof.
|
||||
*
|
||||
* <p>
|
||||
* CoreAbility coreAbil = getAbility(someString); <br>
|
||||
|
@ -247,16 +267,28 @@ public abstract class CoreAbility implements Ability {
|
|||
public static CoreAbility getAbility(String abilityName) {
|
||||
return abilityName != null ? ABILITIES_BY_NAME.get(abilityName.toLowerCase()) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of "fake" instances for each ability that was loaded by {@link #registerAbilities()}
|
||||
* Returns a "fake" instance for a CoreAbility with the specific class.
|
||||
*
|
||||
* @param clazz the class for the type of CoreAbility to be returned
|
||||
* @return a "fake" CoreAbility instance or null
|
||||
*/
|
||||
public static CoreAbility getAbility(Class<? extends CoreAbility> clazz) {
|
||||
return clazz != null ? ABILITIES_BY_CLASS.get(clazz) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a list of "fake" instances for each ability that was loaded by
|
||||
* {@link #registerAbilities()}
|
||||
*/
|
||||
public static ArrayList<CoreAbility> getAbilities() {
|
||||
return new ArrayList<CoreAbility>(ABILITIES_BY_NAME.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Collection of all of the player created instances for a specific type of CoreAbility.
|
||||
* Returns a Collection of all of the player created instances for a
|
||||
* specific type of CoreAbility.
|
||||
*
|
||||
* @param clazz the class for the type of CoreAbilities
|
||||
* @return a Collection of real instances
|
||||
|
@ -270,7 +302,8 @@ public abstract class CoreAbility implements Ability {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a Collection of specific CoreAbility instances that were created by the specified player.
|
||||
* Returns a Collection of specific CoreAbility instances that were created
|
||||
* by the specified player.
|
||||
*
|
||||
* @param player the player that created the instances
|
||||
* @param clazz the class for the type of CoreAbilities
|
||||
|
@ -283,9 +316,10 @@ public abstract class CoreAbility implements Ability {
|
|||
}
|
||||
return (Collection<T>) INSTANCES.get(clazz).get(player.getUniqueId()).values();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an List of fake instances that were loaded by {@link #registerAbilities()} filtered by Element.
|
||||
* Returns an List of fake instances that were loaded by
|
||||
* {@link #registerAbilities()} filtered by Element.
|
||||
*
|
||||
* @param element the Element of the loaded abilities
|
||||
* @return a list of fake CoreAbility instances
|
||||
|
@ -306,7 +340,7 @@ public abstract class CoreAbility implements Ability {
|
|||
}
|
||||
return abilities;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the player has an active CoreAbility instance of type T.
|
||||
*
|
||||
|
@ -316,9 +350,10 @@ public abstract class CoreAbility implements Ability {
|
|||
public static <T extends CoreAbility> boolean hasAbility(Player player, Class<T> clazz) {
|
||||
return getAbility(player, clazz) != null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Set of all of the players that currently have an active instance of clazz.
|
||||
* Returns a Set of all of the players that currently have an active
|
||||
* instance of clazz.
|
||||
*
|
||||
* @param clazz the clazz for the type of CoreAbility
|
||||
*/
|
||||
|
@ -337,10 +372,10 @@ public abstract class CoreAbility implements Ability {
|
|||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Scans and loads plugin CoreAbilities, and Addon CoreAbilities that are located
|
||||
* in a Jar file inside of the /ProjectKorra/Abilities/ folder.
|
||||
* Scans and loads plugin CoreAbilities, and Addon CoreAbilities that are
|
||||
* located in a Jar file inside of the /ProjectKorra/Abilities/ folder.
|
||||
*/
|
||||
public static void registerAbilities() {
|
||||
ABILITIES_BY_NAME.clear();
|
||||
|
@ -350,9 +385,10 @@ public abstract class CoreAbility implements Ability {
|
|||
|
||||
/**
|
||||
* Scans a JavaPlugin and registers CoreAbility class files.
|
||||
*
|
||||
*
|
||||
* @param plugin a JavaPlugin containing CoreAbility class files
|
||||
* @param packagePrefix a prefix of the package name, used to increase performance
|
||||
* @param packagePrefix a prefix of the package name, used to increase
|
||||
* performance
|
||||
* @see #getAbilities()
|
||||
* @see #getAbility(String)
|
||||
*/
|
||||
|
@ -361,26 +397,26 @@ public abstract class CoreAbility implements Ability {
|
|||
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);;
|
||||
Constructor<?> intConstr = rf.newConstructorForSerialization(clazz, objDef);
|
||||
CoreAbility ability = (CoreAbility) clazz.cast(intConstr.newInstance());
|
||||
|
||||
if (ability == null || ability.getName() == null) {
|
||||
|
@ -393,6 +429,7 @@ public abstract class CoreAbility implements Ability {
|
|||
|
||||
String name = ability.getName();
|
||||
ABILITIES_BY_NAME.put(ability.getName().toLowerCase(), ability);
|
||||
ABILITIES_BY_CLASS.put(ability.getClass(), ability);
|
||||
|
||||
if (ability instanceof ComboAbility) {
|
||||
ComboAbility combo = (ComboAbility) ability;
|
||||
|
@ -407,25 +444,28 @@ public abstract class CoreAbility implements Ability {
|
|||
ComboManager.getAuthors().put(name, author);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ability instanceof MultiAbility) {
|
||||
MultiAbility multiAbil = (MultiAbility) ability;
|
||||
MultiAbilityManager.multiAbilityList.add(new MultiAbilityInfo(name, multiAbil.getMultiAbilities()));
|
||||
}
|
||||
|
||||
|
||||
if (ability instanceof AddonAbility) {
|
||||
AddonAbility addon = (AddonAbility) ability;
|
||||
addon.load();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Error e) {
|
||||
}
|
||||
catch (Exception e) {
|
||||
}
|
||||
catch (Error e) {
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Scans all of the Jar files inside of /ProjectKorra/folder and registers
|
||||
* all of the CoreAbility class files that were found.
|
||||
|
@ -441,10 +481,10 @@ public abstract class CoreAbility implements Ability {
|
|||
path.mkdir();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
|
@ -453,14 +493,14 @@ public abstract class CoreAbility implements Ability {
|
|||
plugin.getLogger().info(coreAbil.getName() + " is disabled");
|
||||
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) {
|
||||
|
@ -470,28 +510,37 @@ public abstract class CoreAbility implements Ability {
|
|||
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) {
|
||||
}
|
||||
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(name.toLowerCase());
|
||||
ABILITIES_BY_NAME.remove(name.toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public long getStartTick() {
|
||||
return startTick;
|
||||
}
|
||||
|
||||
public long getCurrentTick() {
|
||||
return player.getWorld().getFullTime();
|
||||
}
|
||||
|
||||
public boolean isStarted() {
|
||||
return started;
|
||||
}
|
||||
|
||||
|
||||
public boolean isRemoved() {
|
||||
return removed;
|
||||
}
|
||||
|
@ -503,37 +552,37 @@ public abstract class CoreAbility implements Ability {
|
|||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isHiddenAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
if (this instanceof AddonAbility) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
String elementName = getElement().getName();
|
||||
if (getElement() instanceof SubElement) {
|
||||
elementName = ((SubElement) getElement()).getParentElement().getName();
|
||||
}
|
||||
|
||||
|
||||
String tag = null;
|
||||
if (this instanceof ComboAbility) {
|
||||
tag = "Abilities." + elementName + "." + elementName + "Combo." + getName() + ".Enabled";
|
||||
tag = "Abilities." + elementName + "." + elementName + "Combo." + getName() + ".Enabled";
|
||||
} else {
|
||||
tag = "Abilities." + elementName + "." + getName() + ".Enabled";
|
||||
}
|
||||
|
||||
|
||||
if (getConfig().isBoolean(tag)) {
|
||||
return getConfig().getBoolean(tag);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
String elementName = getElement().getName();
|
||||
|
@ -547,36 +596,98 @@ public abstract class CoreAbility implements Ability {
|
|||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used by the CollisionManager to check if two instances can collide with
|
||||
* each other. For example, an EarthBlast is not collidable right when the
|
||||
* person selects a source block, but it is collidable once the block begins
|
||||
* traveling.
|
||||
*
|
||||
* @return true if the instance is currently collidable
|
||||
* @see CollisionManager
|
||||
*/
|
||||
public boolean isCollidable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The radius for collision of the ability instance. Some circular abilities
|
||||
* are better represented with 1 single Location with a small or large
|
||||
* radius, such as AirShield, FireShield, EarthSmash, WaterManipulation,
|
||||
* EarthBlast, etc. Some abilities consist of multiple Locations with small
|
||||
* radiuses, such as AirSpout, WaterSpout, Torrent, RaiseEarth, AirSwipe,
|
||||
* FireKick, etc.
|
||||
*
|
||||
* @return the radius for a location returned by {@link #getLocations()}
|
||||
* @see CollisionManager
|
||||
*/
|
||||
public double getCollisionRadius() {
|
||||
return DEFAULT_COLLISION_RADIUS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this ability instance collides with another. Some abilities
|
||||
* may want advanced behavior on a Collision; e.g. FireCombos only remove
|
||||
* the stream that was hit rather than the entire ability.
|
||||
* <p>
|
||||
* collision.getAbilitySecond() - the ability that we are colliding with
|
||||
* collision.isRemovingFirst() - if this ability should be removed
|
||||
* <p>
|
||||
* This ability should only worry about itself because handleCollision will
|
||||
* be called for the other ability instance as well.
|
||||
*
|
||||
* @param collision with data about the other ability instance
|
||||
* @see CollisionManager
|
||||
*/
|
||||
public void handleCollision(Collision collision) {
|
||||
if (collision.isRemovingFirst()) {
|
||||
remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A List of Locations used to represent the ability. Some abilities might
|
||||
* just be 1 Location with a radius, while some might be multiple Locations
|
||||
* with small radiuses.
|
||||
*
|
||||
* @return a List of the ability's locations
|
||||
* @see CollisionManager
|
||||
*/
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
locations.add(getLocation());
|
||||
return locations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current FileConfiguration for the plugin
|
||||
*/
|
||||
public static FileConfiguration getConfig() {
|
||||
return ConfigManager.getConfig();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the language.yml for the plugin
|
||||
*/
|
||||
public static FileConfiguration getLanguageConfig() {
|
||||
return ConfigManager.languageConfig.get();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a String used to debug potential CoreAbility memory that can be caused
|
||||
* by a developer forgetting to call {@link #remove()}
|
||||
* Returns a String used to debug potential CoreAbility memory that can be
|
||||
* caused by a developer forgetting to call {@link #remove()}
|
||||
*/
|
||||
public static String getDebugString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int playerCounter = 0;
|
||||
HashMap<String, Integer> classCounter = new HashMap<>();
|
||||
|
||||
|
||||
for (Map<UUID, Map<Integer, CoreAbility>> map1 : INSTANCES.values()) {
|
||||
playerCounter++;
|
||||
for (Map<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 {
|
||||
|
@ -585,7 +696,7 @@ public abstract class CoreAbility implements Ability {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (Set<CoreAbility> set : INSTANCES_BY_CLASS.values()) {
|
||||
for (CoreAbility coreAbil : set) {
|
||||
String simpleName = coreAbil.getClass().getSimpleName();
|
||||
|
@ -596,7 +707,7 @@ public abstract class CoreAbility implements Ability {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sb.append("Class->UUID's in memory: " + playerCounter + "\n");
|
||||
sb.append("Abilities in memory:\n");
|
||||
for (String className : classCounter.keySet()) {
|
||||
|
@ -604,4 +715,9 @@ public abstract class CoreAbility implements Ability {
|
|||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static double getDefaultCollisionRadius() {
|
||||
return DEFAULT_COLLISION_RADIUS;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.bukkit.util.Vector;
|
|||
import com.projectkorra.projectkorra.BendingPlayer;
|
||||
import com.projectkorra.projectkorra.Element;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.configuration.ConfigManager;
|
||||
import com.projectkorra.projectkorra.earthbending.EarthPassive;
|
||||
import com.projectkorra.projectkorra.earthbending.LavaFlow;
|
||||
|
@ -30,6 +31,7 @@ import com.projectkorra.projectkorra.firebending.Illumination;
|
|||
import com.projectkorra.projectkorra.util.BlockSource;
|
||||
import com.projectkorra.projectkorra.util.Information;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect.ParticleData;
|
||||
import com.projectkorra.projectkorra.util.TempBlock;
|
||||
|
||||
public abstract class EarthAbility extends ElementalAbility {
|
||||
|
@ -82,6 +84,15 @@ public abstract class EarthAbility extends ElementalAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCollision(Collision collision) {
|
||||
super.handleCollision(collision);
|
||||
if (collision.isRemovingFirst()) {
|
||||
ParticleData particleData = (ParticleEffect.ParticleData) new ParticleEffect.BlockData(Material.DIRT, (byte) 0);
|
||||
ParticleEffect.BLOCK_CRACK.display(particleData, 1F, 1F, 1F, 0.1F, 10, collision.getLocationFirst(), 50);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isEarthbendable(Material material) {
|
||||
return isEarth(material) || isMetal(material) || isSand(material) || isLava(material);
|
||||
}
|
||||
|
|
|
@ -19,11 +19,13 @@ import org.bukkit.inventory.ItemStack;
|
|||
|
||||
import com.projectkorra.projectkorra.Element;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.configuration.ConfigManager;
|
||||
import com.projectkorra.projectkorra.firebending.BlazeArc;
|
||||
import com.projectkorra.projectkorra.firebending.HeatControl;
|
||||
import com.projectkorra.projectkorra.util.Information;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect.ParticleData;
|
||||
import com.projectkorra.rpg.RPGMethods;
|
||||
|
||||
public abstract class FireAbility extends ElementalAbility {
|
||||
|
@ -60,6 +62,15 @@ public abstract class FireAbility extends ElementalAbility {
|
|||
public Element getElement() {
|
||||
return Element.FIRE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCollision(Collision collision) {
|
||||
super.handleCollision(collision);
|
||||
if (collision.isRemovingFirst()) {
|
||||
ParticleData particleData = (ParticleEffect.ParticleData) new ParticleEffect.BlockData(Material.FIRE, (byte) 0);
|
||||
ParticleEffect.BLOCK_CRACK.display(particleData, 1F, 1F, 1F, 0.1F, 10, collision.getLocationFirst(), 50);
|
||||
}
|
||||
}
|
||||
|
||||
public double getDayFactor(double value) {
|
||||
return player != null ? getDayFactor(value, player.getWorld()) : 1;
|
||||
|
@ -140,11 +151,15 @@ public abstract class FireAbility extends ElementalAbility {
|
|||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
* <p>
|
||||
* Checks whether a location is within a FireShield.
|
||||
*
|
||||
* @param loc The location to check
|
||||
* @return true If the location is inside a FireShield.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isWithinFireShield(Location loc) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("FireShield");
|
||||
|
|
|
@ -3,8 +3,11 @@ package com.projectkorra.projectkorra.ability;
|
|||
import com.projectkorra.projectkorra.BendingPlayer;
|
||||
import com.projectkorra.projectkorra.Element;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.util.BlockSource;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect;
|
||||
import com.projectkorra.projectkorra.util.TempBlock;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect.ParticleData;
|
||||
import com.projectkorra.projectkorra.waterbending.PhaseChangeFreeze;
|
||||
import com.projectkorra.projectkorra.waterbending.PhaseChangeMelt;
|
||||
import com.projectkorra.projectkorra.waterbending.SurgeWall;
|
||||
|
@ -75,6 +78,15 @@ public abstract class WaterAbility extends ElementalAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCollision(Collision collision) {
|
||||
super.handleCollision(collision);
|
||||
if (collision.isRemovingFirst()) {
|
||||
ParticleData particleData = (ParticleEffect.ParticleData) new ParticleEffect.BlockData(Material.WATER, (byte) 0);
|
||||
ParticleEffect.BLOCK_CRACK.display(particleData, 1F, 1F, 1F, 0.1F, 10, collision.getLocationFirst(), 50);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isIcebendable(Block block) {
|
||||
return isIcebendable(block.getType());
|
||||
}
|
||||
|
@ -301,22 +313,30 @@ public abstract class WaterAbility extends ElementalAbility {
|
|||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
* <p>
|
||||
* 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
|
||||
*/
|
||||
@Deprecated
|
||||
public static void removeWaterSpouts(Location loc, double radius, Player source) {
|
||||
WaterSpout.removeSpouts(loc, radius, source);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
* <p>
|
||||
* 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
|
||||
*/
|
||||
@Deprecated
|
||||
public static void removeWaterSpouts(Location loc, Player source) {
|
||||
removeWaterSpouts(loc, 1.5, source);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
package com.projectkorra.projectkorra.ability.util;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
||||
import com.projectkorra.projectkorra.ability.CoreAbility;
|
||||
|
||||
/**
|
||||
* A Collision is used to represent the collision between two CoreAbility
|
||||
* objects.
|
||||
*
|
||||
* @see CollisionManager
|
||||
*/
|
||||
public class Collision {
|
||||
private CoreAbility abilityFirst;
|
||||
private CoreAbility abilitySecond;
|
||||
private boolean removingFirst;
|
||||
private boolean removingSecond;
|
||||
private Location locationFirst;
|
||||
private Location locationSecond;
|
||||
|
||||
public Collision(CoreAbility abilityFirst, CoreAbility abilitySecond, boolean removingFirst, boolean removingSecond, Location locationFirst, Location locationSecond) {
|
||||
if (abilityFirst == null || abilitySecond == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.abilityFirst = abilityFirst;
|
||||
this.abilitySecond = abilitySecond;
|
||||
this.removingFirst = removingFirst;
|
||||
this.removingSecond = removingSecond;
|
||||
this.locationFirst = locationFirst;
|
||||
this.locationSecond = locationSecond;
|
||||
}
|
||||
|
||||
public Collision(CoreAbility abilityFirst, CoreAbility abilitySecond, boolean removingFirst, boolean removingSecond) {
|
||||
this(abilityFirst, abilitySecond, removingFirst, removingSecond, null, null);
|
||||
}
|
||||
|
||||
public CoreAbility getAbilityFirst() {
|
||||
return abilityFirst;
|
||||
}
|
||||
|
||||
public void setAbilityFirst(CoreAbility abilityFirst) {
|
||||
this.abilityFirst = abilityFirst;
|
||||
}
|
||||
|
||||
public CoreAbility getAbilitySecond() {
|
||||
return abilitySecond;
|
||||
}
|
||||
|
||||
public void setAbilitySecond(CoreAbility abilitySecond) {
|
||||
this.abilitySecond = abilitySecond;
|
||||
}
|
||||
|
||||
public boolean isRemovingFirst() {
|
||||
return removingFirst;
|
||||
}
|
||||
|
||||
public void setRemovingFirst(boolean removingFirst) {
|
||||
this.removingFirst = removingFirst;
|
||||
}
|
||||
|
||||
public boolean isRemovingSecond() {
|
||||
return removingSecond;
|
||||
}
|
||||
|
||||
public void setRemovingSecond(boolean removingSecond) {
|
||||
this.removingSecond = removingSecond;
|
||||
}
|
||||
|
||||
public Location getLocationFirst() {
|
||||
return locationFirst;
|
||||
}
|
||||
|
||||
public void setLocationFirst(Location locationFirst) {
|
||||
this.locationFirst = locationFirst;
|
||||
}
|
||||
|
||||
public Location getLocationSecond() {
|
||||
return locationSecond;
|
||||
}
|
||||
|
||||
public void setLocationSecond(Location locationSecond) {
|
||||
this.locationSecond = locationSecond;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
package com.projectkorra.projectkorra.ability.util;
|
||||
|
||||
import com.projectkorra.projectkorra.ability.CoreAbility;
|
||||
import com.projectkorra.projectkorra.airbending.AirBlast;
|
||||
import com.projectkorra.projectkorra.airbending.AirBubble;
|
||||
import com.projectkorra.projectkorra.airbending.AirCombo;
|
||||
import com.projectkorra.projectkorra.airbending.AirCombo.AirStream;
|
||||
import com.projectkorra.projectkorra.airbending.AirCombo.AirSweep;
|
||||
import com.projectkorra.projectkorra.airbending.AirFlight;
|
||||
import com.projectkorra.projectkorra.airbending.AirScooter;
|
||||
import com.projectkorra.projectkorra.airbending.AirShield;
|
||||
import com.projectkorra.projectkorra.airbending.AirSpout;
|
||||
import com.projectkorra.projectkorra.airbending.AirSuction;
|
||||
import com.projectkorra.projectkorra.airbending.AirSwipe;
|
||||
import com.projectkorra.projectkorra.airbending.Suffocate;
|
||||
import com.projectkorra.projectkorra.airbending.Tornado;
|
||||
import com.projectkorra.projectkorra.earthbending.Catapult;
|
||||
import com.projectkorra.projectkorra.earthbending.Collapse;
|
||||
import com.projectkorra.projectkorra.earthbending.EarthArmor;
|
||||
import com.projectkorra.projectkorra.earthbending.EarthBlast;
|
||||
import com.projectkorra.projectkorra.earthbending.EarthSmash;
|
||||
import com.projectkorra.projectkorra.earthbending.EarthTunnel;
|
||||
import com.projectkorra.projectkorra.earthbending.LavaFlow;
|
||||
import com.projectkorra.projectkorra.earthbending.RaiseEarth;
|
||||
import com.projectkorra.projectkorra.earthbending.Ripple;
|
||||
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.FireBlastCharged;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo.FireKick;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo.FireSpin;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo.FireWheel;
|
||||
import com.projectkorra.projectkorra.firebending.FireJet;
|
||||
import com.projectkorra.projectkorra.firebending.FireShield;
|
||||
import com.projectkorra.projectkorra.firebending.Lightning;
|
||||
import com.projectkorra.projectkorra.firebending.WallOfFire;
|
||||
import com.projectkorra.projectkorra.waterbending.Bloodbending;
|
||||
import com.projectkorra.projectkorra.waterbending.HealingWaters;
|
||||
import com.projectkorra.projectkorra.waterbending.IceBlast;
|
||||
import com.projectkorra.projectkorra.waterbending.IceSpikeBlast;
|
||||
import com.projectkorra.projectkorra.waterbending.OctopusForm;
|
||||
import com.projectkorra.projectkorra.waterbending.PlantArmor;
|
||||
import com.projectkorra.projectkorra.waterbending.SurgeWall;
|
||||
import com.projectkorra.projectkorra.waterbending.SurgeWave;
|
||||
import com.projectkorra.projectkorra.waterbending.Torrent;
|
||||
import com.projectkorra.projectkorra.waterbending.TorrentWave;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterBubble;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterCombo;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterCombo.IceBullet;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterCombo.IceWave;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterManipulation;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterSpout;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterSpoutWave;
|
||||
|
||||
/**
|
||||
* CollisionInitializer is used to create the default Collisions for a given
|
||||
* CollisionManager.
|
||||
*
|
||||
* @see Collision
|
||||
* @see CollisionManager
|
||||
*/
|
||||
public class CollisionInitializer {
|
||||
|
||||
private CollisionManager cm;
|
||||
|
||||
public CollisionInitializer(CollisionManager cm) {
|
||||
this.cm = cm;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void initializeCollisions() {
|
||||
CoreAbility airBlast = CoreAbility.getAbility(AirBlast.class);
|
||||
CoreAbility airBubble = CoreAbility.getAbility(AirBubble.class);
|
||||
CoreAbility airCombo = CoreAbility.getAbility(AirCombo.class);
|
||||
CoreAbility airFlight = CoreAbility.getAbility(AirFlight.class);
|
||||
CoreAbility airScooter = CoreAbility.getAbility(AirScooter.class);
|
||||
CoreAbility airShield = CoreAbility.getAbility(AirShield.class);
|
||||
CoreAbility airSpout = CoreAbility.getAbility(AirSpout.class);
|
||||
CoreAbility airStream = CoreAbility.getAbility(AirStream.class);
|
||||
CoreAbility airSuction = CoreAbility.getAbility(AirSuction.class);
|
||||
CoreAbility airSweep = CoreAbility.getAbility(AirSweep.class);
|
||||
CoreAbility airSwipe = CoreAbility.getAbility(AirSwipe.class);
|
||||
CoreAbility suffocate = CoreAbility.getAbility(Suffocate.class);
|
||||
CoreAbility tornado = CoreAbility.getAbility(Tornado.class);
|
||||
|
||||
CoreAbility catapult = CoreAbility.getAbility(Catapult.class);
|
||||
CoreAbility collapse = CoreAbility.getAbility(Collapse.class);
|
||||
CoreAbility earthArmor = CoreAbility.getAbility(EarthArmor.class);
|
||||
CoreAbility earthBlast = CoreAbility.getAbility(EarthBlast.class);
|
||||
CoreAbility earthSmash = CoreAbility.getAbility(EarthSmash.class);
|
||||
CoreAbility earthTunnel = CoreAbility.getAbility(EarthTunnel.class);
|
||||
CoreAbility lavaFlow = CoreAbility.getAbility(LavaFlow.class);
|
||||
CoreAbility raiseEarth = CoreAbility.getAbility(RaiseEarth.class);
|
||||
CoreAbility ripple = CoreAbility.getAbility(Ripple.class);
|
||||
CoreAbility sandSpout = CoreAbility.getAbility(SandSpout.class);
|
||||
|
||||
CoreAbility blazeArc = CoreAbility.getAbility(BlazeArc.class);
|
||||
CoreAbility combustion = CoreAbility.getAbility(Combustion.class);
|
||||
CoreAbility fireBlast = CoreAbility.getAbility(FireBlast.class);
|
||||
CoreAbility fireBlastCharged = CoreAbility.getAbility(FireBlastCharged.class);
|
||||
CoreAbility fireCombo = CoreAbility.getAbility(FireCombo.class);
|
||||
CoreAbility fireJet = CoreAbility.getAbility(FireJet.class);
|
||||
CoreAbility fireKick = CoreAbility.getAbility(FireKick.class);
|
||||
CoreAbility fireSpin = CoreAbility.getAbility(FireSpin.class);
|
||||
CoreAbility fireWheel = CoreAbility.getAbility(FireWheel.class);
|
||||
CoreAbility fireShield = CoreAbility.getAbility(FireShield.class);
|
||||
CoreAbility lightning = CoreAbility.getAbility(Lightning.class);
|
||||
CoreAbility wallOfFire = CoreAbility.getAbility(WallOfFire.class);
|
||||
|
||||
CoreAbility bloodbending = CoreAbility.getAbility(Bloodbending.class);
|
||||
CoreAbility healingWaters = CoreAbility.getAbility(HealingWaters.class);
|
||||
CoreAbility iceBlast = CoreAbility.getAbility(IceBlast.class);
|
||||
CoreAbility iceBullet = CoreAbility.getAbility(IceBullet.class);
|
||||
CoreAbility iceWave = CoreAbility.getAbility(IceWave.class);
|
||||
CoreAbility iceSpikeBlast = CoreAbility.getAbility(IceSpikeBlast.class);
|
||||
CoreAbility octopusForm = CoreAbility.getAbility(OctopusForm.class);
|
||||
CoreAbility plantArmor = CoreAbility.getAbility(PlantArmor.class);
|
||||
CoreAbility surgeWall = CoreAbility.getAbility(SurgeWall.class);
|
||||
CoreAbility surgeWave = CoreAbility.getAbility(SurgeWave.class);
|
||||
CoreAbility torrent = CoreAbility.getAbility(Torrent.class);
|
||||
CoreAbility torrentWave = CoreAbility.getAbility(TorrentWave.class);
|
||||
CoreAbility waterBubble = CoreAbility.getAbility(WaterBubble.class);
|
||||
CoreAbility waterCombo = CoreAbility.getAbility(WaterCombo.class);
|
||||
CoreAbility waterManipulation = CoreAbility.getAbility(WaterManipulation.class);
|
||||
CoreAbility waterSpout = CoreAbility.getAbility(WaterSpout.class);
|
||||
CoreAbility waterSpoutWave = CoreAbility.getAbility(WaterSpoutWave.class);
|
||||
|
||||
CoreAbility[] smallDamageAbils = { airSwipe, earthBlast, waterManipulation, fireBlast, combustion, blazeArc };
|
||||
CoreAbility[] abilitiesThatRemoveSmall = { earthSmash, airShield, airCombo, fireCombo, waterCombo, fireBlastCharged };
|
||||
CoreAbility[] abilsThatRemoveSpouts = { airSwipe, earthBlast, waterManipulation, fireBlast, fireBlastCharged, earthSmash, fireCombo, airCombo, waterCombo };
|
||||
CoreAbility[] damageComboAbils = { fireKick, fireSpin, fireWheel, airSweep, iceBullet };
|
||||
|
||||
// All small damaging abilities block each other
|
||||
for (int i = 0; i < smallDamageAbils.length; i++) {
|
||||
for (int j = i; j < smallDamageAbils.length; j++) {
|
||||
cm.add(new Collision(smallDamageAbils[i], smallDamageAbils[j], true, true));
|
||||
}
|
||||
}
|
||||
|
||||
// All combos block each other
|
||||
for (int i = 0; i < damageComboAbils.length; i++) {
|
||||
for (int j = i; j < damageComboAbils.length; j++) {
|
||||
cm.add(new Collision(damageComboAbils[i], damageComboAbils[j], true, true));
|
||||
}
|
||||
}
|
||||
|
||||
// These abilities remove all small damaging abilities
|
||||
for (CoreAbility abilThatRemoves : abilitiesThatRemoveSmall) {
|
||||
for (CoreAbility smallDamageAbil : smallDamageAbils) {
|
||||
cm.add(new Collision(abilThatRemoves, smallDamageAbil, false, true));
|
||||
}
|
||||
}
|
||||
|
||||
for (CoreAbility spoutDestroyAbil : abilsThatRemoveSpouts) {
|
||||
cm.add(new Collision(spoutDestroyAbil, airSpout, false, true));
|
||||
cm.add(new Collision(spoutDestroyAbil, waterSpout, false, true));
|
||||
cm.add(new Collision(spoutDestroyAbil, sandSpout, false, true));
|
||||
}
|
||||
|
||||
cm.add(new Collision(airShield, airBlast, false, true));
|
||||
cm.add(new Collision(airShield, airSuction, false, true));
|
||||
cm.add(new Collision(airShield, airStream, false, true));
|
||||
for (CoreAbility comboAbil : damageComboAbils) {
|
||||
cm.add(new Collision(airShield, comboAbil, false, true));
|
||||
}
|
||||
|
||||
cm.add(new Collision(fireShield, fireBlast, false, true));
|
||||
cm.add(new Collision(fireShield, fireBlastCharged, false, true));
|
||||
cm.add(new Collision(fireShield, waterManipulation, false, true));
|
||||
cm.add(new Collision(fireShield, earthBlast, false, true));
|
||||
cm.add(new Collision(fireShield, airSweep, false, true));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
package com.projectkorra.projectkorra.ability.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import com.projectkorra.projectkorra.ProjectKorra;
|
||||
import com.projectkorra.projectkorra.ability.CoreAbility;
|
||||
import com.projectkorra.projectkorra.event.AbilityCollisionEvent;
|
||||
|
||||
/**
|
||||
* A CollisionManager is used to monitor possible collisions between all
|
||||
* CoreAbilities. Use {@link #add(Collision)} to begin monitoring for collision
|
||||
* between two abilities, as shown in {@link CollisionInitializer}.
|
||||
* <p>
|
||||
* For a CoreAbility to collide properly, the {@link CoreAbility#isCollidable()}
|
||||
* , {@link CoreAbility#getCollisionRadius()},
|
||||
* {@link CoreAbility#getLocations()}, and {@link CoreAbility#handleCollision()}
|
||||
* should be overridden if necessary.
|
||||
* <p>
|
||||
* During a Collision the {@link AbilityCollisionEvent} is called, then if not
|
||||
* cancelled, abilityFirst.handleCollision, and finally
|
||||
* abilitySecond.handleCollision.
|
||||
*/
|
||||
public class CollisionManager {
|
||||
|
||||
/*
|
||||
* If true an ability instance can remove multiple other instances on a
|
||||
* single tick. e.g. 3 Colliding WaterManipulations can all be removed
|
||||
* instantly, rather than just 2.
|
||||
*/
|
||||
private boolean removeMultipleInstances;
|
||||
|
||||
/*
|
||||
* The amount of ticks in between checking for collisions. Higher values
|
||||
* reduce lag but are less accurate in detection.
|
||||
*/
|
||||
private long detectionDelay;
|
||||
|
||||
/*
|
||||
* The amount of ticks that an ability must be alive before considered as
|
||||
* collidable. Some CoreAbilities are started even though they will be
|
||||
* removed on the next tick in progress, in these cases we do not want to
|
||||
* consider those abilities for collision.
|
||||
*/
|
||||
private long minAbilityTickAlive;
|
||||
|
||||
/*
|
||||
* Used for efficiency. The distance that we can guarantee that two
|
||||
* abilities will not collide so that we can stop comparing locations early.
|
||||
* For example, two Torrents that are thousands of blocks apart should not
|
||||
* be fully checked.
|
||||
*/
|
||||
private double certainNoCollisionDistance;
|
||||
|
||||
private ArrayList<Collision> collisions;
|
||||
private BukkitRunnable detectionRunnable;
|
||||
|
||||
public CollisionManager() {
|
||||
this.removeMultipleInstances = true;
|
||||
this.detectionDelay = 1;
|
||||
this.minAbilityTickAlive = 3;
|
||||
this.certainNoCollisionDistance = 100;
|
||||
collisions = new ArrayList<>();
|
||||
}
|
||||
|
||||
private void detectCollisions() {
|
||||
HashMap<CoreAbility, List<Location>> locationsCache = new HashMap<>();
|
||||
|
||||
for (Collision collision : collisions) {
|
||||
Collection<? extends CoreAbility> instancesFirst = CoreAbility.getAbilities(collision.getAbilityFirst().getClass());
|
||||
Collection<? extends CoreAbility> instancesSecond = CoreAbility.getAbilities(collision.getAbilitySecond().getClass());
|
||||
HashSet<CoreAbility> alreadyCollided = new HashSet<CoreAbility>();
|
||||
double certainNoCollisionDistSquared = Math.pow(certainNoCollisionDistance, 2);
|
||||
|
||||
for (CoreAbility abilityFirst : instancesFirst) {
|
||||
if (abilityFirst.getPlayer() == null || alreadyCollided.contains(abilityFirst) || !abilityFirst.isCollidable() || abilityFirst.getCurrentTick() - abilityFirst.getStartTick() < minAbilityTickAlive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!locationsCache.containsKey(abilityFirst)) {
|
||||
locationsCache.put(abilityFirst, abilityFirst.getLocations());
|
||||
}
|
||||
List<Location> locationsFirst = locationsCache.get(abilityFirst);
|
||||
if (locationsFirst == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (CoreAbility abilitySecond : instancesSecond) {
|
||||
if (abilitySecond.getPlayer() == null || alreadyCollided.contains(abilitySecond) || !abilitySecond.isCollidable() || abilitySecond.getCurrentTick() - abilitySecond.getStartTick() < minAbilityTickAlive) {
|
||||
continue;
|
||||
} else if (abilityFirst.getPlayer().equals(abilitySecond.getPlayer())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!locationsCache.containsKey(abilitySecond)) {
|
||||
locationsCache.put(abilitySecond, abilitySecond.getLocations());
|
||||
}
|
||||
List<Location> locationsSecond = locationsCache.get(abilitySecond);
|
||||
if (locationsSecond == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean collided = false;
|
||||
boolean certainNoCollision = false; // Used for efficiency
|
||||
Location locationFirst = null;
|
||||
Location locationSecond = null;
|
||||
double requiredDist = abilityFirst.getCollisionRadius() + abilitySecond.getCollisionRadius();
|
||||
double requiredDistSquared = Math.pow(requiredDist, 2);
|
||||
|
||||
for (int i = 0; i < locationsFirst.size(); i++) {
|
||||
locationFirst = locationsFirst.get(i);
|
||||
if (locationFirst == null) {
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < locationsSecond.size(); j++) {
|
||||
locationSecond = locationsSecond.get(j);
|
||||
if (locationSecond == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double distSquared = locationFirst.distanceSquared(locationSecond);
|
||||
if (distSquared <= requiredDistSquared) {
|
||||
collided = true;
|
||||
break;
|
||||
} else if (distSquared >= certainNoCollisionDistSquared) {
|
||||
certainNoCollision = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (collided || certainNoCollision) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (collided) {
|
||||
Collision forwardCollision = new Collision(abilityFirst, abilitySecond, collision.isRemovingFirst(), collision.isRemovingSecond(), locationFirst, locationSecond);
|
||||
Collision reverseCollision = new Collision(abilitySecond, abilityFirst, collision.isRemovingSecond(), collision.isRemovingFirst(), locationSecond, locationFirst);
|
||||
AbilityCollisionEvent event = new AbilityCollisionEvent(forwardCollision);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
continue;
|
||||
}
|
||||
abilityFirst.handleCollision(forwardCollision);
|
||||
abilitySecond.handleCollision(reverseCollision);
|
||||
if (!removeMultipleInstances) {
|
||||
alreadyCollided.add(abilityFirst);
|
||||
alreadyCollided.add(abilitySecond);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new Collision to the CollisionManager so that two abilities can be
|
||||
* checked for collisions.
|
||||
*
|
||||
* @param collision a Collision containing two CoreAbility classes
|
||||
*/
|
||||
public void add(Collision collision) {
|
||||
collisions.add(collision);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins a BukkitRunnable to check for Collisions.
|
||||
*/
|
||||
public void startCollisionDetection() {
|
||||
stopCollisionDetection();
|
||||
detectionRunnable = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
detectCollisions();
|
||||
}
|
||||
};
|
||||
detectionRunnable.runTaskTimer(ProjectKorra.plugin, 0L, detectionDelay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the collision detecting BukkitRunnable.
|
||||
*/
|
||||
public void stopCollisionDetection() {
|
||||
if (detectionRunnable != null) {
|
||||
detectionRunnable.cancel();
|
||||
detectionRunnable = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRemoveMultipleInstances() {
|
||||
return removeMultipleInstances;
|
||||
}
|
||||
|
||||
public void setRemoveMultipleInstances(boolean removeMultipleInstances) {
|
||||
this.removeMultipleInstances = removeMultipleInstances;
|
||||
}
|
||||
|
||||
public long getDetectionDelay() {
|
||||
return detectionDelay;
|
||||
}
|
||||
|
||||
public void setDetectionDelay(long detectionDelay) {
|
||||
this.detectionDelay = detectionDelay;
|
||||
}
|
||||
|
||||
public long getMinAbilityTickAlive() {
|
||||
return minAbilityTickAlive;
|
||||
}
|
||||
|
||||
public void setMinAbilityTickAlive(long minAbilityTickAlive) {
|
||||
this.minAbilityTickAlive = minAbilityTickAlive;
|
||||
}
|
||||
|
||||
public double getCertainNoCollisionDistance() {
|
||||
return certainNoCollisionDistance;
|
||||
}
|
||||
|
||||
public void setCertainNoCollisionDistance(double certainNoCollisionDistance) {
|
||||
this.certainNoCollisionDistance = certainNoCollisionDistance;
|
||||
}
|
||||
|
||||
public ArrayList<Collision> getCollisions() {
|
||||
return collisions;
|
||||
}
|
||||
|
||||
public void setCollisions(ArrayList<Collision> collisions) {
|
||||
this.collisions = collisions;
|
||||
}
|
||||
|
||||
public BukkitRunnable getDetectionRunnable() {
|
||||
return detectionRunnable;
|
||||
}
|
||||
|
||||
public void setDetectionRunnable(BukkitRunnable detectionRunnable) {
|
||||
this.detectionRunnable = detectionRunnable;
|
||||
}
|
||||
|
||||
}
|
|
@ -15,12 +15,22 @@ import com.projectkorra.projectkorra.Element.SubElement;
|
|||
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.airbending.AirCombo.AirStream;
|
||||
import com.projectkorra.projectkorra.airbending.AirCombo.AirSweep;
|
||||
import com.projectkorra.projectkorra.airbending.AirCombo.Twister;
|
||||
import com.projectkorra.projectkorra.chiblocking.ChiCombo.Immobilize;
|
||||
import com.projectkorra.projectkorra.configuration.ConfigManager;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo.FireKick;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo.FireSpin;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo.FireWheel;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo.JetBlast;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo.JetBlaze;
|
||||
import com.projectkorra.projectkorra.util.ClickType;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterCombo;
|
||||
import com.projectkorra.projectkorra.util.ReflectionHandler;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterCombo.IceBullet;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterCombo.IceBulletLeftClick;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterCombo.IceBulletRightClick;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterCombo.IceWave;
|
||||
|
||||
public class ComboManager {
|
||||
|
||||
|
@ -42,7 +52,7 @@ public class ComboManager {
|
|||
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));
|
||||
COMBO_ABILITIES.put("FireKick", new ComboAbilityInfo("FireKick", fireKick, FireKick.class));
|
||||
DESCRIPTIONS.put("FireKick", ConfigManager.languageConfig.get().getString("Abilities.Fire.Combo.FireKick.Description"));
|
||||
INSTRUCTIONS.put("FireKick", "FireBlast > FireBlast > (Hold Shift) > FireBlast.");
|
||||
}
|
||||
|
@ -54,7 +64,7 @@ public class ComboManager {
|
|||
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));
|
||||
COMBO_ABILITIES.put("FireSpin", new ComboAbilityInfo("FireSpin", fireSpin, FireSpin.class));
|
||||
DESCRIPTIONS.put("FireSpin", ConfigManager.languageConfig.get().getString("Abilities.Fire.Combo.FireSpin.Description"));
|
||||
INSTRUCTIONS.put("FireSpin", "FireBlast > FireBlast > FireShield > (Tap Shift).");
|
||||
}
|
||||
|
@ -68,7 +78,7 @@ public class ComboManager {
|
|||
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));
|
||||
COMBO_ABILITIES.put("JetBlast", new ComboAbilityInfo("JetBlast", jetBlast, JetBlast.class));
|
||||
DESCRIPTIONS.put("JetBlast", ConfigManager.languageConfig.get().getString("Abilities.Fire.Combo.JetBlast.Description"));
|
||||
INSTRUCTIONS.put("JetBlast", "FireJet (Tap Shift) > FireJet (Tap Shift) > FireShield (Tap Shift) > FireJet.");
|
||||
}
|
||||
|
@ -82,7 +92,7 @@ public class ComboManager {
|
|||
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));
|
||||
COMBO_ABILITIES.put("JetBlaze", new ComboAbilityInfo("JetBlaze", jetBlaze, JetBlaze.class));
|
||||
DESCRIPTIONS.put("JetBlaze", ConfigManager.languageConfig.get().getString("Abilities.Fire.Combo.JetBlaze.Description"));
|
||||
INSTRUCTIONS.put("JetBlaze", "FireJet (Tap Shift) > FireJet (Tap Shift) > Blaze (Tap Shift) > FireJet.");
|
||||
}
|
||||
|
@ -93,7 +103,7 @@ public class ComboManager {
|
|||
fireWheel.add(new AbilityInformation("FireShield", ClickType.RIGHT_CLICK_BLOCK));
|
||||
fireWheel.add(new AbilityInformation("FireShield", ClickType.RIGHT_CLICK_BLOCK));
|
||||
fireWheel.add(new AbilityInformation("Blaze", ClickType.SHIFT_UP));
|
||||
COMBO_ABILITIES.put("FireWheel", new ComboAbilityInfo("FireWheel", fireWheel, FireCombo.class));
|
||||
COMBO_ABILITIES.put("FireWheel", new ComboAbilityInfo("FireWheel", fireWheel, FireWheel.class));
|
||||
DESCRIPTIONS.put("FireWheel", ConfigManager.languageConfig.get().getString("Abilities.Fire.Combo.FireWheel.Description"));
|
||||
INSTRUCTIONS.put("FireWheel", "FireShield (Hold Shift) > Right Click a block in front of you twice > Switch to Blaze > Release Shift.");
|
||||
}
|
||||
|
@ -104,7 +114,7 @@ public class ComboManager {
|
|||
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));
|
||||
COMBO_ABILITIES.put("Twister", new ComboAbilityInfo("Twister", twister, Twister.class));
|
||||
DESCRIPTIONS.put("Twister", ConfigManager.languageConfig.get().getString("Abilities.Air.Combo.Twister.Description"));
|
||||
INSTRUCTIONS.put("Twister", "AirShield (Tap Shift) > Tornado (Hold Shift) > AirBlast (Left Click)");
|
||||
}
|
||||
|
@ -114,7 +124,7 @@ public class ComboManager {
|
|||
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));
|
||||
COMBO_ABILITIES.put("AirStream", new ComboAbilityInfo("AirStream", airStream, AirStream.class));
|
||||
DESCRIPTIONS.put("AirStream", ConfigManager.languageConfig.get().getString("Abilities.Air.Combo.AirStream.Description"));
|
||||
INSTRUCTIONS.put("AirStream", "AirShield (Hold Shift) > AirSuction (Left Click) > AirBlast (Left Click)");
|
||||
}
|
||||
|
@ -125,7 +135,7 @@ public class ComboManager {
|
|||
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));
|
||||
COMBO_ABILITIES.put("AirSweep", new ComboAbilityInfo("AirSweep", airSweep, AirSweep.class));
|
||||
DESCRIPTIONS.put("AirSweep", ConfigManager.languageConfig.get().getString("Abilities.Air.Combo.AirSweep.Description"));
|
||||
INSTRUCTIONS.put("AirSweep", "AirSwipe (Left Click) > AirSwipe (Left Click) > AirBurst (Hold Shift) > AirBurst (Left Click)");
|
||||
}
|
||||
|
@ -134,7 +144,7 @@ public class ComboManager {
|
|||
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));
|
||||
COMBO_ABILITIES.put("IceWave", new ComboAbilityInfo("IceWave", iceWave, IceWave.class));
|
||||
DESCRIPTIONS.put("IceWave", ConfigManager.languageConfig.get().getString("Abilities.Water.Combo.IceWave.Description"));
|
||||
INSTRUCTIONS.put("IceWave", "Create a WaterSpout Wave > PhaseChange (Left Click)");
|
||||
}
|
||||
|
@ -144,16 +154,16 @@ public class ComboManager {
|
|||
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));
|
||||
COMBO_ABILITIES.put("IceBullet", new ComboAbilityInfo("IceBullet", iceBullet, IceBullet.class));
|
||||
DESCRIPTIONS.put("IceBullet", ConfigManager.languageConfig.get().getString("Abilities.Water.Combo.IceBullet.Description"));
|
||||
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));
|
||||
COMBO_ABILITIES.put("IceBulletLeftClick", new ComboAbilityInfo("IceBulletLeftClick", iceBulletLeft, IceBulletLeftClick.class));
|
||||
ArrayList<AbilityInformation> iceBulletRight = new ArrayList<>();
|
||||
iceBulletRight.add(new AbilityInformation("IceBlast", ClickType.RIGHT_CLICK_BLOCK));
|
||||
COMBO_ABILITIES.put("IceBulletRightClick", new ComboAbilityInfo("IceBulletRightClick", iceBulletRight, WaterCombo.class));
|
||||
COMBO_ABILITIES.put("IceBulletRightClick", new ComboAbilityInfo("IceBulletRightClick", iceBulletRight, IceBulletRightClick.class));
|
||||
}
|
||||
|
||||
if (ConfigManager.defaultConfig.get().getBoolean("Abilities.Chi.ChiCombo.Immobilize.Enabled")) {
|
||||
|
@ -162,7 +172,7 @@ public class ComboManager {
|
|||
immobilize.add(new AbilityInformation("SwiftKick", ClickType.LEFT_CLICK_ENTITY));
|
||||
immobilize.add(new AbilityInformation("QuickStrike", ClickType.LEFT_CLICK_ENTITY));
|
||||
immobilize.add(new AbilityInformation("QuickStrike", ClickType.LEFT_CLICK_ENTITY));
|
||||
COMBO_ABILITIES.put("Immobilize", new ComboAbilityInfo("Immobilize", immobilize, ChiCombo.class));
|
||||
COMBO_ABILITIES.put("Immobilize", new ComboAbilityInfo("Immobilize", immobilize, Immobilize.class));
|
||||
DESCRIPTIONS.put("Immobilize", ConfigManager.languageConfig.get().getString("Abilities.Chi.Combo.Immobilize.Description"));
|
||||
INSTRUCTIONS.put("Immobilize", "QuickStrike (Left Click) > SwiftKick (Left Click) > QuickStrike (Left Click) > QuickStrike (Left Click)");
|
||||
}
|
||||
|
@ -191,17 +201,15 @@ public class ComboManager {
|
|||
}
|
||||
|
||||
new BukkitRunnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
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());
|
||||
if (comboAbil.getComboType() instanceof Class) {
|
||||
Class<?> clazz = (Class<?>) comboAbil.getComboType();
|
||||
try {
|
||||
ReflectionHandler.instantiateObject(clazz, player);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
if (comboAbil.getComboType() instanceof ComboAbility) {
|
||||
((ComboAbility) comboAbil.getComboType()).createNewComboInstance(player);
|
||||
|
@ -209,10 +217,8 @@ public class ComboManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}.runTaskLater(ProjectKorra.plugin, 1L);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,6 +26,7 @@ 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.util.Collision;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.command.Commands;
|
||||
import com.projectkorra.projectkorra.object.HorizontalVelocityTracker;
|
||||
|
@ -80,7 +81,7 @@ public class AirBlast extends AirAbility {
|
|||
if (entity != null) {
|
||||
this.direction = GeneralMethods.getDirection(origin, entity.getLocation()).normalize();
|
||||
} else {
|
||||
this.direction = GeneralMethods.getDirection(origin, GeneralMethods.getTargetedLocation(player, range)) .normalize();
|
||||
this.direction = GeneralMethods.getDirection(origin, GeneralMethods.getTargetedLocation(player, range)).normalize();
|
||||
}
|
||||
} else {
|
||||
origin = player.getEyeLocation();
|
||||
|
@ -126,7 +127,7 @@ public class AirBlast extends AirAbility {
|
|||
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.isFromOtherOrigin = false;
|
||||
this.showParticles = true;
|
||||
this.random = new Random();
|
||||
|
@ -172,7 +173,7 @@ public class AirBlast extends AirAbility {
|
|||
}
|
||||
|
||||
ORIGINS.put(player, location);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void advanceLocation() {
|
||||
|
@ -207,7 +208,7 @@ public class AirBlast extends AirAbility {
|
|||
push.setY(max);
|
||||
}
|
||||
}
|
||||
if(location.getWorld().equals(origin.getWorld())) {
|
||||
if (location.getWorld().equals(origin.getWorld())) {
|
||||
factor *= 1 - location.distance(origin) / (2 * range);
|
||||
}
|
||||
|
||||
|
@ -291,8 +292,7 @@ public class AirBlast extends AirAbility {
|
|||
continue;
|
||||
}
|
||||
|
||||
Material doorTypes[] = { Material.WOODEN_DOOR, Material.SPRUCE_DOOR, Material.BIRCH_DOOR, Material.JUNGLE_DOOR,
|
||||
Material.ACACIA_DOOR, Material.DARK_OAK_DOOR };
|
||||
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()) && canOpenDoors) {
|
||||
if (block.getData() >= 8) {
|
||||
block = block.getRelative(BlockFace.DOWN);
|
||||
|
@ -400,12 +400,13 @@ public class AirBlast extends AirAbility {
|
|||
}
|
||||
|
||||
/*
|
||||
* If a player presses shift and AirBlasts straight down then the AirBlast's location gets
|
||||
* messed up and reading the distance returns Double.NaN. If we don't remove this instance
|
||||
* then the AirBlast will never be removed.
|
||||
* If a player presses shift and AirBlasts straight down then the
|
||||
* AirBlast's location gets messed up and reading the distance returns
|
||||
* Double.NaN. If we don't remove this instance then the AirBlast will
|
||||
* never be removed.
|
||||
*/
|
||||
double dist = 0;
|
||||
if(location.getWorld().equals(origin.getWorld())) {
|
||||
if (location.getWorld().equals(origin.getWorld())) {
|
||||
dist = location.distance(origin);
|
||||
}
|
||||
if (Double.isNaN(dist) || dist > range) {
|
||||
|
@ -421,6 +422,11 @@ public class AirBlast extends AirAbility {
|
|||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean removeAirBlastsAroundPoint(Location location, double radius) {
|
||||
boolean removed = false;
|
||||
for (AirBlast airBlast : getAbilities(AirBlast.class)) {
|
||||
|
@ -449,7 +455,7 @@ public class AirBlast extends AirAbility {
|
|||
public long getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -460,6 +466,11 @@ public class AirBlast extends AirAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return getRadius();
|
||||
}
|
||||
|
||||
public Location getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
@ -619,13 +630,13 @@ public class AirBlast extends AirAbility {
|
|||
public void setParticles(int particles) {
|
||||
this.particles = particles;
|
||||
}
|
||||
|
||||
|
||||
public static int getSelectParticles() {
|
||||
return getConfig().getInt("Abilities.Air.AirBlast.SelectParticles");
|
||||
}
|
||||
|
||||
|
||||
public static double getSelectRange() {
|
||||
return getConfig().getInt("Abilities.Air.AirBlast.SelectRange");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
package com.projectkorra.projectkorra.airbending;
|
||||
|
||||
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.WaterAbility;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterManipulation;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
@ -14,8 +10,11 @@ import org.bukkit.block.Block;
|
|||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Map;
|
||||
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.waterbending.WaterManipulation;
|
||||
|
||||
public class AirBubble extends AirAbility {
|
||||
|
||||
|
@ -27,7 +26,7 @@ public class AirBubble extends AirAbility {
|
|||
|
||||
public AirBubble(Player player) {
|
||||
super(player);
|
||||
|
||||
|
||||
this.radius = 0;
|
||||
this.airRadius = getConfig().getDouble("Abilities.Air.AirBubble.Radius");
|
||||
this.waterRadius = getConfig().getDouble("Abilities.Water.WaterBubble.Radius");
|
||||
|
@ -50,7 +49,7 @@ public class AirBubble extends AirAbility {
|
|||
if (bPlayer == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
String name = bPlayer.getBoundAbilityName();
|
||||
if (name.equalsIgnoreCase("AirBubble") | name.equalsIgnoreCase("WaterBubble")) {
|
||||
if (!hasAbility(player, AirBubble.class) && player.isSneaking()) {
|
||||
|
@ -94,7 +93,7 @@ public class AirBubble extends AirAbility {
|
|||
} else {
|
||||
radius = waterRadius;
|
||||
}
|
||||
|
||||
|
||||
if (airRadius > radius && bPlayer.hasElement(Element.AIR)) {
|
||||
radius = airRadius;
|
||||
}
|
||||
|
@ -129,8 +128,6 @@ public class AirBubble extends AirAbility {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
WaterAbility.removeWaterSpouts(location, radius, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -157,7 +154,7 @@ public class AirBubble extends AirAbility {
|
|||
public long getCooldown() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -168,6 +165,11 @@ public class AirBubble extends AirAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return getRadius();
|
||||
}
|
||||
|
||||
public boolean isWaterBubble() {
|
||||
return waterBubble;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package com.projectkorra.projectkorra.airbending;
|
||||
|
||||
import com.projectkorra.projectkorra.ProjectKorra;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
@ -10,7 +9,9 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import com.projectkorra.projectkorra.ProjectKorra;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
|
||||
public class AirBurst extends AirAbility {
|
||||
|
||||
|
@ -27,7 +28,7 @@ public class AirBurst extends AirAbility {
|
|||
private double particlePercentage;
|
||||
private ArrayList<AirBlast> blasts;
|
||||
private ArrayList<Entity> affectedEntities;
|
||||
|
||||
|
||||
public AirBurst(Player player, boolean isFallBurst) {
|
||||
super(player);
|
||||
if (bPlayer.isOnCooldown(this)) {
|
||||
|
@ -76,7 +77,7 @@ public class AirBurst extends AirAbility {
|
|||
return;
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() > startTime + chargeTime && !isCharged) {
|
||||
if (System.currentTimeMillis() > getStartTime() + chargeTime && !isCharged) {
|
||||
isCharged = true;
|
||||
}
|
||||
|
||||
|
@ -99,7 +100,7 @@ public class AirBurst extends AirAbility {
|
|||
if (bPlayer.isOnCooldown("AirBurst")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Location location = player.getLocation();
|
||||
double x, y, z;
|
||||
double r = 1;
|
||||
|
@ -109,11 +110,11 @@ public class AirBurst extends AirAbility {
|
|||
for (double phi = 0; phi < 360; phi += dphi) {
|
||||
double rphi = Math.toRadians(phi);
|
||||
double rtheta = Math.toRadians(theta);
|
||||
|
||||
|
||||
x = r * Math.cos(rphi) * Math.sin(rtheta);
|
||||
y = r * Math.sin(rphi) * Math.sin(rtheta);
|
||||
z = r * Math.cos(rtheta);
|
||||
|
||||
|
||||
Vector direction = new Vector(x, z, y);
|
||||
AirBlast blast = new AirBlast(player, location, direction.normalize(), pushFactor, this);
|
||||
blast.setDamage(damage);
|
||||
|
@ -136,17 +137,17 @@ public class AirBurst extends AirAbility {
|
|||
double angle = Math.toRadians(30);
|
||||
double x, y, z;
|
||||
double r = 1;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
x = r * Math.cos(rphi) * Math.sin(rtheta);
|
||||
y = r * Math.sin(rphi) * Math.sin(rtheta);
|
||||
z = r * Math.cos(rtheta);
|
||||
|
||||
|
||||
Vector direction = new Vector(x, z, y);
|
||||
if (direction.angle(vector) <= angle) {
|
||||
AirBlast blast = new AirBlast(player, location, direction.normalize(), pushFactor, this);
|
||||
|
@ -185,14 +186,14 @@ public class AirBurst extends AirAbility {
|
|||
for (double phi = 0; phi < 360; phi += dphi) {
|
||||
double rphi = Math.toRadians(phi);
|
||||
double rtheta = Math.toRadians(theta);
|
||||
|
||||
|
||||
x = r * Math.cos(rphi) * Math.sin(rtheta);
|
||||
y = r * Math.sin(rphi) * Math.sin(rtheta);
|
||||
z = r * Math.cos(rtheta);
|
||||
|
||||
|
||||
Vector direction = new Vector(x, z, y);
|
||||
AirBlast blast = new AirBlast(player, location, direction.normalize(), pushFactor, this);
|
||||
|
||||
|
||||
blast.setDamage(damage);
|
||||
blast.setShowParticles(false);
|
||||
blasts.add(blast);
|
||||
|
@ -216,7 +217,7 @@ public class AirBurst extends AirAbility {
|
|||
public long getCooldown() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -227,6 +228,14 @@ public class AirBurst extends AirAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
for (AirBlast blast : blasts) {
|
||||
locations.add(blast.getLocation());
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public void addAffectedEntity(Entity entity) {
|
||||
affectedEntities.add(entity);
|
||||
|
|
|
@ -1,19 +1,7 @@
|
|||
package com.projectkorra.projectkorra.airbending;
|
||||
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ProjectKorra;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.ComboAbility;
|
||||
import com.projectkorra.projectkorra.ability.EarthAbility;
|
||||
import com.projectkorra.projectkorra.ability.FireAbility;
|
||||
import com.projectkorra.projectkorra.ability.WaterAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.command.Commands;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo.FireComboStream;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
import com.projectkorra.projectkorra.util.Flight;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
|
@ -23,12 +11,22 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ProjectKorra;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.ComboAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.command.Commands;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo.FireComboStream;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
import com.projectkorra.projectkorra.util.Flight;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* 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 {
|
||||
|
||||
|
@ -62,7 +60,7 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
|
||||
public AirCombo(Player player, String ability) {
|
||||
super(player);
|
||||
|
||||
|
||||
this.abilityName = ability;
|
||||
this.affectedEntities = new ArrayList<>();
|
||||
this.tasks = new ArrayList<>();
|
||||
|
@ -71,7 +69,7 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (bPlayer.isOnCooldown(ability)) {
|
||||
return;
|
||||
}
|
||||
|
@ -98,7 +96,7 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
this.knockback = getConfig().getDouble("Abilities.Air.AirCombo.AirSweep.Knockback");
|
||||
this.cooldown = getConfig().getLong("Abilities.Air.AirCombo.AirSweep.Cooldown");
|
||||
}
|
||||
|
||||
|
||||
if (bPlayer.isAvatarState()) {
|
||||
this.cooldown = 0;
|
||||
this.damage = AvatarState.getValue(damage);
|
||||
|
@ -201,7 +199,7 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
|
||||
direction = GeneralMethods.getDirection(currentLoc, destination).normalize();
|
||||
currentLoc.add(direction.clone().multiply(speed));
|
||||
|
||||
|
||||
if (player.getWorld() != currentLoc.getWorld()) {
|
||||
remove();
|
||||
return;
|
||||
|
@ -223,12 +221,6 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
} 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));
|
||||
}
|
||||
|
@ -280,8 +272,7 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
destination = player.getLocation().add(player.getEyeLocation().getDirection().normalize().multiply(10));
|
||||
Vector origToDest = GeneralMethods.getDirection(origin, destination);
|
||||
for (double i = 0; i < 30; i++) {
|
||||
Vector vec = GeneralMethods.getDirection(player.getLocation(),
|
||||
origin.clone().add(origToDest.clone().multiply(i / 30)));
|
||||
Vector vec = GeneralMethods.getDirection(player.getLocation(), origin.clone().add(origToDest.clone().multiply(i / 30)));
|
||||
|
||||
FireComboStream fs = new FireComboStream(null, vec, player.getLocation(), range, speed, "AirSweep");
|
||||
fs.setDensity(1);
|
||||
|
@ -316,7 +307,7 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
fstream.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!isTransparent(loc.getBlock())) {
|
||||
if (!isTransparent(loc.clone().add(0, 0.2, 0).getBlock())) {
|
||||
fstream.remove();
|
||||
|
@ -346,12 +337,6 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GeneralMethods.blockAbilities(player, FireCombo.getBlockableAbilities(), loc, 1)) {
|
||||
fstream.remove();
|
||||
} else AirAbility.removeAirSpouts(loc, player);
|
||||
WaterAbility.removeWaterSpouts(loc, player);
|
||||
EarthAbility.removeSandSpouts(loc, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -368,6 +353,11 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean removeAroundPoint(Player player, String ability, Location loc, double radius) {
|
||||
boolean removed = false;
|
||||
for (AirCombo combo : getAbilities(AirCombo.class)) {
|
||||
|
@ -386,8 +376,7 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
} 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())
|
||||
&& Math.abs(fs.getLocation().distance(loc)) <= radius) {
|
||||
if (fs.getLocation() != null && fs.getLocation().getWorld().equals(loc.getWorld()) && Math.abs(fs.getLocation().distance(loc)) <= radius) {
|
||||
fs.remove();
|
||||
removed = true;
|
||||
}
|
||||
|
@ -423,7 +412,7 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
public boolean isHiddenAbility() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -433,7 +422,13 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
// Override in subclasses
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstructions() {
|
||||
return null;
|
||||
|
@ -449,7 +444,6 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
public String getAbilityName() {
|
||||
return abilityName;
|
||||
}
|
||||
|
@ -609,6 +603,10 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
public ArrayList<BukkitRunnable> getTasks() {
|
||||
return tasks;
|
||||
}
|
||||
|
||||
public void setTasks(ArrayList<BukkitRunnable> tasks) {
|
||||
this.tasks = tasks;
|
||||
}
|
||||
|
||||
public ArrayList<Flight> getFlights() {
|
||||
return flights;
|
||||
|
@ -617,44 +615,91 @@ public class AirCombo extends AirAbility implements ComboAbility {
|
|||
public void setCooldown(long cooldown) {
|
||||
this.cooldown = cooldown;
|
||||
}
|
||||
|
||||
public class AirStream extends AirCombo {
|
||||
|
||||
public AirStream(Player player, String name) {
|
||||
// Combo subclasses need to be static to be reflectively called in ComboManager
|
||||
public static class AirStream extends AirCombo {
|
||||
|
||||
public AirStream(Player player) {
|
||||
super(player, "AirStream");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "AirStream";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class AirSweep extends AirCombo {
|
||||
|
||||
public AirSweep(Player player, String name) {
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class AirSweep extends AirCombo {
|
||||
|
||||
public AirSweep(Player player) {
|
||||
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 boolean isCollidable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCollision(Collision collision) {
|
||||
if (collision.isRemovingFirst()) {
|
||||
ArrayList<BukkitRunnable> newTasks = new ArrayList<>();
|
||||
double collisionDistanceSquared = Math.pow(getCollisionRadius() + collision.getAbilitySecond().getCollisionRadius(), 2);
|
||||
// Remove all of the streams that are by this specific ourLocation.
|
||||
// Don't just do a single stream at a time or this algorithm becomes O(n^2) with
|
||||
// Collision's detection algorithm.
|
||||
for (BukkitRunnable task : getTasks()) {
|
||||
if (task instanceof FireComboStream) {
|
||||
FireComboStream stream = (FireComboStream) task;
|
||||
if (stream.getLocation().distanceSquared(collision.getLocationSecond()) > collisionDistanceSquared) {
|
||||
newTasks.add(stream);
|
||||
} else {
|
||||
stream.cancel();
|
||||
}
|
||||
} else {
|
||||
newTasks.add(task);
|
||||
}
|
||||
}
|
||||
setTasks(newTasks);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
for (BukkitRunnable task : getTasks()) {
|
||||
if (task instanceof FireComboStream) {
|
||||
FireComboStream stream = (FireComboStream) task;
|
||||
locations.add(stream.getLocation());
|
||||
}
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Twister extends AirCombo {
|
||||
|
||||
public Twister(Player player) {
|
||||
super(player, "Twister");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Twister";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -25,18 +25,17 @@ public class AirScooter extends AirAbility {
|
|||
private Block floorblock;
|
||||
private Random random;
|
||||
private ArrayList<Double> angles;
|
||||
|
||||
|
||||
private boolean canFly;
|
||||
private boolean hadFly;
|
||||
private double phi = 0;
|
||||
|
||||
|
||||
public AirScooter(Player player) {
|
||||
super(player);
|
||||
|
||||
if (check(player))
|
||||
|
||||
if (check(player))
|
||||
return;
|
||||
else if (!player.isSprinting() || GeneralMethods.isSolid(player.getEyeLocation().getBlock())
|
||||
|| player.getEyeLocation().getBlock().isLiquid())
|
||||
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;
|
||||
|
@ -52,7 +51,7 @@ public class AirScooter extends AirAbility {
|
|||
this.angles = new ArrayList<>();
|
||||
canFly = player.getAllowFlight();
|
||||
hadFly = player.isFlying();
|
||||
|
||||
|
||||
new Flight(player);
|
||||
player.setAllowFlight(true);
|
||||
player.setFlying(true);
|
||||
|
@ -82,8 +81,8 @@ public class AirScooter extends AirAbility {
|
|||
}
|
||||
|
||||
/*
|
||||
* Looks for a block under the player and sets "floorBlock" to a block
|
||||
* under the player if it within the maximum height
|
||||
* Looks for a block under the player and sets "floorBlock" to a block under
|
||||
* the player if it within the maximum height
|
||||
*/
|
||||
private void getFloor() {
|
||||
floorblock = null;
|
||||
|
@ -102,7 +101,7 @@ public class AirScooter extends AirAbility {
|
|||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
getFloor();
|
||||
if (floorblock == null) {
|
||||
remove();
|
||||
|
@ -114,7 +113,7 @@ public class AirScooter extends AirAbility {
|
|||
/*
|
||||
* checks the players speed and ends the move if they are going too slow
|
||||
*/
|
||||
if (System.currentTimeMillis() > startTime + interval) {
|
||||
if (System.currentTimeMillis() > getStartTime() + interval) {
|
||||
if (player.getVelocity().length() < speed * 0.3) {
|
||||
remove();
|
||||
return;
|
||||
|
@ -122,8 +121,8 @@ public class AirScooter extends AirAbility {
|
|||
spinScooter();
|
||||
}
|
||||
/*
|
||||
* Checks for how far the ground is away from the player
|
||||
* it elevates or lowers the player based on their distance from the ground.
|
||||
* Checks for how far the ground is away from the player it elevates or
|
||||
* lowers the player based on their distance from the ground.
|
||||
*/
|
||||
double distance = player.getLocation().getY() - (double) floorblock.getY();
|
||||
double dx = Math.abs(distance - 2.4);
|
||||
|
@ -141,7 +140,7 @@ public class AirScooter extends AirAbility {
|
|||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
player.setSprinting(false);
|
||||
player.removePotionEffect(PotionEffectType.SPEED);
|
||||
player.setVelocity(velocity);
|
||||
|
@ -163,36 +162,33 @@ public class AirScooter extends AirAbility {
|
|||
}
|
||||
|
||||
/*
|
||||
* The particles used for AirScooter
|
||||
* phi = how many rings of particles the sphere has.
|
||||
* theta = how dense the rings are.
|
||||
* r = Radius of the sphere
|
||||
* The particles used for AirScooter phi = how many rings of particles the
|
||||
* sphere has. theta = how dense the rings are. r = Radius of the sphere
|
||||
*/
|
||||
private void spinScooter() {
|
||||
Location origin = player.getLocation();
|
||||
Location origin2 = player.getLocation();
|
||||
phi += Math.PI/10*4;
|
||||
for(double theta = 0; theta <= 2*Math.PI; theta += Math.PI/10) {
|
||||
phi += Math.PI / 10 * 4;
|
||||
for (double theta = 0; theta <= 2 * Math.PI; theta += Math.PI / 10) {
|
||||
double r = 0.6;
|
||||
double x = r*Math.cos(theta)*Math.sin(phi);
|
||||
double y = r*Math.cos(phi);
|
||||
double z = r*Math.sin(theta)*Math.sin(phi);
|
||||
double x = r * Math.cos(theta) * Math.sin(phi);
|
||||
double y = r * Math.cos(phi);
|
||||
double z = r * Math.sin(theta) * Math.sin(phi);
|
||||
origin.add(x, y, z);
|
||||
playAirbendingParticles(origin, 1, 0F, 0F, 0F);
|
||||
origin.subtract(x, y, z);
|
||||
}
|
||||
for(double theta = 0; theta <= 2*Math.PI; theta += Math.PI/10) {
|
||||
for (double theta = 0; theta <= 2 * Math.PI; theta += Math.PI / 10) {
|
||||
double r = 0.6;
|
||||
double x = r*Math.cos(theta)*Math.sin(phi);
|
||||
double y = r*Math.cos(phi);
|
||||
double z = r*Math.sin(theta)*Math.sin(phi);
|
||||
double x = r * Math.cos(theta) * Math.sin(phi);
|
||||
double y = r * Math.cos(phi);
|
||||
double z = r * Math.sin(theta) * Math.sin(phi);
|
||||
origin2.subtract(x, y, z);
|
||||
playAirbendingParticles(origin2, 1, 0F, 0F, 0F);
|
||||
origin2.add(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "AirScooter";
|
||||
|
@ -207,7 +203,7 @@ public class AirScooter extends AirAbility {
|
|||
public long getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return false;
|
||||
|
@ -218,6 +214,10 @@ public class AirScooter extends AirAbility {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return getRadius();
|
||||
}
|
||||
|
||||
public double getSpeed() {
|
||||
return speed;
|
||||
|
@ -258,7 +258,7 @@ public class AirScooter extends AirAbility {
|
|||
public void setFloorblock(Block floorblock) {
|
||||
this.floorblock = floorblock;
|
||||
}
|
||||
|
||||
|
||||
public void setCooldown(long cooldown) {
|
||||
this.cooldown = cooldown;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
package com.projectkorra.projectkorra.airbending;
|
||||
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.command.Commands;
|
||||
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.waterbending.WaterManipulation;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterSpout;
|
||||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
|
@ -20,9 +12,11 @@ import org.bukkit.entity.Entity;
|
|||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.command.Commands;
|
||||
|
||||
public class AirShield extends AirAbility {
|
||||
|
||||
|
@ -34,16 +28,16 @@ public class AirShield extends AirAbility {
|
|||
private int particles;
|
||||
private Random random;
|
||||
private HashMap<Integer, Integer> angles;
|
||||
|
||||
|
||||
public AirShield(Player player) {
|
||||
super(player);
|
||||
|
||||
this.maxRadius = getConfig().getDouble("Abilities.Air.AirShield.Radius");
|
||||
this.isToggledByAvatarState = getConfig().getBoolean("Abilities.Air.AirShield.IsAvatarStateToggle");
|
||||
this.radius = this.maxRadius;
|
||||
this.speed = getConfig().getDouble("Abilities.Air.AirShield.Speed");
|
||||
this.speed = getConfig().getDouble("Abilities.Air.AirShield.Speed");
|
||||
this.streams = getConfig().getInt("Abilities.Air.AirShield.Streams");
|
||||
this.particles = getConfig().getInt("Abilities.Air.AirShield.Particles");
|
||||
this.particles = getConfig().getInt("Abilities.Air.AirShield.Particles");
|
||||
this.random = new Random();
|
||||
this.angles = new HashMap<>();
|
||||
|
||||
|
@ -61,10 +55,15 @@ public class AirShield extends AirAbility {
|
|||
angle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isWithinShield(Location loc) {
|
||||
for (AirShield ashield : getAbilities(AirShield.class)) {
|
||||
if (!ashield.player.getWorld().equals(loc.getWorld())) {
|
||||
|
@ -96,16 +95,6 @@ public class AirShield extends AirAbility {
|
|||
|
||||
private void rotateShield() {
|
||||
Location origin = player.getLocation();
|
||||
FireBlast.removeFireBlastsAroundPoint(origin, radius);
|
||||
Combustion.removeAroundPoint(origin, radius);
|
||||
BlazeArc.removeAroundPoint(origin, radius);
|
||||
AirBlast.removeAirBlastsAroundPoint(origin, radius);
|
||||
AirSuction.removeAirSuctionsAroundPoint(origin, radius);
|
||||
EarthBlast.removeAroundPoint(origin, radius);
|
||||
SandSpout.removeSpouts(origin, radius, player);
|
||||
WaterSpout.removeSpouts(origin, radius, player);
|
||||
WaterManipulation.removeAroundPoint(origin, radius);
|
||||
|
||||
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(origin, radius)) {
|
||||
if (GeneralMethods.isRegionProtectedFromBuild(player, "AirShield", entity.getLocation())) {
|
||||
continue;
|
||||
|
@ -181,7 +170,7 @@ public class AirShield extends AirAbility {
|
|||
radius = maxRadius;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "AirShield";
|
||||
|
@ -196,7 +185,7 @@ public class AirShield extends AirAbility {
|
|||
public long getCooldown() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -207,6 +196,11 @@ public class AirShield extends AirAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return getRadius();
|
||||
}
|
||||
|
||||
public boolean isToggledByAvatarState() {
|
||||
return isToggledByAvatarState;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.projectkorra.projectkorra.airbending;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
@ -9,26 +11,28 @@ import org.bukkit.entity.Player;
|
|||
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.util.Flight;
|
||||
|
||||
public class AirSpout extends AirAbility {
|
||||
|
||||
private static final Integer[] DIRECTIONS = {0, 1, 2, 3, 5, 6, 7, 8};
|
||||
private static final Integer[] DIRECTIONS = { 0, 1, 2, 3, 5, 6, 7, 8 };
|
||||
|
||||
private int angle;
|
||||
private long animTime;
|
||||
private long interval;
|
||||
private long cooldown;
|
||||
private double height;
|
||||
|
||||
public AirSpout(Player player) {
|
||||
super(player);
|
||||
|
||||
|
||||
AirSpout spout = getAbility(player, AirSpout.class);
|
||||
if (spout != null) {
|
||||
spout.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!bPlayer.canBend(this)) {
|
||||
remove();
|
||||
return;
|
||||
|
@ -36,6 +40,7 @@ public class AirSpout extends AirAbility {
|
|||
|
||||
this.angle = 0;
|
||||
this.cooldown = 0;
|
||||
this.animTime = System.currentTimeMillis();
|
||||
this.interval = getConfig().getLong("Abilities.Air.AirSpout.Interval");
|
||||
this.height = getConfig().getDouble("Abilities.Air.AirSpout.Height");
|
||||
|
||||
|
@ -43,12 +48,17 @@ public class AirSpout extends AirAbility {
|
|||
if (!isWithinMaxSpoutHeight(heightRemoveThreshold)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
new Flight(player);
|
||||
start();
|
||||
bPlayer.addCooldown(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean removeSpouts(Location loc0, double radius, Player sourceplayer) {
|
||||
boolean removed = false;
|
||||
for (AirSpout spout : getAbilities(AirSpout.class)) {
|
||||
|
@ -74,7 +84,7 @@ public class AirSpout extends AirAbility {
|
|||
player.setAllowFlight(true);
|
||||
player.setFlying(true);
|
||||
}
|
||||
|
||||
|
||||
private boolean isWithinMaxSpoutHeight(double threshold) {
|
||||
Block ground = getGround();
|
||||
if (ground == null) {
|
||||
|
@ -100,21 +110,18 @@ public class AirSpout extends AirAbility {
|
|||
|
||||
@Override
|
||||
public void progress() {
|
||||
if (player.isDead()
|
||||
|| !player.isOnline()
|
||||
|| !bPlayer.canBendIgnoreBindsCooldowns(this)
|
||||
|| !bPlayer.canBind(this)) {
|
||||
if (player.isDead() || !player.isOnline() || !bPlayer.canBendIgnoreBindsCooldowns(this) || !bPlayer.canBind(this)) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
double heightRemoveThreshold = 2;
|
||||
if (!isWithinMaxSpoutHeight(heightRemoveThreshold)) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!bPlayer.canBind(this)) {
|
||||
|
||||
if (!bPlayer.canBind(this)) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
@ -159,8 +166,8 @@ public class AirSpout extends AirAbility {
|
|||
if (!player.getWorld().equals(block.getWorld())) {
|
||||
return;
|
||||
}
|
||||
if (System.currentTimeMillis() >= startTime + interval) {
|
||||
startTime = System.currentTimeMillis();
|
||||
if (System.currentTimeMillis() >= animTime + interval) {
|
||||
animTime = System.currentTimeMillis();
|
||||
Location location = block.getLocation();
|
||||
Location playerloc = player.getLocation();
|
||||
location = new Location(location.getWorld(), playerloc.getX(), location.getY(), playerloc.getZ());
|
||||
|
@ -191,7 +198,7 @@ public class AirSpout extends AirAbility {
|
|||
public long getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return false;
|
||||
|
@ -202,6 +209,22 @@ public class AirSpout extends AirAbility {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
Location topLoc = player.getLocation().getBlock().getLocation();
|
||||
double ySpacing = 3;
|
||||
for (double i = 0; i <= height; i += ySpacing) {
|
||||
locations.add(topLoc.clone().add(0, -i, 0));
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public int getAngle() {
|
||||
return angle;
|
||||
}
|
||||
|
@ -210,6 +233,14 @@ public class AirSpout extends AirAbility {
|
|||
this.angle = angle;
|
||||
}
|
||||
|
||||
public long getAnimTime() {
|
||||
return animTime;
|
||||
}
|
||||
|
||||
public void setAnimTime(long animTime) {
|
||||
this.animTime = animTime;
|
||||
}
|
||||
|
||||
public long getInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
@ -229,5 +260,5 @@ public class AirSpout extends AirAbility {
|
|||
public void setCooldown(long cooldown) {
|
||||
this.cooldown = cooldown;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import com.projectkorra.projectkorra.BendingPlayer;
|
|||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ProjectKorra;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.command.Commands;
|
||||
import com.projectkorra.projectkorra.object.HorizontalVelocityTracker;
|
||||
|
@ -24,7 +25,7 @@ public class AirSuction extends AirAbility {
|
|||
|
||||
private static final int MAX_TICKS = 10000;
|
||||
private static final Map<Player, Location> ORIGINS = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
private boolean hasOtherOrigin;
|
||||
private int ticks;
|
||||
private int particleCount;
|
||||
|
@ -37,10 +38,10 @@ public class AirSuction extends AirAbility {
|
|||
private Location location;
|
||||
private Location origin;
|
||||
private Vector direction;
|
||||
|
||||
|
||||
public AirSuction(Player player) {
|
||||
super(player);
|
||||
|
||||
|
||||
if (bPlayer.isOnCooldown(this)) {
|
||||
return;
|
||||
} else if (player.getEyeLocation().getBlock().isLiquid()) {
|
||||
|
@ -133,8 +134,7 @@ public class AirSuction extends AirAbility {
|
|||
Location location = origin.clone();
|
||||
for (double i = 1; i <= range; i++) {
|
||||
location = origin.clone().add(direction.clone().multiply(i));
|
||||
if (!isTransparent(location.getBlock())
|
||||
|| GeneralMethods.isRegionProtectedFromBuild(this, location)) {
|
||||
if (!isTransparent(location.getBlock()) || GeneralMethods.isRegionProtectedFromBuild(this, location)) {
|
||||
return origin.clone().add(direction.clone().multiply(i - 1));
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ public class AirSuction extends AirAbility {
|
|||
push.setY(max);
|
||||
}
|
||||
}
|
||||
if(location.getWorld().equals(origin.getWorld())) {
|
||||
if (location.getWorld().equals(origin.getWorld())) {
|
||||
factor *= 1 - location.distance(origin) / (2 * range);
|
||||
}
|
||||
|
||||
|
@ -216,6 +216,11 @@ public class AirSuction extends AirAbility {
|
|||
advanceLocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean removeAirSuctionsAroundPoint(Location location, double radius) {
|
||||
boolean removed = false;
|
||||
for (AirSuction airSuction : getAbilities(AirSuction.class)) {
|
||||
|
@ -244,7 +249,7 @@ public class AirSuction extends AirAbility {
|
|||
public long getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -255,6 +260,11 @@ public class AirSuction extends AirAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return getRadius();
|
||||
}
|
||||
|
||||
public Location getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
@ -346,5 +356,5 @@ public class AirSuction extends AirAbility {
|
|||
public static double getSelectRange() {
|
||||
return getConfig().getDouble("Abilities.Air.AirSuction.SelectRange");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
package com.projectkorra.projectkorra.airbending;
|
||||
|
||||
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.EarthAbility;
|
||||
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.DamageHandler;
|
||||
import com.projectkorra.projectkorra.util.Flight;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterManipulation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
|
@ -25,19 +16,24 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
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.EarthAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.command.Commands;
|
||||
import com.projectkorra.projectkorra.firebending.Illumination;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
import com.projectkorra.projectkorra.util.Flight;
|
||||
|
||||
public class AirSwipe extends AirAbility {
|
||||
|
||||
// Limiting the entities reduces the risk of crashing
|
||||
private static final int MAX_AFFECTABLE_ENTITIES = 10;
|
||||
private static final Integer[] BREAKABLES = {6, 31, 32, 37, 38, 39, 40, 59, 81, 83, 106, 175};
|
||||
|
||||
private static final Integer[] BREAKABLES = { 6, 31, 32, 37, 38, 39, 40, 59, 81, 83, 106, 175 };
|
||||
|
||||
private boolean charging;
|
||||
private int arc;
|
||||
private int particles;
|
||||
|
@ -54,14 +50,14 @@ public class AirSwipe extends AirAbility {
|
|||
private Random random;
|
||||
private Map<Vector, Location> elements;
|
||||
private ArrayList<Entity> affectedEntities;
|
||||
|
||||
|
||||
public AirSwipe(Player player) {
|
||||
this(player, false);
|
||||
}
|
||||
|
||||
public AirSwipe(Player player, boolean charging) {
|
||||
super(player);
|
||||
|
||||
|
||||
if (CoreAbility.hasAbility(player, AirSwipe.class)) {
|
||||
for (AirSwipe ability : CoreAbility.getAbilities(player, AirSwipe.class)) {
|
||||
if (ability.charging) {
|
||||
|
@ -71,7 +67,7 @@ public class AirSwipe extends AirAbility {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.charging = charging;
|
||||
this.origin = player.getEyeLocation();
|
||||
this.particles = getConfig().getInt("Abilities.Air.AirSwipe.Particles");
|
||||
|
@ -88,23 +84,28 @@ public class AirSwipe extends AirAbility {
|
|||
this.random = new Random();
|
||||
this.elements = new ConcurrentHashMap<>();
|
||||
this.affectedEntities = new ArrayList<>();
|
||||
|
||||
|
||||
if (bPlayer.isOnCooldown(this) || player.getEyeLocation().getBlock().isLiquid()) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!bPlayer.canBend(this)) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!charging) {
|
||||
launch();
|
||||
}
|
||||
start();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean removeSwipesAroundPoint(Location loc, double radius) {
|
||||
boolean removed = false;
|
||||
for (AirSwipe aswipe : getAbilities(AirSwipe.class)) {
|
||||
|
@ -130,31 +131,15 @@ public class AirSwipe extends AirAbility {
|
|||
location = location.clone().add(direction.clone().multiply(speed));
|
||||
elements.put(direction, location);
|
||||
|
||||
if (location.distanceSquared(origin) > range * range
|
||||
|| GeneralMethods.isRegionProtectedFromBuild(this, location)) {
|
||||
if (location.distanceSquared(origin) > range * range || GeneralMethods.isRegionProtectedFromBuild(this, location)) {
|
||||
elements.remove(direction);
|
||||
} else {
|
||||
removeAirSpouts(location, player);
|
||||
WaterAbility.removeWaterSpouts(location, player);
|
||||
EarthAbility.removeSandSpouts(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;
|
||||
remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
Block block = location.getBlock();
|
||||
if (!EarthAbility.isTransparent(player, block)) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (Block testblock : GeneralMethods.getBlocksAroundPoint(location, radius)) {
|
||||
if (testblock.getType() == Material.FIRE) {
|
||||
testblock.setType(Material.AIR);
|
||||
|
@ -193,9 +178,6 @@ public class AirSwipe extends AirAbility {
|
|||
}
|
||||
|
||||
private void affectPeople(Location location, Vector direction) {
|
||||
WaterAbility.removeWaterSpouts(location, player);
|
||||
removeAirSpouts(location, player);
|
||||
removeAirSpouts(location, player);
|
||||
final List<Entity> entities = GeneralMethods.getEntitiesAroundPoint(location, radius);
|
||||
final Vector fDirection = direction;
|
||||
|
||||
|
@ -280,12 +262,12 @@ public class AirSwipe extends AirAbility {
|
|||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (player.isDead() || !player.isOnline()) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!charging) {
|
||||
if (elements.isEmpty()) {
|
||||
remove();
|
||||
|
@ -295,12 +277,12 @@ public class AirSwipe extends AirAbility {
|
|||
} else {
|
||||
if (!player.isSneaking()) {
|
||||
double factor = 1;
|
||||
if (System.currentTimeMillis() >= startTime + maxChargeTime) {
|
||||
if (System.currentTimeMillis() >= getStartTime() + maxChargeTime) {
|
||||
factor = maxChargeFactor;
|
||||
} else if (bPlayer.isAvatarState()) {
|
||||
factor = AvatarState.getValue(factor);
|
||||
} else {
|
||||
factor = maxChargeFactor * (double) (System.currentTimeMillis() - startTime) / (double) maxChargeTime;
|
||||
factor = maxChargeFactor * (double) (System.currentTimeMillis() - getStartTime()) / (double) maxChargeTime;
|
||||
}
|
||||
|
||||
charging = false;
|
||||
|
@ -308,7 +290,7 @@ public class AirSwipe extends AirAbility {
|
|||
factor = Math.max(1, factor);
|
||||
damage *= factor;
|
||||
pushFactor *= factor;
|
||||
} else if (System.currentTimeMillis() >= startTime + maxChargeTime) {
|
||||
} else if (System.currentTimeMillis() >= getStartTime() + maxChargeTime) {
|
||||
playAirbendingParticles(player.getEyeLocation(), particles);
|
||||
}
|
||||
}
|
||||
|
@ -328,7 +310,7 @@ public class AirSwipe extends AirAbility {
|
|||
public long getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -339,6 +321,25 @@ public class AirSwipe extends AirAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return origin != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return getRadius();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
for (Location swipeLoc : elements.values()) {
|
||||
locations.add(swipeLoc);
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public Location getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
@ -454,5 +455,5 @@ public class AirSwipe extends AirAbility {
|
|||
public void setStepSize(int stepSize) {
|
||||
this.stepSize = stepSize;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -20,10 +20,11 @@ import com.projectkorra.projectkorra.util.DamageHandler;
|
|||
/**
|
||||
* Suffocate
|
||||
*
|
||||
* Suffocate is an air ability that causes entities to be surrounded by a sphere air that causes
|
||||
* constant damage after a configurable delay. Suffocate also causes Blinding and Slowing affects to
|
||||
* entities depending on how the ability is configured. While in AvatarState this ability can be
|
||||
* used on multiple entities within a large radius. If the user is damaged while performing this
|
||||
* Suffocate is an air ability that causes entities to be surrounded by a sphere
|
||||
* air that causes constant damage after a configurable delay. Suffocate also
|
||||
* causes Blinding and Slowing affects to entities depending on how the ability
|
||||
* is configured. While in AvatarState this ability can be 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 extends AirAbility {
|
||||
|
@ -54,7 +55,7 @@ public class Suffocate extends AirAbility {
|
|||
private Suffocate ability;
|
||||
private ArrayList<BukkitRunnable> tasks;
|
||||
private ArrayList<LivingEntity> targets;
|
||||
|
||||
|
||||
public Suffocate(Player player) {
|
||||
super(player);
|
||||
ability = this;
|
||||
|
@ -131,7 +132,7 @@ public class Suffocate extends AirAbility {
|
|||
targets.add((LivingEntity) target);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!canSuffocateUndead) {
|
||||
for (int i = 0; i < targets.size(); i++) {
|
||||
LivingEntity target = targets.get(i);
|
||||
|
@ -150,10 +151,7 @@ public class Suffocate extends AirAbility {
|
|||
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().distanceSquared(player.getEyeLocation()) > range * range
|
||||
|| GeneralMethods.isRegionProtectedFromBuild(this, target.getLocation())) {
|
||||
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) {
|
||||
|
@ -171,11 +169,10 @@ public class Suffocate extends AirAbility {
|
|||
|
||||
if (requireConstantAim) {
|
||||
double dist = 0;
|
||||
if(player.getWorld().equals(targets.get(0).getWorld())) {
|
||||
if (player.getWorld().equals(targets.get(0).getWorld())) {
|
||||
dist = player.getEyeLocation().distance(targets.get(0).getEyeLocation());
|
||||
}
|
||||
Location targetLoc = player.getEyeLocation().clone()
|
||||
.add(player.getEyeLocation().getDirection().normalize().multiply(dist));
|
||||
Location targetLoc = player.getEyeLocation().clone().add(player.getEyeLocation().getDirection().normalize().multiply(dist));
|
||||
List<Entity> ents = GeneralMethods.getEntitiesAroundPoint(targetLoc, constantAimRadius);
|
||||
|
||||
for (int i = 0; i < targets.size(); i++) {
|
||||
|
@ -191,7 +188,7 @@ public class Suffocate extends AirAbility {
|
|||
}
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() - startTime < chargeTime) {
|
||||
if (System.currentTimeMillis() - getStartTime() < chargeTime) {
|
||||
return;
|
||||
} else if (!started) {
|
||||
started = true;
|
||||
|
@ -257,7 +254,8 @@ public class Suffocate extends AirAbility {
|
|||
}
|
||||
|
||||
/**
|
||||
* Removes an instance of Suffocate if player is the one suffocating entities
|
||||
* Removes an instance of Suffocate if player is the one suffocating
|
||||
* entities
|
||||
**/
|
||||
public static void remove(Player player) {
|
||||
Suffocate suff = getAbility(player, Suffocate.class);
|
||||
|
@ -267,9 +265,9 @@ public class Suffocate extends AirAbility {
|
|||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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
|
||||
**/
|
||||
|
@ -290,13 +288,14 @@ public class Suffocate extends AirAbility {
|
|||
}
|
||||
|
||||
/**
|
||||
* Animates this instance of the Suffocate ability. Depending on the specific time (dt) the
|
||||
* ability will create a different set of SuffocationSpirals.
|
||||
* 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 dt = curTime - getStartTime() - chargeTime;
|
||||
long delay = 2 / particleCount;
|
||||
long t1 = (long) (1500 * animationSpeed);
|
||||
long t2 = (long) (2500 * animationSpeed);
|
||||
|
@ -305,10 +304,8 @@ public class Suffocate extends AirAbility {
|
|||
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);
|
||||
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);
|
||||
|
@ -318,15 +315,9 @@ public class Suffocate extends AirAbility {
|
|||
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);
|
||||
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);
|
||||
|
@ -354,9 +345,9 @@ public class Suffocate extends AirAbility {
|
|||
}
|
||||
|
||||
/**
|
||||
* ** 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
|
||||
* another.
|
||||
* 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 another.
|
||||
*/
|
||||
public class SuffocateSpiral extends BukkitRunnable {
|
||||
private Location startLoc;
|
||||
|
@ -378,8 +369,7 @@ public class Suffocate extends AirAbility {
|
|||
* @param dz z offset
|
||||
* @param type Spiral animation direction
|
||||
*/
|
||||
public SuffocateSpiral(LivingEntity lent, int totalSteps, double radius, long interval, double dx, double dy, double dz,
|
||||
SpiralType type) {
|
||||
public SuffocateSpiral(LivingEntity lent, int totalSteps, double radius, long interval, double dx, double dy, double dz, SpiralType type) {
|
||||
this.target = lent;
|
||||
this.totalSteps = totalSteps;
|
||||
this.radius = radius;
|
||||
|
@ -403,8 +393,7 @@ public class Suffocate extends AirAbility {
|
|||
* @param dz z offset
|
||||
* @param type Spiral animation direction
|
||||
*/
|
||||
public SuffocateSpiral(Location startLoc, int totalSteps, double radius, long interval, double dx, double dy, double dz,
|
||||
SpiralType type) {
|
||||
public SuffocateSpiral(Location startLoc, int totalSteps, double radius, long interval, double dx, double dy, double dz, SpiralType type) {
|
||||
this.startLoc = startLoc;
|
||||
this.totalSteps = totalSteps;
|
||||
this.radius = radius;
|
||||
|
@ -483,7 +472,7 @@ public class Suffocate extends AirAbility {
|
|||
public long getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -494,6 +483,13 @@ public class Suffocate extends AirAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
locations.add(player.getLocation());
|
||||
return locations;
|
||||
}
|
||||
|
||||
public boolean isStarted() {
|
||||
return started;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ public class Tornado extends AirAbility {
|
|||
|
||||
public Tornado(Player player) {
|
||||
super(player);
|
||||
|
||||
|
||||
this.range = getConfig().getDouble("Abilities.Air.Tornado.Range");
|
||||
this.origin = player.getTargetBlock((HashSet<Material>) null, (int) range).getLocation();
|
||||
this.origin.setY(origin.getY() - 1.0 / 10.0 * currentHeight);
|
||||
|
@ -77,7 +77,7 @@ public class Tornado extends AirAbility {
|
|||
}
|
||||
rotateTornado();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
|
@ -199,7 +199,7 @@ public class Tornado extends AirAbility {
|
|||
public long getCooldown() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -210,6 +210,11 @@ public class Tornado extends AirAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return getRadius();
|
||||
}
|
||||
|
||||
public Location getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
|
|
@ -192,7 +192,7 @@ public class ChiCombo extends ChiAbility implements ComboAbility {
|
|||
|
||||
public class Immobilize extends ChiCombo {
|
||||
|
||||
public Immobilize(Player player, String name) {
|
||||
public Immobilize(Player player) {
|
||||
super(player, "Immobilize");
|
||||
}
|
||||
|
||||
|
|
|
@ -630,7 +630,7 @@ public class ConfigManager {
|
|||
config.addDefault("Abilities.Water.IceBlast.Damage", 3);
|
||||
config.addDefault("Abilities.Water.IceBlast.Range", 20);
|
||||
config.addDefault("Abilities.Water.IceBlast.DeflectRange", 3);
|
||||
config.addDefault("Abilities.Water.IceBlast.CollisionRadius", 2);
|
||||
config.addDefault("Abilities.Water.IceBlast.CollisionRadius", 0.5);
|
||||
config.addDefault("Abilities.Water.IceBlast.Interval", 20);
|
||||
config.addDefault("Abilities.Water.IceBlast.Cooldown", 1500);
|
||||
|
||||
|
@ -650,7 +650,7 @@ public class ConfigManager {
|
|||
config.addDefault("Abilities.Water.IceSpike.Field.Cooldown", 2000);
|
||||
config.addDefault("Abilities.Water.IceSpike.Blast.Range", 20);
|
||||
config.addDefault("Abilities.Water.IceSpike.Blast.Damage", 1);
|
||||
config.addDefault("Abilities.Water.IceSpike.Blast.CollisionRadius", 2);
|
||||
config.addDefault("Abilities.Water.IceSpike.Blast.CollisionRadius", 0.5);
|
||||
config.addDefault("Abilities.Water.IceSpike.Blast.DeflectRange", 3);
|
||||
config.addDefault("Abilities.Water.IceSpike.Blast.Cooldown", 500);
|
||||
config.addDefault("Abilities.Water.IceSpike.Blast.SlowCooldown", 5000);
|
||||
|
@ -775,7 +775,7 @@ public class ConfigManager {
|
|||
config.addDefault("Abilities.Water.WaterManipulation.Damage", 3.0);
|
||||
config.addDefault("Abilities.Water.WaterManipulation.Range", 25);
|
||||
config.addDefault("Abilities.Water.WaterManipulation.SelectRange", 16);
|
||||
config.addDefault("Abilities.Water.WaterManipulation.CollisionRadius", 2);
|
||||
config.addDefault("Abilities.Water.WaterManipulation.CollisionRadius", 0.5);
|
||||
config.addDefault("Abilities.Water.WaterManipulation.DeflectRange", 3);
|
||||
config.addDefault("Abilities.Water.WaterManipulation.Speed", 35);
|
||||
config.addDefault("Abilities.Water.WaterManipulation.Push", 0.3);
|
||||
|
@ -844,7 +844,7 @@ public class ConfigManager {
|
|||
config.addDefault("Abilities.Earth.EarthBlast.Push", 0.3);
|
||||
config.addDefault("Abilities.Earth.EarthBlast.Cooldown", 500);
|
||||
config.addDefault("Abilities.Earth.EarthBlast.DeflectRange", 3);
|
||||
config.addDefault("Abilities.Earth.EarthBlast.CollisionRadius", 2);
|
||||
config.addDefault("Abilities.Earth.EarthBlast.CollisionRadius", 0.5);
|
||||
|
||||
config.addDefault("Abilities.Earth.EarthGrab.Enabled", true);
|
||||
config.addDefault("Abilities.Earth.EarthGrab.SelectRange", 20);
|
||||
|
@ -974,7 +974,7 @@ public class ConfigManager {
|
|||
config.addDefault("Abilities.Fire.FireBlast.Enabled", true);
|
||||
config.addDefault("Abilities.Fire.FireBlast.Speed", 20);
|
||||
config.addDefault("Abilities.Fire.FireBlast.Range", 20);
|
||||
config.addDefault("Abilities.Fire.FireBlast.CollisionRadius", 2);
|
||||
config.addDefault("Abilities.Fire.FireBlast.CollisionRadius", 0.5);
|
||||
config.addDefault("Abilities.Fire.FireBlast.Push", 0.3);
|
||||
config.addDefault("Abilities.Fire.FireBlast.Damage", 3);
|
||||
config.addDefault("Abilities.Fire.FireBlast.Cooldown", 1500);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.projectkorra.projectkorra.earthbending;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
@ -25,15 +27,15 @@ public class Collapse extends EarthAbility {
|
|||
private Vector direction;
|
||||
private Block block;
|
||||
private Map<Block, Block> affectedBlocks;
|
||||
|
||||
|
||||
public Collapse(Player player) {
|
||||
super(player);
|
||||
setFields();
|
||||
|
||||
|
||||
if (!bPlayer.canBend(this) || bPlayer.isOnCooldown("CollapsePillar")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
block = BlockSource.getEarthSourceBlock(player, selectRange, ClickType.LEFT_CLICK);
|
||||
if (block == null) {
|
||||
return;
|
||||
|
@ -83,7 +85,7 @@ public class Collapse extends EarthAbility {
|
|||
private void loadAffectedBlocks() {
|
||||
affectedBlocks.clear();
|
||||
Block thisBlock;
|
||||
|
||||
|
||||
for (int i = 0; i <= distance; i++) {
|
||||
thisBlock = block.getWorld().getBlockAt(location.clone().add(direction.clone().multiply(-i)));
|
||||
affectedBlocks.put(thisBlock, thisBlock);
|
||||
|
@ -125,7 +127,7 @@ public class Collapse extends EarthAbility {
|
|||
if (distance == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
moveEarth(block, direction, distance);
|
||||
loadAffectedBlocks();
|
||||
return location.distanceSquared(origin) < distance * distance;
|
||||
|
@ -156,6 +158,15 @@ public class Collapse extends EarthAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
for (Block block : affectedBlocks.values()) {
|
||||
locations.add(block.getLocation());
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public Location getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,6 @@
|
|||
package com.projectkorra.projectkorra.earthbending;
|
||||
|
||||
import com.projectkorra.projectkorra.BendingPlayer;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.EarthAbility;
|
||||
import com.projectkorra.projectkorra.ability.WaterAbility;
|
||||
import com.projectkorra.projectkorra.firebending.Combustion;
|
||||
import com.projectkorra.projectkorra.firebending.FireBlast;
|
||||
import com.projectkorra.projectkorra.util.BlockSource;
|
||||
import com.projectkorra.projectkorra.util.ClickType;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterManipulation;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
|
@ -20,7 +10,14 @@ import org.bukkit.entity.LivingEntity;
|
|||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import com.projectkorra.projectkorra.BendingPlayer;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.EarthAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.util.BlockSource;
|
||||
import com.projectkorra.projectkorra.util.ClickType;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
|
||||
public class EarthBlast extends EarthAbility {
|
||||
|
||||
|
@ -47,7 +44,7 @@ public class EarthBlast extends EarthAbility {
|
|||
|
||||
public EarthBlast(Player player) {
|
||||
super(player);
|
||||
|
||||
|
||||
this.isProgressing = false;
|
||||
this.isAtDestination = false;
|
||||
this.isSettingUp = true;
|
||||
|
@ -59,10 +56,10 @@ public class EarthBlast extends EarthAbility {
|
|||
this.damage = getConfig().getDouble("Abilities.Earth.EarthBlast.Damage");
|
||||
this.speed = getConfig().getDouble("Abilities.Earth.EarthBlast.Speed");
|
||||
this.pushFactor = getConfig().getDouble("Abilities.Earth.EarthBlast.Push");
|
||||
this.selectRange = getConfig().getDouble("Abilities.Earth.EarthBlast.SelectRange");
|
||||
this.selectRange = getConfig().getDouble("Abilities.Earth.EarthBlast.SelectRange");
|
||||
this.time = System.currentTimeMillis();
|
||||
this.interval = (long) (1000.0 / speed);
|
||||
|
||||
|
||||
if (prepare()) {
|
||||
start();
|
||||
time = System.currentTimeMillis();
|
||||
|
@ -84,9 +81,7 @@ public class EarthBlast extends EarthAbility {
|
|||
Location location = player.getEyeLocation();
|
||||
Vector vector = location.getDirection();
|
||||
Location mloc = blast.location;
|
||||
if (mloc.distanceSquared(location) <= range * range
|
||||
&& GeneralMethods.getDistanceFromLine(vector, location, blast.location) < deflectRange
|
||||
&& mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) {
|
||||
if (mloc.distanceSquared(location) <= range * range && GeneralMethods.getDistanceFromLine(vector, location, blast.location) < deflectRange && mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) {
|
||||
blast.remove();
|
||||
remove();
|
||||
return;
|
||||
|
@ -99,7 +94,7 @@ public class EarthBlast extends EarthAbility {
|
|||
if (EarthPassive.isPassiveSand(sourceBlock)) {
|
||||
EarthPassive.revertSand(sourceBlock);
|
||||
}
|
||||
|
||||
|
||||
sourceData = sourceBlock.getData();
|
||||
if (sourceBlock.getType() == Material.SAND) {
|
||||
sourceType = Material.SAND;
|
||||
|
@ -107,7 +102,7 @@ public class EarthBlast extends EarthAbility {
|
|||
sourceBlock.setType(Material.RED_SANDSTONE);
|
||||
} else {
|
||||
sourceBlock.setType(Material.SANDSTONE);
|
||||
}
|
||||
}
|
||||
} else if (sourceBlock.getType() == Material.STEP) {
|
||||
sourceBlock.setType(Material.STEP);
|
||||
sourceType = Material.STEP;
|
||||
|
@ -125,7 +120,7 @@ public class EarthBlast extends EarthAbility {
|
|||
private Location getTargetLocation() {
|
||||
Entity target = GeneralMethods.getTargetedEntity(player, range, new ArrayList<Entity>());
|
||||
Location location;
|
||||
|
||||
|
||||
if (target == null) {
|
||||
location = GeneralMethods.getTargetedLocation(player, range);
|
||||
} else {
|
||||
|
@ -139,7 +134,7 @@ public class EarthBlast extends EarthAbility {
|
|||
if (block == null || !isEarthbendable(block)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
boolean selectedABlockInUse = false;
|
||||
for (EarthBlast blast : getAbilities(player, EarthBlast.class)) {
|
||||
if (!blast.isProgressing) {
|
||||
|
@ -148,11 +143,11 @@ public class EarthBlast extends EarthAbility {
|
|||
selectedABlockInUse = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (selectedABlockInUse) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
checkForCollision();
|
||||
if (block.getLocation().distanceSquared(player.getLocation()) > selectRange * selectRange) {
|
||||
return false;
|
||||
|
@ -169,7 +164,7 @@ public class EarthBlast extends EarthAbility {
|
|||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (System.currentTimeMillis() - time >= interval) {
|
||||
time = System.currentTimeMillis();
|
||||
|
||||
|
@ -213,8 +208,8 @@ public class EarthBlast extends EarthAbility {
|
|||
}
|
||||
|
||||
location = location.clone().add(direction);
|
||||
Block block = location.getBlock();
|
||||
|
||||
Block block = location.getBlock();
|
||||
|
||||
if (block.getLocation().equals(sourceBlock.getLocation())) {
|
||||
location = location.clone().add(direction);
|
||||
block = location.getBlock();
|
||||
|
@ -229,19 +224,6 @@ public class EarthBlast extends EarthAbility {
|
|||
location = location.clone().subtract(direction);
|
||||
direction = GeneralMethods.getDirection(location, destination).normalize();
|
||||
location = location.clone().add(direction);
|
||||
|
||||
WaterAbility.removeWaterSpouts(location, player);
|
||||
AirAbility.removeAirSpouts(location, player);
|
||||
EarthAbility.removeSandSpouts(location, player);
|
||||
|
||||
if (EarthBlast.annihilateBlasts(location, collisionRadius, player)
|
||||
|| WaterManipulation.annihilateBlasts(location, collisionRadius, player)
|
||||
|| FireBlast.annihilateBlasts(location, collisionRadius, player)) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
Combustion.removeAroundPoint(location, collisionRadius);
|
||||
|
||||
Block block2 = location.getBlock();
|
||||
if (block2.getLocation().equals(sourceBlock.getLocation())) {
|
||||
|
@ -263,12 +245,12 @@ public class EarthBlast extends EarthAbility {
|
|||
}
|
||||
if (entity instanceof LivingEntity && (entity.getEntityId() != player.getEntityId() || canHitSelf)) {
|
||||
AirAbility.breakBreathbendingHold(entity);
|
||||
|
||||
|
||||
Location location = player.getEyeLocation();
|
||||
Vector vector = location.getDirection();
|
||||
entity.setVelocity(vector.normalize().multiply(pushFactor));
|
||||
double damage = this.damage;
|
||||
|
||||
double damage = this.damage;
|
||||
|
||||
if (isMetal(sourceBlock) && bPlayer.canMetalbend()) {
|
||||
damage = getMetalAugment(damage);
|
||||
}
|
||||
|
@ -290,7 +272,7 @@ public class EarthBlast extends EarthAbility {
|
|||
}
|
||||
|
||||
moveEarthBlock(sourceBlock, block);
|
||||
|
||||
|
||||
if (block.getType() == Material.SAND) {
|
||||
block.setType(Material.SANDSTONE);
|
||||
}
|
||||
|
@ -311,8 +293,7 @@ public class EarthBlast extends EarthAbility {
|
|||
sourceType = Material.SAND;
|
||||
sourceBlock.setType(sourceType);
|
||||
sourceBlock.setData((byte) 0x1);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sourceBlock.setType(sourceType);
|
||||
}
|
||||
}
|
||||
|
@ -338,7 +319,7 @@ public class EarthBlast extends EarthAbility {
|
|||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
if(destination != null && sourceBlock != null) {
|
||||
if (destination != null && sourceBlock != null) {
|
||||
sourceBlock.setType(Material.AIR);
|
||||
} else if (sourceBlock != null) {
|
||||
if (sourceBlock.getType() == Material.SAND) {
|
||||
|
@ -360,13 +341,13 @@ public class EarthBlast extends EarthAbility {
|
|||
if (sourceBlock == null || !sourceBlock.getWorld().equals(player.getWorld())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (getMovedEarth().containsKey(sourceBlock)) {
|
||||
if (!isEarthRevertOn()) {
|
||||
removeRevertIndex(sourceBlock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Entity target = GeneralMethods.getTargetedEntity(player, range, new ArrayList<Entity>());
|
||||
if (target == null) {
|
||||
destination = getTargetEarthBlock((int) range).getLocation();
|
||||
|
@ -378,12 +359,12 @@ public class EarthBlast extends EarthAbility {
|
|||
firstDestination.setY(destination.getY());
|
||||
destination = GeneralMethods.getPointOnLine(firstDestination, destination, range);
|
||||
}
|
||||
|
||||
|
||||
if (destination.distanceSquared(location) <= 1) {
|
||||
isProgressing = false;
|
||||
destination = null;
|
||||
} else {
|
||||
isProgressing = true;
|
||||
isProgressing = true;
|
||||
playEarthbendingSound(sourceBlock.getLocation());
|
||||
|
||||
Material currentType = sourceBlock.getType();
|
||||
|
@ -393,11 +374,16 @@ public class EarthBlast extends EarthAbility {
|
|||
addTempAirBlock(sourceBlock);
|
||||
} else {
|
||||
sourceBlock.breakNaturally();
|
||||
}
|
||||
}
|
||||
sourceBlock.setType(currentType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean annihilateBlasts(Location location, double radius, Player source) {
|
||||
boolean broke = false;
|
||||
for (EarthBlast blast : getAbilities(EarthBlast.class)) {
|
||||
|
@ -409,7 +395,7 @@ public class EarthBlast extends EarthAbility {
|
|||
}
|
||||
}
|
||||
return broke;
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayList<EarthBlast> getAroundPoint(Location location, double radius) {
|
||||
ArrayList<EarthBlast> list = new ArrayList<EarthBlast>();
|
||||
|
@ -447,11 +433,8 @@ public class EarthBlast extends EarthAbility {
|
|||
Location location = player.getEyeLocation();
|
||||
Vector vector = location.getDirection();
|
||||
Location mloc = blast.location;
|
||||
|
||||
if (mloc.distanceSquared(location) <= blast.range * blast.range
|
||||
&& GeneralMethods.getDistanceFromLine(vector, location, blast.location) < blast.deflectRange
|
||||
&& mloc.distanceSquared(location.clone().add(vector))
|
||||
< mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) {
|
||||
|
||||
if (mloc.distanceSquared(location) <= blast.range * blast.range && GeneralMethods.getDistanceFromLine(vector, location, blast.location) < blast.deflectRange && mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) {
|
||||
blast.redirect(player, blast.getTargetLocation());
|
||||
}
|
||||
|
||||
|
@ -472,11 +455,11 @@ public class EarthBlast extends EarthAbility {
|
|||
ArrayList<EarthBlast> ignore = new ArrayList<EarthBlast>();
|
||||
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
|
||||
EarthBlast earthBlast = null;
|
||||
|
||||
|
||||
if (bPlayer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (EarthBlast blast : getAbilities(player, EarthBlast.class)) {
|
||||
if (!blast.isProgressing && bPlayer.canBend(blast)) {
|
||||
blast.throwEarth();
|
||||
|
@ -505,7 +488,7 @@ public class EarthBlast extends EarthAbility {
|
|||
public long getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -516,6 +499,16 @@ public class EarthBlast extends EarthAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return isProgressing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return collisionRadius;
|
||||
}
|
||||
|
||||
public boolean isProgressing() {
|
||||
return isProgressing;
|
||||
}
|
||||
|
@ -612,10 +605,6 @@ public class EarthBlast extends EarthAbility {
|
|||
this.deflectRange = deflectRange;
|
||||
}
|
||||
|
||||
public double getCollisionRadius() {
|
||||
return collisionRadius;
|
||||
}
|
||||
|
||||
public void setCollisionRadius(double collisionRadius) {
|
||||
this.collisionRadius = collisionRadius;
|
||||
}
|
||||
|
@ -660,4 +649,4 @@ public class EarthBlast extends EarthAbility {
|
|||
this.location = location;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,8 @@
|
|||
package com.projectkorra.projectkorra.earthbending;
|
||||
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.EarthAbility;
|
||||
import com.projectkorra.projectkorra.ability.WaterAbility;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.util.ClickType;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect;
|
||||
import com.projectkorra.projectkorra.util.TempBlock;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
|
@ -19,12 +13,16 @@ import org.bukkit.entity.LivingEntity;
|
|||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.EarthAbility;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.util.ClickType;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect;
|
||||
import com.projectkorra.projectkorra.util.TempBlock;
|
||||
|
||||
public class EarthSmash extends EarthAbility {
|
||||
|
||||
|
||||
public static enum State {
|
||||
START, LIFTING, LIFTED, GRABBED, SHOT, FLYING, REMOVED
|
||||
}
|
||||
|
@ -64,7 +62,7 @@ public class EarthSmash extends EarthAbility {
|
|||
|
||||
public EarthSmash(Player player, ClickType type) {
|
||||
super(player);
|
||||
|
||||
|
||||
this.state = State.START;
|
||||
this.requiredBendableBlocks = getConfig().getInt("Abilities.Earth.EarthSmash.RequiredBendableBlocks");
|
||||
this.maxBlocksToPassThrough = getConfig().getInt("Abilities.Earth.EarthSmash.MaxBlocksToPassThrough");
|
||||
|
@ -89,7 +87,7 @@ public class EarthSmash extends EarthAbility {
|
|||
this.affectedEntities = new ArrayList<>();
|
||||
this.currentBlocks = new ArrayList<>();
|
||||
this.affectedBlocks = new ArrayList<>();
|
||||
|
||||
|
||||
if (type == ClickType.SHIFT_DOWN || type == ClickType.SHIFT_UP && !player.isSneaking()) {
|
||||
if (bPlayer.isAvatarState()) {
|
||||
selectRange = AvatarState.getValue(selectRange);
|
||||
|
@ -119,17 +117,17 @@ public class EarthSmash extends EarthAbility {
|
|||
}
|
||||
grabbedSmash = aimingAtSmashCheck(player, State.SHOT);
|
||||
}
|
||||
|
||||
|
||||
if (grabbedSmash != null) {
|
||||
grabbedSmash.state = State.GRABBED;
|
||||
grabbedSmash.grabbedDistance = 0;
|
||||
if(grabbedSmash.location.getWorld().equals(player.getWorld())) {
|
||||
if (grabbedSmash.location.getWorld().equals(player.getWorld())) {
|
||||
grabbedSmash.grabbedDistance = grabbedSmash.location.distance(player.getEyeLocation());
|
||||
}
|
||||
grabbedSmash.player = player;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
start();
|
||||
} else if (type == ClickType.LEFT_CLICK && player.isSneaking()) {
|
||||
for (EarthSmash smash : getAbilities(EarthSmash.class)) {
|
||||
|
@ -155,11 +153,11 @@ public class EarthSmash extends EarthAbility {
|
|||
@Override
|
||||
public void progress() {
|
||||
progressCounter++;
|
||||
if (state == State.LIFTED && removeTimer > 0 && System.currentTimeMillis() - startTime > removeTimer) {
|
||||
if (state == State.LIFTED && removeTimer > 0 && System.currentTimeMillis() - getStartTime() > removeTimer) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (state == State.START) {
|
||||
if (!bPlayer.canBend(this)) {
|
||||
remove();
|
||||
|
@ -174,7 +172,7 @@ public class EarthSmash extends EarthAbility {
|
|||
|
||||
if (state == State.START && progressCounter > 1) {
|
||||
if (!player.isSneaking()) {
|
||||
if (System.currentTimeMillis() - startTime >= chargeTime) {
|
||||
if (System.currentTimeMillis() - getStartTime() >= chargeTime) {
|
||||
origin = getEarthSourceBlock(selectRange);
|
||||
if (origin == null) {
|
||||
remove();
|
||||
|
@ -187,7 +185,7 @@ public class EarthSmash extends EarthAbility {
|
|||
remove();
|
||||
return;
|
||||
}
|
||||
} else if (System.currentTimeMillis() - startTime > chargeTime) {
|
||||
} else if (System.currentTimeMillis() - getStartTime() > chargeTime) {
|
||||
Location tempLoc = player.getEyeLocation().add(player.getEyeLocation().getDirection().normalize().multiply(1.2));
|
||||
tempLoc.add(0, 0.3, 0);
|
||||
ParticleEffect.SMOKE.display(tempLoc, 0.3F, 0.1F, 0.3F, 0, 4);
|
||||
|
@ -210,10 +208,7 @@ public class EarthSmash extends EarthAbility {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WaterAbility.removeWaterSpouts(location, 2, player);
|
||||
AirAbility.removeAirSpouts(location, 2, player);
|
||||
EarthAbility.removeSandSpouts(location, player);
|
||||
|
||||
draw();
|
||||
return;
|
||||
} else {
|
||||
|
@ -227,20 +222,18 @@ public class EarthSmash extends EarthAbility {
|
|||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
revert();
|
||||
location.add(GeneralMethods.getDirection(location, destination).normalize().multiply(1));
|
||||
if (location.distanceSquared(destination) < 4) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// If an earthsmash runs into too many blocks we should remove it
|
||||
int badBlocksFound = 0;
|
||||
for (Block block : getBlocks()) {
|
||||
if (block.getType() != Material.AIR && (!isTransparent(block)
|
||||
|| block.getType() == Material.WATER
|
||||
|| block.getType() == Material.STATIONARY_WATER)) {
|
||||
if (block.getType() != Material.AIR && (!isTransparent(block) || block.getType() == Material.WATER || block.getType() == Material.STATIONARY_WATER)) {
|
||||
badBlocksFound++;
|
||||
}
|
||||
}
|
||||
|
@ -249,8 +242,6 @@ public class EarthSmash extends EarthAbility {
|
|||
remove();
|
||||
return;
|
||||
}
|
||||
WaterAbility.removeWaterSpouts(location, 2, player);
|
||||
AirAbility.removeAirSpouts(location, 2, player);
|
||||
shootingCollisionDetection();
|
||||
draw();
|
||||
smashToSmashCollisionDetection();
|
||||
|
@ -298,10 +289,10 @@ public class EarthSmash extends EarthAbility {
|
|||
|
||||
/**
|
||||
* Begins animating the EarthSmash from the ground. The lift animation
|
||||
* consists of 3 steps, and each one has to design the shape in the
|
||||
* ground that removes the Earthbendable material. We also need to make
|
||||
* sure that there is a clear path for the EarthSmash to rise, and that
|
||||
* there is enough Earthbendable material for it to be created.
|
||||
* consists of 3 steps, and each one has to design the shape in the ground
|
||||
* that removes the Earthbendable material. We also need to make sure that
|
||||
* there is a clear path for the EarthSmash to rise, and that there is
|
||||
* enough Earthbendable material for it to be created.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void animateLift() {
|
||||
|
@ -368,7 +359,7 @@ public class EarthSmash extends EarthAbility {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We needed to calculate all of the blocks based on the
|
||||
* location being 1 above the initial bending block, however we
|
||||
|
@ -424,14 +415,13 @@ public class EarthSmash extends EarthAbility {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks to see which of the blocks are still attached to the
|
||||
* EarthSmash, remember that blocks can be broken or used in other
|
||||
* abilities so we need to double check and remove any that are not
|
||||
* still attached.
|
||||
* Checks to see which of the blocks are still attached to the EarthSmash,
|
||||
* remember that blocks can be broken or used in other abilities so we need
|
||||
* to double check and remove any that are not still attached.
|
||||
*
|
||||
* Also when we remove the blocks from instances, movedearth, or tempair
|
||||
* we should do it on a delay because tempair takes a couple seconds
|
||||
* before the block shows up in that map.
|
||||
* Also when we remove the blocks from instances, movedearth, or tempair we
|
||||
* should do it on a delay because tempair takes a couple seconds before the
|
||||
* block shows up in that map.
|
||||
*/
|
||||
public void checkRemainingBlocks() {
|
||||
for (int i = 0; i < currentBlocks.size(); i++) {
|
||||
|
@ -452,9 +442,8 @@ public class EarthSmash extends EarthAbility {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the blocks surrounding the EarthSmash's loc. This method ignores
|
||||
* the blocks that should be Air, and only returns the ones that are
|
||||
* dirt.
|
||||
* Gets the blocks surrounding the EarthSmash's loc. This method ignores the
|
||||
* blocks that should be Air, and only returns the ones that are dirt.
|
||||
*/
|
||||
public List<Block> getBlocks() {
|
||||
List<Block> blocks = new ArrayList<Block>();
|
||||
|
@ -473,8 +462,8 @@ public class EarthSmash extends EarthAbility {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the blocks surrounding the EarthSmash's loc. This method returns
|
||||
* all the blocks surrounding the loc, including dirt and air.
|
||||
* Gets the blocks surrounding the EarthSmash's loc. This method returns all
|
||||
* the blocks surrounding the loc, including dirt and air.
|
||||
*/
|
||||
public List<Block> getBlocksIncludingInner() {
|
||||
List<Block> blocks = new ArrayList<Block>();
|
||||
|
@ -489,7 +478,7 @@ public class EarthSmash extends EarthAbility {
|
|||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Switches the Sand Material and Gravel to SandStone and stone
|
||||
* respectively, since gravel and sand cannot be bent due to gravity.
|
||||
|
@ -516,17 +505,16 @@ public class EarthSmash extends EarthAbility {
|
|||
}
|
||||
return tempMat;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines if a player is trying to grab an EarthSmash. A player is
|
||||
* trying to grab an EarthSmash if they are staring at it and holding
|
||||
* shift.
|
||||
* trying to grab an EarthSmash if they are staring at it and holding shift.
|
||||
*/
|
||||
private EarthSmash aimingAtSmashCheck(Player player, State reqState) {
|
||||
if (!allowGrab) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
List<Block> blocks = GeneralMethods.getBlocksAroundPoint(GeneralMethods.getTargetedLocation(player, grabRange, GeneralMethods.NON_OPAQUE), 1);
|
||||
for (EarthSmash smash : getAbilities(EarthSmash.class)) {
|
||||
if (reqState == null || smash.state == reqState) {
|
||||
|
@ -534,8 +522,7 @@ public class EarthSmash extends EarthAbility {
|
|||
if (block == null || smash.getLocation() == null) {
|
||||
continue;
|
||||
}
|
||||
if (block.getLocation().getWorld() == smash.location.getWorld()
|
||||
&& block.getLocation().distanceSquared(smash.location) <= Math.pow(grabDetectionRadius, 2)) {
|
||||
if (block.getLocation().getWorld() == smash.location.getWorld() && block.getLocation().distanceSquared(smash.location) <= Math.pow(grabDetectionRadius, 2)) {
|
||||
return smash;
|
||||
}
|
||||
}
|
||||
|
@ -546,8 +533,8 @@ public class EarthSmash extends EarthAbility {
|
|||
|
||||
/**
|
||||
* This method handles any collision between an EarthSmash and the
|
||||
* surrounding entities, the method only applies to earthsmashes that
|
||||
* have already been shot.
|
||||
* surrounding entities, the method only applies to earthsmashes that have
|
||||
* already been shot.
|
||||
*/
|
||||
public void shootingCollisionDetection() {
|
||||
List<Entity> entities = GeneralMethods.getEntitiesAroundPoint(location, flightDetectionRadius);
|
||||
|
@ -561,28 +548,27 @@ public class EarthSmash extends EarthAbility {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* EarthSmash to EarthSmash collision can only happen when one of the
|
||||
* Smashes have been shot by a player. If we find out that one of them
|
||||
* have collided then we want to return since a smash can only remove 1
|
||||
* at a time.
|
||||
* Smashes have been shot by a player. If we find out that one of them have
|
||||
* collided then we want to return since a smash can only remove 1 at a
|
||||
* time.
|
||||
*/
|
||||
public void smashToSmashCollisionDetection() {
|
||||
for (EarthSmash smash : getAbilities(EarthSmash.class)) {
|
||||
if (smash.location != null && smash != this && smash.location.getWorld() == location.getWorld()
|
||||
&& smash.location.distanceSquared(location) < Math.pow(flightDetectionRadius, 2)) {
|
||||
if (smash.location != null && smash != this && smash.location.getWorld() == location.getWorld() && smash.location.distanceSquared(location) < Math.pow(flightDetectionRadius, 2)) {
|
||||
smash.remove();
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines whether or not a player is trying to fly ontop of an
|
||||
* EarthSmash. A player is considered "flying" if they are standing
|
||||
* ontop of the earthsmash and holding shift.
|
||||
* EarthSmash. A player is considered "flying" if they are standing ontop of
|
||||
* the earthsmash and holding shift.
|
||||
*/
|
||||
private static EarthSmash flyingInSmashCheck(Player player) {
|
||||
for (EarthSmash smash : getAbilities(EarthSmash.class)) {
|
||||
|
@ -591,8 +577,7 @@ public class EarthSmash extends EarthAbility {
|
|||
}
|
||||
//Check to see if the player is standing on top of the smash.
|
||||
if (smash.state == State.LIFTED) {
|
||||
if (smash.location.getWorld().equals(player.getWorld())
|
||||
&& smash.location.clone().add(0, 2, 0).distanceSquared(player.getLocation()) <= Math.pow(smash.flightDetectionRadius, 2)) {
|
||||
if (smash.location.getWorld().equals(player.getWorld()) && smash.location.clone().add(0, 2, 0).distanceSquared(player.getLocation()) <= Math.pow(smash.flightDetectionRadius, 2)) {
|
||||
return smash;
|
||||
}
|
||||
}
|
||||
|
@ -601,12 +586,11 @@ public class EarthSmash extends EarthAbility {
|
|||
}
|
||||
|
||||
/**
|
||||
* A BlockRepresenter is used to keep track of each of the individual
|
||||
* types of blocks that are attached to an EarthSmash. Without the
|
||||
* representer then an EarthSmash can only be made up of 1 material at a
|
||||
* time. For example, an ESmash that is entirely dirt, coalore, or
|
||||
* sandstone. Using the representer will allow all the materials to be
|
||||
* mixed together.
|
||||
* A BlockRepresenter is used to keep track of each of the individual types
|
||||
* of blocks that are attached to an EarthSmash. Without the representer
|
||||
* then an EarthSmash can only be made up of 1 material at a time. For
|
||||
* example, an ESmash that is entirely dirt, coalore, or sandstone. Using
|
||||
* the representer will allow all the materials to be mixed together.
|
||||
*/
|
||||
public class BlockRepresenter {
|
||||
private int x, y, z;
|
||||
|
@ -706,7 +690,7 @@ public class EarthSmash extends EarthAbility {
|
|||
public long getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -717,6 +701,15 @@ public class EarthSmash extends EarthAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
for (TempBlock tblock : affectedBlocks) {
|
||||
locations.add(tblock.getLocation());
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public boolean isAllowGrab() {
|
||||
return allowGrab;
|
||||
}
|
||||
|
@ -836,7 +829,7 @@ public class EarthSmash extends EarthAbility {
|
|||
public void setGrabRange(double grabRange) {
|
||||
this.grabRange = grabRange;
|
||||
}
|
||||
|
||||
|
||||
public double getSelectRange() {
|
||||
return selectRange;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package com.projectkorra.projectkorra.earthbending;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
@ -16,7 +18,7 @@ import com.projectkorra.projectkorra.configuration.ConfigManager;
|
|||
import com.projectkorra.projectkorra.util.TempBlock;
|
||||
|
||||
public class EarthTunnel extends EarthAbility {
|
||||
|
||||
|
||||
private long interval;
|
||||
private long time;
|
||||
private double depth;
|
||||
|
@ -32,10 +34,10 @@ public class EarthTunnel extends EarthAbility {
|
|||
private Vector direction;
|
||||
|
||||
public static Map<TempBlock, Long> airBlocks = new ConcurrentHashMap<TempBlock, Long>();
|
||||
|
||||
|
||||
public EarthTunnel(Player player) {
|
||||
super(player);
|
||||
|
||||
|
||||
this.maxRadius = getConfig().getDouble("Abilities.Earth.EarthTunnel.MaxRadius");
|
||||
this.range = getConfig().getDouble("Abilities.Earth.EarthTunnel.Range");
|
||||
this.radius = getConfig().getDouble("Abilities.Earth.EarthTunnel.Radius");
|
||||
|
@ -43,21 +45,21 @@ public class EarthTunnel extends EarthAbility {
|
|||
this.revert = getConfig().getBoolean("Abilities.Earth.EarthTunnel.Revert");
|
||||
this.radiusIncrement = radius;
|
||||
this.time = System.currentTimeMillis();
|
||||
|
||||
|
||||
this.location = player.getEyeLocation().clone();
|
||||
this.origin = player.getTargetBlock((HashSet<Material>) null, (int) range).getLocation();
|
||||
this.block = origin.getBlock();
|
||||
this.direction = location.getDirection().clone().normalize();
|
||||
this.depth = 0;
|
||||
if(origin.getWorld().equals(location.getWorld())) {
|
||||
this.depth = Math.max(0, origin.distance(location) - 1);
|
||||
if (origin.getWorld().equals(location.getWorld())) {
|
||||
this.depth = Math.max(0, origin.distance(location) - 1);
|
||||
}
|
||||
this.angle = 0;
|
||||
|
||||
if (!bPlayer.canBend(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
|
@ -67,7 +69,7 @@ public class EarthTunnel extends EarthAbility {
|
|||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (System.currentTimeMillis() - time >= interval) {
|
||||
time = System.currentTimeMillis();
|
||||
if (Math.abs(Math.toDegrees(player.getEyeLocation().getDirection().angle(direction))) > 20 || !player.isSneaking()) {
|
||||
|
@ -79,7 +81,7 @@ public class EarthTunnel extends EarthAbility {
|
|||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (angle >= 360) {
|
||||
angle = 0;
|
||||
if (radius >= maxRadius) {
|
||||
|
@ -96,11 +98,11 @@ public class EarthTunnel extends EarthAbility {
|
|||
} else {
|
||||
angle += 20;
|
||||
}
|
||||
|
||||
|
||||
Vector vec = GeneralMethods.getOrthogonalVector(direction, angle, radius);
|
||||
block = location.clone().add(direction.clone().normalize().multiply(depth)).add(vec).getBlock();
|
||||
}
|
||||
|
||||
|
||||
if (revert) {
|
||||
if (getMovedEarth().containsKey(block)) {
|
||||
block.setType(Material.AIR);
|
||||
|
@ -128,7 +130,7 @@ public class EarthTunnel extends EarthAbility {
|
|||
public long getCooldown() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -139,6 +141,15 @@ public class EarthTunnel extends EarthAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
for (TempBlock tblock : airBlocks.keySet()) {
|
||||
locations.add(tblock.getLocation());
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public long getInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
@ -230,7 +241,7 @@ public class EarthTunnel extends EarthAbility {
|
|||
public void setLocation(Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
|
||||
public static void revertAirBlocks() {
|
||||
if (ConfigManager.defaultConfig.get().getBoolean("Abilities.Earth.EarthTunnel.Revert")) {
|
||||
for (TempBlock tempBlock : EarthTunnel.airBlocks.keySet()) {
|
||||
|
@ -241,5 +252,5 @@ public class EarthTunnel extends EarthAbility {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -18,12 +18,13 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class LavaFlow extends LavaAbility {
|
||||
|
||||
|
||||
public static enum AbilityType {
|
||||
SHIFT, CLICK
|
||||
}
|
||||
|
@ -31,7 +32,7 @@ public class LavaFlow extends LavaAbility {
|
|||
private static final Map<Block, TempBlock> TEMP_LAVA_BLOCKS = new ConcurrentHashMap<>();
|
||||
private static final Map<Block, TempBlock> TEMP_LAND_BLOCKS = new ConcurrentHashMap<>();
|
||||
private static final Map<Block, TempBlock> TEMP_AIR_BLOCKS = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
private boolean removing;
|
||||
private boolean makeLava;
|
||||
private boolean clickIsFinished;
|
||||
|
@ -66,7 +67,7 @@ public class LavaFlow extends LavaAbility {
|
|||
private ArrayList<TempBlock> affectedBlocks;
|
||||
private ArrayList<BukkitRunnable> tasks;
|
||||
private Material revertMaterial;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new LavaFlow ability and initializes all of the variables and
|
||||
* cooldowns. The ability is not guaranteed to continue, it may be the case
|
||||
|
@ -155,7 +156,7 @@ public class LavaFlow extends LavaAbility {
|
|||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
long cooldown = makeLava ? clickLavaCooldown : clickLandCooldown;
|
||||
origin = sourceBlock.getLocation();
|
||||
makeLava = !isLava(sourceBlock);
|
||||
|
@ -187,7 +188,7 @@ public class LavaFlow extends LavaAbility {
|
|||
}
|
||||
|
||||
Random random = new Random();
|
||||
|
||||
|
||||
if (type == AbilityType.SHIFT) {
|
||||
if (System.currentTimeMillis() - time > shiftRemoveDelay) {
|
||||
remove();
|
||||
|
@ -249,23 +250,20 @@ public class LavaFlow extends LavaAbility {
|
|||
createLava(block);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} else if (Math.random() < particleDensity
|
||||
&& dSquared < Math.pow(currentRadius + particleDensity, 2)
|
||||
&& currentRadius + particleDensity < shiftMaxRadius
|
||||
&& random.nextInt(3) == 0) {
|
||||
} else if (Math.random() < particleDensity && dSquared < Math.pow(currentRadius + particleDensity, 2) && currentRadius + particleDensity < shiftMaxRadius && random.nextInt(3) == 0) {
|
||||
ParticleEffect.LAVA.display(loc, (float) Math.random(), (float) Math.random(), (float) Math.random(), 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!shiftIsFinished) {
|
||||
|
||||
if (!shiftIsFinished) {
|
||||
if (random.nextInt(10) == 0) {
|
||||
ParticleEffect.LAVA.display(player.getLocation(), (float) Math.random(), (float) Math.random(), (float) Math.random(), 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
currentRadius += shiftFlowSpeed;
|
||||
if (currentRadius > shiftMaxRadius) {
|
||||
currentRadius = shiftMaxRadius;
|
||||
|
@ -274,16 +272,17 @@ public class LavaFlow extends LavaAbility {
|
|||
}
|
||||
} else if (type == AbilityType.CLICK) {
|
||||
/*
|
||||
* The variable makeLava refers to whether or not the ability is trying
|
||||
* to remove land in place of lava or if makeLava = false then lava is
|
||||
* being replaced with land.
|
||||
* The variable makeLava refers to whether or not the ability is
|
||||
* trying to remove land in place of lava or if makeLava = false
|
||||
* then lava is being replaced with land.
|
||||
*
|
||||
* Notice we have separate variables between both versions, because most
|
||||
* of the time making lava will have longer delays and longer cooldowns.
|
||||
* Notice we have separate variables between both versions, because
|
||||
* most of the time making lava will have longer delays and longer
|
||||
* cooldowns.
|
||||
*/
|
||||
long curTime = System.currentTimeMillis() - time;
|
||||
double delay = makeLava ? clickLavaDelay : clickLandDelay;
|
||||
|
||||
|
||||
if (makeLava && curTime > clickLavaCleanupDelay) {
|
||||
remove();
|
||||
return;
|
||||
|
@ -297,9 +296,8 @@ public class LavaFlow extends LavaAbility {
|
|||
for (double z = -clickLavaRadius; z <= clickLavaRadius; z++) {
|
||||
Location loc = origin.clone().add(x, 0, z);
|
||||
Block tempBlock = GeneralMethods.getTopBlock(loc, upwardFlow, downwardFlow);
|
||||
|
||||
if (tempBlock != null && !isLava(tempBlock) && Math.random() < particleDensity
|
||||
&& tempBlock.getLocation().distanceSquared(origin) <= Math.pow(clickLavaRadius, 2)) {
|
||||
|
||||
if (tempBlock != null && !isLava(tempBlock) && Math.random() < particleDensity && tempBlock.getLocation().distanceSquared(origin) <= Math.pow(clickLavaRadius, 2)) {
|
||||
if (random.nextInt(3) == 0) {
|
||||
ParticleEffect.LAVA.display(loc, (float) Math.random(), (float) Math.random(), (float) Math.random(), 0, 1);
|
||||
}
|
||||
|
@ -317,7 +315,7 @@ public class LavaFlow extends LavaAbility {
|
|||
if (!clickIsFinished) {
|
||||
clickIsFinished = true;
|
||||
double radius = makeLava ? clickLavaRadius : clickLandRadius;
|
||||
|
||||
|
||||
for (double x = -radius; x <= radius; x++) {
|
||||
for (double z = -radius; z <= radius; z++) {
|
||||
Location loc = origin.clone().add(x, 0, z);
|
||||
|
@ -398,14 +396,15 @@ public class LavaFlow extends LavaAbility {
|
|||
TempBlock tb = new TempBlock(above, Material.AIR, (byte) 0);
|
||||
TEMP_AIR_BLOCKS.put(above, tb);
|
||||
affectedBlocks.add(tb);
|
||||
} else return;
|
||||
}
|
||||
} else
|
||||
return;
|
||||
}
|
||||
TempBlock tblock = new TempBlock(block, Material.LAVA, (byte) 0);
|
||||
TEMP_LAVA_BLOCKS.put(block, tblock);
|
||||
affectedBlocks.add(tblock);
|
||||
|
||||
|
||||
if (allowNaturalFlow) {
|
||||
// ProjectKorra.plugin.getLogger().info("Flow free!");
|
||||
// ProjectKorra.plugin.getLogger().info("Flow free!");
|
||||
TempBlock.removeBlock(block);
|
||||
}
|
||||
}
|
||||
|
@ -469,7 +468,7 @@ public class LavaFlow extends LavaAbility {
|
|||
tblock.getBlock().getRelative(BlockFace.UP).setType(Material.DOUBLE_PLANT);
|
||||
tblock.getBlock().getRelative(BlockFace.UP).setData((byte) (tblock.getState().getRawData() + 8));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}.runTaskLater(ProjectKorra.plugin, (long) (i / shiftRemoveSpeed));
|
||||
|
||||
|
@ -515,7 +514,6 @@ public class LavaFlow extends LavaAbility {
|
|||
task.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of all the Lava blocks that are adjacent to the block at
|
||||
|
@ -546,7 +544,7 @@ public class LavaFlow extends LavaAbility {
|
|||
public static ArrayList<Block> getAdjacentBlocks(Location loc) {
|
||||
ArrayList<Block> list = new ArrayList<Block>();
|
||||
Block block = loc.getBlock();
|
||||
|
||||
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int y = -2; y <= 1; y++) {
|
||||
for (int z = -1; z <= 1; z++) {
|
||||
|
@ -594,18 +592,18 @@ public class LavaFlow extends LavaAbility {
|
|||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static Material getRevertMaterial() {
|
||||
Material m = Material.STONE;
|
||||
LavaFlow lf = (LavaFlow) CoreAbility.getAbility("LavaFlow");
|
||||
m = lf.revertMaterial;
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
public static Map<Block, TempBlock> getTempLandBlocks() {
|
||||
return TEMP_LAND_BLOCKS;
|
||||
}
|
||||
|
||||
|
||||
public static Map<Block, TempBlock> getTempLavaBlocks() {
|
||||
return TEMP_LAVA_BLOCKS;
|
||||
}
|
||||
|
@ -629,7 +627,7 @@ public class LavaFlow extends LavaAbility {
|
|||
public long getCooldown() {
|
||||
return type == AbilityType.CLICK ? clickLandCooldown : shiftCooldown;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -640,6 +638,15 @@ public class LavaFlow extends LavaAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
for (TempBlock tblock : affectedBlocks) {
|
||||
locations.add(tblock.getLocation());
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public boolean isRemoving() {
|
||||
return removing;
|
||||
}
|
||||
|
@ -895,5 +902,5 @@ public class LavaFlow extends LavaAbility {
|
|||
public ArrayList<BukkitRunnable> getTasks() {
|
||||
return tasks;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import org.bukkit.block.BlockFace;
|
|||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
@ -178,6 +180,15 @@ public class RaiseEarth extends EarthAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
for (Block block : affectedBlocks.values()) {
|
||||
locations.add(block.getLocation());
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public int getDistance() {
|
||||
return distance;
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package com.projectkorra.projectkorra.earthbending;
|
||||
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.EarthAbility;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
|
@ -16,9 +14,11 @@ import org.bukkit.entity.LivingEntity;
|
|||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.EarthAbility;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
|
||||
public class Ripple extends EarthAbility {
|
||||
|
||||
|
@ -328,6 +328,11 @@ public class Ripple extends EarthAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<Location> getLocations() {
|
||||
return locations;
|
||||
}
|
||||
|
||||
public int getStep() {
|
||||
return step;
|
||||
}
|
||||
|
@ -416,10 +421,6 @@ public class Ripple extends EarthAbility {
|
|||
this.block4 = block4;
|
||||
}
|
||||
|
||||
public ArrayList<Location> getLocations() {
|
||||
return locations;
|
||||
}
|
||||
|
||||
public ArrayList<Entity> getEntities() {
|
||||
return entities;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.projectkorra.projectkorra.earthbending;
|
||||
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.SandAbility;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
import com.projectkorra.projectkorra.util.Flight;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
|
@ -13,8 +13,10 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Random;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.SandAbility;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
import com.projectkorra.projectkorra.util.Flight;
|
||||
|
||||
public class SandSpout extends SandAbility {
|
||||
|
||||
|
@ -259,6 +261,20 @@ public class SandSpout extends SandAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
if (player == null) {
|
||||
return locations;
|
||||
}
|
||||
Location top = player.getLocation();
|
||||
double ySpacing = 2;
|
||||
for (double i = 0; i < this.getHeight(); i += ySpacing) {
|
||||
locations.add(top.clone().add(0, -i, 0));
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public boolean isCanSpiral() {
|
||||
return canSpiral;
|
||||
|
|
|
@ -64,7 +64,7 @@ public class Shockwave extends EarthAbility {
|
|||
return;
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() > startTime + chargeTime && !charged) {
|
||||
if (System.currentTimeMillis() > getStartTime() + chargeTime && !charged) {
|
||||
charged = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package com.projectkorra.projectkorra.event;
|
||||
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
|
||||
public class AbilityCollisionEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
|
||||
private boolean cancelled;
|
||||
private Collision collision;
|
||||
|
||||
public AbilityCollisionEvent(Collision collision) {
|
||||
this.collision = collision;
|
||||
this.cancelled = false;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
public Collision getCollision() {
|
||||
return collision;
|
||||
}
|
||||
|
||||
public void setCollision(Collision collision) {
|
||||
this.collision = collision;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ import com.projectkorra.projectkorra.GeneralMethods;
|
|||
import com.projectkorra.projectkorra.ProjectKorra;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.CombustionAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect;
|
||||
|
@ -77,6 +78,11 @@ public class Combustion extends CombustionAbility {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean removeAroundPoint(Location loc, double radius) {
|
||||
for (Combustion combustion : getAbilities(Combustion.class)) {
|
||||
if (combustion.location.getWorld().equals(loc.getWorld())) {
|
||||
|
@ -176,6 +182,11 @@ public class Combustion extends CombustionAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return getRadius();
|
||||
}
|
||||
|
||||
public boolean isBreakBlocks() {
|
||||
return breakBlocks;
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
package com.projectkorra.projectkorra.firebending;
|
||||
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ProjectKorra;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.EarthAbility;
|
||||
import com.projectkorra.projectkorra.ability.FireAbility;
|
||||
import com.projectkorra.projectkorra.ability.WaterAbility;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.earthbending.EarthBlast;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect;
|
||||
import com.projectkorra.projectkorra.waterbending.PlantRegrowth;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterManipulation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
|
@ -23,9 +14,15 @@ import org.bukkit.entity.LivingEntity;
|
|||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ProjectKorra;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.FireAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect;
|
||||
import com.projectkorra.projectkorra.waterbending.PlantRegrowth;
|
||||
|
||||
public class FireBlast extends FireAbility {
|
||||
|
||||
|
@ -196,18 +193,6 @@ public class FireBlast extends FireAbility {
|
|||
return;
|
||||
}
|
||||
|
||||
WaterAbility.removeWaterSpouts(location, player);
|
||||
AirAbility.removeAirSpouts(location, player);
|
||||
EarthAbility.removeSandSpouts(location, player);
|
||||
|
||||
Player source = player;
|
||||
if (EarthBlast.annihilateBlasts(location, collisionRadius, source)
|
||||
|| WaterManipulation.annihilateBlasts(location, collisionRadius, source)
|
||||
|| FireBlast.annihilateBlasts(location, collisionRadius, source)) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, collisionRadius)) {
|
||||
affect(entity);
|
||||
if (entity instanceof LivingEntity) {
|
||||
|
@ -218,6 +203,11 @@ public class FireBlast extends FireAbility {
|
|||
advanceLocation();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean annihilateBlasts(Location location, double radius, Player source) {
|
||||
boolean broke = false;
|
||||
for (FireBlast blast : getAbilities(FireBlast.class)) {
|
||||
|
@ -284,6 +274,11 @@ public class FireBlast extends FireAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return collisionRadius;
|
||||
}
|
||||
|
||||
public boolean isPowerFurnace() {
|
||||
return powerFurnace;
|
||||
|
@ -349,10 +344,6 @@ public class FireBlast extends FireAbility {
|
|||
this.speed = speed;
|
||||
}
|
||||
|
||||
public double getCollisionRadius() {
|
||||
return collisionRadius;
|
||||
}
|
||||
|
||||
public void setCollisionRadius(double collisionRadius) {
|
||||
this.collisionRadius = collisionRadius;
|
||||
}
|
||||
|
|
|
@ -252,7 +252,7 @@ public class FireBlastCharged extends FireAbility {
|
|||
return;
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() > startTime + chargeTime) {
|
||||
if (System.currentTimeMillis() > getStartTime() + chargeTime) {
|
||||
charged = true;
|
||||
}
|
||||
if (!player.isSneaking() && !launched) {
|
||||
|
@ -320,6 +320,16 @@ public class FireBlastCharged extends FireAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return this.launched;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return collisionRadius;
|
||||
}
|
||||
|
||||
public boolean isCharged() {
|
||||
return charged;
|
||||
|
@ -393,10 +403,6 @@ public class FireBlastCharged extends FireAbility {
|
|||
this.range = range;
|
||||
}
|
||||
|
||||
public double getCollisionRadius() {
|
||||
return collisionRadius;
|
||||
}
|
||||
|
||||
public void setCollisionRadius(double collisionRadius) {
|
||||
this.collisionRadius = collisionRadius;
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ public class FireBurst extends FireAbility {
|
|||
return;
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() > startTime + chargeTime && !charged) {
|
||||
if (System.currentTimeMillis() > getStartTime() + chargeTime && !charged) {
|
||||
charged = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.projectkorra.projectkorra.firebending;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
|
@ -16,12 +17,11 @@ import org.bukkit.util.Vector;
|
|||
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ProjectKorra;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.ComboAbility;
|
||||
import com.projectkorra.projectkorra.ability.EarthAbility;
|
||||
import com.projectkorra.projectkorra.ability.ElementalAbility;
|
||||
import com.projectkorra.projectkorra.ability.FireAbility;
|
||||
import com.projectkorra.projectkorra.ability.WaterAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.command.Commands;
|
||||
|
@ -30,26 +30,11 @@ import com.projectkorra.projectkorra.util.DamageHandler;
|
|||
import com.projectkorra.projectkorra.util.ParticleEffect;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* 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 FireCombo extends FireAbility implements ComboAbility {
|
||||
|
||||
private static final ArrayList<String> BLOCKABLE_ABILITIES = new ArrayList<String>() {
|
||||
private static final long serialVersionUID = 0; {
|
||||
add("AirShield");
|
||||
add("FireShield");
|
||||
add("AirSwipe");
|
||||
add("FireBlast");
|
||||
add("EarthBlast");
|
||||
add("WaterManipulation");
|
||||
add("Combustion");
|
||||
add("FireKick");
|
||||
add("FireSpin");
|
||||
add("AirSweep");
|
||||
}
|
||||
};
|
||||
|
||||
private boolean firstTime;
|
||||
private int progressCounter;
|
||||
|
@ -70,20 +55,20 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
private Vector direction;
|
||||
private ArrayList<LivingEntity> affectedEntities;
|
||||
private ArrayList<FireComboStream> tasks;
|
||||
|
||||
|
||||
public FireCombo(Player player, String ability) {
|
||||
super(player);
|
||||
this.ability = ability;
|
||||
|
||||
|
||||
if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this.firstTime = true;
|
||||
this.time = System.currentTimeMillis();
|
||||
this.affectedEntities = new ArrayList<>();
|
||||
this.tasks = new ArrayList<>();
|
||||
|
||||
|
||||
if (ability.equalsIgnoreCase("FireKick")) {
|
||||
this.damage = getConfig().getDouble("Abilities.Fire.FireCombo.FireKick.Damage");
|
||||
this.range = getConfig().getDouble("Abilities.Fire.FireCombo.FireKick.Range");
|
||||
|
@ -112,7 +97,7 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
this.cooldown = getConfig().getLong("Abilities.Fire.FireCombo.JetBlaze.Cooldown");
|
||||
this.fireTicks = getConfig().getDouble("Abilities.Fire.FireCombo.JetBlaze.FireTicks");
|
||||
}
|
||||
|
||||
|
||||
if (bPlayer.isAvatarState()) {
|
||||
this.cooldown = 0;
|
||||
this.damage = AvatarState.getValue(damage);
|
||||
|
@ -121,10 +106,9 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all of the FireCombos created by a specific player but filters the abilities based on
|
||||
* shift or click.
|
||||
* Returns all of the FireCombos created by a specific player but filters
|
||||
* the abilities based on shift or click.
|
||||
*/
|
||||
public static ArrayList<FireCombo> getFireCombo(Player player, ClickType type) {
|
||||
ArrayList<FireCombo> list = new ArrayList<FireCombo>();
|
||||
|
@ -136,6 +120,11 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean removeAroundPoint(Player player, String ability, Location loc, double radius) {
|
||||
boolean removed = false;
|
||||
for (FireCombo combo : getAbilities(FireCombo.class)) {
|
||||
|
@ -145,8 +134,7 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
|
||||
if (ability.equalsIgnoreCase("FireKick") && combo.ability.equalsIgnoreCase("FireKick")) {
|
||||
for (FireComboStream fs : combo.tasks) {
|
||||
if (fs.getLocation() != null && fs.getLocation().getWorld() == loc.getWorld()
|
||||
&& Math.abs(fs.getLocation().distanceSquared(loc)) <= radius * radius) {
|
||||
if (fs.getLocation() != null && fs.getLocation().getWorld() == loc.getWorld() && Math.abs(fs.getLocation().distanceSquared(loc)) <= radius * radius) {
|
||||
fs.remove();
|
||||
removed = true;
|
||||
}
|
||||
|
@ -160,9 +148,7 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (ability.equalsIgnoreCase("FireWheel") && combo.ability.equalsIgnoreCase("FireWheel")) {
|
||||
} else if (ability.equalsIgnoreCase("FireWheel") && combo.ability.equalsIgnoreCase("FireWheel")) {
|
||||
if (combo.location != null && Math.abs(combo.location.distanceSquared(loc)) <= radius * radius) {
|
||||
combo.remove();
|
||||
removed = true;
|
||||
|
@ -227,7 +213,7 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
|
||||
remove();
|
||||
return;
|
||||
|
@ -239,7 +225,7 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bPlayer.addCooldown("FireKick", cooldown);
|
||||
Vector eyeDir = player.getEyeLocation().getDirection().normalize().multiply(range);
|
||||
destination = player.getEyeLocation().add(eyeDir);
|
||||
|
@ -262,17 +248,10 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
player.getWorld().playSound(player.getLocation(), Sound.ITEM_FLINTANDSTEEL_USE, 0.5f, 1f);
|
||||
}
|
||||
location = tasks.get(0).getLocation();
|
||||
for (FireComboStream stream : tasks) {
|
||||
if (GeneralMethods.blockAbilities(player, BLOCKABLE_ABILITIES, stream.location, 2)) {
|
||||
stream.remove();
|
||||
}
|
||||
}
|
||||
} else if (tasks.size() == 0) {
|
||||
remove();
|
||||
return;
|
||||
} AirAbility.removeAirSpouts(location, player);
|
||||
WaterAbility.removeWaterSpouts(location, player);
|
||||
EarthAbility.removeSandSpouts(location, player);
|
||||
}
|
||||
} else if (ability.equalsIgnoreCase("FireSpin")) {
|
||||
if (destination == null) {
|
||||
if (bPlayer.isOnCooldown("FireSpin") && !bPlayer.isAvatarState()) {
|
||||
|
@ -299,20 +278,11 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
tasks.add(fs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (tasks.size() == 0) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
for (FireComboStream stream : tasks) {
|
||||
if (isWithinFireShield(stream.getLocation())) {
|
||||
stream.remove();
|
||||
}
|
||||
if (AirAbility.isWithinAirShield(stream.getLocation())) {
|
||||
stream.remove();
|
||||
}
|
||||
}
|
||||
} else if (ability.equalsIgnoreCase("JetBlast")) {
|
||||
if (System.currentTimeMillis() - time > 5000) {
|
||||
remove();
|
||||
|
@ -323,7 +293,7 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bPlayer.addCooldown("JetBlast", cooldown);
|
||||
firstTime = false;
|
||||
float spread = 0F;
|
||||
|
@ -332,9 +302,8 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
}
|
||||
FireJet fj = getAbility(player, FireJet.class);
|
||||
fj.setSpeed(speed);
|
||||
FireComboStream fs = new FireComboStream(this,
|
||||
player.getVelocity().clone().multiply(-1), player.getLocation(), 3, 0.5, "JetBlast");
|
||||
|
||||
FireComboStream fs = new FireComboStream(this, player.getVelocity().clone().multiply(-1), player.getLocation(), 3, 0.5, "JetBlast");
|
||||
|
||||
fs.setDensity(1);
|
||||
fs.setSpread(0.9F);
|
||||
fs.setUseNewParticles(true);
|
||||
|
@ -404,7 +373,7 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
}
|
||||
location.setY(topBlock.getY() + height);
|
||||
FireComboStream fs = new FireComboStream(this, direction, location.clone().add(0, -1, 0), 5, 1, "FireWheel");
|
||||
|
||||
|
||||
fs.setDensity(0);
|
||||
fs.setSinglePoint(true);
|
||||
fs.setCollisionRadius(1.5);
|
||||
|
@ -422,16 +391,12 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
|
||||
location = location.add(direction.clone().multiply(speed));
|
||||
location.getWorld().playSound(location, Sound.BLOCK_FIRE_AMBIENT, 1, 1);
|
||||
if (GeneralMethods.blockAbilities(player, BLOCKABLE_ABILITIES, location, 2)) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes this instance of FireCombo, cleans up any blocks that are remaining in totalBlocks,
|
||||
* and cancels any remaining tasks.
|
||||
* Removes this instance of FireCombo, cleans up any blocks that are
|
||||
* remaining in totalBlocks, and cancels any remaining tasks.
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
|
@ -470,7 +435,7 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
this.checkCollisionCounter = 0;
|
||||
this.spread = 0;
|
||||
this.collisionRadius = 2;
|
||||
this.particleEffect = ParticleEffect.FLAME;
|
||||
this.particleEffect = ParticleEffect.FLAME;
|
||||
this.fireCombo = fireCombo;
|
||||
this.direction = direction;
|
||||
this.speed = speed;
|
||||
|
@ -479,7 +444,7 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
this.distance = distance;
|
||||
this.ability = ability;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Block block = location.getBlock();
|
||||
|
@ -506,7 +471,7 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
checkCollisionCounter++;
|
||||
if (singlePoint) {
|
||||
remove();
|
||||
|
@ -586,7 +551,7 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
public long getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -596,7 +561,22 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
// Override in subclasses
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
for (FireComboStream stream : tasks) {
|
||||
locations.add(stream.getLocation());
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstructions() {
|
||||
return null;
|
||||
|
@ -611,7 +591,25 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
public ArrayList<AbilityInformation> getCombination() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public void handleCollisionFireStreams(Collision collision) {
|
||||
if (collision.isRemovingFirst()) {
|
||||
ArrayList<FireComboStream> newTasks = new ArrayList<>();
|
||||
double collisionDistanceSquared = Math.pow(getCollisionRadius() + collision.getAbilitySecond().getCollisionRadius(), 2);
|
||||
// Remove all of the streams that are by this specific ourLocation.
|
||||
// Don't just do a single stream at a time or this algorithm becomes O(n^2) with
|
||||
// Collision's detection algorithm.
|
||||
for (FireComboStream stream : tasks) {
|
||||
if (stream.getLocation().distanceSquared(collision.getLocationSecond()) > collisionDistanceSquared) {
|
||||
newTasks.add(stream);
|
||||
} else {
|
||||
stream.cancel();
|
||||
}
|
||||
}
|
||||
tasks = newTasks;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHiddenAbility() {
|
||||
return true;
|
||||
}
|
||||
|
@ -736,10 +734,6 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
this.direction = direction;
|
||||
}
|
||||
|
||||
public static ArrayList<String> getBlockableAbilities() {
|
||||
return BLOCKABLE_ABILITIES;
|
||||
}
|
||||
|
||||
public ArrayList<LivingEntity> getAffectedEntities() {
|
||||
return affectedEntities;
|
||||
}
|
||||
|
@ -748,6 +742,10 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
return tasks;
|
||||
}
|
||||
|
||||
public void setTasks(ArrayList<FireComboStream> tasks) {
|
||||
this.tasks = tasks;
|
||||
}
|
||||
|
||||
public void setCooldown(long cooldown) {
|
||||
this.cooldown = cooldown;
|
||||
}
|
||||
|
@ -755,65 +753,91 @@ public class FireCombo extends FireAbility implements ComboAbility {
|
|||
public void setLocation(Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public class FireKick extends FireCombo {
|
||||
|
||||
public FireKick(Player player, String name) {
|
||||
// Combo subclasses need to be static to be reflectively called in ComboManager
|
||||
public static class FireKick extends FireCombo {
|
||||
|
||||
public FireKick(Player player) {
|
||||
super(player, "FireKick");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "FireKick";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class FireSpin extends FireCombo {
|
||||
|
||||
public FireSpin(Player player, String name) {
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCollision(Collision collision) {
|
||||
handleCollisionFireStreams(collision);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class FireSpin extends FireCombo {
|
||||
|
||||
public FireSpin(Player player) {
|
||||
super(player, "FireSpin");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "FireSpin";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class FireWheel extends FireCombo {
|
||||
|
||||
public FireWheel(Player player, String name) {
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCollision(Collision collision) {
|
||||
handleCollisionFireStreams(collision);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class FireWheel extends FireCombo {
|
||||
|
||||
public FireWheel(Player player) {
|
||||
super(player, "FireWheel");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "FireWheel";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class JetBlast extends FireCombo {
|
||||
|
||||
public JetBlast(Player player, String name) {
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class JetBlast extends FireCombo {
|
||||
|
||||
public JetBlast(Player player) {
|
||||
super(player, "JetBlast");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "JetBlast";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class JetBlaze extends FireCombo {
|
||||
|
||||
public JetBlaze(Player player, String name) {
|
||||
}
|
||||
|
||||
public static class JetBlaze extends FireCombo {
|
||||
|
||||
public JetBlaze(Player player) {
|
||||
super(player, "JetBlaze");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "JetBlaze";
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package com.projectkorra.projectkorra.firebending;
|
||||
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.FireAbility;
|
||||
import com.projectkorra.projectkorra.earthbending.EarthBlast;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect;
|
||||
import com.projectkorra.projectkorra.waterbending.WaterManipulation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
|
@ -16,11 +13,13 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.FireAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect;
|
||||
|
||||
public class FireShield extends FireAbility {
|
||||
|
||||
|
||||
private boolean shield;
|
||||
private boolean ignite;
|
||||
private long time;
|
||||
|
@ -30,6 +29,7 @@ public class FireShield extends FireAbility {
|
|||
private double radius;
|
||||
private double discRadius;
|
||||
private double fireTicks;
|
||||
private Location location;
|
||||
private Random random;
|
||||
|
||||
public FireShield(Player player) {
|
||||
|
@ -38,7 +38,7 @@ public class FireShield extends FireAbility {
|
|||
|
||||
public FireShield(Player player, boolean shield) {
|
||||
super(player);
|
||||
|
||||
|
||||
this.shield = shield;
|
||||
this.ignite = true;
|
||||
this.interval = getConfig().getLong("Abilities.Fire.FireShield.Interval");
|
||||
|
@ -48,7 +48,7 @@ public class FireShield extends FireAbility {
|
|||
this.discRadius = getConfig().getDouble("Abilities.Fire.FireShield.DiscRadius");
|
||||
this.fireTicks = getConfig().getDouble("Abilities.Fire.FireShield.FireTicks");
|
||||
this.random = new Random();
|
||||
|
||||
|
||||
if (hasAbility(player, FireShield.class) || bPlayer.isOnCooldown("FireShield")) {
|
||||
return;
|
||||
} else if (!player.getEyeLocation().getBlock().isLiquid()) {
|
||||
|
@ -60,6 +60,11 @@ public class FireShield extends FireAbility {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isWithinShield(Location loc) {
|
||||
for (FireShield fshield : getAbilities(FireShield.class)) {
|
||||
Location playerLoc = fshield.player.getLocation();
|
||||
|
@ -74,7 +79,8 @@ public class FireShield extends FireAbility {
|
|||
Location tempLoc = playerLoc.clone().add(playerLoc.multiply(fshield.discRadius));
|
||||
if (!tempLoc.getWorld().equals(loc.getWorld())) {
|
||||
return false;
|
||||
} else if (tempLoc.getWorld().equals(loc.getWorld()) && tempLoc.distance(loc) <= fshield.discRadius * fshield.discRadius) {
|
||||
} else if (tempLoc.getWorld().equals(loc.getWorld())
|
||||
&& tempLoc.distance(loc) <= fshield.discRadius * fshield.discRadius) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +96,7 @@ public class FireShield extends FireAbility {
|
|||
} else if (!player.isSneaking() && shield) {
|
||||
remove();
|
||||
return;
|
||||
} else if (System.currentTimeMillis() > startTime + duration && !shield) {
|
||||
} else if (System.currentTimeMillis() > getStartTime() + duration && !shield) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
@ -100,15 +106,15 @@ public class FireShield extends FireAbility {
|
|||
|
||||
if (shield) {
|
||||
ArrayList<Block> blocks = new ArrayList<>();
|
||||
Location location = player.getEyeLocation().clone();
|
||||
location = player.getEyeLocation().clone();
|
||||
|
||||
for (double theta = 0; theta < 180; theta += 20) {
|
||||
for (double phi = 0; phi < 360; phi += 20) {
|
||||
double rphi = Math.toRadians(phi);
|
||||
double rtheta = Math.toRadians(theta);
|
||||
|
||||
Block block = location .clone() .add(radius * Math.cos(rphi) * Math.sin(rtheta), radius * Math.cos(rtheta),
|
||||
radius * Math.sin(rphi) * Math.sin(rtheta)).getBlock();
|
||||
|
||||
Block block = location.clone().add(radius * Math.cos(rphi) * Math.sin(rtheta), radius * Math.cos(rtheta),
|
||||
radius * Math.sin(rphi) * Math.sin(rtheta)).getBlock();
|
||||
if (!blocks.contains(block) && !GeneralMethods.isSolid(block) && !block.isLiquid()) {
|
||||
blocks.add(block);
|
||||
}
|
||||
|
@ -142,13 +148,9 @@ public class FireShield extends FireAbility {
|
|||
new FireDamageTimer(entity, player);
|
||||
}
|
||||
}
|
||||
|
||||
FireBlast.removeFireBlastsAroundPoint(location, radius + 1);
|
||||
BlazeArc.removeAroundPoint(location, radius + 1);
|
||||
Combustion.removeAroundPoint(location, radius + 1);
|
||||
} else {
|
||||
ArrayList<Block> blocks = new ArrayList<>();
|
||||
Location location = player.getEyeLocation().clone();
|
||||
location = player.getEyeLocation().clone();
|
||||
Vector direction = location.getDirection();
|
||||
location = location.clone().add(direction.multiply(radius));
|
||||
|
||||
|
@ -184,11 +186,6 @@ public class FireShield extends FireAbility {
|
|||
}
|
||||
}
|
||||
|
||||
FireBlast.removeFireBlastsAroundPoint(location, discRadius);
|
||||
WaterManipulation.removeAroundPoint(location, discRadius);
|
||||
EarthBlast.removeAroundPoint(location, discRadius);
|
||||
BlazeArc.removeAroundPoint(location, discRadius);
|
||||
Combustion.removeAroundPoint(location, discRadius);
|
||||
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, discRadius)) {
|
||||
if (entity instanceof Projectile) {
|
||||
entity.remove();
|
||||
|
@ -205,14 +202,14 @@ public class FireShield extends FireAbility {
|
|||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return player != null ? player.getLocation() : null;
|
||||
return location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -222,6 +219,11 @@ public class FireShield extends FireAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return shield ? radius : discRadius;
|
||||
}
|
||||
|
||||
public boolean isShield() {
|
||||
return shield;
|
||||
|
@ -290,5 +292,5 @@ public class FireShield extends FireAbility {
|
|||
public void setCooldown(long cooldown) {
|
||||
this.cooldown = cooldown;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package com.projectkorra.projectkorra.firebending;
|
||||
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ProjectKorra;
|
||||
import com.projectkorra.projectkorra.ability.LightningAbility;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
|
@ -15,7 +12,11 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ProjectKorra;
|
||||
import com.projectkorra.projectkorra.ability.LightningAbility;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
|
||||
public class Lightning extends LightningAbility {
|
||||
|
||||
|
@ -52,6 +53,7 @@ public class Lightning extends LightningAbility {
|
|||
private ArrayList<Entity> affectedEntities;
|
||||
private ArrayList<Arc> arcs;
|
||||
private ArrayList<BukkitRunnable> tasks;
|
||||
private ArrayList<Location> locations;
|
||||
|
||||
public Lightning(Player player) {
|
||||
super(player);
|
||||
|
@ -73,6 +75,7 @@ public class Lightning extends LightningAbility {
|
|||
this.affectedEntities = new ArrayList<>();
|
||||
this.arcs = new ArrayList<>();
|
||||
this.tasks = new ArrayList<>();
|
||||
this.locations = new ArrayList<>();
|
||||
|
||||
this.selfHitWater = getConfig().getBoolean("Abilities.Fire.Lightning.SelfHitWater");
|
||||
this.selfHitClose = getConfig().getBoolean("Abilities.Fire.Lightning.SelfHitClose");
|
||||
|
@ -191,6 +194,8 @@ public class Lightning extends LightningAbility {
|
|||
return;
|
||||
}
|
||||
|
||||
locations.clear();
|
||||
|
||||
if (state == State.START) {
|
||||
if (bPlayer.isOnCooldown(this)) {
|
||||
remove();
|
||||
|
@ -504,6 +509,11 @@ public class Lightning extends LightningAbility {
|
|||
return;
|
||||
}
|
||||
Block block = location.getBlock();
|
||||
// We only want to consider this particle as part of the location
|
||||
// on the its first tick, when it actually does the electrocution.
|
||||
// The later ticks are just for visual purposes.
|
||||
locations.add(block.getLocation());
|
||||
|
||||
// Handle Water electrocution
|
||||
if (!hitWater && (isWater(block) || (arcOnIce && isIce(block)))) {
|
||||
hitWater = true;
|
||||
|
@ -636,6 +646,16 @@ public class Lightning extends LightningAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return arcs.size() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
return locations;
|
||||
}
|
||||
|
||||
public boolean isCharged() {
|
||||
return charged;
|
||||
}
|
||||
|
|
|
@ -173,22 +173,22 @@ public class WallOfFire extends FireAbility {
|
|||
public void progress() {
|
||||
time = System.currentTimeMillis();
|
||||
|
||||
if (time - startTime > cooldown) {
|
||||
if (time - getStartTime() > cooldown) {
|
||||
remove();
|
||||
return;
|
||||
} else if (!active) {
|
||||
return;
|
||||
} else if (time - startTime > duration) {
|
||||
} else if (time - getStartTime() > duration) {
|
||||
active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (time - startTime > intervalTick * interval) {
|
||||
if (time - getStartTime() > intervalTick * interval) {
|
||||
intervalTick++;
|
||||
display();
|
||||
}
|
||||
|
||||
if (time - startTime > damageTick * damageInterval) {
|
||||
if (time - getStartTime() > damageTick * damageInterval) {
|
||||
damageTick++;
|
||||
damage();
|
||||
}
|
||||
|
@ -218,6 +218,15 @@ public class WallOfFire extends FireAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
for (Block block : blocks) {
|
||||
locations.add(block.getLocation());
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
|
|
|
@ -283,7 +283,7 @@ public class Bloodbending extends BloodAbility {
|
|||
@Override
|
||||
public void remove() {
|
||||
if (!bPlayer.isAvatarState() && target != null) {
|
||||
if (System.currentTimeMillis() < this.startTime + 1200) {
|
||||
if (System.currentTimeMillis() < getStartTime() + 1200) {
|
||||
bPlayer.addCooldown(this); //Prevents spamming
|
||||
}
|
||||
}
|
||||
|
@ -311,6 +311,9 @@ public class Bloodbending extends BloodAbility {
|
|||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
if (target != null) {
|
||||
return target.getLocation();
|
||||
}
|
||||
return player != null ? player.getLocation() : null;
|
||||
}
|
||||
|
||||
|
@ -328,6 +331,16 @@ public class Bloodbending extends BloodAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
// for collision purposes we only care about the player's location
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
if (player != null) {
|
||||
locations.add(player.getLocation());
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public boolean isCanOnlyBeUsedAtNight() {
|
||||
return canOnlyBeUsedAtNight;
|
||||
|
|
|
@ -105,7 +105,7 @@ public class HealingWaters extends HealingAbility {
|
|||
}
|
||||
|
||||
// If ability is is charged, set charged = true. If not, play charging particles.
|
||||
if (System.currentTimeMillis() >= startTime + chargeTime) {
|
||||
if (System.currentTimeMillis() >= getStartTime() + chargeTime) {
|
||||
if (!charged) {
|
||||
this.charged = true;
|
||||
WaterReturn.emptyWaterBottle(player);
|
||||
|
|
|
@ -338,6 +338,16 @@ public class IceBlast extends IceAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return progressing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return collisionRadius;
|
||||
}
|
||||
|
||||
public boolean isPrepared() {
|
||||
return prepared;
|
||||
|
@ -403,10 +413,6 @@ public class IceBlast extends IceAbility {
|
|||
this.damage = damage;
|
||||
}
|
||||
|
||||
public double getCollisionRadius() {
|
||||
return collisionRadius;
|
||||
}
|
||||
|
||||
public void setCollisionRadius(double collisionRadius) {
|
||||
this.collisionRadius = collisionRadius;
|
||||
}
|
||||
|
|
|
@ -45,11 +45,11 @@ public class IceSpikeBlast extends IceAbility {
|
|||
|
||||
public IceSpikeBlast(Player player) {
|
||||
super(player);
|
||||
|
||||
|
||||
if (bPlayer.isOnCooldown("IceSpikeBlast")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this.data = 0;
|
||||
this.interval = getConfig().getLong("Abilities.Water.IceSpike.Blast.Interval");
|
||||
this.slowCooldown = getConfig().getLong("Abilities.Water.IceSpike.Blast.SlowCooldown");
|
||||
|
@ -60,12 +60,12 @@ public class IceSpikeBlast extends IceAbility {
|
|||
this.cooldown = getConfig().getLong("Abilities.Water.IceSpike.Blast.Cooldown");
|
||||
this.slowPower = getConfig().getInt("Abilities.Water.IceSpike.Blast.SlowPower");
|
||||
this.slowDuration = getConfig().getInt("Abilities.Water.IceSpike.Blast.SlowDuration");
|
||||
|
||||
|
||||
if (!bPlayer.canBend(this) || !bPlayer.canIcebend()) {
|
||||
return;
|
||||
}
|
||||
|
||||
block(player);
|
||||
block(player);
|
||||
this.range = getNightFactor(range);
|
||||
this.damage = getNightFactor(damage);
|
||||
this.slowPower = (int) getNightFactor(slowPower);
|
||||
|
@ -109,7 +109,7 @@ public class IceSpikeBlast extends IceAbility {
|
|||
iceSpike.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sourceBlock = block;
|
||||
location = sourceBlock.getLocation();
|
||||
prepared = true;
|
||||
|
@ -232,7 +232,7 @@ public class IceSpikeBlast extends IceAbility {
|
|||
if (!prepared) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
LivingEntity target = (LivingEntity) GeneralMethods.getTargetedEntity(player, range);
|
||||
if (target == null) {
|
||||
destination = GeneralMethods.getTargetedLocation(player, range, getTransparentMaterial());
|
||||
|
@ -247,14 +247,14 @@ public class IceSpikeBlast extends IceAbility {
|
|||
if (destination.distanceSquared(location) < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
firstDestination = location.clone();
|
||||
if (destination.getY() - location.getY() > 2) {
|
||||
firstDestination.setY(destination.getY() - 1);
|
||||
} else {
|
||||
firstDestination.add(0, 2, 0);
|
||||
}
|
||||
|
||||
|
||||
destination = GeneralMethods.getPointOnLine(firstDestination, destination, range);
|
||||
progressing = true;
|
||||
settingUp = true;
|
||||
|
@ -265,22 +265,21 @@ public class IceSpikeBlast extends IceAbility {
|
|||
sourceBlock.setType(Material.AIR);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void activate(Player player) {
|
||||
redirect(player);
|
||||
boolean activate = false;
|
||||
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
|
||||
|
||||
|
||||
if (bPlayer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (bPlayer.isOnCooldown("IceSpikeBlast")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (IceSpikeBlast ice : getAbilities(player, IceSpikeBlast.class)) {
|
||||
if (ice.prepared) {
|
||||
ice.throwIce();
|
||||
|
@ -288,7 +287,7 @@ public class IceSpikeBlast extends IceAbility {
|
|||
activate = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!activate && !getPlayers(IceSpikeBlast.class).contains(player)) {
|
||||
IceSpikePillar spike = new IceSpikePillar(player);
|
||||
if (!spike.isStarted()) {
|
||||
|
@ -305,16 +304,15 @@ public class IceSpikeBlast extends IceAbility {
|
|||
continue;
|
||||
} else if (!iceSpike.progressing) {
|
||||
continue;
|
||||
} if (GeneralMethods.isRegionProtectedFromBuild(iceSpike, iceSpike.location)) {
|
||||
}
|
||||
if (GeneralMethods.isRegionProtectedFromBuild(iceSpike, iceSpike.location)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Location location = player.getEyeLocation();
|
||||
Vector vector = location.getDirection();
|
||||
Location mloc = iceSpike.location;
|
||||
if (mloc.distanceSquared(location) <= iceSpike.range * iceSpike.range
|
||||
&& GeneralMethods.getDistanceFromLine(vector, location, iceSpike.location) < iceSpike.deflectRange
|
||||
&& mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) {
|
||||
if (mloc.distanceSquared(location) <= iceSpike.range * iceSpike.range && GeneralMethods.getDistanceFromLine(vector, location, iceSpike.location) < iceSpike.deflectRange && mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) {
|
||||
iceSpike.remove();
|
||||
}
|
||||
}
|
||||
|
@ -343,12 +341,10 @@ public class IceSpikeBlast extends IceAbility {
|
|||
Location location = player.getEyeLocation();
|
||||
Vector vector = location.getDirection();
|
||||
Location mloc = iceSpike.location;
|
||||
|
||||
|
||||
if (GeneralMethods.isRegionProtectedFromBuild(iceSpike, mloc)) {
|
||||
continue;
|
||||
} else if (mloc.distanceSquared(location) <= iceSpike.range * iceSpike.range
|
||||
&& GeneralMethods.getDistanceFromLine(vector, location, iceSpike.location) < iceSpike.deflectRange
|
||||
&& mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) {
|
||||
} else if (mloc.distanceSquared(location) <= iceSpike.range * iceSpike.range && GeneralMethods.getDistanceFromLine(vector, location, iceSpike.location) < iceSpike.deflectRange && mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) {
|
||||
Location loc;
|
||||
Entity target = GeneralMethods.getTargetedEntity(player, iceSpike.range);
|
||||
if (target == null) {
|
||||
|
@ -366,15 +362,15 @@ public class IceSpikeBlast extends IceAbility {
|
|||
@SuppressWarnings("deprecation")
|
||||
private static void waterBottle(Player player) {
|
||||
long range = getConfig().getLong("Abilities.Water.IceSpike.Projectile.Range");
|
||||
|
||||
|
||||
if (WaterReturn.hasWaterBottle(player)) {
|
||||
Location eyeLoc = player.getEyeLocation();
|
||||
Block block = eyeLoc.add(eyeLoc.getDirection().normalize()).getBlock();
|
||||
|
||||
|
||||
if (isTransparent(player, block) && isTransparent(player, eyeLoc.getBlock())) {
|
||||
LivingEntity target = (LivingEntity) GeneralMethods.getTargetedEntity(player, range);
|
||||
Location destination;
|
||||
|
||||
|
||||
if (target == null) {
|
||||
destination = GeneralMethods.getTargetedLocation(player, range, getTransparentMaterial());
|
||||
} else {
|
||||
|
@ -387,17 +383,17 @@ public class IceSpikeBlast extends IceAbility {
|
|||
|
||||
MaterialData data = block.getState().getData();
|
||||
block.setType(Material.WATER);
|
||||
block.setData((byte)0);
|
||||
block.setData((byte) 0);
|
||||
IceSpikeBlast iceSpike = new IceSpikeBlast(player);
|
||||
iceSpike.throwIce();
|
||||
iceSpike.sourceBlock = null;
|
||||
|
||||
if (iceSpike.progressing) {
|
||||
WaterReturn.emptyWaterBottle(player);
|
||||
}
|
||||
}
|
||||
block.setType(data.getItemType());
|
||||
block.setData(data.getData());
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -421,7 +417,7 @@ public class IceSpikeBlast extends IceAbility {
|
|||
public long getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -432,6 +428,16 @@ public class IceSpikeBlast extends IceAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return progressing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return collisionRadius;
|
||||
}
|
||||
|
||||
public boolean isPrepared() {
|
||||
return prepared;
|
||||
}
|
||||
|
@ -520,10 +526,6 @@ public class IceSpikeBlast extends IceAbility {
|
|||
this.damage = damage;
|
||||
}
|
||||
|
||||
public double getCollisionRadius() {
|
||||
return collisionRadius;
|
||||
}
|
||||
|
||||
public void setCollisionRadius(double collisionRadius) {
|
||||
this.collisionRadius = collisionRadius;
|
||||
}
|
||||
|
@ -575,5 +577,5 @@ public class IceSpikeBlast extends IceAbility {
|
|||
public void setLocation(Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -475,6 +475,11 @@ public class OctopusForm extends WaterAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return getRadius();
|
||||
}
|
||||
|
||||
public boolean isSourceSelected() {
|
||||
return sourceSelected;
|
||||
|
|
|
@ -23,6 +23,7 @@ public class PlantArmor extends PlantAbility {
|
|||
private int resistance;
|
||||
private long duration;
|
||||
private long cooldown;
|
||||
private long tickTime;
|
||||
private double range;
|
||||
private Material blockType;
|
||||
private Block block;
|
||||
|
@ -39,6 +40,7 @@ public class PlantArmor extends PlantAbility {
|
|||
|
||||
this.range = getNightFactor(range);
|
||||
this.duration = (long) getNightFactor(duration);
|
||||
this.tickTime = System.currentTimeMillis();
|
||||
|
||||
if (hasAbility(player, PlantArmor.class)) {
|
||||
return;
|
||||
|
@ -97,7 +99,7 @@ public class PlantArmor extends PlantAbility {
|
|||
new TempArmor(player, this, new ItemStack[] {boots, leggings, chestplate, helmet});
|
||||
|
||||
formed = true;
|
||||
startTime = System.currentTimeMillis();
|
||||
tickTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private boolean inPosition() {
|
||||
|
@ -125,7 +127,7 @@ public class PlantArmor extends PlantAbility {
|
|||
|
||||
if (formed) {
|
||||
PassiveHandler.checkArmorPassives(player);
|
||||
if (System.currentTimeMillis() > startTime + duration) {
|
||||
if (System.currentTimeMillis() > tickTime + duration) {
|
||||
remove();
|
||||
bPlayer.addCooldown(this);
|
||||
return;
|
||||
|
@ -166,7 +168,7 @@ public class PlantArmor extends PlantAbility {
|
|||
public static boolean canRemoveArmor(Player player) {
|
||||
PlantArmor plantArmor = getAbility(player, PlantArmor.class);
|
||||
if (plantArmor != null) {
|
||||
if (System.currentTimeMillis() < plantArmor.startTime + plantArmor.duration) {
|
||||
if (System.currentTimeMillis() < plantArmor.tickTime + plantArmor.duration) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -188,10 +190,8 @@ public class PlantArmor extends PlantAbility {
|
|||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
if (location != null) {
|
||||
if (!formed) {
|
||||
return location;
|
||||
} else if (block != null) {
|
||||
return block.getLocation();
|
||||
}
|
||||
return player != null ? player.getLocation() : null;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package com.projectkorra.projectkorra.waterbending;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.projectkorra.projectkorra.BendingPlayer;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.WaterAbility;
|
||||
|
@ -9,19 +23,6 @@ import com.projectkorra.projectkorra.util.BlockSource;
|
|||
import com.projectkorra.projectkorra.util.ClickType;
|
||||
import com.projectkorra.projectkorra.util.TempBlock;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class SurgeWall extends WaterAbility {
|
||||
|
||||
private static final byte FULL = 0x0;
|
||||
|
@ -42,6 +43,7 @@ public class SurgeWall extends WaterAbility {
|
|||
private Location location;
|
||||
private Location firstDestination;
|
||||
private Location targetDestination;
|
||||
private ArrayList<Location> locations;
|
||||
private Vector firstDirection;
|
||||
private Vector targetDirection;
|
||||
|
||||
|
@ -53,6 +55,7 @@ public class SurgeWall extends WaterAbility {
|
|||
this.cooldown = getConfig().getLong("Abilities.Water.Surge.Wall.Cooldown");
|
||||
this.range = getConfig().getDouble(RANGE_CONFIG);
|
||||
this.radius = getConfig().getDouble("Abilities.Water.Surge.Wall.Radius");
|
||||
this.locations = new ArrayList<>();
|
||||
|
||||
SurgeWave wave = getAbility(player, SurgeWave.class);
|
||||
if (wave != null && !wave.isProgressing()) {
|
||||
|
@ -214,7 +217,8 @@ public class SurgeWall extends WaterAbility {
|
|||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
locations.clear();
|
||||
|
||||
if (System.currentTimeMillis() - time >= interval) {
|
||||
time = System.currentTimeMillis();
|
||||
boolean matchesName = bPlayer.getBoundAbilityName().equalsIgnoreCase(getName());
|
||||
|
@ -258,6 +262,7 @@ public class SurgeWall extends WaterAbility {
|
|||
WALL_BLOCKS.put(block, player);
|
||||
addWallBlock(block);
|
||||
blocks.add(block);
|
||||
locations.add(block.getLocation());
|
||||
FireBlast.removeFireBlastsAroundPoint(block.getLocation(), 2);
|
||||
}
|
||||
}
|
||||
|
@ -483,6 +488,11 @@ public class SurgeWall extends WaterAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
return locations;
|
||||
}
|
||||
|
||||
public boolean isProgressing() {
|
||||
return progressing;
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
package com.projectkorra.projectkorra.waterbending;
|
||||
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.WaterAbility;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.firebending.FireBlast;
|
||||
import com.projectkorra.projectkorra.util.BlockSource;
|
||||
import com.projectkorra.projectkorra.util.ClickType;
|
||||
import com.projectkorra.projectkorra.util.TempBlock;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
|
@ -18,10 +15,14 @@ import org.bukkit.entity.LivingEntity;
|
|||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.WaterAbility;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.firebending.FireBlast;
|
||||
import com.projectkorra.projectkorra.util.BlockSource;
|
||||
import com.projectkorra.projectkorra.util.ClickType;
|
||||
import com.projectkorra.projectkorra.util.TempBlock;
|
||||
|
||||
public class SurgeWave extends WaterAbility {
|
||||
|
||||
|
@ -439,6 +440,23 @@ public class SurgeWave extends WaterAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return progressing || activateFreeze;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
for (Block block : waveBlocks.keySet()) {
|
||||
locations.add(block.getLocation());
|
||||
}
|
||||
for (Block block : frozenBlocks.keySet()) {
|
||||
locations.add(block.getLocation());
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public boolean isFreezing() {
|
||||
return freezing;
|
||||
|
|
|
@ -655,6 +655,23 @@ public class Torrent extends WaterAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return forming || formed || launch || launching;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
for (TempBlock tblock : blocks) {
|
||||
locations.add(tblock.getLocation());
|
||||
}
|
||||
for (TempBlock tblock : launchedBlocks) {
|
||||
locations.add(tblock.getLocation());
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public boolean isSourceSelected() {
|
||||
return sourceSelected;
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
@ -216,6 +217,15 @@ public class TorrentWave extends WaterAbility {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
for (TempBlock tblock : blocks) {
|
||||
locations.add(tblock.getLocation());
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package com.projectkorra.projectkorra.waterbending;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
@ -17,10 +19,11 @@ import org.bukkit.util.Vector;
|
|||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ProjectKorra;
|
||||
import com.projectkorra.projectkorra.ability.ComboAbility;
|
||||
import com.projectkorra.projectkorra.ability.CoreAbility;
|
||||
import com.projectkorra.projectkorra.ability.IceAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo;
|
||||
import com.projectkorra.projectkorra.firebending.FireCombo.FireComboStream;
|
||||
import com.projectkorra.projectkorra.util.BlockSource;
|
||||
import com.projectkorra.projectkorra.util.ClickType;
|
||||
|
@ -29,9 +32,9 @@ import com.projectkorra.projectkorra.util.ParticleEffect;
|
|||
import com.projectkorra.projectkorra.util.TempBlock;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* 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 WaterCombo extends IceAbility implements ComboAbility {
|
||||
|
||||
|
@ -76,12 +79,11 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
}
|
||||
|
||||
if (name.equalsIgnoreCase("IceWave")) {
|
||||
|
||||
if (bPlayer.isOnCooldown("IceWave") && !bPlayer.isAvatarState()) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this.cooldown = getConfig().getLong("Abilities.Water.WaterCombo.IceWave.Cooldown");
|
||||
} else if (name.equalsIgnoreCase("IceBullet")) {
|
||||
this.damage = getConfig().getDouble("Abilities.Water.WaterCombo.IceBullet.Damage");
|
||||
|
@ -93,7 +95,7 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
this.animationSpeed = getConfig().getDouble("Abilities.Water.WaterCombo.IceBullet.AnimationSpeed");
|
||||
this.speed = 1;
|
||||
}
|
||||
|
||||
|
||||
double aug = getNightFactor(player.getWorld());
|
||||
if (aug > 1) {
|
||||
aug = 1 + (aug - 1) / 3;
|
||||
|
@ -115,7 +117,7 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
}
|
||||
|
||||
if (name.equalsIgnoreCase("IceBulletLeftClick") || name.equalsIgnoreCase("IceBulletRightClick")) {
|
||||
ArrayList<WaterCombo> bullets = getWaterCombo(player, "IceBullet");
|
||||
Collection<IceBullet> bullets = CoreAbility.getAbilities(player, IceBullet.class);
|
||||
if (bullets.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -130,7 +132,7 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
|
@ -149,13 +151,13 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
public void drawWaterCircle(Location loc, double theta, double increment, double radius, Material mat, byte data) {
|
||||
double rotateSpeed = theta;
|
||||
direction = GeneralMethods.rotateXZ(direction, rotateSpeed);
|
||||
|
||||
|
||||
for (double i = 0; i < theta; i += increment) {
|
||||
Vector dir = GeneralMethods.rotateXZ(direction, i - theta / 2).normalize().multiply(radius);
|
||||
dir.setY(0);
|
||||
Block block = loc.clone().add(dir).getBlock();
|
||||
location = block.getLocation();
|
||||
|
||||
|
||||
if (block.getType() == Material.AIR && !GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", block.getLocation())) {
|
||||
createBlock(block, mat, data);
|
||||
}
|
||||
|
@ -169,7 +171,7 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < tasks.size(); i++) {
|
||||
FireComboStream fstream = (FireComboStream) tasks.get(i);
|
||||
Location loc = fstream.getLocation();
|
||||
|
@ -197,10 +199,6 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GeneralMethods.blockAbilities(player, FireCombo.getBlockableAbilities(), loc, 1)) {
|
||||
fstream.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +212,7 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
if (origin == null && WaterSpoutWave.containsType(player, WaterSpoutWave.AbilityType.RELEASE)) {
|
||||
bPlayer.addCooldown("IceWave", cooldown);
|
||||
origin = player.getLocation();
|
||||
|
||||
|
||||
WaterSpoutWave wave = WaterSpoutWave.getType(player, WaterSpoutWave.AbilityType.RELEASE).get(0);
|
||||
wave.setIceWave(true);
|
||||
} else if (!WaterSpoutWave.containsType(player, WaterSpoutWave.AbilityType.RELEASE)) {
|
||||
|
@ -226,19 +224,19 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (origin == null) {
|
||||
if (bPlayer.isOnCooldown("IceBullet") && !bPlayer.isAvatarState()) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Block waterBlock = BlockSource.getWaterSourceBlock(player, range, ClickType.LEFT_CLICK, true, true, bPlayer.canPlantbend());
|
||||
if (waterBlock == null) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
time = 0;
|
||||
origin = waterBlock.getLocation();
|
||||
location = origin.clone();
|
||||
|
@ -253,7 +251,7 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
if (this.time == 0) {
|
||||
this.time = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
long timeDiff = System.currentTimeMillis() - this.time;
|
||||
if (this.state == AbilityState.ICE_BULLET_FORMING) {
|
||||
if (timeDiff < 1000 * animationSpeed) {
|
||||
|
@ -277,7 +275,7 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
Vector vec = player.getEyeLocation().getDirection().normalize();
|
||||
Location loc = player.getEyeLocation().add(vec.clone().multiply(radius + 1.3));
|
||||
FireComboStream fs = new FireComboStream(null, vec, loc, range, speed, "IceBullet");
|
||||
|
||||
|
||||
fs.setDensity(10);
|
||||
fs.setSpread(0.1F);
|
||||
fs.setUseNewParticles(true);
|
||||
|
@ -308,9 +306,9 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
if (waterGrabber != null) {
|
||||
waterGrabber.remove();
|
||||
}
|
||||
|
||||
|
||||
bPlayer.addCooldown(this);
|
||||
|
||||
|
||||
if (name == "IceWave") {
|
||||
bPlayer.addCooldown("WaterWave", getConfig().getLong("Abilities.Water.WaterSpout.Wave.Cooldown"));
|
||||
}
|
||||
|
@ -363,12 +361,12 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
public long getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isHiddenAbility() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSneakAbility() {
|
||||
return true;
|
||||
|
@ -378,7 +376,13 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
// Override in subclasses
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstructions() {
|
||||
return null;
|
||||
|
@ -526,6 +530,10 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
return tasks;
|
||||
}
|
||||
|
||||
public void setTasks(ArrayList<BukkitRunnable> tasks) {
|
||||
this.tasks = tasks;
|
||||
}
|
||||
|
||||
public static Map<Block, TempBlock> getFrozenBlocks() {
|
||||
return FROZEN_BLOCKS;
|
||||
}
|
||||
|
@ -545,31 +553,99 @@ public class WaterCombo extends IceAbility implements ComboAbility {
|
|||
public void setLocation(Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public class IceWave extends WaterCombo {
|
||||
|
||||
public IceWave(Player player, String name) {
|
||||
// Combo subclasses need to be static to be reflectively called in ComboManager
|
||||
public static class IceWave extends WaterCombo {
|
||||
|
||||
public IceWave(Player player) {
|
||||
super(player, "IceWave");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "IceWave";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class IceBullet extends WaterCombo {
|
||||
|
||||
public IceBullet(Player player, String name) {
|
||||
}
|
||||
|
||||
public static class IceBullet extends WaterCombo {
|
||||
|
||||
public IceBullet(Player player) {
|
||||
super(player, "IceBullet");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "IceBullet";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCollision(Collision collision) {
|
||||
if (collision.isRemovingFirst()) {
|
||||
ArrayList<BukkitRunnable> newTasks = new ArrayList<>();
|
||||
double collisionDistanceSquared = Math.pow(getCollisionRadius() + collision.getAbilitySecond().getCollisionRadius(), 2);
|
||||
// Remove all of the streams that are by this specific ourLocation.
|
||||
// Don't just do a single stream at a time or this algorithm becomes O(n^2) with
|
||||
// Collision's detection algorithm.
|
||||
for (BukkitRunnable task : getTasks()) {
|
||||
if (task instanceof FireComboStream) {
|
||||
FireComboStream stream = (FireComboStream) task;
|
||||
if (stream.getLocation().distanceSquared(collision.getLocationSecond()) > collisionDistanceSquared) {
|
||||
newTasks.add(stream);
|
||||
} else {
|
||||
stream.cancel();
|
||||
}
|
||||
} else {
|
||||
newTasks.add(task);
|
||||
}
|
||||
}
|
||||
setTasks(newTasks);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
for (BukkitRunnable task : getTasks()) {
|
||||
if (task instanceof FireComboStream) {
|
||||
FireComboStream stream = (FireComboStream) task;
|
||||
locations.add(stream.getLocation());
|
||||
}
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class IceBulletLeftClick extends WaterCombo {
|
||||
|
||||
public IceBulletLeftClick(Player player) {
|
||||
super(player, "IceBulletLeftClick");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "IceBullet";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class IceBulletRightClick extends WaterCombo {
|
||||
|
||||
public IceBulletRightClick(Player player) {
|
||||
super(player, "IceBulletRightClick");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "IceBullet";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,12 +18,9 @@ import org.bukkit.util.Vector;
|
|||
import com.projectkorra.projectkorra.BendingPlayer;
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.AirAbility;
|
||||
import com.projectkorra.projectkorra.ability.EarthAbility;
|
||||
import com.projectkorra.projectkorra.ability.WaterAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.avatar.AvatarState;
|
||||
import com.projectkorra.projectkorra.earthbending.EarthBlast;
|
||||
import com.projectkorra.projectkorra.firebending.Combustion;
|
||||
import com.projectkorra.projectkorra.firebending.FireBlast;
|
||||
import com.projectkorra.projectkorra.util.BlockSource;
|
||||
import com.projectkorra.projectkorra.util.ClickType;
|
||||
import com.projectkorra.projectkorra.util.DamageHandler;
|
||||
|
@ -230,27 +227,9 @@ public class WaterManipulation extends WaterAbility {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
WaterAbility.removeWaterSpouts(location, player);
|
||||
AirAbility.removeAirSpouts(location, player);
|
||||
EarthAbility.removeSandSpouts(location, player);
|
||||
|
||||
if ((new Random()).nextInt(4) == 0) {
|
||||
playWaterbendingSound(location);
|
||||
}
|
||||
|
||||
double radius = collisionRadius;
|
||||
Player source = player;
|
||||
if (!(location == null)) {
|
||||
if (EarthBlast.annihilateBlasts(location, radius, source)
|
||||
|| WaterManipulation.annihilateBlasts(location, radius, source)
|
||||
|| FireBlast.annihilateBlasts(location, radius, source)) {
|
||||
remove();
|
||||
new WaterReturn(player, sourceBlock);
|
||||
return;
|
||||
}
|
||||
Combustion.removeAroundPoint(location, radius);
|
||||
}
|
||||
|
||||
location = location.clone().add(direction);
|
||||
block = location.getBlock();
|
||||
if (block.getLocation().equals(sourceBlock.getLocation())) {
|
||||
|
@ -386,6 +365,11 @@ public class WaterManipulation extends WaterAbility {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean annihilateBlasts(Location location, double radius, Player player) {
|
||||
boolean broke = false;
|
||||
for (WaterManipulation manip : getAbilities(WaterManipulation.class)) {
|
||||
|
@ -596,6 +580,24 @@ public class WaterManipulation extends WaterAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return progressing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return collisionRadius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCollision(Collision collision) {
|
||||
super.handleCollision(collision);
|
||||
if (collision.isRemovingFirst()) {
|
||||
new WaterReturn(player, sourceBlock);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isProgressing() {
|
||||
return progressing;
|
||||
|
@ -781,10 +783,6 @@ public class WaterManipulation extends WaterAbility {
|
|||
this.location = location;
|
||||
}
|
||||
|
||||
public double getCollisionRadius() {
|
||||
return collisionRadius;
|
||||
}
|
||||
|
||||
public void setCollisionRadius(double collisionRadius) {
|
||||
this.collisionRadius = collisionRadius;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.bukkit.potion.PotionEffectType;
|
|||
|
||||
import com.projectkorra.projectkorra.GeneralMethods;
|
||||
import com.projectkorra.projectkorra.ability.WaterAbility;
|
||||
import com.projectkorra.projectkorra.ability.util.Collision;
|
||||
import com.projectkorra.projectkorra.util.Flight;
|
||||
import com.projectkorra.projectkorra.util.ParticleEffect;
|
||||
import com.projectkorra.projectkorra.util.TempBlock;
|
||||
|
@ -289,6 +290,11 @@ public class WaterSpout extends WaterAbility {
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method was used for the old collision detection system. Please see
|
||||
* {@link Collision} for the new system.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean removeSpouts(Location loc0, double radius, Player sourcePlayer) {
|
||||
boolean removed = false;
|
||||
for (WaterSpout spout : getAbilities(WaterSpout.class)) {
|
||||
|
@ -332,6 +338,24 @@ public class WaterSpout extends WaterAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Location> getLocations() {
|
||||
ArrayList<Location> locations = new ArrayList<>();
|
||||
Location top = this.getLocation();
|
||||
Location iterLoc = getBase().getLocation();
|
||||
double ySpacing = 2;
|
||||
while (iterLoc.getY() <= top.getY()) {
|
||||
locations.add(iterLoc.clone());
|
||||
iterLoc.add(0, ySpacing, 0);
|
||||
}
|
||||
return locations;
|
||||
}
|
||||
|
||||
public boolean isCanBendOnPackedIce() {
|
||||
return canBendOnPackedIce;
|
||||
|
@ -416,5 +440,5 @@ public class WaterSpout extends WaterAbility {
|
|||
public static Map<Block, Block> getAffectedBlocks() {
|
||||
return AFFECTED_BLOCKS;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -42,6 +42,7 @@ public class WaterSpoutWave extends WaterAbility {
|
|||
private boolean iceOnly;
|
||||
private boolean moving;
|
||||
private boolean plant;
|
||||
private boolean collidable;
|
||||
private int progressCounter;
|
||||
private long time;
|
||||
private long cooldown;
|
||||
|
@ -68,6 +69,7 @@ public class WaterSpoutWave extends WaterAbility {
|
|||
this.charging = false;
|
||||
this.iceWave = false;
|
||||
this.iceOnly = false;
|
||||
this.collidable = false;
|
||||
this.plant = getConfig().getBoolean("Abilities.Water.WaterSpout.Wave.AllowPlantSource");
|
||||
this.radius = getConfig().getDouble("Abilities.Water.WaterSpout.Wave.Radius");
|
||||
this.waveRadius = getConfig().getDouble("Abilities.Water.WaterSpout.Wave.WaveRadius");
|
||||
|
@ -241,6 +243,7 @@ public class WaterSpoutWave extends WaterAbility {
|
|||
}
|
||||
} else {
|
||||
moving = true;
|
||||
collidable = true;
|
||||
if ((System.currentTimeMillis() - time > flightTime && !bPlayer.isAvatarState()) || player.isSneaking()) {
|
||||
remove();
|
||||
return;
|
||||
|
@ -473,6 +476,16 @@ public class WaterSpoutWave extends WaterAbility {
|
|||
public boolean isHarmlessAbility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollidable() {
|
||||
return collidable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCollisionRadius() {
|
||||
return getRadius();
|
||||
}
|
||||
|
||||
public double getRadius() {
|
||||
return radius;
|
||||
|
|
Loading…
Reference in a new issue