Rewrote entire plugin around kotlin / libreforge

This commit is contained in:
Auxilor
2021-11-25 21:14:08 +00:00
parent 34fb92707d
commit a51f5b5720
52 changed files with 528 additions and 2329 deletions

View File

@@ -1,71 +0,0 @@
package com.willfp.ecoweapons;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.command.impl.PluginCommand;
import com.willfp.eco.core.display.DisplayModule;
import com.willfp.ecoweapons.commands.CommandEcoweapons;
import com.willfp.ecoweapons.config.EcoWeaponsJson;
import com.willfp.ecoweapons.display.WeaponsDisplay;
import com.willfp.ecoweapons.effects.Effect;
import com.willfp.ecoweapons.effects.Effects;
import com.willfp.ecoweapons.effects.util.EffectListener;
import com.willfp.ecoweapons.util.DiscoverRecipeListener;
import lombok.Getter;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
public class EcoWeaponsPlugin extends EcoPlugin {
/**
* Instance of EcoWeapons.
*/
@Getter
private static EcoWeaponsPlugin instance;
/**
* tiers.json.
*/
@Getter
private final EcoWeaponsJson ecoWeaponsJson;
/**
* Internal constructor called by bukkit on plugin load.
*/
public EcoWeaponsPlugin() {
super(1241, 12134, "&#ff0000");
instance = this;
this.ecoWeaponsJson = new EcoWeaponsJson(this);
}
@Override
protected void handleEnable() {
for (Effect effect : Effects.values()) {
if (effect instanceof Listener) {
this.getEventManager().registerListener((Listener) effect);
}
}
}
@Override
protected List<Listener> loadListeners() {
return Arrays.asList(
new EffectListener(),
new DiscoverRecipeListener(this)
);
}
@Override
protected List<PluginCommand> loadPluginCommands() {
return Arrays.asList(
new CommandEcoweapons(this)
);
}
@Override
protected @Nullable DisplayModule createDisplayModule() {
return new WeaponsDisplay(this);
}
}

View File

@@ -1,28 +0,0 @@
package com.willfp.ecoweapons.commands;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.command.CommandHandler;
import com.willfp.eco.core.command.impl.PluginCommand;
import org.jetbrains.annotations.NotNull;
public class CommandEcoweapons extends PluginCommand {
/**
* Instantiate a new command handler.
*
* @param plugin The plugin for the commands to listen for.
*/
public CommandEcoweapons(@NotNull final EcoPlugin plugin) {
super(plugin, "ecoweapons", "ecoweapons.command.ecoweapons", false);
this.addSubcommand(new CommandReload(plugin))
.addSubcommand(new CommandGive(plugin));
}
@Override
public CommandHandler getHandler() {
return (sender, args) -> {
sender.sendMessage(this.getPlugin().getLangYml().getMessage("invalid-command"));
};
}
}

View File

@@ -1,144 +0,0 @@
package com.willfp.ecoweapons.commands;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.command.CommandHandler;
import com.willfp.eco.core.command.TabCompleteHandler;
import com.willfp.eco.core.command.impl.Subcommand;
import com.willfp.eco.core.config.updating.ConfigUpdater;
import com.willfp.ecoweapons.weapons.Weapon;
import com.willfp.ecoweapons.weapons.Weapons;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class CommandGive extends Subcommand {
/**
* The cached names.
*/
private static final List<String> ITEM_NAMES = new ArrayList<>();
/**
* The cached numbers.
*/
private static final List<String> NUMBERS = Arrays.asList(
"1",
"2",
"3",
"4",
"5",
"10",
"32",
"64"
);
/**
* Instantiate a new command handler.
*
* @param plugin The plugin for the commands to listen for.
*/
public CommandGive(@NotNull final EcoPlugin plugin) {
super(plugin, "give", "ecoweapons.command.give", false);
reload();
}
/**
* Called on reload.
*/
@ConfigUpdater
public static void reload() {
ITEM_NAMES.clear();
ITEM_NAMES.addAll(Weapons.values().stream().map(Weapon::getName).collect(Collectors.toList()));
}
@Override
public CommandHandler getHandler() {
return (sender, args) -> {
if (args.isEmpty()) {
sender.sendMessage(this.getPlugin().getLangYml().getMessage("needs-player"));
return;
}
if (args.size() == 1) {
sender.sendMessage(this.getPlugin().getLangYml().getMessage("needs-item"));
return;
}
String recieverName = args.get(0);
Player reciever = Bukkit.getPlayer(recieverName);
if (reciever == null) {
sender.sendMessage(this.getPlugin().getLangYml().getMessage("invalid-player"));
return;
}
String itemID = args.get(1);
int amount = 1;
Weapon weapon = Weapons.getByName(itemID.toLowerCase());
if (weapon == null) {
sender.sendMessage(this.getPlugin().getLangYml().getMessage("invalid-item"));
return;
}
String message = this.getPlugin().getLangYml().getMessage("give-success");
message = message.replace("%item%", weapon.getName()).replace("%recipient%", reciever.getName());
sender.sendMessage(message);
if (args.size() == 3) {
try {
amount = Integer.parseInt(args.get(2));
} catch (NumberFormatException ignored) {
// do nothing
}
}
ItemStack item = weapon.getItem();
item.setAmount(amount);
reciever.getInventory().addItem(item);
};
}
@Override
public TabCompleteHandler getTabCompleter() {
return (sender, args) -> {
List<String> completions = new ArrayList<>();
if (args.isEmpty()) {
// Currently, this case is not ever reached
return ITEM_NAMES;
}
if (args.size() == 1) {
StringUtil.copyPartialMatches(args.get(0), Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList()), completions);
return completions;
}
if (args.size() == 2) {
StringUtil.copyPartialMatches(args.get(1), ITEM_NAMES, completions);
Collections.sort(completions);
return completions;
}
if (args.size() == 3) {
StringUtil.copyPartialMatches(args.get(2), NUMBERS, completions);
return completions;
}
return new ArrayList<>(0);
};
}
}

View File

@@ -1,26 +0,0 @@
package com.willfp.ecoweapons.commands;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.command.CommandHandler;
import com.willfp.eco.core.command.impl.Subcommand;
import org.jetbrains.annotations.NotNull;
public class CommandReload extends Subcommand {
/**
* Instantiate a new command handler.
*
* @param plugin The plugin for the commands to listen for.
*/
public CommandReload(@NotNull final EcoPlugin plugin) {
super(plugin, "reload", "ecoweapons.command.reload", false);
}
@Override
public CommandHandler getHandler() {
return (sender, args) -> {
this.getPlugin().reload();
sender.sendMessage(this.getPlugin().getLangYml().getMessage("reloaded"));
};
}
}

View File

@@ -1,56 +0,0 @@
package com.willfp.ecoweapons.conditions;
import com.willfp.ecoweapons.EcoWeaponsPlugin;
import lombok.AccessLevel;
import lombok.Getter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public abstract class Condition<T> {
/**
* Instance of EcoWeapons.
*/
@Getter(AccessLevel.PROTECTED)
private final EcoWeaponsPlugin plugin = EcoWeaponsPlugin.getInstance();
/**
* The name of the effect.
*/
@Getter
private final String name;
/**
* The class of the config getter type.
*/
@Getter
private final Class<T> typeClass;
/**
* Create a new condition.
*
* @param name The condition name.
* @param typeClass The class of the config type.
*/
protected Condition(@NotNull final String name,
@NotNull final Class<T> typeClass) {
this.name = name;
this.typeClass = typeClass;
Conditions.addNewCondition(this);
}
/**
* Get if condition is met for a player.
*
* @param player The player.
* @param value The value of the condition.
* @return If met.
*/
public final boolean isMet(@NotNull final Player player,
@NotNull final Object value) {
return isConditionMet(player, typeClass.cast(value));
}
protected abstract boolean isConditionMet(@NotNull Player player,
@NotNull T value);
}

View File

@@ -1,72 +0,0 @@
package com.willfp.ecoweapons.conditions;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableList;
import com.willfp.ecoweapons.conditions.conditions.ConditionAboveHealthPercent;
import com.willfp.ecoweapons.conditions.conditions.ConditionAboveHungerPercent;
import com.willfp.ecoweapons.conditions.conditions.ConditionAboveXPLevel;
import com.willfp.ecoweapons.conditions.conditions.ConditionAboveY;
import com.willfp.ecoweapons.conditions.conditions.ConditionBelowHealthPercent;
import com.willfp.ecoweapons.conditions.conditions.ConditionBelowHungerPercent;
import com.willfp.ecoweapons.conditions.conditions.ConditionBelowXPLevel;
import com.willfp.ecoweapons.conditions.conditions.ConditionBelowY;
import com.willfp.ecoweapons.conditions.conditions.ConditionHasPermission;
import com.willfp.ecoweapons.conditions.conditions.ConditionInBiome;
import com.willfp.ecoweapons.conditions.conditions.ConditionInWater;
import com.willfp.ecoweapons.conditions.conditions.ConditionInWorld;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@UtilityClass
@SuppressWarnings("unused")
public class Conditions {
/**
* All registered effects.
*/
private static final BiMap<String, Condition<?>> BY_NAME = HashBiMap.create();
public static final Condition<?> BELOW_Y = new ConditionBelowY();
public static final Condition<?> ABOVE_Y = new ConditionAboveY();
public static final Condition<?> ABOVE_HEALTH_PERCENT = new ConditionAboveHealthPercent();
public static final Condition<?> BELOW_HEALTH_PERCENT = new ConditionBelowHealthPercent();
public static final Condition<?> IN_WATER = new ConditionInWater();
public static final Condition<?> IN_WORLD = new ConditionInWorld();
public static final Condition<?> ABOVE_XP_LEVEL = new ConditionAboveXPLevel();
public static final Condition<?> BELOW_XP_LEVEL = new ConditionBelowXPLevel();
public static final Condition<?> ABOVE_HUNGER_PERCENT = new ConditionAboveHungerPercent();
public static final Condition<?> BELOW_HUNGER_PERCENT = new ConditionBelowHungerPercent();
public static final Condition<?> IN_BIOME = new ConditionInBiome();
public static final Condition<?> HAS_PERMISSION = new ConditionHasPermission();
/**
* Get condition matching name.s
*
* @param name The name to query.
* @return The matching condition, or null if not found.
*/
public static Condition<?> getByName(@NotNull final String name) {
return BY_NAME.get(name);
}
/**
* List of all registered conditions.
*
* @return The conditions.
*/
public static List<Condition<?>> values() {
return ImmutableList.copyOf(BY_NAME.values());
}
/**
* Add new condition to EcoWeapons.
*
* @param condition The condition to add.
*/
public static void addNewCondition(@NotNull final Condition<?> condition) {
BY_NAME.remove(condition.getName());
BY_NAME.put(condition.getName(), condition);
}
}

View File

@@ -1,21 +0,0 @@
package com.willfp.ecoweapons.conditions.conditions;
import com.willfp.ecoweapons.conditions.Condition;
import org.bukkit.attribute.Attribute;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class ConditionAboveHealthPercent extends Condition<Double> {
public ConditionAboveHealthPercent() {
super("above-health-percent", Double.class);
}
@Override
public boolean isConditionMet(@NotNull final Player player,
@NotNull final Double value) {
double maxHealth = player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
double health = player.getHealth();
return (health / maxHealth) * 100 >= value;
}
}

View File

@@ -1,20 +0,0 @@
package com.willfp.ecoweapons.conditions.conditions;
import com.willfp.ecoweapons.conditions.Condition;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class ConditionAboveHungerPercent extends Condition<Double> {
public ConditionAboveHungerPercent() {
super("above-hunger-percent", Double.class);
}
@Override
public boolean isConditionMet(@NotNull final Player player,
@NotNull final Double value) {
double maxFood = 20;
double food = player.getFoodLevel();
return (food / maxFood) * 100 >= value;
}
}

View File

@@ -1,17 +0,0 @@
package com.willfp.ecoweapons.conditions.conditions;
import com.willfp.ecoweapons.conditions.Condition;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class ConditionAboveXPLevel extends Condition<Integer> {
public ConditionAboveXPLevel() {
super("above-xp-level", Integer.class);
}
@Override
public boolean isConditionMet(@NotNull final Player player,
@NotNull final Integer value) {
return player.getLevel() >= value;
}
}

View File

@@ -1,17 +0,0 @@
package com.willfp.ecoweapons.conditions.conditions;
import com.willfp.ecoweapons.conditions.Condition;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class ConditionAboveY extends Condition<Double> {
public ConditionAboveY() {
super("above-y", Double.class);
}
@Override
public boolean isConditionMet(@NotNull final Player player,
@NotNull final Double value) {
return player.getLocation().getY() >= value;
}
}

View File

@@ -1,21 +0,0 @@
package com.willfp.ecoweapons.conditions.conditions;
import com.willfp.ecoweapons.conditions.Condition;
import org.bukkit.attribute.Attribute;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class ConditionBelowHealthPercent extends Condition<Double> {
public ConditionBelowHealthPercent() {
super("below-health-percent", Double.class);
}
@Override
public boolean isConditionMet(@NotNull final Player player,
@NotNull final Double value) {
double maxHealth = player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
double health = player.getHealth();
return (health / maxHealth) * 100 < value;
}
}

View File

@@ -1,20 +0,0 @@
package com.willfp.ecoweapons.conditions.conditions;
import com.willfp.ecoweapons.conditions.Condition;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class ConditionBelowHungerPercent extends Condition<Double> {
public ConditionBelowHungerPercent() {
super("below-hunger-percent", Double.class);
}
@Override
public boolean isConditionMet(@NotNull final Player player,
@NotNull final Double value) {
double maxFood = 20;
double food = player.getFoodLevel();
return (food / maxFood) * 100 < value;
}
}

View File

@@ -1,17 +0,0 @@
package com.willfp.ecoweapons.conditions.conditions;
import com.willfp.ecoweapons.conditions.Condition;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class ConditionBelowXPLevel extends Condition<Integer> {
public ConditionBelowXPLevel() {
super("below-xp-level", Integer.class);
}
@Override
public boolean isConditionMet(@NotNull final Player player,
@NotNull final Integer value) {
return player.getLevel() < value;
}
}

View File

@@ -1,17 +0,0 @@
package com.willfp.ecoweapons.conditions.conditions;
import com.willfp.ecoweapons.conditions.Condition;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class ConditionBelowY extends Condition<Double> {
public ConditionBelowY() {
super("below-y", Double.class);
}
@Override
public boolean isConditionMet(@NotNull final Player player,
@NotNull final Double value) {
return player.getLocation().getY() < value;
}
}

View File

@@ -1,17 +0,0 @@
package com.willfp.ecoweapons.conditions.conditions;
import com.willfp.ecoweapons.conditions.Condition;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class ConditionHasPermission extends Condition<String> {
public ConditionHasPermission() {
super("has-permission", String.class);
}
@Override
public boolean isConditionMet(@NotNull final Player player,
@NotNull final String value) {
return player.hasPermission(value);
}
}

View File

@@ -1,23 +0,0 @@
package com.willfp.ecoweapons.conditions.conditions;
import com.willfp.ecoweapons.conditions.Condition;
import org.bukkit.block.Biome;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
public class ConditionInBiome extends Condition<String> {
public ConditionInBiome() {
super("in-biome", String.class);
}
@Override
public boolean isConditionMet(@NotNull final Player player,
@NotNull final String value) {
List<String> biomeNames = Arrays.asList(value.toLowerCase().split(" "));
Biome biome = player.getLocation().getWorld().getBiome(player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ());
return biomeNames.contains(biome.name().toLowerCase());
}
}

View File

@@ -1,18 +0,0 @@
package com.willfp.ecoweapons.conditions.conditions;
import com.willfp.ecoweapons.conditions.Condition;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class ConditionInWater extends Condition<Boolean> {
public ConditionInWater() {
super("in-water", Boolean.class);
}
@Override
public boolean isConditionMet(@NotNull final Player player,
@NotNull final Boolean value) {
return (player.getLocation().getBlock().getType() == Material.WATER) == value;
}
}

View File

@@ -1,27 +0,0 @@
package com.willfp.ecoweapons.conditions.conditions;
import com.willfp.ecoweapons.conditions.Condition;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
public class ConditionInWorld extends Condition<String> {
public ConditionInWorld() {
super("in-world", String.class);
}
@Override
public boolean isConditionMet(@NotNull final Player player,
@NotNull final String value) {
List<String> worldNames = Arrays.asList(value.toLowerCase().split(" "));
World world = player.getLocation().getWorld();
if (world == null) {
return false;
}
return worldNames.contains(world.getName().toLowerCase());
}
}

View File

@@ -1,16 +0,0 @@
package com.willfp.ecoweapons.config;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.json.JSONStaticBaseConfig;
import org.jetbrains.annotations.NotNull;
public class EcoWeaponsJson extends JSONStaticBaseConfig {
/**
* Create tiers.json.
*
* @param plugin Instance of EcoWeapons.
*/
public EcoWeaponsJson(@NotNull final EcoPlugin plugin) {
super("ecoweapons", plugin);
}
}

View File

@@ -1,54 +0,0 @@
package com.willfp.ecoweapons.display;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.display.DisplayModule;
import com.willfp.eco.core.display.DisplayPriority;
import com.willfp.ecoweapons.weapons.Weapon;
import com.willfp.ecoweapons.weapons.util.WeaponUtils;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class WeaponsDisplay extends DisplayModule {
/**
* Create weapons display.
*
* @param plugin Instance of EcoWeapons.
*/
public WeaponsDisplay(@NotNull final EcoPlugin plugin) {
super(plugin, DisplayPriority.LOWEST);
}
@Override
public void display(@NotNull final ItemStack itemStack,
@NotNull final Object... args) {
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
return;
}
Weapon weapon = WeaponUtils.getWeaponFromItem(meta);
if (weapon == null) {
return;
}
ItemMeta weaponMeta = weapon.getItem().getItemMeta();
assert weaponMeta != null;
List<String> lore = new ArrayList<>(weaponMeta.getLore());
if (meta.hasLore()) {
lore.addAll(meta.getLore());
}
meta.setLore(lore);
meta.setDisplayName(weaponMeta.getDisplayName());
meta.addItemFlags(weaponMeta.getItemFlags().toArray(new ItemFlag[0]));
itemStack.setItemMeta(meta);
}
}

View File

@@ -1,171 +0,0 @@
package com.willfp.ecoweapons.effects;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.ecoweapons.EcoWeaponsPlugin;
import com.willfp.ecoweapons.weapons.Weapon;
import lombok.AccessLevel;
import lombok.Getter;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Sound;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.util.NumberConversions;
import org.bukkit.util.RayTraceResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public abstract class Effect {
/**
* Instance of EcoWeapons.
*/
@Getter(AccessLevel.PROTECTED)
private final EcoWeaponsPlugin plugin = EcoWeaponsPlugin.getInstance();
/**
* The name of the effect.
*/
@Getter
private final String name;
/**
* The cooldown end times linked to players.
*/
private final Map<UUID, Long> tracker = new HashMap<>();
/**
* Create a new effect.
*
* @param name The effect name.
*/
protected Effect(@NotNull final String name) {
this.name = name;
Effects.addNewEffect(this);
}
/**
* Handle {@link TriggerType#MELEE_ATTACK}.
*
* @param player The player.
* @param victim The victim.
* @param event The event.
* @param args The effect args.
*/
public void handleMeleeAttack(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final EntityDamageByEntityEvent event,
@NotNull final JSONConfig args) {
// Override when needed.
}
/**
* Handle {@link TriggerType#PROJECTILE_HIT_ENTITY}.
*
* @param player The player.
* @param victim The victim.
* @param projectile The projectile.
* @param event The event.
* @param args The effect args.
*/
public void handleProjectileHitEntity(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final Projectile projectile,
@NotNull final ProjectileHitEvent event,
@NotNull final JSONConfig args) {
// Override when needed.
}
/**
* Handle {@link TriggerType#PROJECTILE_HIT}.
*
* @param player The player.
* @param projectile The projectile.
* @param event The event.
* @param args The effect args.
*/
public void handleProjectileHit(@NotNull final Player player,
@NotNull final Projectile projectile,
@NotNull final ProjectileHitEvent event,
@NotNull final JSONConfig args) {
// Override when needed.
}
/**
* Handle {@link TriggerType#ALT_CLICK} and {@link TriggerType#SHIFT_ALT_CLICK}.
*
* @param player The player.
* @param blockRay The block ray.
* @param entityRay The entity ray.
* @param event The event.
* @param args The effect args.
*/
public void handleAltClick(@NotNull final Player player,
@NotNull final RayTraceResult blockRay,
@Nullable final RayTraceResult entityRay,
@NotNull final PlayerInteractEvent event,
@NotNull final JSONConfig args) {
// Override when needed.
}
/**
* Utility method to get a player's cooldown time of a specific effect.
*
* @param player The player to query.
* @return The time left in seconds before next use.
*/
public int getCooldown(@NotNull final Player player) {
if (!tracker.containsKey(player.getUniqueId())) {
return 0;
}
long msLeft = tracker.get(player.getUniqueId()) - System.currentTimeMillis();
long secondsLeft = (long) Math.ceil((double) msLeft / 1000);
return NumberConversions.toInt(secondsLeft);
}
/**
* Handle cooldowns.
*
* @param player The player.
* @param weapon The weapon.
* @param triggerType The trigger type.
* @return If the cooldown is over.
*/
public boolean isCooldownOver(@NotNull final Player player,
@NotNull final Weapon weapon,
@NotNull final TriggerType triggerType) {
int cooldown = getCooldown(player);
if (cooldown > 0) {
if (this.getPlugin().getConfigYml().getBool("cooldown-in-actionbar")) {
String message = this.getPlugin().getLangYml().getString("messages.on-cooldown").replace("%seconds%", String.valueOf(cooldown));
player.spigot().sendMessage(
ChatMessageType.ACTION_BAR,
TextComponent.fromLegacyText(message)
);
} else {
String message = this.getPlugin().getLangYml().getMessage("on-cooldown").replace("%seconds%", String.valueOf(cooldown));
player.sendMessage(message);
}
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 1, 0.5f);
return false;
} else {
tracker.remove(player.getUniqueId());
tracker.put(player.getUniqueId(), System.currentTimeMillis() + (long) ((weapon.getCooldownTime(this, triggerType) * 1000L)));
return true;
}
}
}

View File

@@ -1,66 +0,0 @@
package com.willfp.ecoweapons.effects;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableList;
import com.willfp.ecoweapons.effects.effects.EffectArrowStorm;
import com.willfp.ecoweapons.effects.effects.EffectBleed;
import com.willfp.ecoweapons.effects.effects.EffectConsoleCommand;
import com.willfp.ecoweapons.effects.effects.EffectGivePotionEffect;
import com.willfp.ecoweapons.effects.effects.EffectRailgun;
import com.willfp.ecoweapons.effects.effects.EffectSpawnHelper;
import com.willfp.ecoweapons.effects.effects.EffectStrikeLightning;
import com.willfp.ecoweapons.effects.effects.EffectWarp;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@UtilityClass
@SuppressWarnings("unused")
public class Effects {
/**
* All registered effects.
*/
private static final BiMap<String, Effect> BY_NAME = HashBiMap.create();
public static final Effect STRIKE_LIGHTNING = new EffectStrikeLightning();
public static final Effect RAILGUN = new EffectRailgun();
public static final Effect ARROW_STORM = new EffectArrowStorm();
public static final Effect WARP = new EffectWarp();
public static final Effect CONSOLE_COMMAND = new EffectConsoleCommand();
public static final Effect SPAWN_HELPER = new EffectSpawnHelper();
public static final Effect BLEED = new EffectBleed();
public static final Effect GIVE_POTION_EFFECT = new EffectGivePotionEffect();
/**
* Get effect matching name.
*
* @param name The name to query.
* @return The matching effect, or null if not found.
*/
@Nullable
public static Effect getByName(@NotNull final String name) {
return BY_NAME.get(name);
}
/**
* List of all registered effects.
*
* @return The effects.
*/
public static List<Effect> values() {
return ImmutableList.copyOf(BY_NAME.values());
}
/**
* Add new effect to EcoWeapons.
*
* @param effect The effect to add.
*/
public static void addNewEffect(@NotNull final Effect effect) {
BY_NAME.remove(effect.getName());
BY_NAME.put(effect.getName(), effect);
}
}

View File

@@ -1,47 +0,0 @@
package com.willfp.ecoweapons.effects;
import org.jetbrains.annotations.NotNull;
public enum TriggerType {
/**
* Secondary click.
*/
ALT_CLICK,
/**
* Melee attack.
*/
MELEE_ATTACK,
/**
* Projectile hit.
*/
PROJECTILE_HIT,
/**
* Shift Secondary Click.
*/
SHIFT_ALT_CLICK,
/**
* Projectile damage entity.
*/
PROJECTILE_HIT_ENTITY;
/**
* Get trigger type by name.
*
* @param name The name.
* @return The found type, or null if not found.
*/
public static TriggerType getByName(@NotNull final String name) {
return switch (name.toLowerCase()) {
case "alt_click" -> ALT_CLICK;
case "melee_attack" -> MELEE_ATTACK;
case "projectile_hit" -> PROJECTILE_HIT;
case "shift_alt_click" -> SHIFT_ALT_CLICK;
case "projectile_hit_entity" -> PROJECTILE_HIT_ENTITY;
default -> null;
};
}
}

View File

@@ -1,85 +0,0 @@
package com.willfp.ecoweapons.effects.effects;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.ecoweapons.effects.Effect;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.util.RayTraceResult;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class EffectArrowStorm extends Effect {
public EffectArrowStorm() {
super("arrow-storm");
}
@Override
public void handleMeleeAttack(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final EntityDamageByEntityEvent event,
@NotNull final JSONConfig args) {
handle(victim.getLocation(), args);
}
@Override
public void handleProjectileHitEntity(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final Projectile projectile,
@NotNull final ProjectileHitEvent event,
@NotNull final JSONConfig args) {
handle(victim.getLocation(), args);
}
@Override
public void handleProjectileHit(@NotNull final Player player,
@NotNull final Projectile projectile,
@NotNull final ProjectileHitEvent event,
@NotNull final JSONConfig args) {
handle(projectile.getLocation(), args);
}
@Override
public void handleAltClick(@NotNull final Player player,
@NotNull final RayTraceResult blockRay,
@Nullable final RayTraceResult entityRay,
@NotNull final PlayerInteractEvent event,
@NotNull final JSONConfig args) {
handle(blockRay.getHitPosition().toLocation(player.getWorld()), args);
}
private void handle(@NotNull final Location location,
@NotNull final JSONConfig args) {
int amount = args.getInt("amount");
double height = args.getDouble("height");
double radius = args.getDouble("radius");
Location apex = location.clone().add(0, height, 0);
World world = location.getWorld();
assert world != null;
double angle = (Math.PI * 2) / amount;
for (int i = 0; i < amount; i++) {
Location spawn = apex.clone();
spawn.add(
Math.sin(angle * i) * radius,
0,
Math.cos(angle * i) * radius
);
world.spawn(
spawn,
Arrow.class
).setVelocity(new Vector(0, -1, 0));
}
}
}

View File

@@ -1,56 +0,0 @@
package com.willfp.ecoweapons.effects.effects;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.ecoweapons.effects.Effect;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.atomic.AtomicInteger;
public class EffectBleed extends Effect implements Listener {
public EffectBleed() {
super("bleed");
}
@Override
public void handleMeleeAttack(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final EntityDamageByEntityEvent event,
@NotNull final JSONConfig args) {
handle(player, victim, args);
}
@Override
public void handleProjectileHitEntity(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final Projectile projectile,
@NotNull final ProjectileHitEvent event,
@NotNull final JSONConfig args) {
handle(player, victim, args);
}
private void handle(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final JSONConfig args) {
double bleedDamage = args.getDouble("damage");
int bleedCount = args.getInt("amount");
AtomicInteger currentBleedCount = new AtomicInteger(0);
this.getPlugin().getRunnableFactory().create(bukkitRunnable -> {
currentBleedCount.addAndGet(1);
victim.damage(bleedDamage);
if (currentBleedCount.get() >= bleedCount) {
bukkitRunnable.cancel();
}
}).runTaskTimer(0, 10);
}
}

View File

@@ -1,66 +0,0 @@
package com.willfp.ecoweapons.effects.effects;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.ecoweapons.effects.Effect;
import org.bukkit.Bukkit;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.util.RayTraceResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class EffectConsoleCommand extends Effect {
public EffectConsoleCommand() {
super("console-command");
}
@Override
public void handleMeleeAttack(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final EntityDamageByEntityEvent event,
@NotNull final JSONConfig args) {
Bukkit.getServer().dispatchCommand(
Bukkit.getConsoleSender(),
args.getString("command", false).replace("%player%", player.getName())
);
}
@Override
public void handleProjectileHitEntity(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final Projectile projectile,
@NotNull final ProjectileHitEvent event,
@NotNull final JSONConfig args) {
Bukkit.getServer().dispatchCommand(
Bukkit.getConsoleSender(),
args.getString("command", false).replace("%player%", player.getName())
);
}
@Override
public void handleProjectileHit(@NotNull final Player player,
@NotNull final Projectile projectile,
@NotNull final ProjectileHitEvent event,
@NotNull final JSONConfig args) {
Bukkit.getServer().dispatchCommand(
Bukkit.getConsoleSender(),
args.getString("command", false).replace("%player%", player.getName())
);
}
@Override
public void handleAltClick(@NotNull final Player player,
@NotNull final RayTraceResult blockRay,
@Nullable final RayTraceResult entityRay,
@NotNull final PlayerInteractEvent event,
@NotNull final JSONConfig args) {
Bukkit.getServer().dispatchCommand(
Bukkit.getConsoleSender(),
args.getString("command", false).replace("%player%", player.getName())
);
}
}

View File

@@ -1,64 +0,0 @@
package com.willfp.ecoweapons.effects.effects;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.ecoweapons.effects.Effect;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
public class EffectGivePotionEffect extends Effect implements Listener {
public EffectGivePotionEffect() {
super("give-potion-effect");
}
@Override
public void handleMeleeAttack(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final EntityDamageByEntityEvent event,
@NotNull final JSONConfig args) {
handle(player, victim, args);
}
@Override
public void handleProjectileHitEntity(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final Projectile projectile,
@NotNull final ProjectileHitEvent event,
@NotNull final JSONConfig args) {
handle(player, victim, args);
}
private void handle(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final JSONConfig args) {
PotionEffectType type = PotionEffectType.getByName(args.getString("potion").toUpperCase());
int duration = args.getInt("duration");
int strength = args.getInt("strength") - 1;
if (args.getString("target").equalsIgnoreCase("player")) {
player.addPotionEffect(
new PotionEffect(
type,
duration,
strength
)
);
} else {
victim.addPotionEffect(
new PotionEffect(
type,
duration,
strength
)
);
}
}
}

View File

@@ -1,68 +0,0 @@
package com.willfp.ecoweapons.effects.effects;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.ecoweapons.effects.Effect;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.util.RayTraceResult;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class EffectRailgun extends Effect {
public EffectRailgun() {
super("railgun");
}
@Override
public void handleAltClick(@NotNull final Player player,
@NotNull final RayTraceResult blockRay,
@Nullable final RayTraceResult entityRay,
@NotNull final PlayerInteractEvent event,
@NotNull final JSONConfig args) {
double damage = args.getDouble("damage");
Particle particle = Particle.valueOf(args.getString("particle", false).toUpperCase());
player.playSound(player.getLocation(), Sound.valueOf(args.getString("sound", false).toUpperCase()), 1, 1);
showBeam(player.getLocation().add(0, player.getEyeHeight(), 0), blockRay, particle);
if (entityRay.getHitEntity() instanceof LivingEntity victim) {
if (victim.equals(player)) {
return;
}
victim.damage(damage, player);
} else {
Location location = blockRay.getHitPosition().toLocation(player.getWorld());
assert location.getWorld() != null;
for (Entity nearbyEntity : location.getWorld().getNearbyEntities(location, 2, 2, 2)) {
if (nearbyEntity instanceof LivingEntity livingEntity) {
livingEntity.damage(damage, player);
}
}
}
}
private void showBeam(@NotNull final Location playerLoc,
@NotNull final RayTraceResult rayTrace,
@NotNull final Particle particle) {
Vector ray = rayTrace.getHitPosition().clone().subtract(playerLoc.toVector());
Vector raySegment = ray.clone().normalize();
Location pos = playerLoc.clone();
World world = pos.getWorld();
assert world != null;
double rayLength = ray.length();
for (int i = 0; i < rayLength; i++) {
pos.add(raySegment);
world.spawnParticle(particle, pos, 1, 0, 0, 0, 0, null, true);
}
}
}

View File

@@ -1,122 +0,0 @@
package com.willfp.ecoweapons.effects.effects;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.util.NumberUtils;
import com.willfp.ecoweapons.effects.Effect;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.attribute.Attribute;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Mob;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
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.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.util.RayTraceResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class EffectSpawnHelper extends Effect implements Listener {
public EffectSpawnHelper() {
super("spawn-helper");
}
@Override
public void handleMeleeAttack(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final EntityDamageByEntityEvent event,
@NotNull final JSONConfig args) {
doSpawn(victim, victim.getLocation(), args);
}
@Override
public void handleProjectileHitEntity(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final Projectile projectile,
@NotNull final ProjectileHitEvent event,
@NotNull final JSONConfig args) {
doSpawn(victim, victim.getLocation(), args);
}
@Override
public void handleProjectileHit(@NotNull final Player player,
@NotNull final Projectile projectile,
@NotNull final ProjectileHitEvent event,
@NotNull final JSONConfig args) {
doSpawn(null, projectile.getLocation(), args);
}
@Override
public void handleAltClick(@NotNull final Player player,
@NotNull final RayTraceResult blockRay,
@Nullable final RayTraceResult entityRay,
@NotNull final PlayerInteractEvent event,
@NotNull final JSONConfig args) {
doSpawn(entityRay.getHitEntity(), blockRay.getHitPosition().toLocation(player.getWorld()), args);
}
private void doSpawn(@Nullable final Entity victim,
@NotNull final Location location,
@NotNull final JSONConfig args) {
if (victim != null) {
if (!victim.getMetadata("eco-target").isEmpty()) {
return;
}
}
World world = location.getWorld();
assert world != null;
int toSpawn = args.getInt("amount");
int ticksToLive = args.getInt("ticks-to-live");
double health = args.getDouble("health");
double range = args.getDouble("range");
EntityType entityType = EntityType.valueOf(args.getString("entity").toUpperCase());
for (int i = 0; i < toSpawn; i++) {
Location locToSpawn = location.clone().add(NumberUtils.randFloat(-range, range), NumberUtils.randFloat(0, range), NumberUtils.randFloat(-range, range));
Mob entity = (Mob) world.spawnEntity(locToSpawn, entityType);
if (victim instanceof LivingEntity) {
entity.setTarget((LivingEntity) victim);
}
if (health > entity.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()) {
health = entity.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
}
entity.setHealth(health);
if (victim != null) {
entity.setMetadata("eco-target", this.getPlugin().getMetadataValueFactory().create(victim));
}
this.getPlugin().getScheduler().runLater(entity::remove, ticksToLive);
}
}
@EventHandler
public void onSwitchTarget(@NotNull final EntityTargetEvent event) {
if (event.getEntity().getMetadata("eco-target").isEmpty()) {
return;
}
LivingEntity target = (LivingEntity) event.getEntity().getMetadata("eco-target").get(0).value();
event.setTarget(target);
}
@EventHandler(priority = EventPriority.LOW)
public void onDropItem(@NotNull final EntityDeathEvent event) {
if (event.getEntity().getMetadata("eco-target").isEmpty()) {
return;
}
event.getDrops().clear();
event.setDroppedExp(0);
}
}

View File

@@ -1,67 +0,0 @@
package com.willfp.ecoweapons.effects.effects;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.ecoweapons.effects.Effect;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.util.RayTraceResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class EffectStrikeLightning extends Effect {
public EffectStrikeLightning() {
super("strike-lightning");
}
@Override
public void handleMeleeAttack(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final EntityDamageByEntityEvent event,
@NotNull final JSONConfig args) {
handle(victim.getLocation(), args);
}
@Override
public void handleProjectileHit(@NotNull final Player player,
@NotNull final Projectile projectile,
@NotNull final ProjectileHitEvent event,
@NotNull final JSONConfig args) {
handle(projectile.getLocation(), args);
}
@Override
public void handleProjectileHitEntity(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final Projectile projectile,
@NotNull final ProjectileHitEvent event,
@NotNull final JSONConfig args) {
handle(victim.getLocation(), args);
}
@Override
public void handleAltClick(@NotNull final Player player,
@NotNull final RayTraceResult blockRay,
@Nullable final RayTraceResult entityRay,
@NotNull final PlayerInteractEvent event,
@NotNull final JSONConfig args) {
handle(entityRay.getHitPosition().toLocation(player.getWorld()), args);
}
private void handle(@NotNull final Location location,
@NotNull final JSONConfig args) {
World world = location.getWorld();
assert world != null;
for (int i = 0; i < args.getDouble("amount"); i++) {
this.getPlugin().getScheduler().runLater(() -> {
world.strikeLightning(location);
}, i);
}
}
}

View File

@@ -1,60 +0,0 @@
package com.willfp.ecoweapons.effects.effects;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.ecoweapons.effects.Effect;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.util.RayTraceResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class EffectWarp extends Effect {
public EffectWarp() {
super("warp");
}
@Override
public void handleMeleeAttack(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final EntityDamageByEntityEvent event,
@NotNull final JSONConfig args) {
handle(player, victim.getLocation(), args);
}
@Override
public void handleProjectileHitEntity(@NotNull final Player player,
@NotNull final LivingEntity victim,
@NotNull final Projectile projectile,
@NotNull final ProjectileHitEvent event,
@NotNull final JSONConfig args) {
handle(player, victim.getLocation(), args);
}
@Override
public void handleProjectileHit(@NotNull final Player player,
@NotNull final Projectile projectile,
@NotNull final ProjectileHitEvent event,
@NotNull final JSONConfig args) {
handle(player, projectile.getLocation(), args);
}
@Override
public void handleAltClick(@NotNull final Player player,
@NotNull final RayTraceResult blockRay,
@Nullable final RayTraceResult entityRay,
@NotNull final PlayerInteractEvent event,
@NotNull final JSONConfig args) {
handle(player, blockRay.getHitPosition().toLocation(player.getWorld()), args);
}
private void handle(@NotNull final Player player,
@NotNull final Location location,
@NotNull final JSONConfig args) {
player.teleport(location);
}
}

View File

@@ -1,282 +0,0 @@
package com.willfp.ecoweapons.effects.util;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.integrations.antigrief.AntigriefManager;
import com.willfp.eco.util.ArrowUtils;
import com.willfp.eco.util.NumberUtils;
import com.willfp.ecoweapons.effects.Effect;
import com.willfp.ecoweapons.effects.TriggerType;
import com.willfp.ecoweapons.weapons.Weapon;
import com.willfp.ecoweapons.weapons.util.WeaponUtils;
import org.bukkit.FluidCollisionMode;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.World;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Trident;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.RayTraceResult;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class EffectListener implements Listener {
/**
* Items that must be left-clicked to activate spells for.
*/
private static final List<Material> LEFT_CLICK_ITEMS = Arrays.asList(
Material.FISHING_ROD,
Material.BOW,
Material.CROSSBOW,
Material.TRIDENT
);
/**
* Items that don't cause spells to activate when right clicked.
*/
private static final List<Material> BLACKLIST_CLICKED_BLOCKS = new ArrayList<>(Arrays.asList(
Material.CRAFTING_TABLE,
Material.GRINDSTONE,
Material.ENCHANTING_TABLE,
Material.FURNACE,
Material.SMITHING_TABLE,
Material.LEVER,
Material.REPEATER,
Material.COMPARATOR,
Material.RESPAWN_ANCHOR,
Material.NOTE_BLOCK,
Material.ITEM_FRAME,
Material.CHEST,
Material.BARREL,
Material.BEACON,
Material.LECTERN,
Material.FLETCHING_TABLE,
Material.SMITHING_TABLE,
Material.STONECUTTER,
Material.SMOKER,
Material.BLAST_FURNACE,
Material.BREWING_STAND,
Material.DISPENSER,
Material.DROPPER
));
static {
BLACKLIST_CLICKED_BLOCKS.addAll(Tag.BUTTONS.getValues());
BLACKLIST_CLICKED_BLOCKS.addAll(Tag.BEDS.getValues());
BLACKLIST_CLICKED_BLOCKS.addAll(Tag.DOORS.getValues());
BLACKLIST_CLICKED_BLOCKS.addAll(Tag.FENCE_GATES.getValues());
BLACKLIST_CLICKED_BLOCKS.addAll(Tag.TRAPDOORS.getValues());
BLACKLIST_CLICKED_BLOCKS.addAll(Tag.ANVIL.getValues());
BLACKLIST_CLICKED_BLOCKS.addAll(Tag.SHULKER_BOXES.getValues());
}
/**
* Handle {@link TriggerType#MELEE_ATTACK}.
*
* @param event The event.
*/
@EventHandler(
ignoreCancelled = true
)
public void meleeAttackListener(@NotNull final EntityDamageByEntityEvent event) {
if (!(event.getDamager() instanceof Player player)) {
return;
}
if (!(event.getEntity() instanceof LivingEntity victim)) {
return;
}
Weapon weapon = WeaponUtils.getWeaponFromItem(player.getInventory().getItemInMainHand());
if (weapon == null) {
return;
}
if (!WeaponUtils.areConditionsMet(player, weapon)) {
return;
}
for (Effect effect : weapon.getEffects(TriggerType.MELEE_ATTACK)) {
if (AntigriefManager.canInjure(player, victim)) {
if (effect.isCooldownOver(player, weapon, TriggerType.MELEE_ATTACK)) {
JSONConfig args = weapon.getEffectArgs(effect, TriggerType.MELEE_ATTACK);
Double chance = args.getDoubleOrNull("chance");
if (chance != null) {
if (NumberUtils.randInt(0, 100) > chance) {
continue;
}
}
effect.handleMeleeAttack(player, victim, event, args);
}
}
}
}
/**
* Handle {@link TriggerType#PROJECTILE_HIT} and {@link TriggerType#PROJECTILE_HIT_ENTITY}.
*
* @param event The event.
*/
@EventHandler(
ignoreCancelled = true
)
public void projectileHitListener(@NotNull final ProjectileHitEvent event) {
if (!(event.getEntity() instanceof Trident || event.getEntity() instanceof Arrow)) {
return;
}
ItemStack item;
if (event.getEntity() instanceof Trident trident) {
item = trident.getItem();
} else {
item = ArrowUtils.getBow((Arrow) event.getEntity());
}
if (item == null) {
return;
}
if (!(event.getEntity().getShooter() instanceof Player player)) {
return;
}
Weapon weapon = WeaponUtils.getWeaponFromItem(item);
if (weapon == null) {
return;
}
if (!WeaponUtils.areConditionsMet(player, weapon)) {
return;
}
if (event.getHitEntity() == null) {
for (Effect effect : weapon.getEffects(TriggerType.PROJECTILE_HIT)) {
if (effect.isCooldownOver(player, weapon, TriggerType.PROJECTILE_HIT)) {
JSONConfig args = weapon.getEffectArgs(effect, TriggerType.PROJECTILE_HIT);
Double chance = args.getDoubleOrNull("chance");
if (chance != null) {
if (NumberUtils.randInt(0, 100) > chance) {
continue;
}
}
effect.handleProjectileHit(player, event.getEntity(), event, args);
}
}
} else {
if (event.getHitEntity() instanceof LivingEntity victim) {
for (Effect effect : weapon.getEffects(TriggerType.PROJECTILE_HIT_ENTITY)) {
if (AntigriefManager.canInjure(player, victim)) {
if (effect.isCooldownOver(player, weapon, TriggerType.PROJECTILE_HIT_ENTITY)) {
JSONConfig args = weapon.getEffectArgs(effect, TriggerType.PROJECTILE_HIT_ENTITY);
Double chance = args.getDoubleOrNull("chance");
if (chance != null) {
if (NumberUtils.randInt(0, 100) > chance) {
continue;
}
}
effect.handleProjectileHitEntity(player, victim, event.getEntity(), event, args);
}
}
}
}
}
}
/**
* Handle {@link TriggerType#ALT_CLICK} and {@link TriggerType#SHIFT_ALT_CLICK}.
*
* @param event The event.
*/
@EventHandler
public void altClickListener(@NotNull final PlayerInteractEvent event) {
Player player = event.getPlayer();
ItemStack itemStack = player.getInventory().getItemInMainHand();
Weapon weapon = WeaponUtils.getWeaponFromItem(itemStack);
if (weapon == null) {
return;
}
if (LEFT_CLICK_ITEMS.contains(itemStack.getType())) {
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
return;
}
} else {
if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) {
return;
}
}
if (event.getClickedBlock() != null) {
if (BLACKLIST_CLICKED_BLOCKS.contains(event.getClickedBlock().getType())) {
return;
}
}
if (!WeaponUtils.areConditionsMet(player, weapon)) {
return;
}
RayTraceResult result = player.rayTraceBlocks(50, FluidCollisionMode.NEVER);
if (result == null) {
return;
}
World world = player.getLocation().getWorld();
assert world != null;
RayTraceResult entityResult = world.rayTraceEntities(
player.getEyeLocation(),
player.getEyeLocation().getDirection(),
50,
3,
entity -> entity instanceof LivingEntity
);
if (player.isSneaking()) {
for (Effect effect : weapon.getEffects(TriggerType.SHIFT_ALT_CLICK)) {
if (effect.isCooldownOver(player, weapon, TriggerType.SHIFT_ALT_CLICK)) {
JSONConfig args = weapon.getEffectArgs(effect, TriggerType.SHIFT_ALT_CLICK);
Double chance = args.getDoubleOrNull("chance");
if (chance != null) {
if (NumberUtils.randInt(0, 100) > chance) {
continue;
}
}
effect.handleAltClick(player, result, entityResult, event, args);
}
}
} else {
for (Effect effect : weapon.getEffects(TriggerType.ALT_CLICK)) {
if (effect.isCooldownOver(player, weapon, TriggerType.ALT_CLICK)) {
JSONConfig args = weapon.getEffectArgs(effect, TriggerType.ALT_CLICK);
Double chance = args.getDoubleOrNull("chance");
if (chance != null) {
if (NumberUtils.randInt(0, 100) > chance) {
continue;
}
}
effect.handleAltClick(player, result, entityResult, event, args);
}
}
}
}
}

View File

@@ -1,46 +0,0 @@
package com.willfp.ecoweapons.util;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginDependent;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ShapedRecipe;
import org.jetbrains.annotations.NotNull;
public class DiscoverRecipeListener extends PluginDependent<EcoPlugin> implements Listener {
/**
* Register listener.
*
* @param plugin Talismans.
*/
public DiscoverRecipeListener(@NotNull final EcoPlugin plugin) {
super(plugin);
}
/**
* Unlock all recipes on player join.
*
* @param event The event to listen for.
*/
@EventHandler
public void onJoin(@NotNull final PlayerJoinEvent event) {
Player player = event.getPlayer();
if (this.getPlugin().getConfigYml().getBool("discover-recipes")) {
Bukkit.getServer().recipeIterator().forEachRemaining(recipe -> {
if (recipe instanceof ShapedRecipe) {
NamespacedKey key = ((ShapedRecipe) recipe).getKey();
if (key.getNamespace().equals("ecoweapons")) {
if (!key.getKey().contains("displayed")) {
player.discoverRecipe(key);
}
}
}
});
}
}
}

View File

@@ -1,244 +0,0 @@
package com.willfp.ecoweapons.weapons;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.display.Display;
import com.willfp.eco.core.items.CustomItem;
import com.willfp.eco.core.items.builder.ItemBuilder;
import com.willfp.eco.core.items.builder.ItemStackBuilder;
import com.willfp.eco.core.recipe.Recipes;
import com.willfp.eco.util.NumberUtils;
import com.willfp.ecoweapons.conditions.Condition;
import com.willfp.ecoweapons.conditions.Conditions;
import com.willfp.ecoweapons.effects.Effect;
import com.willfp.ecoweapons.effects.Effects;
import com.willfp.ecoweapons.effects.TriggerType;
import com.willfp.ecoweapons.weapons.util.WeaponUtils;
import lombok.AccessLevel;
import lombok.Getter;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeModifier;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
@SuppressWarnings("unchecked")
public class Weapon {
/**
* Instance of EcoWeapons.
*/
@Getter(AccessLevel.PRIVATE)
private final EcoPlugin plugin;
/**
* The config of the weapon.
*/
@Getter(AccessLevel.PRIVATE)
private final JSONConfig config;
/**
* The name of the weapon.
*/
@Getter
private final String name;
/**
* Conditions and their values.
*/
@Getter
private final Map<Condition<?>, Object> conditions = new HashMap<>();
/**
* Effects and their strengths.
*/
private final Map<TriggerType, Map<Effect, JSONConfig>> effects = new HashMap<>();
/**
* Weapon item.
*/
@Getter
private final ItemStack item;
/**
* Create a new weapon.
*
* @param config The weapons's config.
* @param plugin Instance of EcoWeapons.
*/
public Weapon(@NotNull final JSONConfig config,
@NotNull final EcoPlugin plugin) {
this.config = config;
this.plugin = plugin;
this.name = config.getString("name");
for (JSONConfig cfg : this.getConfig().getSubsections("conditions")) {
Condition<?> effect = Conditions.getByName(cfg.getString("id"));
Object value = cfg.get("args");
conditions.put(effect, value);
}
for (JSONConfig cfg : this.getConfig().getSubsections("effects")) {
Effect effect = Effects.getByName(cfg.getString("id"));
if (effect == null) {
this.getPlugin().getLogger().warning("Invalid effect " + cfg.getString("id") + " specified in " + this.getName());
continue;
}
JSONConfig value = (JSONConfig) cfg.getSubsection("args");
TriggerType triggerType = TriggerType.getByName(cfg.getString("trigger"));
effects.computeIfAbsent(triggerType, k -> new HashMap<>());
Map<Effect, JSONConfig> triggerEffects = effects.get(triggerType);
triggerEffects.put(effect, value);
effects.put(triggerType, triggerEffects);
}
for (TriggerType value : TriggerType.values()) {
if (!effects.containsKey(value)) {
effects.put(value, new HashMap<>());
}
}
item = construct((JSONConfig) this.getConfig().getSubsection("item"));
}
private ItemStack construct(@NotNull final JSONConfig itemConfig) {
Material material = Material.getMaterial(itemConfig.getString("material").toUpperCase());
assert material != null;
ItemBuilder builder = new ItemStackBuilder(material);
builder.setDisplayName(itemConfig.getString("displayName"))
.addItemFlag(
itemConfig.getStrings("flags").stream()
.map(s -> ItemFlag.valueOf(s.toUpperCase()))
.toArray(ItemFlag[]::new)
)
.setUnbreakable(itemConfig.getBool("unbreakable"))
.addLoreLines(itemConfig.getStrings("lore").stream().map(s -> Display.PREFIX + s).collect(Collectors.toList()))
.setCustomModelData(() -> {
int data = itemConfig.getInt("customModelData");
return data != -1 ? data : null;
})
.writeMetaKey(
this.getPlugin().getNamespacedKeyFactory().create("weapon"),
PersistentDataType.STRING,
name
);
Map<Enchantment, Integer> enchants = new HashMap<>();
for (JSONConfig enchantSection : itemConfig.getSubsections("enchants")) {
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(enchantSection.getString("id")));
int level = enchantSection.getInt("level");
enchants.put(enchantment, level);
}
enchants.forEach(builder::addEnchantment);
ItemStack itemStack = builder.build();
ItemMeta meta = itemStack.getItemMeta();
assert meta != null;
for (JSONConfig attribute : itemConfig.getSubsections("attributes")) {
meta.addAttributeModifier(
Attribute.valueOf(attribute.getString("id").toUpperCase()),
new AttributeModifier(
UUID.randomUUID(),
String.valueOf(NumberUtils.randInt(0, 10000000)),
attribute.getDouble("amount"),
AttributeModifier.Operation.valueOf(attribute.getString("operation").toUpperCase()),
EquipmentSlot.HAND
)
);
}
itemStack.setItemMeta(meta);
new CustomItem(this.getPlugin().getNamespacedKeyFactory().create(name.toLowerCase()), test -> Objects.equals(this, WeaponUtils.getWeaponFromItem(test)), itemStack).register();
if (itemConfig.getBool("craftable")) {
Recipes.createAndRegisterRecipe(
this.getPlugin(),
this.getName(),
itemStack,
itemConfig.getStrings("recipe")
);
}
return itemStack;
}
/**
* Get effect strength of effect.
*
* @param effect The effect to query.
* @param triggerType The trigger type.
* @return The strength.
*/
public JSONConfig getEffectArgs(@NotNull final Effect effect,
@NotNull final TriggerType triggerType) {
return effects.get(triggerType).get(effect);
}
/**
* Get cooldown time.
*
* @param effect The effect.
* @param triggerType The trigger type.
* @return The time.
*/
public double getCooldownTime(@NotNull final Effect effect,
@NotNull final TriggerType triggerType) {
return getEffectArgs(effect, triggerType).getDouble("cooldown");
}
/**
* Get all effects for a trigger type.
*
* @param triggerType The type.
* @return The effects.
*/
public Set<Effect> getEffects(@NotNull final TriggerType triggerType) {
return effects.get(triggerType).keySet();
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Weapon set)) {
return false;
}
return this.name.equals(set.name);
}
@Override
public int hashCode() {
return Objects.hash(this.name);
}
@Override
public String toString() {
return "Weapon{"
+ this.name
+ "}";
}
}

View File

@@ -1,77 +0,0 @@
package com.willfp.ecoweapons.weapons;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableList;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.updating.ConfigUpdater;
import com.willfp.ecoweapons.EcoWeaponsPlugin;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@UtilityClass
public class Weapons {
/**
* Registered weapons.
*/
private static final BiMap<String, Weapon> BY_NAME = HashBiMap.create();
/**
* Get all registered {@link Weapon}s.
*
* @return A list of all {@link Weapon}s.
*/
public static List<Weapon> values() {
return ImmutableList.copyOf(BY_NAME.values());
}
/**
* Get {@link Weapon} matching name.
*
* @param name The name to search for.
* @return The matching {@link Weapon}, or null if not found.
*/
@Nullable
public static Weapon getByName(@NotNull final String name) {
return BY_NAME.get(name);
}
/**
* Update all {@link Weapon}s.
*
* @param plugin Instance of EcoWeapons.
*/
@ConfigUpdater
public static void update(@NotNull final EcoWeaponsPlugin plugin) {
for (Weapon weapon : values()) {
removeWeapon(weapon);
}
for (JSONConfig setConfig : plugin.getEcoWeaponsJson().getSubsections("weapons")) {
addNewWeapon(new Weapon(setConfig, plugin));
}
}
/**
* Add new {@link Weapon} to EcoWeapons.
*
* @param weapon The {@link Weapon} to add.
*/
public static void addNewWeapon(@NotNull final Weapon weapon) {
BY_NAME.remove(weapon.getName());
BY_NAME.put(weapon.getName(), weapon);
}
/**
* Remove {@link Weapon} from EcoWeapons.
*
* @param weapon The {@link Weapon} to remove.
*/
public static void removeWeapon(@NotNull final Weapon weapon) {
BY_NAME.remove(weapon.getName());
}
}

View File

@@ -1,81 +0,0 @@
package com.willfp.ecoweapons.weapons.util;
import com.willfp.ecoweapons.EcoWeaponsPlugin;
import com.willfp.ecoweapons.conditions.Condition;
import com.willfp.ecoweapons.weapons.Weapon;
import com.willfp.ecoweapons.weapons.Weapons;
import lombok.experimental.UtilityClass;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
@UtilityClass
public class WeaponUtils {
/**
* Instance of EcoWeapons.
*/
private static final EcoWeaponsPlugin PLUGIN = EcoWeaponsPlugin.getInstance();
/**
* Get weapon from an item.
*
* @param itemStack The itemStack to check.
* @return The weapon, or null if no weapon is found.
*/
@Nullable
public Weapon getWeaponFromItem(@Nullable final ItemStack itemStack) {
if (itemStack == null) {
return null;
}
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
return null;
}
return getWeaponFromItem(meta);
}
/**
* Get weapon on an item.
*
* @param meta The itemStack to check.
* @return The weapon, or null if no weapon is found.
*/
@Nullable
public Weapon getWeaponFromItem(@NotNull final ItemMeta meta) {
PersistentDataContainer container = meta.getPersistentDataContainer();
String weaponName = container.get(PLUGIN.getNamespacedKeyFactory().create("weapon"), PersistentDataType.STRING);
if (weaponName == null) {
return null;
}
return Weapons.getByName(weaponName);
}
/**
* Get if all conditions are met for a player.
*
* @param player The player.
* @param weapon The weapon.
* @return If conditions are met.
*/
public boolean areConditionsMet(@NotNull final Player player,
@NotNull final Weapon weapon) {
for (Map.Entry<Condition<?>, Object> entry : weapon.getConditions().entrySet()) {
if (!entry.getKey().isMet(player, entry.getValue())) {
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,75 @@
package com.willfp.ecoweapons
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.command.impl.PluginCommand
import com.willfp.eco.core.display.DisplayModule
import com.willfp.ecoweapons.commands.CommandEcoweapons
import com.willfp.ecoweapons.config.EcoWeaponsJson
import com.willfp.ecoweapons.display.WeaponsDisplay
import com.willfp.ecoweapons.util.DiscoverRecipeListener
import com.willfp.ecoweapons.weapons.WeaponListener
import com.willfp.ecoweapons.weapons.WeaponUtils
import com.willfp.libreforge.Holder
import com.willfp.libreforge.HolderProvider
import com.willfp.libreforge.LibReforge
import org.bukkit.entity.Player
import org.bukkit.event.Listener
class EcoWeaponsPlugin : EcoPlugin(1241, 12134, "&#ff0000") {
/**
* tiers.json.
*/
val ecoWeaponsJson: EcoWeaponsJson
/**
* Internal constructor called by bukkit on plugin load.
*/
init {
instance = this
ecoWeaponsJson = EcoWeaponsJson(this)
LibReforge.init(this)
LibReforge.registerHolderProvider(object : HolderProvider {
override fun providerHolders(player: Player): Iterable<Holder> {
val weapon = WeaponUtils.getWeaponOnPlayer(player)
return if (weapon == null) emptyList() else listOf(weapon)
}
})
}
override fun handleEnable() {
LibReforge.enable(this)
}
override fun handleDisable() {
LibReforge.disable(this)
}
override fun handleReload() {
LibReforge.reload(this)
}
override fun loadListeners(): List<Listener> {
return listOf(
DiscoverRecipeListener(this),
WeaponListener()
)
}
override fun loadPluginCommands(): List<PluginCommand> {
return listOf(
CommandEcoweapons(this)
)
}
override fun createDisplayModule(): DisplayModule {
return WeaponsDisplay(this)
}
companion object {
/**
* Instance of EcoWeapons.
*/
@JvmStatic
lateinit var instance: EcoWeaponsPlugin
}
}

View File

@@ -0,0 +1,25 @@
package com.willfp.ecoweapons.commands
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.command.CommandHandler
import com.willfp.eco.core.command.impl.PluginCommand
class CommandEcoweapons(
plugin: EcoPlugin
) : PluginCommand(
plugin,
"ecoweapons",
"ecoweapons.command.ecoweapons",
false) {
init {
addSubcommand(CommandReload(plugin))
.addSubcommand(CommandGive(plugin))
}
override fun getHandler(): CommandHandler {
return CommandHandler { sender, _ ->
sender.sendMessage(
plugin.langYml.getMessage("invalid-command")
)
}
}
}

View File

@@ -0,0 +1,89 @@
package com.willfp.ecoweapons.commands
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.command.CommandHandler
import com.willfp.eco.core.command.TabCompleteHandler
import com.willfp.eco.core.command.impl.Subcommand
import org.bukkit.Bukkit
import org.bukkit.inventory.ItemStack
import org.bukkit.util.StringUtil
import com.willfp.ecoweapons.weapons.Weapons
class CommandGive(plugin: EcoPlugin) : Subcommand(plugin, "give", "ecoweapons.command.give", false) {
private val numbers = listOf(
"1",
"2",
"3",
"4",
"5",
"10",
"32",
"64"
)
override fun getHandler(): CommandHandler {
return CommandHandler { sender, args ->
if (args.isEmpty()) {
sender.sendMessage(plugin.langYml.getMessage("needs-player"))
return@CommandHandler
}
if (args.size == 1) {
sender.sendMessage(plugin.langYml.getMessage("needs-item"))
return@CommandHandler
}
val receiverName = args[0]
val receiver = Bukkit.getPlayer(receiverName)
if (receiver == null) {
sender.sendMessage(plugin.langYml.getMessage("invalid-player"))
return@CommandHandler
}
val itemID = args[1]
var amount = 1
val weapon = Weapons.getByID(itemID.lowercase())
if (weapon == null) {
sender.sendMessage(plugin.langYml.getMessage("invalid-item"))
return@CommandHandler
}
var message = plugin.langYml.getMessage("give-success")
message = message.replace("%item%", weapon.id).replace("%recipient%", receiver.name)
sender.sendMessage(message)
if (args.size == 3) {
amount = args[2].toIntOrNull() ?: 1
}
val item: ItemStack = weapon.itemStack
item.amount = amount
receiver.inventory.addItem(item)
}
}
override fun getTabCompleter(): TabCompleteHandler {
return TabCompleteHandler { _, args ->
val completions = mutableListOf<String>()
if (args.isEmpty()) {
return@TabCompleteHandler Weapons.values().map { it.id }
}
if (args.size == 1) {
StringUtil.copyPartialMatches(
args[0],
Bukkit.getOnlinePlayers().map { it.name },
completions)
return@TabCompleteHandler completions
}
if (args.size == 2) {
StringUtil.copyPartialMatches(args[1], Weapons.values().map { it.id }, completions)
completions.sort()
return@TabCompleteHandler completions
}
if (args.size == 3) {
StringUtil.copyPartialMatches(args[2], numbers, completions)
return@TabCompleteHandler completions
}
emptyList()
}
}
}

View File

@@ -0,0 +1,15 @@
package com.willfp.ecoweapons.commands
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.command.impl.Subcommand
import com.willfp.eco.core.command.CommandHandler
import org.bukkit.command.CommandSender
class CommandReload(plugin: EcoPlugin) : Subcommand(plugin, "reload", "ecoweapons.command.reload", false) {
override fun getHandler(): CommandHandler {
return CommandHandler { sender: CommandSender, args: List<String?>? ->
plugin.reload()
sender.sendMessage(plugin.langYml.getMessage("reloaded"))
}
}
}

View File

@@ -0,0 +1,6 @@
package com.willfp.ecoweapons.config
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.config.json.JSONStaticBaseConfig
class EcoWeaponsJson(plugin: EcoPlugin) : JSONStaticBaseConfig("ecoweapons", plugin)

View File

@@ -0,0 +1,28 @@
package com.willfp.ecoweapons.display
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.display.DisplayModule
import com.willfp.eco.core.display.DisplayPriority
import org.bukkit.inventory.ItemStack
import com.willfp.ecoweapons.weapons.WeaponUtils
class WeaponsDisplay(plugin: EcoPlugin) : DisplayModule(plugin, DisplayPriority.LOWEST) {
override fun display(
itemStack: ItemStack,
vararg args: Any
) {
val meta = itemStack.itemMeta ?: return
val weapon = WeaponUtils.getWeaponFromItem(meta) ?: return
val weaponMeta = weapon.itemStack.itemMeta ?: return
val lore: MutableList<String> = weaponMeta.lore?.toMutableList() ?: return
if (meta.hasLore()) {
lore.addAll(meta.lore ?: return)
}
meta.lore = lore
meta.setDisplayName(weaponMeta.displayName)
meta.addItemFlags(*weaponMeta.itemFlags.toTypedArray())
itemStack.itemMeta = meta
}
}

View File

@@ -0,0 +1,28 @@
package com.willfp.ecoweapons.util
import com.willfp.eco.core.EcoPlugin
import org.bukkit.Bukkit
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerJoinEvent
import org.bukkit.inventory.Recipe
import org.bukkit.inventory.ShapedRecipe
class DiscoverRecipeListener(private val plugin: EcoPlugin) : Listener {
@EventHandler
fun onJoin(event: PlayerJoinEvent) {
val player = event.player
if (plugin.configYml.getBool("discover-recipes")) {
Bukkit.getServer().recipeIterator().forEachRemaining { recipe: Recipe? ->
if (recipe is ShapedRecipe) {
val key = recipe.key
if (key.namespace == "ecoweapons") {
if (!key.key.contains("displayed")) {
player.discoverRecipe(key)
}
}
}
}
}
}
}

View File

@@ -0,0 +1,95 @@
package com.willfp.ecoweapons.weapons
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.config.interfaces.JSONConfig
import com.willfp.eco.core.display.Display
import com.willfp.eco.core.items.CustomItem
import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.builder.ItemStackBuilder
import com.willfp.eco.core.recipe.Recipes
import com.willfp.libreforge.Holder
import com.willfp.libreforge.conditions.Conditions
import com.willfp.libreforge.effects.Effects
import org.bukkit.NamespacedKey
import org.bukkit.enchantments.Enchantment
import org.bukkit.inventory.ItemFlag
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataType
import org.jetbrains.annotations.NotNull
import java.util.*
class Weapon(
private val config: JSONConfig,
private val plugin: EcoPlugin
) : Holder {
val id = config.getString("name")
override val effects = config.getSubsections("effects").mapNotNull {
Effects.compile(it, "Weapon ID $id")
}.toSet()
override val conditions = config.getSubsections("conditions").mapNotNull {
Conditions.compile(it, "Weapon ID $id")
}.toSet()
val itemStack: ItemStack = run {
val itemConfig = config.getSubsection("item")
ItemStackBuilder(Items.lookup(itemConfig.getString("material")).item).apply {
setDisplayName(itemConfig.getFormattedString("displayName"))
addItemFlag(
*itemConfig.getStrings("flags")
.mapNotNull { ItemFlag.valueOf(it.uppercase()) }
.toTypedArray<@NotNull ItemFlag>()
)
setUnbreakable(itemConfig.getBool("unbreakable"))
addLoreLines(
itemConfig.getFormattedStrings("lore").map { "${Display.PREFIX}$it" })
setCustomModelData {
val data = itemConfig.getInt("customModelData")
if (data != -1) data else null
}
writeMetaKey(
this@Weapon.plugin.namespacedKeyFactory.create("weapon"),
PersistentDataType.STRING,
this@Weapon.id
)
for (enchantConfig in itemConfig.getSubsections("enchants")) {
addEnchantment(
Enchantment.getByKey(NamespacedKey.minecraft(enchantConfig.getString("id"))) ?: continue,
enchantConfig.getInt("level")
)
}
}.build()
}
val customItem = CustomItem(
plugin.namespacedKeyFactory.create(id),
{ test -> WeaponUtils.getWeaponFromItem(test) == this },
itemStack
).apply { register() }
val craftingRecipe = if (config.getBool("item.craftable")) {
Recipes.createAndRegisterRecipe(
plugin,
id,
itemStack,
config.getStrings("item.recipe")
)
} else null
override fun equals(other: Any?): Boolean {
if (other !is Weapon) {
return false
}
return this.id == other.id
}
override fun hashCode(): Int {
return Objects.hash(this.id)
}
override fun toString(): String {
return "Weapon{$id}"
}
}

View File

@@ -0,0 +1,13 @@
package com.willfp.ecoweapons.weapons
import com.willfp.libreforge.updateEffects
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerItemHeldEvent
class WeaponListener: Listener {
@EventHandler
fun onHoldItem(event: PlayerItemHeldEvent) {
event.player.updateEffects()
}
}

View File

@@ -0,0 +1,51 @@
package com.willfp.ecoweapons.weapons
import com.willfp.ecoweapons.EcoWeaponsPlugin.Companion.instance
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import org.bukkit.persistence.PersistentDataType
object WeaponUtils {
/**
* Instance of EcoWeapons.
*/
private val PLUGIN = instance
/**
* Get weapon from an item.
*
* @param itemStack The itemStack to check.
* @return The weapon, or null if no weapon is found.
*/
fun getWeaponFromItem(itemStack: ItemStack?): Weapon? {
itemStack ?: return null
val meta = itemStack.itemMeta ?: return null
return getWeaponFromItem(meta)
}
/**
* Get weapon on an item.
*
* @param meta The itemStack to check.
* @return The weapon, or null if no weapon is found.
*/
fun getWeaponFromItem(meta: ItemMeta): Weapon? {
val container = meta.persistentDataContainer
val weaponName = container.get(
PLUGIN.namespacedKeyFactory.create("weapon"),
PersistentDataType.STRING
) ?: return null
return Weapons.getByID(weaponName)
}
/**
* Get weapon on a player.
*
* @param player The player to check.
* @return The weapon, or null if no weapon is found.
*/
fun getWeaponOnPlayer(player: Player): Weapon? {
return getWeaponFromItem(player.inventory.itemInMainHand)
}
}

View File

@@ -0,0 +1,72 @@
package com.willfp.ecoweapons.weapons
import com.google.common.collect.BiMap
import com.google.common.collect.HashBiMap
import com.google.common.collect.ImmutableList
import com.willfp.eco.core.config.updating.ConfigUpdater
import com.willfp.ecoweapons.EcoWeaponsPlugin
object Weapons {
/**
* Registered weapons.
*/
private val BY_ID: BiMap<String, Weapon> = HashBiMap.create()
/**
* Get all registered [Weapon]s.
*
* @return A list of all [Weapon]s.
*/
@JvmStatic
fun values(): List<Weapon> {
return ImmutableList.copyOf(BY_ID.values)
}
/**
* Get [Weapon] matching id.
*
* @param name The id to search for.
* @return The matching [Weapon], or null if not found.
*/
@JvmStatic
fun getByID(name: String): Weapon? {
return BY_ID[name]
}
/**
* Update all [Weapon]s.
*
* @param plugin Instance of EcoWeapons.
*/
@ConfigUpdater
@JvmStatic
fun update(plugin: EcoWeaponsPlugin) {
for (weapon in values()) {
removeWeapon(weapon)
}
for (setConfig in plugin.ecoWeaponsJson.getSubsections("weapons")) {
addNewWeapon(Weapon(setConfig, plugin))
}
}
/**
* Add new [Weapon] to EcoWeapons.
*
* @param weapon The [Weapon] to add.
*/
@JvmStatic
fun addNewWeapon(weapon: Weapon) {
BY_ID.remove(weapon.id)
BY_ID[weapon.id] = weapon
}
/**
* Remove [Weapon] from EcoWeapons.
*
* @param weapon The [Weapon] to remove.
*/
@JvmStatic
fun removeWeapon(weapon: Weapon) {
BY_ID.remove(weapon.id)
}
}

View File

@@ -4,4 +4,9 @@
#
discover-recipes: true # If all recipes should be automatically discovered.
cooldown-in-actionbar: true # If effect cooldown messages should be shown in the actionbar rather than in chat.
cooldown:
in-actionbar: true
sound:
enabled: true
sound: "BLOCK_NOTE_BLOCK_PLING"
pitch: 0.5

View File

@@ -32,18 +32,7 @@
"",
"&8&oYou must be on full health to activate bleed"
],
"attributes": [
{
"id": "generic_attack_speed",
"amount": 0.15,
"operation": "multiply_scalar_1"
},
{
"id": "generic_attack_damage",
"amount": 0.2,
"operation": "multiply_scalar_1"
}
],
"attributes": [],
"unbreakable": false,
"flags": [
"hide_attributes"
@@ -110,8 +99,7 @@
"&8» &310% chance to summon lightning",
"&8» &3Surround your opponent with arrows"
],
"attributes": [
],
"attributes": [],
"unbreakable": false,
"flags": [],
"customModelData": -1,
@@ -173,8 +161,7 @@
"&8» &e10% chance to give nausea",
"&8» &e5% chance to give blindness"
],
"attributes": [
],
"attributes": [],
"unbreakable": false,
"flags": [],
"customModelData": -1,

View File

@@ -9,4 +9,4 @@ messages:
needs-item: "&cYou must specify an item!"
invalid-item: "&cInvalid item!"
give-success: "Gave &a%item%&r to &a%recipient%"
on-cooldown: "This effect is on cooldown! Wait &a%seconds% seconds&f to use it!"
on-cooldown: "&cThis effect is on cooldown! &fTime left: &a%seconds% seconds"

View File

@@ -8,6 +8,8 @@ load: STARTUP
depend:
- eco
- ProtocolLib
libraries:
- 'org.jetbrains.kotlin:kotlin-stdlib:1.5.21'
commands:
ecoweapons: