Initial rework

This commit is contained in:
jayoevans 2019-10-24 21:11:15 +10:00
parent c05022aa01
commit af0cf17b0b
152 changed files with 1435 additions and 1497 deletions

View file

@ -2,7 +2,7 @@ package com.projectkorra.projectkorra;
import co.aikar.timings.lib.MCTiming;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.api.ElementalAbility;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.configuration.configs.properties.FirePropertiesConfig;
import com.projectkorra.projectkorra.configuration.configs.properties.WaterPropertiesConfig;

View file

@ -2,8 +2,8 @@ package com.projectkorra.projectkorra;
import com.projectkorra.projectkorra.Element.SubElement;
import com.projectkorra.projectkorra.ability.Ability;
import com.projectkorra.projectkorra.ability.AvatarAbility;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.api.AvatarAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.util.PassiveManager;
import com.projectkorra.projectkorra.avatar.AvatarState;

View file

@ -26,13 +26,13 @@ import com.palmergames.bukkit.towny.war.flagwar.TownyWar;
import com.palmergames.bukkit.towny.war.flagwar.TownyWarConfig;
import com.projectkorra.projectkorra.Element.SubElement;
import com.projectkorra.projectkorra.ability.Ability;
import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.api.AddonAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.FireAbility;
import com.projectkorra.projectkorra.ability.PassiveAbility;
import com.projectkorra.projectkorra.ability.WaterAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.ability.api.ElementalAbility;
import com.projectkorra.projectkorra.ability.api.FireAbility;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
import com.projectkorra.projectkorra.ability.api.WaterAbility;
import com.projectkorra.projectkorra.ability.util.Collision;
import com.projectkorra.projectkorra.ability.util.CollisionInitializer;
import com.projectkorra.projectkorra.ability.util.CollisionManager;

View file

@ -75,17 +75,16 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.Element.SubElement;
import com.projectkorra.projectkorra.ability.Ability;
import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.AvatarAbility;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.api.AddonAbility;
import com.projectkorra.projectkorra.ability.api.AirAbility;
import com.projectkorra.projectkorra.ability.api.AvatarAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
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.api.EarthAbility;
import com.projectkorra.projectkorra.ability.api.ElementalAbility;
import com.projectkorra.projectkorra.ability.api.FireAbility;
import com.projectkorra.projectkorra.ability.api.WaterAbility;
import com.projectkorra.projectkorra.ability.util.ComboManager;
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager;
import com.projectkorra.projectkorra.ability.util.PassiveManager;

View file

@ -1,156 +1,658 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Manager;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.api.AddonAbility;
import com.projectkorra.projectkorra.ability.api.ComboAbility;
import com.projectkorra.projectkorra.ability.api.MultiAbility;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
import com.projectkorra.projectkorra.ability.loader.AddonAbilityLoader;
import com.projectkorra.projectkorra.ability.util.*;
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager.MultiAbilityInfo;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.attribute.AttributeModifier;
import com.projectkorra.projectkorra.attribute.AttributePriority;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.configuration.configs.abilities.AbilityConfig;
import com.projectkorra.projectkorra.element.Element;
import com.projectkorra.projectkorra.event.AbilityEndEvent;
import com.projectkorra.projectkorra.event.AbilityStartEvent;
import com.projectkorra.projectkorra.module.ModuleManager;
import com.projectkorra.projectkorra.util.FlightHandler;
import com.projectkorra.projectkorra.util.TimeUtil;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.plugin.java.JavaPlugin;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.Element.SubElement;
import com.projectkorra.projectkorra.command.HelpCommand;
import com.projectkorra.projectkorra.earthbending.EarthBlast;
import com.projectkorra.projectkorra.firebending.Blaze;
import com.projectkorra.projectkorra.firebending.FireBlast;
import com.projectkorra.projectkorra.firebending.FireBlastCharged;
import com.projectkorra.projectkorra.firebending.FireBurst;
import com.projectkorra.projectkorra.waterbending.TorrentWave;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarFile;
/**
* The Ability interface defines the set of methods that any CoreAbility,
* AddonAbility, ComboAbility, or MultiAbility should implement.
* {@link CoreAbility} provides a default implementation for a few of these
* methods, but most will need to be specified by each Ability individually.
*/
public interface Ability {
/**
* Causes the ability to be updated.
*/
public void progress();
/**
* Causes the ability to be removed from existence.
*/
public void remove();
/**
* Determines if this ability uses the {@link PlayerToggleSneakEvent} as a
* controlling mechanism. Currently {@link WaterPassive} will not work while
* the player has a sneak ability bound.
* Ability provides default implementation of an Ability, including methods
* to control the life cycle of a specific instance. Ability 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 Ability may need to
* override {@link #isCollidable()}, {@link #getCollisionRadius()},
* {@link #handleCollision(Collision)}, and {@link #getLocations()}.
*
* @return true if the ability uses sneak as a controlling mechanism
* @see #start()
* @see #progress()
* @see #remove()
* @see #registerAddonAbilities(String)
* @see #registerPluginAbilities(JavaPlugin, String)
*/
public boolean isSneakAbility();
public abstract class Ability<Config extends AbilityConfig> {
private static final double DEFAULT_COLLISION_RADIUS = 0.3;
private static final List<String> ADDON_PLUGINS = new ArrayList<>();
private static final Map<Class<? extends Ability>, Map<String, Field>> ATTRIBUTE_FIELDS = new HashMap<>();
private static int idCounter;
protected final AbilityManager manager = ModuleManager.getModule(AbilityManager.class);
protected final Config config = ConfigManager.getConfig(((Class<Config>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]));
protected Player player;
protected BendingPlayer bPlayer;
protected FlightHandler flightHandler;
private final Map<String, Map<AttributePriority, Set<Pair<Number, AttributeModifier>>>> attributeModifiers = new HashMap<>();
private final Map<String, Object> attributeValues = new HashMap<>();
private boolean started;
private boolean removed;
private boolean hidden;
private int id;
private long startTime;
private long startTick;
private boolean attributesModified;
static {
idCounter = Integer.MIN_VALUE;
}
/**
* Determines if this ability is considered harmless against other players.
* A harmless ability cannot manipulate another player. For example:
* AirPassive, WaterSpout, AirSpout, and FireJet.
* The default constructor is needed to create a fake instance of each
* Ability 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.
*
* @return true if the ability is harmless and should be allowed in both PvP
* and non-PvP zones
* @see #ABILITIES_BY_NAME
* @see #getAbility(String)
*/
public boolean isHarmlessAbility();
public Ability() {
for (final Field field : this.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(Attribute.class)) {
final Attribute attribute = field.getAnnotation(Attribute.class);
if (!ATTRIBUTE_FIELDS.containsKey(this.getClass())) {
ATTRIBUTE_FIELDS.put(this.getClass(), new HashMap<>());
}
ATTRIBUTE_FIELDS.get(this.getClass()).put(attribute.value(), field);
}
}
}
/**
* Determines if this ability can ignite blocks. For example: {@link Blaze},
* {@link FireBlast}, and {@link FireBurst}.
*/
public boolean isIgniteAbility();
/**
* Determines if this ability can cause explosions. For example:
* {@link FireBlastCharged}
*/
public boolean isExplosiveAbility();
/**
* A hidden ability is an ability that should not be shown by commands such
* as <b>/bending display</b> and <b>/bending help</b>. For example: Combos,
* MultiAbility sub abilities, and helper abilities.
* Creates a new Ability instance but does not start it.
*
* @return true if the ability should not be displayed to the players
* @param player the non-null player that created this instance
* @see #start()
*/
public boolean isHiddenAbility();
public Ability(final Config config, final Player player) {
if (player == null || !this.isEnabled()) {
return;
}
this.player = player;
this.bPlayer = BendingPlayer.getBendingPlayer(player);
this.flightHandler = Manager.getManager(FlightHandler.class);
this.startTime = System.currentTimeMillis();
this.started = false;
this.id = Ability.idCounter;
this.startTick = this.getCurrentTick();
if (idCounter == Integer.MAX_VALUE) {
idCounter = Integer.MIN_VALUE;
} else {
idCounter++;
}
}
/**
* Returns true if the ability is enabled through the config.yml. Usually
* the Enabled option follows the format
* Abilities.ElementName.AbilityName.Enabled.
*/
public boolean isEnabled();
/**
* @return the cooldown for the ability
*/
public long getCooldown();
/**
* Returns the player that caused this ability to be initiated. The player
* can be null in certain circumstances, for example when calling
* {@link CoreAbility#getAbility(String)}, or if an ability decided to set
* player to null.
* 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.
*
* @return the player that this ability belongs to
* @see #getStartTime()
* @see #isStarted()
* @see #isRemoved()
*/
public Player getPlayer();
public final void start() {
if (this.player == null || !this.isEnabled()) {
return;
}
final AbilityStartEvent event = new AbilityStartEvent(this);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
this.remove();
return;
}
this.started = true;
this.startTime = System.currentTimeMillis();
final Class<? extends Ability> clazz = this.getClass();
final UUID uuid = this.player.getUniqueId();
this.manager.startAbility(this);
}
/**
* The name of the ability is used for commands such as <b>/bending
* display</b> and <b>/bending help</b>. The name is also used for
* determining the tag for cooldowns
* {@link BendingPlayer#addCooldown(Ability)}, therefore if two abilities
* have the same name they will also share cooldowns. If two classes share
* the same name (SurgeWall/SurgeWave) but need to have independent
* cooldowns, then {@link BendingPlayer#addCooldown(String, long)} should be
* called explicitly.
* Causes this Ability 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>.
*
* @return Returns the name of the ability
* {@inheritDoc}
*
* @see #isRemoved()
*/
public String getName();
public void remove() {
if (this.player == null) {
return;
}
Bukkit.getServer().getPluginManager().callEvent(new AbilityEndEvent(this));
this.removed = true;
this.manager.removeAbility(this);
}
protected void tryModifyAttributes() {
if (!this.attributesModified) {
modifyAttributes();
this.attributesModified = true;
}
}
/**
* Return's the instructions of an ability. ProjectKorra's help command will
* then use this method to display the instructions of an ability when the
* command is run.
* Ability keeps track of plugins that have registered abilities to use
* for bending reload purposes <br>
* <b>This isn't a simple list, external use isn't recommended</b>
*
* @return the instructions for this ability
* @see HelpCommand
* @see CoreAbility#getInstructions()
* @return a list of entrys with the plugin name and path abilities can be
* found at
*/
public String getInstructions();
public static List<String> getAddonPlugins() {
return ADDON_PLUGINS;
}
/**
* The description of an ability is a few sentences used to describe how the
* player can fully utilize the ability. In most cases the description will
* be specified in the config.yml file and will be retrieved by accessing
* the FileConfiguration via {@link CoreAbility#getConfig}.
* Scans a JavaPlugin and registers Ability class files.
*
* @return the description for this ability
* @see HelpCommand
* @see CoreAbility#getDescription()
* @param plugin a JavaPlugin containing Ability class files
* @param packageBase a prefix of the package name, used to increase
* performance
* @see #getAbilities()
* @see #getAbility(String)
*/
public String getDescription();
public static void registerPluginAbilities(final JavaPlugin plugin, final String packageBase) {
final com.projectkorra.projectkorra.ability.loader.AbilityLoader<Ability> abilityLoader = new com.projectkorra.projectkorra.ability.loader.AbilityLoader<Ability>(plugin, packageBase);
final List<Ability> loadedAbilities = abilityLoader.load(Ability.class, Ability.class);
final String entry = plugin.getName() + "::" + packageBase;
if (!ADDON_PLUGINS.contains(entry)) {
ADDON_PLUGINS.add(entry);
}
for (final Ability coreAbil : loadedAbilities) {
if (!coreAbil.isEnabled()) {
plugin.getLogger().info(coreAbil.getName() + " is disabled");
continue;
}
final String name = coreAbil.getName();
if (name == null) {
plugin.getLogger().warning("Ability " + coreAbil.getClass().getName() + " has no name?");
continue;
}
try {
ABILITIES_BY_NAME.put(name.toLowerCase(), coreAbil);
ABILITIES_BY_CLASS.put(coreAbil.getClass(), coreAbil);
if (coreAbil instanceof ComboAbility) {
final ComboAbility combo = (ComboAbility) coreAbil;
if (combo.getCombination() != null) {
ComboManager.getComboAbilities().put(name, new ComboManager.ComboAbilityInfo(name, combo.getCombination(), combo));
ComboManager.getDescriptions().put(name, coreAbil.getDescription());
ComboManager.getInstructions().put(name, coreAbil.getInstructions());
}
}
if (coreAbil instanceof MultiAbility) {
final MultiAbility multiAbil = (MultiAbility) coreAbil;
MultiAbilityManager.multiAbilityList.add(new MultiAbilityInfo(name, multiAbil.getMultiAbilities()));
}
if (coreAbil instanceof PassiveAbility) {
PassiveAbility passive = (PassiveAbility) coreAbil;
coreAbil.setHiddenAbility(true);
PassiveManager.getPassives().put(name, coreAbil);
if (!PassiveManager.getPassiveClasses().containsKey(passive)) {
PassiveManager.getPassiveClasses().put(passive, coreAbil.getClass());
}
}
} 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();
ABILITIES_BY_NAME.remove(name.toLowerCase());
ABILITIES_BY_CLASS.remove(coreAbil.getClass());
}
}
}
/**
* Specifies the Element used to represent this type of ability, favoring
* SubElements over Elements. For example, a LightningAbility would return
* {@link Element#LIGHTNING} instead of {@link Element#FIRE}.
* Scans all of the Jar files inside of /ProjectKorra/folder and registers
* all of the Ability class files that were found.
*
* @return the most accurate Element that this ability belongs to
* @see SubElement#getParentElement
* @param folder the name of the folder to scan
* @see #getAbilities()
* @see #getAbility(String)
*/
public Element getElement();
public static void registerAddonAbilities(final String folder) {
final ProjectKorra plugin = ProjectKorra.plugin;
final File path = new File(plugin.getDataFolder().toString() + folder);
if (!path.exists()) {
path.mkdir();
return;
}
final com.projectkorra.projectkorra.ability.loader.AddonAbilityLoader<Ability> abilityLoader = new AddonAbilityLoader<Ability>(plugin, path);
final List<Ability> loadedAbilities = abilityLoader.load(Ability.class, Ability.class);
for (final Ability coreAbil : loadedAbilities) {
if (!(coreAbil instanceof AddonAbility)) {
plugin.getLogger().warning(coreAbil.getName() + " is an addon ability and must implement the AddonAbility interface");
continue;
} else if (!coreAbil.isEnabled()) {
plugin.getLogger().info(coreAbil.getName() + " is disabled");
continue;
}
final AddonAbility addon = (AddonAbility) coreAbil;
final String name = coreAbil.getName();
try {
addon.load();
ABILITIES_BY_NAME.put(name.toLowerCase(), coreAbil);
ABILITIES_BY_CLASS.put(coreAbil.getClass(), coreAbil);
if (coreAbil instanceof ComboAbility) {
final ComboAbility combo = (ComboAbility) coreAbil;
if (combo.getCombination() != null) {
ComboManager.getComboAbilities().put(name, new ComboManager.ComboAbilityInfo(name, combo.getCombination(), combo));
ComboManager.getDescriptions().put(name, coreAbil.getDescription());
ComboManager.getInstructions().put(name, coreAbil.getInstructions());
ComboManager.getAuthors().put(name, addon.getAuthor());
}
}
if (coreAbil instanceof MultiAbility) {
final MultiAbility multiAbil = (MultiAbility) coreAbil;
MultiAbilityManager.multiAbilityList.add(new MultiAbilityInfo(name, multiAbil.getMultiAbilities()));
}
if (coreAbil instanceof PassiveAbility) {
PassiveAbility passive = (PassiveAbility) coreAbil;
coreAbil.setHiddenAbility(true);
PassiveManager.getPassives().put(name, coreAbil);
if (!PassiveManager.getPassiveClasses().containsKey(passive)) {
PassiveManager.getPassiveClasses().put(passive, coreAbil.getClass());
}
}
} 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_CLASS.remove(coreAbil.getClass());
}
}
}
public long getStartTime() {
return this.startTime;
}
public long getStartTick() {
return this.startTick;
}
public long getCurrentTick() {
return this.player.getWorld().getFullTime();
}
public boolean isStarted() {
return this.started;
}
public boolean isRemoved() {
return this.removed;
}
public BendingPlayer getBendingPlayer() {
return this.bPlayer;
}
public int getId() {
return this.id;
}
public abstract Class<Config> getConfigType();
public boolean isHiddenAbility() {
return this.hidden;
}
public void setHiddenAbility(final boolean hidden) {
this.hidden = hidden;
}
public String getInstructions() {
return config.Instructions;
}
public String getDescription() {
return config.Description;
}
public String getMovePreview(final Player player) {
final BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
String displayedMessage = "";
if (bPlayer.isOnCooldown(this)) {
final long cooldown = bPlayer.getCooldown(this.getName()) - System.currentTimeMillis();
displayedMessage = this.getElement().getColor() + "" + ChatColor.STRIKETHROUGH + this.getName() + "" + this.getElement().getColor() + " - " + TimeUtil.formatTime(cooldown);
} else {
if (bPlayer.getStance() != null && bPlayer.getStance().getName().equals(this.getName())) {
displayedMessage = this.getElement().getColor() + "" + ChatColor.UNDERLINE + this.getName();
} else {
displayedMessage = this.getElement().getColor() + this.getName();
}
}
return displayedMessage;
}
public Player getPlayer() {
return this.player;
}
/**
* Specifies the Location of the ability, which may be slightly inaccurate
* depending on the Ability implementation. For example, a
* {@link TorrentWave} could not be fully specified by a single location,
* while it is possible for an {@link EarthBlast}. The location is useful
* for making sure that the player is currently in the same world as the
* ability.
* Changes the player that owns this ability instance. Used for redirection
* and other abilities that change the player object.
*
* @return the location of the Ability
* @see BendingPlayer#canBend(CoreAbility)
* @param target The player who now controls the ability
*/
public Location getLocation();
public void setPlayer(final Player target) {
if (target == this.player) {
return;
}
final Class<? extends Ability> clazz = this.getClass();
// The mapping from player UUID to a map of the player's instances.
Map<UUID, Map<Integer, Ability>> classMap = INSTANCES_BY_PLAYER.get(clazz);
if (classMap != null) {
// The map of AbilityId to Ability for the current player.
final Map<Integer, Ability> playerMap = classMap.get(this.player.getUniqueId());
if (playerMap != null) {
// Remove the ability from the current player's map.
playerMap.remove(this.id);
if (playerMap.isEmpty()) {
// Remove the player's empty ability map from global instances map.
classMap.remove(this.player.getUniqueId());
}
}
if (classMap.isEmpty()) {
INSTANCES_BY_PLAYER.remove(this.getClass());
}
}
// Add a new map for the current ability if it doesn't exist in the global map.
if (!INSTANCES_BY_PLAYER.containsKey(clazz)) {
INSTANCES_BY_PLAYER.put(clazz, new ConcurrentHashMap<>());
}
classMap = INSTANCES_BY_PLAYER.get(clazz);
// Create an AbilityId to Ability map for the target player if it doesn't exist.
if (!classMap.containsKey(target.getUniqueId())) {
classMap.put(target.getUniqueId(), new ConcurrentHashMap<>());
}
// Add the current instance to the target player's ability map.
classMap.get(target.getUniqueId()).put(this.getId(), this);
this.player = target;
final BendingPlayer newBendingPlayer = BendingPlayer.getBendingPlayer(target);
if (newBendingPlayer != null) {
this.bPlayer = newBendingPlayer;
}
}
/**
* 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(final Collision collision) {
if (collision.isRemovingFirst()) {
this.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() {
final ArrayList<Location> locations = new ArrayList<>();
locations.add(this.getLocation());
return locations;
}
public Ability addAttributeModifier(final String attribute, final Number value, final AttributeModifier modification) {
return this.addAttributeModifier(attribute, value, modification, AttributePriority.MEDIUM);
}
public Ability addAttributeModifier(final String attribute, final Number value, final AttributeModifier modificationType, final AttributePriority priority) {
Validate.notNull(attribute, "attribute cannot be null");
Validate.notNull(value, "value cannot be null");
Validate.notNull(modificationType, "modifierMethod cannot be null");
Validate.notNull(priority, "priority cannot be null");
Validate.isTrue(ATTRIBUTE_FIELDS.containsKey(this.getClass()) && ATTRIBUTE_FIELDS.get(this.getClass()).containsKey(attribute), "Attribute " + attribute + " is not a defined Attribute for " + this.getName());
if (!this.attributeModifiers.containsKey(attribute)) {
this.attributeModifiers.put(attribute, new HashMap<>());
}
if (!this.attributeModifiers.get(attribute).containsKey(priority)) {
this.attributeModifiers.get(attribute).put(priority, new HashSet<>());
}
this.attributeModifiers.get(attribute).get(priority).add(Pair.of(value, modificationType));
return this;
}
public Ability setAttribute(final String attribute, final Object value) {
Validate.notNull(attribute, "attribute cannot be null");
Validate.notNull(value, "value cannot be null");
Validate.isTrue(ATTRIBUTE_FIELDS.containsKey(this.getClass()) && ATTRIBUTE_FIELDS.get(this.getClass()).containsKey(attribute), "Attribute " + attribute + " is not a defined Attribute for " + this.getName());
this.attributeValues.put(attribute, value);
return this;
}
private void modifyAttributes() {
for (final String attribute : this.attributeModifiers.keySet()) {
final Field field = ATTRIBUTE_FIELDS.get(this.getClass()).get(attribute);
final boolean accessibility = field.isAccessible();
field.setAccessible(true);
try {
for (final AttributePriority priority : AttributePriority.values()) {
if (this.attributeModifiers.get(attribute).containsKey(priority)) {
for (final Pair<Number, AttributeModifier> pair : this.attributeModifiers.get(attribute).get(priority)) {
final Object get = field.get(this);
Validate.isTrue(get instanceof Number, "The field " + field.getName() + " cannot algebraically be modified.");
final Number oldValue = (Number) field.get(this);
final Number newValue = pair.getRight().performModification(oldValue, pair.getLeft());
field.set(this, newValue);
}
}
}
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
} finally {
field.setAccessible(accessibility);
}
}
this.attributeValues.forEach((attribute, value) -> {
final Field field = ATTRIBUTE_FIELDS.get(this.getClass()).get(attribute);
final boolean accessibility = field.isAccessible();
field.setAccessible(true);
try {
field.set(this, value);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
} finally {
field.setAccessible(accessibility);
}
});
}
/**
* Returns a String used to debug potential Ability memory that can be
* caused by a developer forgetting to call {@link #remove()}
*/
public static String getDebugString() {
final StringBuilder sb = new StringBuilder();
int playerCounter = 0;
final HashMap<String, Integer> classCounter = new HashMap<>();
for (final Map<UUID, Map<Integer, Ability>> map1 : INSTANCES_BY_PLAYER.values()) {
playerCounter++;
for (final Map<Integer, Ability> map2 : map1.values()) {
for (final Ability coreAbil : map2.values()) {
final String simpleName = coreAbil.getClass().getSimpleName();
if (classCounter.containsKey(simpleName)) {
classCounter.put(simpleName, classCounter.get(simpleName) + 1);
} else {
classCounter.put(simpleName, 1);
}
}
}
}
for (final Set<Ability> set : INSTANCES_BY_CLASS.values()) {
for (final Ability coreAbil : set) {
final String simpleName = coreAbil.getClass().getSimpleName();
if (classCounter.containsKey(simpleName)) {
classCounter.put(simpleName, classCounter.get(simpleName) + 1);
} else {
classCounter.put(simpleName, 1);
}
}
}
sb.append("Class->UUID's in memory: " + playerCounter + "\n");
sb.append("Abilities in memory:\n");
for (final String className : classCounter.keySet()) {
sb.append(className + ": " + classCounter.get(className) + "\n");
}
return sb.toString();
}
public abstract void progress();
public abstract boolean isSneakAbility();
public abstract boolean isHarmlessAbility();
public abstract boolean isIgniteAbility();
public abstract boolean isExplosiveAbility();
public abstract long getCooldown();
public abstract String getName();
public abstract Element getElement();
public abstract Location getLocation();
public static double getDefaultCollisionRadius() {
return DEFAULT_COLLISION_RADIUS;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
}

View file

@ -0,0 +1,43 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.ability.loader.AbilityLoader;
import com.projectkorra.projectkorra.player.BendingPlayer;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface AbilityData {
/**
* The name of the ability is used for commands such as <b>/bending
* display</b> and <b>/bending help</b>. The name is also used for
* determining the tag for cooldowns
* {@link BendingPlayer#addCooldown(Ability)}, therefore if two abilities
* have the same name they will also share cooldowns. If two classes share
* the same name (SurgeWall/SurgeWave) but need to have independent
* cooldowns, then {@link BendingPlayer#addCooldown(String, long)} should be
* called explicitly.
*
* @return Returns the name of the ability
*/
String name();
/**
* @return the name of the author of this AddonAbility
*/
String author() default "ProjectKorra";
/**
* @return The version of the ability as a String.
*/
String version() default "1.0";
/**
* @return The class used to register this ability.
*/
Class<? extends AbilityLoader> abilityLoader();
}

View file

@ -1,129 +1,251 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.GeneralMethods;
import co.aikar.timings.lib.MCTiming;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
import com.projectkorra.projectkorra.ability.loader.*;
import com.projectkorra.projectkorra.ability.util.ComboManager;
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.configuration.configs.abilities.AbilityConfig;
import com.projectkorra.projectkorra.element.Element;
import com.projectkorra.projectkorra.element.SubElement;
import com.projectkorra.projectkorra.event.AbilityProgressEvent;
import com.projectkorra.projectkorra.firebending.FireBlast;
import com.projectkorra.projectkorra.module.DatabaseModule;
import com.projectkorra.projectkorra.module.ModuleManager;
import com.projectkorra.projectkorra.player.BendingPlayer;
import com.projectkorra.projectkorra.player.BendingPlayerLoadedEvent;
import com.projectkorra.projectkorra.player.BendingPlayerManager;
import com.projectkorra.projectkorra.module.Module;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import java.sql.SQLException;
import java.lang.reflect.ParameterizedType;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
public class AbilityManager extends DatabaseModule<AbilityRepository> {
public class AbilityManager extends Module {
private final BendingPlayerManager bendingPlayerManager;
private final Set<Ability> abilitySet = new HashSet<>();
private final Map<UUID, Map<Class<? extends Ability>, LinkedList<Ability>>> abilityMap = new HashMap<>();
private AbilityManager() {
super("Ability", new AbilityRepository());
public AbilityManager() {
super("Ability");
this.bendingPlayerManager = ModuleManager.getModule(BendingPlayerManager.class);
runAsync(() -> {
try {
getRepository().createTables();
} catch (SQLException e) {
e.printStackTrace();
runTimer(() -> {
for (Ability ability : abilitySet) {
if (ability instanceof PassiveAbility) {
if (!((PassiveAbility) ability).isProgressable()) {
return;
}
runSync(() -> {
log("Created database tables.");
});
});
// This has to be before isDead as isDead will return true if they are offline.
if (!ability.getPlayer().isOnline()) {
ability.remove();
return;
}
if (ability.getPlayer().isDead()) {
return;
}
} else if (ability.getPlayer().isDead()) {
ability.remove();
continue;
} else if (!ability.getPlayer().isOnline()) {
ability.remove();
continue;
}
try {
ability.tryModifyAttributes();
try (MCTiming timing = ProjectKorra.timing(ability.getName()).startTiming()) {
ability.progress();
}
getPlugin().getServer().getPluginManager().callEvent(new AbilityProgressEvent(ability));
} catch (Exception e) {
e.printStackTrace();
getPlugin().getLogger().severe(ability.toString());
try {
ability.getPlayer().sendMessage(ChatColor.YELLOW + "[" + new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").format(new Date()) + "] " + ChatColor.RED + "There was an error running " + ability.getName() + ". please notify the server owner describing exactly what you were doing at this moment");
} catch (final Exception me) {
Bukkit.getLogger().severe("unable to notify ability user of error");
}
try {
ability.remove();
} catch (final Exception re) {
Bukkit.getLogger().severe("unable to fully remove ability of above error");
}
}
}
// TODO progress abilities
}, 1L, 1L);
registerAbilities();
}
private void registerAbilities() {
/**
* Scans and loads plugin CoreAbilities, and Addon CoreAbilities that are
* located in a Jar file inside of the /ProjectKorra/Abilities/ folder.
*/
public void registerAbilities() {
this.abilitySet.clear();
this.abilityMap.clear();
Ability.registerPluginAbilities(getPlugin(), "com.projectkorra");
Ability.registerAddonAbilities("/Abilities/");
registerAbility(FireBlast.class);
}
private void registerAbility(Class<? extends Ability> abilityClass) {
// TODO
private <T extends Ability> void registerAbility(Class<T> abilityClass) throws IllegalAccessException, InstantiationException {
AbilityData abilityData = abilityClass.getDeclaredAnnotation(AbilityData.class);
if (abilityData == null) {
getPlugin().getLogger().warning("Ability " + abilityClass.getName() + " has no AbilityData annotation");
return;
}
@EventHandler
public void onBendingPlayerLoaded(BendingPlayerLoadedEvent event) {
BendingPlayer bendingPlayer = event.getBendingPlayer();
runAsync(() -> {
try {
String[] abilities = getRepository().selectPlayerAbilities(bendingPlayer.getId());
bendingPlayer.setAbilities(abilities);
} catch (SQLException e) {
e.printStackTrace();
}
});
}
public boolean bindAbility(Player player, String abilityName, int slot) {
PlayerBindAbilityEvent playerBindAbilityEvent = new PlayerBindAbilityEvent(player, abilityName);
getPlugin().getServer().getPluginManager().callEvent(playerBindAbilityEvent);
if (playerBindAbilityEvent.isCancelled()) {
String cancelMessage = playerBindAbilityEvent.getCancelMessage();
if (cancelMessage != null) {
GeneralMethods.sendBrandingMessage(player, cancelMessage);
}
return false;
}
BendingPlayer bendingPlayer = this.bendingPlayerManager.getBendingPlayer(player);
bendingPlayer.setAbility(slot, abilityName);
runAsync(() -> {
try {
getRepository().insertPlayerAbility(bendingPlayer.getId(), abilityName, slot);
} catch (SQLException e) {
e.printStackTrace();
}
});
return true;
}
public boolean unbindAbility(Player player, int slot) {
BendingPlayer bendingPlayer = this.bendingPlayerManager.getBendingPlayer(player);
String abilityName = bendingPlayer.getAbility(slot);
String abilityName = abilityData.name();
if (abilityName == null) {
player.sendMessage("No ability bound");
getPlugin().getLogger().warning("Ability " + abilityClass.getName() + " has no name?");
return;
}
AbilityLoader abilityLoader = abilityData.abilityLoader().newInstance();
AbilityConfig abilityConfig = ConfigManager.getConfig(((Class<? extends AbilityConfig>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]));
if (!abilityConfig.Enabled) {
getPlugin().getLogger().info(abilityName + " is disabled");
return;
}
if (abilityLoader instanceof AddonAbilityLoader) {
((AddonAbilityLoader) abilityLoader).load();
}
if (abilityLoader instanceof ComboAbilityLoader) {
ComboAbilityLoader comboAbilityLoader = (ComboAbilityLoader) abilityLoader;
if (comboAbilityLoader.getCombination() == null) {
getPlugin().getLogger().info(abilityName + " has no combination");
return;
}
// TODO Register Combo Ability
// ComboManager.getComboAbilities().put(abilityName, new ComboManager.ComboAbilityInfo(abilityName, comboAbilityLoader.getCombination(), ));
ComboManager.getDescriptions().put(abilityName, abilityConfig.Description);
ComboManager.getInstructions().put(abilityName, abilityConfig.Instructions);
}
if (abilityLoader instanceof MultiAbilityLoader) {
MultiAbilityLoader multiAbilityLoader = (MultiAbilityLoader) abilityLoader;
MultiAbilityManager.multiAbilityList.add(new MultiAbilityManager.MultiAbilityInfo(abilityName, multiAbilityLoader.getMultiAbilities()));
}
if (abilityLoader instanceof PassiveAbilityLoader) {
PassiveAbilityLoader passiveAbilityLoader = (PassiveAbilityLoader) abilityLoader;
// TODO Set Hidden Ability
// TODO Register Passive Ability
// PassiveManager.getPassives().put(abilityName, ability???)
}
}
public void startAbility(Ability ability) {
if (ability.isStarted()) {
return;
}
this.abilitySet.add(ability);
this.abilityMap.computeIfAbsent(ability.getPlayer().getUniqueId(), k -> new HashMap<>())
.computeIfAbsent(ability.getClass(), k -> new LinkedList<>())
.add(ability);
}
protected void removeAbility(Ability ability) {
if (ability.isRemoved()) {
return;
}
this.abilitySet.remove(ability);
this.abilityMap.values().removeIf(abilityMap ->
{
abilityMap.values().removeIf(abilityList ->
{
abilityList.remove(ability);
return abilityList.isEmpty();
});
return abilityMap.isEmpty();
});
}
/**
* Removes every {@link Ability} instance that has been started but not yet
* removed.
*/
public void removeAll() {
new HashSet<>(this.abilitySet).forEach(Ability::remove);
}
public <T extends Ability> boolean hasAbility(Player player, Class<T> ability) {
Map<Class<? extends Ability>, LinkedList<Ability>> abilities = this.abilityMap.get(player.getUniqueId());
if (abilities == null || !abilities.containsKey(ability)) {
return false;
}
bendingPlayer.setAbility(slot, null);
runAsync(() -> {
try {
getRepository().deletePlayerAbility(bendingPlayer.getId(), abilityName);
} catch (SQLException e) {
e.printStackTrace();
return !abilities.get(abilities).isEmpty();
}
public <T extends Ability> T getAbility(Player player, Class<T> ability) {
Map<Class<? extends Ability>, LinkedList<Ability>> abilities = this.abilityMap.get(player.getUniqueId());
if (abilities == null || !abilities.containsKey(ability)) {
return null;
}
return ability.cast(abilities.get(ability).getFirst());
}
public <T extends Ability> Collection<T> getAbilities(Player player, Class<T> ability) {
Map<Class<? extends Ability>, LinkedList<Ability>> abilities = this.abilityMap.get(player.getUniqueId());
if (abilities == null || !abilities.containsKey(ability)) {
return null;
}
return abilities.get(abilities).stream().map(ability::cast).collect(Collectors.toList());
}
public <T extends Ability> LinkedList<T> getAbilities(Class<T> abilityClass) {
LinkedList<T> abilities = new LinkedList<>();
this.abilityMap.values().forEach(a -> {
a.values().forEach(ability -> abilities.add(abilityClass.cast(ability)));
});
return abilities;
}
public List<Ability> getAbilities(Element element) {
this.abilitySet.stream()
.filter(ability ->
{
if (ability.getElement().equals(element)) {
return true;
}
public void clearBinds(Player player) {
BendingPlayer bendingPlayer = this.bendingPlayerManager.getBendingPlayer(player);
bendingPlayer.setAbilities(new String[9]);
runAsync(() -> {
try {
getRepository().deletePlayerAbilities(bendingPlayer.getId());
} catch (SQLException e) {
e.printStackTrace();
if (ability.getElement() instanceof SubElement) {
return ((SubElement) ability.getElement()).getParent().equals(element);
}
});
return false;
})
.collect(Collectors.toList());
}
}

View file

@ -0,0 +1,128 @@
package com.projectkorra.projectkorra.ability;
import com.projectkorra.projectkorra.module.Module;
import com.projectkorra.projectkorra.util.ClickType;
import java.util.*;
public class ComboManager extends Module {
private final Map<UUID, List<AbilityInformation>> recentlyUsed = new HashMap<>();
private ComboManager() {
super("Combo Ability");
}
/**
* Contains information on an ability used in a combo.
*
* @author kingbirdy
*
*/
public static class AbilityInformation {
private String abilityName;
private ClickType clickType;
private long time;
public AbilityInformation(final String name, final ClickType type) {
this(name, type, 0);
}
public AbilityInformation(final String name, final ClickType type, final long time) {
this.abilityName = name;
this.clickType = type;
this.time = time;
}
/**
* Compares if two {@link com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation}'s are equal without
* respect to {@link com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation#time time}.
*
* @param info The AbilityInformation to compare against
* @return True if they are equal without respect to time
*/
public boolean equalsWithoutTime(final com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation info) {
return this.getAbilityName().equals(info.getAbilityName()) && this.getClickType().equals(info.getClickType());
}
/**
* Gets the name of the ability.
*
* @return The name of the ability.
*/
public String getAbilityName() {
return this.abilityName;
}
/**
* Gets the {@link ClickType} of the {@link com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation}.
*
* @return The ClickType
*/
public ClickType getClickType() {
return this.clickType;
}
public long getTime() {
return this.time;
}
public void setAbilityName(final String abilityName) {
this.abilityName = abilityName;
}
public void setClickType(final ClickType clickType) {
this.clickType = clickType;
}
public void setTime(final long time) {
this.time = time;
}
@Override
public String toString() {
return this.abilityName + " " + this.clickType + " " + this.time;
}
}
public static class ComboAbilityInfo {
private String name;
private ArrayList<com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation> abilities;
private Object comboType;
public ComboAbilityInfo(final String name, final ArrayList<com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation> abilities, final Object comboType) {
this.name = name;
this.abilities = abilities;
this.comboType = comboType;
}
public ArrayList<com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation> getAbilities() {
return this.abilities;
}
public Object getComboType() {
return this.comboType;
}
public String getName() {
return this.name;
}
public void setAbilities(final ArrayList<com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation> abilities) {
this.abilities = abilities;
}
public void setComboType(final Object comboType) {
this.comboType = comboType;
}
public void setName(final String name) {
this.name = name;
}
@Override
public String toString() {
return this.name;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
public interface AddonAbility {

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import java.util.ArrayList;
import java.util.List;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.Location;
import org.bukkit.entity.Player;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.entity.Player;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.entity.Player;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import java.util.ArrayList;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.entity.Player;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import java.util.ArrayList;
import java.util.HashSet;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import java.util.Arrays;
import java.util.HashSet;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import java.util.ArrayList;
import java.util.Iterator;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.entity.Player;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.entity.Player;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.entity.Player;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.entity.Player;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.entity.Player;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.entity.Player;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import java.util.ArrayList;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
public interface PassiveAbility {

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.entity.Player;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.entity.Player;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import org.bukkit.entity.Player;

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
public interface SubAbility {

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.api;
import java.util.HashSet;
import java.util.Set;

View file

@ -0,0 +1,117 @@
package com.projectkorra.projectkorra.ability.bind;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.api.PlayerBindAbilityEvent;
import com.projectkorra.projectkorra.module.DatabaseModule;
import com.projectkorra.projectkorra.module.ModuleManager;
import com.projectkorra.projectkorra.player.BendingPlayer;
import com.projectkorra.projectkorra.player.BendingPlayerLoadedEvent;
import com.projectkorra.projectkorra.player.BendingPlayerManager;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import java.sql.SQLException;
public class AbilityBindManager extends DatabaseModule<AbilityBindRepository> {
private final BendingPlayerManager bendingPlayerManager;
private AbilityBindManager() {
super("Ability Binds", new AbilityBindRepository());
this.bendingPlayerManager = ModuleManager.getModule(BendingPlayerManager.class);
runAsync(() -> {
try {
getRepository().createTables();
} catch (SQLException e) {
e.printStackTrace();
}
runSync(() -> {
log("Created database tables.");
});
});
}
@EventHandler
public void onBendingPlayerLoaded(BendingPlayerLoadedEvent event) {
BendingPlayer bendingPlayer = event.getBendingPlayer();
runAsync(() -> {
try {
String[] abilities = getRepository().selectPlayerAbilities(bendingPlayer.getId());
bendingPlayer.setAbilities(abilities);
} catch (SQLException e) {
e.printStackTrace();
}
});
}
public boolean bindAbility(Player player, String abilityName, int slot) {
PlayerBindAbilityEvent playerBindAbilityEvent = new PlayerBindAbilityEvent(player, abilityName);
getPlugin().getServer().getPluginManager().callEvent(playerBindAbilityEvent);
if (playerBindAbilityEvent.isCancelled()) {
String cancelMessage = playerBindAbilityEvent.getCancelMessage();
if (cancelMessage != null) {
GeneralMethods.sendBrandingMessage(player, cancelMessage);
}
return false;
}
BendingPlayer bendingPlayer = this.bendingPlayerManager.getBendingPlayer(player);
bendingPlayer.setAbility(slot, abilityName);
runAsync(() -> {
try {
getRepository().insertPlayerAbility(bendingPlayer.getId(), abilityName, slot);
} catch (SQLException e) {
e.printStackTrace();
}
});
return true;
}
public boolean unbindAbility(Player player, int slot) {
BendingPlayer bendingPlayer = this.bendingPlayerManager.getBendingPlayer(player);
String abilityName = bendingPlayer.getAbility(slot);
if (abilityName == null) {
player.sendMessage("No ability bound");
return false;
}
bendingPlayer.setAbility(slot, null);
runAsync(() -> {
try {
getRepository().deletePlayerAbility(bendingPlayer.getId(), abilityName);
} catch (SQLException e) {
e.printStackTrace();
}
});
return true;
}
public void clearBinds(Player player) {
BendingPlayer bendingPlayer = this.bendingPlayerManager.getBendingPlayer(player);
bendingPlayer.setAbilities(new String[9]);
runAsync(() -> {
try {
getRepository().deletePlayerAbilities(bendingPlayer.getId());
} catch (SQLException e) {
e.printStackTrace();
}
});
}
}

View file

@ -1,4 +1,4 @@
package com.projectkorra.projectkorra.ability;
package com.projectkorra.projectkorra.ability.bind;
import com.projectkorra.projectkorra.database.DatabaseQuery;
import com.projectkorra.projectkorra.database.DatabaseRepository;
@ -8,7 +8,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class AbilityRepository extends DatabaseRepository {
public class AbilityBindRepository extends DatabaseRepository {
private static final DatabaseQuery CREATE_TABLE_PLAYER_ABILITIES = DatabaseQuery.newBuilder()
.mysql("CREATE TABLE IF NOT EXISTS pk_player_abilities (player_id INTEGER REFERENCES pk_bending_players (player_id), ability_name VARCHAR(50) NOT NULL, slot TINYINT NOT NULL, PRIMARY KEY (player_id, ability_name), INDEX player_index (player_id), INDEX ability_index (ability_name));")

View file

@ -0,0 +1,4 @@
package com.projectkorra.projectkorra.ability.loader;
public abstract class AbilityLoader {
}

View file

@ -0,0 +1,20 @@
package com.projectkorra.projectkorra.ability.loader;
import com.projectkorra.projectkorra.ability.AbilityManager;
public abstract class AddonAbilityLoader extends AbilityLoader {
/**
* Called when the ability is loaded by PK. This is where the developer
* registers Listeners and Permissions.
*/
public abstract void load();
/**
* Called whenever ProjectKorra stops and the ability is unloaded. This
* method is useful for cleaning up leftover objects such as frozen blocks.
* Any CoreAbility instances do not need to be cleaned up by stop method, as
* they will be cleaned up by {@link AbilityManager#removeAll()}.
*/
public abstract void stop();
}

View file

@ -0,0 +1,15 @@
package com.projectkorra.projectkorra.ability.loader;
import com.projectkorra.projectkorra.ability.util.ComboManager;
import java.util.ArrayList;
public abstract class ComboAbilityLoader extends AbilityLoader {
/**
* Returns the list of abilities which constitute the combo.
*
* @return An ArrayList containing the combo's steps.
*/
public abstract ArrayList<ComboManager.AbilityInformation> getCombination();
}

View file

@ -0,0 +1,18 @@
package com.projectkorra.projectkorra.ability.loader;
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager;
import java.util.ArrayList;
public abstract class MultiAbilityLoader extends AbilityLoader {
/**
* Returns the sub abilities of a MultiAbility. For example:
* <p>
* {@code new
* MultiAbilitySub("SubAbility", Element.LIGHTNING);}
*
* @return a list of sub MultiAbilities
*/
public abstract ArrayList<MultiAbilityManager.MultiAbilityInfoSub> getMultiAbilities();
}

View file

@ -0,0 +1,21 @@
package com.projectkorra.projectkorra.ability.loader;
public abstract class PassiveAbilityLoader extends AbilityLoader {
/**
* This is a check to see if the passive requires some form of activation,
* such as sneaking, clicking, etc. <br>
* <b>If false, the passive should not call start!</b>
*
* @return false if this passive should always be on
*/
public abstract boolean isInstantiable();
/**
* This is used if the passive should progress
*
* @return false if progress() shouldn't be called;
*/
public abstract boolean isProgressable();
}

View file

@ -12,7 +12,7 @@ import org.bukkit.scheduler.BukkitRunnable;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.PassiveAbility;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
import com.projectkorra.projectkorra.event.AbilityCollisionEvent;
/**

View file

@ -13,7 +13,7 @@ import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.Element.SubElement;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.ComboAbility;
import com.projectkorra.projectkorra.ability.api.ComboAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.EarthDomeConfig;

View file

@ -6,7 +6,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.projectkorra.projectkorra.ability.PlayerBindAbilityEvent;
import com.projectkorra.projectkorra.ability.api.PlayerBindAbilityEvent;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;

View file

@ -13,7 +13,7 @@ import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.Element.SubElement;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.PassiveAbility;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
@SuppressWarnings({ "rawtypes", "unlikely-arg-type" })
public class PassiveManager {

View file

@ -25,7 +25,7 @@ import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.api.AirAbility;
import com.projectkorra.projectkorra.ability.util.Collision;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.command.Commands;

View file

@ -10,7 +10,7 @@ import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.api.AirAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.configuration.configs.abilities.air.AirBlastConfig;

View file

@ -15,8 +15,8 @@ import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.api.AirAbility;
import com.projectkorra.projectkorra.ability.api.ElementalAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.air.AirScooterConfig;

View file

@ -13,7 +13,7 @@ import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.api.AirAbility;
import com.projectkorra.projectkorra.ability.util.Collision;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.avatar.AvatarState;

View file

@ -10,8 +10,8 @@ import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.api.AirAbility;
import com.projectkorra.projectkorra.ability.api.ElementalAbility;
import com.projectkorra.projectkorra.ability.util.Collision;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.air.AirSpoutConfig;

View file

@ -18,7 +18,7 @@ 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.api.AirAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.util.Collision;
import com.projectkorra.projectkorra.attribute.Attribute;

View file

@ -18,9 +18,9 @@ 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.api.AirAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.api.ElementalAbility;
import com.projectkorra.projectkorra.ability.util.Collision;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.command.Commands;

View file

@ -13,7 +13,7 @@ import org.bukkit.scheduler.BukkitRunnable;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.api.AirAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.air.SuffocateConfig;
import com.projectkorra.projectkorra.util.DamageHandler;

View file

@ -12,8 +12,8 @@ import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.api.AirAbility;
import com.projectkorra.projectkorra.ability.api.ElementalAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.configuration.configs.abilities.air.TornadoConfig;

View file

@ -10,8 +10,8 @@ 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.api.AirAbility;
import com.projectkorra.projectkorra.ability.api.ComboAbility;
import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.command.Commands;

View file

@ -13,8 +13,8 @@ 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.api.AirAbility;
import com.projectkorra.projectkorra.ability.api.ComboAbility;
import com.projectkorra.projectkorra.ability.util.Collision;
import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
import com.projectkorra.projectkorra.attribute.Attribute;

View file

@ -9,8 +9,8 @@ import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.ComboAbility;
import com.projectkorra.projectkorra.ability.api.AirAbility;
import com.projectkorra.projectkorra.ability.api.ComboAbility;
import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.command.Commands;

View file

@ -20,8 +20,8 @@ import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.FlightAbility;
import com.projectkorra.projectkorra.ability.MultiAbility;
import com.projectkorra.projectkorra.ability.api.FlightAbility;
import com.projectkorra.projectkorra.ability.api.MultiAbility;
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager;
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager.MultiAbilityInfoSub;
import com.projectkorra.projectkorra.airbending.AirScooter;

View file

@ -5,8 +5,8 @@ import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.PassiveAbility;
import com.projectkorra.projectkorra.ability.api.AirAbility;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.air.AirAgilityConfig;

View file

@ -3,8 +3,8 @@ package com.projectkorra.projectkorra.airbending.passive;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.PassiveAbility;
import com.projectkorra.projectkorra.ability.api.AirAbility;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.configuration.configs.abilities.air.AirSaturationConfig;

View file

@ -3,8 +3,8 @@ package com.projectkorra.projectkorra.airbending.passive;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.PassiveAbility;
import com.projectkorra.projectkorra.ability.api.AirAbility;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
import com.projectkorra.projectkorra.configuration.configs.abilities.air.GracefulDescentConfig;
public class GracefulDescent extends AirAbility<GracefulDescentConfig> implements PassiveAbility {

View file

@ -7,7 +7,7 @@ import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import com.projectkorra.projectkorra.ability.AvatarAbility;
import com.projectkorra.projectkorra.ability.api.AvatarAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.configuration.configs.abilities.avatar.AvatarStateConfig;

View file

@ -8,7 +8,7 @@ import org.bukkit.potion.PotionEffectType;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.chi.AcrobatStanceConfig;

View file

@ -6,7 +6,7 @@ import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.chi.HighJumpConfig;
import com.projectkorra.projectkorra.waterbending.multiabilities.WaterArmsWhip;

View file

@ -8,7 +8,7 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.airbending.Suffocate;
import com.projectkorra.projectkorra.attribute.Attribute;

View file

@ -4,7 +4,7 @@ import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.chiblocking.passive.ChiPassive;
import com.projectkorra.projectkorra.configuration.configs.abilities.chi.QuickStrikeConfig;

View file

@ -5,7 +5,7 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.airbending.Suffocate;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.chiblocking.passive.ChiPassive;

View file

@ -11,7 +11,7 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.configuration.configs.abilities.chi.SmokescreenConfig;

View file

@ -4,8 +4,8 @@ import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.ability.api.ElementalAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.chiblocking.passive.ChiPassive;
import com.projectkorra.projectkorra.configuration.configs.abilities.chi.SwiftKickConfig;

View file

@ -8,7 +8,7 @@ import org.bukkit.potion.PotionEffectType;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.chi.WarriorStanceConfig;

View file

@ -9,8 +9,8 @@ import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.ComboAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.ability.api.ComboAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
import com.projectkorra.projectkorra.attribute.Attribute;

View file

@ -3,8 +3,8 @@ package com.projectkorra.projectkorra.chiblocking.passive;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.PassiveAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.configuration.configs.abilities.chi.AcrobaticsConfig;

View file

@ -5,8 +5,8 @@ import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.PassiveAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.chi.ChiAgilityConfig;

View file

@ -7,7 +7,7 @@ import org.bukkit.scheduler.BukkitRunnable;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.airbending.Suffocate;
import com.projectkorra.projectkorra.chiblocking.AcrobatStance;

View file

@ -3,8 +3,8 @@ package com.projectkorra.projectkorra.chiblocking.passive;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.ability.ChiAbility;
import com.projectkorra.projectkorra.ability.PassiveAbility;
import com.projectkorra.projectkorra.ability.api.ChiAbility;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.configuration.configs.abilities.chi.ChiSaturationConfig;

View file

@ -13,9 +13,9 @@ import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.Element.SubElement;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.ComboAbility;
import com.projectkorra.projectkorra.ability.api.ComboAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.PassiveAbility;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
import com.projectkorra.projectkorra.configuration.configs.commands.BindCommandConfig;
/**

View file

@ -15,10 +15,10 @@ import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.Element.SubElement;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.ComboAbility;
import com.projectkorra.projectkorra.ability.api.AddonAbility;
import com.projectkorra.projectkorra.ability.api.ComboAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.SubAbility;
import com.projectkorra.projectkorra.ability.api.SubAbility;
import com.projectkorra.projectkorra.ability.util.ComboManager;
import com.projectkorra.projectkorra.ability.util.PassiveManager;
import com.projectkorra.projectkorra.configuration.ConfigManager;

View file

@ -11,10 +11,10 @@ import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.ComboAbility;
import com.projectkorra.projectkorra.ability.api.AddonAbility;
import com.projectkorra.projectkorra.ability.api.ComboAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.PassiveAbility;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
import com.projectkorra.projectkorra.ability.util.ComboManager;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.configuration.configs.commands.HelpCommandConfig;

View file

@ -13,7 +13,7 @@ import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.CatapultConfig;
import com.projectkorra.projectkorra.util.ParticleEffect;

View file

@ -10,7 +10,7 @@ import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.CollapseConfig;
import com.projectkorra.projectkorra.util.BlockSource;

View file

@ -10,7 +10,7 @@ import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.CollapseConfig;
import com.projectkorra.projectkorra.util.BlockSource;

View file

@ -19,8 +19,8 @@ import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.ability.api.ElementalAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.configuration.ConfigManager;

View file

@ -13,8 +13,8 @@ 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.api.AirAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.ability.util.Collision;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.EarthBlastConfig;

View file

@ -11,7 +11,7 @@ import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.EarthDomeConfig;

View file

@ -28,8 +28,8 @@ import com.projectkorra.projectkorra.Element;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.ability.api.ElementalAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.avatar.AvatarState;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.EarthGrabConfig;

View file

@ -16,8 +16,8 @@ import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.ability.api.ElementalAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.EarthSmashConfig;

View file

@ -10,8 +10,8 @@ import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.ability.api.ElementalAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.EarthTunnelConfig;
import com.projectkorra.projectkorra.util.TempBlock;

View file

@ -9,7 +9,7 @@ import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.RaiseEarthConfig;
import com.projectkorra.projectkorra.util.BlockSource;

View file

@ -7,7 +7,7 @@ import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.RaiseEarthConfig;
import com.projectkorra.projectkorra.util.BlockSource;

View file

@ -14,8 +14,8 @@ import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.api.AirAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.avatar.AvatarState;
import com.projectkorra.projectkorra.command.Commands;

View file

@ -4,7 +4,7 @@ import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.ShockwaveConfig;
import com.projectkorra.projectkorra.util.ParticleEffect;

View file

@ -13,8 +13,8 @@ import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.ability.api.ElementalAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.TremorsenseConfig;

View file

@ -9,7 +9,7 @@ import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.EarthDomeConfig;
import com.projectkorra.projectkorra.earthbending.EarthDome;

View file

@ -5,8 +5,8 @@ import java.util.ArrayList;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.ability.ComboAbility;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.api.ComboAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.EarthDomeConfig;

View file

@ -13,8 +13,8 @@ import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.ComboAbility;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.api.ComboAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.ConfigManager;

View file

@ -17,8 +17,8 @@ import org.bukkit.scheduler.BukkitRunnable;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ProjectKorra;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.LavaAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.ability.api.LavaAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.LavaFlowConfig;
import com.projectkorra.projectkorra.util.BlockSource;

View file

@ -10,7 +10,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.MetalAbility;
import com.projectkorra.projectkorra.ability.api.MetalAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.ExtractionConfig;
import com.projectkorra.projectkorra.util.TempBlock;

View file

@ -21,7 +21,7 @@ import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.MetalAbility;
import com.projectkorra.projectkorra.ability.api.MetalAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.MetalClipsConfig;
import com.projectkorra.projectkorra.util.DamageHandler;

View file

@ -11,9 +11,9 @@ import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.PassiveAbility;
import com.projectkorra.projectkorra.ability.api.EarthAbility;
import com.projectkorra.projectkorra.ability.api.ElementalAbility;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
import com.projectkorra.projectkorra.command.Commands;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.DensityShiftConfig;

View file

@ -11,8 +11,8 @@ import org.bukkit.block.data.type.TrapDoor;
import org.bukkit.entity.Player;
import com.projectkorra.projectkorra.GeneralMethods;
import com.projectkorra.projectkorra.ability.MetalAbility;
import com.projectkorra.projectkorra.ability.PassiveAbility;
import com.projectkorra.projectkorra.ability.api.MetalAbility;
import com.projectkorra.projectkorra.ability.api.PassiveAbility;
import com.projectkorra.projectkorra.configuration.configs.abilities.earth.FerroControlConfig;
public class FerroControl extends MetalAbility<FerroControlConfig> implements PassiveAbility {

View file

@ -4,7 +4,7 @@ import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.projectkorra.ability.FireAbility;
import com.projectkorra.projectkorra.ability.api.FireAbility;
import com.projectkorra.projectkorra.attribute.Attribute;
import com.projectkorra.projectkorra.avatar.AvatarState;
import com.projectkorra.projectkorra.configuration.configs.abilities.fire.BlazeConfig;

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