// Path: src/main/java/org/cyclops/everlastingabilities/ability/AbilityTypePowerStare.java
// public class AbilityTypePowerStare extends AbilityTypeDefault {
// 
//     private static final int TICK_MODULUS = MinecraftHelpers.SECOND_IN_TICKS / 4;
// 
//     public AbilityTypePowerStare(String id, Supplier<Integer> rarity, Supplier<Integer> maxLevel,
//                                  Supplier<Integer> baseXpPerLevel, Supplier<Boolean> obtainableOnPlayerSpawn, Supplier<Boolean> obtainableOnMobSpawn,
//                                  Supplier<Boolean> obtainableOnCraft, Supplier<Boolean> obtainableOnLoot) {
//         super(id, rarity, maxLevel, baseXpPerLevel, obtainableOnPlayerSpawn, obtainableOnMobSpawn, obtainableOnCraft, obtainableOnLoot);
//     }
// 
//     @Override
//     public void onTick(PlayerEntity player, int level) {
//     
//         if ( AbilityPowerStareConfig.requireSneak && !player.isCrouching() ) {
//             return;
//         }
// 
//         World world = player.world;
//         if (!world.isRemote && player.world.getGameTime() % TICK_MODULUS == 0) {
//             int range = level * 10;
//             double eyeHeight = player.getEyeHeight();
//             Vector3d lookVec = player.getLookVec();
//             Vector3d origin = new Vector3d(player.getPosX(), player.getPosY() + eyeHeight, player.getPosZ());
//             Vector3d direction = origin.add(lookVec.x * range, lookVec.y * range, lookVec.z * range);
// 
//             List<Entity> list = world.getEntitiesWithinAABBExcludingEntity(player,
//                     player.getBoundingBox().expand(lookVec.x * range, lookVec.y * range, lookVec.z * range)
//                             .grow((double) range));
//             for (Entity e : list) {
//                 // TODO TameableEntity was IEntityOwnable
//                 if (e.canBeCollidedWith() && (!(e instanceof TameableEntity) || ((TameableEntity) e).getOwner() != player) && !player.isOnSameTeam(e)) {
//                     Entity entity = null;
//                     float f10 = e.getCollisionBorderSize();
//                     AxisAlignedBB axisalignedbb = e.getBoundingBox().expand((double) f10, (double) f10, (double) f10);
//                     Vector3d hitVec = axisalignedbb.rayTrace(origin, direction).orElse(null);
// 
//                     if (axisalignedbb.contains(origin)) {
//                         entity = e;
//                     } else if (hitVec != null) {
//                         double distance = origin.distanceTo(hitVec);
//                         if (distance < range || range == 0.0D) {
//                             if (e == player.getRidingEntity() && !player.canRiderInteract()) {
//                                 if (range == 0.0D) {
//                                     entity = e;
//                                 }
//                             } else {
//                                 entity = e;
//                             }
//                         }
//                     }
// 
//                     if (entity != null) {
//                         double dx = entity.getPosX() - player.getPosX();
//                         double dy = entity.getPosY() - player.getPosY();
//                         double dz = entity.getPosZ() - player.getPosZ();
//                         double d = MathHelper.sqrt(dx * dx + dy * dy + dz * dz);
//                         double m = 1 / (2 * (Math.max(1, d)));
//                         dx *= m;
//                         dy *= m;
//                         dz *= m;
// 
//                         double strength = 3F;
// 
//                         entity.setMotion(dx * strength, dy * strength, dz * strength);
//                         break;
//                     }
//                 }
//             }
//         }
//     }
// }
// 
// Path: src/main/java/org/cyclops/everlastingabilities/core/config/extendedconfig/AbilityConfig.java
// public abstract class AbilityConfig<T> extends ExtendedConfigForge<AbilityConfig<T>, IAbilityType> {
// 
//     public AbilityConfig(String namedId, Function<AbilityConfig<T>, ? extends IAbilityType> elementConstructor) {
//         super(EverlastingAbilities._instance, namedId, elementConstructor);
//     }
//     
//     @Override
// 	public String getTranslationKey() {
// 		return "ability." + getNamedId();
// 	}
// 
//     @Override
//     public String getFullTranslationKey() {
//         return "ability.abilities." + getMod().getModId()  + "." +getNamedId() + ".name";
//     }
// 
//     @Override
//     public ConfigurableType getConfigurableType() {
//         return ExtendedConfigurableType.ABILITY;
//     }
// 
//     @Override
//     public IForgeRegistry<? super IAbilityType> getRegistry() {
//         return AbilityTypes.REGISTRY;
//     }
// }


import net.minecraft.item.Rarity;
import net.minecraftforge.fml.config.ModConfig;
import org.cyclops.cyclopscore.config.ConfigurableProperty;
import org.cyclops.everlastingabilities.ability.AbilityTypePowerStare;
import org.cyclops.everlastingabilities.core.config.extendedconfig.AbilityConfig;
package org.cyclops.everlastingabilities.ability.config;


/**
 * Config for an ability.
 * @author rubensworks
 *
 */
public class AbilityPowerStareConfig extends AbilityConfig<AbilityTypePowerStare> {

    @ConfigurableProperty(category = "ability", comment = "Rarity of this ability.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
    public static int rarity = Rarity.UNCOMMON.ordinal();

    @ConfigurableProperty(category = "ability", comment = "The maximum ability level.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
    public static int maxLevel = 5;

    @ConfigurableProperty(category = "ability", comment = "The xp required per level.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
    public static int xpPerLevel = 50;

    @ConfigurableProperty(category = "ability", comment = "Require sneak to activate.", configLocation = ModConfig.Type.SERVER)
    public static boolean requireSneak = true;

    @ConfigurableProperty(category = "ability", comment = "If this can be obtained by initially spawning players.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
    public static boolean obtainableOnPlayerSpawn = true;

    @ConfigurableProperty(category = "ability", comment = "If this can be obtained by spawning mobs.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
    public static boolean obtainableOnMobSpawn = true;

    @ConfigurableProperty(category = "ability", comment = "If this can be obtained by combining totems in a crafting grid.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
    public static boolean obtainableOnCraft = true;

    @ConfigurableProperty(category = "ability", comment = "If this can be obtained in loot chests.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
    public static boolean obtainableOnLoot = true;

    public AbilityPowerStareConfig() {
        super("power_stare",
// Path: src/main/java/org/cyclops/everlastingabilities/ability/AbilityTypePowerStare.java
// public class AbilityTypePowerStare extends AbilityTypeDefault {
// 
//     private static final int TICK_MODULUS = MinecraftHelpers.SECOND_IN_TICKS / 4;
// 
//     public AbilityTypePowerStare(String id, Supplier<Integer> rarity, Supplier<Integer> maxLevel,
//                                  Supplier<Integer> baseXpPerLevel, Supplier<Boolean> obtainableOnPlayerSpawn, Supplier<Boolean> obtainableOnMobSpawn,
//                                  Supplier<Boolean> obtainableOnCraft, Supplier<Boolean> obtainableOnLoot) {
//         super(id, rarity, maxLevel, baseXpPerLevel, obtainableOnPlayerSpawn, obtainableOnMobSpawn, obtainableOnCraft, obtainableOnLoot);
//     }
// 
//     @Override
//     public void onTick(PlayerEntity player, int level) {
//     
//         if ( AbilityPowerStareConfig.requireSneak && !player.isCrouching() ) {
//             return;
//         }
// 
//         World world = player.world;
//         if (!world.isRemote && player.world.getGameTime() % TICK_MODULUS == 0) {
//             int range = level * 10;
//             double eyeHeight = player.getEyeHeight();
//             Vector3d lookVec = player.getLookVec();
//             Vector3d origin = new Vector3d(player.getPosX(), player.getPosY() + eyeHeight, player.getPosZ());
//             Vector3d direction = origin.add(lookVec.x * range, lookVec.y * range, lookVec.z * range);
// 
//             List<Entity> list = world.getEntitiesWithinAABBExcludingEntity(player,
//                     player.getBoundingBox().expand(lookVec.x * range, lookVec.y * range, lookVec.z * range)
//                             .grow((double) range));
//             for (Entity e : list) {
//                 // TODO TameableEntity was IEntityOwnable
//                 if (e.canBeCollidedWith() && (!(e instanceof TameableEntity) || ((TameableEntity) e).getOwner() != player) && !player.isOnSameTeam(e)) {
//                     Entity entity = null;
//                     float f10 = e.getCollisionBorderSize();
//                     AxisAlignedBB axisalignedbb = e.getBoundingBox().expand((double) f10, (double) f10, (double) f10);
//                     Vector3d hitVec = axisalignedbb.rayTrace(origin, direction).orElse(null);
// 
//                     if (axisalignedbb.contains(origin)) {
//                         entity = e;
//                     } else if (hitVec != null) {
//                         double distance = origin.distanceTo(hitVec);
//                         if (distance < range || range == 0.0D) {
//                             if (e == player.getRidingEntity() && !player.canRiderInteract()) {
//                                 if (range == 0.0D) {
//                                     entity = e;
//                                 }
//                             } else {
//                                 entity = e;
//                             }
//                         }
//                     }
// 
//                     if (entity != null) {
//                         double dx = entity.getPosX() - player.getPosX();
//                         double dy = entity.getPosY() - player.getPosY();
//                         double dz = entity.getPosZ() - player.getPosZ();
//                         double d = MathHelper.sqrt(dx * dx + dy * dy + dz * dz);
//                         double m = 1 / (2 * (Math.max(1, d)));
//                         dx *= m;
//                         dy *= m;
//                         dz *= m;
// 
//                         double strength = 3F;
// 
//                         entity.setMotion(dx * strength, dy * strength, dz * strength);
//                         break;
//                     }
//                 }
//             }
//         }
//     }
// }
// 
// Path: src/main/java/org/cyclops/everlastingabilities/core/config/extendedconfig/AbilityConfig.java
// public abstract class AbilityConfig<T> extends ExtendedConfigForge<AbilityConfig<T>, IAbilityType> {
// 
//     public AbilityConfig(String namedId, Function<AbilityConfig<T>, ? extends IAbilityType> elementConstructor) {
//         super(EverlastingAbilities._instance, namedId, elementConstructor);
//     }
//     
//     @Override
// 	public String getTranslationKey() {
// 		return "ability." + getNamedId();
// 	}
// 
//     @Override
//     public String getFullTranslationKey() {
//         return "ability.abilities." + getMod().getModId()  + "." +getNamedId() + ".name";
//     }
// 
//     @Override
//     public ConfigurableType getConfigurableType() {
//         return ExtendedConfigurableType.ABILITY;
//     }
// 
//     @Override
//     public IForgeRegistry<? super IAbilityType> getRegistry() {
//         return AbilityTypes.REGISTRY;
//     }
// }


// Path: src/main/java/org/cyclops/everlastingabilities/ability/config/AbilityPowerStareConfig.java
import net.minecraft.item.Rarity;
import net.minecraftforge.fml.config.ModConfig;
import org.cyclops.cyclopscore.config.ConfigurableProperty;
import org.cyclops.everlastingabilities.ability.AbilityTypePowerStare;
import org.cyclops.everlastingabilities.core.config.extendedconfig.AbilityConfig;

package org.cyclops.everlastingabilities.ability.config;


/**
 * Config for an ability.
 * @author rubensworks
 *
 */
public class AbilityPowerStareConfig extends AbilityConfig<AbilityTypePowerStare> {

    @ConfigurableProperty(category = "ability", comment = "Rarity of this ability.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
    public static int rarity = Rarity.UNCOMMON.ordinal();

    @ConfigurableProperty(category = "ability", comment = "The maximum ability level.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
    public static int maxLevel = 5;

    @ConfigurableProperty(category = "ability", comment = "The xp required per level.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
    public static int xpPerLevel = 50;

    @ConfigurableProperty(category = "ability", comment = "Require sneak to activate.", configLocation = ModConfig.Type.SERVER)
    public static boolean requireSneak = true;

    @ConfigurableProperty(category = "ability", comment = "If this can be obtained by initially spawning players.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
    public static boolean obtainableOnPlayerSpawn = true;

    @ConfigurableProperty(category = "ability", comment = "If this can be obtained by spawning mobs.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
    public static boolean obtainableOnMobSpawn = true;

    @ConfigurableProperty(category = "ability", comment = "If this can be obtained by combining totems in a crafting grid.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
    public static boolean obtainableOnCraft = true;

    @ConfigurableProperty(category = "ability", comment = "If this can be obtained in loot chests.", isCommandable = true, configLocation = ModConfig.Type.SERVER)
    public static boolean obtainableOnLoot = true;

    public AbilityPowerStareConfig() {
        super("power_stare",
                eConfig -> new AbilityTypePowerStare(eConfig.getNamedId(), () -> rarity, () -> maxLevel, () -> xpPerLevel,