Added a bunch more effects, and started testing them.

This commit is contained in:
GB6 2019-01-24 12:00:57 +01:00
parent e6f680d281
commit 9a1e9645ed
45 changed files with 1241 additions and 550 deletions

View File

@ -94,13 +94,6 @@
<scope>compile</scope>
</dependency>
<dependency>
<groupId>fr.minuskube.inv</groupId>
<artifactId>smart-invs</artifactId>
<version>1.2.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.milkbowl.vault</groupId>
<artifactId>VaultAPI</artifactId>

View File

@ -1,4 +0,0 @@
package com.songoda.epicenchants;
public class Effect {
}

View File

@ -8,12 +8,11 @@ import com.songoda.epicenchants.listeners.BookListener;
import com.songoda.epicenchants.listeners.PlayerListener;
import com.songoda.epicenchants.managers.EnchantManager;
import com.songoda.epicenchants.managers.FileManager;
import com.songoda.epicenchants.menus.BookMenu;
import com.songoda.epicenchants.objects.Enchant;
import com.songoda.epicenchants.utils.EnchantUtils;
import com.songoda.epicenchants.utils.FastInv;
import com.songoda.epicenchants.utils.VersionDependent;
import com.songoda.epicenchants.utils.parser.InventoryParser;
import fr.minuskube.inv.InventoryManager;
import fr.minuskube.inv.SmartInventory;
import lombok.Getter;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit;
@ -26,16 +25,16 @@ import java.util.stream.Collectors;
import static com.songoda.epicenchants.utils.Chat.color;
import static org.bukkit.Bukkit.getConsoleSender;
@Getter
public class EpicEnchants extends JavaPlugin {
@Getter private FileManager fileManager;
@Getter private EnchantManager enchantManager;
@Getter private BukkitCommandManager commandManager;
@Getter private InventoryManager inventoryManager;
@Getter private Economy economy;
@Getter private Locale locale;
@Getter private SmartInventory bookInventory;
@Getter private EnchantUtils enchantUtils;
private FastInv bookInventory;
private BukkitCommandManager commandManager;
private Economy economy;
private EnchantManager enchantManager;
private EnchantUtils enchantUtils;
private FileManager fileManager;
private Locale locale;
@Override
public void onEnable() {
@ -43,28 +42,27 @@ public class EpicEnchants extends JavaPlugin {
getConsoleSender().sendMessage(color("&7" + getDescription().getName() + " " + getDescription().getVersion() + " by &5Songoda <3&7!"));
getConsoleSender().sendMessage(color("&7Action: &aEnabling&7..."));
Locale.init(this);
FastInv.init(this);
this.locale = Locale.getLocale(getConfig().getString("language"));
this.fileManager = new FileManager(this);
this.enchantManager = new EnchantManager();
this.inventoryManager = new InventoryManager(this);
this.economy = getServer().getServicesManager().getRegistration(Economy.class).getProvider();
this.enchantUtils = new EnchantUtils(this);
Locale.init(this);
this.locale = Locale.getLocale(getConfig().getString("language"));
fileManager.createFiles();
fileManager.loadEnchants();
inventoryManager.init();
setupCommands();
setupListeners();
setupVersion();
if (!enchantManager.getEnchants().isEmpty()) {
getLogger().info("Successfully loaded: " + enchantManager.getEnchants().stream().map(Enchant::getIdentifier).collect(Collectors.joining(",")));
getLogger().info("Successfully loaded enchants: " + enchantManager.getEnchants().stream().map(Enchant::getIdentifier).collect(Collectors.joining(",")));
}
this.bookInventory = InventoryParser.parseBookMenu(this, fileManager.getConfiguration("bookMenu"));
this.bookInventory = new BookMenu(this, fileManager.getConfiguration("bookMenu"));
getConsoleSender().sendMessage(color("&a============================="));
}
@ -99,7 +97,7 @@ public class EpicEnchants extends JavaPlugin {
private void setupVersion() {
int currentVersion = Integer.parseInt(getServer().getClass().getPackage().getName().split("\\.")[3].split("_")[1]);
if(currentVersion >= 13) {
if (currentVersion >= 13) {
VersionDependent.initDefault(currentVersion);
} else {
VersionDependent.initLegacy(currentVersion);

View File

@ -3,8 +3,12 @@ package com.songoda.epicenchants.commands;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.*;
import com.songoda.epicenchants.EpicEnchants;
import com.songoda.epicenchants.enums.EnchantResult;
import com.songoda.epicenchants.objects.Enchant;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@CommandAlias("epicenchants|ee")
public class EnchantCommand extends BaseCommand {
@ -12,19 +16,106 @@ public class EnchantCommand extends BaseCommand {
@Dependency("instance")
private EpicEnchants instance;
//ee give {player} {enchant} {tier}
@Subcommand("give")
@CommandCompletion("@players @enchants @nothing @nothing @nothing")
@Description("Give books to players")
@CommandPermission("epicenchants.givebook")
public void onGiveBook(@Flags("other") Player target, Enchant enchant, @Optional Integer level, @Optional Integer successRate, @Optional Integer destroyRate) {
target.getInventory().addItem(enchant.getBookItem().get(enchant, level, successRate, destroyRate));
}
@Default
@Subcommand("gui")
@Description("Opens the GUI for getting enchants")
public void onGui(Player player) {
instance.getBookInventory().open(player);
}
//ee give {player} {enchant} {tier}
@Subcommand("give")
@CommandCompletion("@players @enchants @nothing @nothing @nothing")
@Description("Give enchant books to players")
@CommandPermission("epicenchants.give")
public void onGiveBook(CommandSender sender, @Flags("other") Player target, Enchant enchant, @Optional Integer level, @Optional Integer successRate, @Optional Integer destroyRate) {
target.getInventory().addItem(enchant.getBookItem().get(enchant, level, successRate, destroyRate));
target.sendMessage(instance.getLocale().getMessageWithPrefix("command.given", enchant.getIdentifier()));
sender.sendMessage(instance.getLocale().getMessageWithPrefix("command.gave", target.getName(), enchant.getIdentifier()));
}
//ee apply {enchant} {tier}
@Subcommand("apply")
@CommandCompletion("@enchants @nothing")
@Description("Apply enchant to item in hand")
@CommandPermission("epicenchants.apply")
public void onApply(Player player, Enchant enchant, int level, @Optional Integer successRate, @Optional Integer destroyRate) {
int slot = player.getInventory().getHeldItemSlot();
ItemStack before = player.getItemInHand();
Pair<ItemStack, EnchantResult> result = instance.getEnchantUtils().apply(before, enchant, level,
successRate == null ? 100 : successRate, destroyRate == null ? 0 : destroyRate);
String messageKey = "";
switch (result.getRight()) {
case FAILURE:
messageKey = "enchant.failure";
break;
case BROKEN_FAILURE:
player.getInventory().clear(slot);
messageKey = "enchant.brokenfailure";
break;
case SUCCESS:
messageKey = "enchant.success";
break;
case CONFLICT:
messageKey = "enchant.conflict";
}
player.sendMessage(instance.getLocale().getMessageWithPrefix(messageKey, enchant.getIdentifier()));
player.getInventory().setItem(slot, result.getLeft());
}
}
/*ABSORPTION
BLINDNESS
CONFUSION
DAMAGE_RESISTANCE
FAST_DIGGING
FIRE_RESISTANCE
HARM
HEAL
HEALTH_BOOST
HUNGER
INCREASE_DAMAGE
INVISIBILITY
JUMP
NIGHT_VISION
POISON
REGENERATION
SATURATION
SLOW
SLOW_DIGGING
SPEED
WATER_BREATHING
WEAKNESS
WITHER*/
/*
ABSORPTION
BLINDNESS
CONFUSION
DAMAGE_RESISTANCE
FAST_DIGGING
FIRE_RESISTANCE
GLOWING
HARM
HEAL
HEALTH_BOOST
HUNGER
INCREASE_DAMAGE
INVISIBILITY
JUMP
LEVITATION
LUCK
NIGHT_VISION
POISON
REGENERATION
SATURATION
SLOW
SLOW_DIGGING
SPEED
UNLUCK
WATER_BREATHING
WEAKNESS
WITHER
*/

View File

@ -0,0 +1,19 @@
package com.songoda.epicenchants.effect;
import com.songoda.epicenchants.enums.EventType;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
public abstract class EffectEventExecutor extends EffectExecutor {
public EffectEventExecutor(ConfigurationSection section) {
super(section);
}
public abstract void execute(Player wearer, Player opponent, int level, Event event, EventType eventType);
@Override
public void execute(Player wearer, Player opponent, int level, EventType eventType) {
throw new UnsupportedOperationException("This method can not be called on EventEffects");
}
}

View File

@ -1,44 +1,76 @@
package com.songoda.epicenchants.effect;
import com.songoda.epicenchants.enums.EnchantType;
import com.songoda.epicenchants.enums.EventType;
import com.songoda.epicenchants.objects.LeveledModifier;
import com.songoda.epicenchants.utils.GeneralUtils;
import lombok.Getter;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import java.util.Optional;
import java.util.function.Consumer;
import static com.songoda.epicenchants.effect.EffectExecutor.Who.OPPONENT;
import static com.songoda.epicenchants.effect.EffectExecutor.Who.WEARER;
public abstract class EffectExecutor {
@Getter private final ConfigurationSection section;
@Getter private final EnchantType enchantType;
public EffectExecutor(ConfigurationSection section) {
this.section = section;
this.enchantType = EnchantType.valueOf(section.getString("type"));
}
public void testAndRun(Player wearer, Player opponent, int level) {
if (!section.isString("chance")) {
execute(wearer, opponent, level);
public void testAndRun(Player wearer, Player opponent, int level, EnchantType type, Event event, EventType eventType) {
if (type != enchantType) {
return;
}
if (GeneralUtils.chance(LeveledModifier.of(section.getString("chance")).get(level))) {
execute(wearer, opponent, level);
if (section.isString("chance") && !GeneralUtils.chance(LeveledModifier.of(section.getString("chance")).get(level, 100))) {
return;
}
if (this instanceof EffectEventExecutor) {
((EffectEventExecutor) this).execute(wearer, opponent, level, event, eventType);
return;
}
execute(wearer, opponent, level, eventType);
}
public abstract void execute(Player wearer, Player opponent, int level, EventType eventType);
public Who who() {
if (section.isString("who")) {
if (section.getString("who").equalsIgnoreCase("wearer")) return WEARER;
else if (section.getString("who").equalsIgnoreCase("opponent")) return OPPONENT;
}
return WEARER;
}
public LeveledModifier getAmount() {
return LeveledModifier.of(section.getString("amount"));
}
public void consume(Consumer<Player> playerConsumer, Player wearer, Player opponent) {
if (enchantType == EnchantType.HELD_ITEM || enchantType == EnchantType.STATIC_EFFECT) {
playerConsumer.accept(wearer);
return;
}
switch (who()) {
case WEARER:
playerConsumer.accept(wearer);
break;
case OPPONENT:
if (opponent != null)
playerConsumer.accept(opponent);
}
}
public abstract void execute(Player wearer, Player opponent, int level);
public Optional<Who> who() {
return Optional.ofNullable(section.getString("who").equalsIgnoreCase("player") ?
Who.PLAYER : section.getString("who").equalsIgnoreCase("opponent") ?
Who.OPPONENT : null);
}
public enum Who {
PLAYER, OPPONENT
}
public Optional<Integer> getAmount() {
return section.isInt("amount") ? Optional.of(section.getInt("amount")) : Optional.empty();
WEARER, OPPONENT
}
}

View File

@ -11,9 +11,14 @@ import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
public class EffectManager {
public Optional<EffectExecutor> getEffect(ConfigurationSection section) {
public static Optional<EffectExecutor> getEffect(ConfigurationSection section) {
if (section == null) {
return Optional.empty();
}
try {
Class<?> clazz = Class.forName(UPPER_UNDERSCORE.to(UPPER_CAMEL, section.getName().toLowerCase()));
String formatted = UPPER_UNDERSCORE.to(UPPER_CAMEL, section.getName().toLowerCase()).replaceAll("-.*$", "");
Class<?> clazz = Class.forName("com.songoda.epicenchants.effect.effects." + formatted);
Constructor<?> constructor = clazz.getConstructor(ConfigurationSection.class);
Object object = constructor.newInstance(section);
return Optional.of((EffectExecutor) object);

View File

@ -0,0 +1,23 @@
package com.songoda.epicenchants.effect.effects;
import com.songoda.epicenchants.effect.EffectEventExecutor;
import com.songoda.epicenchants.enums.EventType;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public class CancelEvent extends EffectEventExecutor {
public CancelEvent(ConfigurationSection section) {
super(section);
}
@Override
public void execute(Player player, Player opponent, int level, Event event, EventType eventType) {
if (!(event instanceof Cancellable)) {
return;
}
((Cancellable) event).setCancelled(true);
}
}

View File

@ -1,6 +1,7 @@
package com.songoda.epicenchants.effect.effects;
import com.songoda.epicenchants.effect.EffectExecutor;
import com.songoda.epicenchants.enums.EventType;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
@ -11,7 +12,7 @@ public class ConsoleCommand extends EffectExecutor {
}
@Override
public void execute(Player wearer, Player opponent, int level) {
public void execute(Player wearer, Player opponent, int level, EventType eventType) {
Bukkit.getConsoleSender().sendMessage(getSection().getString("command")
.replace("{level}", "" + level)
.replace("{wearer}", wearer.getName()

View File

@ -1,6 +1,9 @@
package com.songoda.epicenchants.effect.effects;
import com.songoda.epicenchants.effect.EffectExecutor;
import com.songoda.epicenchants.enums.EventType;
import com.songoda.epicenchants.utils.ItemBuilder;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
@ -10,7 +13,8 @@ public class DropHead extends EffectExecutor {
}
@Override
public void execute(Player wearer, Player opponent, int level) {
public void execute(Player wearer, Player opponent, int level, EventType eventType) {
consume(player -> player.getWorld().dropItemNaturally(player.getLocation(),
new ItemBuilder(Material.LEGACY_SKULL_ITEM).skullOwner(player.getName()).build()), wearer, opponent);
}
}

View File

@ -0,0 +1,17 @@
package com.songoda.epicenchants.effect.effects;
import com.songoda.epicenchants.effect.EffectExecutor;
import com.songoda.epicenchants.enums.EventType;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
public class Extinguish extends EffectExecutor {
public Extinguish(ConfigurationSection section) {
super(section);
}
@Override
public void execute(Player wearer, Player opponent, int level, EventType eventType) {
consume(player -> player.setFireTicks(0), wearer, opponent);
}
}

View File

@ -1,10 +1,12 @@
package com.songoda.epicenchants.effect.effects;
import com.songoda.epicenchants.effect.EffectExecutor;
import com.songoda.epicenchants.enums.EnchantType;
import com.songoda.epicenchants.enums.EventType;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import static com.songoda.epicenchants.effect.EffectExecutor.Who.PLAYER;
import static com.songoda.epicenchants.enums.EventType.ON;
public class Fly extends EffectExecutor {
public Fly(ConfigurationSection section) {
@ -12,10 +14,13 @@ public class Fly extends EffectExecutor {
}
@Override
public void execute(Player wearer, Player opponent, int level) {
who().ifPresent(who -> {
if (who == PLAYER) wearer.setFlying(!wearer.isFlying());
else opponent.setFlying(!opponent.isFlying());
});
public void execute(Player wearer, Player opponent, int level, EventType eventType) {
if (getEnchantType() != EnchantType.STATIC_EFFECT && getEnchantType() != EnchantType.HELD_ITEM) {
throw new IllegalStateException("Fly effect is not a STATIC_EFFECT or HELD_ITEM");
}
wearer.setAllowFlight(eventType == ON);
wearer.setFlying(eventType == ON);
}
}

View File

@ -1,21 +1,17 @@
package com.songoda.epicenchants.effect.effects;
import com.songoda.epicenchants.effect.EffectExecutor;
import com.songoda.epicenchants.enums.EventType;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import static com.songoda.epicenchants.effect.EffectExecutor.Who.PLAYER;
public class Lightning extends EffectExecutor {
public Lightning(ConfigurationSection section) {
super(section);
}
@Override
public void execute(Player wearer, Player opponent, int level) {
who().ifPresent(who -> {
if (who == PLAYER) wearer.getWorld().strikeLightning(wearer.getLocation());
else opponent.getWorld().strikeLightning(opponent.getLocation());
});
public void execute(Player wearer, Player opponent, int level, EventType eventType) {
consume(player -> player.getWorld().strikeLightning(player.getLocation()), wearer, opponent);
}
}

View File

@ -1,10 +1,11 @@
package com.songoda.epicenchants.effect.effects;
import com.songoda.epicenchants.effect.EffectExecutor;
import com.songoda.epicenchants.enums.EventType;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import static com.songoda.epicenchants.effect.EffectExecutor.Who.PLAYER;
import static com.songoda.epicenchants.utils.Chat.color;
public class Message extends EffectExecutor {
public Message(ConfigurationSection section) {
@ -12,12 +13,11 @@ public class Message extends EffectExecutor {
}
@Override
public void execute(Player wearer, Player opponent, int level) {
String message = getSection().getString("message").replace("{level}", "" + level);
who().ifPresent(who -> {
if (who == PLAYER) wearer.sendMessage(message);
else opponent.sendMessage(message);
});
public void execute(Player wearer, Player opponent, int level, EventType eventType) {
if (eventType == EventType.ON || eventType == EventType.NONE)
consume(player -> player.sendMessage(color(getSection().getString("message"))
.replace("{level}", "" + level)
.replace("{wearer}", wearer.getName())
.replace("{opponent}", opponent.getName())), wearer, opponent);
}
}

View File

@ -0,0 +1,24 @@
package com.songoda.epicenchants.effect.effects;
import com.songoda.epicenchants.effect.EffectEventExecutor;
import com.songoda.epicenchants.enums.EventType;
import com.songoda.epicenchants.objects.LeveledModifier;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.entity.EntityDamageEvent;
public class ModifyDamage extends EffectEventExecutor {
public ModifyDamage(ConfigurationSection section) {
super(section);
}
@Override
public void execute(Player wearer, Player opponent, int level, Event event, EventType eventType) {
if (!(event instanceof EntityDamageEvent)) {
return;
}
((EntityDamageEvent) event).setDamage(LeveledModifier.of(getSection().getString("modifier")).get(level, 1));
}
}

View File

@ -0,0 +1,35 @@
package com.songoda.epicenchants.effect.effects;
import com.songoda.epicenchants.effect.EffectEventExecutor;
import com.songoda.epicenchants.enums.EventType;
import com.songoda.epicenchants.objects.LeveledModifier;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.stream.Collectors;
public class MoreDrops extends EffectEventExecutor {
public MoreDrops(ConfigurationSection section) {
super(section);
}
@Override
public void execute(Player player, Player opponent, int level, Event event, EventType type) {
if (!(event instanceof EntityDeathEvent)) {
return;
}
EntityDeathEvent deathEvent = (EntityDeathEvent) event;
LeveledModifier modifier = getAmount();
List<ItemStack> newDrops = deathEvent.getDrops().stream()
.peek(itemStack -> itemStack.setAmount(((int) (itemStack.getAmount() * modifier.get(level, 1)))))
.collect(Collectors.toList());
deathEvent.getDrops().clear();
deathEvent.getDrops().addAll(newDrops);
}
}

View File

@ -1,10 +1,12 @@
package com.songoda.epicenchants.effect.effects;
import com.songoda.epicenchants.effect.EffectExecutor;
import com.songoda.epicenchants.enums.EventType;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import static com.songoda.epicenchants.effect.EffectExecutor.Who.PLAYER;
import static com.songoda.epicenchants.enums.EventType.NONE;
import static com.songoda.epicenchants.enums.EventType.ON;
public class PlayerCommand extends EffectExecutor {
public PlayerCommand(ConfigurationSection section) {
@ -12,12 +14,12 @@ public class PlayerCommand extends EffectExecutor {
}
@Override
public void execute(Player wearer, Player opponent, int level) {
String command = getSection().getString("command").replace("{level}", "" + level);
public void execute(Player wearer, Player opponent, int level, EventType eventType) {
if (eventType == ON || eventType == NONE)
consume(player -> player.performCommand(getSection().getString("command")
.replace("{level}", "" + level)
.replace("{wearer}", wearer.getName())
.replace("{opponent}", opponent.getName())), wearer, opponent);
who().ifPresent(who -> {
if (who == PLAYER) wearer.performCommand(command);
else opponent.performCommand(command);
});
}
}

View File

@ -0,0 +1,50 @@
package com.songoda.epicenchants.effect.effects;
import com.songoda.epicenchants.effect.EffectExecutor;
import com.songoda.epicenchants.enums.EnchantType;
import com.songoda.epicenchants.enums.EventType;
import com.songoda.epicenchants.objects.LeveledModifier;
import com.songoda.epicenchants.utils.GeneralUtils;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
public class Potion extends EffectExecutor {
public Potion(ConfigurationSection section) {
super(section);
}
@Override
public void execute(Player wearer, Player opponent, int level, EventType eventType) {
if (!getSection().isString("potion-type")) {
return;
}
LeveledModifier amplifier = LeveledModifier.of(getSection().getString("amplifier"));
PotionEffectType effectType = PotionEffectType.getByName(getSection().getString("potion-type"));
if (effectType == null) {
return;
}
if (getEnchantType() == EnchantType.STATIC_EFFECT || getEnchantType() == EnchantType.HELD_ITEM) {
if (eventType == EventType.ON) {
consume(player -> player.addPotionEffect(new PotionEffect(effectType, Integer.MAX_VALUE, ((int) amplifier.get(level, 0)))), wearer, opponent);
} else if (eventType == EventType.OFF) {
consume(player -> player.removePotionEffect(effectType), wearer, opponent);
}
return;
}
LeveledModifier duration = LeveledModifier.of(getSection().getString("duration"));
LeveledModifier chance = LeveledModifier.of(getSection().getString("chance"));
if (!GeneralUtils.chance(chance.get(level, 100))) {
return;
}
consume(player -> player.addPotionEffect(new PotionEffect(effectType, ((int) duration.get(level, Integer.MAX_VALUE)), ((int) amplifier.get(level, 0)))), wearer, opponent);
}
}

View File

@ -1,21 +1,17 @@
package com.songoda.epicenchants.effect.effects;
import com.songoda.epicenchants.effect.EffectExecutor;
import com.songoda.epicenchants.enums.EventType;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import static com.songoda.epicenchants.effect.EffectExecutor.Who.PLAYER;
public class Repair extends EffectExecutor {
public Repair(ConfigurationSection section) {
super(section);
}
@Override
public void execute(Player wearer, Player opponent, int level) {
who().ifPresent(who -> {
if (who == PLAYER) wearer.getItemInHand().setDurability((short) 0);
else opponent.getItemInHand().setDurability((short) 0);
});
public void execute(Player wearer, Player opponent, int level, EventType eventType) {
consume(player -> player.getItemInHand().setDurability((short) 0), wearer, opponent);
}
}

View File

@ -1,6 +1,7 @@
package com.songoda.epicenchants.effect.effects;
import com.songoda.epicenchants.effect.EffectExecutor;
import com.songoda.epicenchants.enums.EventType;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
@ -10,10 +11,9 @@ public class StealHealth extends EffectExecutor {
}
@Override
public void execute(Player wearer, Player opponent, int level) {
getAmount().ifPresent(amount -> {
wearer.setHealth(wearer.getHealth() + amount);
opponent.setHealth(opponent.getHealth() - amount);
});
public void execute(Player wearer, Player opponent, int level, EventType eventType) {
double amount = getAmount().get(level, 0);
wearer.setHealth(wearer.getHealth() + amount);
opponent.setHealth(opponent.getHealth() - amount);
}
}

View File

@ -1,22 +1,18 @@
package com.songoda.epicenchants.effect.effects;
import com.songoda.epicenchants.effect.EffectExecutor;
import com.songoda.epicenchants.enums.EventType;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import static com.songoda.epicenchants.effect.EffectExecutor.Who.PLAYER;
public class Tnt extends EffectExecutor {
public Tnt(ConfigurationSection section) {
super(section);
}
@Override
public void execute(Player wearer, Player opponent, int level) {
getAmount().ifPresent(amount -> who().ifPresent(who -> {
if (who == PLAYER) wearer.getWorld().spawnEntity(wearer.getLocation(), EntityType.PRIMED_TNT);
else opponent.getWorld().spawnEntity(opponent.getLocation(), EntityType.PRIMED_TNT);
}));
public void execute(Player wearer, Player opponent, int level, EventType eventType) {
consume(player -> player.getWorld().spawnEntity(player.getLocation(), EntityType.PRIMED_TNT), wearer, opponent);
}
}

View File

@ -1,5 +0,0 @@
package com.songoda.epicenchants.enums;
public enum EnchantProcType {
DAMAGED, DEALT_DAMAGE, MINED
}

View File

@ -1,5 +1,5 @@
package com.songoda.epicenchants.enums;
public enum EnchantResult {
SUCCESS, FAILURE, BROKEN_FAILURE
SUCCESS, FAILURE, BROKEN_FAILURE, CONFLICT,
}

View File

@ -0,0 +1,23 @@
package com.songoda.epicenchants.enums;
public enum EnchantType {
ATTACK_PLAYER,
ATTACK_MOB,
BOW_ATTACK,
BOW_DEFENSE,
DEATH,
DEFENSE_PLAYER,
DEFENSE_MOB,
DEFENSE_BOW,
EXPLOSION,
FALL_DAMAGE,
FIRE,
HELD_ITEM,
MOB_DEATH,
PLAYER_DEATH,
LEFT_CLICK,
BLOCK_BREAK,
REPEATING,
RIGHT_CLICK,
STATIC_EFFECT
}

View File

@ -0,0 +1,5 @@
package com.songoda.epicenchants.enums;
public enum EventType {
ON, OFF, NONE
}

View File

@ -1,26 +0,0 @@
package com.songoda.epicenchants.enums;
import org.bukkit.Material;
import java.util.Arrays;
public enum MaterialType {
TOOL("PICKAXE", "SHOVEL", "SPADE", "AXE", "HOE"),
WEAPON("SWORD", "BOW", "AXE"),
ARMOR("HELMET", "CHESTPLATE", "LEGGINGS", "BOOTS");
private String[] types;
MaterialType(String... types) {
this.types = types;
}
public boolean is(Material material) {
return Arrays.stream(types).anyMatch(s -> material.toString().contains(s));
}
public static MaterialType of(String string) {
return Arrays.stream(values()).filter(s -> s.toString().equals(string.toUpperCase())).findFirst()
.orElseThrow(() -> new IllegalArgumentException("Unknown MaterialType: " + string));
}
}

View File

@ -7,13 +7,13 @@ import com.songoda.epicenchants.objects.Enchant;
import de.tr7zw.itemnbtapi.NBTItem;
import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.ItemStack;
public class BookListener implements Listener {
@ -25,26 +25,17 @@ public class BookListener implements Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onInventoryClick(InventoryClickEvent event) {
if (event.getCursor() == null || event.getCurrentItem() == null || (event.getWhoClicked().getGameMode() != GameMode.CREATIVE && event.getAction() != InventoryAction.SWAP_WITH_CURSOR)) {
if (event.getCursor() == null || event.getCurrentItem() == null || event.getAction() != InventoryAction.SWAP_WITH_CURSOR || event.getClickedInventory().getType() == InventoryType.CREATIVE) {
return;
}
NBTItem nbtItem = new NBTItem(event.getCursor());
ItemStack toApplyTo = event.getCurrentItem();
boolean incorrectItem = false;
try {
if (!nbtItem.getBoolean("book-item")) {
incorrectItem = true;
return;
}
} catch (NullPointerException ignore) {
incorrectItem = true;
if (!nbtItem.getBoolean("book-item")) {
return;
}
if(incorrectItem) return;
Enchant enchant = instance.getEnchantManager().getEnchant(nbtItem.getString("enchant")).orElseThrow(() -> new IllegalStateException("Book without enchant!"));
if (!enchant.getItemWhitelist().contains(toApplyTo.getType())) {

View File

@ -9,11 +9,13 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import java.util.Map;
import static com.songoda.epicenchants.enums.EnchantProcType.DAMAGED;
import static com.songoda.epicenchants.enums.EnchantProcType.DEALT_DAMAGE;
import static com.songoda.epicenchants.enums.EnchantType.*;
import static com.songoda.epicenchants.enums.EventType.OFF;
import static com.songoda.epicenchants.enums.EventType.ON;
public class PlayerListener implements Listener {
private final EpicEnchants instance;
@ -27,19 +29,30 @@ public class PlayerListener implements Listener {
Map<Enchant, Integer> oldArmorMap = instance.getEnchantUtils().getEnchants(event.getOldArmorPiece());
Map<Enchant, Integer> newArmorMap = instance.getEnchantUtils().getEnchants(event.getNewArmorPiece());
oldArmorMap.forEach((enchant, level) -> enchant.onUnEquip(event.getPlayer(), level));
newArmorMap.forEach((enchant, level) -> enchant.onEquip(event.getPlayer(), level));
oldArmorMap.forEach((enchant, level) -> enchant.onAction(event.getPlayer(), null, event, level, STATIC_EFFECT, OFF));
newArmorMap.forEach((enchant, level) -> enchant.onAction(event.getPlayer(), null, event, level, STATIC_EFFECT, ON));
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
if (event.getEntityType() != EntityType.PLAYER || !(event.getDamager() instanceof Player)) {
return;
if (event.getEntityType() == EntityType.PLAYER) {
Player defender = (Player) event.getEntity();
instance.getEnchantUtils().handlePlayer(defender, event, event.getDamager() instanceof Player ? DEFENSE_PLAYER : DEFENSE_MOB);
}
Player player = (Player) event.getEntity();
Player damager = (Player) event.getDamager();
instance.getEnchantUtils().handlePlayer(player, event, DAMAGED);
instance.getEnchantUtils().handlePlayer(damager, event, DEALT_DAMAGE);
if (event.getDamager() instanceof Player) {
Player attacker = (Player) event.getDamager();
instance.getEnchantUtils().handlePlayer(attacker, event, ATTACK_PLAYER);
}
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
instance.getEnchantUtils().getEnchants(event.getPlayer().getInventory().getItem(event.getNewSlot()))
.forEach((enchant, level) -> enchant.onAction(event.getPlayer(), null, event, level, HELD_ITEM, ON));
instance.getEnchantUtils().getEnchants(event.getPlayer().getInventory().getItem(event.getPreviousSlot()))
.forEach((enchant, level) -> enchant.onAction(event.getPlayer(), null, event, level, HELD_ITEM, OFF));
}
}

View File

@ -1,12 +1,8 @@
package com.songoda.epicenchants.managers;
import com.songoda.epicenchants.EpicEnchants;
import com.songoda.epicenchants.objects.Enchant;
import com.songoda.epicenchants.utils.Chat;
import com.songoda.epicenchants.utils.parser.ConfigParser;
import org.apache.commons.io.FileUtils;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
@ -16,9 +12,7 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import static com.songoda.epicenchants.utils.Chat.color;
import static com.songoda.epicenchants.utils.parser.ConfigParser.parseEnchant;
import static java.io.File.separator;
import static java.util.Arrays.asList;
@ -38,7 +32,7 @@ public class FileManager {
if (!dir.exists()) {
File def = new File(instance.getDataFolder() + separator + "enchants" + separator + "StrengthEnchant.yml");
try {
FileUtils.copyInputStreamToFile(instance.getResource("StrengthEnchant.yml"), def);
FileUtils.copyInputStreamToFile(instance.getResource("ExampleEnchant.yml"), def);
} catch (IOException e) {
e.printStackTrace();
}

View File

@ -0,0 +1,59 @@
package com.songoda.epicenchants.menus;
import com.songoda.epicenchants.EpicEnchants;
import com.songoda.epicenchants.objects.Enchant;
import com.songoda.epicenchants.utils.FastInv;
import com.songoda.epicenchants.utils.ItemBuilder;
import org.apache.commons.lang.StringUtils;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import java.util.Optional;
public class BookMenu extends FastInv {
public BookMenu(EpicEnchants instance, FileConfiguration config) {
super(config.getInt("rows") * 9);
if (config.isConfigurationSection("fill")) {
fill(new ItemBuilder(config.getConfigurationSection("fill")).build());
}
config.getConfigurationSection("contents").getKeys(false)
.stream()
.filter(StringUtils::isNumeric)
.map(s -> "contents." + s)
.map(config::getConfigurationSection)
.forEach(section -> {
double expCost = section.getDouble("exp-cost");
double ecoCost = section.getDouble("eco-cost");
int tier = section.getInt("tier");
addItem(getSlot(section.getInt("row"), section.getInt("column")), new ItemBuilder(section).build(), event -> {
Player player = event.getPlayer();
if (!instance.getEconomy().has((player), ecoCost) || (player).getLevel() < expCost) {
player.sendMessage(instance.getLocale().getPrefix() + instance.getLocale().getMessage("event.purchase.cannotafford"));
return;
}
Optional<Enchant> enchant = instance.getEnchantManager().getRandomEnchant(tier);
if (!enchant.isPresent()) {
player.sendMessage(instance.getLocale().getPrefix() + instance.getLocale().getMessage("event.purchase.noenchant"));
return;
}
instance.getEconomy().withdrawPlayer(player, ecoCost);
player.setLevel((int) (player.getLevel() - expCost));
player.getInventory().addItem(enchant.get().getBookItem().get(enchant.get()));
player.sendMessage(instance.getLocale().getPrefix() + instance.getLocale().getMessage("event.purchase.success", "" + tier));
});
});
}
private int getSlot(int row, int column) {
if (column > 9 || row < 1) {
return 0;
}
return (row - 1) * 9 + column - 1;
}
}

View File

@ -1,41 +0,0 @@
package com.songoda.epicenchants.objects;
import com.songoda.epicenchants.enums.EnchantProcType;
import com.songoda.epicenchants.enums.MaterialType;
import com.songoda.epicenchants.wrappers.MobWrapper;
import com.songoda.epicenchants.wrappers.PotionChanceWrapper;
import lombok.Builder;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import java.util.Set;
import static com.songoda.epicenchants.enums.EnchantProcType.DAMAGED;
import static com.songoda.epicenchants.enums.EnchantProcType.DEALT_DAMAGE;
import static com.songoda.epicenchants.enums.MaterialType.ARMOR;
import static com.songoda.epicenchants.enums.MaterialType.WEAPON;
@Builder
public class ActionClass {
private Set<PotionChanceWrapper> potionEffectsWearer;
private Set<PotionChanceWrapper> potionEffectOpponent;
private LeveledModifier modifyDamage;
private Set<MobWrapper> mobs;
public double run(@NotNull Player wearer, @Nullable Player opponent, int level, double damage, EnchantProcType procType, MaterialType type) {
potionEffectsWearer.stream().filter(p -> p.test(level)).forEach(p -> p.perform(wearer, level));
Optional.ofNullable(opponent).ifPresent(a -> potionEffectOpponent.stream().filter(p -> p.test(level)).forEach(p -> p.perform(opponent, level)));
mobs.forEach(mob -> mob.trySpawn(wearer, opponent, level));
double percentage = 0;
if ((procType == DAMAGED && type == ARMOR) || (procType == DEALT_DAMAGE && type == WEAPON)) {
percentage = modifyDamage.get(level) / 100.0;
}
return damage + damage * percentage;
}
}

View File

@ -1,20 +1,16 @@
package com.songoda.epicenchants.objects;
import com.songoda.epicenchants.enums.MaterialType;
import com.songoda.epicenchants.wrappers.PotionEffectWrapper;
import com.songoda.epicenchants.effect.EffectExecutor;
import com.songoda.epicenchants.enums.EnchantType;
import com.songoda.epicenchants.enums.EventType;
import com.songoda.epicenchants.wrappers.MobWrapper;
import lombok.Builder;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.event.Event;
import java.util.Set;
import java.util.stream.Collectors;
import static com.songoda.epicenchants.enums.EnchantProcType.*;
@Builder
@Getter
@ -22,30 +18,16 @@ public class Enchant {
private String identifier;
private int tier;
private int maxLevel;
private MaterialType materialType;
private Set<PotionEffectWrapper> potionEffects;
private Set<String> conflict;
private Set<Material> itemWhitelist;
private Set<EffectExecutor> effectExecutors;
private Set<MobWrapper> mobs;
private String format;
private ActionClass action;
private BookItem bookItem;
private LeveledModifier modifyDamage;
public void onEquip(Player player, int level) {
potionEffects.stream().map(p -> p.get(level)).forEach(player::addPotionEffect);
}
public void onUnEquip(Player player, int level) {
Set<PotionEffectType> effects = potionEffects.stream().map(p -> p.get(level)).map(PotionEffect::getType).collect(Collectors.toSet());
player.getActivePotionEffects().stream().map(PotionEffect::getType).filter(effects::contains).forEach(player::removePotionEffect);
}
public void onReceiveDamage(EntityDamageByEntityEvent event, int level) {
event.setDamage(action.run(((Player) event.getEntity()), ((Player) event.getDamager()), level, event.getDamage(), DAMAGED, materialType));
}
public void onDealDamage(EntityDamageByEntityEvent event, int level) {
event.setDamage(action.run(((Player) event.getEntity()), ((Player) event.getDamager()), level, event.getDamage(), DEALT_DAMAGE, materialType));
}
public void onMine(BlockBreakEvent event, int level) {
public void onAction(Player wearer, Player attacker, Event event, int level, EnchantType enchantType, EventType eventType) {
effectExecutors.forEach(effect -> effect.testAndRun(wearer, attacker, level, enchantType, event, eventType));
mobs.forEach(mobWrapper -> mobWrapper.trySpawn(wearer, attacker, level, enchantType));
}
}

View File

@ -17,8 +17,12 @@ public class LeveledModifier {
return new LeveledModifier(string);
}
public double get(int level) {
if (string.isEmpty() || string.equalsIgnoreCase("MAX")) {
public double get(int level, int def) {
if (string == null || string.isEmpty()) {
return def;
}
if (string.equalsIgnoreCase("MAX")) {
return Integer.MAX_VALUE;
}
@ -28,7 +32,7 @@ public class LeveledModifier {
return Double.parseDouble(scriptEngine.eval(string.replace("{level}", "" + level)).toString());
} catch (ScriptException | NumberFormatException e) {
Bukkit.getLogger().warning("[EpicEnchants] One of your math expressions is not properly formatted.");
return 0;
return def;
}
}
}

View File

@ -1,8 +1,9 @@
package com.songoda.epicenchants.utils;
import com.songoda.epicenchants.EpicEnchants;
import com.songoda.epicenchants.enums.EnchantProcType;
import com.songoda.epicenchants.enums.EnchantResult;
import com.songoda.epicenchants.enums.EnchantType;
import com.songoda.epicenchants.enums.EventType;
import com.songoda.epicenchants.objects.Enchant;
import de.tr7zw.itemnbtapi.NBTCompound;
import de.tr7zw.itemnbtapi.NBTItem;
@ -10,7 +11,6 @@ import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.inventory.ItemStack;
@ -18,6 +18,7 @@ import java.util.*;
import java.util.stream.Collectors;
import static com.songoda.epicenchants.enums.EnchantResult.*;
import static com.songoda.epicenchants.enums.EnchantType.HELD_ITEM;
public class EnchantUtils {
@ -32,6 +33,10 @@ public class EnchantUtils {
return GeneralUtils.chance(destroyRate) ? Pair.of(new ItemStack(Material.AIR), BROKEN_FAILURE) : Pair.of(itemStack, FAILURE);
}
if (getEnchants(itemStack).keySet().stream().anyMatch(s -> enchant.getIdentifier().equalsIgnoreCase(s.getIdentifier()))) {
return Pair.of(itemStack, CONFLICT);
}
ItemBuilder itemBuilder = new ItemBuilder(itemStack);
itemBuilder.removeLore(enchant.getFormat().replace("{level}", "").trim());
itemBuilder.addLore(enchant.getFormat().replace("{level}", "" + level));
@ -57,25 +62,25 @@ public class EnchantUtils {
return Collections.emptyMap();
}
return compound.getKeys().stream().collect(Collectors.toMap(key -> instance.getEnchantManager().getEnchantUnsafe(key), compound::getInteger));
return compound.getKeys().stream().filter(key -> instance.getEnchantManager().getEnchantUnsafe(key) != null)
.collect(Collectors.toMap(key -> instance.getEnchantManager().getEnchantUnsafe(key), compound::getInteger));
}
public void handlePlayer(Player player, Event event, EnchantProcType damageType) {
public void handlePlayer(Player player, Event event, EnchantType enchantType) {
List<ItemStack> stacks = new ArrayList<>(Arrays.asList(player.getInventory().getArmorContents()));
stacks.add(player.getItemInHand());
stacks.removeIf(Objects::isNull);
if (enchantType == HELD_ITEM) {
stacks = Collections.singletonList(player.getItemInHand());
}
stacks.stream().map(this::getEnchants).forEach(list -> list.forEach((enchant, level) -> {
switch (damageType) {
case DAMAGED:
enchant.onReceiveDamage((EntityDamageByEntityEvent) event, level);
break;
case DEALT_DAMAGE:
enchant.onDealDamage((EntityDamageByEntityEvent) event, level);
break;
case MINED:
enchant.onMine((BlockBreakEvent) event, level);
}
Player opponent = event instanceof EntityDamageByEntityEvent ?
((EntityDamageByEntityEvent) event).getDamager() instanceof Player ?
((Player) ((EntityDamageByEntityEvent) event).getDamager()) : null : null;
enchant.onAction(player, opponent, event, level, enchantType, EventType.NONE);
}));
}
}

View File

@ -0,0 +1,525 @@
package com.songoda.epicenchants.utils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.*;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitTask;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* A fast API to easily create advanced GUI.
* The project is on <a href="https://github.com/MrMicky-FR/FastInv">GitHub</a>
*
* @author MrMicky
* @version 2.0.3 - Now supports async operations
*/
public class FastInv implements InventoryHolder {
private static Plugin plugin = null;
private boolean cancelTasksOnClose = true;
private Set<FastInvClickListener> clickListeners = new HashSet<>();
private Set<FastInvCloseListener> closeListeners = new HashSet<>();
private Inventory inventory;
private Map<Integer, FastInvClickListener> itemListeners = new HashMap<>();
private Set<BukkitTask> tasks = new HashSet<>();
/**
* Create a new FastInv with a custom size.
*
* @param size The size of the menus.
*/
public FastInv(int size) {
this(size, InventoryType.CHEST.getDefaultTitle());
}
/**
* Create a new FastInv with a custom size and title.
*
* @param size The size of the menus.
* @param title The title (name) of the menus.
*/
public FastInv(int size, String title) {
this(size, InventoryType.CHEST, title);
}
/**
* Create a new FastInv with a custom type.
*
* @param type The type of the menus.
*/
public FastInv(InventoryType type) {
this(type, type.getDefaultTitle());
}
/**
* Create a new FastInv with a custom type and title.
*
* @param type The type of the menus.
* @param title The title of the menus.
* @throws IllegalStateException if FastInv is not init with FastInv.init(Plugin plugin)
*/
public FastInv(InventoryType type, String title) {
this(0, type, title);
}
private FastInv(int size, InventoryType type, String title) {
if (plugin == null) {
throw new IllegalStateException("FastInv is not initialised");
}
runSync(() -> {
if (type == InventoryType.CHEST && size > 0) {
inventory = Bukkit.createInventory(this, size, title);
} else {
inventory = Bukkit.createInventory(this, type, title);
}
});
}
/**
* Register your FastInv instance.
*
* @param plugin The plugin that uses FastInv.
*/
public static void init(Plugin plugin) {
if (FastInv.plugin == null) {
FastInv.plugin = plugin;
Bukkit.getPluginManager().registerEvents(getListener(), plugin);
}
}
private static Listener getListener() {
return new Listener() {
@EventHandler
public void onClick(InventoryClickEvent event) {
if (event.getInventory().getHolder() instanceof FastInv && event.getWhoClicked() instanceof Player) {
int slot = event.getRawSlot();
FastInv inv = (FastInv) event.getInventory().getHolder();
FastInvClickEvent clickEvent = new FastInvClickEvent((Player) event.getWhoClicked(), inv, slot,
event.getCurrentItem(), true, event.getAction(), event.getClick());
if (inv.itemListeners.containsKey(slot)) {
inv.itemListeners.get(slot).onClick(clickEvent);
}
inv.clickListeners.forEach(listener -> listener.onClick(clickEvent));
if (clickEvent.isCancelled()) {
event.setCancelled(true);
}
}
}
@EventHandler
public void onClose(InventoryCloseEvent event) {
if (event.getInventory().getHolder() instanceof FastInv && event.getPlayer() instanceof Player) {
Player player = (Player) event.getPlayer();
FastInv inv = (FastInv) event.getInventory().getHolder();
FastInvCloseEvent closeEvent = new FastInvCloseEvent(player, inv, false);
inv.closeListeners.forEach(listener -> listener.onClose(closeEvent));
Bukkit.getScheduler().runTask(plugin, () -> {
// Tiny delay to prevent errors.
if (closeEvent.isCancelled() && player.isOnline()) {
player.openInventory(inv.getInventory());
} else if (inv.getInventory().getViewers().isEmpty() && inv.cancelTasksOnClose) {
inv.cancelTasks();
}
});
}
}
@EventHandler
public void onDisable(PluginDisableEvent event) {
if (event.getPlugin().equals(plugin)) {
for (Player player : Bukkit.getOnlinePlayers()) {
if (player.getOpenInventory().getTopInventory().getHolder() instanceof FastInv) {
player.closeInventory();
}
}
}
}
};
}
/**
* Add an {@link ItemStack} to the menus.
*
* @param item The item to add
* @return This FastInv instance, for chaining.
*/
public FastInv addItem(ItemStack item) {
return addItem(item, null);
}
/**
* Add an {@link ItemStack} to the menus with a {@link FastInvClickListener} to handle clicks.
*
* @param item The item to add.
* @param listener The {@link FastInvClickListener} for the item.
* @return This FastInv instance, for chaining.
*/
public FastInv addItem(ItemStack item, FastInvClickListener listener) {
runSync(() -> {
int slot = inventory.firstEmpty();
if (slot >= 0) {
addItem(slot, item, listener);
}
});
return this;
}
/**
* Add an {@link ItemStack} to the menus on a specific slot.
*
* @param slot The slot of the item.
* @param item The item to add.
* @return This FastInv instance, for chaining.
*/
public FastInv addItem(int slot, ItemStack item) {
return addItem(slot, item, null);
}
/**
* Add an {@link ItemStack} to the menus on specific slot with a {@link FastInvClickListener} to handle clicks.
*
* @param slot The slot of the item.
* @param item The item to add.
* @param listener The FastInvClickListener for the item.
* @return This FastInv instance, for chaining.
*/
public FastInv addItem(int slot, ItemStack item, FastInvClickListener listener) {
runSync(() -> {
inventory.setItem(slot, item);
if (listener != null) {
itemListeners.put(slot, listener);
} else {
itemListeners.remove(slot);
}
});
return this;
}
/**
* Add an {@link ItemStack} to the menus on a range of slots.
*
* @param slotFrom Starting slot to put the item in.
* @param slotTo Ending slot to put the item in.
* @param item The item to add.
* @return This FastInv instance, for chaining.
*/
public FastInv addItem(int slotFrom, int slotTo, ItemStack item) {
return addItem(slotFrom, slotTo, item, null);
}
/**
* Add an {@link ItemStack} to the menus on a range of slots with a {@link FastInvClickListener} to handle clicks.
*
* @param slotFrom Starting slot to put the item in.
* @param slotTo Ending slot to put the item in.
* @param item The item to add.
* @param listener The FastInvClickListener for the item.
* @return This FastInv instance, for chaining.
*/
public FastInv addItem(int slotFrom, int slotTo, ItemStack item, FastInvClickListener listener) {
for (int i = slotFrom; i <= slotTo; i++) {
addItem(i, item, listener);
}
return this;
}
/**
* Add an {@link ItemStack} to the menus on multiple slots.
*
* @param slots The slot of the item.
* @param item The item to add.
* @return This FastInv instance, for chaining.
*/
public FastInv addItem(int[] slots, ItemStack item) {
return addItem(slots, item, null);
}
/**
* Add an {@link ItemStack} to the menus on the edges.
*
* @param item The item to add.
* @return This FastInv instance, for chaining.
*/
public FastInv edge(ItemStack item) {
int height = inventory.getSize() / 9;
addItem(0, 9, item);
addItem(inventory.getSize() - 9, inventory.getSize() - 1, item);
for (int i = 0; i < height; i++) {
addItem(i * 9, item);
addItem(i * 9 + 8, item);
}
return this;
}
/**
* Add an {@link ItemStack} to the menus on multiples slots with a {@link FastInvClickListener} to handle click.
*
* @param slots The slots to place the item.
* @param item The item to add.
* @param listener The FastInvClickListener for the item.
* @return This FastInv instance, for chaining.
*/
public FastInv addItem(int[] slots, ItemStack item, FastInvClickListener listener) {
for (int slot : slots) {
addItem(slot, item, listener);
}
return this;
}
public FastInv fill(ItemStack itemStack) {
runSync(() -> {
for (int i = 0; i < inventory.getSize(); i++) {
if (inventory.getItem(i) == null) {
addItem(i, itemStack);
}
}
});
return this;
}
/**
* Add a {@link FastInvCloseListener} to listen on menus close.
*
* @param listener The {@link FastInvCloseListener} to add.
* @return This FastInv instance, for chaining.
*/
public FastInv onClose(FastInvCloseListener listener) {
closeListeners.add(listener);
return this;
}
/**
* Add a {@link FastInvClickListener} to listen on menus click.
*
* @param listener The {@link FastInvClickListener} to add.
* @return This FastInv instance, for chaining.
*/
public FastInv onClick(FastInvClickListener listener) {
clickListeners.add(listener);
return this;
}
/**
* Schedule a task to run.
*
* @param period Delay between each run.
* @param runnable The {@link Runnable} task to run.
* @return This FastInv instance, for chaining.
*/
public FastInv onUpdate(long period, Runnable runnable) {
return onUpdate(period, period, runnable);
}
/**
* Schedule a task to run with a delay before starting.
*
* @param delay Ticks to wait before starting the task.
* @param period Delay between each run.
* @param runnable The {@link Runnable} task to run.
* @return This FastInv instance, for chaining
*/
public FastInv onUpdate(long delay, long period, Runnable runnable) {
tasks.add(Bukkit.getScheduler().runTaskTimer(plugin, runnable, delay, period));
return this;
}
/**
* Open the menus to a player.
*
* @param player The player to open the menu.
*/
public void open(Player player) {
Bukkit.getScheduler().runTask(plugin, () -> player.openInventory(inventory));
}
/**
* Open the menus to players.
*
* @param players The players to open the menu.
*/
public void open(Player... players) {
Bukkit.getScheduler().runTask(plugin, () -> {
for (Player p : players) {
p.openInventory(inventory);
}
});
}
/**
* Cancel all tasks.
*/
public void cancelTasks() {
tasks.forEach(BukkitTask::cancel);
tasks.clear();
}
/**
* Run a task on the server primary thread.
*
* @param runnable The runnable to run on the main thread
*/
public void runSync(Runnable runnable) {
if (Bukkit.isPrimaryThread()) {
runnable.run();
} else {
Bukkit.getScheduler().runTask(plugin, runnable);
}
}
/**
* Get the Bukkit menus associated with this FastInv instance.
*
* @return The Bukkit {@link Inventory}.
*/
@Override
public Inventory getInventory() {
return inventory;
}
/**
* Set if the tasks will be cancel on menus close.
*
* @param cancelTasksOnClose Set if the tasks will be cancel
* @return This FastInv instance, for chaining.
*/
public FastInv setCancelTasksOnClose(boolean cancelTasksOnClose) {
this.cancelTasksOnClose = cancelTasksOnClose;
return this;
}
public interface FastInvClickListener {
void onClick(FastInvClickEvent event);
}
public interface FastInvCloseListener {
void onClose(FastInvCloseEvent event);
}
public static abstract class FastInvEvent {
private boolean cancelled;
private FastInv inventory;
private Player player;
FastInvEvent(Player player, FastInv inventory, boolean cancelled) {
this.player = player;
this.inventory = inventory;
this.cancelled = cancelled;
}
/**
* Get the FastInv menus.
*
* @return This associated FastInv instance.
*/
public FastInv getInventory() {
return inventory;
}
/**
* Get the {@link Player} who clicked.
*
* @return the player who clicked.
*/
public Player getPlayer() {
return player;
}
/**
* Get if the event is cancelled or not.
*
* @return Whether the event was cancelled.
*/
public boolean isCancelled() {
return cancelled;
}
/**
* Set if the event will be cancel or not.
*
* @param cancel Whether the event should be cancelled.
*/
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
}
public static class FastInvClickEvent extends FastInvEvent {
private InventoryAction action;
private ClickType clickType;
private ItemStack item;
private int slot;
private FastInvClickEvent(Player player, FastInv inventory, int slot, ItemStack item,
boolean cancelled, InventoryAction action, ClickType clickType) {
super(player, inventory, cancelled);
this.slot = slot;
this.item = item;
this.action = action;
this.clickType = clickType;
}
/**
* @return The action of the event
*/
public InventoryAction getAction() {
return this.action;
}
/**
* @return The click type
*/
public ClickType getClickType() {
return this.clickType;
}
/**
* Get the clicked {@link ItemStack}
*
* @return The clicked item
*/
public ItemStack getItem() {
return this.item;
}
/**
* Get the number of the clicked slot
*
* @return The slot number
*/
public int getSlot() {
return this.slot;
}
}
public static class FastInvCloseEvent extends FastInvEvent {
private FastInvCloseEvent(Player player, FastInv inventory, boolean cancelled) {
super(player, inventory, cancelled);
}
}
}

View File

@ -9,6 +9,7 @@ import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import java.util.*;
import java.util.stream.Collectors;
@ -157,6 +158,28 @@ public class ItemBuilder {
return this;
}
/*
* Skulls:
*/
public boolean hasSkullOwner() {
return ((SkullMeta) meta).hasOwner();
}
public String getSkullOwner() {
return ((SkullMeta) meta).getOwner();
}
public ItemBuilder skullOwner(String owner) {
item.setDurability((short) 3);
((SkullMeta) meta).setOwner(owner);
return this;
}
public ItemBuilder durability(int durability) {
item.setDurability((short) durability);
return this;
}
/*
* Flags:
*/
@ -197,7 +220,7 @@ public class ItemBuilder {
public ItemStack buildWithWrappers(int level) {
item.setItemMeta(meta);
enchantmentWrappers.forEach(enchant -> item.addEnchantment(enchant.getEnchantment(), enchant.getAmplifier(level)));
enchantmentWrappers.forEach(enchant -> item.addUnsafeEnchantment(enchant.getEnchantment(), enchant.getAmplifier(level)));
return item;
}

View File

@ -1,7 +1,7 @@
package com.songoda.epicenchants.utils.parser;
import com.songoda.epicenchants.enums.MaterialType;
import com.songoda.epicenchants.objects.ActionClass;
import com.songoda.epicenchants.effect.EffectManager;
import com.songoda.epicenchants.enums.EnchantType;
import com.songoda.epicenchants.objects.BookItem;
import com.songoda.epicenchants.objects.Enchant;
import com.songoda.epicenchants.objects.LeveledModifier;
@ -9,17 +9,14 @@ import com.songoda.epicenchants.utils.Chat;
import com.songoda.epicenchants.utils.ItemBuilder;
import com.songoda.epicenchants.wrappers.EnchantmentWrapper;
import com.songoda.epicenchants.wrappers.MobWrapper;
import com.songoda.epicenchants.wrappers.PotionChanceWrapper;
import com.songoda.epicenchants.wrappers.PotionEffectWrapper;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
import org.bukkit.potion.PotionEffectType;
import java.util.Collections;
import java.util.Set;
import java.util.HashSet;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.songoda.epicenchants.utils.Chat.color;
@ -29,69 +26,41 @@ public class ConfigParser {
return Enchant.builder()
.identifier(config.getString("identifier"))
.tier(config.getInt("tier"))
.materialType(MaterialType.of(config.getString("type")))
.maxLevel(config.getInt("max-level"))
.format(color(config.getString("applied-format")))
.action(parseActions(config))
.bookItem(parseBookItem(config.getConfigurationSection("book-item")))
.itemWhitelist(config.getStringList("item-whitelist").stream().map(Material::valueOf).collect(Collectors.toSet()))
.potionEffects(config.getConfigurationSection("potion-effect").getKeys(false).stream()
.map(s -> "potion-effect." + s)
.conflict(new HashSet<>(config.getStringList("conflicting-enchants")))
.mobs(config.getConfigurationSection("mobs").getKeys(false).stream()
.map(s -> "mobs." + s)
.map(config::getConfigurationSection)
.map(ConfigParser::parsePotionEffect)
.map(ConfigParser::parseMobWrapper).collect(Collectors.toSet()))
.effectExecutors(config.getConfigurationSection("effects").getKeys(false).stream()
.map(s -> "effects." + s)
.map(config::getConfigurationSection)
.map(EffectManager::getEffect)
.map(o -> o.orElse(null))
.filter(Objects::nonNull)
.collect(Collectors.toSet()))
.build();
}
public static ActionClass parseActions(ConfigurationSection section) {
return section != null ? ActionClass.builder()
.modifyDamage(LeveledModifier.of(section.getString("modify-damage")))
.potionEffectsWearer(ConfigParser.getPotionChanceSet(section.getConfigurationSection("potion-effect-wearer")))
.potionEffectOpponent(ConfigParser.getPotionChanceSet(section.getConfigurationSection("potion-effect-opponent")))
.mobs(section.getConfigurationSection("mobs").getKeys(false).stream()
.map(s -> "mobs." + s)
.map(section::getConfigurationSection)
.map(ConfigParser::parseMobWrapper).collect(Collectors.toSet()))
.build() : null;
}
private static Set<PotionChanceWrapper> getPotionChanceSet(ConfigurationSection section) {
return section != null ? section.getKeys(false).stream()
.map(section::getConfigurationSection)
.map(ConfigParser::parsePotionChanceEffect)
.collect(Collectors.toSet()) : Collections.emptySet();
}
public static PotionChanceWrapper parsePotionChanceEffect(ConfigurationSection section) {
return section != null ? PotionChanceWrapper.chanceBuilder()
.type(PotionEffectType.getByName(section.getName()))
.amplifier(LeveledModifier.of(section.getString("amplifier")))
.duration(LeveledModifier.of(section.getString("duration")))
.chance(LeveledModifier.of(section.getString("chance")))
.build() : null;
}
public static PotionEffectWrapper parsePotionEffect(ConfigurationSection section) {
return section != null ? PotionEffectWrapper.builder()
.type(PotionEffectType.getByName(section.getName()))
.amplifier(LeveledModifier.of(section.getString("amplifier")))
.duration(LeveledModifier.of(section.getString("duration")))
.build() : null;
}
public static MobWrapper parseMobWrapper(ConfigurationSection section) {
return section != null ? MobWrapper.builder()
.enchantType(EnchantType.valueOf(section.getString("effect-type")))
.entityType(EntityType.valueOf(section.getName()))
.amount(section.getInt("max-amount"))
.maxAmount(LeveledModifier.of(section.getString("max-amount")))
.spawnPercentage(LeveledModifier.of(section.getString("spawn-percentage")))
.health(section.getInt("health"))
.attackDamage(section.getDouble("attack-damage"))
.health(LeveledModifier.of(section.getString("health")))
.attackDamage(LeveledModifier.of(section.getString("attack-damage")))
.equipmentDropChance(LeveledModifier.of(section.getString("equipment-drop-chance")))
.hostile(section.getBoolean("hostile"))
.displayName(color(section.getString("display-name")))
.helmet(section.isConfigurationSection("equipment.helmet") ? new ItemBuilder(section.getConfigurationSection("equipment.helmet")) : null)
.chestPlate(section.isConfigurationSection("equipment.chestplate") ? new ItemBuilder(section.getConfigurationSection("equipment.chestplate")) : null)
.leggings(section.isConfigurationSection("equipment.leggings") ? new ItemBuilder(section.getConfigurationSection("equipment.leggings")) : null)
.boots(section.isConfigurationSection("equipment.boots") ? new ItemBuilder(section.getConfigurationSection("equipment.boots")) : null)
.handItem(section.isConfigurationSection("equipment.hand-item") ? new ItemBuilder(section.getConfigurationSection("equipment.hand-item")) : null)
.build() : null;
}

View File

@ -1,70 +0,0 @@
package com.songoda.epicenchants.utils.parser;
import com.songoda.epicenchants.EpicEnchants;
import com.songoda.epicenchants.objects.Enchant;
import com.songoda.epicenchants.utils.ItemBuilder;
import fr.minuskube.inv.ClickableItem;
import fr.minuskube.inv.SmartInventory;
import fr.minuskube.inv.content.InventoryContents;
import fr.minuskube.inv.content.InventoryProvider;
import org.apache.commons.lang.StringUtils;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import java.util.Optional;
import static com.songoda.epicenchants.utils.Chat.color;
import static java.util.concurrent.ThreadLocalRandom.current;
public class InventoryParser {
public static SmartInventory parseBookMenu(EpicEnchants instance, FileConfiguration config) {
return SmartInventory.builder()
.title(color(config.getString("title")))
.size(config.getInt("rows"), 9)
.provider(new InventoryProvider() {
@Override
public void init(Player opener, InventoryContents inventoryContents) {
if (config.isConfigurationSection("fill")) {
inventoryContents.fill(ClickableItem.empty(new ItemBuilder(config.getConfigurationSection("fill")).build()));
}
config.getConfigurationSection("contents").getKeys(false)
.stream()
.filter(StringUtils::isNumeric)
.map(s -> "contents." + s)
.map(config::getConfigurationSection)
.forEach(section -> {
double expCost = section.getDouble("exp-cost");
double ecoCost = section.getDouble("eco-cost");
int tier = section.getInt("tier");
inventoryContents.set(section.getInt("row"), section.getInt("column"), ClickableItem.of(new ItemBuilder(section).build(), event -> {
Player player = ((Player) event.getWhoClicked());
if (!instance.getEconomy().has((player), ecoCost) || (player).getLevel() < expCost) {
player.sendMessage(instance.getLocale().getPrefix() + instance.getLocale().getMessage("event.purchase.cannotafford"));
return;
}
Optional<Enchant> enchant = instance.getEnchantManager().getRandomEnchant(tier);
if (!enchant.isPresent()) {
player.sendMessage(instance.getLocale().getPrefix() + instance.getLocale().getMessage("event.purchase.noenchant"));
return;
}
instance.getEconomy().withdrawPlayer(player, ecoCost);
player.setLevel((int) (player.getLevel() - expCost));
player.getInventory().addItem(enchant.get().getBookItem().get(enchant.get()));
player.sendMessage(instance.getLocale().getPrefix() + instance.getLocale().getMessage("event.purchase.success", "" + tier));
}));
});
}
@Override
public void update(Player player, InventoryContents inventoryContents) {
}
})
.manager(instance.getInventoryManager())
.build();
}
}

View File

@ -10,7 +10,7 @@ public class EnchantmentWrapper {
private Enchantment enchantment;
public int getAmplifier(int level) {
return (int) amplifier.get(level);
return (int) amplifier.get(level, 0);
}
public Enchantment getEnchantment() {

View File

@ -1,5 +1,6 @@
package com.songoda.epicenchants.wrappers;
import com.songoda.epicenchants.enums.EnchantType;
import com.songoda.epicenchants.objects.LeveledModifier;
import com.songoda.epicenchants.utils.GeneralUtils;
import com.songoda.epicenchants.utils.ItemBuilder;
@ -17,24 +18,28 @@ import static java.util.concurrent.ThreadLocalRandom.current;
@Builder
public class MobWrapper {
private String displayName;
private int amount;
private int health;
private int armorDropChance;
private EntityType entityType;
private LeveledModifier attackDamage;
private EnchantType enchantType;
private LeveledModifier equipmentDropChance;
private LeveledModifier spawnPercentage;
private double attackDamage;
private LeveledModifier health;
private ItemBuilder helmet, chestPlate, leggings, boots, handItem;
private boolean hostile;
private ItemBuilder helmet, chestPlate, leggings, boots;
private LeveledModifier maxAmount;
public boolean trySpawn(@NotNull Player player, Player opponent, int level) {
if (!GeneralUtils.chance(spawnPercentage.get(level))) {
return false;
public void trySpawn(@NotNull Player player, Player opponent, int level, EnchantType enchantType) {
if (this.enchantType != enchantType) {
return;
}
if (!GeneralUtils.chance(spawnPercentage.get(level, 100))) {
return;
}
Location location = player.getLocation();
for (int i = 0; i < current().nextInt(amount + 1); i++) {
for (int i = 0; i < current().nextInt((int) (maxAmount.get(level, 1) + 1)); i++) {
Location spawnLocation = location.clone().add(current().nextInt(-3, 3), 0, current().nextInt(-3, 3));
int y = location.getWorld().getHighestBlockAt(spawnLocation).getY();
@ -44,19 +49,24 @@ public class MobWrapper {
Entity entity = location.getWorld().spawnEntity(spawnLocation, entityType);
entity.setCustomName(displayName);
entity.setCustomName(displayName.replace("{level}", "" + level));
entity.setCustomNameVisible(true);
if (entity instanceof LivingEntity) {
LivingEntity livingEntity = (LivingEntity) entity;
livingEntity.getEquipment().setHelmet(helmet.buildWithWrappers(level));
livingEntity.getEquipment().setChestplate(chestPlate.buildWithWrappers(level));
livingEntity.getEquipment().setLeggings(leggings.buildWithWrappers(level));
livingEntity.getEquipment().setBoots(boots.buildWithWrappers(level));
livingEntity.getEquipment().setHelmetDropChance(armorDropChance);
livingEntity.getEquipment().setLeggingsDropChance(armorDropChance);
livingEntity.getEquipment().setHelmetDropChance(armorDropChance);
livingEntity.getEquipment().setChestplateDropChance(armorDropChance);
int dropChance = (int) equipmentDropChance.get(level, 0);
if (helmet != null) livingEntity.getEquipment().setHelmet(helmet.buildWithWrappers(level));
if (chestPlate != null) livingEntity.getEquipment().setChestplate(chestPlate.buildWithWrappers(level));
if (leggings != null) livingEntity.getEquipment().setLeggings(leggings.buildWithWrappers(level));
if (boots != null) livingEntity.getEquipment().setBoots(boots.buildWithWrappers(level));
livingEntity.getEquipment().setHelmetDropChance(dropChance);
livingEntity.getEquipment().setLeggingsDropChance(dropChance);
livingEntity.getEquipment().setHelmetDropChance(dropChance);
livingEntity.getEquipment().setChestplateDropChance(dropChance);
if (handItem != null) livingEntity.getEquipment().setItemInMainHand(handItem.buildWithWrappers(level));
livingEntity.getEquipment().setItemInMainHandDropChance(dropChance);
}
if (entity instanceof Monster && opponent != null) {
@ -69,16 +79,16 @@ public class MobWrapper {
for (int j = 0; j < list.size(); j++) {
NBTListCompound lc = list.getCompound(j);
if (lc.getString("Name").equals("generic.attackDamage")) {
lc.setDouble("Base", attackDamage);
lc.setDouble("Base", attackDamage.get(level, (int) lc.getDouble("Base")));
continue;
}
if (lc.getString("Name").equals("generic.maxHealth")) {
lc.setDouble("Base", health);
lc.setDouble("Base", health.get(level, (int) lc.getDouble("Base")));
}
}
}
return true;
return;
}
}

View File

@ -1,27 +0,0 @@
package com.songoda.epicenchants.wrappers;
import com.songoda.epicenchants.objects.LeveledModifier;
import com.songoda.epicenchants.utils.GeneralUtils;
import lombok.Builder;
import lombok.Getter;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffectType;
@Getter
public class PotionChanceWrapper extends PotionEffectWrapper {
private LeveledModifier chance;
@Builder(builderMethodName = "chanceBuilder")
PotionChanceWrapper(PotionEffectType type, LeveledModifier amplifier, LeveledModifier duration, LeveledModifier chance ) {
super(type, amplifier, duration);
this.chance = chance;
}
public boolean test(int level) {
return GeneralUtils.chance(chance.get(level));
}
public void perform(Player player, int level) {
player.addPotionEffect(get(level));
}
}

View File

@ -1,19 +0,0 @@
package com.songoda.epicenchants.wrappers;
import com.songoda.epicenchants.objects.LeveledModifier;
import lombok.AllArgsConstructor;
import lombok.Builder;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
@Builder
@AllArgsConstructor
public class PotionEffectWrapper {
private PotionEffectType type;
private LeveledModifier amplifier;
private LeveledModifier duration;
public PotionEffect get(int level) {
return new PotionEffect(type, (int) duration.get(level), (int) amplifier.get(level) - 1);
}
}

View File

@ -0,0 +1,89 @@
#The enchant identifier must be unique
identifier: ExampleEnchant
#The max tier for this enchant
max-level: 4
#The tier of this enchant
tier: 1
#The book item
book-item:
material: BOOK
display-name: "&cExampleEnchant {level}"
lore:
- "&7Drag on to enchant"
- "&cDestroy Rate {destroy_rate}"
- "&aSuccess Rate {success_rate}"
#Format as seen in the lore of the item
applied-format: "&cExampleEnchant {level}"
#What items this enchant can be applied too
item-whitelist:
- "DIAMOND_HELMET"
- "IRON_HELMET"
- "LEATHER_HELMET"
conflicting-enchants:
- "someEnchant"
#Effects
effects:
FLY:
type: STATIC_EFFECT
who: WEARER
#The "-1" is added because every effect key has to be unique.
POTION-1:
#The EffectType
type: DEFENSE_PLAYER
#What player should the effect be ran on
who: WEARER
potion-type: SPEED
duration: "10 * {level}"
chance: "20 * {level}"
amplifier: "{level} - 1"
POTION-2:
type: STATIC_EFFECT
who: WEARER
potion-type: INCREASE_DAMAGE
amplifier: "{level} - 1"
#Chance of spawning when damaged by another player
mobs:
#EntityType
ZOMBIE:
#Max amount zombies that will be spawned
effect-type: DEFENSE_PLAYER
max-amount: "{level}"
spawn-percentage: "20 * {level}"
equipment-drop-chance: "10 * {level}"
health: "3 * {level}"
attack-damage: "{level}"
hostile: true
display-name: "&cAngry guy level {level}"
equipment:
helmet:
material: DIAMOND_HELMET
enchants:
- "DURABILITY:{level}"
- "THORNS:{level} - 1"
chestplate:
material: DIAMOND_CHESTPLATE
enchants:
- "DURABILITY:{level}"
- "THORNS:{level} - 1"
leggings:
material: DIAMOND_LEGGINGS
enchants:
- "DURABILITY:{level}"
- "THORNS:{level} - 1"
boots:
material: DIAMOND_BOOTS
enchants:
- "DURABILITY:{level}"
- "THORNS:{level} - 1"
hand-item:
material: DIAMOND_SWORD
enchant:
- "SHARPNESS:{level}"

View File

@ -1,98 +0,0 @@
#The enchant identifier must be unique
identifier: Strength
#The max tier for this enchant
max-level: 3
#The tier of this enchant
tier: 1
#Type of material this enchant will be applied to (WEAPON/ARMOR/TOOL)
type: ARMOR
#The book item
book-item:
material: BOOK
display-name: "&cStrength {level}"
lore:
- "&7Drag on to enchant"
- "&cDestroy Rate {destroy_rate}"
- "&aSuccess Rate {success_rate}"
#Format as seen in the lore of the item
applied-format: "&7Strength {level}"
#What items this enchant can be applied too
item-whitelist:
- "DIAMOND_HELMET"
- "IRON_HELMET"
- "LEATHER_HELMET"
#Potion effect applied on equip
potion-effects:
INCREASE_DAMAGE:
amplifier: "{level}"
duration: MAX
#Custom effect:
# FLY:
# LIGHTNING:
#
#
#
#
#
effects:
FLY:
type: "STATIC_EFFECT"
chance: 20
who: OPPONENT
#Percentage that will be added or subtracted from the total damage.
modify-damage: 40
#Potion effect that will given to the wearer on damage
potion-effects-wearer:
SPEED:
duration: 3
chance: "20 * {level}"
amplifier: 2
#Potion effect that will given to the opponent on damage
potion-effects-opponent:
SPEED:
duration: 3
chance: "20 * {level}"
amplifier: 2
#Spawned when hit or when you strike an enemy in case of tools
mobs:
ZOMBIE:
max-amount: 3
spawn-percentage: 20
armor-drop-chance: 0
health: 20
attack-damage: 2
hostile: true
display-name: "&cAngry guy"
equipment:
helmet:
material: DIAMOND_HELMET
enchants:
- "DURABILITY:3"
- "THORNS:2"
chestplate:
material: DIAMOND_CHESTPLATE
enchants:
- "DURABILITY:3"
- "THORNS:2"
leggings:
material: DIAMOND_LEGGINGS
enchants:
- "DURABILITY:3"
- "THORNS:2"
boots:
material: DIAMOND_BOOTS
enchants:
- "DURABILITY:3"
- "THORNS:2"

View File

@ -4,7 +4,8 @@ general.nametag.prefix= "&8[&6EpicEnchants&8]"
#Command Messages
command.give.success= "&7You have been given a &6tier {tier} &7Book."
command.book.give= "&7You have been given a &6tier {tier} &7Book."
command.book.gave= "&7You gave {player} a &6tier {tier} &7Book."
#Event Messages
@ -18,3 +19,4 @@ enchant.invalidmaterial= "&cYou can not apply &6{enchant} to that item."
enchant.failure= "&cYou failed to apply &6{enchant}."
enchant.brokenfailure= "&6{enchant} failed to apply and broke your item..."
enchant.success= "&aYou have success fully applied &6{enchant}."
enchant.conflict= "&cYou cannot apply this enchant as it conflicts with another enchant."